2 * COPYRIGHT: GNU GENERAL PUBLIC LICENSE VERSION 2
3 * PROJECT: ReiserFs file system driver for Windows NT/2000/XP/Vista.
6 * PROGRAMMER: Mark Piper, Matt Wu, Bo Brantén.
11 /* INCLUDES *****************************************************************/
15 /* GLOBALS *****************************************************************/
17 extern PRFSD_GLOBAL RfsdGlobal
;
19 /* DEFINITIONS *************************************************************/
26 typedef struct _RFSD_SCANDIR_CALLBACK_CONTEXT
{
28 IN PRFSD_KEY_IN_MEMORY pDirectoryKey
;
29 IN PUNICODE_STRING pTargetFilename
;
31 ULONG idxCurrentDentry
; /// Running count of the dentries processed, so that MatchingIndex will be relative to all dentry spans
33 OUT PRFSD_DENTRY_HEAD pMatchingDentry
; /// If a matching dentry is found, the callback will fill this structure with it
34 OUT PULONG pMatchingIndex
; /// Index of the matching entry (relative to all dentry spans for the directory)
35 } RFSD_SCANDIR_CALLBACK_CONTEXT
, *PRFSD_SCANDIR_CALLBACK_CONTEXT
;
38 #pragma alloc_text(PAGE, RfsdLookupFileName)
39 #pragma alloc_text(PAGE, RfsdScanDir)
40 #pragma alloc_text(PAGE, RfsdCreateFile)
41 #pragma alloc_text(PAGE, RfsdCreateVolume)
42 #pragma alloc_text(PAGE, RfsdCreate)
44 #pragma alloc_text(PAGE, RfsdCreateInode)
45 #pragma alloc_text(PAGE, RfsdSupersedeOrOverWriteFile)
46 #endif // !RFSD_READ_ONLY
47 #pragma alloc_text(PAGE, RfsdScanDirCallback)
51 RfsdLookupFileName (IN PRFSD_VCB Vcb
,
52 IN PUNICODE_STRING FullFileName
,
53 IN PRFSD_MCB ParentMcb
,
54 OUT PRFSD_MCB
* RfsdMcb
,
55 IN OUT PRFSD_INODE Inode
) // An allocated, but unfilled inode, to which the matching file's information will be put
58 UNICODE_STRING FileName
;
61 RFSD_DENTRY_HEAD DirectoryEntry
;
64 BOOLEAN bParent
= FALSE
;
70 Status
= STATUS_OBJECT_NAME_NOT_FOUND
;
75 // Determine the parent node
77 // Looking up a file in the tree, starting at an arbitrary parent node.
79 } else if (FullFileName
->Buffer
[0] == L
'\\') {
80 // Looking up from the root (so there was no parent). Assign the root node parent from the VCB.
81 ParentMcb
= Vcb
->McbTree
;
83 // Otherwise, fail attempt to lookup non-rooted filename
84 return STATUS_OBJECT_PATH_NOT_FOUND
;
87 RtlZeroMemory(&DirectoryEntry
, sizeof(RFSD_DENTRY_HEAD
));
89 // Sanity check that the filename is valid
90 if (FullFileName
->Length
== 0) {
94 // Only if we're looking up *exactly* the root node, load it, and return it
95 if (FullFileName
->Length
== 2 && FullFileName
->Buffer
[0] == L
'\\') {
96 if (!RfsdLoadInode(Vcb
, &(ParentMcb
->Key
), Inode
)) {
100 *RfsdMcb
= Vcb
->McbTree
;
102 return STATUS_SUCCESS
;
105 // Begin lookup from the parent node
106 while (bRun
&& i
< FullFileName
->Length
/2) {
108 ULONG FileAttr
= FILE_ATTRIBUTE_NORMAL
;
113 // Advance through the (potentially) consecutive '\' path seperators in the filename
114 while(i
< FullFileName
->Length
/2 && FullFileName
->Buffer
[i
] == L
'\\') i
++;
119 // Advance to the next '\' path seperator
120 while(i
< FullFileName
->Length
/2 && (FullFileName
->Buffer
[i
] != L
'\\')) i
++;
122 if ( (i
- Length
) <= 0) {
123 // All of the tokens have been parsed...
127 // There remains a token between the path seperators...
129 // FileName is a (non-null-terminated) view into the FullFileName structure
130 FileName
= *FullFileName
;
131 FileName
.Buffer
+= Length
;
132 FileName
.Length
= (USHORT
)((i
- Length
) * 2);
134 // Check to see if the parent MCB already contains a child MCB matching the target FileName
135 Mcb
= RfsdSearchMcb(Vcb
, ParentMcb
, &FileName
);
140 Status
= STATUS_SUCCESS
;
142 if (!IsFlagOn(Mcb
->FileAttr
, FILE_ATTRIBUTE_DIRECTORY
)) {
143 if (i
< FullFileName
->Length
/2) {
144 Status
= STATUS_OBJECT_PATH_NOT_FOUND
;
150 // The parent has no child MCB, or there was no child MCB sibling named FileName. Check the disk using ScanDir...
152 // Load the parent directory's inode / stat data structure
153 // For ReiserFS, I'd need the parent's key. This has to be a key leading to a directory... I'm just getting it to pass it to scan.
154 if (!RfsdLoadInode(Vcb
, &(ParentMcb
->Key
), &in
)) {
155 Status
= STATUS_OBJECT_NAME_NOT_FOUND
;
159 // Sanity check that we loaded a directory (unless we loaded the last token, in which case it's ok that we loaded something else??)
160 if (!S_ISDIR(in
.i_mode
)) {
161 if (i
< FullFileName
->Length
/2) {
162 Status
= STATUS_OBJECT_NAME_NOT_FOUND
;
168 Status
= RfsdScanDir (
173 &(DirectoryEntry
) ); // <
175 if (!NT_SUCCESS(Status
)) {
176 // No such file (or an error occurred), so drop out.
179 if (i >= FullFileName->Length/2)
181 *RfsdMcb = ParentMcb;
185 // We've found what we were looking for...
186 #if 0 // disabled by ffs too
187 if (IsFlagOn( SUPER_BLOCK
->s_feature_incompat
,
188 RFSD_FEATURE_INCOMPAT_FILETYPE
)) {
189 if (rfsd_dir
.file_type
== RFSD_FT_DIR
)
190 SetFlag(FileAttr
, FILE_ATTRIBUTE_DIRECTORY
);
194 RFSD_KEY_IN_MEMORY key
;
195 key
.k_dir_id
= DirectoryEntry
.deh_dir_id
;
196 key
.k_objectid
= DirectoryEntry
.deh_objectid
;
198 if (!RfsdLoadInode(Vcb
, &key
, &in
)) {
199 Status
= STATUS_OBJECT_NAME_NOT_FOUND
;
202 if (S_ISDIR(in
.i_mode
)) {
203 SetFlag(FileAttr
, FILE_ATTRIBUTE_DIRECTORY
);
207 SetFlag(ParentMcb
->Flags
, MCB_IN_USE
);
208 Mcb
= RfsdAllocateMcb(Vcb
, &FileName
, FileAttr
);
209 ClearFlag(ParentMcb
->Flags
, MCB_IN_USE
);
212 Status
= STATUS_OBJECT_NAME_NOT_FOUND
;
216 // NOTE: It should be OK to leave off the 3rd / 4th part of key, because (AFAIK) the only place this is used is ScanDir
217 Mcb
->Key
.k_dir_id
= DirectoryEntry
.deh_dir_id
;
218 Mcb
->Key
.k_objectid
= DirectoryEntry
.deh_objectid
;
219 Mcb
->Key
.k_offset
= Mcb
->Key
.k_type
= 0;
222 RfsdAddMcbNode(Vcb
, ParentMcb
, Mcb
);
229 if (NT_SUCCESS(Status
)) {
230 // If the name has been found, load it according to the inode number in the MCB...
231 // The result will be returned to the caller via Inode
234 if (!RfsdLoadInode(Vcb
, &(Mcb
->Key
), Inode
)) {
235 RfsdPrint((DBG_ERROR
, "RfsdLookupFileName: error loading Inode %x,%xh\n",
236 Mcb
->Key
.k_dir_id
, Mcb
->Key
.k_objectid
));
237 Status
= STATUS_INSUFFICIENT_RESOURCES
;
245 /** (This function is only called by LookupFileName.)
246 NOTE: The offset and type of the key passed are irrelevant, as the function will always open a a directory for searching, and will search for the contents by file name -- not key.
248 STATUS_INSUFFICIENT_RESOURCES if the filename or diskreading buffer could not be allocated
249 STATUS_UNSUCCESSFUL if the buffer could not be read from disk
250 STATUS_NO_SUCH_FILE if the FileName given was not found in the directory scanned
253 RfsdScanDir (IN PRFSD_VCB Vcb
,
254 IN PRFSD_MCB ParentMcb
, // Mcb of the directory to be scanned (which holds the ->Key of the directory)
255 IN PUNICODE_STRING FileName
, // Short file name (not necisarilly null-terminated!)
256 IN OUT PULONG Index
, // Offset (in bytes) of the dentry relative to the start of the directory listing
257 IN OUT PRFSD_DENTRY_HEAD rfsd_dir
) // Directory entry of the found item
259 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
260 RFSD_KEY_IN_MEMORY DirectoryKey
;
264 // Construct the key (for the directory to be searched), by copying the structure
265 DirectoryKey
= ParentMcb
->Key
;
266 DirectoryKey
.k_offset
= 0x1;
267 DirectoryKey
.k_type
= RFSD_KEY_TYPE_v2_DIRENTRY
;
269 // Request that the filesystem tree be parsed, looking for FileName in directory spans belonging to DirectoryKey
271 RFSD_SCANDIR_CALLBACK_CONTEXT CallbackContext
;
273 CallbackContext
.Vcb
= Vcb
;
274 CallbackContext
.pDirectoryKey
= &DirectoryKey
;
275 CallbackContext
.pTargetFilename
= FileName
;
277 CallbackContext
.idxCurrentDentry
= 0;
279 CallbackContext
.pMatchingDentry
= rfsd_dir
;
280 CallbackContext
.pMatchingIndex
= Index
;
282 Status
= RfsdParseFilesystemTree(Vcb
, &DirectoryKey
, Vcb
->SuperBlock
->s_root_block
, &RfsdScanDirCallback
, &CallbackContext
);
284 if (Status
== STATUS_EVENT_DONE
)
286 Status
= STATUS_SUCCESS
;
288 else if (Status
== STATUS_SUCCESS
)
290 Status
= STATUS_NO_SUCH_FILE
;
294 Status
= STATUS_UNSUCCESSFUL
;
298 RfsdPrint((DBG_TRACE
, /*__FUNCTION__*/ " returning %s\n", RfsdNtStatusToString(Status
)));
302 __drv_mustHoldCriticalRegion
304 RfsdCreateFile(PRFSD_IRP_CONTEXT IrpContext
, PRFSD_VCB Vcb
)
306 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
307 PIO_STACK_LOCATION IrpSp
;
308 PRFSD_FCB Fcb
= NULL
;
309 PRFSD_MCB RfsdMcb
= NULL
;
311 PRFSD_FCB ParentFcb
= NULL
;
312 PRFSD_MCB ParentMcb
= NULL
;
314 BOOLEAN bParentFcbCreated
= FALSE
;
316 PRFSD_CCB Ccb
= NULL
;
317 PRFSD_INODE Inode
= 0;
318 BOOLEAN VcbResourceAcquired
= FALSE
;
320 BOOLEAN bDir
= FALSE
;
322 BOOLEAN bFcbAllocated
= FALSE
;
323 BOOLEAN bCreated
= FALSE
;
324 UNICODE_STRING FileName
;
328 ULONG CreateDisposition
;
330 BOOLEAN OpenDirectory
;
331 BOOLEAN OpenTargetDirectory
;
332 BOOLEAN CreateDirectory
;
333 BOOLEAN SequentialOnly
;
334 BOOLEAN NoIntermediateBuffering
;
335 BOOLEAN IsPagingFile
;
336 BOOLEAN DirectoryFile
;
337 BOOLEAN NonDirectoryFile
;
338 BOOLEAN NoEaKnowledge
;
339 BOOLEAN DeleteOnClose
;
340 BOOLEAN TemporaryFile
;
341 BOOLEAN CaseSensitive
;
343 ACCESS_MASK DesiredAccess
;
348 Irp
= IrpContext
->Irp
;
349 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
351 Options
= IrpSp
->Parameters
.Create
.Options
;
353 DirectoryFile
= IsFlagOn(Options
, FILE_DIRECTORY_FILE
);
354 OpenTargetDirectory
= IsFlagOn(IrpSp
->Flags
, SL_OPEN_TARGET_DIRECTORY
);
356 NonDirectoryFile
= IsFlagOn(Options
, FILE_NON_DIRECTORY_FILE
);
357 SequentialOnly
= IsFlagOn(Options
, FILE_SEQUENTIAL_ONLY
);
358 NoIntermediateBuffering
= IsFlagOn( Options
, FILE_NO_INTERMEDIATE_BUFFERING
);
359 NoEaKnowledge
= IsFlagOn(Options
, FILE_NO_EA_KNOWLEDGE
);
360 DeleteOnClose
= IsFlagOn(Options
, FILE_DELETE_ON_CLOSE
);
362 CaseSensitive
= IsFlagOn(IrpSp
->Flags
, SL_CASE_SENSITIVE
);
364 TemporaryFile
= IsFlagOn(IrpSp
->Parameters
.Create
.FileAttributes
,
365 FILE_ATTRIBUTE_TEMPORARY
);
367 CreateDisposition
= (Options
>> 24) & 0x000000ff;
369 IsPagingFile
= IsFlagOn(IrpSp
->Flags
, SL_OPEN_PAGING_FILE
);
371 CreateDirectory
= (BOOLEAN
)(DirectoryFile
&&
372 ((CreateDisposition
== FILE_CREATE
) ||
373 (CreateDisposition
== FILE_OPEN_IF
)));
375 OpenDirectory
= (BOOLEAN
)(DirectoryFile
&&
376 ((CreateDisposition
== FILE_OPEN
) ||
377 (CreateDisposition
== FILE_OPEN_IF
)));
379 DesiredAccess
= IrpSp
->Parameters
.Create
.SecurityContext
->DesiredAccess
;
380 ShareAccess
= IrpSp
->Parameters
.Create
.ShareAccess
;
382 FileName
.Buffer
= NULL
;
386 ExAcquireResourceExclusiveLite(
387 &Vcb
->MainResource
, TRUE
);
389 VcbResourceAcquired
= TRUE
;
391 if (Irp
->Overlay
.AllocationSize
.HighPart
) {
392 Status
= STATUS_INVALID_PARAMETER
;
396 if (!(Inode
= ExAllocatePoolWithTag(
397 PagedPool
, sizeof(RFSD_INODE
), RFSD_POOL_TAG
) )) {
401 RtlZeroMemory(Inode
, sizeof(RFSD_INODE
));
403 FileName
.MaximumLength
= IrpSp
->FileObject
->FileName
.MaximumLength
;
404 FileName
.Length
= IrpSp
->FileObject
->FileName
.Length
;
406 FileName
.Buffer
= ExAllocatePoolWithTag(PagedPool
, FileName
.MaximumLength
, RFSD_POOL_TAG
);
407 if (!FileName
.Buffer
) {
408 Status
= STATUS_INSUFFICIENT_RESOURCES
;
412 RtlZeroMemory(FileName
.Buffer
, FileName
.MaximumLength
);
413 RtlCopyMemory(FileName
.Buffer
, IrpSp
->FileObject
->FileName
.Buffer
, FileName
.Length
);
415 if (IrpSp
->FileObject
->RelatedFileObject
) {
416 ParentFcb
= (PRFSD_FCB
)(IrpSp
->FileObject
->RelatedFileObject
->FsContext
);
419 if ((FileName
.Length
> sizeof(WCHAR
)) &&
420 (FileName
.Buffer
[1] == L
'\\') &&
421 (FileName
.Buffer
[0] == L
'\\')) {
423 FileName
.Length
-= sizeof(WCHAR
);
425 RtlMoveMemory( &FileName
.Buffer
[0],
430 // Bad Name if there are still beginning backslashes.
433 if ((FileName
.Length
> sizeof(WCHAR
)) &&
434 (FileName
.Buffer
[1] == L
'\\') &&
435 (FileName
.Buffer
[0] == L
'\\')) {
437 Status
= STATUS_OBJECT_NAME_INVALID
;
443 if (IsFlagOn(Options
, FILE_OPEN_BY_FILE_ID
)) {
444 Status
= STATUS_NOT_IMPLEMENTED
;
448 RfsdPrint((DBG_INFO
, "RfsdCreateFile: %S (NameLen=%xh) Paging=%xh Option: %xh.\n",
449 FileName
.Buffer
, FileName
.Length
, IsPagingFile
, IrpSp
->Parameters
.Create
.Options
));
452 ParentMcb
= ParentFcb
->RfsdMcb
;
455 Status
= RfsdLookupFileName(
462 if (!NT_SUCCESS(Status
)) {
463 UNICODE_STRING PathName
;
464 UNICODE_STRING RealName
;
465 UNICODE_STRING RemainName
;
473 RfsdPrint((DBG_INFO
, "RfsdCreateFile: File %S will be created.\n", PathName
.Buffer
));
477 if (PathName
.Buffer
[PathName
.Length
/2 - 1] == L
'\\') {
480 PathName
.Buffer
[PathName
.Length
/2] = 0;
482 Status
= STATUS_NOT_A_DIRECTORY
;
488 if (PathName
.Buffer
[0] != L
'\\') {
489 Status
= STATUS_OBJECT_PATH_NOT_FOUND
;
492 ParentMcb
= Vcb
->McbTree
;
498 FsRtlDissectName(PathName
, &RealName
, &RemainName
);
500 if (((RemainName
.Length
!= 0) && (RemainName
.Buffer
[0] == L
'\\')) ||
501 (RealName
.Length
>= 256*sizeof(WCHAR
))) {
502 Status
= STATUS_OBJECT_NAME_INVALID
;
506 if (RemainName
.Length
!= 0) {
510 Status
= RfsdLookupFileName (
517 if (!NT_SUCCESS(Status
)) {
518 Status
= STATUS_OBJECT_PATH_NOT_FOUND
;
523 PathName
= RemainName
;
528 if (FsRtlDoesNameContainWildCards(&RealName
)) {
529 Status
= STATUS_OBJECT_NAME_INVALID
;
533 ParentFcb
= ParentMcb
->RfsdFcb
;
537 PRFSD_INODE pTmpInode
= ExAllocatePoolWithTag(PagedPool
,
538 sizeof(RFSD_INODE
), RFSD_POOL_TAG
);
540 Status
= STATUS_INSUFFICIENT_RESOURCES
;
544 if(!RfsdLoadInode(Vcb
, &(ParentMcb
->Key
), pTmpInode
)) {
546 ExFreePool(pTmpInode
);
548 Status
= STATUS_OBJECT_PATH_NOT_FOUND
;
552 ParentFcb
= RfsdAllocateFcb(Vcb
, ParentMcb
, pTmpInode
);
555 ExFreePool(pTmpInode
);
556 Status
= STATUS_INSUFFICIENT_RESOURCES
;
560 bParentFcbCreated
= TRUE
;
561 ParentFcb
->ReferenceCount
++;
564 // We need to create a new one ?
565 if ((CreateDisposition
== FILE_CREATE
) ||
566 (CreateDisposition
== FILE_OPEN_IF
) ||
567 (CreateDisposition
== FILE_OVERWRITE_IF
)) {
569 if (IsFlagOn(Vcb
->Flags
, VCB_READ_ONLY
)) {
570 Status
= STATUS_MEDIA_WRITE_PROTECTED
;
574 if (IsFlagOn(Vcb
->Flags
, VCB_WRITE_PROTECTED
)) {
575 IoSetHardErrorOrVerifyDevice( IrpContext
->Irp
,
576 Vcb
->Vpb
->RealDevice
);
577 SetFlag(Vcb
->Vpb
->RealDevice
->Flags
, DO_VERIFY_VOLUME
);
579 RfsdRaiseStatus(IrpContext
, STATUS_MEDIA_WRITE_PROTECTED
);
584 Status
= STATUS_INVALID_PARAMETER
;
590 Status
= STATUS_OBJECT_PATH_NOT_FOUND
;
595 if ( RFSD_IS_ROOT_KEY(ParentFcb
->RfsdMcb
->Key
) ) {
596 if ( (RealName
.Length
== 0x10) &&
597 memcmp(RealName
.Buffer
, L
"Recycled\0", 0x10) == 0) {
598 SetFlag( IrpSp
->Parameters
.Create
.FileAttributes
,
599 FILE_ATTRIBUTE_READONLY
);
603 Status
= STATUS_UNSUCCESSFUL
;
605 Status
= RfsdCreateInode( IrpContext
,
609 IrpSp
->Parameters
.Create
.FileAttributes
,
613 Status
= STATUS_UNSUCCESSFUL
;
615 Status
= RfsdCreateInode( IrpContext
,
619 IrpSp
->Parameters
.Create
.FileAttributes
,
624 if (NT_SUCCESS(Status
)) {
628 Irp
->IoStatus
.Information
= FILE_CREATED
;
629 Status
= RfsdLookupFileName (
636 if (NT_SUCCESS(Status
)) {
640 #if DISABLED // dirctl.c [ see also in cleanup.c ]
641 RfsdNotifyReportChange(
645 FILE_NOTIFY_CHANGE_DIR_NAME
,
648 RfsdNotifyReportChange(
652 FILE_NOTIFY_CHANGE_FILE_NAME
,
662 } else if (OpenTargetDirectory
) {
663 if (IsFlagOn(Vcb
->Flags
, VCB_READ_ONLY
)) {
664 Status
= STATUS_MEDIA_WRITE_PROTECTED
;
669 Status
= STATUS_OBJECT_PATH_NOT_FOUND
;
673 RtlZeroMemory( IrpSp
->FileObject
->FileName
.Buffer
,
674 IrpSp
->FileObject
->FileName
.MaximumLength
);
675 IrpSp
->FileObject
->FileName
.Length
= RealName
.Length
;
677 RtlCopyMemory( IrpSp
->FileObject
->FileName
.Buffer
,
683 Irp
->IoStatus
.Information
= FILE_DOES_NOT_EXIST
;
684 Status
= STATUS_SUCCESS
;
686 Status
= STATUS_OBJECT_NAME_NOT_FOUND
;
690 } else { // File / Dir already exists.
692 if (OpenTargetDirectory
) {
694 if (IsFlagOn(Vcb
->Flags
, VCB_READ_ONLY
)) {
695 Status
= STATUS_MEDIA_WRITE_PROTECTED
;
699 Irp
->IoStatus
.Information
= FILE_EXISTS
;
700 Status
= STATUS_SUCCESS
;
702 RtlZeroMemory( IrpSp
->FileObject
->FileName
.Buffer
,
703 IrpSp
->FileObject
->FileName
.MaximumLength
);
704 IrpSp
->FileObject
->FileName
.Length
= RfsdMcb
->ShortName
.Length
;
706 RtlCopyMemory( IrpSp
->FileObject
->FileName
.Buffer
,
707 RfsdMcb
->ShortName
.Buffer
,
708 RfsdMcb
->ShortName
.Length
);
710 //Let Mcb pointer to it's parent
711 RfsdMcb
= RfsdMcb
->Parent
;
716 // We can not create if one exists
717 if (CreateDisposition
== FILE_CREATE
) {
718 Irp
->IoStatus
.Information
= FILE_EXISTS
;
719 Status
= STATUS_OBJECT_NAME_COLLISION
;
723 if(IsFlagOn(RfsdMcb
->FileAttr
, FILE_ATTRIBUTE_DIRECTORY
)) {
725 if ((CreateDisposition
!= FILE_OPEN
) &&
726 (CreateDisposition
!= FILE_OPEN_IF
)) {
728 Status
= STATUS_OBJECT_NAME_COLLISION
;
732 if (NonDirectoryFile
) {
733 Status
= STATUS_FILE_IS_A_DIRECTORY
;
737 if (RFSD_IS_ROOT_KEY(RfsdMcb
->Key
)) {
740 Status
= STATUS_CANNOT_DELETE
;
744 if (OpenTargetDirectory
) {
745 Status
= STATUS_INVALID_PARAMETER
;
751 Irp
->IoStatus
.Information
= FILE_OPENED
;
758 Fcb
= RfsdMcb
->RfsdFcb
;
761 Fcb
= RfsdAllocateFcb (Vcb
, RfsdMcb
, Inode
);
762 bFcbAllocated
= TRUE
;
768 if (IsFlagOn(Fcb
->Flags
, FCB_FILE_DELETED
)) {
769 Status
= STATUS_FILE_DELETED
;
773 if (FlagOn(Fcb
->Flags
, FCB_DELETE_PENDING
)) {
774 Status
= STATUS_DELETE_PENDING
;
780 #if DISABLED // ONLY FOR WRITE SUPPORT?
783 // This file is just created.
787 UNICODE_STRING EntryName
;
790 RtlZeroMemory(&NameBuf
, 6 * sizeof(USHORT
));
792 EntryName
.Length
= EntryName
.MaximumLength
= 2;
793 EntryName
.Buffer
= &NameBuf
[0];
794 NameBuf
[0] = (USHORT
)'.';
796 RfsdAddEntry( IrpContext
, Vcb
, Fcb
,
801 RfsdSaveInode( IrpContext
, Vcb
,
805 EntryName
.Length
= EntryName
.MaximumLength
= 4;
806 EntryName
.Buffer
= &NameBuf
[0];
807 NameBuf
[0] = NameBuf
[1] = (USHORT
)'.';
809 RfsdAddEntry( IrpContext
, Vcb
, Fcb
,
811 Fcb
->RfsdMcb
->Parent
->Inode
,
814 RfsdSaveInode( IrpContext
, Vcb
,
815 Fcb
->RfsdMcb
->Parent
->Inode
,
820 Status
= RfsdExpandFile(
821 IrpContext
, Vcb
, Fcb
,
822 &(Irp
->Overlay
.AllocationSize
));
825 if (!NT_SUCCESS(Status
)) {
836 // This file alreayd exists.
841 if (IsFlagOn(Vcb
->Flags
, VCB_READ_ONLY
)) {
842 Status
= STATUS_MEDIA_WRITE_PROTECTED
;
846 if (IsFlagOn(Vcb
->Flags
, VCB_WRITE_PROTECTED
)) {
847 Status
= STATUS_MEDIA_WRITE_PROTECTED
;
849 IoSetHardErrorOrVerifyDevice( IrpContext
->Irp
,
850 Vcb
->Vpb
->RealDevice
);
852 SetFlag(Vcb
->Vpb
->RealDevice
->Flags
, DO_VERIFY_VOLUME
);
854 RfsdRaiseStatus(IrpContext
, STATUS_MEDIA_WRITE_PROTECTED
);
857 SetFlag(Fcb
->Flags
, FCB_DELETE_ON_CLOSE
);
862 // Just to Open file (Open/OverWrite ...)
865 if ((!IsDirectory(Fcb
)) && (IsFlagOn(IrpSp
->FileObject
->Flags
,
866 FO_NO_INTERMEDIATE_BUFFERING
))) {
867 Fcb
->Header
.IsFastIoPossible
= FastIoIsPossible
;
869 if (IsFlagOn(IrpSp
->FileObject
->Flags
, FO_CACHE_SUPPORTED
) &&
870 (Fcb
->SectionObject
.DataSectionObject
!= NULL
)) {
872 if (Fcb
->NonCachedOpenCount
== Fcb
->OpenHandleCount
) {
873 /* IsFlagOn(FileObject->Flags, FO_FILE_MODIFIED) */
875 if(!IsFlagOn(Vcb
->Flags
, VCB_READ_ONLY
)) {
876 CcFlushCache(&Fcb
->SectionObject
, NULL
, 0, NULL
);
877 ClearFlag(Fcb
->Flags
, FCB_FILE_MODIFIED
);
880 CcPurgeCacheSection(&Fcb
->SectionObject
,
890 if (!IsDirectory(Fcb
)) {
891 if (!IsFlagOn(Vcb
->Flags
, VCB_READ_ONLY
)) {
892 if ((CreateDisposition
== FILE_SUPERSEDE
) && !IsPagingFile
){
893 DesiredAccess
|= DELETE
;
894 } else if (((CreateDisposition
== FILE_OVERWRITE
) ||
895 (CreateDisposition
== FILE_OVERWRITE_IF
)) && !IsPagingFile
) {
896 DesiredAccess
|= (FILE_WRITE_DATA
| FILE_WRITE_EA
|
897 FILE_WRITE_ATTRIBUTES
);
902 if (Fcb
->OpenHandleCount
> 0) {
903 Status
= IoCheckShareAccess( DesiredAccess
,
909 if (!NT_SUCCESS(Status
)) {
913 IoSetShareAccess( DesiredAccess
,
916 &(Fcb
->ShareAccess
) );
919 Ccb
= RfsdAllocateCcb();
921 Fcb
->OpenHandleCount
++;
922 Fcb
->ReferenceCount
++;
924 if (IsFlagOn(IrpSp
->FileObject
->Flags
, FO_NO_INTERMEDIATE_BUFFERING
)) {
925 Fcb
->NonCachedOpenCount
++;
928 Vcb
->OpenFileHandleCount
++;
929 Vcb
->ReferenceCount
++;
931 IrpSp
->FileObject
->FsContext
= (void*)Fcb
;
932 IrpSp
->FileObject
->FsContext2
= (void*) Ccb
;
933 IrpSp
->FileObject
->PrivateCacheMap
= NULL
;
934 IrpSp
->FileObject
->SectionObjectPointer
= &(Fcb
->SectionObject
);
935 IrpSp
->FileObject
->Vpb
= Vcb
->Vpb
;
937 Status
= STATUS_SUCCESS
;
939 RfsdPrint((DBG_INFO
, "RfsdCreateFile: %s OpenCount: %u ReferCount: %u\n",
940 Fcb
->AnsiFileName
.Buffer
, Fcb
->OpenHandleCount
, Fcb
->ReferenceCount
));
942 if (!IsDirectory(Fcb
) && !NoIntermediateBuffering
) {
943 IrpSp
->FileObject
->Flags
|= FO_CACHE_SUPPORTED
;
946 if (!bCreated
&& !IsDirectory(Fcb
)) {
947 if ( DeleteOnClose
||
948 IsFlagOn(DesiredAccess
, FILE_WRITE_DATA
) ||
949 (CreateDisposition
== FILE_OVERWRITE
) ||
950 (CreateDisposition
== FILE_OVERWRITE_IF
)) {
951 if (!MmFlushImageSection( &Fcb
->SectionObject
,
954 Status
= DeleteOnClose
? STATUS_CANNOT_DELETE
:
955 STATUS_SHARING_VIOLATION
;
960 if ((CreateDisposition
== FILE_SUPERSEDE
) ||
961 (CreateDisposition
== FILE_OVERWRITE
) ||
962 (CreateDisposition
== FILE_OVERWRITE_IF
)) {
965 Status
= STATUS_MEDIA_WRITE_PROTECTED
;
971 if (IsFlagOn(Vcb
->Flags
, VCB_READ_ONLY
)) {
972 Status
= STATUS_MEDIA_WRITE_PROTECTED
;
976 if (IsFlagOn(Vcb
->Flags
, VCB_WRITE_PROTECTED
)) {
978 IoSetHardErrorOrVerifyDevice( IrpContext
->Irp
,
979 Vcb
->Vpb
->RealDevice
);
980 SetFlag(Vcb
->Vpb
->RealDevice
->Flags
, DO_VERIFY_VOLUME
);
982 RfsdRaiseStatus(IrpContext
, STATUS_MEDIA_WRITE_PROTECTED
);
985 Status
= RfsdSupersedeOrOverWriteFile( IrpContext
,
990 if (NT_SUCCESS(Status
)) {
996 Status
= RfsdExpandFile(
1000 &(Irp
->Overlay
.AllocationSize
));
1003 if (!(NT_SUCCESS(Status
))) {
1008 #if DISABLED // dirctl.c
1009 RfsdNotifyReportChange(
1013 FILE_NOTIFY_CHANGE_LAST_WRITE
|
1014 FILE_NOTIFY_CHANGE_ATTRIBUTES
|
1015 FILE_NOTIFY_CHANGE_SIZE
,
1016 FILE_ACTION_MODIFIED
);
1019 if (CreateDisposition
== FILE_SUPERSEDE
) {
1020 Irp
->IoStatus
.Information
= FILE_SUPERSEDED
;
1022 Irp
->IoStatus
.Information
= FILE_OVERWRITTEN
;
1030 if (FileName
.Buffer
)
1031 ExFreePool(FileName
.Buffer
);
1033 if (bParentFcbCreated
) {
1034 ParentFcb
->ReferenceCount
--;
1037 if (VcbResourceAcquired
) {
1038 ExReleaseResourceForThreadLite(
1040 ExGetCurrentResourceThread() );
1043 if (!bFcbAllocated
) {
1055 __drv_mustHoldCriticalRegion
1057 RfsdCreateVolume(PRFSD_IRP_CONTEXT IrpContext
, PRFSD_VCB Vcb
)
1059 PIO_STACK_LOCATION IrpSp
;
1064 ACCESS_MASK DesiredAccess
;
1068 BOOLEAN DirectoryFile
;
1069 BOOLEAN OpenTargetDirectory
;
1071 ULONG CreateDisposition
;
1075 RfsdPrint((DBG_FUNC
, "Entering CreateVolume\n"));
1077 Irp
= IrpContext
->Irp
;
1078 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1080 Options
= IrpSp
->Parameters
.Create
.Options
;
1082 DirectoryFile
= IsFlagOn(Options
, FILE_DIRECTORY_FILE
);
1083 OpenTargetDirectory
= IsFlagOn(IrpSp
->Flags
, SL_OPEN_TARGET_DIRECTORY
);
1085 CreateDisposition
= (Options
>> 24) & 0x000000ff;
1087 DesiredAccess
= IrpSp
->Parameters
.Create
.SecurityContext
->DesiredAccess
;
1088 ShareAccess
= IrpSp
->Parameters
.Create
.ShareAccess
;
1090 if (DirectoryFile
) {
1091 return STATUS_NOT_A_DIRECTORY
;
1094 if (OpenTargetDirectory
) {
1095 return STATUS_INVALID_PARAMETER
;
1098 if ( (CreateDisposition
!= FILE_OPEN
) &&
1099 (CreateDisposition
!= FILE_OPEN_IF
) ) {
1100 return STATUS_ACCESS_DENIED
;
1103 Status
= STATUS_SUCCESS
;
1105 if (Vcb
->OpenHandleCount
> 0) {
1106 Status
= IoCheckShareAccess( DesiredAccess
, ShareAccess
,
1108 &(Vcb
->ShareAccess
), TRUE
);
1110 if (!NT_SUCCESS(Status
)) {
1114 IoSetShareAccess( DesiredAccess
, ShareAccess
,
1116 &(Vcb
->ShareAccess
) );
1119 if (FlagOn(DesiredAccess
, FILE_READ_DATA
| FILE_WRITE_DATA
| FILE_APPEND_DATA
)) {
1120 ExAcquireResourceExclusiveLite(&Vcb
->MainResource
, TRUE
);
1122 RfsdFlushFiles(Vcb
, FALSE
);
1123 RfsdFlushVolume(Vcb
, FALSE
);
1125 ExReleaseResourceLite(&Vcb
->MainResource
);
1129 PRFSD_CCB Ccb
= RfsdAllocateCcb();
1132 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1136 IrpSp
->FileObject
->Flags
|= FO_NO_INTERMEDIATE_BUFFERING
;
1137 IrpSp
->FileObject
->FsContext
= Vcb
;
1138 IrpSp
->FileObject
->FsContext2
= Ccb
;
1140 Vcb
->ReferenceCount
++;
1141 Vcb
->OpenHandleCount
++;
1143 Irp
->IoStatus
.Information
= FILE_OPENED
;
1151 __drv_mustHoldCriticalRegion
1153 RfsdCreate (IN PRFSD_IRP_CONTEXT IrpContext
)
1155 PDEVICE_OBJECT DeviceObject
;
1157 PIO_STACK_LOCATION IrpSp
;
1159 NTSTATUS Status
= STATUS_OBJECT_NAME_NOT_FOUND
;
1160 PRFSD_FCBVCB Xcb
= NULL
;
1164 DeviceObject
= IrpContext
->DeviceObject
;
1166 Vcb
= (PRFSD_VCB
) DeviceObject
->DeviceExtension
;
1168 ASSERT(IsMounted(Vcb
));
1170 Irp
= IrpContext
->Irp
;
1172 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1174 Xcb
= (PRFSD_FCBVCB
) (IrpSp
->FileObject
->FsContext
);
1176 if (DeviceObject
== RfsdGlobal
->DeviceObject
) {
1177 RfsdPrint((DBG_INFO
, "RfsdCreate: Create on main device object.\n"));
1179 Status
= STATUS_SUCCESS
;
1181 Irp
->IoStatus
.Information
= FILE_OPENED
;
1183 RfsdUnpinRepinnedBcbs(IrpContext
);
1185 RfsdCompleteIrpContext(IrpContext
, Status
);
1192 if (IsFlagOn(Vcb
->Flags
, VCB_VOLUME_LOCKED
)) {
1193 Status
= STATUS_ACCESS_DENIED
;
1195 if (IsFlagOn(Vcb
->Flags
, VCB_DISMOUNT_PENDING
)) {
1196 Status
= STATUS_VOLUME_DISMOUNTED
;
1202 if ( ((IrpSp
->FileObject
->FileName
.Length
== 0) &&
1203 (IrpSp
->FileObject
->RelatedFileObject
== NULL
)) ||
1204 (Xcb
&& Xcb
->Identifier
.Type
== RFSDVCB
) ) {
1205 Status
= RfsdCreateVolume(IrpContext
, Vcb
);
1207 Status
= RfsdCreateFile(IrpContext
, Vcb
);
1212 if (!IrpContext
->ExceptionInProgress
) {
1213 RfsdUnpinRepinnedBcbs(IrpContext
);
1215 RfsdCompleteIrpContext(IrpContext
, Status
);
1226 PRFSD_IRP_CONTEXT IrpContext
,
1228 PRFSD_FCB ParentFcb
,
1231 PUNICODE_STRING FileName
)
1240 RtlZeroMemory(&RfsdIno
, sizeof(RFSD_INODE
));
1244 Group
= (ParentFcb
->RfsdMcb
->Inode
- 1) / BLOCKS_PER_GROUP
;
1247 RfsdPrint(( DBG_INFO
,
1248 "RfsdCreateInode: %S in %S(Key=%x,%xh)\n",
1250 ParentFcb
->RfsdMcb
->ShortName
.Buffer
,
1251 ParentFcb
->RfsdMcb
->Key
.k_dir_id
, ParentFcb
->RfsdMcb
->Key
.k_objectid
));
1253 Status
= RfsdNewInode(IrpContext
, Vcb
, Group
,Type
, &Inode
);
1255 if (!NT_SUCCESS(Status
)) {
1259 Status
= RfsdAddEntry(IrpContext
, Vcb
, ParentFcb
, Type
, Inode
, FileName
);
1261 if (!NT_SUCCESS(Status
)) {
1263 RfsdFreeInode(IrpContext
, Vcb
, Inode
, Type
);
1268 RfsdSaveInode(IrpContext
, Vcb
, ParentFcb
->RfsdMcb
->Inode
, ParentFcb
->Inode
);
1270 RfsdIno
.i_ctime
= ParentFcb
->Inode
->i_mtime
;
1271 RfsdIno
.i_mode
= ( S_IPERMISSION_MASK
&
1272 ParentFcb
->Inode
->i_mode
);
1273 RfsdIno
.i_uid
= ParentFcb
->Inode
->i_uid
;
1274 RfsdIno
.i_gid
= ParentFcb
->Inode
->i_gid
;
1276 //~ RfsdIno.i_dir_acl = ParentFcb->Inode->i_dir_acl;
1277 //~ RfsdIno.i_file_acl = ParentFcb->Inode->i_file_acl;
1278 RfsdIno
.u
.i_generation
= ParentFcb
->Inode
->u
.i_generation
;
1280 //~ RfsdIno.osd2 = ParentFcb->Inode->osd2;
1282 if (IsFlagOn(FileAttr
, FILE_ATTRIBUTE_READONLY
)) {
1283 RfsdSetReadOnly(RfsdIno
.i_mode
);
1286 if (Type
== RFSD_FT_DIR
) {
1287 RfsdIno
.i_mode
|= S_IFDIR
;
1288 RfsdIno
.i_links_count
= 2;
1289 } else if (Type
== RFSD_FT_REG_FILE
) {
1290 RfsdIno
.i_mode
|= S_IFREG
;
1291 RfsdIno
.i_links_count
= 1;
1294 RfsdIno
.i_links_count
= 1;
1297 RfsdSaveInode(IrpContext
, Vcb
, Inode
, &RfsdIno
);
1299 RfsdPrint((DBG_INFO
, "RfsdCreateInode: New Inode = %xh (Type=%xh)\n", Inode
, Type
));
1307 RfsdSupersedeOrOverWriteFile(
1308 PRFSD_IRP_CONTEXT IrpContext
,
1313 LARGE_INTEGER CurrentTime
;
1314 LARGE_INTEGER AllocationSize
;
1315 NTSTATUS Status
= STATUS_SUCCESS
;
1319 KeQuerySystemTime(&CurrentTime
);
1321 AllocationSize
.QuadPart
= (LONGLONG
)0;
1323 if (!MmCanFileBeTruncated(&(Fcb
->SectionObject
), &(AllocationSize
))) {
1324 Status
= STATUS_USER_MAPPED_FILE
;
1330 Status
= RfsdTruncateFile(IrpContext
, Vcb
, Fcb
, &AllocationSize
);
1333 if (NT_SUCCESS(Status
)) {
1334 Fcb
->Header
.AllocationSize
.QuadPart
=
1335 Fcb
->Header
.FileSize
.QuadPart
= (LONGLONG
) 0;
1337 Fcb
->Inode
->i_size
= 0;
1339 if (S_ISREG(Fcb
->Inode
->i_mode
)) {
1340 KdPrint(("Reminder: Fcb->Inode->i_size_high = 0;\n"));
1341 //~Fcb->Inode->i_size_high = 0;
1344 if (Disposition
== FILE_SUPERSEDE
)
1345 Fcb
->Inode
->i_ctime
= RfsdInodeTime(CurrentTime
);
1347 Fcb
->Inode
->i_atime
=
1348 Fcb
->Inode
->i_mtime
= RfsdInodeTime(CurrentTime
);
1350 LARGE_INTEGER iSize
;
1352 iSize
.QuadPart
= (LONGLONG
) Fcb
->Inode
->i_size
;
1354 if (S_ISREG(Fcb
->Inode
->i_mode
))
1355 KdPrint(("Reminder: Fcb->Inode->i_size_high = 0;\n"));
1356 //~ iSize.HighPart = (LONG)(Fcb->Inode->i_size_high);
1358 if (iSize
.QuadPart
> Fcb
->Header
.AllocationSize
.QuadPart
)
1359 iSize
.QuadPart
= Fcb
->Header
.AllocationSize
.QuadPart
;
1361 Fcb
->Header
.FileSize
.QuadPart
= iSize
.QuadPart
;
1363 Fcb
->Inode
->i_size
= iSize
.LowPart
;
1364 //~ Fcb->Inode->i_size_high = (ULONG) iSize.HighPart;
1367 RfsdSaveInode(IrpContext
, Vcb
, Fcb
->RfsdMcb
->Inode
, Fcb
->Inode
);
1372 #endif // !RFSD_READ_ONLY
1375 Searches to find if the name if is located in the dentry span within the block.
1377 STATUS_SUCCESS if the name was not found, but processing should continue
1378 STATUS_EVENT_DONE if the name was found, and processing should stop
1381 RfsdScanDirCallback(
1385 PRFSD_SCANDIR_CALLBACK_CONTEXT pCallbackContext
= (PRFSD_SCANDIR_CALLBACK_CONTEXT
) pContext
;
1386 RFSD_KEY_IN_MEMORY DirectoryKey
;
1387 PUCHAR pBlockBuffer
= NULL
;
1388 PRFSD_ITEM_HEAD pDirectoryItemHeader
= NULL
;
1389 PUCHAR pDirectoryItemBuffer
= NULL
;
1391 BOOLEAN bFound
= FALSE
;
1392 PRFSD_DENTRY_HEAD pPrevDentry
= NULL
;
1393 ULONG idxDentryInSpan
= 0;
1394 UNICODE_STRING InodeFileName
;
1395 USHORT InodeFileNameLength
;
1399 InodeFileName
.Buffer
= NULL
;
1401 RfsdPrint((DBG_FUNC
, /*__FUNCTION__*/ " invoked on block %i\n", BlockNumber
));
1407 pBlockBuffer
= RfsdAllocateAndLoadBlock(pCallbackContext
->Vcb
, BlockNumber
);
1408 if (!pBlockBuffer
) { Status
= STATUS_INSUFFICIENT_RESOURCES
; _SEH2_LEAVE
; }
1410 // Construct the item key to search for
1411 DirectoryKey
= *(pCallbackContext
->pDirectoryKey
);
1412 DirectoryKey
.k_type
= RFSD_KEY_TYPE_v2_DIRENTRY
;
1414 // Get the item header and its information
1415 Status
= RfsdFindItemHeaderInBlock(
1416 pCallbackContext
->Vcb
, &DirectoryKey
, pBlockBuffer
,
1417 ( &pDirectoryItemHeader
), //<
1418 &CompareKeysWithoutOffset
1421 // If this block doesn't happen to contain a directory item, skip it.
1422 if ( (Status
== STATUS_NO_SUCH_MEMBER
) || !pDirectoryItemHeader
)
1424 KdPrint(("Block %i did not contain the appropriate diritem header\n", BlockNumber
));
1425 Status
= STATUS_SUCCESS
; _SEH2_LEAVE
;
1428 // Setup the item buffer
1429 pDirectoryItemBuffer
= (PUCHAR
) pBlockBuffer
+ pDirectoryItemHeader
->ih_item_location
;
1433 // Allocate the unicode filename buffer
1434 InodeFileName
.Buffer
= ExAllocatePoolWithTag(PagedPool
, (RFSD_NAME_LEN
+ 1) * 2, RFSD_POOL_TAG
);
1435 if (!InodeFileName
.Buffer
) { Status
= STATUS_INSUFFICIENT_RESOURCES
; _SEH2_LEAVE
; }
1438 while (!bFound
&& (idxDentryInSpan
< pDirectoryItemHeader
->u
.ih_entry_count
) ) {
1442 // reading dir entries from Dcb
1445 PRFSD_DENTRY_HEAD pCurrentDentry
= (PRFSD_DENTRY_HEAD
) (pDirectoryItemBuffer
+ (idxDentryInSpan
* sizeof(RFSD_DENTRY_HEAD
)));
1447 // Skip the directory entry for the parent of the root directory (because it should not be shown, and has no stat data)
1448 // (NOTE: Any change made here should also be mirrored in RfsdDirControlCallback)
1449 if (pCurrentDentry
->deh_dir_id
== 0 /*&& pCurrentDentry->deh_objectid == 1*/)
1450 { goto ProcessNextEntry
; }
1452 // Retrieve the filename of the loaded directory entry from the buffer (encoded with the codepage)
1453 // NOTE: The filename is not gauranteed to be null-terminated, and so the end may implicitly be the start of the previous entry.
1454 OemName
.Buffer
= (PUCHAR
) pDirectoryItemBuffer
+ pCurrentDentry
->deh_location
;
1455 OemName
.MaximumLength
= (pPrevDentry
? pPrevDentry
->deh_location
: // The end of this entry is the start of the previous
1456 pDirectoryItemHeader
->ih_item_len
// Otherwise this is the first entry, the end of which is the end of the item.
1457 ) - pCurrentDentry
->deh_location
;
1458 OemName
.Length
= RfsdStringLength(OemName
.Buffer
, OemName
.MaximumLength
);
1462 // Convert that name to unicode
1464 InodeFileNameLength
= (USHORT
) RfsdOEMToUnicodeSize(&OemName
) + 2;
1466 // If the unicode InodeFileName.Buffer is not large enough, expand it
1467 if (InodeFileName
.MaximumLength
< InodeFileNameLength
)
1469 // Free the existing buffer
1470 if (InodeFileName
.Buffer
) { ExFreePool(InodeFileName
.Buffer
); }
1472 // Allocate a new larger buffer
1473 InodeFileName
.Buffer
= ExAllocatePoolWithTag(PagedPool
, InodeFileNameLength
, RFSD_POOL_TAG
);
1474 if (!InodeFileName
.Buffer
) { Status
= STATUS_INSUFFICIENT_RESOURCES
; _SEH2_LEAVE
; }
1475 InodeFileName
.MaximumLength
= InodeFileNameLength
;
1478 InodeFileName
.Length
= 0;
1480 RtlZeroMemory( InodeFileName
.Buffer
, InodeFileNameLength
);
1482 Status
= RfsdOEMToUnicode(
1486 if (!NT_SUCCESS(Status
)) { _SEH2_LEAVE
; }
1490 // Compare it to the name we are searching for
1491 if (!RtlCompareUnicodeString(
1492 pCallbackContext
->pTargetFilename
,
1495 // This entry MATCHED! Copy the matching dentry into the output field on the context
1498 *(pCallbackContext
->pMatchingIndex
) = (pCallbackContext
->idxCurrentDentry
* sizeof(RFSD_DENTRY_HEAD
));
1499 RtlCopyMemory(pCallbackContext
->pMatchingDentry
, pCurrentDentry
, sizeof(RFSD_DENTRY_HEAD
));
1501 RfsdPrint(( DBG_INFO
, /*__FUNCTION__*/ ": Found: Name=%S Key=%xh,%xh\n",
1502 InodeFileName
.Buffer
, pCurrentDentry
->deh_dir_id
, pCurrentDentry
->deh_objectid
));
1504 Status
= STATUS_EVENT_DONE
;
1509 // Advance to the next directory entry
1510 pPrevDentry
= pCurrentDentry
;
1512 ++(pCallbackContext
->idxCurrentDentry
);
1516 // Indicate success, so that parsing will continue with subsequent blocks.
1517 Status
= STATUS_SUCCESS
;
1520 if (pBlockBuffer
) ExFreePool(pBlockBuffer
);
1521 if (InodeFileName
.Buffer
) ExFreePool(InodeFileName
.Buffer
);