2 * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
3 * Copyright (c) 2009, 2010, 2011 Your File System, Inc.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * - Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
14 * this list of conditions and the following disclaimer in the
16 * and/or other materials provided with the distribution.
17 * - Neither the names of Kernel Drivers, LLC and Your File System, Inc.
18 * nor the names of their contributors may be used to endorse or promote
19 * products derived from this software without specific prior written
20 * permission from Kernel Drivers, LLC and Your File System, Inc.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
26 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 // File: AFSNameSupport.cpp
39 #include "AFSCommon.h"
42 AFSLocateNameEntry( IN GUID *AuthGroup,
43 IN PFILE_OBJECT FileObject,
44 IN UNICODE_STRING *RootPathName,
45 IN UNICODE_STRING *ParsedPathName,
46 IN AFSNameArrayHdr *NameArray,
48 OUT AFSVolumeCB **VolumeCB,
49 IN OUT AFSDirectoryCB **ParentDirectoryCB,
50 OUT AFSDirectoryCB **DirectoryCB,
51 OUT PUNICODE_STRING ComponentName)
54 NTSTATUS ntStatus = STATUS_SUCCESS;
55 UNICODE_STRING uniPathName, uniComponentName, uniRemainingPath, uniSearchName, uniFullPathName;
57 AFSDirectoryCB *pDirEntry = NULL, *pParentDirEntry = NULL;
58 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
59 UNICODE_STRING uniSysName;
60 ULONG ulSubstituteIndex = 0;
61 BOOLEAN bSubstituteName = FALSE;
62 AFSNameArrayHdr *pNameArray = NameArray;
63 BOOLEAN bAllocatedSymLinkBuffer = FALSE;
64 UNICODE_STRING uniRelativeName, uniNoOpName;
65 AFSObjectInfoCB *pCurrentObject = NULL;
66 AFSObjectInfoCB *pParentObjectInfo = NULL;
67 AFSVolumeCB *pCurrentVolume = *VolumeCB;
68 BOOLEAN bReleaseCurrentVolume = TRUE;
69 BOOLEAN bSubstitutedName = FALSE;
75 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
76 AFS_TRACE_LEVEL_VERBOSE_2,
77 "AFSLocateNameEntry (FO: %08lX) Processing full name %wZ\n",
81 RtlInitUnicodeString( &uniSysName,
84 RtlInitUnicodeString( &uniRelativeName,
87 RtlInitUnicodeString( &uniNoOpName,
91 // Cleanup some parameters
94 if( ComponentName != NULL)
97 ComponentName->Length = 0;
98 ComponentName->MaximumLength = 0;
99 ComponentName->Buffer = NULL;
103 // We will parse through the filename, locating the directory nodes until we encounter a cache miss
104 // Starting at the root node
107 pParentDirEntry = NULL;
109 pDirEntry = *ParentDirectoryCB;
111 uniPathName = *ParsedPathName;
113 uniFullPathName = *RootPathName;
115 uniComponentName.Length = uniComponentName.MaximumLength = 0;
116 uniComponentName.Buffer = NULL;
118 uniRemainingPath.Length = uniRemainingPath.MaximumLength = 0;
119 uniRemainingPath.Buffer = NULL;
121 uniSearchName.Length = uniSearchName.MaximumLength = 0;
122 uniSearchName.Buffer = NULL;
124 ASSERT( pCurrentVolume->VolumeReferenceCount > 1);
130 // Check our total link count for this name array
133 if( pNameArray->LinkCount >= (LONG)pDevExt->Specific.RDR.MaxLinkCount)
136 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
139 pCurrentObject = pDirEntry->ObjectInformation;
141 KeQueryTickCount( &pCurrentObject->LastAccessCount);
144 // Check that the directory entry is not deleted or pending delete
147 if( BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED))
150 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
151 AFS_TRACE_LEVEL_ERROR,
152 "AFSLocateNameEntry (FO: %08lX) Deleted parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
154 &pDirEntry->NameInformation.FileName,
155 pCurrentObject->FileId.Cell,
156 pCurrentObject->FileId.Volume,
157 pCurrentObject->FileId.Vnode,
158 pCurrentObject->FileId.Unique,
159 STATUS_FILE_DELETED);
161 try_return( ntStatus = STATUS_FILE_DELETED);
164 if( BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_PENDING_DELETE))
167 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
168 AFS_TRACE_LEVEL_ERROR,
169 "AFSLocateNameEntry (FO: %08lX) Delete pending on %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
171 &pDirEntry->NameInformation.FileName,
172 pCurrentObject->FileId.Cell,
173 pCurrentObject->FileId.Volume,
174 pCurrentObject->FileId.Vnode,
175 pCurrentObject->FileId.Unique,
176 STATUS_DELETE_PENDING);
178 try_return( ntStatus = STATUS_DELETE_PENDING);
182 // Check if the directory requires verification
185 if( BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_FLAGS_VERIFY) &&
186 ( pCurrentObject->FileType != AFS_FILE_TYPE_DIRECTORY ||
187 !AFSIsEnumerationInProcess( pCurrentObject)))
190 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
191 AFS_TRACE_LEVEL_VERBOSE,
192 "AFSLocateNameEntry (FO: %08lX) Verifying parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
194 &pDirEntry->NameInformation.FileName,
195 pCurrentObject->FileId.Cell,
196 pCurrentObject->FileId.Volume,
197 pCurrentObject->FileId.Vnode,
198 pCurrentObject->FileId.Unique);
201 // Directory TreeLock should be exclusively held
204 AFSAcquireExcl( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
207 ntStatus = AFSVerifyEntry( AuthGroup,
210 AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
212 if( !NT_SUCCESS( ntStatus))
215 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
216 AFS_TRACE_LEVEL_ERROR,
217 "AFSLocateNameEntry (FO: %08lX) Failed to verify parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
219 &pDirEntry->NameInformation.FileName,
220 pCurrentObject->FileId.Cell,
221 pCurrentObject->FileId.Volume,
222 pCurrentObject->FileId.Vnode,
223 pCurrentObject->FileId.Unique,
226 try_return( ntStatus);
231 // Ensure the parent node has been evaluated, if not then go do it now
234 if( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) ||
235 pCurrentObject->FileType == AFS_FILE_TYPE_UNKNOWN)
238 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
239 AFS_TRACE_LEVEL_VERBOSE,
240 "AFSLocateNameEntry (FO: %08lX) Evaluating parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
242 &pDirEntry->NameInformation.FileName,
243 pCurrentObject->FileId.Cell,
244 pCurrentObject->FileId.Volume,
245 pCurrentObject->FileId.Vnode,
246 pCurrentObject->FileId.Unique);
248 ntStatus = AFSEvaluateNode( AuthGroup,
251 if( !NT_SUCCESS( ntStatus))
254 if ( ntStatus == STATUS_NOT_A_DIRECTORY)
257 if ( pCurrentObject->ParentObjectInformation == NULL)
260 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
261 AFS_TRACE_LEVEL_ERROR,
262 "AFSLocateNameEntry (FO: %08lX) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT NULL Status %08lX\n",
264 &pDirEntry->NameInformation.FileName,
265 pCurrentObject->FileId.Cell,
266 pCurrentObject->FileId.Volume,
267 pCurrentObject->FileId.Vnode,
268 pCurrentObject->FileId.Unique,
274 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
275 AFS_TRACE_LEVEL_ERROR,
276 "AFSLocateNameEntry (FO: %08lX) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT %08lX-%08lX-%08lX-%08lX Status %08lX\n",
278 &pDirEntry->NameInformation.FileName,
279 pCurrentObject->FileId.Cell,
280 pCurrentObject->FileId.Volume,
281 pCurrentObject->FileId.Vnode,
282 pCurrentObject->FileId.Unique,
283 pCurrentObject->ParentObjectInformation->FileId.Cell,
284 pCurrentObject->ParentObjectInformation->FileId.Volume,
285 pCurrentObject->ParentObjectInformation->FileId.Vnode,
286 pCurrentObject->ParentObjectInformation->FileId.Unique,
292 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
293 AFS_TRACE_LEVEL_ERROR,
294 "AFSLocateNameEntry (FO: %08lX) Failed to evaluate parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
296 &pDirEntry->NameInformation.FileName,
297 pCurrentObject->FileId.Cell,
298 pCurrentObject->FileId.Volume,
299 pCurrentObject->FileId.Vnode,
300 pCurrentObject->FileId.Unique,
304 try_return( ntStatus);
307 ClearFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
311 // If this is a mount point or symlink then go get the real directory node
314 switch( pCurrentObject->FileType)
317 case AFS_FILE_TYPE_SYMLINK:
320 UNICODE_STRING uniTempName;
321 WCHAR *pTmpBuffer = NULL;
325 // Check if the flag is set to NOT evaluate a symlink
326 // and we are done with the parsing
329 if( BooleanFlagOn( Flags, AFS_LOCATE_FLAGS_NO_SL_TARGET_EVAL) &&
330 uniRemainingPath.Length == 0)
334 // Pass back the directory entries
337 *ParentDirectoryCB = pParentDirEntry;
339 *DirectoryCB = pDirEntry;
341 *VolumeCB = pCurrentVolume;
343 *RootPathName = uniFullPathName;
345 try_return( ntStatus);
348 AFSAcquireExcl( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
351 AFSAcquireExcl( &pDirEntry->NonPaged->Lock,
354 if( pDirEntry->NameInformation.TargetName.Length == 0)
358 // We'll reset the DV to ensure we validate the metadata content
361 pCurrentObject->DataVersion.QuadPart = (ULONGLONG)-1;
363 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_VERIFY);
365 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
366 AFS_TRACE_LEVEL_VERBOSE,
367 "AFSLocateNameEntry (FO: %08lX) Verifying symlink parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
369 &pDirEntry->NameInformation.FileName,
370 pCurrentObject->FileId.Cell,
371 pCurrentObject->FileId.Volume,
372 pCurrentObject->FileId.Vnode,
373 pCurrentObject->FileId.Unique);
376 // Directory TreeLock should be exclusively held
379 ntStatus = AFSVerifyEntry( AuthGroup,
382 AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
384 if( !NT_SUCCESS( ntStatus))
387 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
388 AFS_TRACE_LEVEL_ERROR,
389 "AFSLocateNameEntry (FO: %08lX) Failed to verify symlink parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
391 &pDirEntry->NameInformation.FileName,
392 pCurrentObject->FileId.Cell,
393 pCurrentObject->FileId.Volume,
394 pCurrentObject->FileId.Vnode,
395 pCurrentObject->FileId.Unique,
398 AFSReleaseResource( &pDirEntry->NonPaged->Lock);
400 try_return( ntStatus);
404 // If the type changed then reprocess this entry
407 if( pCurrentObject->FileType != AFS_FILE_TYPE_SYMLINK)
410 AFSReleaseResource( &pDirEntry->NonPaged->Lock);
418 AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
422 // If we were given a zero length target name then deny access to the entry
425 if( pDirEntry->NameInformation.TargetName.Length == 0)
428 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
430 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
431 AFS_TRACE_LEVEL_ERROR,
432 "AFSLocateNameEntry (FO: %08lX) Failed to retrieve target name for symlink %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
434 &pDirEntry->NameInformation.FileName,
435 pCurrentObject->FileId.Cell,
436 pCurrentObject->FileId.Volume,
437 pCurrentObject->FileId.Vnode,
438 pCurrentObject->FileId.Unique,
441 AFSReleaseResource( &pDirEntry->NonPaged->Lock);
443 try_return( ntStatus);
446 if( AFSIsRelativeName( &pDirEntry->NameInformation.TargetName))
449 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
450 AFS_TRACE_LEVEL_VERBOSE,
451 "AFSLocateNameEntry (FO: %08lX) Processing relative symlink target %wZ for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
453 &pDirEntry->NameInformation.TargetName,
454 &pDirEntry->NameInformation.FileName,
455 pCurrentObject->FileId.Cell,
456 pCurrentObject->FileId.Volume,
457 pCurrentObject->FileId.Vnode,
458 pCurrentObject->FileId.Unique);
461 // We'll substitute this name into the current process name
462 // starting at where we sit in the path
465 uniTempName.Length = 0;
466 uniTempName.MaximumLength = (USHORT)((char *)uniComponentName.Buffer - (char *)uniFullPathName.Buffer) +
467 pDirEntry->NameInformation.TargetName.Length +
469 uniRemainingPath.Length;
471 uniTempName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
472 uniTempName.MaximumLength,
473 AFS_NAME_BUFFER_ONE_TAG);
475 if( uniTempName.Buffer == NULL)
478 AFSReleaseResource( &pDirEntry->NonPaged->Lock);
480 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
484 // We have so first copy in the portion up to the component
488 RtlCopyMemory( uniTempName.Buffer,
489 uniFullPathName.Buffer,
490 (ULONG)((char *)uniComponentName.Buffer - (char *)uniFullPathName.Buffer));
492 uniTempName.Length = (USHORT)((char *)uniComponentName.Buffer - (char *)uniFullPathName.Buffer);
494 if( bAllocatedSymLinkBuffer ||
498 pTmpBuffer = uniFullPathName.Buffer;
501 bAllocatedSymLinkBuffer = TRUE;
504 // Have we parsed this name yet? Better have at least once ...
507 if( uniComponentName.Length == 0)
513 // Copy in the target name ...
516 RtlCopyMemory( &uniTempName.Buffer[ uniTempName.Length/sizeof( WCHAR)],
517 pDirEntry->NameInformation.TargetName.Buffer,
518 pDirEntry->NameInformation.TargetName.Length);
520 uniPathName.Buffer = &uniTempName.Buffer[ uniTempName.Length/sizeof( WCHAR)];
522 uniPathName.Length += pDirEntry->NameInformation.TargetName.Length;
523 uniPathName.MaximumLength = uniTempName.MaximumLength;
525 uniTempName.Length += pDirEntry->NameInformation.TargetName.Length;
528 // And now any remaining portion of the name
531 if( uniRemainingPath.Length > 0)
534 if( uniRemainingPath.Buffer[ 0] != L'\\')
537 uniRemainingPath.Buffer--;
538 uniRemainingPath.Length += sizeof( WCHAR);
540 uniPathName.Length += sizeof( WCHAR);
543 RtlCopyMemory( &uniTempName.Buffer[ uniTempName.Length/sizeof( WCHAR)],
544 uniRemainingPath.Buffer,
545 uniRemainingPath.Length);
547 uniTempName.Length += uniRemainingPath.Length;
550 uniFullPathName = uniTempName;
552 if( pTmpBuffer != NULL)
555 AFSExFreePool( pTmpBuffer);
558 AFSReleaseResource( &pDirEntry->NonPaged->Lock);
561 // Dereference the current entry ..
564 lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
566 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
567 AFS_TRACE_LEVEL_VERBOSE,
568 "AFSLocateNameEntry Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
569 &pDirEntry->NameInformation.FileName,
575 // OK, need to back up one entry for the correct parent since the current
576 // entry we are on is the symlink itself
579 pDirEntry = AFSBackupEntry( pNameArray);
582 // Increment our reference on this dir entry
585 lCount = InterlockedIncrement( &pDirEntry->OpenReferenceCount);
587 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
588 AFS_TRACE_LEVEL_VERBOSE,
589 "AFSLocateNameEntry Increment1 count on %wZ DE %p Ccb %p Cnt %d\n",
590 &pDirEntry->NameInformation.FileName,
595 if( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_ROOT_VOLUME))
598 pParentDirEntry = NULL;
603 pParentDirEntry = AFSGetParentEntry( pNameArray);
605 ASSERT( pParentDirEntry != pDirEntry);
611 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
612 AFS_TRACE_LEVEL_VERBOSE,
613 "AFSLocateNameEntry (FO: %08lX) Processing absolute symlink target %wZ for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
615 &pDirEntry->NameInformation.TargetName,
616 &pDirEntry->NameInformation.FileName,
617 pCurrentObject->FileId.Cell,
618 pCurrentObject->FileId.Volume,
619 pCurrentObject->FileId.Vnode,
620 pCurrentObject->FileId.Unique);
623 // We'll substitute this name into the current process name
624 // starting at where we sit in the path
627 uniTempName.Length = 0;
628 uniTempName.MaximumLength = pDirEntry->NameInformation.TargetName.Length +
630 uniRemainingPath.Length;
632 uniTempName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
633 uniTempName.MaximumLength,
634 AFS_NAME_BUFFER_TWO_TAG);
636 if( uniTempName.Buffer == NULL)
639 AFSReleaseResource( &pDirEntry->NonPaged->Lock);
641 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
644 if( bAllocatedSymLinkBuffer ||
648 pTmpBuffer = uniFullPathName.Buffer;
651 bAllocatedSymLinkBuffer = TRUE;
654 // Have we parsed this name yet? Better have at least once ...
657 if( uniComponentName.Length == 0)
663 // Copy in the target name ...
666 RtlCopyMemory( uniTempName.Buffer,
667 pDirEntry->NameInformation.TargetName.Buffer,
668 pDirEntry->NameInformation.TargetName.Length);
670 uniTempName.Length = pDirEntry->NameInformation.TargetName.Length;
673 // And now any remaining portion of the name
676 if( uniRemainingPath.Length > 0)
679 if( uniRemainingPath.Buffer[ 0] != L'\\')
682 uniRemainingPath.Buffer--;
683 uniRemainingPath.Length += sizeof( WCHAR);
686 RtlCopyMemory( &uniTempName.Buffer[ uniTempName.Length/sizeof( WCHAR)],
687 uniRemainingPath.Buffer,
688 uniRemainingPath.Length);
690 uniTempName.Length += uniRemainingPath.Length;
693 uniFullPathName = uniTempName;
695 uniPathName = uniTempName;
697 if( pTmpBuffer != NULL)
700 AFSExFreePool( pTmpBuffer);
703 AFSReleaseResource( &pDirEntry->NonPaged->Lock);
706 // If our current volume is not the global root then make it so ...
709 if( pCurrentVolume != AFSGlobalRoot)
712 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
713 AFS_TRACE_LEVEL_VERBOSE,
714 "AFSLocateNameEntry (FO: %08lX) Current volume not global, resetting for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
716 &pDirEntry->NameInformation.FileName,
717 pCurrentObject->FileId.Cell,
718 pCurrentObject->FileId.Volume,
719 pCurrentObject->FileId.Vnode,
720 pCurrentObject->FileId.Unique);
722 lCount = InterlockedDecrement( &pCurrentVolume->VolumeReferenceCount);
724 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
725 AFS_TRACE_LEVEL_VERBOSE,
726 "AFSLocateNameEntry Decrement count on volume %08lX Cnt %d\n",
730 pCurrentVolume = AFSGlobalRoot;
732 lCount = InterlockedIncrement( &pCurrentVolume->VolumeReferenceCount);
734 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
735 AFS_TRACE_LEVEL_VERBOSE,
736 "AFSLocateNameEntry Increment count on volume %08lX Cnt %d\n",
742 // Dereference our current dir entry
745 lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
747 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
748 AFS_TRACE_LEVEL_VERBOSE,
749 "AFSLocateNameEntry Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
750 &pDirEntry->NameInformation.FileName,
755 pDirEntry = pCurrentVolume->DirectoryCB;
758 // Reference the new dir entry
761 lCount = InterlockedIncrement( &pDirEntry->OpenReferenceCount);
763 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
764 AFS_TRACE_LEVEL_VERBOSE,
765 "AFSLocateNameEntry Increment2 count on %wZ DE %p Ccb %p Cnt %d\n",
766 &pDirEntry->NameInformation.FileName,
772 // Reset the name array
773 // Persist the link count in the name array
776 lLinkCount = pNameArray->LinkCount;
778 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
779 AFS_TRACE_LEVEL_VERBOSE,
780 "AFSLocateNameEntry (FO: %08lX) Resetting name array for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
782 &pDirEntry->NameInformation.FileName,
783 pCurrentObject->FileId.Cell,
784 pCurrentObject->FileId.Volume,
785 pCurrentObject->FileId.Vnode,
786 pCurrentObject->FileId.Unique);
788 AFSResetNameArray( pNameArray,
791 pNameArray->LinkCount = lLinkCount;
794 // Process over the \\<Global root> portion of the name
797 FsRtlDissectName( uniPathName,
801 if( RtlCompareUnicodeString( &uniComponentName,
806 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
807 AFS_TRACE_LEVEL_ERROR,
808 "AFSLocateNameEntry Name %wZ contains invalid server name\n",
812 // The correct response would be STATUS_OBJECT_PATH_INVALID
813 // but that prevents cmd.exe from performing a recursive
814 // directory enumeration when opening a directory entry
815 // that represents a symlink to an invalid path is discovered.
817 try_return( ntStatus = STATUS_OBJECT_PATH_NOT_FOUND);
820 uniPathName = uniRemainingPath;
822 pParentDirEntry = NULL;
826 // Increment our link count
829 lCount = InterlockedIncrement( &pNameArray->LinkCount);
834 case AFS_FILE_TYPE_MOUNTPOINT:
838 // Check if the flag is set to NOT evaluate a mount point
839 // and we are done with the parsing
842 if( BooleanFlagOn( Flags, AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL) &&
843 uniRemainingPath.Length == 0)
847 // Pass back the directory entries
850 *ParentDirectoryCB = pParentDirEntry;
852 *DirectoryCB = pDirEntry;
854 *VolumeCB = pCurrentVolume;
856 *RootPathName = uniFullPathName;
858 try_return( ntStatus);
861 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
862 AFS_TRACE_LEVEL_VERBOSE,
863 "AFSLocateNameEntry (FO: %08lX) Building MP target for parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
865 &pDirEntry->NameInformation.FileName,
866 pCurrentObject->FileId.Cell,
867 pCurrentObject->FileId.Volume,
868 pCurrentObject->FileId.Vnode,
869 pCurrentObject->FileId.Unique);
872 // Go retrieve the target entry for this node
873 // Release the current volume cb entry since we would
874 // have lock inversion in the following call
875 // Also decrement the ref count on the volume
878 ASSERT( pCurrentVolume->VolumeReferenceCount > 1);
880 lCount = InterlockedDecrement( &pCurrentVolume->VolumeReferenceCount);
882 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
883 AFS_TRACE_LEVEL_VERBOSE,
884 "AFSLocateNameEntry Decrement2 count on volume %08lX Cnt %d\n",
886 pCurrentVolume->VolumeReferenceCount);
888 ntStatus = AFSBuildMountPointTarget( AuthGroup,
892 if( !NT_SUCCESS( ntStatus))
895 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
896 AFS_TRACE_LEVEL_ERROR,
897 "AFSLocateNameEntry (FO: %08lX) Failed to build MP target for parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
899 &pDirEntry->NameInformation.FileName,
900 pCurrentObject->FileId.Cell,
901 pCurrentObject->FileId.Volume,
902 pCurrentObject->FileId.Vnode,
903 pCurrentObject->FileId.Unique,
907 // We already decremented the current volume above
910 bReleaseCurrentVolume = FALSE;
912 try_return( ntStatus);
915 ASSERT( pCurrentVolume->VolumeReferenceCount > 1);
918 // The name array stores both the mount point and the target.
919 // Insert the target.
922 AFSInsertNextElement( pNameArray,
923 pCurrentVolume->DirectoryCB);
926 // We want to restart processing here on the new parent ...
927 // Deref and ref count the entries
930 lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
932 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
933 AFS_TRACE_LEVEL_VERBOSE,
934 "AFSLocateNameEntry Decrement3 count on %wZ DE %p Ccb %p Cnt %d\n",
935 &pDirEntry->NameInformation.FileName,
940 pDirEntry = pCurrentVolume->DirectoryCB;
942 lCount = InterlockedIncrement( &pDirEntry->OpenReferenceCount);
944 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
945 AFS_TRACE_LEVEL_VERBOSE,
946 "AFSLocateNameEntry Increment3 count on %wZ DE %p Ccb %p Cnt %d\n",
947 &pDirEntry->NameInformation.FileName,
952 pParentDirEntry = NULL;
955 // Increment our link count
958 lCount = InterlockedIncrement( &pNameArray->LinkCount);
963 case AFS_FILE_TYPE_DFSLINK:
966 if( BooleanFlagOn( Flags, AFS_LOCATE_FLAGS_NO_DFS_LINK_EVAL))
970 // Pass back the directory entries
973 *ParentDirectoryCB = pParentDirEntry;
975 *DirectoryCB = pDirEntry;
977 *VolumeCB = pCurrentVolume;
979 *RootPathName = uniFullPathName;
981 try_return( ntStatus);
985 // This is a DFS link so we need to update the file name and return STATUS_REPARSE to the
986 // system for it to reevaluate it
989 if( FileObject != NULL)
992 ntStatus = AFSProcessDFSLink( pDirEntry,
1001 // This is where we have been re-entered from an NP evaluation call via the BuildBranch()
1005 ntStatus = STATUS_INVALID_PARAMETER;
1008 if( ntStatus != STATUS_SUCCESS &&
1009 ntStatus != STATUS_REPARSE)
1012 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1013 AFS_TRACE_LEVEL_ERROR,
1014 "AFSLocateNameEntry (FO: %08lX) Failed to process DFSLink parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1016 &pDirEntry->NameInformation.FileName,
1017 pCurrentObject->FileId.Cell,
1018 pCurrentObject->FileId.Volume,
1019 pCurrentObject->FileId.Vnode,
1020 pCurrentObject->FileId.Unique,
1024 try_return( ntStatus);
1027 case AFS_FILE_TYPE_UNKNOWN:
1028 case AFS_FILE_TYPE_INVALID:
1032 // Something was not processed ...
1035 try_return( ntStatus = STATUS_ACCESS_DENIED);
1038 } /* end of switch */
1041 // If the parent is not initialized then do it now
1044 if( pCurrentObject->FileType == AFS_FILE_TYPE_DIRECTORY &&
1045 !BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
1048 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1049 AFS_TRACE_LEVEL_VERBOSE,
1050 "AFSLocateNameEntry (FO: %08lX) Enumerating parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1052 &pDirEntry->NameInformation.FileName,
1053 pCurrentObject->FileId.Cell,
1054 pCurrentObject->FileId.Volume,
1055 pCurrentObject->FileId.Vnode,
1056 pCurrentObject->FileId.Unique);
1058 AFSAcquireExcl( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
1061 if( !BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
1064 ntStatus = AFSEnumerateDirectory( AuthGroup,
1068 if( !NT_SUCCESS( ntStatus))
1071 AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
1073 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1074 AFS_TRACE_LEVEL_ERROR,
1075 "AFSLocateNameEntry (FO: %08lX) Failed to enumerate parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1077 &pDirEntry->NameInformation.FileName,
1078 pCurrentObject->FileId.Cell,
1079 pCurrentObject->FileId.Volume,
1080 pCurrentObject->FileId.Vnode,
1081 pCurrentObject->FileId.Unique,
1084 try_return( ntStatus);
1087 SetFlag( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
1090 AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
1092 else if( pCurrentObject->FileType == AFS_FILE_TYPE_FILE)
1095 if( uniPathName.Length > 0)
1098 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1099 AFS_TRACE_LEVEL_ERROR,
1100 "AFSLocateNameEntry (FO: %08lX) Encountered file node %wZ FID %08lX-%08lX-%08lX-%08lX in path processing\n",
1102 &pDirEntry->NameInformation.FileName,
1103 pCurrentObject->FileId.Cell,
1104 pCurrentObject->FileId.Volume,
1105 pCurrentObject->FileId.Vnode,
1106 pCurrentObject->FileId.Unique);
1108 // The proper error code to return would be STATUS_OBJECT_PATH_INVALID because
1109 // one of the components of the path is not a directory. However, returning
1110 // that error prevents IIS 7 and 7.5 from being able to serve data out of AFS.
1111 // Instead IIS insists on treating the target file as if it is a directory containing
1112 // a potential web.config file. NTFS and LanMan return STATUS_OBJECT_PATH_NOT_FOUND.
1113 // AFS will follow suit.
1115 ntStatus = STATUS_OBJECT_PATH_NOT_FOUND;
1120 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1121 AFS_TRACE_LEVEL_VERBOSE,
1122 "AFSLocateNameEntry (FO: %08lX) Returning file %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1124 &pDirEntry->NameInformation.FileName,
1125 pCurrentObject->FileId.Cell,
1126 pCurrentObject->FileId.Volume,
1127 pCurrentObject->FileId.Vnode,
1128 pCurrentObject->FileId.Unique);
1131 // Pass back the directory entries
1134 *ParentDirectoryCB = pParentDirEntry;
1136 *DirectoryCB = pDirEntry;
1138 *VolumeCB = pCurrentVolume;
1140 *RootPathName = uniFullPathName;
1143 try_return( ntStatus);
1147 // If we are at the end of the processing, set our returned information and get out
1150 if( uniPathName.Length == 0)
1153 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1154 AFS_TRACE_LEVEL_VERBOSE,
1155 "AFSLocateNameEntry (FO: %08lX) Completed processing returning %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1157 &pDirEntry->NameInformation.FileName,
1158 pCurrentObject->FileId.Cell,
1159 pCurrentObject->FileId.Volume,
1160 pCurrentObject->FileId.Vnode,
1161 pCurrentObject->FileId.Unique);
1164 // Pass back the directory entries
1167 *ParentDirectoryCB = pParentDirEntry;
1169 *DirectoryCB = pDirEntry;
1171 *VolumeCB = pCurrentVolume;
1173 *RootPathName = uniFullPathName;
1175 try_return( ntStatus);
1179 // We may have returned to the top of the while( TRUE)
1181 if( bSubstituteName &&
1182 uniSearchName.Buffer != NULL)
1185 AFSExFreePool( uniSearchName.Buffer);
1187 bSubstituteName = FALSE;
1189 uniSearchName.Length = uniSearchName.MaximumLength = 0;
1190 uniSearchName.Buffer = NULL;
1193 ulSubstituteIndex = 1;
1195 ntStatus = STATUS_SUCCESS;
1198 // Get the next component name
1201 FsRtlDissectName( uniPathName,
1206 // Check for the . and .. in the path
1209 if( RtlCompareUnicodeString( &uniComponentName,
1214 uniPathName = uniRemainingPath;
1219 if( RtlCompareUnicodeString( &uniComponentName,
1224 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1225 AFS_TRACE_LEVEL_VERBOSE,
1226 "AFSLocateNameEntry (FO: %08lX) Backing up entry from %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1228 &pDirEntry->NameInformation.FileName,
1229 pCurrentObject->FileId.Cell,
1230 pCurrentObject->FileId.Volume,
1231 pCurrentObject->FileId.Vnode,
1232 pCurrentObject->FileId.Unique);
1235 // Need to back up one entry in the name array
1237 lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
1239 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1240 AFS_TRACE_LEVEL_VERBOSE,
1241 "AFSLocateNameEntry Decrement4 count on %wZ DE %p Ccb %p Cnt %d\n",
1242 &pDirEntry->NameInformation.FileName,
1247 pDirEntry = AFSBackupEntry( NameArray);
1249 if( pDirEntry == NULL)
1252 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1253 AFS_TRACE_LEVEL_ERROR,
1254 "AFSLocateNameEntry AFSBackupEntry failed\n");
1256 try_return(ntStatus = STATUS_OBJECT_PATH_INVALID);
1259 lCount = InterlockedIncrement( &pDirEntry->OpenReferenceCount);
1261 if( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_ROOT_VOLUME))
1264 pParentDirEntry = NULL;
1269 pParentDirEntry = AFSGetParentEntry( pNameArray);
1271 ASSERT( pParentDirEntry != pDirEntry);
1274 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1275 AFS_TRACE_LEVEL_VERBOSE,
1276 "AFSLocateNameEntry Increment4 count on %wZ DE %p Ccb %p Cnt %d\n",
1277 &pDirEntry->NameInformation.FileName,
1280 pDirEntry->OpenReferenceCount);
1282 uniPathName = uniRemainingPath;
1288 // Update our pointers
1291 pParentDirEntry = pDirEntry;
1295 uniSearchName = uniComponentName;
1297 while( pDirEntry == NULL)
1301 // If the SearchName contains @SYS then we perform the substitution.
1302 // If there is no substitution we give up.
1305 if( !bSubstituteName &&
1306 FsRtlIsNameInExpression( &uniSysName,
1312 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1313 AFS_TRACE_LEVEL_VERBOSE_2,
1314 "AFSLocateNameEntry (FO: %08lX) Processing @SYS substitution for %wZ Index %08lX\n",
1319 ntStatus = AFSSubstituteSysName( &uniComponentName,
1323 if ( NT_SUCCESS( ntStatus))
1326 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1327 AFS_TRACE_LEVEL_VERBOSE_2,
1328 "AFSLocateNameEntry (FO: %08lX) Located substitution %wZ for %wZ Index %08lX\n",
1335 // Go reparse the name again
1338 bSubstituteName = TRUE;
1340 ulSubstituteIndex++; // For the next entry, if needed
1342 continue; // while( pDirEntry == NULL)
1347 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1348 AFS_TRACE_LEVEL_ERROR,
1349 "AFSLocateNameEntry (FO: %08lX) Failed to locate substitute string for %wZ Index %08lX Status %08lX\n",
1355 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
1359 // Pass back the directory entries
1362 *ParentDirectoryCB = pParentDirEntry;
1364 *DirectoryCB = NULL;
1366 *VolumeCB = pCurrentVolume;
1368 if( ComponentName != NULL)
1371 *ComponentName = uniComponentName;
1374 *RootPathName = uniFullPathName;
1378 // We can't possibly have a pDirEntry since the lookup failed
1380 try_return( ntStatus);
1385 // Generate the CRC on the node and perform a case sensitive lookup
1388 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1389 AFS_TRACE_LEVEL_VERBOSE_2,
1390 "AFSLocateNameEntry (FO: %08lX) Searching for entry %wZ case sensitive\n",
1394 ulCRC = AFSGenerateCRC( &uniSearchName,
1397 AFSAcquireShared( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
1400 AFSLocateCaseSensitiveDirEntry( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
1404 if( pDirEntry == NULL)
1408 // Missed so perform a case insensitive lookup
1411 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1412 AFS_TRACE_LEVEL_VERBOSE_2,
1413 "AFSLocateNameEntry (FO: %08lX) Searching for entry %wZ case insensitive\n",
1417 ulCRC = AFSGenerateCRC( &uniSearchName,
1420 AFSLocateCaseInsensitiveDirEntry( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
1424 if( pDirEntry == NULL)
1428 // OK, if this component is a valid short name then try
1429 // a lookup in the short name tree
1432 if( RtlIsNameLegalDOS8Dot3( &uniSearchName,
1437 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1438 AFS_TRACE_LEVEL_VERBOSE_2,
1439 "AFSLocateNameEntry (FO: %08lX) Searching for entry %wZ short name\n",
1443 AFSLocateShortNameDirEntry( pParentDirEntry->ObjectInformation->Specific.Directory.ShortNameTree,
1448 if( pDirEntry == NULL)
1452 // If we substituted a name then reset our search name and try again
1455 if( bSubstituteName)
1458 AFSExFreePool( uniSearchName.Buffer);
1460 uniSearchName = uniComponentName;
1462 bSubstituteName = FALSE;
1464 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1466 continue; // while( pDirEntry == NULL)
1469 if( uniRemainingPath.Length > 0)
1472 ntStatus = STATUS_OBJECT_PATH_NOT_FOUND;
1477 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
1479 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1480 AFS_TRACE_LEVEL_VERBOSE,
1481 "AFSLocateNameEntry (FO: %08lX) Returning name not found for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1484 pCurrentObject->FileId.Cell,
1485 pCurrentObject->FileId.Volume,
1486 pCurrentObject->FileId.Vnode,
1487 pCurrentObject->FileId.Unique);
1490 // Pass back the directory entries
1493 *ParentDirectoryCB = pParentDirEntry;
1495 *DirectoryCB = NULL;
1497 *VolumeCB = pCurrentVolume;
1499 if( ComponentName != NULL)
1502 *ComponentName = uniComponentName;
1505 *RootPathName = uniFullPathName;
1508 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1511 // Node name not found so get out
1514 try_return( ntStatus); // while( pDirEntry == NULL)
1521 // Here we have a match on the case insensitive lookup for the name. If there
1522 // Is more than one link entry for this node then fail the lookup request
1525 if( !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD) ||
1526 pDirEntry->CaseInsensitiveList.fLink != NULL)
1529 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1531 try_return(ntStatus = STATUS_OBJECT_NAME_COLLISION);
1536 if( pDirEntry != NULL)
1540 // If the verify flag is set on the parent and the current entry is deleted
1541 // revalidate the parent and search again.
1544 if( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED) &&
1545 BooleanFlagOn( pParentDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY))
1548 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1550 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1551 AFS_TRACE_LEVEL_VERBOSE,
1552 "AFSLocateNameEntry (FO: %08lX) Verifying(2) parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1554 &pParentDirEntry->NameInformation.FileName,
1555 pParentDirEntry->ObjectInformation->FileId.Cell,
1556 pParentDirEntry->ObjectInformation->FileId.Volume,
1557 pParentDirEntry->ObjectInformation->FileId.Vnode,
1558 pParentDirEntry->ObjectInformation->FileId.Unique);
1561 // Directory TreeLock should be exclusively held
1564 AFSAcquireExcl( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
1567 ntStatus = AFSVerifyEntry( AuthGroup,
1570 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1572 if( !NT_SUCCESS( ntStatus))
1575 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1576 AFS_TRACE_LEVEL_ERROR,
1577 "AFSLocateNameEntry (FO: %08lX) Failed to verify(2) parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1579 &pParentDirEntry->NameInformation.FileName,
1580 pParentDirEntry->ObjectInformation->FileId.Cell,
1581 pParentDirEntry->ObjectInformation->FileId.Volume,
1582 pParentDirEntry->ObjectInformation->FileId.Vnode,
1583 pParentDirEntry->ObjectInformation->FileId.Unique,
1586 try_return( ntStatus);
1589 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1590 AFS_TRACE_LEVEL_VERBOSE,
1591 "AFSLocateNameEntry (FO: %08lX) Reprocessing component %wZ in parent %wZ\n",
1594 &pParentDirEntry->NameInformation.FileName);
1603 // Increment our dir entry ref count
1606 lCount = InterlockedIncrement( &pDirEntry->OpenReferenceCount);
1608 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1609 AFS_TRACE_LEVEL_VERBOSE,
1610 "AFSLocateNameEntry Increment5 count on %wZ DE %p Ccb %p Cnt %d\n",
1611 &pDirEntry->NameInformation.FileName,
1617 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1619 } // End while( pDirEntry == NULL)
1622 // If we have a dirEntry for this component, perform some basic validation on it
1625 if( pDirEntry != NULL &&
1626 BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
1629 pCurrentObject = pDirEntry->ObjectInformation;
1631 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1632 AFS_TRACE_LEVEL_ERROR,
1633 "AFSLocateNameEntry (FO: %08lX) Deleted entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1635 &pDirEntry->NameInformation.FileName,
1636 pCurrentObject->FileId.Cell,
1637 pCurrentObject->FileId.Volume,
1638 pCurrentObject->FileId.Vnode,
1639 pCurrentObject->FileId.Unique);
1642 // This entry was deleted through the invalidation call back so perform cleanup
1646 ASSERT( pCurrentObject->ParentObjectInformation != NULL);
1648 AFSAcquireExcl( pCurrentObject->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
1651 AFSAcquireExcl( pCurrentObject->VolumeCB->ObjectInfoTree.TreeLock,
1654 lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
1659 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING|AFS_SUBSYSTEM_CLEANUP_PROCESSING,
1660 AFS_TRACE_LEVEL_VERBOSE,
1661 "AFSLocateNameEntry Deleting dir entry %08lX (%08lX) for %wZ\n",
1664 &pDirEntry->NameInformation.FileName);
1667 // Remove and delete the directory entry from the parent list
1670 AFSDeleteDirEntry( pCurrentObject->ParentObjectInformation,
1673 if( pCurrentObject->ObjectReferenceCount <= 0)
1676 if( BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_INSERTED_HASH_TREE))
1679 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
1680 AFS_TRACE_LEVEL_VERBOSE,
1681 "AFSLocateNameEntry Removing object %08lX from volume tree\n",
1684 AFSRemoveHashEntry( &pCurrentObject->VolumeCB->ObjectInfoTree.TreeHead,
1685 &pCurrentObject->TreeEntry);
1687 ClearFlag( pCurrentObject->Flags, AFS_OBJECT_INSERTED_HASH_TREE);
1694 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1695 AFS_TRACE_LEVEL_VERBOSE,
1696 "AFSLocateNameEntry Setting DELETE flag in dir entry %p for %wZ\n",
1698 &pDirEntry->NameInformation.FileName);
1700 SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
1702 AFSRemoveNameEntry( pCurrentObject->ParentObjectInformation,
1706 AFSReleaseResource( pCurrentObject->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1708 AFSReleaseResource( pCurrentObject->VolumeCB->ObjectInfoTree.TreeLock);
1711 // We deleted the dir entry so check if there is any remaining portion
1712 // of the name to process.
1715 if( uniRemainingPath.Length > 0)
1717 ntStatus = STATUS_OBJECT_PATH_NOT_FOUND;
1722 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
1724 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1725 AFS_TRACE_LEVEL_VERBOSE,
1726 "AFSLocateNameEntry (FO: %08lX) Returning name not found(2) for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1729 pCurrentObject->FileId.Cell,
1730 pCurrentObject->FileId.Volume,
1731 pCurrentObject->FileId.Vnode,
1732 pCurrentObject->FileId.Unique);
1735 // Pass back the directory entries
1738 *ParentDirectoryCB = pParentDirEntry;
1740 *DirectoryCB = NULL;
1742 *VolumeCB = pCurrentVolume;
1744 if( ComponentName != NULL)
1747 *ComponentName = uniComponentName;
1750 *RootPathName = uniFullPathName;
1754 if( ntStatus != STATUS_SUCCESS)
1757 try_return( ntStatus);
1761 // Decrement the previous parent
1764 lCount = InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
1766 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1767 AFS_TRACE_LEVEL_VERBOSE,
1768 "AFSLocateNameEntry Decrement5 count on Parent %wZ DE %p Ccb %p Cnt %d\n",
1769 &pParentDirEntry->NameInformation.FileName,
1775 // If we ended up substituting a name in the component then update
1776 // the full path and update the pointers
1779 if( bSubstituteName)
1782 BOOLEAN bRelativeOpen = FALSE;
1784 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1785 AFS_TRACE_LEVEL_VERBOSE_2,
1786 "AFSLocateNameEntry (FO: %08lX) Substituting %wZ into %wZ Index %08lX\n",
1792 if( FileObject != NULL &&
1793 FileObject->RelatedFileObject != NULL)
1796 bRelativeOpen = TRUE;
1800 // AFSSubstituteNameInPath will replace the uniFullPathName.Buffer
1801 // and free the prior Buffer contents but only if the fourth
1802 // parameter is TRUE.
1805 ntStatus = AFSSubstituteNameInPath( &uniFullPathName,
1810 bAllocatedSymLinkBuffer ||
1813 if( !NT_SUCCESS( ntStatus))
1816 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1817 AFS_TRACE_LEVEL_ERROR,
1818 "AFSLocateNameEntry (FO: %08lX) Failure to substitute %wZ into %wZ Index %08lX Status %08lX\n",
1825 try_return( ntStatus);
1829 // We have substituted a name into the buffer so if we do this again for this
1830 // path, we need to free up the buffer we allocated.
1833 bSubstitutedName = TRUE;
1837 // Update the search parameters
1840 uniPathName = uniRemainingPath;
1843 // Check if the is a SymLink entry but has no Target FileID or Name. In this
1844 // case it might be a DFS Link so let's go and evaluate it to be sure
1847 if( pCurrentObject->FileType == AFS_FILE_TYPE_SYMLINK &&
1848 pCurrentObject->TargetFileId.Vnode == 0 &&
1849 pCurrentObject->TargetFileId.Unique == 0 &&
1850 pDirEntry->NameInformation.TargetName.Length == 0)
1853 ntStatus = AFSValidateSymLink( AuthGroup,
1856 if( !NT_SUCCESS( ntStatus))
1859 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1860 AFS_TRACE_LEVEL_ERROR,
1861 "AFSLocateNameEntry (FO: %08lX) Failed to evaluate possible DFS Link %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1863 &pDirEntry->NameInformation.FileName,
1864 pCurrentObject->FileId.Cell,
1865 pCurrentObject->FileId.Volume,
1866 pCurrentObject->FileId.Vnode,
1867 pCurrentObject->FileId.Unique,
1870 try_return( ntStatus);
1875 // Update the name array
1878 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1879 AFS_TRACE_LEVEL_VERBOSE,
1880 "AFSLocateNameEntry (FO: %08lX) Inserting name array entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1882 &pDirEntry->NameInformation.FileName,
1883 pCurrentObject->FileId.Cell,
1884 pCurrentObject->FileId.Volume,
1885 pCurrentObject->FileId.Vnode,
1886 pCurrentObject->FileId.Unique);
1888 ntStatus = AFSInsertNextElement( pNameArray,
1891 if( !NT_SUCCESS( ntStatus))
1894 try_return( ntStatus);
1900 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1901 AFS_TRACE_LEVEL_VERBOSE,
1902 "AFSLocateNameEntry (FO: %08lX) Completed processing %wZ Status %08lX\n",
1907 if( ( !NT_SUCCESS( ntStatus) &&
1908 ntStatus != STATUS_OBJECT_NAME_NOT_FOUND) ||
1909 ntStatus == STATUS_REPARSE)
1912 if( pDirEntry != NULL)
1915 lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
1917 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1918 AFS_TRACE_LEVEL_VERBOSE,
1919 "AFSLocateNameEntry Decrement6 count on %wZ DE %p Ccb %p Cnt %d\n",
1920 &pDirEntry->NameInformation.FileName,
1925 else if( pParentDirEntry != NULL)
1928 lCount = InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
1930 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1931 AFS_TRACE_LEVEL_VERBOSE,
1932 "AFSLocateNameEntry Decrement7 count on %wZ DE %p Ccb %p Cnt %d\n",
1933 &pParentDirEntry->NameInformation.FileName,
1939 if( bReleaseCurrentVolume)
1942 ASSERT( pCurrentVolume->VolumeReferenceCount > 1);
1944 lCount = InterlockedDecrement( &pCurrentVolume->VolumeReferenceCount);
1946 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
1947 AFS_TRACE_LEVEL_VERBOSE,
1948 "AFSLocateNameEntry Decrement3 count on volume %08lX Cnt %d\n",
1953 if( RootPathName->Buffer != uniFullPathName.Buffer)
1956 AFSExFreePool( uniFullPathName.Buffer);
1962 if( *ParentDirectoryCB != NULL)
1965 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1966 AFS_TRACE_LEVEL_VERBOSE,
1967 "AFSLocateNameEntry Count on Parent %wZ DE %p Ccb %p Cnt %d\n",
1968 &(*ParentDirectoryCB)->NameInformation.FileName,
1971 (*ParentDirectoryCB)->OpenReferenceCount);
1974 if( *DirectoryCB != NULL)
1977 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1978 AFS_TRACE_LEVEL_VERBOSE,
1979 "AFSLocateNameEntry Count on %wZ DE %p Ccb %p Cnt %d\n",
1980 &(*DirectoryCB)->NameInformation.FileName,
1983 (*DirectoryCB)->OpenReferenceCount);
1987 if( bSubstituteName &&
1988 uniSearchName.Buffer != NULL)
1991 AFSExFreePool( uniSearchName.Buffer);
1999 AFSCreateDirEntry( IN GUID *AuthGroup,
2000 IN AFSObjectInfoCB *ParentObjectInfo,
2001 IN AFSDirectoryCB *ParentDirCB,
2002 IN PUNICODE_STRING FileName,
2003 IN PUNICODE_STRING ComponentName,
2004 IN ULONG Attributes,
2005 IN OUT AFSDirectoryCB **DirEntry)
2008 NTSTATUS ntStatus = STATUS_SUCCESS;
2009 AFSDirectoryCB *pDirNode = NULL, *pExistingDirNode = NULL;
2010 UNICODE_STRING uniShortName;
2011 LARGE_INTEGER liFileSize = {0,0};
2017 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2018 AFS_TRACE_LEVEL_VERBOSE_2,
2019 "AFSCreateDirEntry Creating dir entry in parent %wZ FID %08lX-%08lX-%08lX-%08lX Component %wZ Attribs %08lX\n",
2020 &ParentDirCB->NameInformation.FileName,
2021 ParentObjectInfo->FileId.Cell,
2022 ParentObjectInfo->FileId.Volume,
2023 ParentObjectInfo->FileId.Vnode,
2024 ParentObjectInfo->FileId.Unique,
2029 // OK, before inserting the node into the parent tree, issue
2030 // the request to the service for node creation
2031 // We will need to drop the lock on the parent node since the create
2032 // could cause a callback into the file system to invalidate it's cache
2035 ntStatus = AFSNotifyFileCreate( AuthGroup,
2043 // If the returned status is STATUS_REPARSE then the entry exists
2044 // and we raced, get out.
2046 if( ntStatus == STATUS_REPARSE)
2049 *DirEntry = pDirNode;
2051 try_return( ntStatus = STATUS_SUCCESS);
2054 if( !NT_SUCCESS( ntStatus))
2057 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2058 AFS_TRACE_LEVEL_ERROR,
2059 "AFSCreateDirEntry Failed to create dir entry in parent %wZ FID %08lX-%08lX-%08lX-%08lX Component %wZ Attribs %08lX Status %08lX\n",
2060 &ParentDirCB->NameInformation.FileName,
2061 ParentObjectInfo->FileId.Cell,
2062 ParentObjectInfo->FileId.Volume,
2063 ParentObjectInfo->FileId.Vnode,
2064 ParentObjectInfo->FileId.Unique,
2069 try_return( ntStatus);
2072 AFSAcquireExcl( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2076 // Before attempting to insert the new entry, check if we need to validate the parent
2079 if( BooleanFlagOn( ParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY))
2082 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2083 AFS_TRACE_LEVEL_VERBOSE,
2084 "AFSCreateDirEntry Verifying parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2085 &ParentDirCB->NameInformation.FileName,
2086 ParentObjectInfo->FileId.Cell,
2087 ParentObjectInfo->FileId.Volume,
2088 ParentObjectInfo->FileId.Vnode,
2089 ParentObjectInfo->FileId.Unique);
2091 ntStatus = AFSVerifyEntry( AuthGroup,
2094 if( !NT_SUCCESS( ntStatus))
2097 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2098 AFS_TRACE_LEVEL_ERROR,
2099 "AFSCreateDirEntry Failed to verify parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2100 &ParentDirCB->NameInformation.FileName,
2101 ParentObjectInfo->FileId.Cell,
2102 ParentObjectInfo->FileId.Volume,
2103 ParentObjectInfo->FileId.Vnode,
2104 ParentObjectInfo->FileId.Unique,
2107 AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2109 try_return( ntStatus);
2114 // Check for the entry in the event we raced with some other thread
2117 AFSLocateCaseSensitiveDirEntry( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
2118 (ULONG)pDirNode->CaseSensitiveTreeEntry.HashIndex,
2121 if( pExistingDirNode != NULL)
2123 if (AFSIsEqualFID( &pDirNode->ObjectInformation->FileId,
2124 &pExistingDirNode->ObjectInformation->FileId))
2127 AFSDeleteDirEntry( ParentObjectInfo,
2130 lCount = InterlockedIncrement( &pExistingDirNode->OpenReferenceCount);
2132 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2133 AFS_TRACE_LEVEL_VERBOSE,
2134 "AFSCreateDirEntry Increment count on %wZ DE %p Cnt %d\n",
2135 &pExistingDirNode->NameInformation.FileName,
2139 *DirEntry = pExistingDirNode;
2141 AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2143 try_return( ntStatus = STATUS_SUCCESS);
2149 // Need to tear down this entry and rebuild it below
2152 if( pExistingDirNode->OpenReferenceCount == 0)
2155 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2156 AFS_TRACE_LEVEL_VERBOSE,
2157 "AFSCreateDirEntry Different FIDs - Deleting DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
2159 &pExistingDirNode->NameInformation.FileName,
2160 pExistingDirNode->ObjectInformation->FileId.Cell,
2161 pExistingDirNode->ObjectInformation->FileId.Volume,
2162 pExistingDirNode->ObjectInformation->FileId.Vnode,
2163 pExistingDirNode->ObjectInformation->FileId.Unique,
2164 pDirNode->ObjectInformation->FileId.Cell,
2165 pDirNode->ObjectInformation->FileId.Volume,
2166 pDirNode->ObjectInformation->FileId.Vnode,
2167 pDirNode->ObjectInformation->FileId.Unique);
2169 AFSDeleteDirEntry( ParentObjectInfo,
2175 SetFlag( pExistingDirNode->Flags, AFS_DIR_ENTRY_DELETED);
2177 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2178 AFS_TRACE_LEVEL_VERBOSE,
2179 "AFSCreateDirEntry Different FIDs - Removing DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
2181 &pExistingDirNode->NameInformation.FileName,
2182 pExistingDirNode->ObjectInformation->FileId.Cell,
2183 pExistingDirNode->ObjectInformation->FileId.Volume,
2184 pExistingDirNode->ObjectInformation->FileId.Vnode,
2185 pExistingDirNode->ObjectInformation->FileId.Unique,
2186 pDirNode->ObjectInformation->FileId.Cell,
2187 pDirNode->ObjectInformation->FileId.Volume,
2188 pDirNode->ObjectInformation->FileId.Vnode,
2189 pDirNode->ObjectInformation->FileId.Unique);
2191 AFSRemoveNameEntry( ParentObjectInfo,
2198 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2199 AFS_TRACE_LEVEL_VERBOSE_2,
2200 "AFSCreateDirEntry Inserting dir entry in parent %wZ FID %08lX-%08lX-%08lX-%08lX Component %wZ\n",
2201 &ParentDirCB->NameInformation.FileName,
2202 ParentObjectInfo->FileId.Cell,
2203 ParentObjectInfo->FileId.Volume,
2204 ParentObjectInfo->FileId.Vnode,
2205 ParentObjectInfo->FileId.Unique,
2209 // Insert the directory node
2212 AFSInsertDirectoryNode( ParentObjectInfo,
2216 lCount = InterlockedIncrement( &pDirNode->OpenReferenceCount);
2218 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2219 AFS_TRACE_LEVEL_VERBOSE,
2220 "AFSCreateDirEntry Increment2 count on %wZ DE %p Cnt %d\n",
2221 &pDirNode->NameInformation.FileName,
2226 // Pass back the dir entry
2229 *DirEntry = pDirNode;
2231 AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2242 AFSInsertDirectoryNode( IN AFSObjectInfoCB *ParentObjectInfo,
2243 IN AFSDirectoryCB *DirEntry,
2244 IN BOOLEAN InsertInEnumList)
2252 ASSERT( ExIsResourceAcquiredExclusiveLite( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock));
2255 // Insert the node into the directory node tree
2258 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2259 AFS_TRACE_LEVEL_VERBOSE,
2260 "AFSInsertDirectoryNode Insert DE %p for %wZ Clearing NOT_IN flag\n",
2262 &DirEntry->NameInformation.FileName);
2264 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
2266 if( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead == NULL)
2269 ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = DirEntry;
2271 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2272 AFS_TRACE_LEVEL_VERBOSE,
2273 "AFSInsertDirectoryNode Insert DE %p to head of case sensitive tree for %wZ\n",
2275 &DirEntry->NameInformation.FileName);
2280 AFSInsertCaseSensitiveDirEntry( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
2283 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2284 AFS_TRACE_LEVEL_VERBOSE,
2285 "AFSInsertDirectoryNode Insert DE %p to case sensitive tree for %wZ\n",
2287 &DirEntry->NameInformation.FileName);
2290 if( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead == NULL)
2293 ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = DirEntry;
2295 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
2297 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2298 AFS_TRACE_LEVEL_VERBOSE,
2299 "AFSInsertDirectoryNode Insert DE %p to head of case insensitive tree for %wZ\n",
2301 &DirEntry->NameInformation.FileName);
2306 AFSInsertCaseInsensitiveDirEntry( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
2309 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2310 AFS_TRACE_LEVEL_VERBOSE,
2311 "AFSInsertDirectoryNode Insert DE %p to case insensitive tree for %wZ\n",
2313 &DirEntry->NameInformation.FileName);
2317 // Into the shortname tree
2320 if( DirEntry->Type.Data.ShortNameTreeEntry.HashIndex != 0)
2323 if( ParentObjectInfo->Specific.Directory.ShortNameTree == NULL)
2326 ParentObjectInfo->Specific.Directory.ShortNameTree = DirEntry;
2328 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2329 AFS_TRACE_LEVEL_VERBOSE,
2330 "AFSInsertDirectoryNode Insert DE %p to head of shortname tree for %wZ\n",
2332 &DirEntry->NameInformation.FileName);
2334 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
2339 if( !NT_SUCCESS( AFSInsertShortNameDirEntry( ParentObjectInfo->Specific.Directory.ShortNameTree,
2342 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2343 AFS_TRACE_LEVEL_VERBOSE,
2344 "AFSInsertDirectoryNode Failed to insert DE %p to shortname tree for %wZ\n",
2346 &DirEntry->NameInformation.FileName);
2350 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
2352 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2353 AFS_TRACE_LEVEL_VERBOSE,
2354 "AFSInsertDirectoryNode Insert DE %p to shortname tree for %wZ\n",
2356 &DirEntry->NameInformation.FileName);
2361 if( InsertInEnumList)
2365 // And insert the node into the directory list
2368 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2369 AFS_TRACE_LEVEL_VERBOSE,
2370 "AFSInsertDirectoryNode Inserting entry %08lX %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2372 &DirEntry->NameInformation.FileName,
2373 DirEntry->ObjectInformation->FileId.Cell,
2374 DirEntry->ObjectInformation->FileId.Volume,
2375 DirEntry->ObjectInformation->FileId.Vnode,
2376 DirEntry->ObjectInformation->FileId.Unique);
2378 if( ParentObjectInfo->Specific.Directory.DirectoryNodeListHead == NULL)
2381 ParentObjectInfo->Specific.Directory.DirectoryNodeListHead = DirEntry;
2386 ParentObjectInfo->Specific.Directory.DirectoryNodeListTail->ListEntry.fLink = (void *)DirEntry;
2388 DirEntry->ListEntry.bLink = (void *)ParentObjectInfo->Specific.Directory.DirectoryNodeListTail;
2391 ParentObjectInfo->Specific.Directory.DirectoryNodeListTail = DirEntry;
2393 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST);
2395 lCount = InterlockedIncrement( &ParentObjectInfo->Specific.Directory.DirectoryNodeCount);
2397 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
2398 AFS_TRACE_LEVEL_VERBOSE,
2399 "AFSInsertDirectoryNode Adding entry %wZ Inc Count %d to parent FID %08lX-%08lX-%08lX-%08lX\n",
2400 &DirEntry->NameInformation.FileName,
2402 ParentObjectInfo->FileId.Cell,
2403 ParentObjectInfo->FileId.Volume,
2404 ParentObjectInfo->FileId.Vnode,
2405 ParentObjectInfo->FileId.Unique);
2413 AFSDeleteDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
2414 IN AFSDirectoryCB *DirEntry)
2417 NTSTATUS ntStatus = STATUS_SUCCESS;
2423 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2424 AFS_TRACE_LEVEL_VERBOSE,
2425 "AFSDeleteDirEntry Deleting dir entry in parent %08lX Entry %08lX %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2428 &DirEntry->NameInformation.FileName,
2429 DirEntry->ObjectInformation->FileId.Cell,
2430 DirEntry->ObjectInformation->FileId.Volume,
2431 DirEntry->ObjectInformation->FileId.Vnode,
2432 DirEntry->ObjectInformation->FileId.Unique);
2434 AFSRemoveDirNodeFromParent( ParentObjectInfo,
2439 // Free up the name buffer if it was reallocated
2442 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_RELEASE_NAME_BUFFER))
2445 AFSExFreePool( DirEntry->NameInformation.FileName.Buffer);
2448 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER))
2451 AFSExFreePool( DirEntry->NameInformation.TargetName.Buffer);
2455 // Dereference the object for this dir entry
2458 ASSERT( DirEntry->ObjectInformation->ObjectReferenceCount > 0);
2460 lCount = InterlockedDecrement( &DirEntry->ObjectInformation->ObjectReferenceCount);
2464 SetFlag( DirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED);
2467 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2468 AFS_TRACE_LEVEL_VERBOSE,
2469 "AFSDeleteDirEntry Decrement count on object %08lX Cnt %d\n",
2470 DirEntry->ObjectInformation,
2471 DirEntry->ObjectInformation->ObjectReferenceCount);
2473 ExDeleteResourceLite( &DirEntry->NonPaged->Lock);
2475 AFSExFreePool( DirEntry->NonPaged);
2478 // Free up the dir entry
2481 AFSExFreePool( DirEntry);
2488 AFSRemoveDirNodeFromParent( IN AFSObjectInfoCB *ParentObjectInfo,
2489 IN AFSDirectoryCB *DirEntry,
2490 IN BOOLEAN RemoveFromEnumList)
2493 NTSTATUS ntStatus = STATUS_SUCCESS;
2500 ASSERT( ExIsResourceAcquiredExclusiveLite( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock));
2502 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2503 AFS_TRACE_LEVEL_VERBOSE,
2504 "AFSRemoveDirNodeFromParent Removing DirEntry %08lX %wZ FID %08lX-%08lX-%08lX-%08lX from Parent %08lX\n",
2506 &DirEntry->NameInformation.FileName,
2507 DirEntry->ObjectInformation->FileId.Cell,
2508 DirEntry->ObjectInformation->FileId.Volume,
2509 DirEntry->ObjectInformation->FileId.Vnode,
2510 DirEntry->ObjectInformation->FileId.Unique,
2513 if( !BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
2516 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2517 AFS_TRACE_LEVEL_VERBOSE,
2518 "AFSRemoveDirNodeFromParent Removing DirEntry %08lX name %wZ\n",
2520 &DirEntry->NameInformation.FileName);
2522 AFSRemoveNameEntry( ParentObjectInfo,
2528 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2529 AFS_TRACE_LEVEL_VERBOSE,
2530 "AFSRemoveDirNodeFromParent DE %p for %wZ NOT removing entry due to flag set\n",
2532 &DirEntry->NameInformation.FileName);
2536 if( RemoveFromEnumList &&
2537 BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST))
2541 // And remove the entry from the enumeration list
2544 if( DirEntry->ListEntry.fLink == NULL)
2547 ParentObjectInfo->Specific.Directory.DirectoryNodeListTail = (AFSDirectoryCB *)DirEntry->ListEntry.bLink;
2552 ((AFSDirectoryCB *)DirEntry->ListEntry.fLink)->ListEntry.bLink = DirEntry->ListEntry.bLink;
2555 if( DirEntry->ListEntry.bLink == NULL)
2558 ParentObjectInfo->Specific.Directory.DirectoryNodeListHead = (AFSDirectoryCB *)DirEntry->ListEntry.fLink;
2563 ((AFSDirectoryCB *)DirEntry->ListEntry.bLink)->ListEntry.fLink = DirEntry->ListEntry.fLink;
2566 ASSERT( ParentObjectInfo->Specific.Directory.DirectoryNodeCount > 0);
2568 lCount = InterlockedDecrement( &ParentObjectInfo->Specific.Directory.DirectoryNodeCount);
2570 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST);
2572 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
2573 AFS_TRACE_LEVEL_VERBOSE,
2574 "AFSRemoveDirNodeFromParent Removing entry %wZ Dec Count %d to parent FID %08lX-%08lX-%08lX-%08lX\n",
2575 &DirEntry->NameInformation.FileName,
2577 ParentObjectInfo->FileId.Cell,
2578 ParentObjectInfo->FileId.Volume,
2579 ParentObjectInfo->FileId.Vnode,
2580 ParentObjectInfo->FileId.Unique);
2582 DirEntry->ListEntry.fLink = NULL;
2583 DirEntry->ListEntry.bLink = NULL;
2591 AFSFixupTargetName( IN OUT PUNICODE_STRING FileName,
2592 IN OUT PUNICODE_STRING TargetFileName)
2595 NTSTATUS ntStatus = STATUS_SUCCESS;
2596 UNICODE_STRING uniFileName;
2602 // We will process backwards from the end of the name looking
2603 // for the first \ we encounter
2606 uniFileName.Length = FileName->Length;
2607 uniFileName.MaximumLength = FileName->MaximumLength;
2609 uniFileName.Buffer = FileName->Buffer;
2614 if( uniFileName.Buffer[ (uniFileName.Length/sizeof( WCHAR)) - 1] == L'\\')
2618 // Subtract one more character off of the filename if it is not the root
2621 if( uniFileName.Length > sizeof( WCHAR))
2624 uniFileName.Length -= sizeof( WCHAR);
2628 // Now build up the target name
2631 TargetFileName->Length = FileName->Length - uniFileName.Length;
2634 // If we are not on the root then fixup the name
2637 if( uniFileName.Length > sizeof( WCHAR))
2640 TargetFileName->Length -= sizeof( WCHAR);
2642 TargetFileName->Buffer = &uniFileName.Buffer[ (uniFileName.Length/sizeof( WCHAR)) + 1];
2647 TargetFileName->Buffer = &uniFileName.Buffer[ uniFileName.Length/sizeof( WCHAR)];
2651 // Fixup the passed back filename length
2654 FileName->Length = uniFileName.Length;
2656 TargetFileName->MaximumLength = TargetFileName->Length;
2661 uniFileName.Length -= sizeof( WCHAR);
2669 AFSParseName( IN PIRP Irp,
2671 OUT PUNICODE_STRING FileName,
2672 OUT PUNICODE_STRING ParsedFileName,
2673 OUT PUNICODE_STRING RootFileName,
2674 OUT ULONG *ParseFlags,
2675 OUT AFSVolumeCB **VolumeCB,
2676 OUT AFSDirectoryCB **ParentDirectoryCB,
2677 OUT AFSNameArrayHdr **NameArray)
2680 NTSTATUS ntStatus = STATUS_SUCCESS;
2681 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2682 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2683 UNICODE_STRING uniFullName, uniComponentName, uniRemainingPath;
2685 AFSDirectoryCB *pDirEntry = NULL, *pShareDirEntry = NULL, *pTargetDirEntry = NULL;
2686 USHORT usIndex = 0, usDriveIndex = 0;
2687 AFSCcb *pRelatedCcb = NULL;
2688 AFSNameArrayHdr *pNameArray = NULL, *pRelatedNameArray = NULL;
2689 USHORT usComponentIndex = 0;
2690 USHORT usComponentLength = 0;
2691 AFSVolumeCB *pVolumeCB = NULL;
2692 AFSFcb *pRelatedFcb = NULL;
2693 BOOLEAN bReleaseTreeLock = FALSE;
2694 BOOLEAN bIsAllShare = FALSE;
2701 // Indicate we are opening a root ...
2704 *ParseFlags = AFS_PARSE_FLAG_ROOT_ACCESS;
2706 if( pIrpSp->FileObject->RelatedFileObject != NULL)
2709 pRelatedFcb = (AFSFcb *)pIrpSp->FileObject->RelatedFileObject->FsContext;
2711 pRelatedCcb = (AFSCcb *)pIrpSp->FileObject->RelatedFileObject->FsContext2;
2713 pRelatedNameArray = pRelatedCcb->NameArray;
2715 uniFullName = pIrpSp->FileObject->FileName;
2717 ASSERT( pRelatedFcb != NULL);
2720 // No wild cards in the name
2723 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2724 AFS_TRACE_LEVEL_VERBOSE_2,
2725 "AFSParseName (%08lX) Relative open for %wZ FID %08lX-%08lX-%08lX-%08lX component %wZ\n",
2727 &pRelatedCcb->DirectoryCB->NameInformation.FileName,
2728 pRelatedCcb->DirectoryCB->ObjectInformation->FileId.Cell,
2729 pRelatedCcb->DirectoryCB->ObjectInformation->FileId.Volume,
2730 pRelatedCcb->DirectoryCB->ObjectInformation->FileId.Vnode,
2731 pRelatedCcb->DirectoryCB->ObjectInformation->FileId.Unique,
2734 if( FsRtlDoesNameContainWildCards( &uniFullName))
2737 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2738 AFS_TRACE_LEVEL_ERROR,
2739 "AFSParseName (%08lX) Component %wZ contains wild cards\n",
2743 try_return( ntStatus = STATUS_OBJECT_NAME_INVALID);
2746 pVolumeCB = pRelatedFcb->ObjectInformation->VolumeCB;
2748 pDirEntry = pRelatedCcb->DirectoryCB;
2750 *FileName = pIrpSp->FileObject->FileName;
2753 // Grab the root node while checking state
2756 AFSAcquireShared( pVolumeCB->VolumeLock,
2759 if( BooleanFlagOn( pVolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
2760 BooleanFlagOn( pVolumeCB->Flags, AFS_VOLUME_FLAGS_OFFLINE))
2764 // The volume has been taken off line so fail the access
2767 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2768 AFS_TRACE_LEVEL_ERROR,
2769 "AFSParseName (%08lX) Volume %08lX:%08lX OFFLINE/INVALID\n",
2771 pVolumeCB->ObjectInformation.FileId.Cell,
2772 pVolumeCB->ObjectInformation.FileId.Volume);
2774 AFSReleaseResource( pVolumeCB->VolumeLock);
2776 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
2779 if( BooleanFlagOn( pVolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_VERIFY))
2782 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2783 AFS_TRACE_LEVEL_VERBOSE,
2784 "AFSParseName (%08lX) Verifying root of volume %08lX:%08lX\n",
2786 pVolumeCB->ObjectInformation.FileId.Cell,
2787 pVolumeCB->ObjectInformation.FileId.Volume);
2789 ntStatus = AFSVerifyVolume( (ULONGLONG)PsGetCurrentProcessId(),
2792 if( !NT_SUCCESS( ntStatus))
2795 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2796 AFS_TRACE_LEVEL_ERROR,
2797 "AFSParseName (%08lX) Failed verification of root Status %08lX\n",
2801 AFSReleaseResource( pVolumeCB->VolumeLock);
2803 try_return( ntStatus);
2807 AFSReleaseResource( pVolumeCB->VolumeLock);
2809 if( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY))
2812 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2813 AFS_TRACE_LEVEL_VERBOSE,
2814 "AFSParseName (%08lX) Verifying parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2816 &pDirEntry->NameInformation.FileName,
2817 pDirEntry->ObjectInformation->FileId.Cell,
2818 pDirEntry->ObjectInformation->FileId.Volume,
2819 pDirEntry->ObjectInformation->FileId.Vnode,
2820 pDirEntry->ObjectInformation->FileId.Unique);
2823 // Directory TreeLock should be exclusively held
2826 AFSAcquireExcl( pDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
2829 ntStatus = AFSVerifyEntry( AuthGroup,
2832 AFSReleaseResource( pDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
2834 if( !NT_SUCCESS( ntStatus))
2837 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2838 AFS_TRACE_LEVEL_VERBOSE,
2839 "AFSParseName (%08lX) Failed verification of parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2841 &pDirEntry->NameInformation.FileName,
2842 pDirEntry->ObjectInformation->FileId.Cell,
2843 pDirEntry->ObjectInformation->FileId.Volume,
2844 pDirEntry->ObjectInformation->FileId.Vnode,
2845 pDirEntry->ObjectInformation->FileId.Unique,
2848 try_return( ntStatus);
2853 // Create our full path name buffer
2856 uniFullName.MaximumLength = pRelatedCcb->FullFileName.Length +
2858 pIrpSp->FileObject->FileName.Length +
2861 uniFullName.Length = 0;
2863 uniFullName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2864 uniFullName.MaximumLength,
2865 AFS_NAME_BUFFER_THREE_TAG);
2867 if( uniFullName.Buffer == NULL)
2870 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2871 AFS_TRACE_LEVEL_ERROR,
2872 "AFSParseName (%08lX) Failed to allocate full name buffer\n",
2875 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2878 RtlZeroMemory( uniFullName.Buffer,
2879 uniFullName.MaximumLength);
2881 RtlCopyMemory( uniFullName.Buffer,
2882 pRelatedCcb->FullFileName.Buffer,
2883 pRelatedCcb->FullFileName.Length);
2885 uniFullName.Length = pRelatedCcb->FullFileName.Length;
2887 usComponentIndex = (USHORT)(uniFullName.Length/sizeof( WCHAR));
2889 usComponentLength = pIrpSp->FileObject->FileName.Length;
2891 if( uniFullName.Buffer[ (uniFullName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
2892 pIrpSp->FileObject->FileName.Length > 0 &&
2893 pIrpSp->FileObject->FileName.Buffer[ 0] != L'\\' &&
2894 pIrpSp->FileObject->FileName.Buffer[ 0] != L':')
2897 uniFullName.Buffer[ (uniFullName.Length/sizeof( WCHAR))] = L'\\';
2899 uniFullName.Length += sizeof( WCHAR);
2901 usComponentLength += sizeof( WCHAR);
2904 if( pIrpSp->FileObject->FileName.Length > 0)
2907 RtlCopyMemory( &uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)],
2908 pIrpSp->FileObject->FileName.Buffer,
2909 pIr
\epSp->FileObject->FileName.Length);
2911 uniFullName.Length += pIrpSp->FileObject->FileName.Length;
2914 *RootFileName = uniFullName;
2917 // We populate up to the current parent
2920 if( pRelatedNameArray == NULL)
2924 // Init and populate our name array
2927 pNameArray = AFSInitNameArray( NULL,
2930 if( pNameArray == NULL)
2933 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2934 AFS_TRACE_LEVEL_VERBOSE,
2935 "AFSParseName (%08lX) Failed to initialize name array\n",
2938 AFSExFreePool( uniFullName.Buffer);
2940 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2943 ntStatus = AFSPopulateNameArray( pNameArray,
2945 pRelatedCcb->DirectoryCB);
2951 // Init and populate our name array
2954 pNameArray = AFSInitNameArray( NULL,
2955 pRelatedNameArray->MaxElementCount);
2957 if( pNameArray == NULL)
2960 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2961 AFS_TRACE_LEVEL_VERBOSE,
2962 "AFSParseName (%08lX) Failed to initialize name array\n",
2965 AFSExFreePool( uniFullName.Buffer);
2967 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2970 ntStatus = AFSPopulateNameArrayFromRelatedArray( pNameArray,
2972 pRelatedCcb->DirectoryCB);
2975 if( !NT_SUCCESS( ntStatus))
2978 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2979 AFS_TRACE_LEVEL_VERBOSE,
2980 "AFSParseName (%08lX) Failed to populate name array\n",
2983 AFSExFreePool( uniFullName.Buffer);
2985 try_return( ntStatus);
2988 ParsedFileName->Length = usComponentLength;
2989 ParsedFileName->MaximumLength = uniFullName.MaximumLength;
2991 ParsedFileName->Buffer = &uniFullName.Buffer[ usComponentIndex];
2994 // Indicate to caller that RootFileName must be freed
2997 SetFlag( *ParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
2999 *NameArray = pNameArray;
3001 *VolumeCB = pVolumeCB;
3004 // Increment our volume reference count
3007 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
3009 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
3010 AFS_TRACE_LEVEL_VERBOSE,
3011 "AFSParseName Increment count on volume %08lX Cnt %d\n",
3015 *ParentDirectoryCB = pDirEntry;
3017 lCount = InterlockedIncrement( &pDirEntry->OpenReferenceCount);
3019 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3020 AFS_TRACE_LEVEL_VERBOSE,
3021 "AFSParseName Increment1 count on %wZ DE %p Ccb %p Cnt %d\n",
3022 &pDirEntry->NameInformation.FileName,
3027 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3028 AFS_TRACE_LEVEL_VERBOSE_2,
3029 "AFSParseName (%08lX) Returning full name %wZ\n",
3033 try_return( ntStatus);
3037 // No wild cards in the name
3040 uniFullName = pIrpSp->FileObject->FileName;
3042 if( FsRtlDoesNameContainWildCards( &uniFullName) ||
3043 uniFullName.Length < AFSServerName.Length)
3046 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3047 AFS_TRACE_LEVEL_ERROR,
3048 "AFSParseName (%08lX) Name %wZ contains wild cards or too short\n",
3052 try_return( ntStatus = STATUS_OBJECT_NAME_INVALID);
3056 // The name is a fully qualified name. Parse out the server/share names and
3057 // point to the root qualified name
3058 // First thing is to locate the server name
3061 FsRtlDissectName( uniFullName,
3065 uniFullName = uniRemainingPath;
3068 // This component is the server name we are serving
3071 if( RtlCompareUnicodeString( &uniComponentName,
3077 // Drive letter based name?
3080 uniFullName = pIrpSp->FileObject->FileName;
3082 while( usIndex < uniFullName.Length/sizeof( WCHAR))
3085 if( uniFullName.Buffer[ usIndex] == L':')
3088 uniFullName.Buffer = &uniFullName.Buffer[ usIndex + 2];
3090 uniFullName.Length -= (usIndex + 2) * sizeof( WCHAR);
3092 usDriveIndex = usIndex - 1;
3101 // Do we have the right server name now?
3104 FsRtlDissectName( uniFullName,
3108 uniFullName = uniRemainingPath;
3111 // This component is the server name we are serving
3114 if( RtlCompareUnicodeString( &uniComponentName,
3119 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3120 AFS_TRACE_LEVEL_ERROR,
3121 "AFSParseName (%08lX) Name %wZ does not have server name\n",
3123 &pIrpSp->FileObject->FileName);
3125 try_return( ntStatus = STATUS_BAD_NETWORK_NAME);
3129 // Validate this drive letter is actively mapped
3132 if( usDriveIndex > 0 &&
3133 !AFSIsDriveMapped( pIrpSp->FileObject->FileName.Buffer[ usDriveIndex]))
3136 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3137 AFS_TRACE_LEVEL_ERROR,
3138 "AFSParseName (%08lX) Name %wZ contains invalid drive mapping\n",
3140 &pIrpSp->FileObject->FileName);
3142 try_return( ntStatus = STATUS_BAD_NETWORK_NAME);
3146 if( FsRtlDoesNameContainWildCards( &uniFullName))
3149 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3150 AFS_TRACE_LEVEL_ERROR,
3151 "AFSParseName (%08lX) Component %wZ contains wild cards\n",
3155 try_return( ntStatus = STATUS_OBJECT_NAME_INVALID);
3158 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3159 AFS_TRACE_LEVEL_VERBOSE_2,
3160 "AFSParseName (%08lX) Processing full name %wZ\n",
3164 if( uniFullName.Length > 0 &&
3165 uniFullName.Buffer[ (uniFullName.Length/sizeof( WCHAR)) - 1] == L'\\')
3168 uniFullName.Length -= sizeof( WCHAR);
3172 // Be sure we are online and ready to go
3175 AFSAcquireShared( AFSGlobalRoot->VolumeLock,
3178 if( BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
3179 BooleanFlagOn( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE))
3183 // The volume has been taken off line so fail the access
3186 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3187 AFS_TRACE_LEVEL_ERROR,
3188 "AFSParseName (%08lX) Volume %08lX:%08lX OFFLINE/INVALID\n",
3190 AFSGlobalRoot->ObjectInformation.FileId.Cell,
3191 AFSGlobalRoot->ObjectInformation.FileId.Volume);
3193 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3195 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
3198 if( BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_VERIFY))
3201 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3202 AFS_TRACE_LEVEL_VERBOSE,
3203 "AFSParseName (%08lX) Verifying root of volume %08lX:%08lX\n",
3205 AFSGlobalRoot->ObjectInformation.FileId.Cell,
3206 AFSGlobalRoot->ObjectInformation.FileId.Volume);
3208 ntStatus = AFSVerifyVolume( (ULONGLONG)PsGetCurrentProcessId(),
3211 if( !NT_SUCCESS( ntStatus))
3214 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3215 AFS_TRACE_LEVEL_ERROR,
3216 "AFSParseName (%08lX) Failed verification of root Status %08lX\n",
3220 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3222 try_return( ntStatus);
3226 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3228 if( !BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
3231 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3232 AFS_TRACE_LEVEL_VERBOSE,
3233 "AFSParseName (%08lX) Enumerating global root of volume %08lX:%08lX\n",
3235 AFSGlobalRoot->ObjectInformation.FileId.Cell,
3236 AFSGlobalRoot->ObjectInformation.FileId.Volume);
3238 ntStatus = AFSEnumerateGlobalRoot( AuthGroup);
3240 if( !NT_SUCCESS( ntStatus))
3243 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3244 AFS_TRACE_LEVEL_ERROR,
3245 "AFSParseName (%08lX) Failed enumeraiton of root Status %08lX\n",
3249 try_return( ntStatus);
3254 // Check for the \\Server access and return it as though it where \\Server\Globalroot
3257 if( uniRemainingPath.Buffer == NULL ||
3258 ( uniRemainingPath.Length == sizeof( WCHAR) &&
3259 uniRemainingPath.Buffer[ 0] == L'\\'))
3262 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3263 AFS_TRACE_LEVEL_VERBOSE_2,
3264 "AFSParseName (%08lX) Returning global root access\n",