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)
1522 // Increment our dir entry ref count since we will decrement it on exit
1525 lCount = InterlockedIncrement( &pDirEntry->OpenReferenceCount);
1527 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1528 AFS_TRACE_LEVEL_VERBOSE,
1529 "AFSLocateNameEntry Increment5 count on %wZ DE %p Ccb %p Cnt %d\n",
1530 &pDirEntry->NameInformation.FileName,
1535 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1537 try_return(ntStatus = STATUS_OBJECT_NAME_COLLISION);
1542 if( pDirEntry != NULL)
1546 // If the verify flag is set on the parent and the current entry is deleted
1547 // revalidate the parent and search again.
1550 if( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED) &&
1551 BooleanFlagOn( pParentDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY))
1554 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1556 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1557 AFS_TRACE_LEVEL_VERBOSE,
1558 "AFSLocateNameEntry (FO: %08lX) Verifying(2) parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1560 &pParentDirEntry->NameInformation.FileName,
1561 pParentDirEntry->ObjectInformation->FileId.Cell,
1562 pParentDirEntry->ObjectInformation->FileId.Volume,
1563 pParentDirEntry->ObjectInformation->FileId.Vnode,
1564 pParentDirEntry->ObjectInformation->FileId.Unique);
1567 // Directory TreeLock should be exclusively held
1570 AFSAcquireExcl( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
1573 ntStatus = AFSVerifyEntry( AuthGroup,
1576 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1578 if( !NT_SUCCESS( ntStatus))
1581 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1582 AFS_TRACE_LEVEL_ERROR,
1583 "AFSLocateNameEntry (FO: %08lX) Failed to verify(2) parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1585 &pParentDirEntry->NameInformation.FileName,
1586 pParentDirEntry->ObjectInformation->FileId.Cell,
1587 pParentDirEntry->ObjectInformation->FileId.Volume,
1588 pParentDirEntry->ObjectInformation->FileId.Vnode,
1589 pParentDirEntry->ObjectInformation->FileId.Unique,
1592 try_return( ntStatus);
1595 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1596 AFS_TRACE_LEVEL_VERBOSE,
1597 "AFSLocateNameEntry (FO: %08lX) Reprocessing component %wZ in parent %wZ\n",
1600 &pParentDirEntry->NameInformation.FileName);
1609 // Increment our dir entry ref count
1612 lCount = InterlockedIncrement( &pDirEntry->OpenReferenceCount);
1614 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1615 AFS_TRACE_LEVEL_VERBOSE,
1616 "AFSLocateNameEntry Increment5 count on %wZ DE %p Ccb %p Cnt %d\n",
1617 &pDirEntry->NameInformation.FileName,
1623 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1625 } // End while( pDirEntry == NULL)
1628 // If we have a dirEntry for this component, perform some basic validation on it
1631 if( pDirEntry != NULL &&
1632 BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
1635 pCurrentObject = pDirEntry->ObjectInformation;
1637 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1638 AFS_TRACE_LEVEL_ERROR,
1639 "AFSLocateNameEntry (FO: %08lX) Deleted entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1641 &pDirEntry->NameInformation.FileName,
1642 pCurrentObject->FileId.Cell,
1643 pCurrentObject->FileId.Volume,
1644 pCurrentObject->FileId.Vnode,
1645 pCurrentObject->FileId.Unique);
1648 // This entry was deleted through the invalidation call back so perform cleanup
1652 pParentObjectInfo = pCurrentObject->ParentObjectInformation;
1654 ASSERT( pParentObjectInfo != NULL);
1656 AFSAcquireExcl( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
1659 AFSAcquireExcl( pCurrentObject->VolumeCB->ObjectInfoTree.TreeLock,
1662 lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
1667 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING|AFS_SUBSYSTEM_CLEANUP_PROCESSING,
1668 AFS_TRACE_LEVEL_VERBOSE,
1669 "AFSLocateNameEntry Deleting dir entry %08lX (%08lX) for %wZ\n",
1672 &pDirEntry->NameInformation.FileName);
1675 // Remove and delete the directory entry from the parent list
1678 AFSDeleteDirEntry( pParentObjectInfo,
1681 AFSAcquireShared( &pCurrentObject->NonPagedInfo->ObjectInfoLock,
1684 if( pCurrentObject->ObjectReferenceCount <= 0)
1687 if( BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_INSERTED_HASH_TREE))
1690 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
1691 AFS_TRACE_LEVEL_VERBOSE,
1692 "AFSLocateNameEntry Removing object %08lX from volume tree\n",
1695 AFSRemoveHashEntry( &pCurrentObject->VolumeCB->ObjectInfoTree.TreeHead,
1696 &pCurrentObject->TreeEntry);
1698 ClearFlag( pCurrentObject->Flags, AFS_OBJECT_INSERTED_HASH_TREE);
1702 AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock);
1707 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1708 AFS_TRACE_LEVEL_VERBOSE,
1709 "AFSLocateNameEntry Setting DELETE flag in dir entry %p for %wZ\n",
1711 &pDirEntry->NameInformation.FileName);
1713 SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
1715 AFSRemoveNameEntry( pParentObjectInfo,
1719 AFSReleaseResource( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
1721 AFSReleaseResource( pCurrentObject->VolumeCB->ObjectInfoTree.TreeLock);
1724 // We deleted the dir entry so check if there is any remaining portion
1725 // of the name to process.
1728 if( uniRemainingPath.Length > 0)
1730 ntStatus = STATUS_OBJECT_PATH_NOT_FOUND;
1735 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
1737 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1738 AFS_TRACE_LEVEL_VERBOSE,
1739 "AFSLocateNameEntry (FO: %08lX) Returning name not found(2) for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1742 pCurrentObject->FileId.Cell,
1743 pCurrentObject->FileId.Volume,
1744 pCurrentObject->FileId.Vnode,
1745 pCurrentObject->FileId.Unique);
1748 // Pass back the directory entries
1751 *ParentDirectoryCB = pParentDirEntry;
1753 *DirectoryCB = NULL;
1755 *VolumeCB = pCurrentVolume;
1757 if( ComponentName != NULL)
1760 *ComponentName = uniComponentName;
1763 *RootPathName = uniFullPathName;
1767 if( ntStatus != STATUS_SUCCESS)
1770 try_return( ntStatus);
1774 // Decrement the previous parent
1777 lCount = InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
1779 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1780 AFS_TRACE_LEVEL_VERBOSE,
1781 "AFSLocateNameEntry Decrement5 count on Parent %wZ DE %p Ccb %p Cnt %d\n",
1782 &pParentDirEntry->NameInformation.FileName,
1788 // If we ended up substituting a name in the component then update
1789 // the full path and update the pointers
1792 if( bSubstituteName)
1795 BOOLEAN bRelativeOpen = FALSE;
1797 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1798 AFS_TRACE_LEVEL_VERBOSE_2,
1799 "AFSLocateNameEntry (FO: %08lX) Substituting %wZ into %wZ Index %08lX\n",
1805 if( FileObject != NULL &&
1806 FileObject->RelatedFileObject != NULL)
1809 bRelativeOpen = TRUE;
1813 // AFSSubstituteNameInPath will replace the uniFullPathName.Buffer
1814 // and free the prior Buffer contents but only if the fourth
1815 // parameter is TRUE.
1818 ntStatus = AFSSubstituteNameInPath( &uniFullPathName,
1823 bAllocatedSymLinkBuffer ||
1826 if( !NT_SUCCESS( ntStatus))
1829 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1830 AFS_TRACE_LEVEL_ERROR,
1831 "AFSLocateNameEntry (FO: %08lX) Failure to substitute %wZ into %wZ Index %08lX Status %08lX\n",
1838 try_return( ntStatus);
1842 // We have substituted a name into the buffer so if we do this again for this
1843 // path, we need to free up the buffer we allocated.
1846 bSubstitutedName = TRUE;
1850 // Update the search parameters
1853 uniPathName = uniRemainingPath;
1856 // Check if the is a SymLink entry but has no Target FileID or Name. In this
1857 // case it might be a DFS Link so let's go and evaluate it to be sure
1860 if( pCurrentObject->FileType == AFS_FILE_TYPE_SYMLINK &&
1861 pCurrentObject->TargetFileId.Vnode == 0 &&
1862 pCurrentObject->TargetFileId.Unique == 0 &&
1863 pDirEntry->NameInformation.TargetName.Length == 0)
1866 ntStatus = AFSValidateSymLink( AuthGroup,
1869 if( !NT_SUCCESS( ntStatus))
1872 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1873 AFS_TRACE_LEVEL_ERROR,
1874 "AFSLocateNameEntry (FO: %08lX) Failed to evaluate possible DFS Link %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1876 &pDirEntry->NameInformation.FileName,
1877 pCurrentObject->FileId.Cell,
1878 pCurrentObject->FileId.Volume,
1879 pCurrentObject->FileId.Vnode,
1880 pCurrentObject->FileId.Unique,
1883 try_return( ntStatus);
1888 // Update the name array
1891 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1892 AFS_TRACE_LEVEL_VERBOSE,
1893 "AFSLocateNameEntry (FO: %08lX) Inserting name array entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1895 &pDirEntry->NameInformation.FileName,
1896 pCurrentObject->FileId.Cell,
1897 pCurrentObject->FileId.Volume,
1898 pCurrentObject->FileId.Vnode,
1899 pCurrentObject->FileId.Unique);
1901 ntStatus = AFSInsertNextElement( pNameArray,
1904 if( !NT_SUCCESS( ntStatus))
1907 try_return( ntStatus);
1913 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1914 AFS_TRACE_LEVEL_VERBOSE,
1915 "AFSLocateNameEntry (FO: %08lX) Completed processing %wZ Status %08lX\n",
1920 if( ( !NT_SUCCESS( ntStatus) &&
1921 ntStatus != STATUS_OBJECT_NAME_NOT_FOUND) ||
1922 ntStatus == STATUS_REPARSE)
1925 if( pDirEntry != NULL)
1928 lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
1930 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1931 AFS_TRACE_LEVEL_VERBOSE,
1932 "AFSLocateNameEntry Decrement6 count on %wZ DE %p Ccb %p Cnt %d\n",
1933 &pDirEntry->NameInformation.FileName,
1938 else if( pParentDirEntry != NULL)
1941 lCount = InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
1943 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1944 AFS_TRACE_LEVEL_VERBOSE,
1945 "AFSLocateNameEntry Decrement7 count on %wZ DE %p Ccb %p Cnt %d\n",
1946 &pParentDirEntry->NameInformation.FileName,
1952 if( bReleaseCurrentVolume)
1955 ASSERT( pCurrentVolume->VolumeReferenceCount > 1);
1957 lCount = InterlockedDecrement( &pCurrentVolume->VolumeReferenceCount);
1959 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
1960 AFS_TRACE_LEVEL_VERBOSE,
1961 "AFSLocateNameEntry Decrement3 count on volume %08lX Cnt %d\n",
1966 if( RootPathName->Buffer != uniFullPathName.Buffer)
1969 AFSExFreePoolWithTag( uniFullPathName.Buffer, 0);
1975 if( *ParentDirectoryCB != NULL)
1978 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1979 AFS_TRACE_LEVEL_VERBOSE,
1980 "AFSLocateNameEntry Count on Parent %wZ DE %p Ccb %p Cnt %d\n",
1981 &(*ParentDirectoryCB)->NameInformation.FileName,
1984 (*ParentDirectoryCB)->OpenReferenceCount);
1987 if( *DirectoryCB != NULL)
1990 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1991 AFS_TRACE_LEVEL_VERBOSE,
1992 "AFSLocateNameEntry Count on %wZ DE %p Ccb %p Cnt %d\n",
1993 &(*DirectoryCB)->NameInformation.FileName,
1996 (*DirectoryCB)->OpenReferenceCount);
2000 if( bSubstituteName &&
2001 uniSearchName.Buffer != NULL)
2004 AFSExFreePoolWithTag( uniSearchName.Buffer, 0);
2012 AFSCreateDirEntry( IN GUID *AuthGroup,
2013 IN AFSObjectInfoCB *ParentObjectInfo,
2014 IN AFSDirectoryCB *ParentDirCB,
2015 IN PUNICODE_STRING FileName,
2016 IN PUNICODE_STRING ComponentName,
2017 IN ULONG Attributes,
2018 IN OUT AFSDirectoryCB **DirEntry)
2021 NTSTATUS ntStatus = STATUS_SUCCESS;
2022 AFSDirectoryCB *pDirNode = NULL, *pExistingDirNode = NULL;
2023 UNICODE_STRING uniShortName;
2024 LARGE_INTEGER liFileSize = {0,0};
2030 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2031 AFS_TRACE_LEVEL_VERBOSE_2,
2032 "AFSCreateDirEntry Creating dir entry in parent %wZ FID %08lX-%08lX-%08lX-%08lX Component %wZ Attribs %08lX\n",
2033 &ParentDirCB->NameInformation.FileName,
2034 ParentObjectInfo->FileId.Cell,
2035 ParentObjectInfo->FileId.Volume,
2036 ParentObjectInfo->FileId.Vnode,
2037 ParentObjectInfo->FileId.Unique,
2042 // OK, before inserting the node into the parent tree, issue
2043 // the request to the service for node creation
2044 // We will need to drop the lock on the parent node since the create
2045 // could cause a callback into the file system to invalidate it's cache
2048 ntStatus = AFSNotifyFileCreate( AuthGroup,
2056 // If the returned status is STATUS_REPARSE then the entry exists
2057 // and we raced, get out.
2059 if( ntStatus == STATUS_REPARSE)
2062 *DirEntry = pDirNode;
2064 try_return( ntStatus = STATUS_SUCCESS);
2067 if( !NT_SUCCESS( ntStatus))
2070 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2071 AFS_TRACE_LEVEL_ERROR,
2072 "AFSCreateDirEntry Failed to create dir entry in parent %wZ FID %08lX-%08lX-%08lX-%08lX Component %wZ Attribs %08lX Status %08lX\n",
2073 &ParentDirCB->NameInformation.FileName,
2074 ParentObjectInfo->FileId.Cell,
2075 ParentObjectInfo->FileId.Volume,
2076 ParentObjectInfo->FileId.Vnode,
2077 ParentObjectInfo->FileId.Unique,
2082 try_return( ntStatus);
2085 AFSAcquireExcl( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2089 // Before attempting to insert the new entry, check if we need to validate the parent
2092 if( BooleanFlagOn( ParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY))
2095 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2096 AFS_TRACE_LEVEL_VERBOSE,
2097 "AFSCreateDirEntry Verifying parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2098 &ParentDirCB->NameInformation.FileName,
2099 ParentObjectInfo->FileId.Cell,
2100 ParentObjectInfo->FileId.Volume,
2101 ParentObjectInfo->FileId.Vnode,
2102 ParentObjectInfo->FileId.Unique);
2104 ntStatus = AFSVerifyEntry( AuthGroup,
2107 if( !NT_SUCCESS( ntStatus))
2110 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2111 AFS_TRACE_LEVEL_ERROR,
2112 "AFSCreateDirEntry Failed to verify parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2113 &ParentDirCB->NameInformation.FileName,
2114 ParentObjectInfo->FileId.Cell,
2115 ParentObjectInfo->FileId.Volume,
2116 ParentObjectInfo->FileId.Vnode,
2117 ParentObjectInfo->FileId.Unique,
2120 AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2122 try_return( ntStatus);
2127 // Check for the entry in the event we raced with some other thread
2130 AFSLocateCaseSensitiveDirEntry( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
2131 (ULONG)pDirNode->CaseSensitiveTreeEntry.HashIndex,
2134 if( pExistingDirNode != NULL)
2136 if (AFSIsEqualFID( &pDirNode->ObjectInformation->FileId,
2137 &pExistingDirNode->ObjectInformation->FileId))
2140 AFSDeleteDirEntry( ParentObjectInfo,
2143 lCount = InterlockedIncrement( &pExistingDirNode->OpenReferenceCount);
2145 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2146 AFS_TRACE_LEVEL_VERBOSE,
2147 "AFSCreateDirEntry Increment count on %wZ DE %p Cnt %d\n",
2148 &pExistingDirNode->NameInformation.FileName,
2152 *DirEntry = pExistingDirNode;
2154 AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2156 try_return( ntStatus = STATUS_SUCCESS);
2162 // Need to tear down this entry and rebuild it below
2165 if( pExistingDirNode->OpenReferenceCount == 0)
2168 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2169 AFS_TRACE_LEVEL_VERBOSE,
2170 "AFSCreateDirEntry Different FIDs - Deleting DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
2172 &pExistingDirNode->NameInformation.FileName,
2173 pExistingDirNode->ObjectInformation->FileId.Cell,
2174 pExistingDirNode->ObjectInformation->FileId.Volume,
2175 pExistingDirNode->ObjectInformation->FileId.Vnode,
2176 pExistingDirNode->ObjectInformation->FileId.Unique,
2177 pDirNode->ObjectInformation->FileId.Cell,
2178 pDirNode->ObjectInformation->FileId.Volume,
2179 pDirNode->ObjectInformation->FileId.Vnode,
2180 pDirNode->ObjectInformation->FileId.Unique);
2182 AFSDeleteDirEntry( ParentObjectInfo,
2188 SetFlag( pExistingDirNode->Flags, AFS_DIR_ENTRY_DELETED);
2190 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2191 AFS_TRACE_LEVEL_VERBOSE,
2192 "AFSCreateDirEntry Different FIDs - Removing DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
2194 &pExistingDirNode->NameInformation.FileName,
2195 pExistingDirNode->ObjectInformation->FileId.Cell,
2196 pExistingDirNode->ObjectInformation->FileId.Volume,
2197 pExistingDirNode->ObjectInformation->FileId.Vnode,
2198 pExistingDirNode->ObjectInformation->FileId.Unique,
2199 pDirNode->ObjectInformation->FileId.Cell,
2200 pDirNode->ObjectInformation->FileId.Volume,
2201 pDirNode->ObjectInformation->FileId.Vnode,
2202 pDirNode->ObjectInformation->FileId.Unique);
2204 AFSRemoveNameEntry( ParentObjectInfo,
2211 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2212 AFS_TRACE_LEVEL_VERBOSE_2,
2213 "AFSCreateDirEntry Inserting dir entry in parent %wZ FID %08lX-%08lX-%08lX-%08lX Component %wZ\n",
2214 &ParentDirCB->NameInformation.FileName,
2215 ParentObjectInfo->FileId.Cell,
2216 ParentObjectInfo->FileId.Volume,
2217 ParentObjectInfo->FileId.Vnode,
2218 ParentObjectInfo->FileId.Unique,
2222 // Insert the directory node
2225 AFSInsertDirectoryNode( ParentObjectInfo,
2229 lCount = InterlockedIncrement( &pDirNode->OpenReferenceCount);
2231 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2232 AFS_TRACE_LEVEL_VERBOSE,
2233 "AFSCreateDirEntry Increment2 count on %wZ DE %p Cnt %d\n",
2234 &pDirNode->NameInformation.FileName,
2239 // Pass back the dir entry
2242 *DirEntry = pDirNode;
2244 AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2255 AFSInsertDirectoryNode( IN AFSObjectInfoCB *ParentObjectInfo,
2256 IN AFSDirectoryCB *DirEntry,
2257 IN BOOLEAN InsertInEnumList)
2265 ASSERT( ExIsResourceAcquiredExclusiveLite( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock));
2268 // Insert the node into the directory node tree
2271 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2272 AFS_TRACE_LEVEL_VERBOSE,
2273 "AFSInsertDirectoryNode Insert DE %p for %wZ Clearing NOT_IN flag\n",
2275 &DirEntry->NameInformation.FileName);
2277 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
2279 if( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead == NULL)
2282 ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = DirEntry;
2284 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2285 AFS_TRACE_LEVEL_VERBOSE,
2286 "AFSInsertDirectoryNode Insert DE %p to head of case sensitive tree for %wZ\n",
2288 &DirEntry->NameInformation.FileName);
2293 AFSInsertCaseSensitiveDirEntry( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
2296 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2297 AFS_TRACE_LEVEL_VERBOSE,
2298 "AFSInsertDirectoryNode Insert DE %p to case sensitive tree for %wZ\n",
2300 &DirEntry->NameInformation.FileName);
2303 if( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead == NULL)
2306 ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = DirEntry;
2308 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
2310 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2311 AFS_TRACE_LEVEL_VERBOSE,
2312 "AFSInsertDirectoryNode Insert DE %p to head of case insensitive tree for %wZ\n",
2314 &DirEntry->NameInformation.FileName);
2319 AFSInsertCaseInsensitiveDirEntry( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
2322 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2323 AFS_TRACE_LEVEL_VERBOSE,
2324 "AFSInsertDirectoryNode Insert DE %p to case insensitive tree for %wZ\n",
2326 &DirEntry->NameInformation.FileName);
2330 // Into the shortname tree
2333 if( DirEntry->Type.Data.ShortNameTreeEntry.HashIndex != 0)
2336 if( ParentObjectInfo->Specific.Directory.ShortNameTree == NULL)
2339 ParentObjectInfo->Specific.Directory.ShortNameTree = DirEntry;
2341 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2342 AFS_TRACE_LEVEL_VERBOSE,
2343 "AFSInsertDirectoryNode Insert DE %p to head of shortname tree for %wZ\n",
2345 &DirEntry->NameInformation.FileName);
2347 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
2352 if( !NT_SUCCESS( AFSInsertShortNameDirEntry( ParentObjectInfo->Specific.Directory.ShortNameTree,
2355 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2356 AFS_TRACE_LEVEL_VERBOSE,
2357 "AFSInsertDirectoryNode Failed to insert DE %p to shortname tree for %wZ\n",
2359 &DirEntry->NameInformation.FileName);
2363 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
2365 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2366 AFS_TRACE_LEVEL_VERBOSE,
2367 "AFSInsertDirectoryNode Insert DE %p to shortname tree for %wZ\n",
2369 &DirEntry->NameInformation.FileName);
2374 if( InsertInEnumList)
2378 // And insert the node into the directory list
2381 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2382 AFS_TRACE_LEVEL_VERBOSE,
2383 "AFSInsertDirectoryNode Inserting entry %08lX %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2385 &DirEntry->NameInformation.FileName,
2386 DirEntry->ObjectInformation->FileId.Cell,
2387 DirEntry->ObjectInformation->FileId.Volume,
2388 DirEntry->ObjectInformation->FileId.Vnode,
2389 DirEntry->ObjectInformation->FileId.Unique);
2391 if( ParentObjectInfo->Specific.Directory.DirectoryNodeListHead == NULL)
2394 ParentObjectInfo->Specific.Directory.DirectoryNodeListHead = DirEntry;
2399 ParentObjectInfo->Specific.Directory.DirectoryNodeListTail->ListEntry.fLink = (void *)DirEntry;
2401 DirEntry->ListEntry.bLink = (void *)ParentObjectInfo->Specific.Directory.DirectoryNodeListTail;
2404 ParentObjectInfo->Specific.Directory.DirectoryNodeListTail = DirEntry;
2406 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST);
2408 lCount = InterlockedIncrement( &ParentObjectInfo->Specific.Directory.DirectoryNodeCount);
2410 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
2411 AFS_TRACE_LEVEL_VERBOSE,
2412 "AFSInsertDirectoryNode Adding entry %wZ Inc Count %d to parent FID %08lX-%08lX-%08lX-%08lX\n",
2413 &DirEntry->NameInformation.FileName,
2415 ParentObjectInfo->FileId.Cell,
2416 ParentObjectInfo->FileId.Volume,
2417 ParentObjectInfo->FileId.Vnode,
2418 ParentObjectInfo->FileId.Unique);
2426 AFSDeleteDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
2427 IN AFSDirectoryCB *DirEntry)
2430 NTSTATUS ntStatus = STATUS_SUCCESS;
2436 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2437 AFS_TRACE_LEVEL_VERBOSE,
2438 "AFSDeleteDirEntry Deleting dir entry in parent %08lX Entry %08lX %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2441 &DirEntry->NameInformation.FileName,
2442 DirEntry->ObjectInformation->FileId.Cell,
2443 DirEntry->ObjectInformation->FileId.Volume,
2444 DirEntry->ObjectInformation->FileId.Vnode,
2445 DirEntry->ObjectInformation->FileId.Unique);
2447 AFSRemoveDirNodeFromParent( ParentObjectInfo,
2452 // Free up the name buffer if it was reallocated
2455 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_RELEASE_NAME_BUFFER))
2458 AFSExFreePoolWithTag( DirEntry->NameInformation.FileName.Buffer, 0);
2461 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER))
2464 AFSExFreePoolWithTag( DirEntry->NameInformation.TargetName.Buffer, 0);
2468 // Dereference the object for this dir entry
2471 ASSERT( DirEntry->ObjectInformation->ObjectReferenceCount > 0);
2473 lCount = AFSObjectInfoDecrement( DirEntry->ObjectInformation);
2475 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2476 AFS_TRACE_LEVEL_VERBOSE,
2477 "AFSDeleteDirEntry Decrement count on object %08lX Cnt %d\n",
2478 DirEntry->ObjectInformation,
2481 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_DELETED) &&
2482 DirEntry->ObjectInformation->Links == 0)
2485 SetFlag( DirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED);
2488 ExDeleteResourceLite( &DirEntry->NonPaged->Lock);
2490 AFSExFreePoolWithTag( DirEntry->NonPaged, AFS_DIR_ENTRY_NP_TAG);
2493 // Free up the dir entry
2496 AFSExFreePoolWithTag( DirEntry, AFS_DIR_ENTRY_TAG);
2503 AFSRemoveDirNodeFromParent( IN AFSObjectInfoCB *ParentObjectInfo,
2504 IN AFSDirectoryCB *DirEntry,
2505 IN BOOLEAN RemoveFromEnumList)
2508 NTSTATUS ntStatus = STATUS_SUCCESS;
2515 ASSERT( ExIsResourceAcquiredExclusiveLite( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock));
2517 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2518 AFS_TRACE_LEVEL_VERBOSE,
2519 "AFSRemoveDirNodeFromParent Removing DirEntry %08lX %wZ FID %08lX-%08lX-%08lX-%08lX from Parent %08lX\n",
2521 &DirEntry->NameInformation.FileName,
2522 DirEntry->ObjectInformation->FileId.Cell,
2523 DirEntry->ObjectInformation->FileId.Volume,
2524 DirEntry->ObjectInformation->FileId.Vnode,
2525 DirEntry->ObjectInformation->FileId.Unique,
2528 if( !BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
2531 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2532 AFS_TRACE_LEVEL_VERBOSE,
2533 "AFSRemoveDirNodeFromParent Removing DirEntry %08lX name %wZ\n",
2535 &DirEntry->NameInformation.FileName);
2537 AFSRemoveNameEntry( ParentObjectInfo,
2543 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2544 AFS_TRACE_LEVEL_VERBOSE,
2545 "AFSRemoveDirNodeFromParent DE %p for %wZ NOT removing entry due to flag set\n",
2547 &DirEntry->NameInformation.FileName);
2551 if( RemoveFromEnumList &&
2552 BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST))
2556 // And remove the entry from the enumeration list
2559 if( DirEntry->ListEntry.fLink == NULL)
2562 ParentObjectInfo->Specific.Directory.DirectoryNodeListTail = (AFSDirectoryCB *)DirEntry->ListEntry.bLink;
2567 ((AFSDirectoryCB *)DirEntry->ListEntry.fLink)->ListEntry.bLink = DirEntry->ListEntry.bLink;
2570 if( DirEntry->ListEntry.bLink == NULL)
2573 ParentObjectInfo->Specific.Directory.DirectoryNodeListHead = (AFSDirectoryCB *)DirEntry->ListEntry.fLink;
2578 ((AFSDirectoryCB *)DirEntry->ListEntry.bLink)->ListEntry.fLink = DirEntry->ListEntry.fLink;
2581 ASSERT( ParentObjectInfo->Specific.Directory.DirectoryNodeCount > 0);
2583 lCount = InterlockedDecrement( &ParentObjectInfo->Specific.Directory.DirectoryNodeCount);
2585 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST);
2587 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
2588 AFS_TRACE_LEVEL_VERBOSE,
2589 "AFSRemoveDirNodeFromParent Removing entry %wZ Dec Count %d to parent FID %08lX-%08lX-%08lX-%08lX\n",
2590 &DirEntry->NameInformation.FileName,
2592 ParentObjectInfo->FileId.Cell,
2593 ParentObjectInfo->FileId.Volume,
2594 ParentObjectInfo->FileId.Vnode,
2595 ParentObjectInfo->FileId.Unique);
2597 DirEntry->ListEntry.fLink = NULL;
2598 DirEntry->ListEntry.bLink = NULL;
2606 AFSFixupTargetName( IN OUT PUNICODE_STRING FileName,
2607 IN OUT PUNICODE_STRING TargetFileName)
2610 NTSTATUS ntStatus = STATUS_SUCCESS;
2611 UNICODE_STRING uniFileName;
2617 // We will process backwards from the end of the name looking
2618 // for the first \ we encounter
2621 uniFileName.Length = FileName->Length;
2622 uniFileName.MaximumLength = FileName->MaximumLength;
2624 uniFileName.Buffer = FileName->Buffer;
2629 if( uniFileName.Buffer[ (uniFileName.Length/sizeof( WCHAR)) - 1] == L'\\')
2633 // Subtract one more character off of the filename if it is not the root
2636 if( uniFileName.Length > sizeof( WCHAR))
2639 uniFileName.Length -= sizeof( WCHAR);
2643 // Now build up the target name
2646 TargetFileName->Length = FileName->Length - uniFileName.Length;
2649 // If we are not on the root then fixup the name
2652 if( uniFileName.Length > sizeof( WCHAR))
2655 TargetFileName->Length -= sizeof( WCHAR);
2657 TargetFileName->Buffer = &uniFileName.Buffer[ (uniFileName.Length/sizeof( WCHAR)) + 1];
2662 TargetFileName->Buffer = &uniFileName.Buffer[ uniFileName.Length/sizeof( WCHAR)];
2666 // Fixup the passed back filename length
2669 FileName->Length = uniFileName.Length;
2671 TargetFileName->MaximumLength = TargetFileName->Length;
2676 uniFileName.Length -= sizeof( WCHAR);
2684 AFSParseName( IN PIRP Irp,
2686 OUT PUNICODE_STRING FileName,
2687 OUT PUNICODE_STRING ParsedFileName,
2688 OUT PUNICODE_STRING RootFileName,
2689 OUT ULONG *ParseFlags,
2690 OUT AFSVolumeCB **VolumeCB,
2691 OUT AFSDirectoryCB **ParentDirectoryCB,
2692 OUT AFSNameArrayHdr **NameArray)
2695 NTSTATUS ntStatus = STATUS_SUCCESS;
2696 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2697 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2698 UNICODE_STRING uniFullName, uniComponentName, uniRemainingPath;
2700 AFSDirectoryCB *pDirEntry = NULL, *pShareDirEntry = NULL, *pTargetDirEntry = NULL;
2701 USHORT usIndex = 0, usDriveIndex = 0;
2702 AFSCcb *pRelatedCcb = NULL;
2703 AFSNameArrayHdr *pNameArray = NULL, *pRelatedNameArray = NULL;
2704 USHORT usComponentIndex = 0;
2705 USHORT usComponentLength = 0;
2706 AFSVolumeCB *pVolumeCB = NULL;
2707 AFSFcb *pRelatedFcb = NULL;
2708 BOOLEAN bReleaseTreeLock = FALSE;
2709 BOOLEAN bIsAllShare = FALSE;
2716 // Indicate we are opening a root ...
2719 *ParseFlags = AFS_PARSE_FLAG_ROOT_ACCESS;
2721 if( pIrpSp->FileObject->RelatedFileObject != NULL)
2724 pRelatedFcb = (AFSFcb *)pIrpSp->FileObject->RelatedFileObject->FsContext;
2726 pRelatedCcb = (AFSCcb *)pIrpSp->FileObject->RelatedFileObject->FsContext2;
2728 pRelatedNameArray = pRelatedCcb->NameArray;
2730 uniFullName = pIrpSp->FileObject->FileName;
2732 ASSERT( pRelatedFcb != NULL);
2735 // No wild cards in the name
2738 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2739 AFS_TRACE_LEVEL_VERBOSE_2,
2740 "AFSParseName (%08lX) Relative open for %wZ FID %08lX-%08lX-%08lX-%08lX component %wZ\n",
2742 &pRelatedCcb->DirectoryCB->NameInformation.FileName,
2743 pRelatedCcb->DirectoryCB->ObjectInformation->FileId.Cell,
2744 pRelatedCcb->DirectoryCB->ObjectInformation->FileId.Volume,
2745 pRelatedCcb->DirectoryCB->ObjectInformation->FileId.Vnode,
2746 pRelatedCcb->DirectoryCB->ObjectInformation->FileId.Unique,
2749 if( FsRtlDoesNameContainWildCards( &uniFullName))
2752 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2753 AFS_TRACE_LEVEL_ERROR,
2754 "AFSParseName (%08lX) Component %wZ contains wild cards\n",
2758 try_return( ntStatus = STATUS_OBJECT_NAME_INVALID);
2761 pVolumeCB = pRelatedFcb->ObjectInformation->VolumeCB;
2763 pDirEntry = pRelatedCcb->DirectoryCB;
2765 *FileName = pIrpSp->FileObject->FileName;
2768 // Grab the root node while checking state
2771 AFSAcquireShared( pVolumeCB->VolumeLock,
2774 if( BooleanFlagOn( pVolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
2775 BooleanFlagOn( pVolumeCB->Flags, AFS_VOLUME_FLAGS_OFFLINE))
2779 // The volume has been taken off line so fail the access
2782 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2783 AFS_TRACE_LEVEL_ERROR,
2784 "AFSParseName (%08lX) Volume %08lX:%08lX OFFLINE/INVALID\n",
2786 pVolumeCB->ObjectInformation.FileId.Cell,
2787 pVolumeCB->ObjectInformation.FileId.Volume);
2789 AFSReleaseResource( pVolumeCB->VolumeLock);
2791 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
2794 if( BooleanFlagOn( pVolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_VERIFY))
2797 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2798 AFS_TRACE_LEVEL_VERBOSE,
2799 "AFSParseName (%08lX) Verifying root of volume %08lX:%08lX\n",
2801 pVolumeCB->ObjectInformation.FileId.Cell,
2802 pVolumeCB->ObjectInformation.FileId.Volume);
2804 ntStatus = AFSVerifyVolume( (ULONGLONG)PsGetCurrentProcessId(),
2807 if( !NT_SUCCESS( ntStatus))
2810 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2811 AFS_TRACE_LEVEL_ERROR,
2812 "AFSParseName (%08lX) Failed verification of root Status %08lX\n",
2816 AFSReleaseResource( pVolumeCB->VolumeLock);
2818 try_return( ntStatus);
2822 AFSReleaseResource( pVolumeCB->VolumeLock);
2824 if( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY))
2827 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2828 AFS_TRACE_LEVEL_VERBOSE,
2829 "AFSParseName (%08lX) Verifying parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2831 &pDirEntry->NameInformation.FileName,
2832 pDirEntry->ObjectInformation->FileId.Cell,
2833 pDirEntry->ObjectInformation->FileId.Volume,
2834 pDirEntry->ObjectInformation->FileId.Vnode,
2835 pDirEntry->ObjectInformation->FileId.Unique);
2838 // Directory TreeLock should be exclusively held
2841 AFSAcquireExcl( pDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
2844 ntStatus = AFSVerifyEntry( AuthGroup,
2847 AFSReleaseResource( pDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
2849 if( !NT_SUCCESS( ntStatus))
2852 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2853 AFS_TRACE_LEVEL_VERBOSE,
2854 "AFSParseName (%08lX) Failed verification of parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2856 &pDirEntry->NameInformation.FileName,
2857 pDirEntry->ObjectInformation->FileId.Cell,
2858 pDirEntry->ObjectInformation->FileId.Volume,
2859 pDirEntry->ObjectInformation->FileId.Vnode,
2860 pDirEntry->ObjectInformation->FileId.Unique,
2863 try_return( ntStatus);
2868 // Create our full path name buffer
2871 uniFullName.MaximumLength = pRelatedCcb->FullFileName.Length +
2873 pIrpSp->FileObject->FileName.Length +
2876 uniFullName.Length = 0;
2878 uniFullName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2879 uniFullName.MaximumLength,
2880 AFS_NAME_BUFFER_THREE_TAG);
2882 if( uniFullName.Buffer == NULL)
2885 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2886 AFS_TRACE_LEVEL_ERROR,
2887 "AFSParseName (%08lX) Failed to allocate full name buffer\n",
2890 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2893 RtlZeroMemory( uniFullName.Buffer,
2894 uniFullName.MaximumLength);
2896 RtlCopyMemory( uniFullName.Buffer,
2897 pRelatedCcb->FullFileName.Buffer,
2898 pRelatedCcb->FullFileName.Length);
2900 uniFullName.Length = pRelatedCcb->FullFileName.Length;
2902 usComponentIndex = (USHORT)(uniFullName.Length/sizeof( WCHAR));
2904 usComponentLength = pIrpSp->FileObject->FileName.Length;
2906 if( uniFullName.Buffer[ (uniFullName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
2907 pIrpSp->FileObject->FileName.Length > 0 &&
2908 pIrpSp->FileObject->FileName.Buffer[ 0] != L'\\' &&
2909 pIrpSp->FileObject->FileName.Buffer[ 0] != L':')
2912 uniFullName.Buffer[ (uniFullName.Length/sizeof( WCHAR))] = L'\\';
2914 uniFullName.Length += sizeof( WCHAR);
2916 usComponentLength += sizeof( WCHAR);
2919 if( pIrpSp->FileObject->FileName.Length > 0)
2922 RtlCopyMemory( &uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)],
2923 pIrpSp->FileObject->FileName.Buffer,
2924 pIr
\epSp->FileObject->FileName.Length);
2926 uniFullName.Length += pIrpSp->FileObject->FileName.Length;
2929 *RootFileName = uniFullName;
2932 // We populate up to the current parent
2935 if( pRelatedNameArray == NULL)
2939 // Init and populate our name array
2942 pNameArray = AFSInitNameArray( NULL,
2945 if( pNameArray == NULL)
2948 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2949 AFS_TRACE_LEVEL_VERBOSE,
2950 "AFSParseName (%08lX) Failed to initialize name array\n",
2953 AFSExFreePoolWithTag( uniFullName.Buffer, 0);
2955 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2958 ntStatus = AFSPopulateNameArray( pNameArray,
2960 pRelatedCcb->DirectoryCB);
2966 // Init and populate our name array
2969 pNameArray = AFSInitNameArray( NULL,
2970 pRelatedNameArray->MaxElementCount);
2972 if( pNameArray == NULL)
2975 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2976 AFS_TRACE_LEVEL_VERBOSE,
2977 "AFSParseName (%08lX) Failed to initialize name array\n",
2980 AFSExFreePoolWithTag( uniFullName.Buffer, 0);
2982 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2985 ntStatus = AFSPopulateNameArrayFromRelatedArray( pNameArray,
2987 pRelatedCcb->DirectoryCB);
2990 if( !NT_SUCCESS( ntStatus))
2993 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2994 AFS_TRACE_LEVEL_VERBOSE,
2995 "AFSParseName (%08lX) Failed to populate name array\n",
2998 AFSExFreePoolWithTag( uniFullName.Buffer, 0);
3000 try_return( ntStatus);
3003 ParsedFileName->Length = usComponentLength;
3004 ParsedFileName->MaximumLength = uniFullName.MaximumLength;
3006 ParsedFileName->Buffer = &uniFullName.Buffer[ usComponentIndex];
3009 // Indicate to caller that RootFileName must be freed
3012 SetFlag( *ParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
3014 *NameArray = pNameArray;
3016 *VolumeCB = pVolumeCB;
3019 // Increment our volume reference count
3022 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
3024 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
3025 AFS_TRACE_LEVEL_VERBOSE,
3026 "AFSParseName Increment count on volume %08lX Cnt %d\n",
3030 *ParentDirectoryCB = pDirEntry;
3032 lCount = InterlockedIncrement( &pDirEntry->OpenReferenceCount);
3034 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3035 AFS_TRACE_LEVEL_VERBOSE,
3036 "AFSParseName Increment1 count on %wZ DE %p Ccb %p Cnt %d\n",
3037 &pDirEntry->NameInformation.FileName,
3042 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3043 AFS_TRACE_LEVEL_VERBOSE_2,
3044 "AFSParseName (%08lX) Returning full name %wZ\n",
3048 try_return( ntStatus);
3052 // No wild cards in the name
3055 uniFullName = pIrpSp->FileObject->FileName;
3057 if( FsRtlDoesNameContainWildCards( &uniFullName) ||
3058 uniFullName.Length < AFSServerName.Length)
3061 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3062 AFS_TRACE_LEVEL_ERROR,
3063 "AFSParseName (%08lX) Name %wZ contains wild cards or too short\n",
3067 try_return( ntStatus = STATUS_OBJECT_NAME_INVALID);
3071 // The name is a fully qualified name. Parse out the server/share names and
3072 // point to the root qualified name
3073 // First thing is to locate the server name
3076 FsRtlDissectName( uniFullName,
3080 uniFullName = uniRemainingPath;
3083 // This component is the server name we are serving
3086 if( RtlCompareUnicodeString( &uniComponentName,
3092 // Drive letter based name?
3095 uniFullName = pIrpSp->FileObject->FileName;
3097 while( usIndex < uniFullName.Length/sizeof( WCHAR))
3100 if( uniFullName.Buffer[ usIndex] == L':')
3103 uniFullName.Buffer = &uniFullName.Buffer[ usIndex + 2];
3105 uniFullName.Length -= (usIndex + 2) * sizeof( WCHAR);
3107 usDriveIndex = usIndex - 1;
3116 // Do we have the right server name now?
3119 FsRtlDissectName( uniFullName,
3123 uniFullName = uniRemainingPath;
3126 // This component is the server name we are serving
3129 if( RtlCompareUnicodeString( &uniComponentName,
3134 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3135 AFS_TRACE_LEVEL_ERROR,
3136 "AFSParseName (%08lX) Name %wZ does not have server name\n",
3138 &pIrpSp->FileObject->FileName);
3140 try_return( ntStatus = STATUS_BAD_NETWORK_NAME);
3144 // Validate this drive letter is actively mapped
3147 if( usDriveIndex > 0 &&
3148 !AFSIsDriveMapped( pIrpSp->FileObject->FileName.Buffer[ usDriveIndex]))
3151 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3152 AFS_TRACE_LEVEL_ERROR,
3153 "AFSParseName (%08lX) Name %wZ contains invalid drive mapping\n",
3155 &pIrpSp->FileObject->FileName);
3157 try_return( ntStatus = STATUS_BAD_NETWORK_NAME);
3161 if( FsRtlDoesNameContainWildCards( &uniFullName))
3164 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3165 AFS_TRACE_LEVEL_ERROR,
3166 "AFSParseName (%08lX) Component %wZ contains wild cards\n",
3170 try_return( ntStatus = STATUS_OBJECT_NAME_INVALID);
3173 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3174 AFS_TRACE_LEVEL_VERBOSE_2,
3175 "AFSParseName (%08lX) Processing full name %wZ\n",
3179 if( uniFullName.Length > 0 &&
3180 uniFullName.Buffer[ (uniFullName.Length/sizeof( WCHAR)) - 1] == L'\\')
3183 uniFullName.Length -= sizeof( WCHAR);
3187 // Be sure we are online and ready to go
3190 AFSAcquireShared( AFSGlobalRoot->VolumeLock,
3193 if( BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
3194 BooleanFlagOn( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE))
3198 // The volume has been taken off line so fail the access
3201 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3202 AFS_TRACE_LEVEL_ERROR,
3203 "AFSParseName (%08lX) Volume %08lX:%08lX OFFLINE/INVALID\n",
3205 AFSGlobalRoot->ObjectInformation.FileId.Cell,
3206 AFSGlobalRoot->ObjectInformation.FileId.Volume);
3208 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3210 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
3213 if( BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_VERIFY))
3216 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3217 AFS_TRACE_LEVEL_VERBOSE,
3218 "AFSParseName (%08lX) Verifying root of volume %08lX:%08lX\n",
3220 AFSGlobalRoot->ObjectInformation.FileId.Cell,
3221 AFSGlobalRoot->ObjectInformation.FileId.Volume);
3223 ntStatus = AFSVerifyVolume( (ULONGLONG)PsGetCurrentProcessId(),
3226 if( !NT_SUCCESS( ntStatus))
3229 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3230 AFS_TRACE_LEVEL_ERROR,
3231 "AFSParseName (%08lX) Failed verification of root Status %08lX\n",
3235 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3237 try_return( ntStatus);
3241 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3243 if( !BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
3246 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3247 AFS_TRACE_LEVEL_VERBOSE,
3248 "AFSParseName (%08lX) Enumerating global root of volume %08lX:%08lX\n",
3250 AFSGlobalRoot->ObjectInformation.FileId.Cell,
3251 AFSGlobalRoot->ObjectInformation.FileId.Volume);
3253 ntStatus = AFSEnumerateGlobalRoot( AuthGroup);
3255 if( !NT_SUCCESS( ntStatus))
3258 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3259 AFS_TRACE_LEVEL_ERROR,
3260 "AFSParseName (%08lX) Failed enumeraiton of root Status %08lX\n",
3264 try_return( ntStatus);
3269 // Check for the \\Server access and return it as though it where \\Server\Globalroot
3272 if( uniRemainingPath.Buffer == NULL ||
3273 ( uniRemainingPath.Length == sizeof( WCHAR) &&
3274 uniRemainingPath.Buffer[ 0] == L'\\'))
3277 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3278 AFS_TRACE_LEVEL_VERBOSE_2,
3279 "AFSParseName (%08lX) Returning global root access\n",
3282 lCount = InterlockedIncrement( &AFSGlobalRoot->DirectoryCB->OpenReferenceCount);
3284 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3285 AFS_TRACE_LEVEL_VERBOSE,
3286 "AFSParseName Increment2 count on %wZ DE %p Ccb %p Cnt %d\n",
3287 &AFSGlobalRoot->DirectoryCB->NameInformation.FileName,
3288 AFSGlobalRoot->DirectoryCB,
3294 FileName->Length = 0;
3295 FileName->MaximumLength = 0;
3296 FileName->Buffer = NULL;
3298 try_return( ntStatus = STATUS_SUCCESS);
3301 *RootFileName = uniFullName;
3304 // Include the starting \ in the root name
3307 if( RootFileName->Buffer[ 0] != L'\\')
3309 RootFileName->Buffer--;
3310 RootFileName->Length += sizeof( WCHAR);
3311 RootFileName->MaximumLength += sizeof( WCHAR);
3315 // Get the 'share' name
3318 FsRtlDissectName( uniFullName,
3322 if( FsRtlDoesNameContainWildCards( &uniFullName))
3325 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3326 AFS_TRACE_LEVEL_ERROR,
3327 "AFSParseName (%08lX) Component %wZ contains wild cards\n",
3331 try_return( ntStatus = STATUS_OBJECT_NAME_INVALID);
3335 // If this is the ALL access then perform some additional processing
3338 if( uniComponentName.Length == 0 ||
3339 RtlCompareUnicodeString( &uniComponentName,
3347 // If there is nothing else then get out
3350 if( uniRemainingPath.Buffer == NULL ||
3351 uniRemainingPath.Length == 0 ||
3352 ( uniRemainingPath.Length == sizeof( WCHAR) &&
3353 uniRemainingPath.Buffer[ 0] == L'\\'))
3356 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3357 AFS_TRACE_LEVEL_VERBOSE_2,
3358 "AFSParseName (%08lX) Returning global root access\n",
3361 lCount = InterlockedIncrement( &AFSGlobalRoot->DirectoryCB->OpenReferenceCount);
3363 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3364 AFS_TRACE_LEVEL_VERBOSE,
3365 "AFSParseName Increment3 count on %wZ DE %p Ccb %p Cnt %d\n",
3366 &AFSGlobalRoot->DirectoryCB->NameInformation.FileName,
3367 AFSGlobalRoot->DirectoryCB,
3373 FileName->Length = 0;
3374 FileName->MaximumLength = 0;
3375 FileName->Buffer = NULL;
3377 try_return( ntStatus = STATUS_SUCCESS);
3381 // Process the name again to strip off the ALL portion
3384 uniFullName = uniRemainingPath;
3386 FsRtlDissectName( uniFullName,
3391 // Check for the PIOCtl name
3394 if( RtlCompareUnicodeString( &uniComponentName,
3399 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3400 AFS_TRACE_LEVEL_VERBOSE_2,
3401 "AFSParseName (%08lX) Returning root PIOCtl access\n",
3404 lCount = InterlockedIncrement( &AFSGlobalRoot->DirectoryCB->OpenReferenceCount);
3406 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3407 AFS_TRACE_LEVEL_VERBOSE,
3408 "AFSParseName Increment4 count on %wZ DE %p Ccb %p Cnt %d\n",
3409 &AFSGlobalRoot->DirectoryCB->NameInformation.FileName,
3410 AFSGlobalRoot->DirectoryCB,
3414 ClearFlag( *ParseFlags, AFS_PARSE_FLAG_ROOT_ACCESS);
3418 *FileName = AFSPIOCtlName;
3420 try_return( ntStatus = STATUS_SUCCESS);
3423 else if( (pDirEntry = AFSGetSpecialShareNameEntry( &uniComponentName,
3424 &uniRemainingPath)) != NULL)
3427 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3428 AFS_TRACE_LEVEL_VERBOSE_2,
3429 "AFSParseName (%08lX) Returning root share name %wZ access\n",
3434 // Add in the full share name to pass back
3437 if( uniRemainingPath.Buffer != NULL)
3441 // This routine strips off the leading slash so add it back in
3444 uniRemainingPath.Buffer--;
3445 uniRemainingPath.Length += sizeof( WCHAR);
3446 uniRemainingPath.MaximumLength += sizeof( WCHAR);
3449 // And the cell name
3452 uniRemainingPath.Buffer -= (uniComponentName.Length/sizeof( WCHAR));
3453 uniRemainingPath.Length += uniComponentName.Length;
3454 uniRemainingPath.MaximumLength += uniComponentName.Length;
3456 uniComponentName = uniRemainingPath;
3461 *FileName = uniComponentName;
3463 *ParentDirectoryCB = pDirEntry;
3465 ClearFlag( *ParseFlags, AFS_PARSE_FLAG_ROOT_ACCESS);
3467 lCount = InterlockedIncrement( &pDirEntry->OpenReferenceCount);
3469 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3470 AFS_TRACE_LEVEL_VERBOSE,
3471 "AFSParseName Increment5 count on %wZ DE %p Ccb %p Cnt %d\n",
3472 &pDirEntry->NameInformation.FileName,
3477 try_return( ntStatus = STATUS_SUCCESS);
3481 // Determine the 'share' we are accessing
3484 ulCRC = AFSGenerateCRC( &uniComponentName,
3487 AFSAcquireShared( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
3490 bReleaseTreeLock = TRUE;
3492 AFSLocateCaseSensitiveDirEntry( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
3496 if( pDirEntry == NULL)
3499 ulCRC = AFSGenerateCRC( &uniComponentName,
3502 AFSLocateCaseInsensitiveDirEntry( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
3506 if( pDirEntry == NULL)
3510 // OK, if this component is a valid short name then try
3511 // a lookup in the short name tree
3514 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
3515 RtlIsNameLegalDOS8Dot3( &uniComponentName,
3520 AFSLocateShortNameDirEntry( AFSGlobalRoot->ObjectInformation.Specific.Directory.ShortNameTree,
3525 if( pDirEntry == NULL)
3529 // Check with the service whether it is a valid cell name
3532 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
3534 bReleaseTreeLock = FALSE;
3536 ntStatus = AFSCheckCellName( AuthGroup,
3540 if( !NT_SUCCESS( ntStatus))
3544 uniRemainingPath.Length == 0 &&
3545 ntStatus == STATUS_OBJECT_PATH_NOT_FOUND)
3548 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
3551 try_return( ntStatus);
3557 if( bReleaseTreeLock)
3559 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
3564 // Be sure we are starting from the correct volume
3567 if( pDirEntry->ObjectInformation->VolumeCB != AFSGlobalRoot)
3571 // We dropped the global root in the CheckCellName routine which is the
3572 // only way we can be here
3575 pVolumeCB = pDirEntry->ObjectInformation->VolumeCB;
3578 // Init our name array
3581 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
3584 if( pNameArray == NULL)
3587 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3588 AFS_TRACE_LEVEL_VERBOSE,
3589 "AFSParseName (%08lX) Failed to initialize name array\n",
3592 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3595 ntStatus = AFSInsertNextElement( pNameArray,
3596 pVolumeCB->DirectoryCB);
3601 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3602 AFS_TRACE_LEVEL_VERBOSE,
3603 "AFSParseName (%08lX) Failed to insert name array element\n",
3606 try_return( ntStatus);
3610 // In this case don't add back in the 'share' name since that is where we are
3611 // starting. Just put the leading slash back in
3614 if( uniRemainingPath.Buffer != NULL)
3617 uniRemainingPath.Buffer--;
3618 uniRemainingPath.Length += sizeof( WCHAR);
3619 uniRemainingPath.MaximumLength += sizeof( WCHAR);
3621 if( uniRemainingPath.Length > sizeof( WCHAR))
3624 ClearFlag( *ParseFlags, AFS_PARSE_FLAG_ROOT_ACCESS);
3628 // Pass back the parent being the root of the volume
3631 *ParentDirectoryCB = pVolumeCB->DirectoryCB;
3637 // Pass back a root slash
3640 uniRemainingPath = uniComponentName;
3642 uniRemainingPath.Buffer--;
3643 uniRemainingPath.Length = sizeof( WCHAR);
3644 uniRemainingPath.MaximumLength = sizeof( WCHAR);
3647 // This is a root open so pass back no parent
3650 *ParentDirectoryCB = NULL;
3656 pVolumeCB = AFSGlobalRoot;
3659 // Init our name array
3662 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
3664 if( pNameArray == NULL)
3667 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3668 AFS_TRACE_LEVEL_VERBOSE,
3669 "AFSParseName (%08lX) Failed to initialize name array\n",
3672 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3676 // Add back in the 'share' portion of the name since we will parse it out on return
3679 if( uniRemainingPath.Buffer != NULL)
3683 // This routine strips off the leading slash so add it back in
3686 uniRemainingPath.Buffer--;
3687 uniRemainingPath.Length += sizeof( WCHAR);
3688 uniRemainingPath.MaximumLength += sizeof( WCHAR);
3690 if( uniRemainingPath.Length > sizeof( WCHAR))
3693 ClearFlag( *ParseFlags, AFS_PARSE_FLAG_ROOT_ACCESS);
3697 // And the cell name
3700 uniRemainingPath.Buffer -= (uniComponentName.Length/sizeof( WCHAR));
3701 uniRemainingPath.Length += uniComponentName.Length;
3702 uniRemainingPath.MaximumLength += uniComponentName.Length;
3707 uniRemainingPath = uniComponentName;
3711 // And the leading slash again ...
3714 uniRemainingPath.Buffer--;
3715 uniRemainingPath.Length += sizeof( WCHAR);
3716 uniRemainingPath.MaximumLength += sizeof( WCHAR);
3718 lCount = InterlockedIncrement( &pVolumeCB->DirectoryCB->OpenReferenceCount);
3720 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3721 AFS_TRACE_LEVEL_VERBOSE,
3722 "AFSParseName Increment6 count on %wZ DE %p Ccb %p Cnt %d\n",
3723 &pVolumeCB->DirectoryCB->NameInformation.FileName,
3724 pVolumeCB->DirectoryCB,
3726 lCount = pVolumeCB->DirectoryCB->OpenReferenceCount);
3729 // Pass back the parent being the volume root
3732 *ParentDirectoryCB = pVolumeCB->DirectoryCB;
3737 // Return the remaining portion as the file name
3740 *FileName = uniRemainingPath;
3742 *ParsedFileName = uniRemainingPath;
3744 *NameArray = pNameArray;
3746 *VolumeCB = pVolumeCB;
3749 // Increment our reference on the volume
3752 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
3754 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
3755 AFS_TRACE_LEVEL_VERBOSE,
3756 "AFSParseName Increment2 count on global volume %08lX Cnt %d\n",
3762 if( NT_SUCCESS( ntStatus))
3765 if( *ParentDirectoryCB != NULL)
3768 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3769 AFS_TRACE_LEVEL_VERBOSE,
3770 "AFSParseName Count on %wZ DE %p Ccb %p Cnt %d\n",
3771 &(*ParentDirectoryCB)->NameInformation.FileName,
3774 (*ParentDirectoryCB)->OpenReferenceCount);
3778 if( *VolumeCB != NULL)
3780 ASSERT( (*VolumeCB)->VolumeReferenceCount > 1);
3783 if( ntStatus != STATUS_SUCCESS)
3786 if( pNameArray != NULL)
3789 AFSFreeNameArray( pNameArray);
3798 AFSCheckCellName( IN GUID *AuthGroup,
3799 IN UNICODE_STRING *CellName,
3800 OUT AFSDirectoryCB **ShareDirEntry)
3803 NTSTATUS ntStatus = STATUS_SUCCESS;
3804 UNICODE_STRING uniName;
3805 AFSDirEnumEntry *pDirEnumEntry = NULL;
3806 AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
3807 AFSDirHdr *pDirHdr = &AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr;
3808 AFSDirectoryCB *pDirNode = NULL;
3809 UNICODE_STRING uniDirName, uniTargetName;
3810 AFSVolumeCB *pVolumeCB = NULL;
3817 // Look for some default names we will not handle
3820 RtlInitUnicodeString( &uniName,
3823 if( RtlCompareUnicodeString( &uniName,
3828 try_return( ntStatus = STATUS_NO_SUCH_FILE);
3831 RtlInitUnicodeString( &uniName,
3834 if( RtlCompareUnicodeString( &uniName,
3839 try_return( ntStatus = STATUS_NO_SUCH_FILE);
3842 RtlInitUnicodeString( &uniName,
3845 if( RtlCompareUnicodeString( &uniName,
3850 try_return( ntStatus = STATUS_NO_SUCH_FILE);
3853 RtlInitUnicodeString( &uniName,
3856 if( RtlCompareUnicodeString( &uniName,
3861 try_return( ntStatus = STATUS_NO_SUCH_FILE);
3865 // OK, ask the CM about this component name
3868 ntStatus = AFSEvaluateTargetByName( AuthGroup,
3869 &AFSGlobalRoot->ObjectInformation,
3873 if( !NT_SUCCESS( ntStatus))
3876 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3877 AFS_TRACE_LEVEL_WARNING,
3878 "AFSCheckCellName entry %wZ does not exist parent FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
3880 AFSGlobalRoot->ObjectInformation.FileId.Cell,
3881 AFSGlobalRoot->ObjectInformation.FileId.Volume,
3882 AFSGlobalRoot->ObjectInformation.FileId.Vnode,
3883 AFSGlobalRoot->ObjectInformation.FileId.Unique,
3886 try_return( ntStatus);
3890 // OK, we have a dir enum entry back so add it to the root node
3893 uniDirName = *CellName;
3895 uniTargetName.Length = (USHORT)pDirEnumEntry->TargetNameLength;
3896 uniTargetName.MaximumLength = uniTargetName.Length;
3897 uniTargetName.Buffer = (WCHAR *)((char *)pDirEnumEntry + pDirEnumEntry->TargetNameOffset);
3900 // Is this entry a root volume entry?
3903 if( pDirEnumEntry->FileId.Cell != AFSGlobalRoot->ObjectInformation.FileId.Cell ||
3904 pDirEnumEntry->FileId.Volume != AFSGlobalRoot->ObjectInformation.FileId.Volume)
3908 // Build the root volume entry
3911 ntStatus = AFSBuildRootVolume( AuthGroup,
3912 &pDirEnumEntry->FileId,
3915 if( !NT_SUCCESS( ntStatus))
3917 try_return( ntStatus);
3920 *ShareDirEntry = pVolumeCB->DirectoryCB;
3922 lCount = InterlockedIncrement( &pVolumeCB->DirectoryCB->OpenReferenceCount);
3924 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3925 AFS_TRACE_LEVEL_VERBOSE,
3926 "AFSCheckCellName Increment1 count on %wZ DE %p Ccb %p Cnt %d\n",
3927 &pVolumeCB->DirectoryCB->NameInformation.FileName,
3928 pVolumeCB->DirectoryCB,
3932 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
3937 lCount = InterlockedIncrement( &pDirHdr->ContentIndex);
3939 pDirNode = AFSInitDirEntry( &AFSGlobalRoot->ObjectInformation,
3945 if( pDirNode == NULL)
3948 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3952 // Init the short name if we have one
3955 if( pDirEnumEntry->ShortNameLength > 0)
3958 pDirNode->NameInformation.ShortNameLength = pDirEnumEntry->ShortNameLength;
3960 RtlCopyMemory( pDirNode->NameInformation.ShortName,
3961 pDirEnumEntry->ShortName,
3962 pDirNode->NameInformation.ShortNameLength);
3965 AFSAcquireExcl( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
3969 // Insert the node into the name tree
3972 ASSERT( ExIsResourceAcquiredExclusiveLite( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock));
3974 if( pDirHdr->CaseSensitiveTreeHead == NULL)
3977 pDirHdr->CaseSensitiveTreeHead = pDirNode;
3982 if( !NT_SUCCESS( AFSInsertCaseSensitiveDirEntry( pDirHdr->CaseSensitiveTreeHead,
3986 AFSDeleteDirEntry( &AFSGlobalRoot->ObjectInformation,
3989 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
3991 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3995 ClearFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
3997 if( pDirHdr->CaseInsensitiveTreeHead == NULL)
4000 pDirHdr->CaseInsensitiveTreeHead = pDirNode;
4002 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
4007 AFSInsertCaseInsensitiveDirEntry( pDirHdr->CaseInsensitiveTreeHead,
4011 if( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListHead == NULL)
4014 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListHead = pDirNode;
4019 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListTail->ListEntry.fLink = pDirNode;
4021 pDirNode->ListEntry.bLink = AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListTail;
4024 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListTail = pDirNode;
4026 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST);
4028 lCount = InterlockedIncrement( &AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeCount);
4030 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
4031 AFS_TRACE_LEVEL_VERBOSE,
4032 "AFSCheckCellName Adding entry %wZ Inc Count %d to parent FID %08lX-%08lX-%08lX-%08lX\n",
4033 &pDirNode->NameInformation.FileName,
4035 AFSGlobalRoot->ObjectInformation.FileId.Cell,
4036 AFSGlobalRoot->ObjectInformation.FileId.Volume,
4037 AFSGlobalRoot->ObjectInformation.FileId.Vnode,
4038 AFSGlobalRoot->ObjectInformation.FileId.Unique);
4040 lCount = InterlockedIncrement( &pDirNode->OpenReferenceCount);
4042 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
4043 AFS_TRACE_LEVEL_VERBOSE,
4044 "AFSCheckCellName Increment2 count on %wZ DE %p Ccb %p Cnt %d\n",
4045 &pDirNode->NameInformation.FileName,
4050 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
4053 // Pass back the dir node
4056 *ShareDirEntry = pDirNode;
4061 if( pDirEnumEntry != NULL)
4064 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_31_TAG);
4072 AFSBuildMountPointTarget( IN GUID *AuthGroup,
4073 IN AFSDirectoryCB *DirectoryCB,
4074 OUT AFSVolumeCB **TargetVolumeCB)
4077 NTSTATUS ntStatus = STATUS_SUCCESS;
4078 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
4079 AFSDirEnumEntry *pDirEntry = NULL;
4080 AFSDirectoryCB *pDirNode = NULL;
4081 UNICODE_STRING uniDirName, uniTargetName;
4082 ULONGLONG ullIndex = 0;
4083 AFSVolumeCB *pVolumeCB = NULL;
4084 AFSFileID stTargetFileID;
4086 BOOLEAN bReleaseVolumeLock = FALSE;
4092 // Loop on each entry, building the chain until we encounter the final target
4095 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4096 AFS_TRACE_LEVEL_VERBOSE_2,
4097 "AFSBuildMountPointTarget Building target directory for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4098 &DirectoryCB->NameInformation.FileName,
4099 DirectoryCB->ObjectInformation->FileId.Cell,
4100 DirectoryCB->ObjectInformation->FileId.Volume,
4101 DirectoryCB->ObjectInformation->FileId.Vnode,
4102 DirectoryCB->ObjectInformation->FileId.Unique);
4105 // Do we need to evaluate the node?
4108 //if( DirectoryCB->ObjectInformation->TargetFileId.Vnode == 0 &&
4109 // DirectoryCB->ObjectInformation->TargetFileId.Unique == 0)
4113 // Go evaluate the current target to get the target fid
4116 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4117 AFS_TRACE_LEVEL_VERBOSE_2,
4118 "AFSBuildMountPointTarget Evaluating target %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4119 &DirectoryCB->NameInformation.FileName,
4120 DirectoryCB->ObjectInformation->FileId.Cell,
4121 DirectoryCB->ObjectInformation->FileId.Volume,
4122 DirectoryCB->ObjectInformation->FileId.Vnode,
4123 DirectoryCB->ObjectInformation->FileId.Unique);
4125 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
4130 if( !NT_SUCCESS( ntStatus))
4133 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4134 AFS_TRACE_LEVEL_ERROR,
4135 "AFSBuildMountPointTarget Failed to evaluate target %wZ Status %08lX\n",
4136 &DirectoryCB->NameInformation.FileName,
4138 try_return( ntStatus);
4141 if( pDirEntry->TargetFileId.Vnode == 0 &&
4142 pDirEntry->TargetFileId.Unique == 0)
4145 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4146 AFS_TRACE_LEVEL_ERROR,
4147 "AFSBuildMountPointTarget Target %wZ FID %08lX-%08lX-%08lX-%08lX service returned zero FID\n",
4148 &DirectoryCB->NameInformation.FileName,
4149 DirectoryCB->ObjectInformation->FileId.Cell,
4150 DirectoryCB->ObjectInformation->FileId.Volume,
4151 DirectoryCB->ObjectInformation->FileId.Vnode,
4152 DirectoryCB->ObjectInformation->FileId.Unique);
4154 try_return( ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED);
4157 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
4160 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
4161 &DirectoryCB->Flags,
4162 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
4163 (USHORT)pDirEntry->TargetNameLength);
4165 if( !NT_SUCCESS( ntStatus))
4168 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
4170 try_return( ntStatus);
4173 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
4175 DirectoryCB->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
4178 stTargetFileID = DirectoryCB->ObjectInformation->TargetFileId;
4181 // Try to locate this FID. First the volume then the
4185 ullIndex = AFSCreateHighIndex( &stTargetFileID);
4187 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4188 AFS_TRACE_LEVEL_VERBOSE,
4189 "AFSBuildMountPointTarget Acquiring RDR VolumeTreeLock lock %08lX EXCL %08lX\n",
4190 &pDevExt->Specific.RDR.VolumeTreeLock,
4191 PsGetCurrentThread());
4193 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock,
4196 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4197 AFS_TRACE_LEVEL_VERBOSE_2,
4198 "AFSBuildMountPointTarget Locating volume for target %I64X\n",
4201 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
4203 (AFSBTreeEntry **)&pVolumeCB);
4206 // We can be processing a request for a target that is on a volume
4207 // we have never seen before.
4210 if( pVolumeCB == NULL)
4214 // Locking is held correctly in init routine
4217 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
4220 // Go init the root of the volume
4223 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4224 AFS_TRACE_LEVEL_VERBOSE_2,
4225 "AFSBuildMountPointTarget Initializing root for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4226 &DirectoryCB->NameInformation.FileName,
4227 DirectoryCB->ObjectInformation->FileId.Cell,
4228 DirectoryCB->ObjectInformation->FileId.Volume,
4229 DirectoryCB->ObjectInformation->FileId.Vnode,
4230 DirectoryCB->ObjectInformation->FileId.Unique);
4232 ntStatus = AFSInitVolume( AuthGroup,
4236 if( !NT_SUCCESS( ntStatus))
4239 try_return( ntStatus);
4243 // pVolumeCB->VolumeLock held exclusive and
4244 // pVolumeCB->VolumeReferenceCount has been incremented
4245 // pVolumeCB->RootFcb == NULL
4248 bReleaseVolumeLock = TRUE;
4254 // AFSInitVolume returns with a VolumeReferenceCount
4255 // obtain one to match
4258 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
4260 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
4261 AFS_TRACE_LEVEL_VERBOSE,
4262 "AFSBuildMountPointTarget Increment count on volume %08lX Cnt %d\n",
4266 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
4269 if( pVolumeCB->RootFcb == NULL)
4272 if ( bReleaseVolumeLock == FALSE)
4275 AFSAcquireExcl( pVolumeCB->VolumeLock,
4278 bReleaseVolumeLock = TRUE;
4282 // Initialize the root fcb for this volume
4285 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
4288 if( !NT_SUCCESS( ntStatus))
4291 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
4293 AFSReleaseResource( pVolumeCB->VolumeLock);
4295 try_return( ntStatus);
4299 // Drop the lock acquired above
4302 AFSReleaseResource( &pVolumeCB->RootFcb->NPFcb->Resource);
4305 if ( bReleaseVolumeLock == TRUE)
4308 AFSReleaseResource( pVolumeCB->VolumeLock);
4311 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4312 AFS_TRACE_LEVEL_VERBOSE_2,
4313 "AFSBuildMountPointTarget Evaluated target of %wZ FID %08lX-%08lX-%08lX-%08lX as root volume\n",
4314 &pVolumeCB->DirectoryCB->NameInformation.FileName,
4315 pVolumeCB->ObjectInformation.FileId.Cell,
4316 pVolumeCB->ObjectInformation.FileId.Volume,
4317 pVolumeCB->ObjectInformation.FileId.Vnode,
4318 pVolumeCB->ObjectInformation.FileId.Unique);
4320 *TargetVolumeCB = pVolumeCB;
4327 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
4335 AFSBuildRootVolume( IN GUID *AuthGroup,
4336 IN AFSFileID *FileId,
4337 OUT AFSVolumeCB **TargetVolumeCB)
4340 NTSTATUS ntStatus = STATUS_SUCCESS;
4341 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
4342 AFSDirectoryCB *pDirNode = NULL;
4343 UNICODE_STRING uniDirName, uniTargetName;
4344 ULONGLONG ullIndex = 0;
4345 AFSVolumeCB *pVolumeCB = NULL;
4347 BOOLEAN bReleaseVolumeLock = FALSE;
4352 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4353 AFS_TRACE_LEVEL_VERBOSE_2,
4354 "AFSBuildRootVolume Building target volume for FID %08lX-%08lX-%08lX-%08lX\n",
4360 ullIndex = AFSCreateHighIndex( FileId);
4362 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4363 AFS_TRACE_LEVEL_VERBOSE,
4364 "AFSBuildRootVolume Acquiring RDR VolumeTreeLock lock %08lX EXCL %08lX\n",
4365 &pDevExt->Specific.RDR.VolumeTreeLock,
4366 PsGetCurrentThread());
4368 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock,
4371 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4372 AFS_TRACE_LEVEL_VERBOSE_2,
4373 "AFSBuildRootVolume Locating volume for target %I64X\n",
4376 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
4378 (AFSBTreeEntry **)&pVolumeCB);
4381 // We can be processing a request for a target that is on a volume
4382 // we have never seen before.
4385 if( pVolumeCB == NULL)
4389 // Locking is held correctly in init routine
4392 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
4395 // Go init the root of the volume
4398 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4399 AFS_TRACE_LEVEL_VERBOSE_2,
4400 "AFSBuildRootVolume Initializing root for FID %08lX-%08lX-%08lX-%08lX\n",
4406 ntStatus = AFSInitVolume( AuthGroup,
4410 if( !NT_SUCCESS( ntStatus))
4413 try_return( ntStatus);
4417 // pVolumeCB->VolumeLock is held exclusive
4418 // pVolumeCB->VolumeReferenceCount has been incremented
4419 // pVolumeCB->RootFcb == NULL
4422 bReleaseVolumeLock = TRUE;
4428 // AFSInitVolume returns with a VolumeReferenceCount
4429 // obtain one to match
4432 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
4434 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
4435 AFS_TRACE_LEVEL_VERBOSE,
4436 "AFSBuildRootVolume Increment count on volume %08lX Cnt %d\n",
4440 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
4444 if( pVolumeCB->RootFcb == NULL)
4447 if ( bReleaseVolumeLock == FALSE)
4450 AFSAcquireExcl( pVolumeCB->VolumeLock,
4453 bReleaseVolumeLock = TRUE;
4457 // Initialize the root fcb for this volume
4460 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
4463 if( !NT_SUCCESS( ntStatus))
4466 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
4468 AFSReleaseResource( pVolumeCB->VolumeLock);
4470 try_return( ntStatus);
4474 // Drop the lock acquired above
4477 AFSReleaseResource( &pVolumeCB->RootFcb->NPFcb->Resource);
4480 if ( bReleaseVolumeLock == TRUE)
4483 AFSReleaseResource( pVolumeCB->VolumeLock);
4486 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4487 AFS_TRACE_LEVEL_VERBOSE_2,
4488 "AFSBuildRootVolume Evaluated target of %wZ FID %08lX-%08lX-%08lX-%08lX as root volume\n",
4489 &pVolumeCB->DirectoryCB->NameInformation.FileName,
4490 pVolumeCB->ObjectInformation.FileId.Cell,
4491 pVolumeCB->ObjectInformation.FileId.Volume,
4492 pVolumeCB->ObjectInformation.FileId.Vnode,
4493 pVolumeCB->ObjectInformation.FileId.Unique);
4495 *TargetVolumeCB = pVolumeCB;
4506 AFSProcessDFSLink( IN AFSDirectoryCB *DirEntry,
4507 IN PFILE_OBJECT FileObject,
4508 IN UNICODE_STRING *RemainingPath,
4512 NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
4513 UNICODE_STRING uniReparseName;
4514 UNICODE_STRING uniMUPDeviceName;
4515 AFSDirEnumEntry *pDirEntry = NULL;
4521 // Build up the name to reparse
4524 RtlInitUnicodeString( &uniMUPDeviceName,
4527 uniReparseName.Length = 0;
4528 uniReparseName.Buffer = NULL;
4531 // Be sure we have a target name
4534 if( DirEntry->NameInformation.TargetName.Length == 0)
4537 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
4542 if( !NT_SUCCESS( ntStatus) ||
4543 pDirEntry->TargetNameLength == 0)
4546 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4547 AFS_TRACE_LEVEL_ERROR,
4548 "AFSProcessDFSLink EvaluateTargetByID failed for Fcb %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4549 &DirEntry->NameInformation.FileName,
4550 DirEntry->ObjectInformation->FileId.Cell,
4551 DirEntry->ObjectInformation->FileId.Volume,
4552 DirEntry->ObjectInformation->FileId.Vnode,
4553 DirEntry->ObjectInformation->FileId.Unique,
4556 if( NT_SUCCESS( ntStatus))
4559 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
4562 try_return( ntStatus);
4566 // Update the target name
4569 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
4572 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
4574 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
4575 (USHORT)pDirEntry->TargetNameLength);
4577 if( !NT_SUCCESS( ntStatus))
4580 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4581 AFS_TRACE_LEVEL_ERROR,
4582 "AFSProcessDFSLink UpdateTargetName failed for Fcb %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4583 &DirEntry->NameInformation.FileName,
4584 DirEntry->ObjectInformation->FileId.Cell,
4585 DirEntry->ObjectInformation->FileId.Volume,
4586 DirEntry->ObjectInformation->FileId.Vnode,
4587 DirEntry->ObjectInformation->FileId.Unique,
4590 AFSReleaseResource( &DirEntry->NonPaged->Lock);
4592 try_return( ntStatus);
4595 AFSConvertToShared( &DirEntry->NonPaged->Lock);
4599 AFSAcquireShared( &DirEntry->NonPaged->Lock,
4603 uniReparseName.MaximumLength = uniMUPDeviceName.Length +
4605 DirEntry->NameInformation.TargetName.Length +
4608 if( RemainingPath != NULL &&
4609 RemainingPath->Length > 0)
4612 uniReparseName.MaximumLength += RemainingPath->Length;
4616 // Allocate the reparse buffer
4619 uniReparseName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
4620 uniReparseName.MaximumLength,
4621 AFS_REPARSE_NAME_TAG);
4623 if( uniReparseName.Buffer == NULL)
4626 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4627 AFS_TRACE_LEVEL_ERROR,
4628 "AFSProcessDFSLink uniReparseName.Buffer == NULL Fcb %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4629 &DirEntry->NameInformation.FileName,
4630 DirEntry->ObjectInformation->FileId.Cell,
4631 DirEntry->ObjectInformation->FileId.Volume,
4632 DirEntry->ObjectInformation->FileId.Vnode,
4633 DirEntry->ObjectInformation->FileId.Unique,
4634 STATUS_INSUFFICIENT_RESOURCES);
4636 AFSReleaseResource( &DirEntry->NonPaged->Lock);
4638 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4642 // Start building the name
4645 RtlCopyMemory( uniReparseName.Buffer,
4646 uniMUPDeviceName.Buffer,
4647 uniMUPDeviceName.Length);
4649 uniReparseName.Length = uniMUPDeviceName.Length;
4651 if( DirEntry->NameInformation.TargetName.Buffer[ 0] != L'\\')
4654 uniReparseName.Buffer[ uniReparseName.Length/sizeof( WCHAR)] = L'\\';
4656 uniReparseName.Length += sizeof( WCHAR);
4659 RtlCopyMemory( &uniReparseName.Buffer[ uniReparseName.Length/sizeof( WCHAR)],
4660 DirEntry->NameInformation.TargetName.Buffer,
4661 DirEntry->NameInformation.TargetName.Length);
4663 uniReparseName.Length += DirEntry->NameInformation.TargetName.Length;
4665 AFSReleaseResource( &DirEntry->NonPaged->Lock);
4667 if( RemainingPath != NULL &&
4668 RemainingPath->Length > 0)
4671 if( uniReparseName.Buffer[ (uniReparseName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
4672 RemainingPath->Buffer[ 0] != L'\\')
4675 uniReparseName.Buffer[ uniReparseName.Length/sizeof( WCHAR)] = L'\\';
4677 uniReparseName.Length += sizeof( WCHAR);
4680 RtlCopyMemory( &uniReparseName.Buffer[ uniReparseName.Length/sizeof( WCHAR)],
4681 RemainingPath->Buffer,
4682 RemainingPath->Length);
4684 uniReparseName.Length += RemainingPath->Length;
4688 // Update the name in the file object
4691 if( FileObject->FileName.Buffer != NULL)
4694 AFSExFreePoolWithTag( FileObject->FileName.Buffer, 0);
4697 FileObject->FileName = uniReparseName;
4699 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4700 AFS_TRACE_LEVEL_VERBOSE,
4701 "AFSProcessDFSLink Reparsing access to Fcb %wZ FID %08lX-%08lX-%08lX-%08lX to %wZ\n",
4702 &DirEntry->NameInformation.FileName,
4703 DirEntry->ObjectInformation->FileId.Cell,
4704 DirEntry->ObjectInformation->FileId.Volume,
4705 DirEntry->ObjectInformation->FileId.Vnode,
4706 DirEntry->ObjectInformation->FileId.Unique,
4710 // Return status reparse ...
4713 ntStatus = STATUS_REPARSE;
4720 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);