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