1 /*===========================================================================
2  *
3  *                            PUBLIC DOMAIN NOTICE
4  *               National Center for Biotechnology Information
5  *
6  *  This software/database is a "United States Government Work" under the
7  *  terms of the United States Copyright Act.  It was written as part of
8  *  the author's official duties as a United States Government employee and
9  *  thus cannot be copyrighted.  This software/database is freely available
10  *  to the public for use. The National Library of Medicine and the U.S.
11  *  Government have not placed any restriction on its use or reproduction.
12  *
13  *  Although all reasonable efforts have been taken to ensure the accuracy
14  *  and reliability of the software and data, the NLM and the U.S.
15  *  Government do not and cannot warrant the performance or results that
16  *  may be obtained by using this software or data. The NLM and the U.S.
17  *  Government disclaim all warranties, express or implied, including
18  *  warranties of performance, merchantability or fitness for any particular
19  *  purpose.
20  *
21  *  Please cite the author in any work or product based on this material.
22  *
23  * ===========================================================================
24  *
25  */
26 
27  /* Something unusual: Lyrics
28   *
29   * That file contains only one useful function:
30   *
31   *                       XFS_Private_InitOperations
32   *
33   * it needed to fill _DOKAN_OPERATIONS structure.
34   *
35   * I put here all possible stubs to _DOKAN_OPERATIONS
36   * functions. However, I will use only several of them while
37   * structure initialisation. So, if You want to extend functionality,
38   * please edit already ready stub and add new function to structure
39   * initialized .
40   *
41   */
42 
43 #include <windows.h>
44 
45 #include <klib/out.h>
46 #include <klib/log.h>
47 #include <klib/namelist.h>
48 #include <kfs/file.h>
49 #include <kfs/directory.h>
50 #include <kfs/impl.h>               /* KDirectoryGetSysDir() */
51 #include <vfs/path.h>
52 #include <vfs/manager.h>
53 
54 #include <xfs/node.h>
55 #include <xfs/tree.h>
56 #include <xfs/editors.h>
57 #include <xfs/handle.h>
58 #include <xfs/perm.h>
59 #include <xfs/path.h>
60 
61 #include <sysalloc.h>
62 
63 #include <WinBase.h>
64 #include <WinNT.h>
65 #include <wchar.h>
66 
67 #include "operations.h"
68 #include "zehr.h"
69 #include "schwarzschraube.h"
70 
71 /****************************************************************
72  * Song over babalula
73  ****************************************************************/
74 #define USE_XFS_DOKAN_CREATEFILE              1   /* - */  /* */
75 #define USE_XFS_DOKAN_OPENDIRECTORY           1   /* - */  /* */
76 #define USE_XFS_DOKAN_CREATEDIRECTORY         1   /* - */  /* */
77 #define USE_XFS_DOKAN_CLEANUP                 1   /* - */  /* */
78 #define USE_XFS_DOKAN_CLOSEFILE               1   /* - */  /* */
79 #define USE_XFS_DOKAN_READFILE                1   /* - */  /* */
80 #define USE_XFS_DOKAN_WRITEFILE               1   /* - */  /* */
81 #define USE_XFS_DOKAN_FLUSHFILEBUFFERS        0   /* - */  /* */
82 #define USE_XFS_DOKAN_GETFILEINFORMATION      1   /* - */  /* */
83 #define USE_XFS_DOKAN_FINDFILES               1   /* - */  /* */
84 #define USE_XFS_DOKAN_FINDFILESWITHPATTERN    0   /* - */  /* NO NEED */
85 #define USE_XFS_DOKAN_SETFILEATTRIBUTES       0   /* - */  /* */
86 #define USE_XFS_DOKAN_SETFILETIME             0   /* - */  /* */
87 #define USE_XFS_DOKAN_DELETEFILE              1   /* - */  /* */
88 #define USE_XFS_DOKAN_DELETEDIRECTORY         1   /* - */  /* */
89 #define USE_XFS_DOKAN_MOVEFILE                1   /* - */  /* */
90 #define USE_XFS_DOKAN_SETENDOFFILE            0   /* - */  /* */
91 #define USE_XFS_DOKAN_SETALLOCATIONSIZE       0   /* - */  /* */
92 #define USE_XFS_DOKAN_LOCKFILE                0   /* - */  /* */
93 #define USE_XFS_DOKAN_UNLOCKFILE              0   /* - */  /* */
94 #define USE_XFS_DOKAN_GETDISKFREESPACE        0   /* - */  /* NO NEED */
95 #define USE_XFS_DOKAN_GETVOLUMEINFORMATION    1   /* - */  /* */
96 #define USE_XFS_DOKAN_UNMOUNT                 1   /* - */  /* */
97 #define USE_XFS_DOKAN_GETFILESECURITY         1   /* - */  /* */
98 #define USE_XFS_DOKAN_SETFILESECURITY         1   /* - */  /* */
99 
100 /*)))
101   |||   Operations
102   (((*/
103 
104 /*))
105  //
106 || is using _DOKAN_OPTIONS structure for that goal. So, there
107 || is different way to access for XFSPeer for both libraries
108  \\
109   (*/
110 
111 /*))    KLog does not work with WCHAR :D
112  ((*/
113 XFS_EXTERN rc_t CC wLogMsg ( KLogLevel Level, LPCWSTR Format, ... );
114 
115 /*\
116 |*| importante protopute
117 \*/
118 struct KSysDir;
119 rc_t KSysDirOSPath (
120                 const struct KSysDir * self,
121                 wchar_t * real,
122                 size_t bsize,
123                 const char * path,
124                 va_list args
125                 );
126 
127 /*)))
128  /// Some common things are here
129 (((*/
130 LIB_EXPORT
131 rc_t CC
XFSPathInnerToNative(WCHAR * NativePathBuffer,size_t NativePathBufferSize,const char * InnerPath,...)132 XFSPathInnerToNative (
133                 WCHAR * NativePathBuffer,
134                 size_t NativePathBufferSize,
135                 const char * InnerPath,
136                 ...
137 )
138 {
139     rc_t RCt;
140     KDirectory * Dir;
141     struct KSysDir * SysDir;
142     va_list VaLsd;
143 
144     RCt = 0;
145     Dir = NULL;
146 
147     if ( InnerPath == NULL || NativePathBuffer == NULL
148         || NativePathBufferSize == 0 )
149     {
150         return XFS_RC ( rcNull );
151     }
152 
153     RCt = KDirectoryNativeDir ( & Dir );
154     if ( RCt == 0 ) {
155         SysDir = KDirectoryGetSysDir(Dir);
156 
157         va_start ( VaLsd, InnerPath );
158         RCt = KSysDirOSPath (
159                                 SysDir,
160                                 NativePathBuffer,
161                                 NativePathBufferSize,
162                                 InnerPath,
163                                 VaLsd
164                                 );
165         va_end ( VaLsd );
166     }
167 
168     return RCt;
169 }   /* XFSPathInnerToNative () */
170 
171 static
172 rc_t CC
_DOKAN_make_v_path(LPCWSTR File,VPath ** Path)173 _DOKAN_make_v_path ( LPCWSTR File, VPath ** Path )
174 {
175     rc_t RCt;
176     char Buffer [ XFS_SIZE_4096 ];
177     char * pChar;
178     size_t Size;
179 
180     RCt = 0;
181     Size = 0;
182     pChar = NULL;
183     * Buffer = 0;
184 
185     if ( File == NULL || Path == NULL ) {
186         return XFS_RC ( rcNull );
187     }
188     * Path = NULL;
189 
190         /* Quite stupid, but I don't know what to do
191          */
192     RCt = wcstombs_s (
193                     & Size,
194                     Buffer,
195                     sizeof ( Buffer ),
196                     File,
197                     wcslen ( File )
198                     );
199 
200     if ( RCt == 0 ) {
201             /* That is kinda stupid, and I should think about it
202              */
203         pChar = Buffer;
204         while ( * pChar != 0 ) {
205             if ( * pChar == '\\' ) {
206                 * pChar = '/';
207             }
208             pChar ++;
209         }
210 
211         RCt = VFSManagerMakePath ( XFS_VfsManager (), Path, Buffer );
212     }
213 
214     return RCt;
215 }   /* _DOKAN_make_v_path () */
216 
217 static
218 rc_t CC
_DOKAN_get_node(const PDOKAN_FILE_INFO FileInfo,const struct VPath * Path,const struct XFSNode ** TheNode)219 _DOKAN_get_node (
220                 const PDOKAN_FILE_INFO FileInfo,
221                 const struct VPath * Path,
222                 const struct XFSNode ** TheNode
223 )
224 {
225     struct XFSTreeDepot * Depot;
226     const struct XFSNode * Node;
227     rc_t RCt;
228 
229     Depot = NULL;
230     RCt = 0;
231 
232     if ( FileInfo == NULL || TheNode == NULL ) {
233         return XFS_RC ( rcNull );
234     }
235 
236     * TheNode = NULL;
237 
238     Depot = ( struct XFSTreeDepot * ) FileInfo -> DokanOptions -> GlobalContext;
239     if ( Depot == NULL ) {
240         return XFS_RC ( rcInvalid );
241     }
242 
243     RCt = XFSTreeDepotFindNodeForPath ( Depot, Path, & Node );
244 
245     if ( RCt == 0 ) {
246         * TheNode = Node;
247     }
248 
249 /*
250 //TT wLogMsg ( klogDebug, L"_DOKAB_get_node () TreeDepot [0x%p] Node [0x%p] Opts [0x%p]\n", TreeDepot, Node, FileInfo -> DokanOptions );
251 */
252 
253     return RCt;
254 }   /* _DOKAN_get_node () */
255 
256 static
257 rc_t CC
_DOKAN_get_path_and_node(LPCWSTR File,const PDOKAN_FILE_INFO Info,const struct VPath ** Path,const struct XFSNode ** Node,XFSNType * NodeType)258 _DOKAN_get_path_and_node (
259                         LPCWSTR File,
260                         const PDOKAN_FILE_INFO Info,
261                         const struct VPath ** Path,
262                         const struct XFSNode ** Node,
263                         XFSNType * NodeType
264 )
265 {
266     rc_t RCt;
267     struct XFSNode * RNode;
268     struct VPath * RPath;
269     XFSNType Type;
270     const struct XFSAttrEditor * Ediotr;
271 
272     RCt = 0;
273     RNode = NULL;
274     RPath = NULL;
275     Type = kxfsBadPath;
276     Ediotr = NULL;
277 
278     if ( File == NULL || Info == NULL ) {
279         return XFS_RC ( rcNull );
280     }
281 
282     RCt = _DOKAN_make_v_path ( File, & RPath );
283     if ( RCt == 0 ) {
284 
285         RCt = _DOKAN_get_node ( Info, RPath, & RNode );
286         if ( RCt == 0 ) {
287             if ( NodeType != NULL ) {
288                 RCt = XFSNodeAttrEditor ( RNode, & Ediotr );
289                 if ( RCt == 0 ) {
290                     RCt = XFSAttrEditorType ( Ediotr, & Type );
291 
292                     XFSEditorDispose ( & ( Ediotr -> Papahen ) );
293                 }
294             }
295         }
296     }
297 
298     if ( RCt == 0 ) {
299         if ( Path != NULL ) {
300             * Path = RPath;
301         }
302         else {
303             VPathRelease ( RPath );
304         }
305 
306         if ( Node != NULL ) {
307             * Node = RNode;
308         }
309         else {
310             XFSNodeRelease ( RNode );
311         }
312 
313         if ( NodeType != NULL ) {
314             * NodeType = Type;
315         }
316     }
317     else {
318         if ( RPath != NULL ) {
319             VPathRelease ( RPath );
320         }
321 
322         if ( RNode != NULL ) {
323             XFSNodeRelease ( RNode );
324         }
325     }
326 
327     return RCt;
328 }   /* _DOKAN_get_path_and_node () */
329 
330 static
331 rc_t
_DOKAN_get_parent_node(const struct VPath * Path,DOKAN_FILE_INFO * TheFileInfo,struct XFSNode ** Node,XFSNType * Type,char ** NodeName)332 _DOKAN_get_parent_node (
333                 const struct VPath * Path,
334                 DOKAN_FILE_INFO * TheFileInfo,  /* Depot source */
335                 struct XFSNode ** Node,         /* Ret node */
336                 XFSNType * Type,                /* could be NULL */
337                 char ** NodeName                /* could be NULL */
338 )
339 {
340     rc_t RCt;
341     struct XFSTreeDepot * Depot;
342     char BB [ XFS_SIZE_4096 ];
343     struct XFSPath * xPath;
344     uint32_t xPathQ;
345     struct XFSNode * xNode;
346     struct XFSAttrEditor * xEditor;
347     char * xName;
348     const struct XFSPath * xParent;
349 
350     RCt = 0;
351     Depot = NULL;
352     * BB = 0;
353     xPath = NULL;
354     xPathQ = 0;
355     xNode = NULL;
356     xEditor = NULL;
357     xName = NULL;
358     xParent = NULL;
359 
360     if ( Node == NULL ) {
361         return XFS_RC ( rcNull );
362     }
363 
364     * Node = NULL;
365 
366     if ( Path == NULL || TheFileInfo == NULL ) {
367         return XFS_RC ( rcNull );
368     }
369 
370     if ( Type != NULL ) {
371         * Type = kxfsNotFound;
372     }
373 
374     if ( NodeName != NULL ) {
375         * NodeName = NULL;
376     }
377 
378         /*) First we should retrieve fresh instance of depot
379          (*/
380     Depot = ( struct XFSTreeDepot * ) TheFileInfo -> DokanOptions -> GlobalContext;
381     if ( Depot == NULL ) {
382         return XFS_RC ( rcInvalid );
383     }
384 
385         /*) Reading VPath
386          (*/
387     RCt = XFS_ReadVPath_ZHR ( Path, BB, sizeof ( BB ), "" );
388     if ( RCt == 0 ) {
389             /*) Making XFSPath
390              (*/
391         RCt = XFSPathMake ( & xPath, true, BB );
392         if ( RCt == 0 ) {
393             xPathQ = XFSPathPartCount ( xPath );
394             if ( xPathQ < 2 ) {
395                 RCt = XFS_RC ( rcInvalid );
396             }
397             else {
398                     /*) Here we are composing parent path
399                      (*/
400                 RCt = XFSPathParent ( xPath, & xParent );
401                 if ( RCt == 0 ) {
402                         /*) Here we are looking for NODE
403                          (*/
404                     RCt = XFSTreeDepotFindNode (
405                                                 Depot,
406                                                 XFSPathGet ( xParent ),
407                                                 & xNode
408                                                 );
409                     if ( RCt == 0 ) {
410                         if ( Type != NULL ) {
411                             RCt = XFSNodeAttrEditor ( xNode, & xEditor );
412                             if ( RCt == 0 ) {
413                                 RCt = XFSAttrEditorType ( xEditor, Type );
414                                 XFSEditorDispose ( & ( xEditor -> Papahen ) );
415                             }
416                         }
417 
418                         if ( RCt == 0 ) {
419                             if ( NodeName != NULL ) {
420                                 RCt = XFS_StrDup (
421                                                 XFSPathName ( xPath ),
422                                                 & xName
423                                                 );
424                                 if ( RCt == 0 ) {
425                                     * NodeName = xName;
426                                 }
427                             }
428                         }
429 
430                         if ( RCt == 0 ) {
431                             * Node = xNode;
432                         }
433                     }
434                 }
435 
436                 XFSPathRelease ( xParent );
437             }
438 
439             XFSPathRelease ( xPath );
440         }
441     }
442 
443     if ( RCt != 0 ) {
444         * Node = NULL;
445         if ( Type != NULL ) {
446             * Type = kxfsNotFound;
447         }
448         if ( NodeName != NULL ) {
449             * NodeName = NULL;
450         }
451         if ( xNode != NULL ) {
452             XFSNodeRelease ( xNode );
453         }
454         if ( xName != NULL ) {
455             free ( xName );
456         }
457     }
458 
459     return RCt;
460 }   /* _DOKAN_get_parent_node () */
461 
462 static
463 rc_t
_DOKAN_get_parent_node_from_char(LPCWSTR ThePath,DOKAN_FILE_INFO * TheFileInfo,struct XFSNode ** Node,XFSNType * Type,char ** NodeName)464 _DOKAN_get_parent_node_from_char (
465                 LPCWSTR ThePath,
466                 DOKAN_FILE_INFO * TheFileInfo,  /* Depot source */
467                 struct XFSNode ** Node,         /* Ret node */
468                 XFSNType * Type,                /* could be NULL */
469                 char ** NodeName                /* could be NULL */
470 )
471 {
472     rc_t RCt;
473     struct VPath * Path;
474 
475     RCt = 0;
476     Path = NULL;
477 
478     if ( ThePath == NULL || TheFileInfo == NULL || Node == NULL ) {
479         return XFS_RC ( rcNull );
480     }
481 
482     * Node = NULL;
483 
484     RCt = _DOKAN_make_v_path ( ThePath, & Path );
485     if ( RCt == 0 ) {
486         RCt = _DOKAN_get_parent_node (
487                                     Path,
488                                     TheFileInfo,
489                                     Node,
490                                     Type,
491                                     NodeName
492                                     );
493 
494         VPathRelease ( Path );
495     }
496 
497     return RCt;
498 }   /* _DOKAN_get_parent_node_from_char() */
499 
500 static
501 rc_t
_DOKAN_delete_file_dir(LPCWSTR FileName,PDOKAN_FILE_INFO TheFileInfo)502 _DOKAN_delete_file_dir (
503                     LPCWSTR FileName,
504                     PDOKAN_FILE_INFO TheFileInfo
505 )
506 {
507     rc_t RCt;
508     struct XFSNode * Node;
509     XFSNType Type;
510     char * Name;
511     struct XFSDirEditor * Editor;
512 
513     RCt = 0;
514     Node = NULL;
515     Type = kxfsNotFound;
516     Name = NULL;
517     Editor = NULL;
518 
519     if ( FileName == NULL || TheFileInfo == NULL ) {
520         return XFS_RC ( rcNull );
521     }
522 
523     RCt = _DOKAN_get_parent_node_from_char (
524                                         FileName,
525                                         TheFileInfo,
526                                         & Node,
527                                         & Type,
528                                         & Name
529                                         );
530     if ( RCt == 0 ) {
531         RCt = XFSNodeDirEditor ( Node, & Editor );
532         if ( RCt == 0 ) {
533             RCt = XFSDirEditorDelete ( Editor, Name );
534 
535             XFSEditorDispose ( & ( Editor -> Papahen ) );
536         }
537 
538         XFSNodeRelease ( Node );
539         free ( Name );
540     }
541 
542     return 0;
543 }   /* DOKAN_delete_file_dir () */
544 
545 /************************************************************/
546 /************************************************************/
547 
548 #if USE_XFS_DOKAN_CREATEFILE == 1
549 
550 static
551 void
__PrintDisposition__(LPCWSTR FileName,DWORD CreationDisposition)552 __PrintDisposition__ ( LPCWSTR FileName, DWORD CreationDisposition )
553 {
554     WCHAR BF [ XFS_SIZE_4096 ];
555 
556     swprintf (
557             BF,
558             sizeof ( BF ) / sizeof ( WCHAR ),
559             L"Disposition [%08x][%s]:",
560             CreationDisposition ,
561             FileName
562             );
563 
564     switch ( CreationDisposition ) {
565         case CREATE_NEW :        wcscat ( BF, L" CREATE_NEW" ); break;
566         case OPEN_ALWAYS :       wcscat ( BF, L" OPEN_ALWAYS" ); break;
567         case CREATE_ALWAYS :     wcscat ( BF, L" CREATE_ALWAYS" ); break;
568         case OPEN_EXISTING :     wcscat ( BF, L" OPEN_EXISTING" ); break;
569         case TRUNCATE_EXISTING : wcscat ( BF, L" TRUNCATE_EXISTING" ); break;
570         default:                 wcscat ( BF, L" UNKNOWN" ); break;
571     }
572 
573     wLogMsg ( klogDebug, L"%s (%d)\n", BF, CreationDisposition );
574 }   /* __PrintDisposition__ () */
575 
576 static
577 void
__PrintAccessMode__(LPCWSTR FileName,DWORD AccessMode)578 __PrintAccessMode__ ( LPCWSTR FileName, DWORD AccessMode )
579 {
580     int llp, klf;
581     WCHAR BF [ XFS_SIZE_4096 ];
582 
583     swprintf ( BF, sizeof ( BF ) / sizeof ( WCHAR ), L"AccessMode [%08x][%s]:", AccessMode, FileName );
584 
585     for ( llp = 31; 0 <= llp; llp -- ) {
586         klf = 1 << llp;
587         if ( llp % 8 == 0 ) {
588             wcscat ( BF, L" " );
589         }
590 
591         if ( ( AccessMode & klf ) == klf ) {
592             wcscat ( BF, L"1" );
593         }
594         else {
595             wcscat ( BF, L"0" );
596         }
597     }
598     wLogMsg ( klogDebug, L"%s\n", BF );
599 
600     swprintf ( BF, sizeof ( BF ) / sizeof ( WCHAR ), L"AccessMode [%08xl][%s]:", AccessMode, FileName );
601     if ( ( AccessMode & FILE_READ_DATA ) == FILE_READ_DATA ) wcscat ( BF, L" FILE_READ_DATA" );
602     if ( ( AccessMode & FILE_WRITE_DATA ) == FILE_WRITE_DATA ) wcscat ( BF, L" FILE_WRITE_DATA" );
603     if ( ( AccessMode & FILE_APPEND_DATA ) == FILE_APPEND_DATA ) wcscat ( BF, L" FILE_APPEND_DATA" );
604     if ( ( AccessMode & FILE_READ_EA ) == FILE_READ_EA ) wcscat ( BF, L" FILE_READ_EA" );
605     if ( ( AccessMode & FILE_WRITE_EA ) == FILE_WRITE_EA ) wcscat ( BF, L" FILE_WRITE_EA" );
606     if ( ( AccessMode & FILE_EXECUTE ) == FILE_EXECUTE ) wcscat ( BF, L" FILE_EXECUTE" );
607     if ( ( AccessMode & FILE_DELETE_CHILD ) == FILE_DELETE_CHILD ) wcscat ( BF, L" FILE_DELETE_CHILD" );
608     if ( ( AccessMode & FILE_READ_ATTRIBUTES ) == FILE_READ_ATTRIBUTES ) wcscat ( BF, L" FILE_READ_ATTRIBUTES" );
609     if ( ( AccessMode & FILE_WRITE_ATTRIBUTES ) == FILE_WRITE_ATTRIBUTES ) wcscat ( BF, L" FILE_WRITE_ATTRIBUTES" );
610     if ( ( AccessMode & FILE_ALL_ACCESS ) == FILE_ALL_ACCESS ) wcscat ( BF, L" FILE_ALL_ACCESS" );
611     if ( ( AccessMode & READ_CONTROL ) == READ_CONTROL ) wcscat ( BF, L" READ_CONTROL" );
612     if ( ( AccessMode & DELETE ) == DELETE ) wcscat ( BF, L" DELETE" );
613 
614     wLogMsg ( klogDebug, L"%s\n", BF );
615 }   /* __PrintAccessMode__ () */
616 
617 static
618 int
_HandleForNode(const struct XFSNode * Node,PDOKAN_FILE_INFO TheFileInfo)619 _HandleForNode (
620             const struct XFSNode * Node,
621             PDOKAN_FILE_INFO TheFileInfo
622 )
623 {
624     int RetVal;
625     struct XFSHandle * Handle;
626 
627     RetVal = 0;
628 
629     if ( Node == NULL ) {
630         return ERROR_INVALID_DATA;
631     }
632 
633     if ( TheFileInfo == NULL ) {
634         RetVal = ERROR_INVALID_DATA;
635     } else {
636         if ( XFSHandleMake ( Node, & Handle ) != 0 ) {
637             RetVal = ERROR_INVALID_DATA;
638         }
639         else {
640             TheFileInfo -> Context = ( ULONG ) Handle;
641 
642             RetVal = 0;
643         }
644     }
645 
646     XFSNodeRelease ( Node );
647 
648     return RetVal;
649 }   /* _HandleForNode () */
650 
651 static
652 int
_HandleOpenExistingFileEdit(const struct XFSNode * Node,PDOKAN_FILE_INFO TheFileInfo,bool Write,bool Read)653 _HandleOpenExistingFileEdit (
654                     const struct XFSNode * Node,
655                     PDOKAN_FILE_INFO TheFileInfo,
656                     bool Write,
657                     bool Read
658 )
659 {
660     struct XFSFileEditor * Editor;
661     rc_t RCt;
662     XFSNMode Mode;
663     struct XFSHandle * Handle;
664     int RetVal;
665 
666     Editor = NULL;
667     Mode = 0;
668     Handle = NULL;
669     RCt= 0;
670     RetVal = 0;
671 
672     if ( Node == NULL ) {
673         return ERROR_INVALID_DATA;
674     }
675 
676     if ( TheFileInfo == NULL ) {
677         XFSNodeRelease ( Node );
678 
679         return ERROR_INVALID_DATA;
680     }
681 
682     if ( Write ) {
683         Mode |= kxfsWrite;
684     }
685 
686     if ( Read ) {
687         Mode |= kxfsRead;
688     }
689 
690     RCt = XFSNodeFileEditor ( Node, & Editor );
691     if ( RCt == 0 ) {
692         RCt = XFSFileEditorOpen ( Editor, Mode );
693         if ( RCt == 0 ) {
694             RCt = XFSHandleMake ( Node, & Handle );
695             if ( RCt == 0 ) {
696                 XFSHandleSet ( Handle, Editor );
697 
698                 TheFileInfo -> Context = ( ULONG ) Handle;
699             }
700         }
701     }
702 
703     if ( RCt != 0 ) {
704         if ( Editor != NULL ) {
705             XFSEditorDispose ( & ( Editor -> Papahen ) );
706         }
707     }
708 
709     XFSNodeRelease ( Node );
710 
711     if ( RCt == 0 ) {
712         RetVal = 0;
713     }
714     else {
715         if ( RCt == XFS_RC ( rcBusy ) ) {
716             RetVal = ERROR_PATH_BUSY;
717         }
718         else {
719             RetVal = ERROR_ACCESS_DENIED;
720         }
721     }
722 
723     return RetVal;
724 }   /* _HandleOpenExistingFileEdit () */
725 
726 static
727 int
_HandleCreateNewFileEdit(const struct VPath * Path,DOKAN_FILE_INFO * TheFileInfo,bool Write,bool Read)728 _HandleCreateNewFileEdit (
729                         const struct VPath * Path,
730                         DOKAN_FILE_INFO * TheFileInfo,
731                         bool Write,
732                         bool Read
733 )
734 {
735     rc_t RCt;
736     struct XFSNode * Node;
737     struct XFSDirEditor * DirEditor;
738     struct XFSHandle * Handle;
739     char * NodeName;
740     XFSNType Type;
741     XFSNMode Mode;
742 
743     RCt = 0;
744     Node = NULL;
745     DirEditor = NULL;
746     Handle = NULL;
747     NodeName = NULL;
748     Type = kxfsNotFound;
749     Mode = kxfsNone;
750 
751     if ( TheFileInfo == NULL ) {
752         return XFS_RC ( rcNull );
753     }
754 
755     TheFileInfo -> Context = 0;
756 
757     if ( Write ) { Mode |= kxfsWrite; }
758     if ( Read ) { Mode |= kxfsRead; }
759 
760     RCt = _DOKAN_get_parent_node (
761                                 Path,
762                                 TheFileInfo,
763                                 & Node,
764                                 & Type,
765                                 & NodeName
766                                 );
767     if ( RCt == 0 ) {
768             /* I do not check if node exists or not,
769              * cuz Bogus node will fail on retrieving
770              * DirEditor
771              */
772         RCt = XFSNodeDirEditor ( Node, & DirEditor );
773         if ( RCt == 0 ) {
774             RCt = XFSDirEditorCreate (
775                                     DirEditor,
776                                     NodeName,
777                                     Mode,
778                                     & Handle
779                                     );
780             if ( RCt == 0 ) {
781                 TheFileInfo -> Context = ( ULONG ) Handle;
782             }
783         }
784 
785         XFSNodeRelease ( Node );
786         free ( NodeName );
787     }
788 
789     if ( RCt != 0 ) {
790         if ( DirEditor != NULL ) {
791             XFSEditorDispose ( & ( DirEditor -> Papahen ) );
792         }
793     }
794 
795     return RCt == 0 ? 0 : ERROR_ACCESS_DENIED;
796 }   /* _HandleCreateNewFileEdit () */
797 
798 /*))
799  ((     Really strange method, long and stupid.
800   ))
801  ((*/
802 static
803 int DOKAN_CALLBACK
XFS_DOKAN_CreateFile(LPCWSTR FileName,DWORD AccessMode,DWORD ShareMode,DWORD CreationDisposition,DWORD FlagsAndAttributes,PDOKAN_FILE_INFO TheFileInfo)804 XFS_DOKAN_CreateFile (
805             LPCWSTR FileName,
806             DWORD AccessMode,
807             DWORD ShareMode,
808             DWORD CreationDisposition,
809             DWORD FlagsAndAttributes,
810             PDOKAN_FILE_INFO TheFileInfo
811 )
812 {
813     rc_t RCt;
814     int RetValue;
815     struct XFSNode * Node;
816     XFSNType Type;
817     bool Read, Write;
818     VPath * Path;
819 
820     RCt = 0;
821     RetValue = 0;
822     Node = NULL;
823     Type = kxfsBadPath;
824     Read = Write = false;
825     Path = NULL;
826 
827 #ifdef I_AM_AN_IMBECILE
828 {
829 if ( wcsstr ( FileName, klogDebug, L"CVS" ) != NULL
830     || wcsstr ( FileName, klogDebug, L".svn" ) != NULL
831     || wcsstr ( FileName, klogDebug, L"desktop.ini" ) != NULL
832     || wcsstr ( FileName, klogDebug, L".gs" ) != NULL
833     || wcsstr ( FileName, klogDebug, L"Authorun.inf" ) != NULL
834     ) {
835 wLogMsg ( klogDebug, L" CREATE File [%s][VYHUHOL]\n", FileName );
836     return ERROR_PATH_NOT_FOUND * - 1;
837 }
838 }
839 #endif /* I_AM_AN_IMBECILE */
840 
841 wLogMsg ( klogDebug, L" CREATE File [%s][I=0x%p][H=0x%p]\n", FileName, TheFileInfo, (void * ) TheFileInfo -> Context );
842 
843     if ( FileName == NULL || TheFileInfo == NULL ) {
844         return 1 * - 1; /* TODO !!! */
845     }
846     TheFileInfo -> Context = 0L;
847 
848 __PrintAccessMode__ ( FileName, AccessMode );
849 __PrintDisposition__ ( FileName, CreationDisposition );
850 
851         /* Awkward attempt to reduce filesystem abuse from
852             CVS agen and all other services, like gzip
853          */
854 
855         /* First we should know what kind of file object do we have
856          */
857     RCt = _DOKAN_get_path_and_node (
858                                 FileName,
859                                 TheFileInfo,
860                                 & Path,
861                                 & Node,
862                                 & Type
863                                 );
864         /* Something really wrong did happen
865          */
866     if ( RCt != 0 ) {
867         return 1 * - 1;
868     }
869 
870         /* Reading/Writing file
871          */
872     Read = ( AccessMode & FILE_READ_DATA ) == FILE_READ_DATA;
873     Write = ( AccessMode & FILE_WRITE_DATA ) == FILE_WRITE_DATA;
874 
875         /* We need only existing file
876          */
877     if ( Type == kxfsNotFound && CreationDisposition == OPEN_EXISTING ) {
878         TheFileInfo -> Context = 0L;
879 
880         XFSNodeRelease ( Node );
881         VPathRelease ( Path );
882 
883         RetValue = ERROR_FILE_NOT_FOUND;
884 
885 wLogMsg ( klogDebug, L"     RETURNS [%s][RC=%d][H=NULL][I=0x%p][%d]\n", FileName, RetValue, TheFileInfo, __LINE__ );
886         return RetValue * - 1;
887     }
888 
889         /* We are trying to open new file
890          */
891     if ( Type == kxfsNotFound && CreationDisposition != OPEN_EXISTING
892         && ( Read || Write )
893     ) {
894         RetValue = _HandleCreateNewFileEdit ( Path, TheFileInfo, Write, Read );
895 
896         VPathRelease ( Path );
897 wLogMsg ( klogDebug, L"     RETURNS [%s][RC=%d][H=0x%p][I=0x%p][%d]\n", FileName, RetValue, ( void * ) ( TheFileInfo -> Context ), TheFileInfo, __LINE__ );
898         return RetValue * - 1;
899     }
900 
901         /* Reading directory content
902          */
903     if ( Type == kxfsDir ) {
904             /* Reading Directory Listing
905              */
906         if ( CreationDisposition == OPEN_EXISTING && Read ) {
907             RetValue = _HandleForNode ( Node, TheFileInfo );
908 
909             VPathRelease ( Path );
910 wLogMsg ( klogDebug, L"     RETURNS [%s][RC=%d][H=0x%p][I=0x%p][%d]\n", FileName, RetValue, ( void * ) ( TheFileInfo -> Context ), TheFileInfo, __LINE__ );
911             return RetValue * - 1;
912         }
913     }
914 
915         /* Reading/Writin existing file
916          */
917     if ( ( Read || Write ) && Type != kxfsDir &&  Type != kxfsNotFound && Type != kxfsBadPath ) {
918         RetValue = _HandleOpenExistingFileEdit ( Node, TheFileInfo, Write, Read );
919 
920         VPathRelease ( Path );
921 wLogMsg ( klogDebug, L"     RETURNS [%s][RC=%d][H=0x%p][I=0x%p][%d]\n", FileName, RetValue, ( void * ) ( TheFileInfo -> Context ), TheFileInfo, __LINE__ );
922         return RetValue * - 1;
923     }
924 
925         /* Reading/Writin file attributes
926          */
927     if ( ( AccessMode & FILE_GENERIC_READ ) == FILE_WRITE_ATTRIBUTES && CreationDisposition == OPEN_EXISTING ) {
928         RetValue = _HandleOpenExistingFileEdit ( Node, TheFileInfo, Write, Read );
929 
930         VPathRelease ( Path );
931 wLogMsg ( klogDebug, L"     RETURNS [%s][RC=%d][H=0x%p][I=0x%p][%d]\n", FileName, RetValue, ( void * ) ( TheFileInfo -> Context ), TheFileInfo, __LINE__ );
932         return RetValue * - 1;
933     }
934 
935         /* Security read ... SACL DACL
936          */
937     if ( ( AccessMode & READ_CONTROL ) == READ_CONTROL
938             && ( ! Read )
939             && ( ! Write )
940     ) {
941         RetValue = _HandleForNode ( Node, TheFileInfo );
942 
943         VPathRelease ( Path );
944 wLogMsg ( klogDebug, L"     RETURNS [%s][RC=%d][H=0x%p][I=0x%p][%d]\n", FileName, RetValue, ( void * ) ( TheFileInfo -> Context ), TheFileInfo, __LINE__ );
945         return RetValue * - 1;
946     }
947 
948         /* We are reading file attributes, and all other requests
949          */
950     if ( ( AccessMode & FILE_GENERIC_READ ) == FILE_READ_ATTRIBUTES ) {
951         RetValue = _HandleForNode ( Node, TheFileInfo );
952 
953         VPathRelease ( Path );
954 wLogMsg ( klogDebug, L"     RETURNS [%s][RC=%d][H=0x%p][I=0x%p][%d]\n", FileName, RetValue, ( void * ) ( TheFileInfo -> Context ), TheFileInfo, __LINE__ );
955         return RetValue * - 1;
956     }
957 
958         /* We are deleting file ...
959          */
960     if ( ( AccessMode & DELETE ) == DELETE ) {
961         RetValue = _HandleForNode ( Node, TheFileInfo );
962 
963         VPathRelease ( Path );
964 wLogMsg ( klogDebug, L"     RETURNS [%s][RC=%d][H=0x%p][I=0x%p][%d]\n", FileName, RetValue, ( void * ) ( TheFileInfo -> Context ), TheFileInfo, __LINE__ );
965         return RetValue * - 1;
966     }
967 
968     /* Something else is here */
969     RetValue = 1; // TODO
970 
971     XFSNodeRelease ( Node );
972     VPathRelease ( Path );
973 
974 wLogMsg ( klogDebug, L"     RETURNS [%s][RC=%d][I=0x%p][%d]\n", FileName, RetValue, TheFileInfo, __LINE__ );
975 
976     return RetValue * - 1;
977 }   /* CreateFile() */
978 
979 #endif /* USE_XFS_DOKAN_CREATEFILE == 1 */
980 
981 /************************************************************/
982 /************************************************************/
983 
984 #if USE_XFS_DOKAN_OPENDIRECTORY == 1
985 
986 static
987 int DOKAN_CALLBACK
XFS_DOKAN_OpenDirectory(LPCWSTR FileName,PDOKAN_FILE_INFO TheFileInfo)988 XFS_DOKAN_OpenDirectory (
989             LPCWSTR FileName,
990             PDOKAN_FILE_INFO TheFileInfo
991 )
992 {
993     rc_t RCt;
994     const struct XFSNode * TheNode;
995     XFSNType Type;
996     int RetVal;
997 
998     RCt = 0;
999     TheNode = NULL;
1000     Type = kxfsNotFound;
1001     RetVal = 0;
1002 
1003 //TT wLogMsg ( klogDebug, L" OPEN directory [%s][I=0x%p][C=0x%p]\n", FileName, TheFileInfo, (void * ) TheFileInfo -> Context );
1004 
1005     if ( FileName == NULL || TheFileInfo == NULL ) {
1006         return 1 * - 1;
1007     }
1008     TheFileInfo -> Context = 0L;
1009 
1010     RCt = _DOKAN_get_path_and_node (
1011                                 FileName,
1012                                 TheFileInfo,
1013                                 NULL,
1014                                 & TheNode,
1015                                 & Type
1016                                 );
1017     if ( RCt == 0 ) {
1018         if ( Type == kxfsDir ) {
1019             RetVal = _HandleForNode ( TheNode, TheFileInfo );
1020         }
1021         else {
1022             RetVal = ERROR_PATH_NOT_FOUND;
1023 
1024             XFSNodeRelease ( TheNode );
1025         }
1026     }
1027     else {
1028         RetVal = ERROR_INVALID_DATA;
1029     }
1030 
1031 //TT wLogMsg ( klogDebug, L" OPEN directory,cont [%s][I=0x%p][C=0x%p][RC=%lu]\n", FileName, TheFileInfo, (void * ) TheFileInfo -> Context, RetVal );
1032     return RetVal * - 1;
1033 }   /* OpenDirectory() */
1034 
1035 #endif /* USE_XFS_DOKAN_OPENDIRECTORY == 1 */
1036 
1037 /************************************************************/
1038 /************************************************************/
1039 
1040 #if USE_XFS_DOKAN_CREATEDIRECTORY == 1
1041 
1042 static
1043 int DOKAN_CALLBACK
XFS_DOKAN_CreateDirectory(LPCWSTR FileName,PDOKAN_FILE_INFO TheFileInfo)1044 XFS_DOKAN_CreateDirectory (
1045             LPCWSTR FileName,
1046             PDOKAN_FILE_INFO TheFileInfo
1047 )
1048 {
1049     rc_t RCt;
1050     struct XFSNode * Node;
1051     char * Name;
1052     struct XFSDirEditor * Editor;
1053 
1054     RCt = 0;
1055     Node = NULL;
1056     Name = NULL;
1057     Editor = NULL;
1058 
1059 //TT wLogMsg ( klogDebug, L"CREATE Directory [%s][FI=0x%p][H=0x%p]\n", FileName, TheFileInfo, (void * ) TheFileInfo -> Context );
1060 
1061     RCt = _DOKAN_get_parent_node_from_char (
1062                                         FileName,
1063                                         TheFileInfo,
1064                                         & Node,
1065                                         NULL,
1066                                         & Name
1067                                         );
1068     if ( RCt == 0 ) {
1069         RCt = XFSNodeDirEditor ( Node, & Editor );
1070         if ( RCt == 0 ) {
1071             RCt = XFSDirEditorCreateDir ( Editor, Name );
1072 
1073             XFSEditorDispose ( & ( Editor -> Papahen ) );
1074         }
1075 
1076         XFSNodeRelease ( Node );
1077         free ( Name );
1078     }
1079 
1080 //TT wLogMsg ( klogDebug, L"   CREATE Directory [%s][FI=0x%p][H=0x%p][RC=%d]\n", FileName, TheFileInfo, (void * ) TheFileInfo -> Context, RCt );
1081 
1082     return RCt == 0 ? 0 : - 1;
1083 }   /* CreateDirectory() */
1084 
1085 #endif /* USE_XFS_DOKAN_CREATEDIRECTORY == 1 */
1086 
1087 /************************************************************/
1088 /************************************************************/
1089 
1090 #if USE_XFS_DOKAN_CLEANUP == 1
1091 
1092     /*))
1093      // We should remember, all files are closing and deleting here
1094     ((*/
1095 static
1096 int DOKAN_CALLBACK
XFS_DOKAN_Cleanup(LPCWSTR FileName,PDOKAN_FILE_INFO TheFileInfo)1097 XFS_DOKAN_Cleanup (
1098             LPCWSTR FileName,
1099             PDOKAN_FILE_INFO TheFileInfo
1100 )
1101 {
1102     struct XFSHandle * Handle;
1103     struct XFSFileEditor * Editor;
1104 
1105     if ( FileName == NULL || TheFileInfo == NULL ) {
1106         return ERROR_INVALID_DATA * - 1;
1107     }
1108 
1109     Handle = ( struct XFSHandle * ) TheFileInfo -> Context;
1110 
1111     if ( Handle == NULL )  {
1112         return ERROR_INVALID_HANDLE * - 1;
1113     }
1114 
1115 //TT wLogMsg ( klogDebug, L" CLEANUP File [%s][I=0x%p][H=0x%p][Del=%d]\n", FileName, TheFileInfo, Handle, TheFileInfo -> DeleteOnClose );
1116 
1117     TheFileInfo -> Context = 0L;
1118 
1119     Editor = ( struct XFSFileEditor * ) XFSHandleGet ( Handle );
1120     if ( Editor != NULL ) {
1121         /*)) I believe that if ... if here is non-NULL handle,
1122          //  it could be only handle for KFile, will change if ...
1123         ((*/
1124         XFSFileEditorClose ( Editor );
1125         XFSEditorDispose ( & ( Editor -> Papahen ) );
1126         XFSHandleSet ( Handle, NULL );
1127     }
1128     XFSHandleRelease ( Handle );
1129 
1130     if ( TheFileInfo -> DeleteOnClose ) {
1131 //TT wLogMsg ( klogDebug, L"     CLEANUP File : DELETE ON CLOSE [%s][I=0x%p][H=0x%p]\n", FileName, TheFileInfo, Handle );
1132         _DOKAN_delete_file_dir ( FileName, TheFileInfo );
1133 
1134     }
1135 
1136     return 0;
1137 }   /* Cleanup() */
1138 
1139 #endif /* USE_XFS_DOKAN_CLEANUP == 1 */
1140 
1141 /************************************************************/
1142 /************************************************************/
1143 
1144 #if USE_XFS_DOKAN_CLOSEFILE == 1
1145 
1146 static
1147 int DOKAN_CALLBACK
XFS_DOKAN_CloseFile(LPCWSTR FileName,PDOKAN_FILE_INFO TheFileInfo)1148 XFS_DOKAN_CloseFile (
1149             LPCWSTR FileName,
1150             PDOKAN_FILE_INFO TheFileInfo
1151 )
1152 {
1153     rc_t RCt;
1154     struct XFSHandle * Handle;
1155     struct XFSFileEditor * Editor;
1156 
1157     RCt = 0; Handle = NULL;
1158     Editor = NULL;
1159 
1160     if ( FileName == NULL || TheFileInfo == NULL ) {
1161         return 1 * - 1;
1162     }
1163 
1164     Handle = ( struct XFSHandle * ) TheFileInfo -> Context;
1165 
1166 //TT wLogMsg ( klogDebug, L" CLOSE File [%s][I=0x%p][H=0x%p]\n", FileName, TheFileInfo, Handle );
1167 
1168     if ( Handle == NULL )  {
1169         /* That's is OK */
1170         return 0;
1171     }
1172 
1173 //TT wLogMsg ( klogDebug, L" CLOSE File: Cleanup method wasn't called [%s][E=0x%p]\n", FileName, Handle );
1174 
1175     TheFileInfo -> Context = 0L;
1176 
1177     Editor = ( struct XFSFileEditor * ) XFSHandleGet ( Handle );
1178     if ( Editor != NULL ) {
1179 
1180         XFSFileEditorClose ( Editor );
1181         XFSEditorDispose ( & ( Editor -> Papahen ) );
1182         XFSHandleSet ( Handle, NULL );
1183     }
1184     XFSHandleRelease ( Handle );
1185 
1186     if ( TheFileInfo -> DeleteOnClose ) {
1187         RCt = _DOKAN_delete_file_dir ( FileName, TheFileInfo );
1188     }
1189 
1190 //TT wLogMsg ( klogDebug, L" CLOSE File,cont [%s][I=0x%p][H=0x%p][RC=%d]\n", FileName, TheFileInfo, Handle, RCt );
1191 
1192     return ( RCt == 0 ? 0 : ERROR_INVALID_DATA ) * - 1;
1193 }   /* CloseFile() */
1194 
1195 #endif /* USE_XFS_DOKAN_CLOSEFILE == 1 */
1196 
1197 /************************************************************/
1198 /************************************************************/
1199 
1200 #if USE_XFS_DOKAN_READFILE == 1
1201 
1202 static
1203 int DOKAN_CALLBACK
XFS_DOKAN_ReadFile(LPCWSTR FileName,LPVOID Buffer,DWORD NumberOfBytesToRead,LPDWORD NumberOfBytesRead,LONGLONG Offset,PDOKAN_FILE_INFO TheFileInfo)1204 XFS_DOKAN_ReadFile (
1205             LPCWSTR FileName,
1206             LPVOID Buffer,
1207             DWORD NumberOfBytesToRead,
1208             LPDWORD NumberOfBytesRead,
1209             LONGLONG Offset,
1210             PDOKAN_FILE_INFO TheFileInfo
1211 )
1212 {
1213     struct XFSHandle * Handle;
1214     bool LocallyOpened;
1215     struct XFSFileEditor * Editor;
1216     const struct XFSNode * Node;
1217     rc_t RCt;
1218     int RetVal;
1219     size_t n2r, nRd;
1220 
1221     Handle = NULL;
1222     LocallyOpened = false;
1223     Editor = NULL;
1224     Node = NULL;
1225     RCt = 0;
1226     RetVal = 0;
1227     n2r = nRd = 0;
1228 
1229     if ( FileName == NULL || TheFileInfo == NULL ) {
1230         return 1 * - 1; /* TODO !!! */
1231     }
1232 
1233 //TT wLogMsg ( klogDebug, L" READ File [%s][I=0x%p][H=0x%p] - [N=%lu][O=%lu]\n", FileName, TheFileInfo, (void * ) TheFileInfo -> Context, NumberOfBytesToRead, Offset );
1234 
1235     Handle = ( struct XFSHandle * ) TheFileInfo -> Context;
1236     n2r = ( size_t ) NumberOfBytesToRead;
1237 
1238         /*)) That's could happen, and we need to reopen fiel
1239          ((*/
1240     if ( Handle == NULL ) {
1241 //TT wLogMsg ( klogDebug, L" READ File [%s][I=0x%p][H=0x%p] - REOPENING!\n", FileName, TheFileInfo, (void * ) TheFileInfo -> Context );
1242 
1243             /*)) First we are looking for a node
1244              ((*/
1245 
1246         RCt = _DOKAN_get_path_and_node (
1247                                     FileName,
1248                                     TheFileInfo,
1249                                     NULL,   /* VPath, no need */
1250                                     & Node,
1251                                     NULL    /* NodeType */
1252                                     );
1253         if ( RCt == 0 ) {
1254             RCt = XFSNodeFileEditor ( Node, & Editor );
1255             if ( RCt == 0 ) {
1256                 RCt = XFSFileEditorOpen ( Editor, kxfsRead );
1257                 if ( RCt == 0 ) {
1258                     LocallyOpened = true;
1259                 }
1260             }
1261         }
1262     }
1263     else {
1264         Editor = ( struct XFSFileEditor * ) XFSHandleGet ( Handle );
1265         if ( Editor == NULL ) {
1266             RCt = XFS_RC ( rcInvalid );
1267         }
1268         else {
1269             Node = XFSHandleNode ( Handle );
1270             if ( Node == NULL ) {
1271                 RCt = XFS_RC ( rcInvalid );
1272             }
1273         }
1274     }
1275 
1276     if ( RCt == 0 ) {
1277         /*) Here we are reading info
1278          (*/
1279         RCt = XFSFileEditorRead (
1280                             Editor,
1281                             Offset,
1282                             Buffer,
1283                             n2r,
1284                             & nRd
1285                             );
1286         * NumberOfBytesRead = nRd;
1287     }
1288 
1289     if ( LocallyOpened ) {
1290 //TT wLogMsg ( klogDebug, L" READ File [%s][I=0x%p][H=0x%p] - RECLOSING!\n", FileName, TheFileInfo, (void * ) TheFileInfo -> Context );
1291         if ( Editor != NULL ) {
1292             XFSFileEditorClose ( Editor );
1293 
1294             XFSEditorDispose ( & ( Editor -> Papahen ) );
1295         }
1296 
1297         Editor = NULL;
1298 
1299         if ( Node != NULL ) {
1300             XFSNodeRelease ( Node );
1301 
1302             Node = NULL;
1303         }
1304     }
1305 
1306     RetVal =  RCt == 0 ? 0 : ERROR_INVALID_DATA;
1307 
1308 //TT wLogMsg ( klogDebug, L" READ File,cont [%s][I=0x%p][H=0x%p] - [Read=%lu][RC=%d]!\n", FileName, TheFileInfo, (void * ) TheFileInfo -> Context, * NumberOfBytesRead, RetVal );
1309 
1310     return RetVal * - 1;
1311 }   /* ReadFile() */
1312 
1313 #endif /* USE_XFS_DOKAN_READFILE == 1 */
1314 
1315 /************************************************************/
1316 /************************************************************/
1317 
1318 #if USE_XFS_DOKAN_WRITEFILE == 1
1319 
1320 static
1321 int DOKAN_CALLBACK
XFS_DOKAN_WriteFile(LPCWSTR FileName,LPCVOID Buffer,DWORD NumBytesWrite,LPDWORD NumBytesWritten,LONGLONG Offset,PDOKAN_FILE_INFO TheFileInfo)1322 XFS_DOKAN_WriteFile (
1323             LPCWSTR FileName,
1324             LPCVOID Buffer,
1325             DWORD NumBytesWrite,
1326             LPDWORD NumBytesWritten,
1327             LONGLONG Offset,
1328             PDOKAN_FILE_INFO TheFileInfo
1329 )
1330 {
1331     struct XFSHandle * Handle;
1332     bool LocallyOpened;
1333     struct XFSFileEditor * Editor;
1334     const struct XFSNode * Node;
1335     rc_t RCt;
1336     int RetVal;
1337     size_t n2w, nWr;
1338 
1339     Handle = NULL;
1340     LocallyOpened = false;
1341     Editor = NULL;
1342     Node = NULL;
1343     RCt = 0;
1344     RetVal = 0;
1345     n2w = nWr = 0;
1346 
1347     if ( FileName == NULL || TheFileInfo == NULL ) {
1348         return 1 * - 1; /* TODO !!! */
1349     }
1350 
1351 //TT wLogMsg ( klogDebug, L" WRITE File [%s][I=0x%p][H=0x%p] - [O=%d][N=%d]\n", FileName, TheFileInfo, (void * ) TheFileInfo -> Context, (int)Offset, (int)NumBytesWrite );
1352 
1353     n2w = ( size_t ) NumBytesWrite;
1354 
1355     Handle = ( struct XFSHandle * ) TheFileInfo -> Context;
1356 
1357         /*)) That's could happen, and we need to reopen fiel
1358          ((*/
1359     if ( Handle == NULL ) {
1360 //TT wLogMsg ( klogDebug, L" WRITE File [%s][I=0x%p][H=0x%p] - REOPENING!\n", FileName, TheFileInfo, (void * ) TheFileInfo -> Context );
1361 
1362             /*)) First we are looking for a node
1363              ((*/
1364 
1365         RCt = _DOKAN_get_path_and_node (
1366                                     FileName,
1367                                     TheFileInfo,
1368                                     NULL,   /* VPath, no need */
1369                                     & Node,
1370                                     NULL    /* NodeType */
1371                                     );
1372         if ( RCt == 0 ) {
1373             RCt = XFSNodeFileEditor ( Node, & Editor );
1374             if ( RCt == 0 ) {
1375                 RCt = XFSFileEditorOpen ( Editor, kxfsWrite );
1376                 if ( RCt == 0 ) {
1377                     LocallyOpened = true;
1378                 }
1379             }
1380         }
1381     }
1382     else {
1383         Editor = ( struct XFSFileEditor * ) XFSHandleGet ( Handle );
1384         if ( Editor == NULL ) {
1385             RCt = XFS_RC ( rcInvalid );
1386         }
1387         else {
1388             Node = XFSHandleNode ( Handle );
1389             if ( Node == NULL ) {
1390                 RCt = XFS_RC ( rcInvalid );
1391             }
1392         }
1393     }
1394 
1395     if ( RCt == 0 ) {
1396         /*) Here we are reading info
1397          (*/
1398         RCt = XFSFileEditorWrite (
1399                             Editor,
1400                             Offset,
1401                             Buffer,
1402                             n2w,
1403                             & nWr
1404                             );
1405         * NumBytesWritten = nWr;
1406     }
1407 
1408     if ( LocallyOpened ) {
1409 //TT wLogMsg ( klogDebug, L" WRITE File [%s][I=0x%p][H=0x%p] - RECLOSING!\n", FileName, TheFileInfo, (void * ) TheFileInfo -> Context );
1410         if ( Editor != NULL ) {
1411             XFSFileEditorClose ( Editor );
1412 
1413             XFSEditorDispose ( & ( Editor -> Papahen ) );
1414         }
1415 
1416         Editor = NULL;
1417 
1418         if ( Node != NULL ) {
1419             XFSNodeRelease ( Node );
1420 
1421             Node = NULL;
1422         }
1423     }
1424 
1425     RetVal =  RCt == 0 ? 0 : ERROR_INVALID_DATA;
1426 
1427 //TT wLogMsg ( klogDebug, L" WRITE File,cont [%s][I=0x%p][H=0x%p] - [Wrote=%d][RC=%d]!\n", FileName, TheFileInfo, (void * ) TheFileInfo -> Context, (int)* NumBytesWritten, (int)RetVal );
1428 
1429     return RetVal * - 1;
1430 }   /* WriteFile() */
1431 
1432 #endif /* USE_XFS_DOKAN_WRITEFILE == 1 */
1433 
1434 /************************************************************/
1435 /************************************************************/
1436 
1437 #if USE_XFS_DOKAN_FLUSHFILEBUFFERS == 1
1438 
1439 
1440 static
1441 int DOKAN_CALLBACK
XFS_DOKAN_FlushFileBuffers(LPCWSTR FileName,PDOKAN_FILE_INFO TheFileInfo)1442 XFS_DOKAN_FlushFileBuffers (
1443             LPCWSTR FileName,
1444             PDOKAN_FILE_INFO TheFileInfo
1445 )
1446 {
1447 //TT wLogMsg ( klogDebug, L"FLUSHFILEBUFFERS(DOKAN): [%s][FI=0x%p]\n", FileName, TheFileInfo );
1448     return - 0;
1449 }   /* FlushFileBuffers() */
1450 
1451 #endif /* USE_XFS_DOKAN_FLUSHFILEBUFFERS == 1 */
1452 
1453 /************************************************************/
1454 /************************************************************/
1455 
1456 #if USE_XFS_DOKAN_GETFILEINFORMATION == 1
1457 
1458 /*))
1459  // TODO : introduce global handle class, which will represent all
1460 ((*/
1461 
1462 static
1463 int
_Read_HANDLE_FILE_INFORMATION(const struct XFSHandle * Handle,LPBY_HANDLE_FILE_INFORMATION HandleFileInfo)1464 _Read_HANDLE_FILE_INFORMATION (
1465                         const struct XFSHandle * Handle,
1466                         LPBY_HANDLE_FILE_INFORMATION HandleFileInfo
1467 )
1468 {
1469     rc_t RCt;
1470     int RetVal;
1471     const struct XFSNode * Node;
1472     struct XFSAttrEditor * Editor;
1473     struct XFSFileEditor * FileEditor;
1474     struct XFSPerm * Perm;
1475     const char * PermStr;
1476     XFSNType Type;
1477     ULONG64 Time;
1478     KTime_t TheTime;
1479     DWORD TimeHigh, TimeLow;
1480     LARGE_INTEGER FileSize;
1481     uint64_t Size;
1482 
1483     RCt = 0;
1484     RetVal = 0;
1485     Node = NULL;
1486     Editor = NULL;
1487     Perm = NULL;
1488     PermStr = NULL;
1489     Type = kxfsNotFound;
1490 
1491     if ( Handle == NULL || HandleFileInfo == NULL ) {
1492         return 1;
1493     }
1494 
1495     Node = XFSHandleNode ( Handle );
1496     if ( Node == NULL ) {
1497         return 1;
1498     }
1499 
1500     RCt = XFSNodeAttrEditor ( Node, & Editor );
1501     if ( RCt != 0 || Editor == NULL ) {
1502         return 1;
1503     }
1504 
1505     while ( true ) {
1506         ZeroMemory (
1507                 HandleFileInfo,
1508                 sizeof ( BY_HANDLE_FILE_INFORMATION )
1509                 );
1510 
1511             /* File Attributes */
1512         if ( XFSAttrEditorType ( Editor, & Type ) != 0 ) {
1513             RetVal = 1;
1514             break;
1515         }
1516         HandleFileInfo -> dwFileAttributes
1517                                         = FILE_ATTRIBUTE_NORMAL;
1518         switch ( Type ) {
1519             case kxfsFile:
1520                 break;
1521             case kxfsDir:
1522                 HandleFileInfo -> dwFileAttributes
1523                                         |= FILE_ATTRIBUTE_DIRECTORY;
1524                 break;
1525             case kxfsLink:
1526             default:
1527                 HandleFileInfo -> dwFileAttributes
1528                                         = INVALID_FILE_ATTRIBUTES;
1529                 break;
1530         }
1531 
1532         if ( HandleFileInfo -> dwFileAttributes != INVALID_FILE_ATTRIBUTES && Type != kxfsDir ) {
1533 /* ### Check permissions */
1534             if ( XFSAttrEditorPermissions ( Editor, & PermStr ) == 0 ) {
1535                 if ( XFSPermMake ( PermStr, & Perm ) == 0 ) {
1536                     if ( XFSPermAuth ( Perm, kxfsUser ) != NULL ) {
1537                         if ( ! XFSAuthCanRead (
1538                                          XFSPermAuth ( Perm, kxfsUser )
1539                                          ) ) {
1540                             HandleFileInfo -> dwFileAttributes
1541                                             |= FILE_ATTRIBUTE_READONLY;
1542                         }
1543                     }
1544                     free ( Perm );
1545                 }
1546             }
1547         }
1548 
1549             /* Times */
1550         if ( XFSAttrEditorDate ( Editor, & TheTime ) != 0 ) {
1551             RetVal = 1;
1552             break;
1553         }
1554         Time = ( TheTime * 10000000 ) + 116444736000000000;;
1555         TimeLow = ( DWORD ) Time;
1556         TimeHigh = Time >> 32;
1557         HandleFileInfo -> ftCreationTime.dwLowDateTime = TimeLow;
1558         HandleFileInfo -> ftCreationTime.dwHighDateTime = TimeHigh;
1559         HandleFileInfo -> ftLastAccessTime.dwLowDateTime = TimeLow;
1560         HandleFileInfo -> ftLastAccessTime.dwHighDateTime = TimeHigh;
1561         HandleFileInfo -> ftLastWriteTime.dwLowDateTime = TimeLow;
1562         HandleFileInfo -> ftLastWriteTime.dwHighDateTime = TimeHigh;
1563 
1564             /* Sizes: set default value and try to get some */
1565         FileSize.QuadPart = 0;
1566         HandleFileInfo -> nFileSizeHigh = FileSize.HighPart;
1567         HandleFileInfo -> nFileSizeLow = FileSize.LowPart;
1568 
1569         FileEditor = ( struct XFSFileEditor * ) XFSHandleGet ( Handle );
1570         if ( FileEditor == NULL ) {
1571             RCt = XFSNodeFileEditor ( Node, & FileEditor );
1572             if ( RCt == 0 ) {
1573                 if ( FileEditor != NULL ) {
1574                     if ( XFSFileEditorSize ( FileEditor, & Size ) == 0 ) {
1575                         FileSize.QuadPart = Size;
1576                         HandleFileInfo -> nFileSizeHigh = FileSize.HighPart;
1577                         HandleFileInfo -> nFileSizeLow = FileSize.LowPart;
1578                     }
1579 
1580                     XFSEditorDispose ( & ( FileEditor -> Papahen ) );
1581                 }
1582             }
1583         } else {
1584             if ( XFSFileEditorSize ( FileEditor, & Size ) == 0 ) {
1585                 FileSize.QuadPart = Size;
1586                 HandleFileInfo -> nFileSizeHigh = FileSize.HighPart;
1587                 HandleFileInfo -> nFileSizeLow = FileSize.LowPart;
1588             }
1589         }
1590 
1591         break;
1592     }
1593 
1594     XFSEditorDispose ( & ( Editor -> Papahen ) );
1595 
1596     return RetVal;
1597 }   /* _Read_HANDLE_FILE_INFORMATION () */
1598 
1599 static
1600 int DOKAN_CALLBACK
XFS_DOKAN_GetFileInformation(LPCWSTR FileName,LPBY_HANDLE_FILE_INFORMATION HandleFileInfo,PDOKAN_FILE_INFO FileInfo)1601 XFS_DOKAN_GetFileInformation (
1602             LPCWSTR FileName,
1603             LPBY_HANDLE_FILE_INFORMATION HandleFileInfo,
1604             PDOKAN_FILE_INFO FileInfo
1605 )
1606 {
1607     struct XFSHandle * Handle;
1608     int RetValue;
1609 
1610     RetValue = 0;
1611     Handle = NULL;
1612 
1613 //TT wLogMsg ( klogDebug, L" INFO file [%s][I=0x%p][H=0x%p]\n", FileName, FileInfo, (void * ) FileInfo -> Context );
1614 
1615     if ( FileName == NULL || HandleFileInfo == NULL || FileInfo == NULL ) {
1616         return ERROR_INVALID_DATA * - 1;
1617     }
1618 
1619     Handle = ( struct XFSHandle * ) FileInfo -> Context;
1620 
1621     if ( Handle == NULL )  {
1622         return ERROR_INVALID_HANDLE * - 1;
1623     }
1624 
1625     RetValue = _Read_HANDLE_FILE_INFORMATION ( Handle, HandleFileInfo );
1626 
1627 //TT wLogMsg ( klogDebug, L" INFO File,cont [%s][0x%p][RV=%d]\n", FileName, FileInfo, RetValue );
1628 
1629     return RetValue * - 1;
1630 }   /* GetFileInformation() */
1631 
1632 #endif /* USE_XFS_DOKAN_GETFILEINFORMATION == 1 */
1633 
1634 /************************************************************/
1635 /************************************************************/
1636 
1637 #if USE_XFS_DOKAN_FINDFILES == 1
1638 
1639 static
1640 rc_t CC
_Read_PWIN32_FIND_DATA(const struct XFSNode * Node,LPWIN32_FIND_DATAW FindData)1641 _Read_PWIN32_FIND_DATA (
1642                 const struct XFSNode * Node,
1643                 LPWIN32_FIND_DATAW FindData
1644 )
1645 {
1646     rc_t RCt;
1647     struct XFSAttrEditor * Editor;
1648     struct XFSFileEditor * FileEditor;
1649     struct XFSPerm * Perm;
1650     const char * PermStr;
1651     ULONG64 Time;
1652     XFSNType Type;
1653     KTime_t TheTime;
1654     DWORD TimeHigh, TimeLow;
1655     LARGE_INTEGER FileSize;
1656     uint64_t Size;
1657     size_t CopyNum;
1658 
1659     RCt = 0;
1660     Editor = NULL;
1661     Perm = NULL;
1662     PermStr = NULL;
1663     Type = kxfsNotFound;
1664     CopyNum = 0;
1665 
1666     if ( Node == NULL || FindData == NULL ) {
1667         return XFS_RC ( rcNull );
1668     }
1669 
1670     ZeroMemory ( FindData, sizeof ( WIN32_FIND_DATAW ) );
1671 
1672 
1673     RCt = XFSNodeAttrEditor ( Node, & Editor );
1674     if ( RCt != 0 || Editor == NULL ) {
1675         return XFS_RC ( rcInvalid );
1676     }
1677 
1678     if ( XFSAttrEditorType ( Editor, & Type ) != 0 ) {
1679         XFSEditorDispose ( & ( Editor -> Papahen ) );
1680 
1681         return XFS_RC ( rcInvalid );
1682     }
1683 
1684     FindData -> dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
1685 
1686     switch ( Type ) {
1687         case kxfsFile:
1688             break;
1689         case kxfsDir:
1690             FindData -> dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
1691             break;
1692         case kxfsLink:
1693         default:
1694             FindData -> dwFileAttributes = INVALID_FILE_ATTRIBUTES;
1695             break;
1696     }
1697 
1698     if ( FindData -> dwFileAttributes != INVALID_FILE_ATTRIBUTES && Type != kxfsDir ) {
1699 /* ### Check permissions */
1700         RCt = XFSAttrEditorPermissions ( Editor, & PermStr );
1701         if ( RCt == 0 ) {
1702             RCt = XFSPermMake ( PermStr, & Perm );
1703             if ( RCt == 0 ) {
1704                 if ( XFSPermAuth ( Perm, kxfsUser ) == NULL ) {
1705                     RCt = XFS_RC ( rcInvalid );
1706                 }
1707                 free ( Perm );
1708             }
1709         }
1710     }
1711 
1712     if ( RCt != 0 ) {
1713         XFSEditorDispose ( & ( Editor -> Papahen ) );
1714         return RCt;
1715     }
1716 
1717     RCt = XFSAttrEditorDate ( Editor, & TheTime );
1718     XFSEditorDispose ( & ( Editor -> Papahen ) );
1719     if ( RCt != 0 ) {
1720         return RCt;
1721     }
1722     Time = ( TheTime * 10000000 ) + 116444736000000000;;
1723     TimeLow = ( DWORD ) Time;
1724     TimeHigh = Time >> 32;
1725 
1726     FindData -> ftCreationTime.dwLowDateTime = TimeLow;
1727     FindData -> ftCreationTime.dwHighDateTime = TimeHigh;
1728     FindData -> ftLastAccessTime.dwLowDateTime = TimeLow;
1729     FindData -> ftLastAccessTime.dwHighDateTime = TimeHigh;
1730     FindData -> ftLastWriteTime.dwLowDateTime = TimeLow;
1731     FindData -> ftLastWriteTime.dwHighDateTime = TimeHigh;
1732 
1733     FileSize.QuadPart = 0;
1734     RCt = XFSNodeFileEditor ( Node, & FileEditor );
1735     if ( RCt == 0 ) {
1736         if ( FileEditor != NULL ) {
1737             RCt = XFSFileEditorSize ( FileEditor, & Size );
1738             if ( RCt == 0 ) {
1739                 FileSize.QuadPart = Size;
1740             }
1741             XFSEditorDispose ( & ( FileEditor -> Papahen ) );
1742         }
1743     }
1744     if ( RCt != 0 ) {
1745         RCt = 0;
1746     }
1747     FindData -> nFileSizeHigh = FileSize.HighPart;
1748     FindData -> nFileSizeLow = FileSize.LowPart;
1749 
1750         /*))
1751          // And here is it ... dances with schimpanami
1752         ((*/
1753     if ( mbstowcs_s (
1754                     & CopyNum,
1755                     FindData -> cFileName,
1756                     MAX_PATH,
1757                     Node -> Name,
1758                     string_size ( Node -> Name )
1759                     ) != 0 ) {
1760         RCt = XFS_RC ( rcInvalid );
1761     }
1762 
1763     if ( RCt == 0 ) {
1764         GetShortPathNameW (
1765                         FindData -> cFileName,
1766                         FindData -> cAlternateFileName,
1767                         sizeof ( FindData -> cAlternateFileName )
1768                                                     / sizeof ( WCHAR )
1769                         );
1770     }
1771 
1772     return RCt;
1773 }   /* _Read_PWIN32_FIND_DATA () */
1774 
1775 static
1776 rc_t CC
_FindDataForFile(const struct XFSDirEditor * Editor,const char * FileName,LPWIN32_FIND_DATAW FindData)1777 _FindDataForFile (
1778                 const struct XFSDirEditor * Editor,
1779                 const char * FileName,
1780                 LPWIN32_FIND_DATAW FindData
1781 )
1782 {
1783     rc_t RCt;
1784     struct XFSNode * Child;
1785 
1786     RCt = 0;
1787     Child = NULL;
1788 
1789     if ( Editor == NULL || FileName == NULL || FindData == NULL ) {
1790         return XFS_RC ( rcNull );
1791     }
1792 
1793         /*) First we are looking for child node
1794          (*/
1795     RCt = XFSDirEditorFind ( Editor, FileName, & Child );
1796     if ( RCt == 0 ) {
1797             /*) Second we are reading data for child node
1798              (*/
1799         RCt = _Read_PWIN32_FIND_DATA ( Child, FindData );
1800     }
1801 
1802     return RCt;
1803 }   /* _FindDataForFile () */
1804 
1805 static
1806 int DOKAN_CALLBACK
XFS_DOKAN_FindFiles(LPCWSTR PathName,PFillFindData FindDataCallback,PDOKAN_FILE_INFO TheFileInfo)1807 XFS_DOKAN_FindFiles (
1808             LPCWSTR PathName,
1809             PFillFindData FindDataCallback,
1810             PDOKAN_FILE_INFO TheFileInfo
1811 )
1812 {
1813     rc_t RCt;
1814     struct XFSHandle * Handle;
1815     const struct XFSDirEditor * Editor;
1816     const struct XFSNode * Node;
1817     struct KNamelist * List;
1818     uint32_t ListQty, llp;
1819     const char * Name;
1820     WIN32_FIND_DATAW FindData;
1821     int RetVal;
1822 
1823     RCt = 0;
1824     Handle = NULL;
1825     Editor = NULL;
1826     Node = NULL;
1827     List = NULL;
1828     ListQty = llp = 0;
1829     Name = NULL;
1830     RetVal = 0;
1831 
1832     if ( PathName == NULL || FindDataCallback == NULL
1833         || TheFileInfo == NULL
1834     ) {
1835         return ERROR_INVALID_DATA * - 1;
1836     }
1837 
1838 //TT wLogMsg ( klogDebug, L" FIND Files [%s][0x%p]\n", PathName, TheFileInfo );
1839 
1840     Handle = ( struct XFSHandle * ) TheFileInfo -> Context;
1841     if ( Handle == NULL ) {
1842         return ERROR_INVALID_HANDLE * - 1;
1843     }
1844 
1845     Node = XFSHandleNode ( Handle );
1846     if ( Node == NULL ) {
1847         return ERROR_INVALID_DATA * - 1;
1848     }
1849 
1850     if ( XFSNodeDirEditor ( Node, & Editor ) != 0 ) {
1851         return ERROR_INVALID_DATA * - 1;
1852     }
1853 
1854     if ( Editor == 0 ) {
1855         return ERROR_INVALID_FUNCTION * - 1;
1856     }
1857 
1858     if ( XFSDirEditorList ( Editor, & List ) == 0 ) {
1859         if ( KNamelistCount ( List, & ListQty ) == 0 ) {
1860             for ( llp = 0; llp < ListQty; llp ++ ) {
1861                 RCt = KNamelistGet ( List, llp, & Name );
1862                 if ( RCt == 0 ) {
1863                     RCt = _FindDataForFile ( Editor, Name, & FindData );
1864                     if ( RCt == 0 ) {
1865                         FindDataCallback ( & FindData, TheFileInfo );
1866                     }
1867                 }
1868 
1869                 if ( RCt != 0 ) {
1870 /* Do we need that? TODO!!!
1871                     RetVal = ERROR_INVALID_DATA;
1872                     break;
1873 */
1874                     RCt = 0; /* Right ? */
1875                 }
1876             }
1877         }
1878         else {
1879             RetVal = ERROR_INVALID_DATA;
1880         }
1881 
1882         KNamelistRelease ( List );
1883     }
1884     else {
1885         RetVal = ERROR_INVALID_DATA;
1886     }
1887 
1888     XFSEditorDispose ( & ( Editor -> Papahen ) );
1889 
1890 //TT wLogMsg ( klogDebug, L" FIND Files [%s][0x%p][H=0x%p][V=%d]\n", PathName, TheFileInfo, Handle, RetVal );
1891 
1892     return RetVal * - 1;
1893 }   /* FindFiles() */
1894 
1895 #endif /* USE_XFS_DOKAN_FINDFILES == 1 */
1896 
1897 /************************************************************/
1898 /************************************************************/
1899 
1900 #if USE_XFS_DOKAN_FINDFILESWITHPATTERN == 1
1901 
1902 
1903 static
1904 int DOKAN_CALLBACK
XFS_DOKAN_FindFilesWithPattern(LPCWSTR PathName,LPCWSTR SearchPattern,PFillFindData FindDataCallback,PDOKAN_FILE_INFO TheFileInfo)1905 XFS_DOKAN_FindFilesWithPattern (
1906             LPCWSTR PathName,
1907             LPCWSTR SearchPattern,
1908             PFillFindData FindDataCallback,
1909             PDOKAN_FILE_INFO TheFileInfo
1910 )
1911 {
1912 //TT wLogMsg ( klogDebug, L"FINDFILESWITHPATTERN(DOKAN): [%s][FI=0x%p]\n", FileName, TheFileInfo );
1913     return - 0;
1914 }   /* FindFilesWithPattern() */
1915 
1916 #endif /* USE_XFS_DOKAN_FINDFILESWITHPATTERN == 1 */
1917 
1918 /************************************************************/
1919 /************************************************************/
1920 
1921 #if USE_XFS_DOKAN_SETFILEATTRIBUTES == 1
1922 
1923 
1924 static
1925 int DOKAN_CALLBACK
XFS_DOKAN_SetFileAttributes(LPCWSTR FileName,DWORD FileAttributes,PDOKAN_FILE_INFO TheFileInfo)1926 XFS_DOKAN_SetFileAttributes (
1927             LPCWSTR FileName,
1928             DWORD FileAttributes,
1929             PDOKAN_FILE_INFO TheFileInfo
1930 )
1931 {
1932 //TT wLogMsg ( klogDebug, L"SETFILEATTRIBUTES(DOKAN): [%s][FI=0x%p]\n", FileName, TheFileInfo );
1933     return - 0;
1934 }   /* SetFileAttributes() */
1935 
1936 #endif /* USE_XFS_DOKAN_SETFILEATTRIBUTES == 1 */
1937 
1938 /************************************************************/
1939 /************************************************************/
1940 
1941 #if USE_XFS_DOKAN_SETFILETIME == 1
1942 
1943 
1944 static
1945 int DOKAN_CALLBACK
XFS_DOKAN_SetFileTime(LPCWSTR FileName,CONST FILETIME * CreationTime,CONST FILETIME * LastAccessTime,CONST FILETIME * LastWriteTime,PDOKAN_FILE_INFO TheFileInfo)1946 XFS_DOKAN_SetFileTime (
1947             LPCWSTR FileName,
1948             CONST FILETIME * CreationTime,
1949             CONST FILETIME * LastAccessTime,
1950             CONST FILETIME * LastWriteTime,
1951             PDOKAN_FILE_INFO TheFileInfo
1952 )
1953 {
1954     rc_t RCt;
1955     struct XFSAttrEditor * Editor;
1956     const struct XFSNode * Node;
1957     KTime_t Time;
1958     ULONG64 xTime;
1959 
1960     RCt = 0;
1961     Editor = NULL;
1962     Node = NULL;
1963     Time = 0;
1964     xTime = 0;
1965 
1966 //TT wLogMsg ( klogDebug, L" SET file time: [%s][FI=0x%p]\n", FileName, TheFileInfo );
1967 
1968     if ( FileName == NULL || TheFileInfo == NULL ) {
1969         return ERROR_INVALID_DATA * - 1;
1970     }
1971 
1972         /*\ First we should convert time to time
1973         \*/
1974     xTime = LastWriteTime -> dwHighDateTime << 32;
1975     xTime += LastWriteTime -> dwLowDateTime;
1976     xTime -= 116444736000000000;
1977     xTime /= 10000000;
1978 
1979     RCt = _DOKAN_get_path_and_node (
1980                                 FileName,
1981                                 TheFileInfo,
1982                                 NULL,   /* VPath, no need */
1983                                 & Node,
1984                                 NULL    /* NodeType */
1985                                 );
1986     if ( RCt == 0 ) {
1987         RCt = XFSNodeAttrEditor ( Node, & Editor );
1988 
1989         if ( RCt == 0 ) {
1990             RCt = XFSAttrEditorSetDate ( Editor, xTime );
1991         }
1992 
1993         XFSNodeRelease ( Node );
1994     }
1995 
1996 //TT wLogMsg ( klogDebug, L" SET file time,cont: [%s][FI=0x%p][RC=%d]\n", FileName, TheFileInfo, RCt );
1997 
1998     return ( RCt == 0 ? 0 : ERROR_INVALID_DATA ) * - 1;
1999 }   /* SetFileTime() */
2000 
2001 #endif /* USE_XFS_DOKAN_SETFILETIME == 1 */
2002 
2003 /************************************************************/
2004 /************************************************************/
2005 #if USE_XFS_DOKAN_DELETEFILE == 1
2006 
2007 static
2008 int DOKAN_CALLBACK
XFS_DOKAN_DeleteFile(LPCWSTR FileName,PDOKAN_FILE_INFO TheFileInfo)2009 XFS_DOKAN_DeleteFile (
2010             LPCWSTR FileName,
2011             PDOKAN_FILE_INFO TheFileInfo
2012 )
2013 {
2014     rc_t RCt;
2015 
2016     RCt = 0;
2017 
2018 //TT wLogMsg ( klogDebug, L"DELETE File [%s][FI=0x%p][H=0x%p]\n", FileName, TheFileInfo, (void * ) TheFileInfo -> Context );
2019 
2020     RCt = _DOKAN_delete_file_dir ( FileName, TheFileInfo );
2021 
2022 //TT wLogMsg ( klogDebug, L"   DELETE File,cont [%s][FI=0x%p][H=0x%p][RC=%d]\n", FileName, TheFileInfo, (void * ) TheFileInfo -> Context, RCt );
2023 
2024     return ( RCt == 0 ? 0 : ERROR_INVALID_DATA ) * - 1;
2025 }   /* DeleteFile() */
2026 
2027 #endif /* USE_XFS_DOKAN_DELETEFILE == 1 */
2028 
2029 /************************************************************/
2030 /************************************************************/
2031 
2032 #if USE_XFS_DOKAN_DELETEDIRECTORY == 1
2033 
2034 static
2035 int DOKAN_CALLBACK
XFS_DOKAN_DeleteDirectory(LPCWSTR FileName,PDOKAN_FILE_INFO TheFileInfo)2036 XFS_DOKAN_DeleteDirectory (
2037             LPCWSTR FileName,
2038             PDOKAN_FILE_INFO TheFileInfo
2039 )
2040 {
2041     rc_t RCt;
2042 
2043     RCt = 0;
2044 
2045 //TT wLogMsg ( klogDebug, L"DELETE Directory [%s][FI=0x%p][H=0x%p]\n", FileName, TheFileInfo, (void * ) TheFileInfo -> Context );
2046 
2047     RCt = _DOKAN_delete_file_dir ( FileName, TheFileInfo );
2048 
2049 //TT wLogMsg ( klogDebug, L"   DELETE Directory [%s][FI=0x%p][H=0x%p][RC=%d]\n", FileName, TheFileInfo, (void * ) TheFileInfo -> Context, RCt );
2050 
2051     return ( RCt == 0 ? 0 : ERROR_INVALID_DATA ) * - 1;
2052 }   /* DeleteDirectory() */
2053 
2054 #endif /* USE_XFS_DOKAN_DELETEDIRECTORY == 1 */
2055 
2056 /************************************************************/
2057 /************************************************************/
2058 
2059 #if USE_XFS_DOKAN_MOVEFILE == 1
2060 
2061 
2062 static
2063 int DOKAN_CALLBACK
XFS_DOKAN_MoveFile(LPCWSTR OldFile,LPCWSTR NewFile,BOOL ReplaceExisting,PDOKAN_FILE_INFO TheFileInfo)2064 XFS_DOKAN_MoveFile (
2065             LPCWSTR OldFile,
2066             LPCWSTR NewFile,
2067             BOOL ReplaceExisting,
2068             PDOKAN_FILE_INFO TheFileInfo
2069 )
2070 {
2071     rc_t RCt;
2072     struct XFSNode * OldDir, * NewDir;
2073     char * OldName, * NewName;
2074     struct XFSDirEditor * Editor;
2075 
2076     RCt = 0;
2077     OldDir = NewDir = NULL;
2078     OldName = NewName = NULL;
2079     Editor = NULL;
2080 
2081 //TT wLogMsg ( klogDebug, L"MOVE File FR[%s]TO[%s][FI=0x%p][H=0x%p]\n", OldFile, NewFile, TheFileInfo, (void * ) TheFileInfo -> Context );
2082 
2083     RCt = _DOKAN_get_parent_node_from_char (
2084                                         OldFile,
2085                                         TheFileInfo,
2086                                         & OldDir,
2087                                         NULL,
2088                                         & OldName
2089                                         );
2090     if ( RCt == 0 ) {
2091         RCt = _DOKAN_get_parent_node_from_char (
2092                                             NewFile,
2093                                             TheFileInfo,
2094                                             & NewDir,
2095                                             NULL,
2096                                             & NewName
2097                                             );
2098         if ( RCt == 0 ) {
2099             RCt = XFSNodeDirEditor ( OldDir, & Editor );
2100             if ( RCt == 0 ) {
2101                 RCt = XFSDirEditorMove (
2102                                     Editor,
2103                                     OldName,
2104                                     NewDir,
2105                                     NewName
2106                                     );
2107                 XFSEditorDispose ( & ( Editor -> Papahen ) );
2108             }
2109 
2110             XFSNodeRelease ( NewDir );
2111             free ( NewName );
2112         }
2113 
2114         XFSNodeRelease ( OldDir );
2115         free ( OldName );
2116     }
2117 
2118 //TT wLogMsg ( klogDebug, L"   MOVE File FR[%s]TO[%s][FI=0x%p][H=0x%p][RC=%d]\n", OldFile, NewFile, TheFileInfo, (void * ) TheFileInfo -> Context, RCt );
2119 
2120     return ( RCt == 0 ? 0 : ERROR_INVALID_DATA ) * - 1;
2121 }   /* MoveFile() */
2122 
2123 #endif /* USE_XFS_DOKAN_MOVEFILE == 1 */
2124 
2125 /************************************************************/
2126 /************************************************************/
2127 
2128 #if USE_XFS_DOKAN_SETENDOFFILE == 1
2129 
2130 
2131 static
2132 int DOKAN_CALLBACK
XFS_DOKAN_SetEndOfFile(LPCWSTR FileName,LONGLONG Length,PDOKAN_FILE_INFO TheFileInfo)2133 XFS_DOKAN_SetEndOfFile (
2134             LPCWSTR FileName,
2135             LONGLONG Length,
2136             PDOKAN_FILE_INFO TheFileInfo
2137 )
2138 {
2139     rc_t RCt;
2140     struct XFSHandle * Handle;
2141     struct XFSFileEditor * FileEditor;
2142     const struct XFSNode * Node;
2143 
2144     RCt = 0;
2145     Handle = NULL;
2146     Editor = NULL;
2147     Node = NULL;
2148 
2149 //TT wLogMsg ( klogDebug, L" SET end of file: [%s][FI=0x%p]\n", FileName, TheFileInfo );
2150 
2151     if ( FileName == NULL || TheFileInfo == NULL ) {
2152         return ERROR_INVALID_DATA * - 1;
2153     }
2154 
2155     Handle = ( struct XFSHandle * ) TheFileInfo -> Context;
2156 
2157     Editor = Handle != NULL
2158                 ? ( struct XFSFileEditor * ) XFSHandleGet ( Handle )
2159                 : NULL
2160                 ;
2161     if ( Editor == NULL ) {
2162         RCt = _DOKAN_get_path_and_node (
2163                                     FileName,
2164                                     TheFileInfo,
2165                                     NULL,   /* VPath, no need */
2166                                     & Node,
2167                                     NULL    /* NodeType */
2168                                     );
2169         if ( RCt == 0 ) {
2170             RCt = XFSNodeFileEditor ( Node, & Editor );
2171             if ( RCt == 0 ) {
2172                 RCt = XFSFileEditorSetSize ( Editor, Length );
2173 
2174                 XFSEditorDispose ( & ( Editor -> Papahen ) );
2175             }
2176 
2177             XFSNodeRelease ( Node );
2178         }
2179     }
2180     else {
2181         RCt = XFSFileEditorSetSize ( Editor, Length );
2182     }
2183 
2184     return ( RCt == 0 ? 0 : ERROR_INVALID_DATA ) * - 1;
2185 }   /* SetEndOfFile() */
2186 
2187 #endif /* USE_XFS_DOKAN_SETENDOFFILE == 1 */
2188 
2189 /************************************************************/
2190 /************************************************************/
2191 
2192 #if USE_XFS_DOKAN_SETALLOCATIONSIZE == 1
2193 
2194 
2195 static
2196 int DOKAN_CALLBACK
XFS_DOKAN_SetAllocationSize(LPCWSTR FileName,LONGLONG Length,PDOKAN_FILE_INFO TheFileInfo)2197 XFS_DOKAN_SetAllocationSize (
2198             LPCWSTR FileName,
2199             LONGLONG Length,
2200             PDOKAN_FILE_INFO TheFileInfo
2201 )
2202 {
2203 //TT wLogMsg ( klogDebug, L"SETALLOCATIONSIZE(DOKAN): [%s][FI=0x%p]\n", FileName, TheFileInfo );
2204     return - 0;
2205 }   /* SetAllocationSize() */
2206 
2207 #endif /* USE_XFS_DOKAN_SETALLOCATIONSIZE == 1 */
2208 
2209 /************************************************************/
2210 /************************************************************/
2211 
2212 #if USE_XFS_DOKAN_LOCKFILE == 1
2213 
2214 static
2215 int DOKAN_CALLBACK
XFS_DOKAN_LockFile(LPCWSTR FileName,LONGLONG ByteOffset,LONGLONG Length,PDOKAN_FILE_INFO TheFileInfo)2216 XFS_DOKAN_LockFile (
2217             LPCWSTR FileName,
2218             LONGLONG ByteOffset,
2219             LONGLONG Length,
2220             PDOKAN_FILE_INFO TheFileInfo
2221 )
2222 {
2223 //TT wLogMsg ( klogDebug, L"LOCKFILE(DOKAN): [%s][FI=0x%p]\n", FileName, TheFileInfo );
2224     return - 0;
2225 }   /* LockFile() */
2226 
2227 #endif /* USE_XFS_DOKAN_LOCKFILE == 1 */
2228 
2229 /************************************************************/
2230 /************************************************************/
2231 
2232 #if USE_XFS_DOKAN_UNLOCKFILE == 1
2233 
2234 static
2235 int DOKAN_CALLBACK
XFS_DOKAN_UnlockFile(LPCWSTR FileName,LONGLONG ByteOffset,LONGLONG Length,PDOKAN_FILE_INFO TheFileInfo)2236 XFS_DOKAN_UnlockFile (
2237             LPCWSTR FileName,
2238             LONGLONG ByteOffset,
2239             LONGLONG Length,
2240             PDOKAN_FILE_INFO TheFileInfo
2241 )
2242 {
2243 //TT wLogMsg ( klogDebug, L"UNLOCKFILE(DOKAN): [%s][FI=0x%p]\n", FileName, TheFileInfo );
2244     return - 0;
2245 }   /* UnlockFile() */
2246 
2247 #endif /* USE_XFS_DOKAN_UNLOCKFILE == 1 */
2248 
2249 /************************************************************/
2250 /************************************************************/
2251 
2252 #if USE_XFS_DOKAN_GETDISKFREESPACE == 1
2253 
2254 static
2255 int DOKAN_CALLBACK
XFS_DOKAN_GetDiskFreeSpace(PULONGLONG FreeBytesAvailable,PULONGLONG TotalNumberOfBytes,PULONGLONG TotalNumberOfFreeBytes,PDOKAN_FILE_INFO TheFileInfo)2256 XFS_DOKAN_GetDiskFreeSpace (
2257             PULONGLONG FreeBytesAvailable,
2258             PULONGLONG TotalNumberOfBytes,
2259             PULONGLONG TotalNumberOfFreeBytes,
2260             PDOKAN_FILE_INFO TheFileInfo
2261 )
2262 {
2263 //TT wLogMsg ( klogDebug, L"GETDISKFREESPACE(DOKAN): [%s][FI=0x%p]\n", FileName, TheFileInfo );
2264     return - 0;
2265 }   /* GetDiskFreeSpace() */
2266 
2267 #endif /* USE_XFS_DOKAN_GETDISKFREESPACE == 1 */
2268 
2269 /************************************************************/
2270 /************************************************************/
2271 
2272 #if USE_XFS_DOKAN_GETVOLUMEINFORMATION == 1
2273 
2274 static
2275 int DOKAN_CALLBACK
XFS_DOKAN_GetVolumeInformation(LPWSTR VolumeNameBuffer,DWORD VolumeNameSize,LPDWORD VolumeSerialNumber,LPDWORD MaximumComponentLength,LPDWORD FileSystemFlags,LPWSTR FileSystemNameBuffer,DWORD FileSystemNameSize,PDOKAN_FILE_INFO TheFileInfo)2276 XFS_DOKAN_GetVolumeInformation (
2277             LPWSTR VolumeNameBuffer,
2278             DWORD VolumeNameSize,
2279             LPDWORD VolumeSerialNumber,
2280             LPDWORD MaximumComponentLength,
2281             LPDWORD FileSystemFlags,
2282             LPWSTR FileSystemNameBuffer,
2283             DWORD FileSystemNameSize,
2284             PDOKAN_FILE_INFO TheFileInfo
2285 )
2286 {
2287 //TT wLogMsg ( klogDebug, L"GETVOLUMEINFORMATION(DOKAN): [FI=0x%p]\n", TheFileInfo );
2288 
2289     wcscpy_s(
2290             VolumeNameBuffer,
2291             VolumeNameSize / sizeof(WCHAR),
2292             // L"NCBI&CO"
2293             L"dbGaP"
2294             );
2295 
2296     * VolumeSerialNumber = 0x19450509;
2297     * MaximumComponentLength = 256;
2298     * FileSystemFlags = FILE_CASE_SENSITIVE_SEARCH
2299                         | FILE_CASE_PRESERVED_NAMES
2300                         | FILE_SUPPORTS_REMOTE_STORAGE
2301                         | FILE_UNICODE_ON_DISK
2302                         | FILE_PERSISTENT_ACLS  /*  comment if ACL and
2303                                                     security does not
2304                                                     needed
2305                                                 */
2306                         ;
2307 
2308     wcscpy_s(
2309             FileSystemNameBuffer,
2310             FileSystemNameSize / sizeof(WCHAR),
2311             L"NCBI&CO"
2312             );
2313 
2314     return 0;
2315 }   /* GetVolumeInformation() */
2316 
2317 #endif /* USE_XFS_DOKAN_GETVOLUMEINFORMATION == 1 */
2318 
2319 /************************************************************/
2320 /************************************************************/
2321 
2322 #if USE_XFS_DOKAN_UNMOUNT == 1
2323 
2324 
2325 static
2326 int DOKAN_CALLBACK
XFS_DOKAN_Unmount(PDOKAN_FILE_INFO TheFileInfo)2327 XFS_DOKAN_Unmount (
2328             PDOKAN_FILE_INFO TheFileInfo
2329 )
2330 {
2331 wLogMsg ( klogDebug, L"UNMOUNT(DOKAN): [FI=0x%p]\n", TheFileInfo );
2332     return - 0;
2333 }   /* Unmount() */
2334 
2335 #endif /* USE_XFS_DOKAN_UNMOUNT == 1 */
2336 
2337 /************************************************************/
2338 /************************************************************/
2339 
2340 #if USE_XFS_DOKAN_GETFILESECURITY == 1
2341 
2342 /************************************************************
2343  *  Luriks : see file security.c
2344  ***********************************************************/
2345 
2346 static const char * _sDefaultPermissions = "rwxr-xr-x";
2347 
2348 XFS_EXTERN void CC _SI_Dump (
2349                         SECURITY_INFORMATION Inf,
2350                         char * Buff,
2351                         size_t BuffSize
2352                         );
2353 
2354 XFS_EXTERN rc_t CC XFSSecurityDescriptor (
2355                                     SECURITY_INFORMATION SecInfo,
2356                                     const char * Permissions,
2357                                     XFSNType NodeType,
2358                                     PSECURITY_DESCRIPTOR Descriptor,
2359                                     ULONG DescriptorLength
2360                                     );
2361 
2362 XFS_EXTERN rc_t CC XFSSecurityDescriptorSize (
2363                                     SECURITY_INFORMATION SecInfo,
2364                                     const char * Permissions,
2365                                     XFSNType NodeType,
2366                                     ULONG * DescSize
2367                                     );
2368 
2369 static
2370 int DOKAN_CALLBACK
XFS_DOKAN_GetFileSecurity(LPCWSTR FileName,PSECURITY_INFORMATION SecInfo,PSECURITY_DESCRIPTOR SecDsc,ULONG SecDscLen,PULONG SecDscLenNeeded,PDOKAN_FILE_INFO TheFileInfo)2371 XFS_DOKAN_GetFileSecurity (
2372                         LPCWSTR FileName,
2373                         PSECURITY_INFORMATION SecInfo,
2374                         PSECURITY_DESCRIPTOR SecDsc,
2375                         ULONG SecDscLen,
2376                         PULONG SecDscLenNeeded,
2377                         PDOKAN_FILE_INFO TheFileInfo
2378 )
2379 {
2380     rc_t RCt;
2381     int RetVal;
2382     SECURITY_INFORMATION Sinfo;
2383     const struct XFSHandle * Handle;
2384     const struct XFSNode * Node;
2385     const struct XFSAttrEditor * Editor;
2386     XFSNType Type;
2387     const char * Permissions;
2388 
2389     RetVal = 0;
2390     RCt = 0;
2391     Sinfo = 0;
2392     Handle = NULL;
2393     Node = NULL;
2394     Editor = NULL;
2395     Type = kxfsNotFound;
2396     Permissions = NULL;
2397 
2398     if ( FileName == NULL || TheFileInfo == NULL ) {
2399         return ERROR_INVALID_DATA * - 1;
2400     }
2401 
2402     if ( SecDscLenNeeded == NULL || SecDsc == NULL || SecInfo == NULL ) {
2403         return ERROR_INVALID_DATA * - 1;
2404     }
2405     * SecDscLenNeeded = 0;
2406     Sinfo = * SecInfo;
2407 
2408     Handle = ( struct XFSHandle * ) TheFileInfo -> Context;
2409 
2410     if ( Handle == NULL )  {
2411         return ERROR_INVALID_HANDLE * - 1;
2412     }
2413 
2414     Node = XFSHandleNode ( Handle );
2415     if ( Node == NULL ) {
2416         return ERROR_INVALID_HANDLE * - 1;
2417     }
2418 
2419     if ( XFSNodeAttrEditor ( Node, & Editor ) != 0 ) {
2420         return ERROR_INVALID_HANDLE * - 1;
2421     }
2422 
2423 //TT wLogMsg ( klogDebug, L" SECURITY File [%s][0x%p][E=0x%p]\n", FileName, TheFileInfo, Editor );
2424 /*
2425 {
2426 char FU [ 64 ];
2427 _SI_Dump ( Sinfo, FU, sizeof ( FU ) );
2428 printf ( "SECURITY File [%s][0x%p]\n", FU, TheFileInfo );
2429 }
2430 */
2431 
2432     RCt = XFSAttrEditorType ( Editor, & Type );
2433     if ( RCt == 0 ) {
2434         if ( Type == kxfsFile || Type == kxfsDir || Type == kxfsLink ) {
2435             RCt = XFSAttrEditorPermissions ( Editor, & Permissions );
2436             if ( RCt == 0 ) {
2437 
2438                 if ( Permissions == NULL ) {
2439                     Permissions = _sDefaultPermissions;
2440                 }
2441 
2442                 /*   First we are going to check if here is enough space
2443                  */
2444                 RCt = XFSSecurityDescriptorSize (
2445                                             Sinfo,
2446                                             Permissions,
2447                                             Type,
2448                                             SecDscLenNeeded
2449                                             );
2450                 if ( RCt == 0 && 0 < * SecDscLenNeeded ) {
2451                     if ( SecDscLen == 0 || SecDscLen < * SecDscLenNeeded ) {
2452 //TT wLogMsg ( klogDebug, L" SECURITY File ( SIZE Requested ) [%s][NS=%d][BS=%d]\n", FileName, * SecDscLenNeeded, SecDscLen );
2453                         RetVal = ERROR_INSUFFICIENT_BUFFER;
2454                     }
2455                     else {
2456                         RCt = XFSSecurityDescriptor (
2457                                                 Sinfo,
2458                                                 Permissions,
2459                                                 Type,
2460                                                 SecDsc,
2461                                                 SecDscLen
2462                                                 );
2463                     }
2464                 }
2465             }
2466         }
2467         else {
2468             RCt = XFS_RC ( rcInvalid );
2469         }
2470     }
2471 
2472     if ( RCt != 0 ) {
2473         if ( RetVal == 0 ) {
2474             RetVal = ERROR_INVALID_HANDLE;
2475         }
2476     }
2477 
2478     XFSEditorDispose ( & ( Editor -> Papahen ) );
2479 //TT wLogMsg ( klogDebug, L" SECURITY File,cont [%s][0x%p][R=%d]\n", FileName, TheFileInfo, RetVal );
2480 
2481     return RetVal * - 1;
2482 }   /* GetFileSecurity() */
2483 
2484 #endif /* USE_XFS_DOKAN_GETFILESECURITY == 1 */
2485 
2486 /************************************************************/
2487 /************************************************************/
2488 
2489 #if USE_XFS_DOKAN_SETFILESECURITY == 1
2490 
2491 static
2492 int DOKAN_CALLBACK
XFS_DOKAN_SetFileSecurity(LPCWSTR FileName,PSECURITY_INFORMATION SecurityInformation,PSECURITY_DESCRIPTOR SecurityDescriptor,ULONG SecurityDescriptorLength,PDOKAN_FILE_INFO TheFileInfo)2493 XFS_DOKAN_SetFileSecurity (
2494             LPCWSTR FileName,
2495             PSECURITY_INFORMATION SecurityInformation,
2496             PSECURITY_DESCRIPTOR SecurityDescriptor,
2497             ULONG SecurityDescriptorLength,
2498             PDOKAN_FILE_INFO TheFileInfo
2499 )
2500 {
2501 //TT wLogMsg ( klogDebug, L"SETFILESECURITY(DOKAN): [%s][FI=0x%p]\n", FileName, TheFileInfo );
2502     return - 0;
2503 }   /* SetFileSecurity() */
2504 
2505 #endif /* USE_XFS_DOKAN_SETFILESECURITY == 1 */
2506 
2507 /************************************************************/
2508 /************************************************************/
2509 
2510 /*))
2511   || Old good necessary method
2512   (*/
2513 LIB_EXPORT
2514 rc_t CC
XFS_Private_InitOperations(DOKAN_OPERATIONS * Operations)2515 XFS_Private_InitOperations ( DOKAN_OPERATIONS * Operations )
2516 {
2517     if ( Operations == NULL ) {
2518         return XFS_RC ( rcNull );
2519     }
2520 
2521     ZeroMemory ( Operations, sizeof( struct _DOKAN_OPERATIONS ) );
2522 
2523 
2524 #if USE_XFS_DOKAN_CREATEFILE == 1
2525     Operations -> CreateFile = XFS_DOKAN_CreateFile;
2526 #endif /* USE_XFS_DOKAN_CREATEFILE == 1 */
2527 
2528 #if USE_XFS_DOKAN_OPENDIRECTORY == 1
2529     Operations -> OpenDirectory = XFS_DOKAN_OpenDirectory;
2530 #endif /* USE_XFS_DOKAN_OPENDIRECTORY == 1 */
2531 
2532 #if USE_XFS_DOKAN_CREATEDIRECTORY == 1
2533     Operations -> CreateDirectory = XFS_DOKAN_CreateDirectory;
2534 #endif /* USE_XFS_DOKAN_CREATEDIRECTORY == 1 */
2535 
2536 #if USE_XFS_DOKAN_CLEANUP == 1
2537     Operations -> Cleanup = XFS_DOKAN_Cleanup;
2538 #endif /* USE_XFS_DOKAN_CLEANUP == 1 */
2539 
2540 #if USE_XFS_DOKAN_CLOSEFILE == 1
2541     Operations -> CloseFile = XFS_DOKAN_CloseFile;
2542 #endif /* USE_XFS_DOKAN_CLOSEFILE == 1 */
2543 
2544 #if USE_XFS_DOKAN_READFILE == 1
2545     Operations -> ReadFile = XFS_DOKAN_ReadFile;
2546 #endif /* USE_XFS_DOKAN_READFILE == 1 */
2547 
2548 #if USE_XFS_DOKAN_WRITEFILE == 1
2549     Operations -> WriteFile = XFS_DOKAN_WriteFile;
2550 #endif /* USE_XFS_DOKAN_WRITEFILE == 1 */
2551 
2552 #if USE_XFS_DOKAN_FLUSHFILEBUFFERS == 1
2553     Operations -> FlushFileBuffers = XFS_DOKAN_FlushFileBuffers;
2554 #endif /* USE_XFS_DOKAN_FLUSHFILEBUFFERS == 1 */
2555 
2556 #if USE_XFS_DOKAN_GETFILEINFORMATION == 1
2557     Operations -> GetFileInformation = XFS_DOKAN_GetFileInformation;
2558 #endif /* USE_XFS_DOKAN_GETFILEINFORMATION == 1 */
2559 
2560 #if USE_XFS_DOKAN_FINDFILES == 1
2561     Operations -> FindFiles = XFS_DOKAN_FindFiles;
2562 #endif /* USE_XFS_DOKAN_FINDFILES == 1 */
2563 
2564 #if USE_XFS_DOKAN_FINDFILESWITHPATTERN == 1
2565     Operations -> FindFilesWithPattern = XFS_DOKAN_FindFilesWithPattern;
2566 #endif /* USE_XFS_DOKAN_FINDFILESWITHPATTERN == 1 */
2567 
2568 #if USE_XFS_DOKAN_SETFILEATTRIBUTES == 1
2569     Operations -> SetFileAttributes = XFS_DOKAN_SetFileAttributes;
2570 #endif /* USE_XFS_DOKAN_SETFILEATTRIBUTES == 1 */
2571 
2572 #if USE_XFS_DOKAN_SETFILETIME == 1
2573     Operations -> SetFileTime = XFS_DOKAN_SetFileTime;
2574 #endif /* USE_XFS_DOKAN_SETFILETIME == 1 */
2575 
2576 #if USE_XFS_DOKAN_DELETEFILE == 1
2577     Operations -> DeleteFile = XFS_DOKAN_DeleteFile;
2578 #endif /* USE_XFS_DOKAN_DELETEFILE == 1 */
2579 
2580 #if USE_XFS_DOKAN_DELETEDIRECTORY == 1
2581     Operations -> DeleteDirectory = XFS_DOKAN_DeleteDirectory;
2582 #endif /* USE_XFS_DOKAN_DELETEDIRECTORY == 1 */
2583 
2584 #if USE_XFS_DOKAN_MOVEFILE == 1
2585     Operations -> MoveFile = XFS_DOKAN_MoveFile;
2586 #endif /* USE_XFS_DOKAN_MOVEFILE == 1 */
2587 
2588 #if USE_XFS_DOKAN_SETENDOFFILE == 1
2589     Operations -> SetEndOfFile = XFS_DOKAN_SetEndOfFile;
2590 #endif /* USE_XFS_DOKAN_SETENDOFFILE == 1 */
2591 
2592 #if USE_XFS_DOKAN_SETALLOCATIONSIZE == 1
2593     Operations -> SetAllocationSize = XFS_DOKAN_SetAllocationSize;
2594 #endif /* USE_XFS_DOKAN_SETALLOCATIONSIZE == 1 */
2595 
2596 #if USE_XFS_DOKAN_LOCKFILE == 1
2597     Operations -> LockFile = XFS_DOKAN_LockFile;
2598 #endif /* USE_XFS_DOKAN_LOCKFILE == 1 */
2599 
2600 #if USE_XFS_DOKAN_UNLOCKFILE == 1
2601     Operations -> UnlockFile = XFS_DOKAN_UnlockFile;
2602 #endif /* USE_XFS_DOKAN_UNLOCKFILE == 1 */
2603 
2604 #if USE_XFS_DOKAN_GETDISKFREESPACE == 1
2605     Operations -> GetDiskFreeSpace = XFS_DOKAN_GetDiskFreeSpace;
2606 #endif /* USE_XFS_DOKAN_GETDISKFREESPACE == 1 */
2607 
2608 #if USE_XFS_DOKAN_GETVOLUMEINFORMATION == 1
2609     Operations -> GetVolumeInformation = XFS_DOKAN_GetVolumeInformation;
2610 #endif /* USE_XFS_DOKAN_GETVOLUMEINFORMATION == 1 */
2611 
2612 #if USE_XFS_DOKAN_UNMOUNT == 1
2613     Operations -> Unmount = XFS_DOKAN_Unmount;
2614 #endif /* USE_XFS_DOKAN_UNMOUNT == 1 */
2615 
2616 #if USE_XFS_DOKAN_GETFILESECURITY == 1
2617     Operations -> GetFileSecurity = XFS_DOKAN_GetFileSecurity;
2618 #endif /* USE_XFS_DOKAN_GETFILESECURITY == 1 */
2619 
2620 #if USE_XFS_DOKAN_SETFILESECURITY == 1
2621     Operations -> SetFileSecurity = XFS_DOKAN_SetFileSecurity;
2622 #endif /* USE_XFS_DOKAN_SETFILESECURITY == 1 */
2623 
2624     return 0;
2625 }   /* XFS_Private_InitOperations() */
2626 
2627 
2628 /****************************************************************
2629  * LogMsg as pLogMsg does not work with WCHAR ... so ... julep
2630  ****************************************************************/
2631 LIB_EXPORT
2632 rc_t CC
wLogMsg(KLogLevel Level,LPCWSTR Format,...)2633 wLogMsg ( KLogLevel Level, LPCWSTR Format, ... )
2634 {
2635     rc_t RCt;
2636     WCHAR BF [ XFS_SIZE_4096 ];
2637     char BFF [ XFS_SIZE_4096 ];
2638     va_list Args;
2639     size_t Size;
2640 
2641     RCt = 0;
2642     * BF = 0;
2643     * BFF = 0;
2644     Size = 0;
2645 
2646     if ( Level <= KLogLevelGet () ) {
2647         va_start ( Args, Format );
2648 
2649         if ( vswprintf ( BF, sizeof ( BF ) / sizeof ( WCHAR ), Format, Args ) == - 1 ) {
2650             RCt = XFS_RC ( rcInvalid );
2651         }
2652 
2653         va_end ( Args );
2654 
2655         if ( RCt == 0 ) {
2656             if ( wcstombs_s ( & Size, BFF, sizeof ( BFF ), BF, wcslen ( BF ) ) == 0 ) {
2657                 RCt = LogMsg ( Level, BFF );
2658             }
2659             else {
2660                 RCt = XFS_RC ( rcInvalid );
2661             }
2662         }
2663     }
2664 
2665     return RCt;
2666 }   /* wLogMsg () */
2667