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 AFSExFreePoolWithTag( pTmpBuffer, 0);
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);
622 if ( !AFSIsAbsoluteAFSName( &pDirEntry->NameInformation.TargetName))
625 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
626 AFS_TRACE_LEVEL_ERROR,
627 "AFSLocateNameEntry Name %wZ contains invalid server name\n",
628 &pDirEntry->NameInformation.TargetName);
631 // The correct response would be STATUS_OBJECT_PATH_INVALID
632 // but that prevents cmd.exe from performing a recursive
633 // directory enumeration when opening a directory entry
634 // that represents a symlink to an invalid path is discovered.
637 AFSReleaseResource( &pDirEntry->NonPaged->Lock);
639 try_return( ntStatus = STATUS_OBJECT_PATH_NOT_FOUND);
643 // We'll substitute this name into the current process name
644 // starting at where we sit in the path
647 uniTempName.Length = 0;
648 uniTempName.MaximumLength = pDirEntry->NameInformation.TargetName.Length +
650 uniRemainingPath.Length;
652 uniTempName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
653 uniTempName.MaximumLength,
654 AFS_NAME_BUFFER_TWO_TAG);
656 if( uniTempName.Buffer == NULL)
659 AFSReleaseResource( &pDirEntry->NonPaged->Lock);
661 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
664 if( bAllocatedSymLinkBuffer ||
668 pTmpBuffer = uniFullPathName.Buffer;
671 bAllocatedSymLinkBuffer = TRUE;
674 // Have we parsed this name yet? Better have at least once ...
677 if( uniComponentName.Length == 0)
683 // Copy in the target name ...
686 RtlCopyMemory( uniTempName.Buffer,
687 &pDirEntry->NameInformation.TargetName.Buffer[ AFSMountRootName.Length/sizeof( WCHAR)],
688 pDirEntry->NameInformation.TargetName.Length - AFSMountRootName.Length);
690 uniTempName.Length = pDirEntry->NameInformation.TargetName.Length - AFSMountRootName.Length;
693 // And now any remaining portion of the name
696 if( uniRemainingPath.Length > 0)
699 if( uniRemainingPath.Buffer[ 0] != L'\\')
702 uniRemainingPath.Buffer--;
703 uniRemainingPath.Length += sizeof( WCHAR);
706 RtlCopyMemory( &uniTempName.Buffer[ uniTempName.Length/sizeof( WCHAR)],
707 uniRemainingPath.Buffer,
708 uniRemainingPath.Length);
710 uniTempName.Length += uniRemainingPath.Length;
713 uniFullPathName = uniTempName;
715 uniPathName = uniTempName;
717 if( pTmpBuffer != NULL)
720 AFSExFreePoolWithTag( pTmpBuffer, 0);
723 AFSReleaseResource( &pDirEntry->NonPaged->Lock);
726 // If our current volume is not the global root then make it so ...
729 if( pCurrentVolume != AFSGlobalRoot)
732 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
733 AFS_TRACE_LEVEL_VERBOSE,
734 "AFSLocateNameEntry (FO: %08lX) Current volume not global, resetting for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
736 &pDirEntry->NameInformation.FileName,
737 pCurrentObject->FileId.Cell,
738 pCurrentObject->FileId.Volume,
739 pCurrentObject->FileId.Vnode,
740 pCurrentObject->FileId.Unique);
742 lCount = InterlockedDecrement( &pCurrentVolume->VolumeReferenceCount);
744 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
745 AFS_TRACE_LEVEL_VERBOSE,
746 "AFSLocateNameEntry Decrement count on volume %08lX Cnt %d\n",
750 pCurrentVolume = AFSGlobalRoot;
752 lCount = InterlockedIncrement( &pCurrentVolume->VolumeReferenceCount);
754 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
755 AFS_TRACE_LEVEL_VERBOSE,
756 "AFSLocateNameEntry Increment count on volume %08lX Cnt %d\n",
762 // Dereference our current dir entry
765 lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
767 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
768 AFS_TRACE_LEVEL_VERBOSE,
769 "AFSLocateNameEntry Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
770 &pDirEntry->NameInformation.FileName,
775 pDirEntry = pCurrentVolume->DirectoryCB;
778 // Reference the new dir entry
781 lCount = InterlockedIncrement( &pDirEntry->OpenReferenceCount);
783 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
784 AFS_TRACE_LEVEL_VERBOSE,
785 "AFSLocateNameEntry Increment2 count on %wZ DE %p Ccb %p Cnt %d\n",
786 &pDirEntry->NameInformation.FileName,
792 // Reset the name array
793 // Persist the link count in the name array
796 lLinkCount = pNameArray->LinkCount;
798 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
799 AFS_TRACE_LEVEL_VERBOSE,
800 "AFSLocateNameEntry (FO: %08lX) Resetting name array for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
802 &pDirEntry->NameInformation.FileName,
803 pCurrentObject->FileId.Cell,
804 pCurrentObject->FileId.Volume,
805 pCurrentObject->FileId.Vnode,
806 pCurrentObject->FileId.Unique);
808 AFSResetNameArray( pNameArray,
811 pNameArray->LinkCount = lLinkCount;
813 pParentDirEntry = NULL;
817 // Increment our link count
820 lCount = InterlockedIncrement( &pNameArray->LinkCount);
825 case AFS_FILE_TYPE_MOUNTPOINT:
829 // Check if the flag is set to NOT evaluate a mount point
830 // and we are done with the parsing
833 if( BooleanFlagOn( Flags, AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL) &&
834 uniRemainingPath.Length == 0)
838 // Pass back the directory entries
841 *ParentDirectoryCB = pParentDirEntry;
843 *DirectoryCB = pDirEntry;
845 *VolumeCB = pCurrentVolume;
847 *RootPathName = uniFullPathName;
849 try_return( ntStatus);
852 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
853 AFS_TRACE_LEVEL_VERBOSE,
854 "AFSLocateNameEntry (FO: %08lX) Building MP target for parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
856 &pDirEntry->NameInformation.FileName,
857 pCurrentObject->FileId.Cell,
858 pCurrentObject->FileId.Volume,
859 pCurrentObject->FileId.Vnode,
860 pCurrentObject->FileId.Unique);
863 // Go retrieve the target entry for this node
864 // Release the current volume cb entry since we would
865 // have lock inversion in the following call
866 // Also decrement the ref count on the volume
869 ASSERT( pCurrentVolume->VolumeReferenceCount > 1);
871 lCount = InterlockedDecrement( &pCurrentVolume->VolumeReferenceCount);
873 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
874 AFS_TRACE_LEVEL_VERBOSE,
875 "AFSLocateNameEntry Decrement2 count on volume %08lX Cnt %d\n",
877 pCurrentVolume->VolumeReferenceCount);
879 ntStatus = AFSBuildMountPointTarget( AuthGroup,
883 if( !NT_SUCCESS( ntStatus))
886 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
887 AFS_TRACE_LEVEL_ERROR,
888 "AFSLocateNameEntry (FO: %08lX) Failed to build MP target for parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
890 &pDirEntry->NameInformation.FileName,
891 pCurrentObject->FileId.Cell,
892 pCurrentObject->FileId.Volume,
893 pCurrentObject->FileId.Vnode,
894 pCurrentObject->FileId.Unique,
898 // We already decremented the current volume above
901 bReleaseCurrentVolume = FALSE;
903 try_return( ntStatus);
906 ASSERT( pCurrentVolume->VolumeReferenceCount > 1);
909 // We want to restart processing here on the new parent ...
910 // Deref and ref count the entries
913 lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
915 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
916 AFS_TRACE_LEVEL_VERBOSE,
917 "AFSLocateNameEntry Decrement3 count on %wZ DE %p Ccb %p Cnt %d\n",
918 &pDirEntry->NameInformation.FileName,
923 pDirEntry = pCurrentVolume->DirectoryCB;
925 lCount = InterlockedIncrement( &pDirEntry->OpenReferenceCount);
927 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
928 AFS_TRACE_LEVEL_VERBOSE,
929 "AFSLocateNameEntry Increment3 count on %wZ DE %p Ccb %p Cnt %d\n",
930 &pDirEntry->NameInformation.FileName,
936 // The name array stores both the mount point and the target.
937 // Insert the target.
940 AFSInsertNextElement( pNameArray,
943 pParentDirEntry = NULL;
946 // Increment our link count
949 lCount = InterlockedIncrement( &pNameArray->LinkCount);
954 case AFS_FILE_TYPE_DFSLINK:
957 if( BooleanFlagOn( Flags, AFS_LOCATE_FLAGS_NO_DFS_LINK_EVAL))
961 // Pass back the directory entries
964 *ParentDirectoryCB = pParentDirEntry;
966 *DirectoryCB = pDirEntry;
968 *VolumeCB = pCurrentVolume;
970 *RootPathName = uniFullPathName;
972 try_return( ntStatus);
976 // This is a DFS link so we need to update the file name and return STATUS_REPARSE to the
977 // system for it to reevaluate it
980 if( FileObject != NULL)
983 ntStatus = AFSProcessDFSLink( pDirEntry,
992 // This is where we have been re-entered from an NP evaluation call via the BuildBranch()
996 ntStatus = STATUS_INVALID_PARAMETER;
999 if( ntStatus != STATUS_SUCCESS &&
1000 ntStatus != STATUS_REPARSE)
1003 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1004 AFS_TRACE_LEVEL_ERROR,
1005 "AFSLocateNameEntry (FO: %08lX) Failed to process DFSLink parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1007 &pDirEntry->NameInformation.FileName,
1008 pCurrentObject->FileId.Cell,
1009 pCurrentObject->FileId.Volume,
1010 pCurrentObject->FileId.Vnode,
1011 pCurrentObject->FileId.Unique,
1015 try_return( ntStatus);
1018 case AFS_FILE_TYPE_UNKNOWN:
1019 case AFS_FILE_TYPE_INVALID:
1023 // Something was not processed ...
1026 try_return( ntStatus = STATUS_ACCESS_DENIED);
1029 } /* end of switch */
1032 // If the parent is not initialized then do it now
1035 if( pCurrentObject->FileType == AFS_FILE_TYPE_DIRECTORY &&
1036 !BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
1039 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1040 AFS_TRACE_LEVEL_VERBOSE,
1041 "AFSLocateNameEntry (FO: %08lX) Enumerating parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1043 &pDirEntry->NameInformation.FileName,
1044 pCurrentObject->FileId.Cell,
1045 pCurrentObject->FileId.Volume,
1046 pCurrentObject->FileId.Vnode,
1047 pCurrentObject->FileId.Unique);
1049 AFSAcquireExcl( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
1052 if( !BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
1055 ntStatus = AFSEnumerateDirectory( AuthGroup,
1059 if( !NT_SUCCESS( ntStatus))
1062 AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
1064 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1065 AFS_TRACE_LEVEL_ERROR,
1066 "AFSLocateNameEntry (FO: %08lX) Failed to enumerate parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1068 &pDirEntry->NameInformation.FileName,
1069 pCurrentObject->FileId.Cell,
1070 pCurrentObject->FileId.Volume,
1071 pCurrentObject->FileId.Vnode,
1072 pCurrentObject->FileId.Unique,
1075 try_return( ntStatus);
1078 SetFlag( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
1081 AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
1083 else if( pCurrentObject->FileType == AFS_FILE_TYPE_FILE)
1086 if( uniPathName.Length > 0)
1089 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1090 AFS_TRACE_LEVEL_ERROR,
1091 "AFSLocateNameEntry (FO: %08lX) Encountered file node %wZ FID %08lX-%08lX-%08lX-%08lX in path processing\n",
1093 &pDirEntry->NameInformation.FileName,
1094 pCurrentObject->FileId.Cell,
1095 pCurrentObject->FileId.Volume,
1096 pCurrentObject->FileId.Vnode,
1097 pCurrentObject->FileId.Unique);
1099 // The proper error code to return would be STATUS_OBJECT_PATH_INVALID because
1100 // one of the components of the path is not a directory. However, returning
1101 // that error prevents IIS 7 and 7.5 from being able to serve data out of AFS.
1102 // Instead IIS insists on treating the target file as if it is a directory containing
1103 // a potential web.config file. NTFS and LanMan return STATUS_OBJECT_PATH_NOT_FOUND.
1104 // AFS will follow suit.
1106 ntStatus = STATUS_OBJECT_PATH_NOT_FOUND;
1111 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1112 AFS_TRACE_LEVEL_VERBOSE,
1113 "AFSLocateNameEntry (FO: %08lX) Returning file %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1115 &pDirEntry->NameInformation.FileName,
1116 pCurrentObject->FileId.Cell,
1117 pCurrentObject->FileId.Volume,
1118 pCurrentObject->FileId.Vnode,
1119 pCurrentObject->FileId.Unique);
1122 // Pass back the directory entries
1125 *ParentDirectoryCB = pParentDirEntry;
1127 *DirectoryCB = pDirEntry;
1129 *VolumeCB = pCurrentVolume;
1131 *RootPathName = uniFullPathName;
1134 try_return( ntStatus);
1138 // If we are at the end of the processing, set our returned information and get out
1141 if( uniPathName.Length == 0)
1144 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1145 AFS_TRACE_LEVEL_VERBOSE,
1146 "AFSLocateNameEntry (FO: %08lX) Completed processing returning %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1148 &pDirEntry->NameInformation.FileName,
1149 pCurrentObject->FileId.Cell,
1150 pCurrentObject->FileId.Volume,
1151 pCurrentObject->FileId.Vnode,
1152 pCurrentObject->FileId.Unique);
1155 // Pass back the directory entries
1158 *ParentDirectoryCB = pParentDirEntry;
1160 *DirectoryCB = pDirEntry;
1162 *VolumeCB = pCurrentVolume;
1164 *RootPathName = uniFullPathName;
1166 try_return( ntStatus);
1170 // We may have returned to the top of the while( TRUE)
1172 if( bSubstituteName &&
1173 uniSearchName.Buffer != NULL)
1176 AFSExFreePoolWithTag( uniSearchName.Buffer, 0);
1178 bSubstituteName = FALSE;
1180 uniSearchName.Length = uniSearchName.MaximumLength = 0;
1181 uniSearchName.Buffer = NULL;
1184 ulSubstituteIndex = 1;
1186 ntStatus = STATUS_SUCCESS;
1189 // Get the next component name
1192 FsRtlDissectName( uniPathName,
1197 // Check for the . and .. in the path
1200 if( RtlCompareUnicodeString( &uniComponentName,
1205 uniPathName = uniRemainingPath;
1210 if( RtlCompareUnicodeString( &uniComponentName,
1215 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1216 AFS_TRACE_LEVEL_VERBOSE,
1217 "AFSLocateNameEntry (FO: %08lX) Backing up entry from %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1219 &pDirEntry->NameInformation.FileName,
1220 pCurrentObject->FileId.Cell,
1221 pCurrentObject->FileId.Volume,
1222 pCurrentObject->FileId.Vnode,
1223 pCurrentObject->FileId.Unique);
1226 // Need to back up one entry in the name array
1228 lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
1230 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1231 AFS_TRACE_LEVEL_VERBOSE,
1232 "AFSLocateNameEntry Decrement4 count on %wZ DE %p Ccb %p Cnt %d\n",
1233 &pDirEntry->NameInformation.FileName,
1238 pDirEntry = AFSBackupEntry( NameArray);
1240 if( pDirEntry == NULL)
1243 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1244 AFS_TRACE_LEVEL_ERROR,
1245 "AFSLocateNameEntry AFSBackupEntry failed\n");
1247 try_return(ntStatus = STATUS_OBJECT_PATH_INVALID);
1250 lCount = InterlockedIncrement( &pDirEntry->OpenReferenceCount);
1252 if( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_ROOT_VOLUME))
1255 pParentDirEntry = NULL;
1260 pParentDirEntry = AFSGetParentEntry( pNameArray);
1262 ASSERT( pParentDirEntry != pDirEntry);
1265 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1266 AFS_TRACE_LEVEL_VERBOSE,
1267 "AFSLocateNameEntry Increment4 count on %wZ DE %p Ccb %p Cnt %d\n",
1268 &pDirEntry->NameInformation.FileName,
1271 pDirEntry->OpenReferenceCount);
1273 uniPathName = uniRemainingPath;
1279 // Update our pointers
1282 pParentDirEntry = pDirEntry;
1286 uniSearchName = uniComponentName;
1288 while( pDirEntry == NULL)
1292 // If the SearchName contains @SYS then we perform the substitution.
1293 // If there is no substitution we give up.
1296 if( !bSubstituteName &&
1297 FsRtlIsNameInExpression( &uniSysName,
1303 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1304 AFS_TRACE_LEVEL_VERBOSE_2,
1305 "AFSLocateNameEntry (FO: %08lX) Processing @SYS substitution for %wZ Index %08lX\n",
1310 ntStatus = AFSSubstituteSysName( &uniComponentName,
1314 if ( NT_SUCCESS( ntStatus))
1317 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1318 AFS_TRACE_LEVEL_VERBOSE_2,
1319 "AFSLocateNameEntry (FO: %08lX) Located substitution %wZ for %wZ Index %08lX\n",
1326 // Go reparse the name again
1329 bSubstituteName = TRUE;
1331 ulSubstituteIndex++; // For the next entry, if needed
1333 continue; // while( pDirEntry == NULL)
1338 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1339 AFS_TRACE_LEVEL_ERROR,
1340 "AFSLocateNameEntry (FO: %08lX) Failed to locate substitute string for %wZ Index %08lX Status %08lX\n",
1346 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
1350 // Pass back the directory entries
1353 *ParentDirectoryCB = pParentDirEntry;
1355 *DirectoryCB = NULL;
1357 *VolumeCB = pCurrentVolume;
1359 if( ComponentName != NULL)
1362 *ComponentName = uniComponentName;
1365 *RootPathName = uniFullPathName;
1369 // We can't possibly have a pDirEntry since the lookup failed
1371 try_return( ntStatus);
1376 // Generate the CRC on the node and perform a case sensitive lookup
1379 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1380 AFS_TRACE_LEVEL_VERBOSE_2,
1381 "AFSLocateNameEntry (FO: %08lX) Searching for entry %wZ case sensitive\n",
1385 ulCRC = AFSGenerateCRC( &uniSearchName,
1388 AFSAcquireShared( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
1391 AFSLocateCaseSensitiveDirEntry( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
1395 if( pDirEntry == NULL)
1399 // Missed so perform a case insensitive lookup
1402 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1403 AFS_TRACE_LEVEL_VERBOSE_2,
1404 "AFSLocateNameEntry (FO: %08lX) Searching for entry %wZ case insensitive\n",
1408 ulCRC = AFSGenerateCRC( &uniSearchName,
1411 AFSLocateCaseInsensitiveDirEntry( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
1415 if( pDirEntry == NULL)
1419 // OK, if this component is a valid short name then try
1420 // a lookup in the short name tree
1423 if( !BooleanFlagOn( pDevExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
1424 RtlIsNameLegalDOS8Dot3( &uniSearchName,
1429 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1430 AFS_TRACE_LEVEL_VERBOSE_2,
1431 "AFSLocateNameEntry (FO: %08lX) Searching for entry %wZ short name\n",
1435 AFSLocateShortNameDirEntry( pParentDirEntry->ObjectInformation->Specific.Directory.ShortNameTree,
1440 if( pDirEntry == NULL)
1444 // If we substituted a name then reset our search name and try again
1447 if( bSubstituteName)
1450 AFSExFreePoolWithTag( uniSearchName.Buffer, 0);
1452 uniSearchName = uniComponentName;
1454 bSubstituteName = FALSE;
1456 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1458 continue; // while( pDirEntry == NULL)
1461 if( uniRemainingPath.Length > 0)
1464 ntStatus = STATUS_OBJECT_PATH_NOT_FOUND;
1469 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
1471 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1472 AFS_TRACE_LEVEL_VERBOSE,
1473 "AFSLocateNameEntry (FO: %08lX) Returning name not found for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1476 pCurrentObject->FileId.Cell,
1477 pCurrentObject->FileId.Volume,
1478 pCurrentObject->FileId.Vnode,
1479 pCurrentObject->FileId.Unique);
1482 // Pass back the directory entries
1485 *ParentDirectoryCB = pParentDirEntry;
1487 *DirectoryCB = NULL;
1489 *VolumeCB = pCurrentVolume;
1491 if( ComponentName != NULL)
1494 *ComponentName = uniComponentName;
1497 *RootPathName = uniFullPathName;
1500 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1503 // Node name not found so get out
1506 try_return( ntStatus); // while( pDirEntry == NULL)
1513 // Here we have a match on the case insensitive lookup for the name. If there
1514 // Is more than one link entry for this node then fail the lookup request
1517 if( !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD) ||
1518 pDirEntry->CaseInsensitiveList.fLink != NULL)
1521 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1523 try_return(ntStatus = STATUS_OBJECT_NAME_COLLISION);
1528 if( pDirEntry != NULL)
1532 // If the verify flag is set on the parent and the current entry is deleted
1533 // revalidate the parent and search again.
1536 if( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED) &&
1537 BooleanFlagOn( pParentDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY))
1540 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1542 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1543 AFS_TRACE_LEVEL_VERBOSE,
1544 "AFSLocateNameEntry (FO: %08lX) Verifying(2) parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1546 &pParentDirEntry->NameInformation.FileName,
1547 pParentDirEntry->ObjectInformation->FileId.Cell,
1548 pParentDirEntry->ObjectInformation->FileId.Volume,
1549 pParentDirEntry->ObjectInformation->FileId.Vnode,
1550 pParentDirEntry->ObjectInformation->FileId.Unique);
1553 // Directory TreeLock should be exclusively held
1556 AFSAcquireExcl( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
1559 ntStatus = AFSVerifyEntry( AuthGroup,
1562 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1564 if( !NT_SUCCESS( ntStatus))
1567 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1568 AFS_TRACE_LEVEL_ERROR,
1569 "AFSLocateNameEntry (FO: %08lX) Failed to verify(2) parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1571 &pParentDirEntry->NameInformation.FileName,
1572 pParentDirEntry->ObjectInformation->FileId.Cell,
1573 pParentDirEntry->ObjectInformation->FileId.Volume,
1574 pParentDirEntry->ObjectInformation->FileId.Vnode,
1575 pParentDirEntry->ObjectInformation->FileId.Unique,
1578 try_return( ntStatus);
1581 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1582 AFS_TRACE_LEVEL_VERBOSE,
1583 "AFSLocateNameEntry (FO: %08lX) Reprocessing component %wZ in parent %wZ\n",
1586 &pParentDirEntry->NameInformation.FileName);
1595 // Increment our dir entry ref count
1598 lCount = InterlockedIncrement( &pDirEntry->OpenReferenceCount);
1600 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1601 AFS_TRACE_LEVEL_VERBOSE,
1602 "AFSLocateNameEntry Increment5 count on %wZ DE %p Ccb %p Cnt %d\n",
1603 &pDirEntry->NameInformation.FileName,
1609 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1611 } // End while( pDirEntry == NULL)
1614 // If we have a dirEntry for this component, perform some basic validation on it
1617 if( pDirEntry != NULL &&
1618 BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
1621 pCurrentObject = pDirEntry->ObjectInformation;
1623 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1624 AFS_TRACE_LEVEL_ERROR,
1625 "AFSLocateNameEntry (FO: %08lX) Deleted entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1627 &pDirEntry->NameInformation.FileName,
1628 pCurrentObject->FileId.Cell,
1629 pCurrentObject->FileId.Volume,
1630 pCurrentObject->FileId.Vnode,
1631 pCurrentObject->FileId.Unique);
1634 // This entry was deleted through the invalidation call back so perform cleanup
1638 pParentObjectInfo = pCurrentObject->ParentObjectInformation;
1640 ASSERT( pParentObjectInfo != NULL);
1642 AFSAcquireExcl( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
1645 AFSAcquireExcl( pCurrentObject->VolumeCB->ObjectInfoTree.TreeLock,
1648 lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
1653 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING|AFS_SUBSYSTEM_CLEANUP_PROCESSING,
1654 AFS_TRACE_LEVEL_VERBOSE,
1655 "AFSLocateNameEntry Deleting dir entry %08lX (%08lX) for %wZ\n",
1658 &pDirEntry->NameInformation.FileName);
1661 // Remove and delete the directory entry from the parent list
1664 AFSDeleteDirEntry( pParentObjectInfo,
1667 AFSAcquireShared( &pCurrentObject->NonPagedInfo->ObjectInfoLock,
1670 if( pCurrentObject->ObjectReferenceCount <= 0)
1673 if( BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_INSERTED_HASH_TREE))
1676 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
1677 AFS_TRACE_LEVEL_VERBOSE,
1678 "AFSLocateNameEntry Removing object %08lX from volume tree\n",
1681 AFSRemoveHashEntry( &pCurrentObject->VolumeCB->ObjectInfoTree.TreeHead,
1682 &pCurrentObject->TreeEntry);
1684 ClearFlag( pCurrentObject->Flags, AFS_OBJECT_INSERTED_HASH_TREE);
1688 AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock);
1693 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1694 AFS_TRACE_LEVEL_VERBOSE,
1695 "AFSLocateNameEntry Setting DELETE flag in dir entry %p for %wZ\n",
1697 &pDirEntry->NameInformation.FileName);
1699 SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
1701 AFSRemoveNameEntry( pParentObjectInfo,
1705 AFSReleaseResource( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
1707 AFSReleaseResource( pCurrentObject->VolumeCB->ObjectInfoTree.TreeLock);
1710 // We deleted the dir entry so check if there is any remaining portion
1711 // of the name to process.
1714 if( uniRemainingPath.Length > 0)
1716 ntStatus = STATUS_OBJECT_PATH_NOT_FOUND;
1721 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
1723 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1724 AFS_TRACE_LEVEL_VERBOSE,
1725 "AFSLocateNameEntry (FO: %08lX) Returning name not found(2) for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1728 pCurrentObject->FileId.Cell,
1729 pCurrentObject->FileId.Volume,
1730 pCurrentObject->FileId.Vnode,
1731 pCurrentObject->FileId.Unique);
1734 // Pass back the directory entries
1737 *ParentDirectoryCB = pParentDirEntry;
1739 *DirectoryCB = NULL;
1741 *VolumeCB = pCurrentVolume;
1743 if( ComponentName != NULL)
1746 *ComponentName = uniComponentName;
1749 *RootPathName = uniFullPathName;
1753 if( ntStatus != STATUS_SUCCESS)
1756 try_return( ntStatus);
1760 // Decrement the previous parent
1763 lCount = InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
1765 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1766 AFS_TRACE_LEVEL_VERBOSE,
1767 "AFSLocateNameEntry Decrement5 count on Parent %wZ DE %p Ccb %p Cnt %d\n",
1768 &pParentDirEntry->NameInformation.FileName,
1774 // If we ended up substituting a name in the component then update
1775 // the full path and update the pointers
1778 if( bSubstituteName)
1781 BOOLEAN bRelativeOpen = FALSE;
1783 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1784 AFS_TRACE_LEVEL_VERBOSE_2,
1785 "AFSLocateNameEntry (FO: %08lX) Substituting %wZ into %wZ Index %08lX\n",
1791 if( FileObject != NULL &&
1792 FileObject->RelatedFileObject != NULL)
1795 bRelativeOpen = TRUE;
1799 // AFSSubstituteNameInPath will replace the uniFullPathName.Buffer
1800 // and free the prior Buffer contents but only if the fourth
1801 // parameter is TRUE.
1804 ntStatus = AFSSubstituteNameInPath( &uniFullPathName,
1809 bAllocatedSymLinkBuffer ||
1812 if( !NT_SUCCESS( ntStatus))
1815 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1816 AFS_TRACE_LEVEL_ERROR,
1817 "AFSLocateNameEntry (FO: %08lX) Failure to substitute %wZ into %wZ Index %08lX Status %08lX\n",
1824 try_return( ntStatus);
1828 // We have substituted a name into the buffer so if we do this again for this
1829 // path, we need to free up the buffer we allocated.
1832 bSubstitutedName = TRUE;
1836 // Update the search parameters
1839 uniPathName = uniRemainingPath;
1842 // Check if the is a SymLink entry but has no Target FileID or Name. In this
1843 // case it might be a DFS Link so let's go and evaluate it to be sure
1846 if( pCurrentObject->FileType == AFS_FILE_TYPE_SYMLINK &&
1847 pCurrentObject->TargetFileId.Vnode == 0 &&
1848 pCurrentObject->TargetFileId.Unique == 0 &&
1849 pDirEntry->NameInformation.TargetName.Length == 0)
1852 ntStatus = AFSValidateSymLink( AuthGroup,
1855 if( !NT_SUCCESS( ntStatus))
1858 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1859 AFS_TRACE_LEVEL_ERROR,
1860 "AFSLocateNameEntry (FO: %08lX) Failed to evaluate possible DFS Link %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1862 &pDirEntry->NameInformation.FileName,
1863 pCurrentObject->FileId.Cell,
1864 pCurrentObject->FileId.Volume,
1865 pCurrentObject->FileId.Vnode,
1866 pCurrentObject->FileId.Unique,
1869 try_return( ntStatus);
1874 // Update the name array
1877 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1878 AFS_TRACE_LEVEL_VERBOSE,
1879 "AFSLocateNameEntry (FO: %08lX) Inserting name array entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1881 &pDirEntry->NameInformation.FileName,
1882 pCurrentObject->FileId.Cell,
1883 pCurrentObject->FileId.Volume,
1884 pCurrentObject->FileId.Vnode,
1885 pCurrentObject->FileId.Unique);
1887 ntStatus = AFSInsertNextElement( pNameArray,
1890 if( !NT_SUCCESS( ntStatus))
1893 try_return( ntStatus);
1899 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1900 AFS_TRACE_LEVEL_VERBOSE,
1901 "AFSLocateNameEntry (FO: %08lX) Completed processing %wZ Status %08lX\n",
1906 if( ( !NT_SUCCESS( ntStatus) &&
1907 ntStatus != STATUS_OBJECT_NAME_NOT_FOUND) ||
1908 ntStatus == STATUS_REPARSE)
1911 if( pDirEntry != NULL)
1914 lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
1916 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1917 AFS_TRACE_LEVEL_VERBOSE,
1918 "AFSLocateNameEntry Decrement6 count on %wZ DE %p Ccb %p Cnt %d\n",
1919 &pDirEntry->NameInformation.FileName,
1924 else if( pParentDirEntry != NULL)
1927 lCount = InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
1929 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1930 AFS_TRACE_LEVEL_VERBOSE,
1931 "AFSLocateNameEntry Decrement7 count on %wZ DE %p Ccb %p Cnt %d\n",
1932 &pParentDirEntry->NameInformation.FileName,
1938 if( bReleaseCurrentVolume)
1941 ASSERT( pCurrentVolume->VolumeReferenceCount > 1);
1943 lCount = InterlockedDecrement( &pCurrentVolume->VolumeReferenceCount);
1945 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
1946 AFS_TRACE_LEVEL_VERBOSE,
1947 "AFSLocateNameEntry Decrement3 count on volume %08lX Cnt %d\n",
1952 if( RootPathName->Buffer != uniFullPathName.Buffer)
1955 AFSExFreePoolWithTag( uniFullPathName.Buffer, 0);
1961 if( *ParentDirectoryCB != NULL)
1964 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1965 AFS_TRACE_LEVEL_VERBOSE,
1966 "AFSLocateNameEntry Count on Parent %wZ DE %p Ccb %p Cnt %d\n",
1967 &(*ParentDirectoryCB)->NameInformation.FileName,
1970 (*ParentDirectoryCB)->OpenReferenceCount);
1973 if( *DirectoryCB != NULL)
1976 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1977 AFS_TRACE_LEVEL_VERBOSE,
1978 "AFSLocateNameEntry Count on %wZ DE %p Ccb %p Cnt %d\n",
1979 &(*DirectoryCB)->NameInformation.FileName,
1982 (*DirectoryCB)->OpenReferenceCount);
1986 if( bSubstituteName &&
1987 uniSearchName.Buffer != NULL)
1990 AFSExFreePoolWithTag( uniSearchName.Buffer, 0);
1998 AFSCreateDirEntry( IN GUID *AuthGroup,
1999 IN AFSObjectInfoCB *ParentObjectInfo,
2000 IN AFSDirectoryCB *ParentDirCB,
2001 IN PUNICODE_STRING FileName,
2002 IN PUNICODE_STRING ComponentName,
2003 IN ULONG Attributes,
2004 IN OUT AFSDirectoryCB **DirEntry)
2007 NTSTATUS ntStatus = STATUS_SUCCESS;
2008 AFSDirectoryCB *pDirNode = NULL, *pExistingDirNode = NULL;
2009 UNICODE_STRING uniShortName;
2010 LARGE_INTEGER liFileSize = {0,0};
2016 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2017 AFS_TRACE_LEVEL_VERBOSE_2,
2018 "AFSCreateDirEntry Creating dir entry in parent %wZ FID %08lX-%08lX-%08lX-%08lX Component %wZ Attribs %08lX\n",
2019 &ParentDirCB->NameInformation.FileName,
2020 ParentObjectInfo->FileId.Cell,
2021 ParentObjectInfo->FileId.Volume,
2022 ParentObjectInfo->FileId.Vnode,
2023 ParentObjectInfo->FileId.Unique,
2028 // OK, before inserting the node into the parent tree, issue
2029 // the request to the service for node creation
2030 // We will need to drop the lock on the parent node since the create
2031 // could cause a callback into the file system to invalidate it's cache
2034 ntStatus = AFSNotifyFileCreate( AuthGroup,
2042 // If the returned status is STATUS_REPARSE then the entry exists
2043 // and we raced, get out.
2045 if( ntStatus == STATUS_REPARSE)
2048 *DirEntry = pDirNode;
2050 try_return( ntStatus = STATUS_SUCCESS);
2053 if( !NT_SUCCESS( ntStatus))
2056 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2057 AFS_TRACE_LEVEL_ERROR,
2058 "AFSCreateDirEntry Failed to create dir entry in parent %wZ FID %08lX-%08lX-%08lX-%08lX Component %wZ Attribs %08lX Status %08lX\n",
2059 &ParentDirCB->NameInformation.FileName,
2060 ParentObjectInfo->FileId.Cell,
2061 ParentObjectInfo->FileId.Volume,
2062 ParentObjectInfo->FileId.Vnode,
2063 ParentObjectInfo->FileId.Unique,
2068 try_return( ntStatus);
2071 AFSAcquireExcl( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2075 // Before attempting to insert the new entry, check if we need to validate the parent
2078 if( BooleanFlagOn( ParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY))
2081 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2082 AFS_TRACE_LEVEL_VERBOSE,
2083 "AFSCreateDirEntry Verifying parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2084 &ParentDirCB->NameInformation.FileName,
2085 ParentObjectInfo->FileId.Cell,
2086 ParentObjectInfo->FileId.Volume,
2087 ParentObjectInfo->FileId.Vnode,
2088 ParentObjectInfo->FileId.Unique);
2090 ntStatus = AFSVerifyEntry( AuthGroup,
2093 if( !NT_SUCCESS( ntStatus))
2096 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2097 AFS_TRACE_LEVEL_ERROR,
2098 "AFSCreateDirEntry Failed to verify parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2099 &ParentDirCB->NameInformation.FileName,
2100 ParentObjectInfo->FileId.Cell,
2101 ParentObjectInfo->FileId.Volume,
2102 ParentObjectInfo->FileId.Vnode,
2103 ParentObjectInfo->FileId.Unique,
2106 AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2108 try_return( ntStatus);
2113 // Check for the entry in the event we raced with some other thread
2116 AFSLocateCaseSensitiveDirEntry( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
2117 (ULONG)pDirNode->CaseSensitiveTreeEntry.HashIndex,
2120 if( pExistingDirNode != NULL)
2122 if (AFSIsEqualFID( &pDirNode->ObjectInformation->FileId,
2123 &pExistingDirNode->ObjectInformation->FileId))
2126 AFSDeleteDirEntry( ParentObjectInfo,
2129 lCount = InterlockedIncrement( &pExistingDirNode->OpenReferenceCount);
2131 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2132 AFS_TRACE_LEVEL_VERBOSE,
2133 "AFSCreateDirEntry Increment count on %wZ DE %p Cnt %d\n",
2134 &pExistingDirNode->NameInformation.FileName,
2138 *DirEntry = pExistingDirNode;
2140 AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2142 try_return( ntStatus = STATUS_SUCCESS);
2148 // Need to tear down this entry and rebuild it below
2151 if( pExistingDirNode->OpenReferenceCount == 0)
2154 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2155 AFS_TRACE_LEVEL_VERBOSE,
2156 "AFSCreateDirEntry Different FIDs - Deleting DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
2158 &pExistingDirNode->NameInformation.FileName,
2159 pExistingDirNode->ObjectInformation->FileId.Cell,
2160 pExistingDirNode->ObjectInformation->FileId.Volume,
2161 pExistingDirNode->ObjectInformation->FileId.Vnode,
2162 pExistingDirNode->ObjectInformation->FileId.Unique,
2163 pDirNode->ObjectInformation->FileId.Cell,
2164 pDirNode->ObjectInformation->FileId.Volume,
2165 pDirNode->ObjectInformation->FileId.Vnode,
2166 pDirNode->ObjectInformation->FileId.Unique);
2168 AFSDeleteDirEntry( ParentObjectInfo,
2174 SetFlag( pExistingDirNode->Flags, AFS_DIR_ENTRY_DELETED);
2176 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2177 AFS_TRACE_LEVEL_VERBOSE,
2178 "AFSCreateDirEntry Different FIDs - Removing DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
2180 &pExistingDirNode->NameInformation.FileName,
2181 pExistingDirNode->ObjectInformation->FileId.Cell,
2182 pExistingDirNode->ObjectInformation->FileId.Volume,
2183 pExistingDirNode->ObjectInformation->FileId.Vnode,
2184 pExistingDirNode->ObjectInformation->FileId.Unique,
2185 pDirNode->ObjectInformation->FileId.Cell,
2186 pDirNode->ObjectInformation->FileId.Volume,
2187 pDirNode->ObjectInformation->FileId.Vnode,
2188 pDirNode->ObjectInformation->FileId.Unique);
2190 AFSRemoveNameEntry( ParentObjectInfo,
2197 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2198 AFS_TRACE_LEVEL_VERBOSE_2,
2199 "AFSCreateDirEntry Inserting dir entry in parent %wZ FID %08lX-%08lX-%08lX-%08lX Component %wZ\n",
2200 &ParentDirCB->NameInformation.FileName,
2201 ParentObjectInfo->FileId.Cell,
2202 ParentObjectInfo->FileId.Volume,
2203 ParentObjectInfo->FileId.Vnode,
2204 ParentObjectInfo->FileId.Unique,
2208 // Insert the directory node
2211 AFSInsertDirectoryNode( ParentObjectInfo,
2215 lCount = InterlockedIncrement( &pDirNode->OpenReferenceCount);
2217 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2218 AFS_TRACE_LEVEL_VERBOSE,
2219 "AFSCreateDirEntry Increment2 count on %wZ DE %p Cnt %d\n",
2220 &pDirNode->NameInformation.FileName,
2225 // Pass back the dir entry
2228 *DirEntry = pDirNode;
2230 AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2241 AFSInsertDirectoryNode( IN AFSObjectInfoCB *ParentObjectInfo,
2242 IN AFSDirectoryCB *DirEntry,
2243 IN BOOLEAN InsertInEnumList)
2251 ASSERT( ExIsResourceAcquiredExclusiveLite( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock));
2254 // Insert the node into the directory node tree
2257 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2258 AFS_TRACE_LEVEL_VERBOSE,
2259 "AFSInsertDirectoryNode Insert DE %p for %wZ Clearing NOT_IN flag\n",
2261 &DirEntry->NameInformation.FileName);
2263 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
2265 if( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead == NULL)
2268 ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = DirEntry;
2270 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2271 AFS_TRACE_LEVEL_VERBOSE,
2272 "AFSInsertDirectoryNode Insert DE %p to head of case sensitive tree for %wZ\n",
2274 &DirEntry->NameInformation.FileName);
2279 AFSInsertCaseSensitiveDirEntry( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
2282 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2283 AFS_TRACE_LEVEL_VERBOSE,
2284 "AFSInsertDirectoryNode Insert DE %p to case sensitive tree for %wZ\n",
2286 &DirEntry->NameInformation.FileName);
2289 if( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead == NULL)
2292 ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = DirEntry;
2294 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
2296 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2297 AFS_TRACE_LEVEL_VERBOSE,
2298 "AFSInsertDirectoryNode Insert DE %p to head of case insensitive tree for %wZ\n",
2300 &DirEntry->NameInformation.FileName);
2305 AFSInsertCaseInsensitiveDirEntry( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
2308 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2309 AFS_TRACE_LEVEL_VERBOSE,
2310 "AFSInsertDirectoryNode Insert DE %p to case insensitive tree for %wZ\n",
2312 &DirEntry->NameInformation.FileName);
2316 // Into the shortname tree
2319 if( DirEntry->Type.Data.ShortNameTreeEntry.HashIndex != 0)
2322 if( ParentObjectInfo->Specific.Directory.ShortNameTree == NULL)
2325 ParentObjectInfo->Specific.Directory.ShortNameTree = DirEntry;
2327 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2328 AFS_TRACE_LEVEL_VERBOSE,
2329 "AFSInsertDirectoryNode Insert DE %p to head of shortname tree for %wZ\n",
2331 &DirEntry->NameInformation.FileName);
2333 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
2338 if( !NT_SUCCESS( AFSInsertShortNameDirEntry( ParentObjectInfo->Specific.Directory.ShortNameTree,
2341 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2342 AFS_TRACE_LEVEL_VERBOSE,
2343 "AFSInsertDirectoryNode Failed to insert DE %p to shortname tree for %wZ\n",
2345 &DirEntry->NameInformation.FileName);
2349 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
2351 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2352 AFS_TRACE_LEVEL_VERBOSE,
2353 "AFSInsertDirectoryNode Insert DE %p to shortname tree for %wZ\n",
2355 &DirEntry->NameInformation.FileName);
2360 if( InsertInEnumList)
2364 // And insert the node into the directory list
2367 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2368 AFS_TRACE_LEVEL_VERBOSE,
2369 "AFSInsertDirectoryNode Inserting entry %08lX %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2371 &DirEntry->NameInformation.FileName,
2372 DirEntry->ObjectInformation->FileId.Cell,
2373 DirEntry->ObjectInformation->FileId.Volume,
2374 DirEntry->ObjectInformation->FileId.Vnode,
2375 DirEntry->ObjectInformation->FileId.Unique);
2377 if( ParentObjectInfo->Specific.Directory.DirectoryNodeListHead == NULL)
2380 ParentObjectInfo->Specific.Directory.DirectoryNodeListHead = DirEntry;
2385 ParentObjectInfo->Specific.Directory.DirectoryNodeListTail->ListEntry.fLink = (void *)DirEntry;
2387 DirEntry->ListEntry.bLink = (void *)ParentObjectInfo->Specific.Directory.DirectoryNodeListTail;
2390 ParentObjectInfo->Specific.Directory.DirectoryNodeListTail = DirEntry;
2392 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST);
2394 lCount = InterlockedIncrement( &ParentObjectInfo->Specific.Directory.DirectoryNodeCount);
2396 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
2397 AFS_TRACE_LEVEL_VERBOSE,
2398 "AFSInsertDirectoryNode Adding entry %wZ Inc Count %d to parent FID %08lX-%08lX-%08lX-%08lX\n",
2399 &DirEntry->NameInformation.FileName,
2401 ParentObjectInfo->FileId.Cell,
2402 ParentObjectInfo->FileId.Volume,
2403 ParentObjectInfo->FileId.Vnode,
2404 ParentObjectInfo->FileId.Unique);
2412 AFSDeleteDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
2413 IN AFSDirectoryCB *DirEntry)
2416 NTSTATUS ntStatus = STATUS_SUCCESS;
2422 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2423 AFS_TRACE_LEVEL_VERBOSE,
2424 "AFSDeleteDirEntry Deleting dir entry in parent %08lX Entry %08lX %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2427 &DirEntry->NameInformation.FileName,
2428 DirEntry->ObjectInformation->FileId.Cell,
2429 DirEntry->ObjectInformation->FileId.Volume,
2430 DirEntry->ObjectInformation->FileId.Vnode,
2431 DirEntry->ObjectInformation->FileId.Unique);
2433 AFSRemoveDirNodeFromParent( ParentObjectInfo,
2438 // Free up the name buffer if it was reallocated
2441 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_RELEASE_NAME_BUFFER))
2444 AFSExFreePoolWithTag( DirEntry->NameInformation.FileName.Buffer, 0);
2447 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER))
2450 AFSExFreePoolWithTag( DirEntry->NameInformation.TargetName.Buffer, 0);
2454 // Dereference the object for this dir entry
2457 ASSERT( DirEntry->ObjectInformation->ObjectReferenceCount > 0);
2459 lCount = AFSObjectInfoDecrement( DirEntry->ObjectInformation);
2461 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2462 AFS_TRACE_LEVEL_VERBOSE,
2463 "AFSDeleteDirEntry Decrement count on object %08lX Cnt %d\n",
2464 DirEntry->ObjectInformation,
2467 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_DELETED) &&
2468 DirEntry->ObjectInformation->Links == 0)
2471 SetFlag( DirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED);
2474 ExDeleteResourceLite( &DirEntry->NonPaged->Lock);
2476 AFSExFreePoolWithTag( DirEntry->NonPaged, AFS_DIR_ENTRY_NP_TAG);
2479 // Free up the dir entry
2482 AFSExFreePoolWithTag( DirEntry, AFS_DIR_ENTRY_TAG);
2489 AFSRemoveDirNodeFromParent( IN AFSObjectInfoCB *ParentObjectInfo,
2490 IN AFSDirectoryCB *DirEntry,
2491 IN BOOLEAN RemoveFromEnumList)
2494 NTSTATUS ntStatus = STATUS_SUCCESS;
2501 ASSERT( ExIsResourceAcquiredExclusiveLite( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock));
2503 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2504 AFS_TRACE_LEVEL_VERBOSE,
2505 "AFSRemoveDirNodeFromParent Removing DirEntry %08lX %wZ FID %08lX-%08lX-%08lX-%08lX from Parent %08lX\n",
2507 &DirEntry->NameInformation.FileName,
2508 DirEntry->ObjectInformation->FileId.Cell,
2509 DirEntry->ObjectInformation->FileId.Volume,
2510 DirEntry->ObjectInformation->FileId.Vnode,
2511 DirEntry->ObjectInformation->FileId.Unique,
2514 if( !BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
2517 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2518 AFS_TRACE_LEVEL_VERBOSE,
2519 "AFSRemoveDirNodeFromParent Removing DirEntry %08lX name %wZ\n",
2521 &DirEntry->NameInformation.FileName);
2523 AFSRemoveNameEntry( ParentObjectInfo,
2529 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2530 AFS_TRACE_LEVEL_VERBOSE,
2531 "AFSRemoveDirNodeFromParent DE %p for %wZ NOT removing entry due to flag set\n",
2533 &DirEntry->NameInformation.FileName);
2537 if( RemoveFromEnumList &&
2538 BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST))
2542 // And remove the entry from the enumeration list
2545 if( DirEntry->ListEntry.fLink == NULL)
2548 ParentObjectInfo->Specific.Directory.DirectoryNodeListTail = (AFSDirectoryCB *)DirEntry->ListEntry.bLink;
2553 ((AFSDirectoryCB *)DirEntry->ListEntry.fLink)->ListEntry.bLink = DirEntry->ListEntry.bLink;
2556 if( DirEntry->ListEntry.bLink == NULL)
2559 ParentObjectInfo->Specific.Directory.DirectoryNodeListHead = (AFSDirectoryCB *)DirEntry->ListEntry.fLink;
2564 ((AFSDirectoryCB *)DirEntry->ListEntry.bLink)->ListEntry.fLink = DirEntry->ListEntry.fLink;
2567 ASSERT( ParentObjectInfo->Specific.Directory.DirectoryNodeCount > 0);
2569 lCount = InterlockedDecrement( &ParentObjectInfo->Specific.Directory.DirectoryNodeCount);
2571 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST);
2573 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
2574 AFS_TRACE_LEVEL_VERBOSE,
2575 "AFSRemoveDirNodeFromParent Removing entry %wZ Dec Count %d to parent FID %08lX-%08lX-%08lX-%08lX\n",
2576 &DirEntry->NameInformation.FileName,
2578 ParentObjectInfo->FileId.Cell,
2579 ParentObjectInfo->FileId.Volume,
2580 ParentObjectInfo->FileId.Vnode,
2581 ParentObjectInfo->FileId.Unique);
2583 DirEntry->ListEntry.fLink = NULL;
2584 DirEntry->ListEntry.bLink = NULL;
2592 AFSFixupTargetName( IN OUT PUNICODE_STRING FileName,
2593 IN OUT PUNICODE_STRING TargetFileName)
2596 NTSTATUS ntStatus = STATUS_SUCCESS;
2597 UNICODE_STRING uniFileName;
2603 // We will process backwards from the end of the name looking
2604 // for the first \ we encounter
2607 uniFileName.Length = FileName->Length;
2608 uniFileName.MaximumLength = FileName->MaximumLength;
2610 uniFileName.Buffer = FileName->Buffer;
2615 if( uniFileName.Buffer[ (uniFileName.Length/sizeof( WCHAR)) - 1] == L'\\')
2619 // Subtract one more character off of the filename if it is not the root
2622 if( uniFileName.Length > sizeof( WCHAR))
2625 uniFileName.Length -= sizeof( WCHAR);
2629 // Now build up the target name
2632 TargetFileName->Length = FileName->Length - uniFileName.Length;
2635 // If we are not on the root then fixup the name
2638 if( uniFileName.Length > sizeof( WCHAR))
2641 TargetFileName->Length -= sizeof( WCHAR);
2643 TargetFileName->Buffer = &uniFileName.Buffer[ (uniFileName.Length/sizeof( WCHAR)) + 1];
2648 TargetFileName->Buffer = &uniFileName.Buffer[ uniFileName.Length/sizeof( WCHAR)];
2652 // Fixup the passed back filename length
2655 FileName->Length = uniFileName.Length;
2657 TargetFileName->MaximumLength = TargetFileName->Length;
2662 uniFileName.Length -= sizeof( WCHAR);
2670 AFSParseName( IN PIRP Irp,
2672 OUT PUNICODE_STRING FileName,
2673 OUT PUNICODE_STRING ParsedFileName,
2674 OUT PUNICODE_STRING RootFileName,
2675 OUT ULONG *ParseFlags,
2676 OUT AFSVolumeCB **VolumeCB,
2677 OUT AFSDirectoryCB **ParentDirectoryCB,
2678 OUT AFSNameArrayHdr **NameArray)
2681 NTSTATUS ntStatus = STATUS_SUCCESS;
2682 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2683 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2684 UNICODE_STRING uniFullName, uniComponentName, uniRemainingPath;
2686 AFSDirectoryCB *pDirEntry = NULL, *pShareDirEntry = NULL, *pTargetDirEntry = NULL;
2687 USHORT usIndex = 0, usDriveIndex = 0;
2688 AFSCcb *pRelatedCcb = NULL;
2689 AFSNameArrayHdr *pNameArray = NULL, *pRelatedNameArray = NULL;
2690 USHORT usComponentIndex = 0;
2691 USHORT usComponentLength = 0;
2692 AFSVolumeCB *pVolumeCB = NULL;
2693 AFSFcb *pRelatedFcb = NULL;
2694 BOOLEAN bReleaseTreeLock = FALSE;
2695 BOOLEAN bIsAllShare = FALSE;
2702 // Indicate we are opening a root ...
2705 *ParseFlags = AFS_PARSE_FLAG_ROOT_ACCESS;
2707 if( pIrpSp->FileObject->RelatedFileObject != NULL)
2710 pRelatedFcb = (AFSFcb *)pIrpSp->FileObject->RelatedFileObject->FsContext;
2712 pRelatedCcb = (AFSCcb *)pIrpSp->FileObject->RelatedFileObject->FsContext2;
2714 pRelatedNameArray = pRelatedCcb->NameArray;
2716 uniFullName = pIrpSp->FileObject->FileName;
2718 ASSERT( pRelatedFcb != NULL);
2721 // No wild cards in the name
2724 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2725 AFS_TRACE_LEVEL_VERBOSE_2,
2726 "AFSParseName (%08lX) Relative open for %wZ FID %08lX-%08lX-%08lX-%08lX component %wZ\n",
2728 &pRelatedCcb->DirectoryCB->NameInformation.FileName,
2729 pRelatedCcb->DirectoryCB->ObjectInformation->FileId.Cell,
2730 pRelatedCcb->DirectoryCB->ObjectInformation->FileId.Volume,
2731 pRelatedCcb->DirectoryCB->ObjectInformation->FileId.Vnode,
2732 pRelatedCcb->DirectoryCB->ObjectInformation->FileId.Unique,
2735 if( FsRtlDoesNameContainWildCards( &uniFullName))
2738 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2739 AFS_TRACE_LEVEL_ERROR,
2740 "AFSParseName (%08lX) Component %wZ contains wild cards\n",
2744 try_return( ntStatus = STATUS_OBJECT_NAME_INVALID);
2747 pVolumeCB = pRelatedFcb->ObjectInformation->VolumeCB;
2749 pDirEntry = pRelatedCcb->DirectoryCB;
2751 *FileName = pIrpSp->FileObject->FileName;
2754 // Grab the root node while checking state
2757 AFSAcquireShared( pVolumeCB->VolumeLock,
2760 if( BooleanFlagOn( pVolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
2761 BooleanFlagOn( pVolumeCB->Flags, AFS_VOLUME_FLAGS_OFFLINE))
2765 // The volume has been taken off line so fail the access
2768 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2769 AFS_TRACE_LEVEL_ERROR,
2770 "AFSParseName (%08lX) Volume %08lX:%08lX OFFLINE/INVALID\n",
2772 pVolumeCB->ObjectInformation.FileId.Cell,
2773 pVolumeCB->ObjectInformation.FileId.Volume);
2775 AFSReleaseResource( pVolumeCB->VolumeLock);
2777 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
2780 if( BooleanFlagOn( pVolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_VERIFY))
2783 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2784 AFS_TRACE_LEVEL_VERBOSE,
2785 "AFSParseName (%08lX) Verifying root of volume %08lX:%08lX\n",
2787 pVolumeCB->ObjectInformation.FileId.Cell,
2788 pVolumeCB->ObjectInformation.FileId.Volume);
2790 ntStatus = AFSVerifyVolume( (ULONGLONG)PsGetCurrentProcessId(),
2793 if( !NT_SUCCESS( ntStatus))
2796 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2797 AFS_TRACE_LEVEL_ERROR,
2798 "AFSParseName (%08lX) Failed verification of root Status %08lX\n",
2802 AFSReleaseResource( pVolumeCB->VolumeLock);
2804 try_return( ntStatus);
2808 AFSReleaseResource( pVolumeCB->VolumeLock);
2810 if( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY))
2813 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2814 AFS_TRACE_LEVEL_VERBOSE,
2815 "AFSParseName (%08lX) Verifying parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2817 &pDirEntry->NameInformation.FileName,
2818 pDirEntry->ObjectInformation->FileId.Cell,
2819 pDirEntry->ObjectInformation->FileId.Volume,
2820 pDirEntry->ObjectInformation->FileId.Vnode,
2821 pDirEntry->ObjectInformation->FileId.Unique);
2824 // Directory TreeLock should be exclusively held
2827 AFSAcquireExcl( pDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
2830 ntStatus = AFSVerifyEntry( AuthGroup,
2833 AFSReleaseResource( pDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
2835 if( !NT_SUCCESS( ntStatus))
2838 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2839 AFS_TRACE_LEVEL_VERBOSE,
2840 "AFSParseName (%08lX) Failed verification of parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2842 &pDirEntry->NameInformation.FileName,
2843 pDirEntry->ObjectInformation->FileId.Cell,
2844 pDirEntry->ObjectInformation->FileId.Volume,
2845 pDirEntry->ObjectInformation->FileId.Vnode,
2846 pDirEntry->ObjectInformation->FileId.Unique,
2849 try_return( ntStatus);
2854 // Create our full path name buffer
2857 uniFullName.MaximumLength = pRelatedCcb->FullFileName.Length +
2859 pIrpSp->FileObject->FileName.Length +
2862 uniFullName.Length = 0;
2864 uniFullName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2865 uniFullName.MaximumLength,
2866 AFS_NAME_BUFFER_THREE_TAG);
2868 if( uniFullName.Buffer == NULL)
2871 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2872 AFS_TRACE_LEVEL_ERROR,
2873 "AFSParseName (%08lX) Failed to allocate full name buffer\n",
2876 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2879 RtlZeroMemory( uniFullName.Buffer,
2880 uniFullName.MaximumLength);
2882 RtlCopyMemory( uniFullName.Buffer,
2883 pRelatedCcb->FullFileName.Buffer,
2884 pRelatedCcb->FullFileName.Length);
2886 uniFullName.Length = pRelatedCcb->FullFileName.Length;
2888 usComponentIndex = (USHORT)(uniFullName.Length/sizeof( WCHAR));
2890 usComponentLength = pIrpSp->FileObject->FileName.Length;
2892 if( uniFullName.Buffer[ (uniFullName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
2893 pIrpSp->FileObject->FileName.Length > 0 &&
2894 pIrpSp->FileObject->FileName.Buffer[ 0] != L'\\' &&
2895 pIrpSp->FileObject->FileName.Buffer[ 0] != L':')
2898 uniFullName.Buffer[ (uniFullName.Length/sizeof( WCHAR))] = L'\\';
2900 uniFullName.Length += sizeof( WCHAR);
2902 usComponentLength += sizeof( WCHAR);
2905 if( pIrpSp->FileObject->FileName.Length > 0)
2908 RtlCopyMemory( &uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)],
2909 pIrpSp->FileObject->FileName.Buffer,
2910 pIr
\epSp->FileObject->FileName.Length);
2912 uniFullName.Length += pIrpSp->FileObject->FileName.Length;
2915 *RootFileName = uniFullName;
2918 // We populate up to the current parent
2921 if( pRelatedNameArray == NULL)
2925 // Init and populate our name array
2928 pNameArray = AFSInitNameArray( NULL,
2931 if( pNameArray == NULL)
2934 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2935 AFS_TRACE_LEVEL_VERBOSE,
2936 "AFSParseName (%08lX) Failed to initialize name array\n",
2939 AFSExFreePoolWithTag( uniFullName.Buffer, 0);
2941 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2944 ntStatus = AFSPopulateNameArray( pNameArray,
2946 pRelatedCcb->DirectoryCB);
2952 // Init and populate our name array
2955 pNameArray = AFSInitNameArray( NULL,
2956 pRelatedNameArray->MaxElementCount);
2958 if( pNameArray == NULL)
2961 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2962 AFS_TRACE_LEVEL_VERBOSE,
2963 "AFSParseName (%08lX) Failed to initialize name array\n",
2966 AFSExFreePoolWithTag( uniFullName.Buffer, 0);
2968 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2971 ntStatus = AFSPopulateNameArrayFromRelatedArray( pNameArray,
2973 pRelatedCcb->DirectoryCB);
2976 if( !NT_SUCCESS( ntStatus))
2979 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2980 AFS_TRACE_LEVEL_VERBOSE,
2981 "AFSParseName (%08lX) Failed to populate name array\n",
2984 AFSExFreePoolWithTag( uniFullName.Buffer, 0);
2986 try_return( ntStatus);
2989 ParsedFileName->Length = usComponentLength;
2990 ParsedFileName->MaximumLength = uniFullName.MaximumLength;
2992 ParsedFileName->Buffer = &uniFullName.Buffer[ usComponentIndex];
2995 // Indicate to caller that RootFileName must be freed
2998 SetFlag( *ParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
3000 *NameArray = pNameArray;
3002 *VolumeCB = pVolumeCB;
3005 // Increment our volume reference count
3008 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
3010 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
3011 AFS_TRACE_LEVEL_VERBOSE,
3012 "AFSParseName Increment count on volume %08lX Cnt %d\n",
3016 *ParentDirectoryCB = pDirEntry;
3018 lCount = InterlockedIncrement( &pDirEntry->OpenReferenceCount);
3020 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3021 AFS_TRACE_LEVEL_VERBOSE,
3022 "AFSParseName Increment1 count on %wZ DE %p Ccb %p Cnt %d\n",
3023 &pDirEntry->NameInformation.FileName,
3028 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3029 AFS_TRACE_LEVEL_VERBOSE_2,
3030 "AFSParseName (%08lX) Returning full name %wZ\n",
3034 try_return( ntStatus);
3038 // No wild cards in the name
3041 uniFullName = pIrpSp->FileObject->FileName;
3043 if( FsRtlDoesNameContainWildCards( &uniFullName) ||
3044 uniFullName.Length < AFSServerName.Length)
3047 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3048 AFS_TRACE_LEVEL_ERROR,
3049 "AFSParseName (%08lX) Name %wZ contains wild cards or too short\n",
3053 try_return( ntStatus = STATUS_OBJECT_NAME_INVALID);
3057 // The name is a fully qualified name. Parse out the server/share names and
3058 // point to the root qualified name
3059 // First thing is to locate the server name
3062 FsRtlDissectName( uniFullName,
3066 uniFullName = uniRemainingPath;
3069 // This component is the server name we are serving
3072 if( RtlCompareUnicodeString( &uniComponentName,
3078 // Drive letter based name?
3081 uniFullName = pIrpSp->FileObject->FileName;
3083 while( usIndex < uniFullName.Length/sizeof( WCHAR))
3086 if( uniFullName.Buffer[ usIndex] == L':')
3089 uniFullName.Buffer = &uniFullName.Buffer[ usIndex + 2];
3091 uniFullName.Length -= (usIndex + 2) * sizeof( WCHAR);
3093 usDriveIndex = usIndex - 1;
3102 // Do we have the right server name now?
3105 FsRtlDissectName( uniFullName,
3109 uniFullName = uniRemainingPath;
3112 // This component is the server name we are serving
3115 if( RtlCompareUnicodeString( &uniComponentName,
3120 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3121 AFS_TRACE_LEVEL_ERROR,
3122 "AFSParseName (%08lX) Name %wZ does not have server name\n",
3124 &pIrpSp->FileObject->FileName);
3126 try_return( ntStatus = STATUS_BAD_NETWORK_NAME);
3130 // Validate this drive letter is actively mapped
3133 if( usDriveIndex > 0 &&
3134 !AFSIsDriveMapped( pIrpSp->FileObject->FileName.Buffer[ usDriveIndex]))
3137 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3138 AFS_TRACE_LEVEL_ERROR,
3139 "AFSParseName (%08lX) Name %wZ contains invalid drive mapping\n",
3141 &pIrpSp->FileObject->FileName);
3143 try_return( ntStatus = STATUS_BAD_NETWORK_NAME);
3147 if( FsRtlDoesNameContainWildCards( &uniFullName))
3150 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3151 AFS_TRACE_LEVEL_ERROR,
3152 "AFSParseName (%08lX) Component %wZ contains wild cards\n",
3156 try_return( ntStatus = STATUS_OBJECT_NAME_INVALID);
3159 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3160 AFS_TRACE_LEVEL_VERBOSE_2,
3161 "AFSParseName (%08lX) Processing full name %wZ\n",
3165 if( uniFullName.Length > 0 &&
3166 uniFullName.Buffer[ (uniFullName.Length/sizeof( WCHAR)) - 1] == L'\\')
3169 uniFullName.Length -= sizeof( WCHAR);
3173 // Be sure we are online and ready to go
3176 AFSAcquireShared( AFSGlobalRoot->VolumeLock,
3179 if( BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
3180 BooleanFlagOn( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE))
3184 // The volume has been taken off line so fail the access
3187 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3188 AFS_TRACE_LEVEL_ERROR,
3189 "AFSParseName (%08lX) Volume %08lX:%08lX OFFLINE/INVALID\n",
3191 AFSGlobalRoot->ObjectInformation.FileId.Cell,
3192 AFSGlobalRoot->ObjectInformation.FileId.Volume);
3194 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3196 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
3199 if( BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_VERIFY))
3202 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3203 AFS_TRACE_LEVEL_VERBOSE,
3204 "AFSParseName (%08lX) Verifying root of volume %08lX:%08lX\n",
3206 AFSGlobalRoot->ObjectInformation.FileId.Cell,
3207 AFSGlobalRoot->ObjectInformation.FileId.Volume);
3209 ntStatus = AFSVerifyVolume( (ULONGLONG)PsGetCurrentProcessId(),
3212 if( !NT_SUCCESS( ntStatus))
3215 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3216 AFS_TRACE_LEVEL_ERROR,
3217 "AFSParseName (%08lX) Failed verification of root Status %08lX\n",
3221 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3223 try_return( ntStatus);
3227 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3229 if( !BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
3232 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3233 AFS_TRACE_LEVEL_VERBOSE,
3234 "AFSParseName (%08lX) Enumerating global root of volume %08lX:%08lX\n",
3236 AFSGlobalRoot->ObjectInformation.FileId.Cell,
3237 AFSGlobalRoot->ObjectInformation.FileId.Volume);
3239 ntStatus = AFSEnumerateGlobalRoot( AuthGroup);
3241 if( !NT_SUCCESS( ntStatus))
3244 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3245 AFS_TRACE_LEVEL_ERROR,
3246 "AFSParseName (%08lX) Failed enumeraiton of root Status %08lX\n",
3250 try_return( ntStatus);
3255 // Check for the \\Server access and return it as though it where \\Server\Globalroot
3258 if( uniRemainingPath.Buffer == NULL ||
3259 ( uniRemainingPath.Length == sizeof( WCHAR) &&
3260 uniRemainingPath.Buffer[ 0] == L'\\'))
3263 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3264 AFS_TRACE_LEVEL_VERBOSE_2,
3265 "AFSParseName (%08lX) Returning global root access\n",
3268 lCount = InterlockedIncrement( &AFSGlobalRoot->DirectoryCB->OpenReferenceCount);
3270 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3271 AFS_TRACE_LEVEL_VERBOSE,
3272 "AFSParseName Increment2 count on %wZ DE %p Ccb %p Cnt %d\n",
3273 &AFSGlobalRoot->DirectoryCB->NameInformation.FileName,
3274 AFSGlobalRoot->DirectoryCB,
3280 FileName->Length = 0;
3281 FileName->MaximumLength = 0;
3282 FileName->Buffer = NULL;
3284 try_return( ntStatus = STATUS_SUCCESS);
3287 *RootFileName = uniFullName;
3290 // Include the starting \ in the root name
3293 if( RootFileName->Buffer[ 0] != L'\\')
3295 RootFileName->Buffer--;
3296 RootFileName->Length += sizeof( WCHAR);
3297 RootFileName->MaximumLength += sizeof( WCHAR);
3301 // Get the 'share' name
3304 FsRtlDissectName( uniFullName,
3308 if( FsRtlDoesNameContainWildCards( &uniFullName))
3311 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3312 AFS_TRACE_LEVEL_ERROR,
3313 "AFSParseName (%08lX) Component %wZ contains wild cards\n",
3317 try_return( ntStatus = STATUS_OBJECT_NAME_INVALID);
3321 // If this is the ALL access then perform some additional processing
3324 if( uniComponentName.Length == 0 ||
3325 RtlCompareUnicodeString( &uniComponentName,
3333 // If there is nothing else then get out
3336 if( uniRemainingPath.Buffer == NULL ||
3337 uniRemainingPath.Length == 0 ||
3338 ( uniRemainingPath.Length == sizeof( WCHAR) &&
3339 uniRemainingPath.Buffer[ 0] == L'\\'))
3342 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3343 AFS_TRACE_LEVEL_VERBOSE_2,
3344 "AFSParseName (%08lX) Returning global root access\n",
3347 lCount = InterlockedIncrement( &AFSGlobalRoot->DirectoryCB->OpenReferenceCount);
3349 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3350 AFS_TRACE_LEVEL_VERBOSE,
3351 "AFSParseName Increment3 count on %wZ DE %p Ccb %p Cnt %d\n",
3352 &AFSGlobalRoot->DirectoryCB->NameInformation.FileName,
3353 AFSGlobalRoot->DirectoryCB,
3359 FileName->Length = 0;
3360 FileName->MaximumLength = 0;
3361 FileName->Buffer = NULL;
3363 try_return( ntStatus = STATUS_SUCCESS);
3367 // Process the name again to strip off the ALL portion
3370 uniFullName = uniRemainingPath;
3372 FsRtlDissectName( uniFullName,
3377 // Check for the PIOCtl name
3380 if( RtlCompareUnicodeString( &uniComponentName,
3385 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3386 AFS_TRACE_LEVEL_VERBOSE_2,
3387 "AFSParseName (%08lX) Returning root PIOCtl access\n",
3390 lCount = InterlockedIncrement( &AFSGlobalRoot->DirectoryCB->OpenReferenceCount);
3392 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3393 AFS_TRACE_LEVEL_VERBOSE,
3394 "AFSParseName Increment4 count on %wZ DE %p Ccb %p Cnt %d\n",
3395 &AFSGlobalRoot->DirectoryCB->NameInformation.FileName,
3396 AFSGlobalRoot->DirectoryCB,
3400 ClearFlag( *ParseFlags, AFS_PARSE_FLAG_ROOT_ACCESS);
3404 *FileName = AFSPIOCtlName;
3406 try_return( ntStatus = STATUS_SUCCESS);
3409 else if( (pDirEntry = AFSGetSpecialShareNameEntry( &uniComponentName,
3410 &uniRemainingPath)) != NULL)
3413 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3414 AFS_TRACE_LEVEL_VERBOSE_2,
3415 "AFSParseName (%08lX) Returning root share name %wZ access\n",
3420 // Add in the full share name to pass back
3423 if( uniRemainingPath.Buffer != NULL)
3427 // This routine strips off the leading slash so add it back in
3430 uniRemainingPath.Buffer--;
3431 uniRemainingPath.Length += sizeof( WCHAR);
3432 uniRemainingPath.MaximumLength += sizeof( WCHAR);
3435 // And the cell name
3438 uniRemainingPath.Buffer -= (uniComponentName.Length/sizeof( WCHAR));
3439 uniRemainingPath.Length += uniComponentName.Length;
3440 uniRemainingPath.MaximumLength += uniComponentName.Length;
3442 uniComponentName = uniRemainingPath;
3447 *FileName = uniComponentName;
3449 *ParentDirectoryCB = pDirEntry;
3451 ClearFlag( *ParseFlags, AFS_PARSE_FLAG_ROOT_ACCESS);
3453 lCount = InterlockedIncrement( &pDirEntry->OpenReferenceCount);
3455 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3456 AFS_TRACE_LEVEL_VERBOSE,
3457 "AFSParseName Increment5 count on %wZ DE %p Ccb %p Cnt %d\n",
3458 &pDirEntry->NameInformation.FileName,
3463 try_return( ntStatus = STATUS_SUCCESS);
3467 // Determine the 'share' we are accessing
3470 ulCRC = AFSGenerateCRC( &uniComponentName,
3473 AFSAcquireShared( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
3476 bReleaseTreeLock = TRUE;
3478 AFSLocateCaseSensitiveDirEntry( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
3482 if( pDirEntry == NULL)
3485 ulCRC = AFSGenerateCRC( &uniComponentName,
3488 AFSLocateCaseInsensitiveDirEntry( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
3492 if( pDirEntry == NULL)
3496 // OK, if this component is a valid short name then try
3497 // a lookup in the short name tree
3500 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
3501 RtlIsNameLegalDOS8Dot3( &uniComponentName,
3506 AFSLocateShortNameDirEntry( AFSGlobalRoot->ObjectInformation.Specific.Directory.ShortNameTree,
3511 if( pDirEntry == NULL)
3515 // Check with the service whether it is a valid cell name
3518 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
3520 bReleaseTreeLock = FALSE;
3522 ntStatus = AFSCheckCellName( AuthGroup,
3526 if( !NT_SUCCESS( ntStatus))
3530 uniRemainingPath.Length == 0 &&
3531 ntStatus == STATUS_OBJECT_PATH_NOT_FOUND)
3534 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
3537 try_return( ntStatus);
3543 if( bReleaseTreeLock)
3545 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
3550 // Be sure we are starting from the correct volume
3553 if( pDirEntry->ObjectInformation->VolumeCB != AFSGlobalRoot)
3557 // We dropped the global root in the CheckCellName routine which is the
3558 // only way we can be here
3561 pVolumeCB = pDirEntry->ObjectInformation->VolumeCB;
3564 // Init our name array
3567 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
3570 if( pNameArray == NULL)
3573 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3574 AFS_TRACE_LEVEL_VERBOSE,
3575 "AFSParseName (%08lX) Failed to initialize name array\n",
3578 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3581 ntStatus = AFSInsertNextElement( pNameArray,
3582 pVolumeCB->DirectoryCB);
3587 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3588 AFS_TRACE_LEVEL_VERBOSE,
3589 "AFSParseName (%08lX) Failed to insert name array element\n",
3592 try_return( ntStatus);
3596 // In this case don't add back in the 'share' name since that is where we are
3597 // starting. Just put the leading slash back in
3600 if( uniRemainingPath.Buffer != NULL)
3603 uniRemainingPath.Buffer--;
3604 uniRemainingPath.Length += sizeof( WCHAR);
3605 uniRemainingPath.MaximumLength += sizeof( WCHAR);
3607 if( uniRemainingPath.Length > sizeof( WCHAR))
3610 ClearFlag( *ParseFlags, AFS_PARSE_FLAG_ROOT_ACCESS);
3614 // Pass back the parent being the root of the volume
3617 *ParentDirectoryCB = pVolumeCB->DirectoryCB;
3623 // Pass back a root slash
3626 uniRemainingPath = uniComponentName;
3628 uniRemainingPath.Buffer--;
3629 uniRemainingPath.Length = sizeof( WCHAR);
3630 uniRemainingPath.MaximumLength = sizeof( WCHAR);
3633 // This is a root open so pass back no parent
3636 *ParentDirectoryCB = NULL;
3642 pVolumeCB = AFSGlobalRoot;
3645 // Init our name array
3648 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
3650 if( pNameArray == NULL)
3653 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3654 AFS_TRACE_LEVEL_VERBOSE,
3655 "AFSParseName (%08lX) Failed to initialize name array\n",
3658 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3662 // Add back in the 'share' portion of the name since we will parse it out on return
3665 if( uniRemainingPath.Buffer != NULL)
3669 // This routine strips off the leading slash so add it back in
3672 uniRemainingPath.Buffer--;
3673 uniRemainingPath.Length += sizeof( WCHAR);
3674 uniRemainingPath.MaximumLength += sizeof( WCHAR);
3676 if( uniRemainingPath.Length > sizeof( WCHAR))
3679 ClearFlag( *ParseFlags, AFS_PARSE_FLAG_ROOT_ACCESS);
3683 // And the cell name
3686 uniRemainingPath.Buffer -= (uniComponentName.Length/sizeof( WCHAR));
3687 uniRemainingPath.Length += uniComponentName.Length;
3688 uniRemainingPath.MaximumLength += uniComponentName.Length;
3693 uniRemainingPath = uniComponentName;
3697 // And the leading slash again ...
3700 uniRemainingPath.Buffer--;
3701 uniRemainingPath.Length += sizeof( WCHAR);
3702 uniRemainingPath.MaximumLength += sizeof( WCHAR);
3704 lCount = InterlockedIncrement( &pVolumeCB->DirectoryCB->OpenReferenceCount);
3706 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3707 AFS_TRACE_LEVEL_VERBOSE,
3708 "AFSParseName Increment6 count on %wZ DE %p Ccb %p Cnt %d\n",
3709 &pVolumeCB->DirectoryCB->NameInformation.FileName,
3710 pVolumeCB->DirectoryCB,
3712 lCount = pVolumeCB->DirectoryCB->OpenReferenceCount);
3715 // Pass back the parent being the volume root
3718 *ParentDirectoryCB = pVolumeCB->DirectoryCB;
3723 // Return the remaining portion as the file name
3726 *FileName = uniRemainingPath;
3728 *ParsedFileName = uniRemainingPath;
3730 *NameArray = pNameArray;
3732 *VolumeCB = pVolumeCB;
3735 // Increment our reference on the volume
3738 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
3740 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
3741 AFS_TRACE_LEVEL_VERBOSE,
3742 "AFSParseName Increment2 count on global volume %08lX Cnt %d\n",
3748 if( NT_SUCCESS( ntStatus))
3751 if( *ParentDirectoryCB != NULL)
3754 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3755 AFS_TRACE_LEVEL_VERBOSE,
3756 "AFSParseName Count on %wZ DE %p Ccb %p Cnt %d\n",
3757 &(*ParentDirectoryCB)->NameInformation.FileName,
3760 (*ParentDirectoryCB)->OpenReferenceCount);
3764 if( *VolumeCB != NULL)
3766 ASSERT( (*VolumeCB)->VolumeReferenceCount > 1);
3769 if( ntStatus != STATUS_SUCCESS)
3772 if( pNameArray != NULL)
3775 AFSFreeNameArray( pNameArray);
3784 AFSCheckCellName( IN GUID *AuthGroup,
3785 IN UNICODE_STRING *CellName,
3786 OUT AFSDirectoryCB **ShareDirEntry)
3789 NTSTATUS ntStatus = STATUS_SUCCESS;
3790 UNICODE_STRING uniName;
3791 AFSDirEnumEntry *pDirEnumEntry = NULL;
3792 AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
3793 AFSDirHdr *pDirHdr = &AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr;
3794 AFSDirectoryCB *pDirNode = NULL;
3795 UNICODE_STRING uniDirName, uniTargetName;
3796 AFSVolumeCB *pVolumeCB = NULL;
3803 // Look for some default names we will not handle
3806 RtlInitUnicodeString( &uniName,
3809 if( RtlCompareUnicodeString( &uniName,
3814 try_return( ntStatus = STATUS_NO_SUCH_FILE);
3817 RtlInitUnicodeString( &uniName,
3820 if( RtlCompareUnicodeString( &uniName,
3825 try_return( ntStatus = STATUS_NO_SUCH_FILE);
3828 RtlInitUnicodeString( &uniName,
3831 if( RtlCompareUnicodeString( &uniName,
3836 try_return( ntStatus = STATUS_NO_SUCH_FILE);
3839 RtlInitUnicodeString( &uniName,
3842 if( RtlCompareUnicodeString( &uniName,
3847 try_return( ntStatus = STATUS_NO_SUCH_FILE);
3851 // OK, ask the CM about this component name
3854 ntStatus = AFSEvaluateTargetByName( AuthGroup,
3855 &AFSGlobalRoot->ObjectInformation,
3859 if( !NT_SUCCESS( ntStatus))
3862 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3863 AFS_TRACE_LEVEL_WARNING,
3864 "AFSCheckCellName entry %wZ does not exist parent FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
3866 AFSGlobalRoot->ObjectInformation.FileId.Cell,
3867 AFSGlobalRoot->ObjectInformation.FileId.Volume,
3868 AFSGlobalRoot->ObjectInformation.FileId.Vnode,
3869 AFSGlobalRoot->ObjectInformation.FileId.Unique,
3872 try_return( ntStatus);
3876 // OK, we have a dir enum entry back so add it to the root node
3879 uniDirName = *CellName;
3881 uniTargetName.Length = (USHORT)pDirEnumEntry->TargetNameLength;
3882 uniTargetName.MaximumLength = uniTargetName.Length;
3883 uniTargetName.Buffer = (WCHAR *)((char *)pDirEnumEntry + pDirEnumEntry->TargetNameOffset);
3886 // Is this entry a root volume entry?
3889 if( pDirEnumEntry->FileId.Cell != AFSGlobalRoot->ObjectInformation.FileId.Cell ||
3890 pDirEnumEntry->FileId.Volume != AFSGlobalRoot->ObjectInformation.FileId.Volume)
3894 // Build the root volume entry
3897 ntStatus = AFSBuildRootVolume( AuthGroup,
3898 &pDirEnumEntry->FileId,
3901 if( !NT_SUCCESS( ntStatus))
3903 try_return( ntStatus);
3906 *ShareDirEntry = pVolumeCB->DirectoryCB;
3908 lCount = InterlockedIncrement( &pVolumeCB->DirectoryCB->OpenReferenceCount);
3910 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3911 AFS_TRACE_LEVEL_VERBOSE,
3912 "AFSCheckCellName Increment1 count on %wZ DE %p Ccb %p Cnt %d\n",
3913 &pVolumeCB->DirectoryCB->NameInformation.FileName,
3914 pVolumeCB->DirectoryCB,
3918 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
3923 lCount = InterlockedIncrement( &pDirHdr->ContentIndex);
3925 pDirNode = AFSInitDirEntry( &AFSGlobalRoot->ObjectInformation,
3931 if( pDirNode == NULL)
3934 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3938 // Init the short name if we have one
3941 if( pDirEnumEntry->ShortNameLength > 0)
3944 pDirNode->NameInformation.ShortNameLength = pDirEnumEntry->ShortNameLength;
3946 RtlCopyMemory( pDirNode->NameInformation.ShortName,
3947 pDirEnumEntry->ShortName,
3948 pDirNode->NameInformation.ShortNameLength);
3951 AFSAcquireExcl( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
3955 // Insert the node into the name tree
3958 ASSERT( ExIsResourceAcquiredExclusiveLite( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock));
3960 if( pDirHdr->CaseSensitiveTreeHead == NULL)
3963 pDirHdr->CaseSensitiveTreeHead = pDirNode;
3968 if( !NT_SUCCESS( AFSInsertCaseSensitiveDirEntry( pDirHdr->CaseSensitiveTreeHead,
3972 AFSDeleteDirEntry( &AFSGlobalRoot->ObjectInformation,
3975 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
3977 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3981 ClearFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
3983 if( pDirHdr->CaseInsensitiveTreeHead == NULL)
3986 pDirHdr->CaseInsensitiveTreeHead = pDirNode;
3988 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
3993 AFSInsertCaseInsensitiveDirEntry( pDirHdr->CaseInsensitiveTreeHead,
3997 if( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListHead == NULL)
4000 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListHead = pDirNode;
4005 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListTail->ListEntry.fLink = pDirNode;
4007 pDirNode->ListEntry.bLink = AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListTail;
4010 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListTail = pDirNode;
4012 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST);
4014 lCount = InterlockedIncrement( &AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeCount);
4016 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
4017 AFS_TRACE_LEVEL_VERBOSE,
4018 "AFSCheckCellName Adding entry %wZ Inc Count %d to parent FID %08lX-%08lX-%08lX-%08lX\n",
4019 &pDirNode->NameInformation.FileName,
4021 AFSGlobalRoot->ObjectInformation.FileId.Cell,
4022 AFSGlobalRoot->ObjectInformation.FileId.Volume,
4023 AFSGlobalRoot->ObjectInformation.FileId.Vnode,
4024 AFSGlobalRoot->ObjectInformation.FileId.Unique);
4026 lCount = InterlockedIncrement( &pDirNode->OpenReferenceCount);
4028 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
4029 AFS_TRACE_LEVEL_VERBOSE,
4030 "AFSCheckCellName Increment2 count on %wZ DE %p Ccb %p Cnt %d\n",
4031 &pDirNode->NameInformation.FileName,
4036 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
4039 // Pass back the dir node
4042 *ShareDirEntry = pDirNode;
4047 if( pDirEnumEntry != NULL)
4050 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_31_TAG);
4058 AFSBuildMountPointTarget( IN GUID *AuthGroup,
4059 IN AFSDirectoryCB *DirectoryCB,
4060 OUT AFSVolumeCB **TargetVolumeCB)
4063 NTSTATUS ntStatus = STATUS_SUCCESS;
4064 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
4065 AFSDirEnumEntry *pDirEntry = NULL;
4066 AFSDirectoryCB *pDirNode = NULL;
4067 UNICODE_STRING uniDirName, uniTargetName;
4068 ULONGLONG ullIndex = 0;
4069 AFSVolumeCB *pVolumeCB = NULL;
4070 AFSFileID stTargetFileID;
4072 BOOLEAN bReleaseVolumeLock = FALSE;
4078 // Loop on each entry, building the chain until we encounter the final target
4081 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4082 AFS_TRACE_LEVEL_VERBOSE_2,
4083 "AFSBuildMountPointTarget Building target directory for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4084 &DirectoryCB->NameInformation.FileName,
4085 DirectoryCB->ObjectInformation->FileId.Cell,
4086 DirectoryCB->ObjectInformation->FileId.Volume,
4087 DirectoryCB->ObjectInformation->FileId.Vnode,
4088 DirectoryCB->ObjectInformation->FileId.Unique);
4091 // Do we need to evaluate the node?
4094 //if( DirectoryCB->ObjectInformation->TargetFileId.Vnode == 0 &&
4095 // DirectoryCB->ObjectInformation->TargetFileId.Unique == 0)
4099 // Go evaluate the current target to get the target fid
4102 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4103 AFS_TRACE_LEVEL_VERBOSE_2,
4104 "AFSBuildMountPointTarget Evaluating target %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4105 &DirectoryCB->NameInformation.FileName,
4106 DirectoryCB->ObjectInformation->FileId.Cell,
4107 DirectoryCB->ObjectInformation->FileId.Volume,
4108 DirectoryCB->ObjectInformation->FileId.Vnode,
4109 DirectoryCB->ObjectInformation->FileId.Unique);
4111 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
4116 if( !NT_SUCCESS( ntStatus))
4119 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4120 AFS_TRACE_LEVEL_ERROR,
4121 "AFSBuildMountPointTarget Failed to evaluate target %wZ Status %08lX\n",
4122 &DirectoryCB->NameInformation.FileName,
4124 try_return( ntStatus);
4127 if( pDirEntry->TargetFileId.Vnode == 0 &&
4128 pDirEntry->TargetFileId.Unique == 0)
4131 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4132 AFS_TRACE_LEVEL_ERROR,
4133 "AFSBuildMountPointTarget Target %wZ FID %08lX-%08lX-%08lX-%08lX service returned zero FID\n",
4134 &DirectoryCB->NameInformation.FileName,
4135 DirectoryCB->ObjectInformation->FileId.Cell,
4136 DirectoryCB->ObjectInformation->FileId.Volume,
4137 DirectoryCB->ObjectInformation->FileId.Vnode,
4138 DirectoryCB->ObjectInformation->FileId.Unique);
4140 try_return( ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED);
4143 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
4146 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
4147 &DirectoryCB->Flags,
4148 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
4149 (USHORT)pDirEntry->TargetNameLength);
4151 if( !NT_SUCCESS( ntStatus))
4154 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
4156 try_return( ntStatus);
4159 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
4161 DirectoryCB->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
4164 stTargetFileID = DirectoryCB->ObjectInformation->TargetFileId;
4167 // Try to locate this FID. First the volume then the
4171 ullIndex = AFSCreateHighIndex( &stTargetFileID);
4173 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4174 AFS_TRACE_LEVEL_VERBOSE,
4175 "AFSBuildMountPointTarget Acquiring RDR VolumeTreeLock lock %08lX EXCL %08lX\n",
4176 &pDevExt->Specific.RDR.VolumeTreeLock,
4177 PsGetCurrentThread());
4179 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock,
4182 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4183 AFS_TRACE_LEVEL_VERBOSE_2,
4184 "AFSBuildMountPointTarget Locating volume for target %I64X\n",
4187 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
4189 (AFSBTreeEntry **)&pVolumeCB);
4192 // We can be processing a request for a target that is on a volume
4193 // we have never seen before.
4196 if( pVolumeCB == NULL)
4200 // Locking is held correctly in init routine
4203 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
4206 // Go init the root of the volume
4209 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4210 AFS_TRACE_LEVEL_VERBOSE_2,
4211 "AFSBuildMountPointTarget Initializing root for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4212 &DirectoryCB->NameInformation.FileName,
4213 DirectoryCB->ObjectInformation->FileId.Cell,
4214 DirectoryCB->ObjectInformation->FileId.Volume,
4215 DirectoryCB->ObjectInformation->FileId.Vnode,
4216 DirectoryCB->ObjectInformation->FileId.Unique);
4218 ntStatus = AFSInitVolume( AuthGroup,
4222 if( !NT_SUCCESS( ntStatus))
4225 try_return( ntStatus);
4229 // pVolumeCB->VolumeLock held exclusive and
4230 // pVolumeCB->VolumeReferenceCount has been incremented
4231 // pVolumeCB->RootFcb == NULL
4234 bReleaseVolumeLock = TRUE;
4240 // AFSInitVolume returns with a VolumeReferenceCount
4241 // obtain one to match
4244 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
4246 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
4247 AFS_TRACE_LEVEL_VERBOSE,
4248 "AFSBuildMountPointTarget Increment count on volume %08lX Cnt %d\n",
4252 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
4255 if( pVolumeCB->RootFcb == NULL)
4258 if ( bReleaseVolumeLock == FALSE)
4261 AFSAcquireExcl( pVolumeCB->VolumeLock,
4264 bReleaseVolumeLock = TRUE;
4268 // Initialize the root fcb for this volume
4271 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
4274 if( !NT_SUCCESS( ntStatus))
4277 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
4279 AFSReleaseResource( pVolumeCB->VolumeLock);
4281 try_return( ntStatus);
4285 // Drop the lock acquired above
4288 AFSReleaseResource( &pVolumeCB->RootFcb->NPFcb->Resource);
4291 if ( bReleaseVolumeLock == TRUE)
4294 AFSReleaseResource( pVolumeCB->VolumeLock);
4297 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4298 AFS_TRACE_LEVEL_VERBOSE_2,
4299 "AFSBuildMountPointTarget Evaluated target of %wZ FID %08lX-%08lX-%08lX-%08lX as root volume\n",
4300 &pVolumeCB->DirectoryCB->NameInformation.FileName,
4301 pVolumeCB->ObjectInformation.FileId.Cell,
4302 pVolumeCB->ObjectInformation.FileId.Volume,
4303 pVolumeCB->ObjectInformation.FileId.Vnode,
4304 pVolumeCB->ObjectInformation.FileId.Unique);
4306 *TargetVolumeCB = pVolumeCB;
4313 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
4321 AFSBuildRootVolume( IN GUID *AuthGroup,
4322 IN AFSFileID *FileId,
4323 OUT AFSVolumeCB **TargetVolumeCB)
4326 NTSTATUS ntStatus = STATUS_SUCCESS;
4327 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
4328 AFSDirectoryCB *pDirNode = NULL;
4329 UNICODE_STRING uniDirName, uniTargetName;
4330 ULONGLONG ullIndex = 0;
4331 AFSVolumeCB *pVolumeCB = NULL;
4333 BOOLEAN bReleaseVolumeLock = FALSE;
4338 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4339 AFS_TRACE_LEVEL_VERBOSE_2,
4340 "AFSBuildRootVolume Building target volume for FID %08lX-%08lX-%08lX-%08lX\n",
4346 ullIndex = AFSCreateHighIndex( FileId);
4348 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4349 AFS_TRACE_LEVEL_VERBOSE,
4350 "AFSBuildRootVolume Acquiring RDR VolumeTreeLock lock %08lX EXCL %08lX\n",
4351 &pDevExt->Specific.RDR.VolumeTreeLock,
4352 PsGetCurrentThread());
4354 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock,
4357 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4358 AFS_TRACE_LEVEL_VERBOSE_2,
4359 "AFSBuildRootVolume Locating volume for target %I64X\n",
4362 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
4364 (AFSBTreeEntry **)&pVolumeCB);
4367 // We can be processing a request for a target that is on a volume
4368 // we have never seen before.
4371 if( pVolumeCB == NULL)
4375 // Locking is held correctly in init routine
4378 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
4381 // Go init the root of the volume
4384 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4385 AFS_TRACE_LEVEL_VERBOSE_2,
4386 "AFSBuildRootVolume Initializing root for FID %08lX-%08lX-%08lX-%08lX\n",
4392 ntStatus = AFSInitVolume( AuthGroup,
4396 if( !NT_SUCCESS( ntStatus))
4399 try_return( ntStatus);
4403 // pVolumeCB->VolumeLock is held exclusive
4404 // pVolumeCB->VolumeReferenceCount has been incremented
4405 // pVolumeCB->RootFcb == NULL
4408 bReleaseVolumeLock = TRUE;
4414 // AFSInitVolume returns with a VolumeReferenceCount
4415 // obtain one to match
4418 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
4420 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
4421 AFS_TRACE_LEVEL_VERBOSE,
4422 "AFSBuildRootVolume Increment count on volume %08lX Cnt %d\n",
4426 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
4430 if( pVolumeCB->RootFcb == NULL)
4433 if ( bReleaseVolumeLock == FALSE)
4436 AFSAcquireExcl( pVolumeCB->VolumeLock,
4439 bReleaseVolumeLock = TRUE;
4443 // Initialize the root fcb for this volume
4446 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
4449 if( !NT_SUCCESS( ntStatus))
4452 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
4454 AFSReleaseResource( pVolumeCB->VolumeLock);
4456 try_return( ntStatus);
4460 // Drop the lock acquired above
4463 AFSReleaseResource( &pVolumeCB->RootFcb->NPFcb->Resource);
4466 if ( bReleaseVolumeLock == TRUE)
4469 AFSReleaseResource( pVolumeCB->VolumeLock);
4472 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4473 AFS_TRACE_LEVEL_VERBOSE_2,
4474 "AFSBuildRootVolume Evaluated target of %wZ FID %08lX-%08lX-%08lX-%08lX as root volume\n",
4475 &pVolumeCB->DirectoryCB->NameInformation.FileName,
4476 pVolumeCB->ObjectInformation.FileId.Cell,
4477 pVolumeCB->ObjectInformation.FileId.Volume,
4478 pVolumeCB->ObjectInformation.FileId.Vnode,
4479 pVolumeCB->ObjectInformation.FileId.Unique);
4481 *TargetVolumeCB = pVolumeCB;
4492 AFSProcessDFSLink( IN AFSDirectoryCB *DirEntry,
4493 IN PFILE_OBJECT FileObject,
4494 IN UNICODE_STRING *RemainingPath,
4498 NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
4499 UNICODE_STRING uniReparseName;
4500 UNICODE_STRING uniMUPDeviceName;
4501 AFSDirEnumEntry *pDirEntry = NULL;
4507 // Build up the name to reparse
4510 RtlInitUnicodeString( &uniMUPDeviceName,
4513 uniReparseName.Length = 0;
4514 uniReparseName.Buffer = NULL;
4517 // Be sure we have a target name
4520 if( DirEntry->NameInformation.TargetName.Length == 0)
4523 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
4528 if( !NT_SUCCESS( ntStatus) ||
4529 pDirEntry->TargetNameLength == 0)
4532 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4533 AFS_TRACE_LEVEL_ERROR,
4534 "AFSProcessDFSLink EvaluateTargetByID failed for Fcb %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4535 &DirEntry->NameInformation.FileName,
4536 DirEntry->ObjectInformation->FileId.Cell,
4537 DirEntry->ObjectInformation->FileId.Volume,
4538 DirEntry->ObjectInformation->FileId.Vnode,
4539 DirEntry->ObjectInformation->FileId.Unique,
4542 if( NT_SUCCESS( ntStatus))
4545 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
4548 try_return( ntStatus);
4552 // Update the target name
4555 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
4558 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
4560 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
4561 (USHORT)pDirEntry->TargetNameLength);
4563 if( !NT_SUCCESS( ntStatus))
4566 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4567 AFS_TRACE_LEVEL_ERROR,
4568 "AFSProcessDFSLink UpdateTargetName failed for Fcb %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4569 &DirEntry->NameInformation.FileName,
4570 DirEntry->ObjectInformation->FileId.Cell,
4571 DirEntry->ObjectInformation->FileId.Volume,
4572 DirEntry->ObjectInformation->FileId.Vnode,
4573 DirEntry->ObjectInformation->FileId.Unique,
4576 AFSReleaseResource( &DirEntry->NonPaged->Lock);
4578 try_return( ntStatus);
4581 AFSConvertToShared( &DirEntry->NonPaged->Lock);
4585 AFSAcquireShared( &DirEntry->NonPaged->Lock,
4589 uniReparseName.MaximumLength = uniMUPDeviceName.Length +
4591 DirEntry->NameInformation.TargetName.Length +
4594 if( RemainingPath != NULL &&
4595 RemainingPath->Length > 0)
4598 uniReparseName.MaximumLength += RemainingPath->Length;
4602 // Allocate the reparse buffer
4605 uniReparseName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
4606 uniReparseName.MaximumLength,
4607 AFS_REPARSE_NAME_TAG);
4609 if( uniReparseName.Buffer == NULL)
4612 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4613 AFS_TRACE_LEVEL_ERROR,
4614 "AFSProcessDFSLink uniReparseName.Buffer == NULL Fcb %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4615 &DirEntry->NameInformation.FileName,
4616 DirEntry->ObjectInformation->FileId.Cell,
4617 DirEntry->ObjectInformation->FileId.Volume,
4618 DirEntry->ObjectInformation->FileId.Vnode,
4619 DirEntry->ObjectInformation->FileId.Unique,
4620 STATUS_INSUFFICIENT_RESOURCES);
4622 AFSReleaseResource( &DirEntry->NonPaged->Lock);
4624 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4628 // Start building the name
4631 RtlCopyMemory( uniReparseName.Buffer,
4632 uniMUPDeviceName.Buffer,
4633 uniMUPDeviceName.Length);
4635 uniReparseName.Length = uniMUPDeviceName.Length;
4637 if( DirEntry->NameInformation.TargetName.Buffer[ 0] != L'\\')
4640 uniReparseName.Buffer[ uniReparseName.Length/sizeof( WCHAR)] = L'\\';
4642 uniReparseName.Length += sizeof( WCHAR);
4645 RtlCopyMemory( &uniReparseName.Buffer[ uniReparseName.Length/sizeof( WCHAR)],
4646 DirEntry->NameInformation.TargetName.Buffer,
4647 DirEntry->NameInformation.TargetName.Length);
4649 uniReparseName.Length += DirEntry->NameInformation.TargetName.Length;
4651 AFSReleaseResource( &DirEntry->NonPaged->Lock);
4653 if( RemainingPath != NULL &&
4654 RemainingPath->Length > 0)
4657 if( uniReparseName.Buffer[ (uniReparseName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
4658 RemainingPath->Buffer[ 0] != L'\\')
4661 uniReparseName.Buffer[ uniReparseName.Length/sizeof( WCHAR)] = L'\\';
4663 uniReparseName.Length += sizeof( WCHAR);
4666 RtlCopyMemory( &uniReparseName.Buffer[ uniReparseName.Length/sizeof( WCHAR)],
4667 RemainingPath->Buffer,
4668 RemainingPath->Length);
4670 uniReparseName.Length += RemainingPath->Length;
4674 // Update the name in the file object
4677 if( FileObject->FileName.Buffer != NULL)
4680 AFSExFreePoolWithTag( FileObject->FileName.Buffer, 0);
4683 FileObject->FileName = uniReparseName;
4685 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4686 AFS_TRACE_LEVEL_VERBOSE,
4687 "AFSProcessDFSLink Reparsing access to Fcb %wZ FID %08lX-%08lX-%08lX-%08lX to %wZ\n",
4688 &DirEntry->NameInformation.FileName,
4689 DirEntry->ObjectInformation->FileId.Cell,
4690 DirEntry->ObjectInformation->FileId.Volume,
4691 DirEntry->ObjectInformation->FileId.Vnode,
4692 DirEntry->ObjectInformation->FileId.Unique,
4696 // Return status reparse ...
4699 ntStatus = STATUS_REPARSE;
4706 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);