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);
623 // We'll substitute this name into the current process name
624 // starting at where we sit in the path
627 uniTempName.Length = 0;
628 uniTempName.MaximumLength = pDirEntry->NameInformation.TargetName.Length +
630 uniRemainingPath.Length;
632 uniTempName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
633 uniTempName.MaximumLength,
634 AFS_NAME_BUFFER_TWO_TAG);
636 if( uniTempName.Buffer == NULL)
639 AFSReleaseResource( &pDirEntry->NonPaged->Lock);
641 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
644 if( bAllocatedSymLinkBuffer ||
648 pTmpBuffer = uniFullPathName.Buffer;
651 bAllocatedSymLinkBuffer = TRUE;
654 // Have we parsed this name yet? Better have at least once ...
657 if( uniComponentName.Length == 0)
663 // Copy in the target name ...
666 RtlCopyMemory( uniTempName.Buffer,
667 pDirEntry->NameInformation.TargetName.Buffer,
668 pDirEntry->NameInformation.TargetName.Length);
670 uniTempName.Length = pDirEntry->NameInformation.TargetName.Length;
673 // And now any remaining portion of the name
676 if( uniRemainingPath.Length > 0)
679 if( uniRemainingPath.Buffer[ 0] != L'\\')
682 uniRemainingPath.Buffer--;
683 uniRemainingPath.Length += sizeof( WCHAR);
686 RtlCopyMemory( &uniTempName.Buffer[ uniTempName.Length/sizeof( WCHAR)],
687 uniRemainingPath.Buffer,
688 uniRemainingPath.Length);
690 uniTempName.Length += uniRemainingPath.Length;
693 uniFullPathName = uniTempName;
695 uniPathName = uniTempName;
697 if( pTmpBuffer != NULL)
700 AFSExFreePoolWithTag( pTmpBuffer, 0);
703 AFSReleaseResource( &pDirEntry->NonPaged->Lock);
706 // If our current volume is not the global root then make it so ...
709 if( pCurrentVolume != AFSGlobalRoot)
712 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
713 AFS_TRACE_LEVEL_VERBOSE,
714 "AFSLocateNameEntry (FO: %08lX) Current volume not global, resetting for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
716 &pDirEntry->NameInformation.FileName,
717 pCurrentObject->FileId.Cell,
718 pCurrentObject->FileId.Volume,
719 pCurrentObject->FileId.Vnode,
720 pCurrentObject->FileId.Unique);
722 lCount = InterlockedDecrement( &pCurrentVolume->VolumeReferenceCount);
724 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
725 AFS_TRACE_LEVEL_VERBOSE,
726 "AFSLocateNameEntry Decrement count on volume %08lX Cnt %d\n",
730 pCurrentVolume = AFSGlobalRoot;
732 lCount = InterlockedIncrement( &pCurrentVolume->VolumeReferenceCount);
734 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
735 AFS_TRACE_LEVEL_VERBOSE,
736 "AFSLocateNameEntry Increment count on volume %08lX Cnt %d\n",
742 // Dereference our current dir entry
745 lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
747 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
748 AFS_TRACE_LEVEL_VERBOSE,
749 "AFSLocateNameEntry Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
750 &pDirEntry->NameInformation.FileName,
755 pDirEntry = pCurrentVolume->DirectoryCB;
758 // Reference the new dir entry
761 lCount = InterlockedIncrement( &pDirEntry->OpenReferenceCount);
763 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
764 AFS_TRACE_LEVEL_VERBOSE,
765 "AFSLocateNameEntry Increment2 count on %wZ DE %p Ccb %p Cnt %d\n",
766 &pDirEntry->NameInformation.FileName,
772 // Reset the name array
773 // Persist the link count in the name array
776 lLinkCount = pNameArray->LinkCount;
778 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
779 AFS_TRACE_LEVEL_VERBOSE,
780 "AFSLocateNameEntry (FO: %08lX) Resetting name array for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
782 &pDirEntry->NameInformation.FileName,
783 pCurrentObject->FileId.Cell,
784 pCurrentObject->FileId.Volume,
785 pCurrentObject->FileId.Vnode,
786 pCurrentObject->FileId.Unique);
788 AFSResetNameArray( pNameArray,
791 pNameArray->LinkCount = lLinkCount;
794 // Process over the \\<Global root> portion of the name
797 FsRtlDissectName( uniPathName,
801 if( RtlCompareUnicodeString( &uniComponentName,
806 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
807 AFS_TRACE_LEVEL_ERROR,
808 "AFSLocateNameEntry Name %wZ contains invalid server name\n",
812 // The correct response would be STATUS_OBJECT_PATH_INVALID
813 // but that prevents cmd.exe from performing a recursive
814 // directory enumeration when opening a directory entry
815 // that represents a symlink to an invalid path is discovered.
817 try_return( ntStatus = STATUS_OBJECT_PATH_NOT_FOUND);
820 uniPathName = uniRemainingPath;
822 pParentDirEntry = NULL;
826 // Increment our link count
829 lCount = InterlockedIncrement( &pNameArray->LinkCount);
834 case AFS_FILE_TYPE_MOUNTPOINT:
838 // Check if the flag is set to NOT evaluate a mount point
839 // and we are done with the parsing
842 if( BooleanFlagOn( Flags, AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL) &&
843 uniRemainingPath.Length == 0)
847 // Pass back the directory entries
850 *ParentDirectoryCB = pParentDirEntry;
852 *DirectoryCB = pDirEntry;
854 *VolumeCB = pCurrentVolume;
856 *RootPathName = uniFullPathName;
858 try_return( ntStatus);
861 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
862 AFS_TRACE_LEVEL_VERBOSE,
863 "AFSLocateNameEntry (FO: %08lX) Building MP target for parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
865 &pDirEntry->NameInformation.FileName,
866 pCurrentObject->FileId.Cell,
867 pCurrentObject->FileId.Volume,
868 pCurrentObject->FileId.Vnode,
869 pCurrentObject->FileId.Unique);
872 // Go retrieve the target entry for this node
873 // Release the current volume cb entry since we would
874 // have lock inversion in the following call
875 // Also decrement the ref count on the volume
878 ASSERT( pCurrentVolume->VolumeReferenceCount > 1);
880 lCount = InterlockedDecrement( &pCurrentVolume->VolumeReferenceCount);
882 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
883 AFS_TRACE_LEVEL_VERBOSE,
884 "AFSLocateNameEntry Decrement2 count on volume %08lX Cnt %d\n",
886 pCurrentVolume->VolumeReferenceCount);
888 ntStatus = AFSBuildMountPointTarget( AuthGroup,
892 if( !NT_SUCCESS( ntStatus))
895 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
896 AFS_TRACE_LEVEL_ERROR,
897 "AFSLocateNameEntry (FO: %08lX) Failed to build MP target for parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
899 &pDirEntry->NameInformation.FileName,
900 pCurrentObject->FileId.Cell,
901 pCurrentObject->FileId.Volume,
902 pCurrentObject->FileId.Vnode,
903 pCurrentObject->FileId.Unique,
907 // We already decremented the current volume above
910 bReleaseCurrentVolume = FALSE;
912 try_return( ntStatus);
915 ASSERT( pCurrentVolume->VolumeReferenceCount > 1);
918 // The name array stores both the mount point and the target.
919 // Insert the target.
922 AFSInsertNextElement( pNameArray,
923 pCurrentVolume->DirectoryCB);
926 // We want to restart processing here on the new parent ...
927 // Deref and ref count the entries
930 lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
932 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
933 AFS_TRACE_LEVEL_VERBOSE,
934 "AFSLocateNameEntry Decrement3 count on %wZ DE %p Ccb %p Cnt %d\n",
935 &pDirEntry->NameInformation.FileName,
940 pDirEntry = pCurrentVolume->DirectoryCB;
942 lCount = InterlockedIncrement( &pDirEntry->OpenReferenceCount);
944 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
945 AFS_TRACE_LEVEL_VERBOSE,
946 "AFSLocateNameEntry Increment3 count on %wZ DE %p Ccb %p Cnt %d\n",
947 &pDirEntry->NameInformation.FileName,
952 pParentDirEntry = NULL;
955 // Increment our link count
958 lCount = InterlockedIncrement( &pNameArray->LinkCount);
963 case AFS_FILE_TYPE_DFSLINK:
966 if( BooleanFlagOn( Flags, AFS_LOCATE_FLAGS_NO_DFS_LINK_EVAL))
970 // Pass back the directory entries
973 *ParentDirectoryCB = pParentDirEntry;
975 *DirectoryCB = pDirEntry;
977 *VolumeCB = pCurrentVolume;
979 *RootPathName = uniFullPathName;
981 try_return( ntStatus);
985 // This is a DFS link so we need to update the file name and return STATUS_REPARSE to the
986 // system for it to reevaluate it
989 if( FileObject != NULL)
992 ntStatus = AFSProcessDFSLink( pDirEntry,
1001 // This is where we have been re-entered from an NP evaluation call via the BuildBranch()
1005 ntStatus = STATUS_INVALID_PARAMETER;
1008 if( ntStatus != STATUS_SUCCESS &&
1009 ntStatus != STATUS_REPARSE)
1012 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1013 AFS_TRACE_LEVEL_ERROR,
1014 "AFSLocateNameEntry (FO: %08lX) Failed to process DFSLink parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1016 &pDirEntry->NameInformation.FileName,
1017 pCurrentObject->FileId.Cell,
1018 pCurrentObject->FileId.Volume,
1019 pCurrentObject->FileId.Vnode,
1020 pCurrentObject->FileId.Unique,
1024 try_return( ntStatus);
1027 case AFS_FILE_TYPE_UNKNOWN:
1028 case AFS_FILE_TYPE_INVALID:
1032 // Something was not processed ...
1035 try_return( ntStatus = STATUS_ACCESS_DENIED);
1038 } /* end of switch */
1041 // If the parent is not initialized then do it now
1044 if( pCurrentObject->FileType == AFS_FILE_TYPE_DIRECTORY &&
1045 !BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
1048 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1049 AFS_TRACE_LEVEL_VERBOSE,
1050 "AFSLocateNameEntry (FO: %08lX) Enumerating parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1052 &pDirEntry->NameInformation.FileName,
1053 pCurrentObject->FileId.Cell,
1054 pCurrentObject->FileId.Volume,
1055 pCurrentObject->FileId.Vnode,
1056 pCurrentObject->FileId.Unique);
1058 AFSAcquireExcl( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
1061 if( !BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
1064 ntStatus = AFSEnumerateDirectory( AuthGroup,
1068 if( !NT_SUCCESS( ntStatus))
1071 AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
1073 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1074 AFS_TRACE_LEVEL_ERROR,
1075 "AFSLocateNameEntry (FO: %08lX) Failed to enumerate parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1077 &pDirEntry->NameInformation.FileName,
1078 pCurrentObject->FileId.Cell,
1079 pCurrentObject->FileId.Volume,
1080 pCurrentObject->FileId.Vnode,
1081 pCurrentObject->FileId.Unique,
1084 try_return( ntStatus);
1087 SetFlag( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
1090 AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
1092 else if( pCurrentObject->FileType == AFS_FILE_TYPE_FILE)
1095 if( uniPathName.Length > 0)
1098 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1099 AFS_TRACE_LEVEL_ERROR,
1100 "AFSLocateNameEntry (FO: %08lX) Encountered file node %wZ FID %08lX-%08lX-%08lX-%08lX in path processing\n",
1102 &pDirEntry->NameInformation.FileName,
1103 pCurrentObject->FileId.Cell,
1104 pCurrentObject->FileId.Volume,
1105 pCurrentObject->FileId.Vnode,
1106 pCurrentObject->FileId.Unique);
1108 // The proper error code to return would be STATUS_OBJECT_PATH_INVALID because
1109 // one of the components of the path is not a directory. However, returning
1110 // that error prevents IIS 7 and 7.5 from being able to serve data out of AFS.
1111 // Instead IIS insists on treating the target file as if it is a directory containing
1112 // a potential web.config file. NTFS and LanMan return STATUS_OBJECT_PATH_NOT_FOUND.
1113 // AFS will follow suit.
1115 ntStatus = STATUS_OBJECT_PATH_NOT_FOUND;
1120 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1121 AFS_TRACE_LEVEL_VERBOSE,
1122 "AFSLocateNameEntry (FO: %08lX) Returning file %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1124 &pDirEntry->NameInformation.FileName,
1125 pCurrentObject->FileId.Cell,
1126 pCurrentObject->FileId.Volume,
1127 pCurrentObject->FileId.Vnode,
1128 pCurrentObject->FileId.Unique);
1131 // Pass back the directory entries
1134 *ParentDirectoryCB = pParentDirEntry;
1136 *DirectoryCB = pDirEntry;
1138 *VolumeCB = pCurrentVolume;
1140 *RootPathName = uniFullPathName;
1143 try_return( ntStatus);
1147 // If we are at the end of the processing, set our returned information and get out
1150 if( uniPathName.Length == 0)
1153 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1154 AFS_TRACE_LEVEL_VERBOSE,
1155 "AFSLocateNameEntry (FO: %08lX) Completed processing returning %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1157 &pDirEntry->NameInformation.FileName,
1158 pCurrentObject->FileId.Cell,
1159 pCurrentObject->FileId.Volume,
1160 pCurrentObject->FileId.Vnode,
1161 pCurrentObject->FileId.Unique);
1164 // Pass back the directory entries
1167 *ParentDirectoryCB = pParentDirEntry;
1169 *DirectoryCB = pDirEntry;
1171 *VolumeCB = pCurrentVolume;
1173 *RootPathName = uniFullPathName;
1175 try_return( ntStatus);
1179 // We may have returned to the top of the while( TRUE)
1181 if( bSubstituteName &&
1182 uniSearchName.Buffer != NULL)
1185 AFSExFreePoolWithTag( uniSearchName.Buffer, 0);
1187 bSubstituteName = FALSE;
1189 uniSearchName.Length = uniSearchName.MaximumLength = 0;
1190 uniSearchName.Buffer = NULL;
1193 ulSubstituteIndex = 1;
1195 ntStatus = STATUS_SUCCESS;
1198 // Get the next component name
1201 FsRtlDissectName( uniPathName,
1206 // Check for the . and .. in the path
1209 if( RtlCompareUnicodeString( &uniComponentName,
1214 uniPathName = uniRemainingPath;
1219 if( RtlCompareUnicodeString( &uniComponentName,
1224 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1225 AFS_TRACE_LEVEL_VERBOSE,
1226 "AFSLocateNameEntry (FO: %08lX) Backing up entry from %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1228 &pDirEntry->NameInformation.FileName,
1229 pCurrentObject->FileId.Cell,
1230 pCurrentObject->FileId.Volume,
1231 pCurrentObject->FileId.Vnode,
1232 pCurrentObject->FileId.Unique);
1235 // Need to back up one entry in the name array
1237 lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
1239 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1240 AFS_TRACE_LEVEL_VERBOSE,
1241 "AFSLocateNameEntry Decrement4 count on %wZ DE %p Ccb %p Cnt %d\n",
1242 &pDirEntry->NameInformation.FileName,
1247 pDirEntry = AFSBackupEntry( NameArray);
1249 if( pDirEntry == NULL)
1252 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1253 AFS_TRACE_LEVEL_ERROR,
1254 "AFSLocateNameEntry AFSBackupEntry failed\n");
1256 try_return(ntStatus = STATUS_OBJECT_PATH_INVALID);
1259 lCount = InterlockedIncrement( &pDirEntry->OpenReferenceCount);
1261 if( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_ROOT_VOLUME))
1264 pParentDirEntry = NULL;
1269 pParentDirEntry = AFSGetParentEntry( pNameArray);
1271 ASSERT( pParentDirEntry != pDirEntry);
1274 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1275 AFS_TRACE_LEVEL_VERBOSE,
1276 "AFSLocateNameEntry Increment4 count on %wZ DE %p Ccb %p Cnt %d\n",
1277 &pDirEntry->NameInformation.FileName,
1280 pDirEntry->OpenReferenceCount);
1282 uniPathName = uniRemainingPath;
1288 // Update our pointers
1291 pParentDirEntry = pDirEntry;
1295 uniSearchName = uniComponentName;
1297 while( pDirEntry == NULL)
1301 // If the SearchName contains @SYS then we perform the substitution.
1302 // If there is no substitution we give up.
1305 if( !bSubstituteName &&
1306 FsRtlIsNameInExpression( &uniSysName,
1312 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1313 AFS_TRACE_LEVEL_VERBOSE_2,
1314 "AFSLocateNameEntry (FO: %08lX) Processing @SYS substitution for %wZ Index %08lX\n",
1319 ntStatus = AFSSubstituteSysName( &uniComponentName,
1323 if ( NT_SUCCESS( ntStatus))
1326 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1327 AFS_TRACE_LEVEL_VERBOSE_2,
1328 "AFSLocateNameEntry (FO: %08lX) Located substitution %wZ for %wZ Index %08lX\n",
1335 // Go reparse the name again
1338 bSubstituteName = TRUE;
1340 ulSubstituteIndex++; // For the next entry, if needed
1342 continue; // while( pDirEntry == NULL)
1347 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1348 AFS_TRACE_LEVEL_ERROR,
1349 "AFSLocateNameEntry (FO: %08lX) Failed to locate substitute string for %wZ Index %08lX Status %08lX\n",
1355 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
1359 // Pass back the directory entries
1362 *ParentDirectoryCB = pParentDirEntry;
1364 *DirectoryCB = NULL;
1366 *VolumeCB = pCurrentVolume;
1368 if( ComponentName != NULL)
1371 *ComponentName = uniComponentName;
1374 *RootPathName = uniFullPathName;
1378 // We can't possibly have a pDirEntry since the lookup failed
1380 try_return( ntStatus);
1385 // Generate the CRC on the node and perform a case sensitive lookup
1388 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1389 AFS_TRACE_LEVEL_VERBOSE_2,
1390 "AFSLocateNameEntry (FO: %08lX) Searching for entry %wZ case sensitive\n",
1394 ulCRC = AFSGenerateCRC( &uniSearchName,
1397 AFSAcquireShared( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
1400 AFSLocateCaseSensitiveDirEntry( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
1404 if( pDirEntry == NULL)
1408 // Missed so perform a case insensitive lookup
1411 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1412 AFS_TRACE_LEVEL_VERBOSE_2,
1413 "AFSLocateNameEntry (FO: %08lX) Searching for entry %wZ case insensitive\n",
1417 ulCRC = AFSGenerateCRC( &uniSearchName,
1420 AFSLocateCaseInsensitiveDirEntry( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
1424 if( pDirEntry == NULL)
1428 // OK, if this component is a valid short name then try
1429 // a lookup in the short name tree
1432 if( !BooleanFlagOn( pDevExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
1433 RtlIsNameLegalDOS8Dot3( &uniSearchName,
1438 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1439 AFS_TRACE_LEVEL_VERBOSE_2,
1440 "AFSLocateNameEntry (FO: %08lX) Searching for entry %wZ short name\n",
1444 AFSLocateShortNameDirEntry( pParentDirEntry->ObjectInformation->Specific.Directory.ShortNameTree,
1449 if( pDirEntry == NULL)
1453 // If we substituted a name then reset our search name and try again
1456 if( bSubstituteName)
1459 AFSExFreePoolWithTag( uniSearchName.Buffer, 0);
1461 uniSearchName = uniComponentName;
1463 bSubstituteName = FALSE;
1465 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1467 continue; // while( pDirEntry == NULL)
1470 if( uniRemainingPath.Length > 0)
1473 ntStatus = STATUS_OBJECT_PATH_NOT_FOUND;
1478 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
1480 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1481 AFS_TRACE_LEVEL_VERBOSE,
1482 "AFSLocateNameEntry (FO: %08lX) Returning name not found for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1485 pCurrentObject->FileId.Cell,
1486 pCurrentObject->FileId.Volume,
1487 pCurrentObject->FileId.Vnode,
1488 pCurrentObject->FileId.Unique);
1491 // Pass back the directory entries
1494 *ParentDirectoryCB = pParentDirEntry;
1496 *DirectoryCB = NULL;
1498 *VolumeCB = pCurrentVolume;
1500 if( ComponentName != NULL)
1503 *ComponentName = uniComponentName;
1506 *RootPathName = uniFullPathName;
1509 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1512 // Node name not found so get out
1515 try_return( ntStatus); // while( pDirEntry == NULL)
1522 // Here we have a match on the case insensitive lookup for the name. If there
1523 // Is more than one link entry for this node then fail the lookup request
1526 if( !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD) ||
1527 pDirEntry->CaseInsensitiveList.fLink != NULL)
1530 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1532 try_return(ntStatus = STATUS_OBJECT_NAME_COLLISION);
1537 if( pDirEntry != NULL)
1541 // If the verify flag is set on the parent and the current entry is deleted
1542 // revalidate the parent and search again.
1545 if( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED) &&
1546 BooleanFlagOn( pParentDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY))
1549 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1551 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1552 AFS_TRACE_LEVEL_VERBOSE,
1553 "AFSLocateNameEntry (FO: %08lX) Verifying(2) parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1555 &pParentDirEntry->NameInformation.FileName,
1556 pParentDirEntry->ObjectInformation->FileId.Cell,
1557 pParentDirEntry->ObjectInformation->FileId.Volume,
1558 pParentDirEntry->ObjectInformation->FileId.Vnode,
1559 pParentDirEntry->ObjectInformation->FileId.Unique);
1562 // Directory TreeLock should be exclusively held
1565 AFSAcquireExcl( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
1568 ntStatus = AFSVerifyEntry( AuthGroup,
1571 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1573 if( !NT_SUCCESS( ntStatus))
1576 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1577 AFS_TRACE_LEVEL_ERROR,
1578 "AFSLocateNameEntry (FO: %08lX) Failed to verify(2) parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1580 &pParentDirEntry->NameInformation.FileName,
1581 pParentDirEntry->ObjectInformation->FileId.Cell,
1582 pParentDirEntry->ObjectInformation->FileId.Volume,
1583 pParentDirEntry->ObjectInformation->FileId.Vnode,
1584 pParentDirEntry->ObjectInformation->FileId.Unique,
1587 try_return( ntStatus);
1590 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1591 AFS_TRACE_LEVEL_VERBOSE,
1592 "AFSLocateNameEntry (FO: %08lX) Reprocessing component %wZ in parent %wZ\n",
1595 &pParentDirEntry->NameInformation.FileName);
1604 // Increment our dir entry ref count
1607 lCount = InterlockedIncrement( &pDirEntry->OpenReferenceCount);
1609 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1610 AFS_TRACE_LEVEL_VERBOSE,
1611 "AFSLocateNameEntry Increment5 count on %wZ DE %p Ccb %p Cnt %d\n",
1612 &pDirEntry->NameInformation.FileName,
1618 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1620 } // End while( pDirEntry == NULL)
1623 // If we have a dirEntry for this component, perform some basic validation on it
1626 if( pDirEntry != NULL &&
1627 BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
1630 pCurrentObject = pDirEntry->ObjectInformation;
1632 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1633 AFS_TRACE_LEVEL_ERROR,
1634 "AFSLocateNameEntry (FO: %08lX) Deleted entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1636 &pDirEntry->NameInformation.FileName,
1637 pCurrentObject->FileId.Cell,
1638 pCurrentObject->FileId.Volume,
1639 pCurrentObject->FileId.Vnode,
1640 pCurrentObject->FileId.Unique);
1643 // This entry was deleted through the invalidation call back so perform cleanup
1647 pParentObjectInfo = pCurrentObject->ParentObjectInformation;
1649 ASSERT( pParentObjectInfo != NULL);
1651 AFSAcquireExcl( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
1654 AFSAcquireExcl( pCurrentObject->VolumeCB->ObjectInfoTree.TreeLock,
1657 lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
1662 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING|AFS_SUBSYSTEM_CLEANUP_PROCESSING,
1663 AFS_TRACE_LEVEL_VERBOSE,
1664 "AFSLocateNameEntry Deleting dir entry %08lX (%08lX) for %wZ\n",
1667 &pDirEntry->NameInformation.FileName);
1670 // Remove and delete the directory entry from the parent list
1673 AFSDeleteDirEntry( pParentObjectInfo,
1676 AFSAcquireShared( &pCurrentObject->NonPagedInfo->ObjectInfoLock,
1679 if( pCurrentObject->ObjectReferenceCount <= 0)
1682 if( BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_INSERTED_HASH_TREE))
1685 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
1686 AFS_TRACE_LEVEL_VERBOSE,
1687 "AFSLocateNameEntry Removing object %08lX from volume tree\n",
1690 AFSRemoveHashEntry( &pCurrentObject->VolumeCB->ObjectInfoTree.TreeHead,
1691 &pCurrentObject->TreeEntry);
1693 ClearFlag( pCurrentObject->Flags, AFS_OBJECT_INSERTED_HASH_TREE);
1697 AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock);
1702 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1703 AFS_TRACE_LEVEL_VERBOSE,
1704 "AFSLocateNameEntry Setting DELETE flag in dir entry %p for %wZ\n",
1706 &pDirEntry->NameInformation.FileName);
1708 SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
1710 AFSRemoveNameEntry( pParentObjectInfo,
1714 AFSReleaseResource( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
1716 AFSReleaseResource( pCurrentObject->VolumeCB->ObjectInfoTree.TreeLock);
1719 // We deleted the dir entry so check if there is any remaining portion
1720 // of the name to process.
1723 if( uniRemainingPath.Length > 0)
1725 ntStatus = STATUS_OBJECT_PATH_NOT_FOUND;
1730 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
1732 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1733 AFS_TRACE_LEVEL_VERBOSE,
1734 "AFSLocateNameEntry (FO: %08lX) Returning name not found(2) for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1737 pCurrentObject->FileId.Cell,
1738 pCurrentObject->FileId.Volume,
1739 pCurrentObject->FileId.Vnode,
1740 pCurrentObject->FileId.Unique);
1743 // Pass back the directory entries
1746 *ParentDirectoryCB = pParentDirEntry;
1748 *DirectoryCB = NULL;
1750 *VolumeCB = pCurrentVolume;
1752 if( ComponentName != NULL)
1755 *ComponentName = uniComponentName;
1758 *RootPathName = uniFullPathName;
1762 if( ntStatus != STATUS_SUCCESS)
1765 try_return( ntStatus);
1769 // Decrement the previous parent
1772 lCount = InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
1774 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1775 AFS_TRACE_LEVEL_VERBOSE,
1776 "AFSLocateNameEntry Decrement5 count on Parent %wZ DE %p Ccb %p Cnt %d\n",
1777 &pParentDirEntry->NameInformation.FileName,
1783 // If we ended up substituting a name in the component then update
1784 // the full path and update the pointers
1787 if( bSubstituteName)
1790 BOOLEAN bRelativeOpen = FALSE;
1792 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1793 AFS_TRACE_LEVEL_VERBOSE_2,
1794 "AFSLocateNameEntry (FO: %08lX) Substituting %wZ into %wZ Index %08lX\n",
1800 if( FileObject != NULL &&
1801 FileObject->RelatedFileObject != NULL)
1804 bRelativeOpen = TRUE;
1808 // AFSSubstituteNameInPath will replace the uniFullPathName.Buffer
1809 // and free the prior Buffer contents but only if the fourth
1810 // parameter is TRUE.
1813 ntStatus = AFSSubstituteNameInPath( &uniFullPathName,
1818 bAllocatedSymLinkBuffer ||
1821 if( !NT_SUCCESS( ntStatus))
1824 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1825 AFS_TRACE_LEVEL_ERROR,
1826 "AFSLocateNameEntry (FO: %08lX) Failure to substitute %wZ into %wZ Index %08lX Status %08lX\n",
1833 try_return( ntStatus);
1837 // We have substituted a name into the buffer so if we do this again for this
1838 // path, we need to free up the buffer we allocated.
1841 bSubstitutedName = TRUE;
1845 // Update the search parameters
1848 uniPathName = uniRemainingPath;
1851 // Check if the is a SymLink entry but has no Target FileID or Name. In this
1852 // case it might be a DFS Link so let's go and evaluate it to be sure
1855 if( pCurrentObject->FileType == AFS_FILE_TYPE_SYMLINK &&
1856 pCurrentObject->TargetFileId.Vnode == 0 &&
1857 pCurrentObject->TargetFileId.Unique == 0 &&
1858 pDirEntry->NameInformation.TargetName.Length == 0)
1861 ntStatus = AFSValidateSymLink( AuthGroup,
1864 if( !NT_SUCCESS( ntStatus))
1867 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1868 AFS_TRACE_LEVEL_ERROR,
1869 "AFSLocateNameEntry (FO: %08lX) Failed to evaluate possible DFS Link %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1871 &pDirEntry->NameInformation.FileName,
1872 pCurrentObject->FileId.Cell,
1873 pCurrentObject->FileId.Volume,
1874 pCurrentObject->FileId.Vnode,
1875 pCurrentObject->FileId.Unique,
1878 try_return( ntStatus);
1883 // Update the name array
1886 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1887 AFS_TRACE_LEVEL_VERBOSE,
1888 "AFSLocateNameEntry (FO: %08lX) Inserting name array entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1890 &pDirEntry->NameInformation.FileName,
1891 pCurrentObject->FileId.Cell,
1892 pCurrentObject->FileId.Volume,
1893 pCurrentObject->FileId.Vnode,
1894 pCurrentObject->FileId.Unique);
1896 ntStatus = AFSInsertNextElement( pNameArray,
1899 if( !NT_SUCCESS( ntStatus))
1902 try_return( ntStatus);
1908 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1909 AFS_TRACE_LEVEL_VERBOSE,
1910 "AFSLocateNameEntry (FO: %08lX) Completed processing %wZ Status %08lX\n",
1915 if( ( !NT_SUCCESS( ntStatus) &&
1916 ntStatus != STATUS_OBJECT_NAME_NOT_FOUND) ||
1917 ntStatus == STATUS_REPARSE)
1920 if( pDirEntry != NULL)
1923 lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
1925 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1926 AFS_TRACE_LEVEL_VERBOSE,
1927 "AFSLocateNameEntry Decrement6 count on %wZ DE %p Ccb %p Cnt %d\n",
1928 &pDirEntry->NameInformation.FileName,
1933 else if( pParentDirEntry != NULL)
1936 lCount = InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
1938 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1939 AFS_TRACE_LEVEL_VERBOSE,
1940 "AFSLocateNameEntry Decrement7 count on %wZ DE %p Ccb %p Cnt %d\n",
1941 &pParentDirEntry->NameInformation.FileName,
1947 if( bReleaseCurrentVolume)
1950 ASSERT( pCurrentVolume->VolumeReferenceCount > 1);
1952 lCount = InterlockedDecrement( &pCurrentVolume->VolumeReferenceCount);
1954 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
1955 AFS_TRACE_LEVEL_VERBOSE,
1956 "AFSLocateNameEntry Decrement3 count on volume %08lX Cnt %d\n",
1961 if( RootPathName->Buffer != uniFullPathName.Buffer)
1964 AFSExFreePoolWithTag( uniFullPathName.Buffer, 0);
1970 if( *ParentDirectoryCB != NULL)
1973 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1974 AFS_TRACE_LEVEL_VERBOSE,
1975 "AFSLocateNameEntry Count on Parent %wZ DE %p Ccb %p Cnt %d\n",
1976 &(*ParentDirectoryCB)->NameInformation.FileName,
1979 (*ParentDirectoryCB)->OpenReferenceCount);
1982 if( *DirectoryCB != NULL)
1985 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1986 AFS_TRACE_LEVEL_VERBOSE,
1987 "AFSLocateNameEntry Count on %wZ DE %p Ccb %p Cnt %d\n",
1988 &(*DirectoryCB)->NameInformation.FileName,
1991 (*DirectoryCB)->OpenReferenceCount);
1995 if( bSubstituteName &&
1996 uniSearchName.Buffer != NULL)
1999 AFSExFreePoolWithTag( uniSearchName.Buffer, 0);
2007 AFSCreateDirEntry( IN GUID *AuthGroup,
2008 IN AFSObjectInfoCB *ParentObjectInfo,
2009 IN AFSDirectoryCB *ParentDirCB,
2010 IN PUNICODE_STRING FileName,
2011 IN PUNICODE_STRING ComponentName,
2012 IN ULONG Attributes,
2013 IN OUT AFSDirectoryCB **DirEntry)
2016 NTSTATUS ntStatus = STATUS_SUCCESS;
2017 AFSDirectoryCB *pDirNode = NULL, *pExistingDirNode = NULL;
2018 UNICODE_STRING uniShortName;
2019 LARGE_INTEGER liFileSize = {0,0};
2025 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2026 AFS_TRACE_LEVEL_VERBOSE_2,
2027 "AFSCreateDirEntry Creating dir entry in parent %wZ FID %08lX-%08lX-%08lX-%08lX Component %wZ Attribs %08lX\n",
2028 &ParentDirCB->NameInformation.FileName,
2029 ParentObjectInfo->FileId.Cell,
2030 ParentObjectInfo->FileId.Volume,
2031 ParentObjectInfo->FileId.Vnode,
2032 ParentObjectInfo->FileId.Unique,
2037 // OK, before inserting the node into the parent tree, issue
2038 // the request to the service for node creation
2039 // We will need to drop the lock on the parent node since the create
2040 // could cause a callback into the file system to invalidate it's cache
2043 ntStatus = AFSNotifyFileCreate( AuthGroup,
2051 // If the returned status is STATUS_REPARSE then the entry exists
2052 // and we raced, get out.
2054 if( ntStatus == STATUS_REPARSE)
2057 *DirEntry = pDirNode;
2059 try_return( ntStatus = STATUS_SUCCESS);
2062 if( !NT_SUCCESS( ntStatus))
2065 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2066 AFS_TRACE_LEVEL_ERROR,
2067 "AFSCreateDirEntry Failed to create dir entry in parent %wZ FID %08lX-%08lX-%08lX-%08lX Component %wZ Attribs %08lX Status %08lX\n",
2068 &ParentDirCB->NameInformation.FileName,
2069 ParentObjectInfo->FileId.Cell,
2070 ParentObjectInfo->FileId.Volume,
2071 ParentObjectInfo->FileId.Vnode,
2072 ParentObjectInfo->FileId.Unique,
2077 try_return( ntStatus);
2080 AFSAcquireExcl( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2084 // Before attempting to insert the new entry, check if we need to validate the parent
2087 if( BooleanFlagOn( ParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY))
2090 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2091 AFS_TRACE_LEVEL_VERBOSE,
2092 "AFSCreateDirEntry Verifying parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2093 &ParentDirCB->NameInformation.FileName,
2094 ParentObjectInfo->FileId.Cell,
2095 ParentObjectInfo->FileId.Volume,
2096 ParentObjectInfo->FileId.Vnode,
2097 ParentObjectInfo->FileId.Unique);
2099 ntStatus = AFSVerifyEntry( AuthGroup,
2102 if( !NT_SUCCESS( ntStatus))
2105 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2106 AFS_TRACE_LEVEL_ERROR,
2107 "AFSCreateDirEntry Failed to verify parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2108 &ParentDirCB->NameInformation.FileName,
2109 ParentObjectInfo->FileId.Cell,
2110 ParentObjectInfo->FileId.Volume,
2111 ParentObjectInfo->FileId.Vnode,
2112 ParentObjectInfo->FileId.Unique,
2115 AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2117 try_return( ntStatus);
2122 // Check for the entry in the event we raced with some other thread
2125 AFSLocateCaseSensitiveDirEntry( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
2126 (ULONG)pDirNode->CaseSensitiveTreeEntry.HashIndex,
2129 if( pExistingDirNode != NULL)
2131 if (AFSIsEqualFID( &pDirNode->ObjectInformation->FileId,
2132 &pExistingDirNode->ObjectInformation->FileId))
2135 AFSDeleteDirEntry( ParentObjectInfo,
2138 lCount = InterlockedIncrement( &pExistingDirNode->OpenReferenceCount);
2140 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2141 AFS_TRACE_LEVEL_VERBOSE,
2142 "AFSCreateDirEntry Increment count on %wZ DE %p Cnt %d\n",
2143 &pExistingDirNode->NameInformation.FileName,
2147 *DirEntry = pExistingDirNode;
2149 AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2151 try_return( ntStatus = STATUS_SUCCESS);
2157 // Need to tear down this entry and rebuild it below
2160 if( pExistingDirNode->OpenReferenceCount == 0)
2163 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2164 AFS_TRACE_LEVEL_VERBOSE,
2165 "AFSCreateDirEntry Different FIDs - Deleting DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
2167 &pExistingDirNode->NameInformation.FileName,
2168 pExistingDirNode->ObjectInformation->FileId.Cell,
2169 pExistingDirNode->ObjectInformation->FileId.Volume,
2170 pExistingDirNode->ObjectInformation->FileId.Vnode,
2171 pExistingDirNode->ObjectInformation->FileId.Unique,
2172 pDirNode->ObjectInformation->FileId.Cell,
2173 pDirNode->ObjectInformation->FileId.Volume,
2174 pDirNode->ObjectInformation->FileId.Vnode,
2175 pDirNode->ObjectInformation->FileId.Unique);
2177 AFSDeleteDirEntry( ParentObjectInfo,
2183 SetFlag( pExistingDirNode->Flags, AFS_DIR_ENTRY_DELETED);
2185 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2186 AFS_TRACE_LEVEL_VERBOSE,
2187 "AFSCreateDirEntry Different FIDs - Removing DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
2189 &pExistingDirNode->NameInformation.FileName,
2190 pExistingDirNode->ObjectInformation->FileId.Cell,
2191 pExistingDirNode->ObjectInformation->FileId.Volume,
2192 pExistingDirNode->ObjectInformation->FileId.Vnode,
2193 pExistingDirNode->ObjectInformation->FileId.Unique,
2194 pDirNode->ObjectInformation->FileId.Cell,
2195 pDirNode->ObjectInformation->FileId.Volume,
2196 pDirNode->ObjectInformation->FileId.Vnode,
2197 pDirNode->ObjectInformation->FileId.Unique);
2199 AFSRemoveNameEntry( ParentObjectInfo,
2206 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2207 AFS_TRACE_LEVEL_VERBOSE_2,
2208 "AFSCreateDirEntry Inserting dir entry in parent %wZ FID %08lX-%08lX-%08lX-%08lX Component %wZ\n",
2209 &ParentDirCB->NameInformation.FileName,
2210 ParentObjectInfo->FileId.Cell,
2211 ParentObjectInfo->FileId.Volume,
2212 ParentObjectInfo->FileId.Vnode,
2213 ParentObjectInfo->FileId.Unique,
2217 // Insert the directory node
2220 AFSInsertDirectoryNode( ParentObjectInfo,
2224 lCount = InterlockedIncrement( &pDirNode->OpenReferenceCount);
2226 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2227 AFS_TRACE_LEVEL_VERBOSE,
2228 "AFSCreateDirEntry Increment2 count on %wZ DE %p Cnt %d\n",
2229 &pDirNode->NameInformation.FileName,
2234 // Pass back the dir entry
2237 *DirEntry = pDirNode;
2239 AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2250 AFSInsertDirectoryNode( IN AFSObjectInfoCB *ParentObjectInfo,
2251 IN AFSDirectoryCB *DirEntry,
2252 IN BOOLEAN InsertInEnumList)
2260 ASSERT( ExIsResourceAcquiredExclusiveLite( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock));
2263 // Insert the node into the directory node tree
2266 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2267 AFS_TRACE_LEVEL_VERBOSE,
2268 "AFSInsertDirectoryNode Insert DE %p for %wZ Clearing NOT_IN flag\n",
2270 &DirEntry->NameInformation.FileName);
2272 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
2274 if( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead == NULL)
2277 ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = DirEntry;
2279 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2280 AFS_TRACE_LEVEL_VERBOSE,
2281 "AFSInsertDirectoryNode Insert DE %p to head of case sensitive tree for %wZ\n",
2283 &DirEntry->NameInformation.FileName);
2288 AFSInsertCaseSensitiveDirEntry( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
2291 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2292 AFS_TRACE_LEVEL_VERBOSE,
2293 "AFSInsertDirectoryNode Insert DE %p to case sensitive tree for %wZ\n",
2295 &DirEntry->NameInformation.FileName);
2298 if( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead == NULL)
2301 ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = DirEntry;
2303 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
2305 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2306 AFS_TRACE_LEVEL_VERBOSE,
2307 "AFSInsertDirectoryNode Insert DE %p to head of case insensitive tree for %wZ\n",
2309 &DirEntry->NameInformation.FileName);
2314 AFSInsertCaseInsensitiveDirEntry( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
2317 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2318 AFS_TRACE_LEVEL_VERBOSE,
2319 "AFSInsertDirectoryNode Insert DE %p to case insensitive tree for %wZ\n",
2321 &DirEntry->NameInformation.FileName);
2325 // Into the shortname tree
2328 if( DirEntry->Type.Data.ShortNameTreeEntry.HashIndex != 0)
2331 if( ParentObjectInfo->Specific.Directory.ShortNameTree == NULL)
2334 ParentObjectInfo->Specific.Directory.ShortNameTree = DirEntry;
2336 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2337 AFS_TRACE_LEVEL_VERBOSE,
2338 "AFSInsertDirectoryNode Insert DE %p to head of shortname tree for %wZ\n",
2340 &DirEntry->NameInformation.FileName);
2342 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
2347 if( !NT_SUCCESS( AFSInsertShortNameDirEntry( ParentObjectInfo->Specific.Directory.ShortNameTree,
2350 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2351 AFS_TRACE_LEVEL_VERBOSE,
2352 "AFSInsertDirectoryNode Failed to insert DE %p to shortname tree for %wZ\n",
2354 &DirEntry->NameInformation.FileName);
2358 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
2360 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2361 AFS_TRACE_LEVEL_VERBOSE,
2362 "AFSInsertDirectoryNode Insert DE %p to shortname tree for %wZ\n",
2364 &DirEntry->NameInformation.FileName);
2369 if( InsertInEnumList)
2373 // And insert the node into the directory list
2376 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2377 AFS_TRACE_LEVEL_VERBOSE,
2378 "AFSInsertDirectoryNode Inserting entry %08lX %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2380 &DirEntry->NameInformation.FileName,
2381 DirEntry->ObjectInformation->FileId.Cell,
2382 DirEntry->ObjectInformation->FileId.Volume,
2383 DirEntry->ObjectInformation->FileId.Vnode,
2384 DirEntry->ObjectInformation->FileId.Unique);
2386 if( ParentObjectInfo->Specific.Directory.DirectoryNodeListHead == NULL)
2389 ParentObjectInfo->Specific.Directory.DirectoryNodeListHead = DirEntry;
2394 ParentObjectInfo->Specific.Directory.DirectoryNodeListTail->ListEntry.fLink = (void *)DirEntry;
2396 DirEntry->ListEntry.bLink = (void *)ParentObjectInfo->Specific.Directory.DirectoryNodeListTail;
2399 ParentObjectInfo->Specific.Directory.DirectoryNodeListTail = DirEntry;
2401 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST);
2403 lCount = InterlockedIncrement( &ParentObjectInfo->Specific.Directory.DirectoryNodeCount);
2405 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
2406 AFS_TRACE_LEVEL_VERBOSE,
2407 "AFSInsertDirectoryNode Adding entry %wZ Inc Count %d to parent FID %08lX-%08lX-%08lX-%08lX\n",
2408 &DirEntry->NameInformation.FileName,
2410 ParentObjectInfo->FileId.Cell,
2411 ParentObjectInfo->FileId.Volume,
2412 ParentObjectInfo->FileId.Vnode,
2413 ParentObjectInfo->FileId.Unique);
2421 AFSDeleteDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
2422 IN AFSDirectoryCB *DirEntry)
2425 NTSTATUS ntStatus = STATUS_SUCCESS;
2431 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2432 AFS_TRACE_LEVEL_VERBOSE,
2433 "AFSDeleteDirEntry Deleting dir entry in parent %08lX Entry %08lX %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2436 &DirEntry->NameInformation.FileName,
2437 DirEntry->ObjectInformation->FileId.Cell,
2438 DirEntry->ObjectInformation->FileId.Volume,
2439 DirEntry->ObjectInformation->FileId.Vnode,
2440 DirEntry->ObjectInformation->FileId.Unique);
2442 AFSRemoveDirNodeFromParent( ParentObjectInfo,
2447 // Free up the name buffer if it was reallocated
2450 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_RELEASE_NAME_BUFFER))
2453 AFSExFreePoolWithTag( DirEntry->NameInformation.FileName.Buffer, 0);
2456 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER))
2459 AFSExFreePoolWithTag( DirEntry->NameInformation.TargetName.Buffer, 0);
2463 // Dereference the object for this dir entry
2466 ASSERT( DirEntry->ObjectInformation->ObjectReferenceCount > 0);
2468 lCount = AFSObjectInfoDecrement( DirEntry->ObjectInformation);
2470 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2471 AFS_TRACE_LEVEL_VERBOSE,
2472 "AFSDeleteDirEntry Decrement count on object %08lX Cnt %d\n",
2473 DirEntry->ObjectInformation,
2476 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_DELETED))
2479 SetFlag( DirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED);
2482 ExDeleteResourceLite( &DirEntry->NonPaged->Lock);
2484 AFSExFreePoolWithTag( DirEntry->NonPaged, AFS_DIR_ENTRY_NP_TAG);
2487 // Free up the dir entry
2490 AFSExFreePoolWithTag( DirEntry, AFS_DIR_ENTRY_TAG);
2497 AFSRemoveDirNodeFromParent( IN AFSObjectInfoCB *ParentObjectInfo,
2498 IN AFSDirectoryCB *DirEntry,
2499 IN BOOLEAN RemoveFromEnumList)
2502 NTSTATUS ntStatus = STATUS_SUCCESS;
2509 ASSERT( ExIsResourceAcquiredExclusiveLite( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock));
2511 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2512 AFS_TRACE_LEVEL_VERBOSE,
2513 "AFSRemoveDirNodeFromParent Removing DirEntry %08lX %wZ FID %08lX-%08lX-%08lX-%08lX from Parent %08lX\n",
2515 &DirEntry->NameInformation.FileName,
2516 DirEntry->ObjectInformation->FileId.Cell,
2517 DirEntry->ObjectInformation->FileId.Volume,
2518 DirEntry->ObjectInformation->FileId.Vnode,
2519 DirEntry->ObjectInformation->FileId.Unique,
2522 if( !BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
2525 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2526 AFS_TRACE_LEVEL_VERBOSE,
2527 "AFSRemoveDirNodeFromParent Removing DirEntry %08lX name %wZ\n",
2529 &DirEntry->NameInformation.FileName);
2531 AFSRemoveNameEntry( ParentObjectInfo,
2537 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2538 AFS_TRACE_LEVEL_VERBOSE,
2539 "AFSRemoveDirNodeFromParent DE %p for %wZ NOT removing entry due to flag set\n",
2541 &DirEntry->NameInformation.FileName);
2545 if( RemoveFromEnumList &&
2546 BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST))
2550 // And remove the entry from the enumeration list
2553 if( DirEntry->ListEntry.fLink == NULL)
2556 ParentObjectInfo->Specific.Directory.DirectoryNodeListTail = (AFSDirectoryCB *)DirEntry->ListEntry.bLink;
2561 ((AFSDirectoryCB *)DirEntry->ListEntry.fLink)->ListEntry.bLink = DirEntry->ListEntry.bLink;
2564 if( DirEntry->ListEntry.bLink == NULL)
2567 ParentObjectInfo->Specific.Directory.DirectoryNodeListHead = (AFSDirectoryCB *)DirEntry->ListEntry.fLink;
2572 ((AFSDirectoryCB *)DirEntry->ListEntry.bLink)->ListEntry.fLink = DirEntry->ListEntry.fLink;
2575 ASSERT( ParentObjectInfo->Specific.Directory.DirectoryNodeCount > 0);
2577 lCount = InterlockedDecrement( &ParentObjectInfo->Specific.Directory.DirectoryNodeCount);
2579 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST);
2581 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
2582 AFS_TRACE_LEVEL_VERBOSE,
2583 "AFSRemoveDirNodeFromParent Removing entry %wZ Dec Count %d to parent FID %08lX-%08lX-%08lX-%08lX\n",
2584 &DirEntry->NameInformation.FileName,
2586 ParentObjectInfo->FileId.Cell,
2587 ParentObjectInfo->FileId.Volume,
2588 ParentObjectInfo->FileId.Vnode,
2589 ParentObjectInfo->FileId.Unique);
2591 DirEntry->ListEntry.fLink = NULL;
2592 DirEntry->ListEntry.bLink = NULL;
2600 AFSFixupTargetName( IN OUT PUNICODE_STRING FileName,
2601 IN OUT PUNICODE_STRING TargetFileName)
2604 NTSTATUS ntStatus = STATUS_SUCCESS;
2605 UNICODE_STRING uniFileName;
2611 // We will process backwards from the end of the name looking
2612 // for the first \ we encounter
2615 uniFileName.Length = FileName->Length;
2616 uniFileName.MaximumLength = FileName->MaximumLength;
2618 uniFileName.Buffer = FileName->Buffer;
2623 if( uniFileName.Buffer[ (uniFileName.Length/sizeof( WCHAR)) - 1] == L'\\')
2627 // Subtract one more character off of the filename if it is not the root
2630 if( uniFileName.Length > sizeof( WCHAR))
2633 uniFileName.Length -= sizeof( WCHAR);
2637 // Now build up the target name
2640 TargetFileName->Length = FileName->Length - uniFileName.Length;
2643 // If we are not on the root then fixup the name
2646 if( uniFileName.Length > sizeof( WCHAR))
2649 TargetFileName->Length -= sizeof( WCHAR);
2651 TargetFileName->Buffer = &uniFileName.Buffer[ (uniFileName.Length/sizeof( WCHAR)) + 1];
2656 TargetFileName->Buffer = &uniFileName.Buffer[ uniFileName.Length/sizeof( WCHAR)];
2660 // Fixup the passed back filename length
2663 FileName->Length = uniFileName.Length;
2665 TargetFileName->MaximumLength = TargetFileName->Length;
2670 uniFileName.Length -= sizeof( WCHAR);
2678 AFSParseName( IN PIRP Irp,
2680 OUT PUNICODE_STRING FileName,
2681 OUT PUNICODE_STRING ParsedFileName,
2682 OUT PUNICODE_STRING RootFileName,
2683 OUT ULONG *ParseFlags,
2684 OUT AFSVolumeCB **VolumeCB,
2685 OUT AFSDirectoryCB **ParentDirectoryCB,
2686 OUT AFSNameArrayHdr **NameArray)
2689 NTSTATUS ntStatus = STATUS_SUCCESS;
2690 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2691 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2692 UNICODE_STRING uniFullName, uniComponentName, uniRemainingPath;
2694 AFSDirectoryCB *pDirEntry = NULL, *pShareDirEntry = NULL, *pTargetDirEntry = NULL;
2695 USHORT usIndex = 0, usDriveIndex = 0;
2696 AFSCcb *pRelatedCcb = NULL;
2697 AFSNameArrayHdr *pNameArray = NULL, *pRelatedNameArray = NULL;
2698 USHORT usComponentIndex = 0;
2699 USHORT usComponentLength = 0;
2700 AFSVolumeCB *pVolumeCB = NULL;
2701 AFSFcb *pRelatedFcb = NULL;
2702 BOOLEAN bReleaseTreeLock = FALSE;
2703 BOOLEAN bIsAllShare = FALSE;
2710 // Indicate we are opening a root ...
2713 *ParseFlags = AFS_PARSE_FLAG_ROOT_ACCESS;
2715 if( pIrpSp->FileObject->RelatedFileObject != NULL)
2718 pRelatedFcb = (AFSFcb *)pIrpSp->FileObject->RelatedFileObject->FsContext;
2720 pRelatedCcb = (AFSCcb *)pIrpSp->FileObject->RelatedFileObject->FsContext2;
2722 pRelatedNameArray = pRelatedCcb->NameArray;
2724 uniFullName = pIrpSp->FileObject->FileName;
2726 ASSERT( pRelatedFcb != NULL);
2729 // No wild cards in the name
2732 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2733 AFS_TRACE_LEVEL_VERBOSE_2,
2734 "AFSParseName (%08lX) Relative open for %wZ FID %08lX-%08lX-%08lX-%08lX component %wZ\n",
2736 &pRelatedCcb->DirectoryCB->NameInformation.FileName,
2737 pRelatedCcb->DirectoryCB->ObjectInformation->FileId.Cell,
2738 pRelatedCcb->DirectoryCB->ObjectInformation->FileId.Volume,
2739 pRelatedCcb->DirectoryCB->ObjectInformation->FileId.Vnode,
2740 pRelatedCcb->DirectoryCB->ObjectInformation->FileId.Unique,
2743 if( FsRtlDoesNameContainWildCards( &uniFullName))
2746 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2747 AFS_TRACE_LEVEL_ERROR,
2748 "AFSParseName (%08lX) Component %wZ contains wild cards\n",
2752 try_return( ntStatus = STATUS_OBJECT_NAME_INVALID);
2755 pVolumeCB = pRelatedFcb->ObjectInformation->VolumeCB;
2757 pDirEntry = pRelatedCcb->DirectoryCB;
2759 *FileName = pIrpSp->FileObject->FileName;
2762 // Grab the root node while checking state
2765 AFSAcquireShared( pVolumeCB->VolumeLock,
2768 if( BooleanFlagOn( pVolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
2769 BooleanFlagOn( pVolumeCB->Flags, AFS_VOLUME_FLAGS_OFFLINE))
2773 // The volume has been taken off line so fail the access
2776 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2777 AFS_TRACE_LEVEL_ERROR,
2778 "AFSParseName (%08lX) Volume %08lX:%08lX OFFLINE/INVALID\n",
2780 pVolumeCB->ObjectInformation.FileId.Cell,
2781 pVolumeCB->ObjectInformation.FileId.Volume);
2783 AFSReleaseResource( pVolumeCB->VolumeLock);
2785 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
2788 if( BooleanFlagOn( pVolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_VERIFY))
2791 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2792 AFS_TRACE_LEVEL_VERBOSE,
2793 "AFSParseName (%08lX) Verifying root of volume %08lX:%08lX\n",
2795 pVolumeCB->ObjectInformation.FileId.Cell,
2796 pVolumeCB->ObjectInformation.FileId.Volume);
2798 ntStatus = AFSVerifyVolume( (ULONGLONG)PsGetCurrentProcessId(),
2801 if( !NT_SUCCESS( ntStatus))
2804 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2805 AFS_TRACE_LEVEL_ERROR,
2806 "AFSParseName (%08lX) Failed verification of root Status %08lX\n",
2810 AFSReleaseResource( pVolumeCB->VolumeLock);
2812 try_return( ntStatus);
2816 AFSReleaseResource( pVolumeCB->VolumeLock);
2818 if( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY))
2821 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2822 AFS_TRACE_LEVEL_VERBOSE,
2823 "AFSParseName (%08lX) Verifying parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2825 &pDirEntry->NameInformation.FileName,
2826 pDirEntry->ObjectInformation->FileId.Cell,
2827 pDirEntry->ObjectInformation->FileId.Volume,
2828 pDirEntry->ObjectInformation->FileId.Vnode,
2829 pDirEntry->ObjectInformation->FileId.Unique);
2832 // Directory TreeLock should be exclusively held
2835 AFSAcquireExcl( pDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
2838 ntStatus = AFSVerifyEntry( AuthGroup,
2841 AFSReleaseResource( pDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
2843 if( !NT_SUCCESS( ntStatus))
2846 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2847 AFS_TRACE_LEVEL_VERBOSE,
2848 "AFSParseName (%08lX) Failed verification of parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2850 &pDirEntry->NameInformation.FileName,
2851 pDirEntry->ObjectInformation->FileId.Cell,
2852 pDirEntry->ObjectInformation->FileId.Volume,
2853 pDirEntry->ObjectInformation->FileId.Vnode,
2854 pDirEntry->ObjectInformation->FileId.Unique,
2857 try_return( ntStatus);
2862 // Create our full path name buffer
2865 uniFullName.MaximumLength = pRelatedCcb->FullFileName.Length +
2867 pIrpSp->FileObject->FileName.Length +
2870 uniFullName.Length = 0;
2872 uniFullName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2873 uniFullName.MaximumLength,
2874 AFS_NAME_BUFFER_THREE_TAG);
2876 if( uniFullName.Buffer == NULL)
2879 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2880 AFS_TRACE_LEVEL_ERROR,
2881 "AFSParseName (%08lX) Failed to allocate full name buffer\n",
2884 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2887 RtlZeroMemory( uniFullName.Buffer,
2888 uniFullName.MaximumLength);
2890 RtlCopyMemory( uniFullName.Buffer,
2891 pRelatedCcb->FullFileName.Buffer,
2892 pRelatedCcb->FullFileName.Length);
2894 uniFullName.Length = pRelatedCcb->FullFileName.Length;
2896 usComponentIndex = (USHORT)(uniFullName.Length/sizeof( WCHAR));
2898 usComponentLength = pIrpSp->FileObject->FileName.Length;
2900 if( uniFullName.Buffer[ (uniFullName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
2901 pIrpSp->FileObject->FileName.Length > 0 &&
2902 pIrpSp->FileObject->FileName.Buffer[ 0] != L'\\' &&
2903 pIrpSp->FileObject->FileName.Buffer[ 0] != L':')
2906 uniFullName.Buffer[ (uniFullName.Length/sizeof( WCHAR))] = L'\\';
2908 uniFullName.Length += sizeof( WCHAR);
2910 usComponentLength += sizeof( WCHAR);
2913 if( pIrpSp->FileObject->FileName.Length > 0)
2916 RtlCopyMemory( &uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)],
2917 pIrpSp->FileObject->FileName.Buffer,
2918 pIr
\epSp->FileObject->FileName.Length);
2920 uniFullName.Length += pIrpSp->FileObject->FileName.Length;
2923 *RootFileName = uniFullName;
2926 // We populate up to the current parent
2929 if( pRelatedNameArray == NULL)
2933 // Init and populate our name array
2936 pNameArray = AFSInitNameArray( NULL,
2939 if( pNameArray == NULL)
2942 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2943 AFS_TRACE_LEVEL_VERBOSE,
2944 "AFSParseName (%08lX) Failed to initialize name array\n",
2947 AFSExFreePoolWithTag( uniFullName.Buffer, 0);
2949 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2952 ntStatus = AFSPopulateNameArray( pNameArray,
2954 pRelatedCcb->DirectoryCB);
2960 // Init and populate our name array
2963 pNameArray = AFSInitNameArray( NULL,
2964 pRelatedNameArray->MaxElementCount);
2966 if( pNameArray == NULL)
2969 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2970 AFS_TRACE_LEVEL_VERBOSE,
2971 "AFSParseName (%08lX) Failed to initialize name array\n",
2974 AFSExFreePoolWithTag( uniFullName.Buffer, 0);
2976 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2979 ntStatus = AFSPopulateNameArrayFromRelatedArray( pNameArray,
2981 pRelatedCcb->DirectoryCB);
2984 if( !NT_SUCCESS( ntStatus))
2987 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2988 AFS_TRACE_LEVEL_VERBOSE,
2989 "AFSParseName (%08lX) Failed to populate name array\n",
2992 AFSExFreePoolWithTag( uniFullName.Buffer, 0);
2994 try_return( ntStatus);
2997 ParsedFileName->Length = usComponentLength;
2998 ParsedFileName->MaximumLength = uniFullName.MaximumLength;
3000 ParsedFileName->Buffer = &uniFullName.Buffer[ usComponentIndex];
3003 // Indicate to caller that RootFileName must be freed
3006 SetFlag( *ParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
3008 *NameArray = pNameArray;
3010 *VolumeCB = pVolumeCB;
3013 // Increment our volume reference count
3016 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
3018 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
3019 AFS_TRACE_LEVEL_VERBOSE,
3020 "AFSParseName Increment count on volume %08lX Cnt %d\n",
3024 *ParentDirectoryCB = pDirEntry;
3026 lCount = InterlockedIncrement( &pDirEntry->OpenReferenceCount);
3028 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3029 AFS_TRACE_LEVEL_VERBOSE,
3030 "AFSParseName Increment1 count on %wZ DE %p Ccb %p Cnt %d\n",
3031 &pDirEntry->NameInformation.FileName,
3036 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3037 AFS_TRACE_LEVEL_VERBOSE_2,
3038 "AFSParseName (%08lX) Returning full name %wZ\n",
3042 try_return( ntStatus);
3046 // No wild cards in the name
3049 uniFullName = pIrpSp->FileObject->FileName;
3051 if( FsRtlDoesNameContainWildCards( &uniFullName) ||
3052 uniFullName.Length < AFSServerName.Length)
3055 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3056 AFS_TRACE_LEVEL_ERROR,
3057 "AFSParseName (%08lX) Name %wZ contains wild cards or too short\n",
3061 try_return( ntStatus = STATUS_OBJECT_NAME_INVALID);
3065 // The name is a fully qualified name. Parse out the server/share names and
3066 // point to the root qualified name
3067 // First thing is to locate the server name
3070 FsRtlDissectName( uniFullName,
3074 uniFullName = uniRemainingPath;
3077 // This component is the server name we are serving
3080 if( RtlCompareUnicodeString( &uniComponentName,
3086 // Drive letter based name?
3089 uniFullName = pIrpSp->FileObject->FileName;
3091 while( usIndex < uniFullName.Length/sizeof( WCHAR))
3094 if( uniFullName.Buffer[ usIndex] == L':')
3097 uniFullName.Buffer = &uniFullName.Buffer[ usIndex + 2];
3099 uniFullName.Length -= (usIndex + 2) * sizeof( WCHAR);
3101 usDriveIndex = usIndex - 1;
3110 // Do we have the right server name now?
3113 FsRtlDissectName( uniFullName,
3117 uniFullName = uniRemainingPath;
3120 // This component is the server name we are serving
3123 if( RtlCompareUnicodeString( &uniComponentName,
3128 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3129 AFS_TRACE_LEVEL_ERROR,
3130 "AFSParseName (%08lX) Name %wZ does not have server name\n",
3132 &pIrpSp->FileObject->FileName);
3134 try_return( ntStatus = STATUS_BAD_NETWORK_NAME);
3138 // Validate this drive letter is actively mapped
3141 if( usDriveIndex > 0 &&
3142 !AFSIsDriveMapped( pIrpSp->FileObject->FileName.Buffer[ usDriveIndex]))
3145 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3146 AFS_TRACE_LEVEL_ERROR,
3147 "AFSParseName (%08lX) Name %wZ contains invalid drive mapping\n",
3149 &pIrpSp->FileObject->FileName);
3151 try_return( ntStatus = STATUS_BAD_NETWORK_NAME);
3155 if( FsRtlDoesNameContainWildCards( &uniFullName))
3158 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3159 AFS_TRACE_LEVEL_ERROR,
3160 "AFSParseName (%08lX) Component %wZ contains wild cards\n",
3164 try_return( ntStatus = STATUS_OBJECT_NAME_INVALID);
3167 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3168 AFS_TRACE_LEVEL_VERBOSE_2,
3169 "AFSParseName (%08lX) Processing full name %wZ\n",
3173 if( uniFullName.Length > 0 &&
3174 uniFullName.Buffer[ (uniFullName.Length/sizeof( WCHAR)) - 1] == L'\\')
3177 uniFullName.Length -= sizeof( WCHAR);
3181 // Be sure we are online and ready to go
3184 AFSAcquireShared( AFSGlobalRoot->VolumeLock,
3187 if( BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
3188 BooleanFlagOn( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE))
3192 // The volume has been taken off line so fail the access
3195 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3196 AFS_TRACE_LEVEL_ERROR,
3197 "AFSParseName (%08lX) Volume %08lX:%08lX OFFLINE/INVALID\n",
3199 AFSGlobalRoot->ObjectInformation.FileId.Cell,
3200 AFSGlobalRoot->ObjectInformation.FileId.Volume);
3202 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3204 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
3207 if( BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_VERIFY))
3210 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3211 AFS_TRACE_LEVEL_VERBOSE,
3212 "AFSParseName (%08lX) Verifying root of volume %08lX:%08lX\n",
3214 AFSGlobalRoot->ObjectInformation.FileId.Cell,
3215 AFSGlobalRoot->ObjectInformation.FileId.Volume);
3217 ntStatus = AFSVerifyVolume( (ULONGLONG)PsGetCurrentProcessId(),
3220 if( !NT_SUCCESS( ntStatus))
3223 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3224 AFS_TRACE_LEVEL_ERROR,
3225 "AFSParseName (%08lX) Failed verification of root Status %08lX\n",
3229 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3231 try_return( ntStatus);
3235 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3237 if( !BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
3240 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3241 AFS_TRACE_LEVEL_VERBOSE,
3242 "AFSParseName (%08lX) Enumerating global root of volume %08lX:%08lX\n",
3244 AFSGlobalRoot->ObjectInformation.FileId.Cell,
3245 AFSGlobalRoot->ObjectInformation.FileId.Volume);
3247 ntStatus = AFSEnumerateGlobalRoot( AuthGroup);
3249 if( !NT_SUCCESS( ntStatus))
3252 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3253 AFS_TRACE_LEVEL_ERROR,
3254 "AFSParseName (%08lX) Failed enumeraiton of root Status %08lX\n",
3258 try_return( ntStatus);
3263 // Check for the \\Server access and return it as though it where \\Server\Globalroot
3266 if( uniRemainingPath.Buffer == NULL ||
3267 ( uniRemainingPath.Length == sizeof( WCHAR) &&
3268 uniRemainingPath.Buffer[ 0] == L'\\'))
3271 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3272 AFS_TRACE_LEVEL_VERBOSE_2,
3273 "AFSParseName (%08lX) Returning global root access\n",
3276 lCount = InterlockedIncrement( &AFSGlobalRoot->DirectoryCB->OpenReferenceCount);
3278 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3279 AFS_TRACE_LEVEL_VERBOSE,
3280 "AFSParseName Increment2 count on %wZ DE %p Ccb %p Cnt %d\n",
3281 &AFSGlobalRoot->DirectoryCB->NameInformation.FileName,
3282 AFSGlobalRoot->DirectoryCB,
3288 FileName->Length = 0;
3289 FileName->MaximumLength = 0;
3290 FileName->Buffer = NULL;
3292 try_return( ntStatus = STATUS_SUCCESS);
3295 *RootFileName = uniFullName;
3298 // Include the starting \ in the root name
3301 if( RootFileName->Buffer[ 0] != L'\\')
3303 RootFileName->Buffer--;
3304 RootFileName->Length += sizeof( WCHAR);
3305 RootFileName->MaximumLength += sizeof( WCHAR);
3309 // Get the 'share' name
3312 FsRtlDissectName( uniFullName,
3316 if( FsRtlDoesNameContainWildCards( &uniFullName))
3319 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3320 AFS_TRACE_LEVEL_ERROR,
3321 "AFSParseName (%08lX) Component %wZ contains wild cards\n",
3325 try_return( ntStatus = STATUS_OBJECT_NAME_INVALID);
3329 // If this is the ALL access then perform some additional processing
3332 if( uniComponentName.Length == 0 ||
3333 RtlCompareUnicodeString( &uniComponentName,
3341 // If there is nothing else then get out
3344 if( uniRemainingPath.Buffer == NULL ||
3345 uniRemainingPath.Length == 0 ||
3346 ( uniRemainingPath.Length == sizeof( WCHAR) &&
3347 uniRemainingPath.Buffer[ 0] == L'\\'))
3350 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3351 AFS_TRACE_LEVEL_VERBOSE_2,
3352 "AFSParseName (%08lX) Returning global root access\n",
3355 lCount = InterlockedIncrement( &AFSGlobalRoot->DirectoryCB->OpenReferenceCount);
3357 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3358 AFS_TRACE_LEVEL_VERBOSE,
3359 "AFSParseName Increment3 count on %wZ DE %p Ccb %p Cnt %d\n",
3360 &AFSGlobalRoot->DirectoryCB->NameInformation.FileName,
3361 AFSGlobalRoot->DirectoryCB,
3367 FileName->Length = 0;
3368 FileName->MaximumLength = 0;
3369 FileName->Buffer = NULL;
3371 try_return( ntStatus = STATUS_SUCCESS);
3375 // Process the name again to strip off the ALL portion
3378 uniFullName = uniRemainingPath;
3380 FsRtlDissectName( uniFullName,
3385 // Check for the PIOCtl name
3388 if( RtlCompareUnicodeString( &uniComponentName,
3393 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3394 AFS_TRACE_LEVEL_VERBOSE_2,
3395 "AFSParseName (%08lX) Returning root PIOCtl access\n",
3398 lCount = InterlockedIncrement( &AFSGlobalRoot->DirectoryCB->OpenReferenceCount);
3400 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3401 AFS_TRACE_LEVEL_VERBOSE,
3402 "AFSParseName Increment4 count on %wZ DE %p Ccb %p Cnt %d\n",
3403 &AFSGlobalRoot->DirectoryCB->NameInformation.FileName,
3404 AFSGlobalRoot->DirectoryCB,
3408 ClearFlag( *ParseFlags, AFS_PARSE_FLAG_ROOT_ACCESS);
3412 *FileName = AFSPIOCtlName;
3414 try_return( ntStatus = STATUS_SUCCESS);
3417 else if( (pDirEntry = AFSGetSpecialShareNameEntry( &uniComponentName,
3418 &uniRemainingPath)) != NULL)
3421 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3422 AFS_TRACE_LEVEL_VERBOSE_2,
3423 "AFSParseName (%08lX) Returning root share name %wZ access\n",
3428 // Add in the full share name to pass back
3431 if( uniRemainingPath.Buffer != NULL)
3435 // This routine strips off the leading slash so add it back in
3438 uniRemainingPath.Buffer--;
3439 uniRemainingPath.Length += sizeof( WCHAR);
3440 uniRemainingPath.MaximumLength += sizeof( WCHAR);
3443 // And the cell name
3446 uniRemainingPath.Buffer -= (uniComponentName.Length/sizeof( WCHAR));
3447 uniRemainingPath.Length += uniComponentName.Length;
3448 uniRemainingPath.MaximumLength += uniComponentName.Length;
3450 uniComponentName = uniRemainingPath;
3455 *FileName = uniComponentName;
3457 *ParentDirectoryCB = pDirEntry;
3459 ClearFlag( *ParseFlags, AFS_PARSE_FLAG_ROOT_ACCESS);
3461 lCount = InterlockedIncrement( &pDirEntry->OpenReferenceCount);
3463 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3464 AFS_TRACE_LEVEL_VERBOSE,
3465 "AFSParseName Increment5 count on %wZ DE %p Ccb %p Cnt %d\n",
3466 &pDirEntry->NameInformation.FileName,
3471 try_return( ntStatus = STATUS_SUCCESS);
3475 // Determine the 'share' we are accessing
3478 ulCRC = AFSGenerateCRC( &uniComponentName,
3481 AFSAcquireShared( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
3484 bReleaseTreeLock = TRUE;
3486 AFSLocateCaseSensitiveDirEntry( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
3490 if( pDirEntry == NULL)
3493 ulCRC = AFSGenerateCRC( &uniComponentName,
3496 AFSLocateCaseInsensitiveDirEntry( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
3500 if( pDirEntry == NULL)
3504 // OK, if this component is a valid short name then try
3505 // a lookup in the short name tree
3508 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
3509 RtlIsNameLegalDOS8Dot3( &uniComponentName,
3514 AFSLocateShortNameDirEntry( AFSGlobalRoot->ObjectInformation.Specific.Directory.ShortNameTree,
3519 if( pDirEntry == NULL)
3523 // Check with the service whether it is a valid cell name
3526 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
3528 bReleaseTreeLock = FALSE;
3530 ntStatus = AFSCheckCellName( AuthGroup,
3534 if( !NT_SUCCESS( ntStatus))
3538 uniRemainingPath.Length == 0 &&
3539 ntStatus == STATUS_OBJECT_PATH_NOT_FOUND)
3542 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
3545 try_return( ntStatus);
3551 if( bReleaseTreeLock)
3553 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
3558 // Be sure we are starting from the correct volume
3561 if( pDirEntry->ObjectInformation->VolumeCB != AFSGlobalRoot)
3565 // We dropped the global root in the CheckCellName routine which is the
3566 // only way we can be here
3569 pVolumeCB = pDirEntry->ObjectInformation->VolumeCB;
3572 // Init our name array
3575 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
3578 if( pNameArray == NULL)
3581 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3582 AFS_TRACE_LEVEL_VERBOSE,
3583 "AFSParseName (%08lX) Failed to initialize name array\n",
3586 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3589 ntStatus = AFSInsertNextElement( pNameArray,
3590 pVolumeCB->DirectoryCB);
3595 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3596 AFS_TRACE_LEVEL_VERBOSE,
3597 "AFSParseName (%08lX) Failed to insert name array element\n",
3600 try_return( ntStatus);
3604 // In this case don't add back in the 'share' name since that is where we are
3605 // starting. Just put the leading slash back in
3608 if( uniRemainingPath.Buffer != NULL)
3611 uniRemainingPath.Buffer--;
3612 uniRemainingPath.Length += sizeof( WCHAR);
3613 uniRemainingPath.MaximumLength += sizeof( WCHAR);
3615 if( uniRemainingPath.Length > sizeof( WCHAR))
3618 ClearFlag( *ParseFlags, AFS_PARSE_FLAG_ROOT_ACCESS);
3622 // Pass back the parent being the root of the volume
3625 *ParentDirectoryCB = pVolumeCB->DirectoryCB;
3631 // Pass back a root slash
3634 uniRemainingPath = uniComponentName;
3636 uniRemainingPath.Buffer--;
3637 uniRemainingPath.Length = sizeof( WCHAR);
3638 uniRemainingPath.MaximumLength = sizeof( WCHAR);
3641 // This is a root open so pass back no parent
3644 *ParentDirectoryCB = NULL;
3650 pVolumeCB = AFSGlobalRoot;
3653 // Init our name array
3656 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
3658 if( pNameArray == NULL)
3661 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3662 AFS_TRACE_LEVEL_VERBOSE,
3663 "AFSParseName (%08lX) Failed to initialize name array\n",
3666 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3670 // Add back in the 'share' portion of the name since we will parse it out on return
3673 if( uniRemainingPath.Buffer != NULL)
3677 // This routine strips off the leading slash so add it back in
3680 uniRemainingPath.Buffer--;
3681 uniRemainingPath.Length += sizeof( WCHAR);
3682 uniRemainingPath.MaximumLength += sizeof( WCHAR);
3684 if( uniRemainingPath.Length > sizeof( WCHAR))
3687 ClearFlag( *ParseFlags, AFS_PARSE_FLAG_ROOT_ACCESS);
3691 // And the cell name
3694 uniRemainingPath.Buffer -= (uniComponentName.Length/sizeof( WCHAR));
3695 uniRemainingPath.Length += uniComponentName.Length;
3696 uniRemainingPath.MaximumLength += uniComponentName.Length;
3701 uniRemainingPath = uniComponentName;
3705 // And the leading slash again ...
3708 uniRemainingPath.Buffer--;
3709 uniRemainingPath.Length += sizeof( WCHAR);
3710 uniRemainingPath.MaximumLength += sizeof( WCHAR);
3712 lCount = InterlockedIncrement( &pVolumeCB->DirectoryCB->OpenReferenceCount);
3714 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3715 AFS_TRACE_LEVEL_VERBOSE,
3716 "AFSParseName Increment6 count on %wZ DE %p Ccb %p Cnt %d\n",
3717 &pVolumeCB->DirectoryCB->NameInformation.FileName,
3718 pVolumeCB->DirectoryCB,
3720 lCount = pVolumeCB->DirectoryCB->OpenReferenceCount);
3723 // Pass back the parent being the volume root
3726 *ParentDirectoryCB = pVolumeCB->DirectoryCB;
3731 // Return the remaining portion as the file name
3734 *FileName = uniRemainingPath;
3736 *ParsedFileName = uniRemainingPath;
3738 *NameArray = pNameArray;
3740 *VolumeCB = pVolumeCB;
3743 // Increment our reference on the volume
3746 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
3748 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
3749 AFS_TRACE_LEVEL_VERBOSE,
3750 "AFSParseName Increment2 count on global volume %08lX Cnt %d\n",
3756 if( NT_SUCCESS( ntStatus))
3759 if( *ParentDirectoryCB != NULL)
3762 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3763 AFS_TRACE_LEVEL_VERBOSE,
3764 "AFSParseName Count on %wZ DE %p Ccb %p Cnt %d\n",
3765 &(*ParentDirectoryCB)->NameInformation.FileName,
3768 (*ParentDirectoryCB)->OpenReferenceCount);
3772 if( *VolumeCB != NULL)
3774 ASSERT( (*VolumeCB)->VolumeReferenceCount > 1);
3777 if( ntStatus != STATUS_SUCCESS)
3780 if( pNameArray != NULL)
3783 AFSFreeNameArray( pNameArray);
3792 AFSCheckCellName( IN GUID *AuthGroup,
3793 IN UNICODE_STRING *CellName,
3794 OUT AFSDirectoryCB **ShareDirEntry)
3797 NTSTATUS ntStatus = STATUS_SUCCESS;
3798 UNICODE_STRING uniName;
3799 AFSDirEnumEntry *pDirEnumEntry = NULL;
3800 AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
3801 AFSDirHdr *pDirHdr = &AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr;
3802 AFSDirectoryCB *pDirNode = NULL;
3803 UNICODE_STRING uniDirName, uniTargetName;
3804 AFSVolumeCB *pVolumeCB = NULL;
3811 // Look for some default names we will not handle
3814 RtlInitUnicodeString( &uniName,
3817 if( RtlCompareUnicodeString( &uniName,
3822 try_return( ntStatus = STATUS_NO_SUCH_FILE);
3825 RtlInitUnicodeString( &uniName,
3828 if( RtlCompareUnicodeString( &uniName,
3833 try_return( ntStatus = STATUS_NO_SUCH_FILE);
3836 RtlInitUnicodeString( &uniName,
3839 if( RtlCompareUnicodeString( &uniName,
3844 try_return( ntStatus = STATUS_NO_SUCH_FILE);
3847 RtlInitUnicodeString( &uniName,
3850 if( RtlCompareUnicodeString( &uniName,
3855 try_return( ntStatus = STATUS_NO_SUCH_FILE);
3859 // OK, ask the CM about this component name
3862 ntStatus = AFSEvaluateTargetByName( AuthGroup,
3863 &AFSGlobalRoot->ObjectInformation,
3867 if( !NT_SUCCESS( ntStatus))
3870 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3871 AFS_TRACE_LEVEL_WARNING,
3872 "AFSCheckCellName entry %wZ does not exist parent FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
3874 AFSGlobalRoot->ObjectInformation.FileId.Cell,
3875 AFSGlobalRoot->ObjectInformation.FileId.Volume,
3876 AFSGlobalRoot->ObjectInformation.FileId.Vnode,
3877 AFSGlobalRoot->ObjectInformation.FileId.Unique,
3880 try_return( ntStatus);
3884 // OK, we have a dir enum entry back so add it to the root node
3887 uniDirName = *CellName;
3889 uniTargetName.Length = (USHORT)pDirEnumEntry->TargetNameLength;
3890 uniTargetName.MaximumLength = uniTargetName.Length;
3891 uniTargetName.Buffer = (WCHAR *)((char *)pDirEnumEntry + pDirEnumEntry->TargetNameOffset);
3894 // Is this entry a root volume entry?
3897 if( pDirEnumEntry->FileId.Cell != AFSGlobalRoot->ObjectInformation.FileId.Cell ||
3898 pDirEnumEntry->FileId.Volume != AFSGlobalRoot->ObjectInformation.FileId.Volume)
3902 // Build the root volume entry
3905 ntStatus = AFSBuildRootVolume( AuthGroup,
3906 &pDirEnumEntry->FileId,
3909 if( !NT_SUCCESS( ntStatus))
3911 try_return( ntStatus);
3914 *ShareDirEntry = pVolumeCB->DirectoryCB;
3916 lCount = InterlockedIncrement( &pVolumeCB->DirectoryCB->OpenReferenceCount);
3918 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3919 AFS_TRACE_LEVEL_VERBOSE,
3920 "AFSCheckCellName Increment1 count on %wZ DE %p Ccb %p Cnt %d\n",
3921 &pVolumeCB->DirectoryCB->NameInformation.FileName,
3922 pVolumeCB->DirectoryCB,
3926 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
3931 lCount = InterlockedIncrement( &pDirHdr->ContentIndex);
3933 pDirNode = AFSInitDirEntry( &AFSGlobalRoot->ObjectInformation,
3939 if( pDirNode == NULL)
3942 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3946 // Init the short name if we have one
3949 if( pDirEnumEntry->ShortNameLength > 0)
3952 pDirNode->NameInformation.ShortNameLength = pDirEnumEntry->ShortNameLength;
3954 RtlCopyMemory( pDirNode->NameInformation.ShortName,
3955 pDirEnumEntry->ShortName,
3956 pDirNode->NameInformation.ShortNameLength);
3959 AFSAcquireExcl( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
3963 // Insert the node into the name tree
3966 ASSERT( ExIsResourceAcquiredExclusiveLite( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock));
3968 if( pDirHdr->CaseSensitiveTreeHead == NULL)
3971 pDirHdr->CaseSensitiveTreeHead = pDirNode;
3976 if( !NT_SUCCESS( AFSInsertCaseSensitiveDirEntry( pDirHdr->CaseSensitiveTreeHead,
3980 AFSDeleteDirEntry( &AFSGlobalRoot->ObjectInformation,
3983 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
3985 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3989 ClearFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
3991 if( pDirHdr->CaseInsensitiveTreeHead == NULL)
3994 pDirHdr->CaseInsensitiveTreeHead = pDirNode;
3996 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
4001 AFSInsertCaseInsensitiveDirEntry( pDirHdr->CaseInsensitiveTreeHead,
4005 if( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListHead == NULL)
4008 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListHead = pDirNode;
4013 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListTail->ListEntry.fLink = pDirNode;
4015 pDirNode->ListEntry.bLink = AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListTail;
4018 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListTail = pDirNode;
4020 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST);
4022 lCount = InterlockedIncrement( &AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeCount);
4024 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
4025 AFS_TRACE_LEVEL_VERBOSE,
4026 "AFSCheckCellName Adding entry %wZ Inc Count %d to parent FID %08lX-%08lX-%08lX-%08lX\n",
4027 &pDirNode->NameInformation.FileName,
4029 AFSGlobalRoot->ObjectInformation.FileId.Cell,
4030 AFSGlobalRoot->ObjectInformation.FileId.Volume,
4031 AFSGlobalRoot->ObjectInformation.FileId.Vnode,
4032 AFSGlobalRoot->ObjectInformation.FileId.Unique);
4034 lCount = InterlockedIncrement( &pDirNode->OpenReferenceCount);
4036 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
4037 AFS_TRACE_LEVEL_VERBOSE,
4038 "AFSCheckCellName Increment2 count on %wZ DE %p Ccb %p Cnt %d\n",
4039 &pDirNode->NameInformation.FileName,
4044 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
4047 // Pass back the dir node
4050 *ShareDirEntry = pDirNode;
4055 if( pDirEnumEntry != NULL)
4058 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_31_TAG);
4066 AFSBuildMountPointTarget( IN GUID *AuthGroup,
4067 IN AFSDirectoryCB *DirectoryCB,
4068 OUT AFSVolumeCB **TargetVolumeCB)
4071 NTSTATUS ntStatus = STATUS_SUCCESS;
4072 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
4073 AFSDirEnumEntry *pDirEntry = NULL;
4074 AFSDirectoryCB *pDirNode = NULL;
4075 UNICODE_STRING uniDirName, uniTargetName;
4076 ULONGLONG ullIndex = 0;
4077 AFSVolumeCB *pVolumeCB = NULL;
4078 AFSFileID stTargetFileID;
4080 BOOLEAN bReleaseVolumeLock = FALSE;
4086 // Loop on each entry, building the chain until we encounter the final target
4089 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4090 AFS_TRACE_LEVEL_VERBOSE_2,
4091 "AFSBuildMountPointTarget Building target directory for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4092 &DirectoryCB->NameInformation.FileName,
4093 DirectoryCB->ObjectInformation->FileId.Cell,
4094 DirectoryCB->ObjectInformation->FileId.Volume,
4095 DirectoryCB->ObjectInformation->FileId.Vnode,
4096 DirectoryCB->ObjectInformation->FileId.Unique);
4099 // Do we need to evaluate the node?
4102 //if( DirectoryCB->ObjectInformation->TargetFileId.Vnode == 0 &&
4103 // DirectoryCB->ObjectInformation->TargetFileId.Unique == 0)
4107 // Go evaluate the current target to get the target fid
4110 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4111 AFS_TRACE_LEVEL_VERBOSE_2,
4112 "AFSBuildMountPointTarget Evaluating target %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4113 &DirectoryCB->NameInformation.FileName,
4114 DirectoryCB->ObjectInformation->FileId.Cell,
4115 DirectoryCB->ObjectInformation->FileId.Volume,
4116 DirectoryCB->ObjectInformation->FileId.Vnode,
4117 DirectoryCB->ObjectInformation->FileId.Unique);
4119 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
4124 if( !NT_SUCCESS( ntStatus))
4127 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4128 AFS_TRACE_LEVEL_ERROR,
4129 "AFSBuildMountPointTarget Failed to evaluate target %wZ Status %08lX\n",
4130 &DirectoryCB->NameInformation.FileName,
4132 try_return( ntStatus);
4135 if( pDirEntry->TargetFileId.Vnode == 0 &&
4136 pDirEntry->TargetFileId.Unique == 0)
4139 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4140 AFS_TRACE_LEVEL_ERROR,
4141 "AFSBuildMountPointTarget Target %wZ FID %08lX-%08lX-%08lX-%08lX service returned zero FID\n",
4142 &DirectoryCB->NameInformation.FileName,
4143 DirectoryCB->ObjectInformation->FileId.Cell,
4144 DirectoryCB->ObjectInformation->FileId.Volume,
4145 DirectoryCB->ObjectInformation->FileId.Vnode,
4146 DirectoryCB->ObjectInformation->FileId.Unique);
4148 try_return( ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED);
4151 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
4154 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
4155 &DirectoryCB->Flags,
4156 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
4157 (USHORT)pDirEntry->TargetNameLength);
4159 if( !NT_SUCCESS( ntStatus))
4162 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
4164 try_return( ntStatus);
4167 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
4169 DirectoryCB->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
4172 stTargetFileID = DirectoryCB->ObjectInformation->TargetFileId;
4175 // Try to locate this FID. First the volume then the
4179 ullIndex = AFSCreateHighIndex( &stTargetFileID);
4181 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4182 AFS_TRACE_LEVEL_VERBOSE,
4183 "AFSBuildMountPointTarget Acquiring RDR VolumeTreeLock lock %08lX EXCL %08lX\n",
4184 &pDevExt->Specific.RDR.VolumeTreeLock,
4185 PsGetCurrentThread());
4187 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock,
4190 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4191 AFS_TRACE_LEVEL_VERBOSE_2,
4192 "AFSBuildMountPointTarget Locating volume for target %I64X\n",
4195 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
4197 (AFSBTreeEntry **)&pVolumeCB);
4200 // We can be processing a request for a target that is on a volume
4201 // we have never seen before.
4204 if( pVolumeCB == NULL)
4208 // Locking is held correctly in init routine
4211 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
4214 // Go init the root of the volume
4217 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4218 AFS_TRACE_LEVEL_VERBOSE_2,
4219 "AFSBuildMountPointTarget Initializing root for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4220 &DirectoryCB->NameInformation.FileName,
4221 DirectoryCB->ObjectInformation->FileId.Cell,
4222 DirectoryCB->ObjectInformation->FileId.Volume,
4223 DirectoryCB->ObjectInformation->FileId.Vnode,
4224 DirectoryCB->ObjectInformation->FileId.Unique);
4226 ntStatus = AFSInitVolume( AuthGroup,
4230 if( !NT_SUCCESS( ntStatus))
4233 try_return( ntStatus);
4237 // pVolumeCB->VolumeLock held exclusive and
4238 // pVolumeCB->VolumeReferenceCount has been incremented
4239 // pVolumeCB->RootFcb == NULL
4242 bReleaseVolumeLock = TRUE;
4248 // AFSInitVolume returns with a VolumeReferenceCount
4249 // obtain one to match
4252 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
4254 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
4255 AFS_TRACE_LEVEL_VERBOSE,
4256 "AFSBuildMountPointTarget Increment count on volume %08lX Cnt %d\n",
4260 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
4263 if( pVolumeCB->RootFcb == NULL)
4266 if ( bReleaseVolumeLock == FALSE)
4269 AFSAcquireExcl( pVolumeCB->VolumeLock,
4272 bReleaseVolumeLock = TRUE;
4276 // Initialize the root fcb for this volume
4279 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
4282 if( !NT_SUCCESS( ntStatus))
4285 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
4287 AFSReleaseResource( pVolumeCB->VolumeLock);
4289 try_return( ntStatus);
4293 // Drop the lock acquired above
4296 AFSReleaseResource( &pVolumeCB->RootFcb->NPFcb->Resource);
4299 if ( bReleaseVolumeLock == TRUE)
4302 AFSReleaseResource( pVolumeCB->VolumeLock);
4305 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4306 AFS_TRACE_LEVEL_VERBOSE_2,
4307 "AFSBuildMountPointTarget Evaluated target of %wZ FID %08lX-%08lX-%08lX-%08lX as root volume\n",
4308 &pVolumeCB->DirectoryCB->NameInformation.FileName,
4309 pVolumeCB->ObjectInformation.FileId.Cell,
4310 pVolumeCB->ObjectInformation.FileId.Volume,
4311 pVolumeCB->ObjectInformation.FileId.Vnode,
4312 pVolumeCB->ObjectInformation.FileId.Unique);
4314 *TargetVolumeCB = pVolumeCB;
4321 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
4329 AFSBuildRootVolume( IN GUID *AuthGroup,
4330 IN AFSFileID *FileId,
4331 OUT AFSVolumeCB **TargetVolumeCB)
4334 NTSTATUS ntStatus = STATUS_SUCCESS;
4335 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
4336 AFSDirectoryCB *pDirNode = NULL;
4337 UNICODE_STRING uniDirName, uniTargetName;
4338 ULONGLONG ullIndex = 0;
4339 AFSVolumeCB *pVolumeCB = NULL;
4341 BOOLEAN bReleaseVolumeLock = FALSE;
4346 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4347 AFS_TRACE_LEVEL_VERBOSE_2,
4348 "AFSBuildRootVolume Building target volume for FID %08lX-%08lX-%08lX-%08lX\n",
4354 ullIndex = AFSCreateHighIndex( FileId);
4356 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4357 AFS_TRACE_LEVEL_VERBOSE,
4358 "AFSBuildRootVolume Acquiring RDR VolumeTreeLock lock %08lX EXCL %08lX\n",
4359 &pDevExt->Specific.RDR.VolumeTreeLock,
4360 PsGetCurrentThread());
4362 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock,
4365 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4366 AFS_TRACE_LEVEL_VERBOSE_2,
4367 "AFSBuildRootVolume Locating volume for target %I64X\n",
4370 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
4372 (AFSBTreeEntry **)&pVolumeCB);
4375 // We can be processing a request for a target that is on a volume
4376 // we have never seen before.
4379 if( pVolumeCB == NULL)
4383 // Locking is held correctly in init routine
4386 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
4389 // Go init the root of the volume
4392 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4393 AFS_TRACE_LEVEL_VERBOSE_2,
4394 "AFSBuildRootVolume Initializing root for FID %08lX-%08lX-%08lX-%08lX\n",
4400 ntStatus = AFSInitVolume( AuthGroup,
4404 if( !NT_SUCCESS( ntStatus))
4407 try_return( ntStatus);
4411 // pVolumeCB->VolumeLock is held exclusive
4412 // pVolumeCB->VolumeReferenceCount has been incremented
4413 // pVolumeCB->RootFcb == NULL
4416 bReleaseVolumeLock = TRUE;
4422 // AFSInitVolume returns with a VolumeReferenceCount
4423 // obtain one to match
4426 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
4428 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
4429 AFS_TRACE_LEVEL_VERBOSE,
4430 "AFSBuildRootVolume Increment count on volume %08lX Cnt %d\n",
4434 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
4438 if( pVolumeCB->RootFcb == NULL)
4441 if ( bReleaseVolumeLock == FALSE)
4444 AFSAcquireExcl( pVolumeCB->VolumeLock,
4447 bReleaseVolumeLock = TRUE;
4451 // Initialize the root fcb for this volume
4454 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
4457 if( !NT_SUCCESS( ntStatus))
4460 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
4462 AFSReleaseResource( pVolumeCB->VolumeLock);
4464 try_return( ntStatus);
4468 // Drop the lock acquired above
4471 AFSReleaseResource( &pVolumeCB->RootFcb->NPFcb->Resource);
4474 if ( bReleaseVolumeLock == TRUE)
4477 AFSReleaseResource( pVolumeCB->VolumeLock);
4480 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4481 AFS_TRACE_LEVEL_VERBOSE_2,
4482 "AFSBuildRootVolume Evaluated target of %wZ FID %08lX-%08lX-%08lX-%08lX as root volume\n",
4483 &pVolumeCB->DirectoryCB->NameInformation.FileName,
4484 pVolumeCB->ObjectInformation.FileId.Cell,
4485 pVolumeCB->ObjectInformation.FileId.Volume,
4486 pVolumeCB->ObjectInformation.FileId.Vnode,
4487 pVolumeCB->ObjectInformation.FileId.Unique);
4489 *TargetVolumeCB = pVolumeCB;
4500 AFSProcessDFSLink( IN AFSDirectoryCB *DirEntry,
4501 IN PFILE_OBJECT FileObject,
4502 IN UNICODE_STRING *RemainingPath,
4506 NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
4507 UNICODE_STRING uniReparseName;
4508 UNICODE_STRING uniMUPDeviceName;
4509 AFSDirEnumEntry *pDirEntry = NULL;
4515 // Build up the name to reparse
4518 RtlInitUnicodeString( &uniMUPDeviceName,
4521 uniReparseName.Length = 0;
4522 uniReparseName.Buffer = NULL;
4525 // Be sure we have a target name
4528 if( DirEntry->NameInformation.TargetName.Length == 0)
4531 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
4536 if( !NT_SUCCESS( ntStatus) ||
4537 pDirEntry->TargetNameLength == 0)
4540 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4541 AFS_TRACE_LEVEL_ERROR,
4542 "AFSProcessDFSLink EvaluateTargetByID failed for Fcb %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4543 &DirEntry->NameInformation.FileName,
4544 DirEntry->ObjectInformation->FileId.Cell,
4545 DirEntry->ObjectInformation->FileId.Volume,
4546 DirEntry->ObjectInformation->FileId.Vnode,
4547 DirEntry->ObjectInformation->FileId.Unique,
4550 if( NT_SUCCESS( ntStatus))
4553 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
4556 try_return( ntStatus);
4560 // Update the target name
4563 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
4566 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
4568 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
4569 (USHORT)pDirEntry->TargetNameLength);
4571 if( !NT_SUCCESS( ntStatus))
4574 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4575 AFS_TRACE_LEVEL_ERROR,
4576 "AFSProcessDFSLink UpdateTargetName failed for Fcb %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4577 &DirEntry->NameInformation.FileName,
4578 DirEntry->ObjectInformation->FileId.Cell,
4579 DirEntry->ObjectInformation->FileId.Volume,
4580 DirEntry->ObjectInformation->FileId.Vnode,
4581 DirEntry->ObjectInformation->FileId.Unique,
4584 AFSReleaseResource( &DirEntry->NonPaged->Lock);
4586 try_return( ntStatus);
4589 AFSConvertToShared( &DirEntry->NonPaged->Lock);
4593 AFSAcquireShared( &DirEntry->NonPaged->Lock,
4597 uniReparseName.MaximumLength = uniMUPDeviceName.Length +
4599 DirEntry->NameInformation.TargetName.Length +
4602 if( RemainingPath != NULL &&
4603 RemainingPath->Length > 0)
4606 uniReparseName.MaximumLength += RemainingPath->Length;
4610 // Allocate the reparse buffer
4613 uniReparseName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
4614 uniReparseName.MaximumLength,
4615 AFS_REPARSE_NAME_TAG);
4617 if( uniReparseName.Buffer == NULL)
4620 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4621 AFS_TRACE_LEVEL_ERROR,
4622 "AFSProcessDFSLink uniReparseName.Buffer == NULL Fcb %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4623 &DirEntry->NameInformation.FileName,
4624 DirEntry->ObjectInformation->FileId.Cell,
4625 DirEntry->ObjectInformation->FileId.Volume,
4626 DirEntry->ObjectInformation->FileId.Vnode,
4627 DirEntry->ObjectInformation->FileId.Unique,
4628 STATUS_INSUFFICIENT_RESOURCES);
4630 AFSReleaseResource( &DirEntry->NonPaged->Lock);
4632 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4636 // Start building the name
4639 RtlCopyMemory( uniReparseName.Buffer,
4640 uniMUPDeviceName.Buffer,
4641 uniMUPDeviceName.Length);
4643 uniReparseName.Length = uniMUPDeviceName.Length;
4645 if( DirEntry->NameInformation.TargetName.Buffer[ 0] != L'\\')
4648 uniReparseName.Buffer[ uniReparseName.Length/sizeof( WCHAR)] = L'\\';
4650 uniReparseName.Length += sizeof( WCHAR);
4653 RtlCopyMemory( &uniReparseName.Buffer[ uniReparseName.Length/sizeof( WCHAR)],
4654 DirEntry->NameInformation.TargetName.Buffer,
4655 DirEntry->NameInformation.TargetName.Length);
4657 uniReparseName.Length += DirEntry->NameInformation.TargetName.Length;
4659 AFSReleaseResource( &DirEntry->NonPaged->Lock);
4661 if( RemainingPath != NULL &&
4662 RemainingPath->Length > 0)
4665 if( uniReparseName.Buffer[ (uniReparseName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
4666 RemainingPath->Buffer[ 0] != L'\\')
4669 uniReparseName.Buffer[ uniReparseName.Length/sizeof( WCHAR)] = L'\\';
4671 uniReparseName.Length += sizeof( WCHAR);
4674 RtlCopyMemory( &uniReparseName.Buffer[ uniReparseName.Length/sizeof( WCHAR)],
4675 RemainingPath->Buffer,
4676 RemainingPath->Length);
4678 uniReparseName.Length += RemainingPath->Length;
4682 // Update the name in the file object
4685 if( FileObject->FileName.Buffer != NULL)
4688 AFSExFreePoolWithTag( FileObject->FileName.Buffer, 0);
4691 FileObject->FileName = uniReparseName;
4693 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4694 AFS_TRACE_LEVEL_VERBOSE,
4695 "AFSProcessDFSLink Reparsing access to Fcb %wZ FID %08lX-%08lX-%08lX-%08lX to %wZ\n",
4696 &DirEntry->NameInformation.FileName,
4697 DirEntry->ObjectInformation->FileId.Cell,
4698 DirEntry->ObjectInformation->FileId.Volume,
4699 DirEntry->ObjectInformation->FileId.Vnode,
4700 DirEntry->ObjectInformation->FileId.Unique,
4704 // Return status reparse ...
4707 ntStatus = STATUS_REPARSE;
4714 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);