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"
44 // On entry, *VolumeCB must have a held ReferenceCount provided by
45 // the caller which will be released. On successful exit, *VolumeCB
46 // will be assigned the new current volume with a held ReferenceCount.
48 // On entry, *ParentDirectoryCB must have a held DirOpenReferenceCount
49 // provided by the caller.
53 AFSLocateNameEntry( IN GUID *AuthGroup,
54 IN PFILE_OBJECT FileObject,
55 IN UNICODE_STRING *RootPathName,
56 IN UNICODE_STRING *ParsedPathName,
57 IN AFSNameArrayHdr *NameArray,
59 IN OUT AFSVolumeCB **VolumeCB,
60 IN OUT AFSDirectoryCB **ParentDirectoryCB,
61 OUT AFSDirectoryCB **DirectoryCB,
62 OUT PUNICODE_STRING ComponentName)
65 NTSTATUS ntStatus = STATUS_SUCCESS;
66 UNICODE_STRING uniPathName, uniComponentName, uniRemainingPath, uniSearchName, uniFullPathName;
68 AFSDirectoryCB *pDirEntry = NULL, *pParentDirEntry = NULL;
69 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
70 UNICODE_STRING uniSysName;
71 ULONG ulSubstituteIndex = 0;
72 BOOLEAN bSubstituteName = FALSE;
73 AFSNameArrayHdr *pNameArray = NameArray;
74 BOOLEAN bAllocatedSymLinkBuffer = FALSE;
75 UNICODE_STRING uniRelativeName, uniNoOpName;
76 AFSObjectInfoCB *pCurrentObject = NULL;
77 AFSObjectInfoCB *pParentObjectInfo = NULL;
78 AFSVolumeCB *pCurrentVolume = *VolumeCB;
79 BOOLEAN bReleaseCurrentVolume = TRUE;
80 BOOLEAN bSubstitutedName = FALSE;
86 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
87 AFS_TRACE_LEVEL_VERBOSE_2,
88 "AFSLocateNameEntry (FO: %p) Processing full name %wZ\n",
92 RtlInitUnicodeString( &uniSysName,
95 RtlInitUnicodeString( &uniRelativeName,
98 RtlInitUnicodeString( &uniNoOpName,
102 // Cleanup some parameters
105 if( ComponentName != NULL)
108 ComponentName->Length = 0;
109 ComponentName->MaximumLength = 0;
110 ComponentName->Buffer = NULL;
114 // We will parse through the filename, locating the directory nodes until we encounter a cache miss
115 // Starting at the root node
118 pParentDirEntry = NULL;
120 pDirEntry = *ParentDirectoryCB;
122 uniPathName = *ParsedPathName;
124 uniFullPathName = *RootPathName;
126 uniComponentName.Length = uniComponentName.MaximumLength = 0;
127 uniComponentName.Buffer = NULL;
129 uniRemainingPath.Length = uniRemainingPath.MaximumLength = 0;
130 uniRemainingPath.Buffer = NULL;
132 uniSearchName.Length = uniSearchName.MaximumLength = 0;
133 uniSearchName.Buffer = NULL;
138 ASSERT( pCurrentVolume->VolumeReferenceCount > 1);
140 ASSERT( pDirEntry->DirOpenReferenceCount > 0);
143 // Check our total link count for this name array
146 if( pNameArray->LinkCount >= (LONG)pDevExt->Specific.RDR.MaxLinkCount)
149 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
152 pCurrentObject = pDirEntry->ObjectInformation;
154 KeQueryTickCount( &pCurrentObject->LastAccessCount);
157 // Check that the directory entry is not deleted or pending delete
160 if( BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED))
163 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
164 AFS_TRACE_LEVEL_ERROR,
165 "AFSLocateNameEntry (FO: %p) Deleted parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
167 &pDirEntry->NameInformation.FileName,
168 pCurrentObject->FileId.Cell,
169 pCurrentObject->FileId.Volume,
170 pCurrentObject->FileId.Vnode,
171 pCurrentObject->FileId.Unique,
172 STATUS_FILE_DELETED);
174 try_return( ntStatus = STATUS_FILE_DELETED);
177 if( BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_PENDING_DELETE))
180 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
181 AFS_TRACE_LEVEL_ERROR,
182 "AFSLocateNameEntry (FO: %p) Delete pending on %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
184 &pDirEntry->NameInformation.FileName,
185 pCurrentObject->FileId.Cell,
186 pCurrentObject->FileId.Volume,
187 pCurrentObject->FileId.Vnode,
188 pCurrentObject->FileId.Unique,
189 STATUS_DELETE_PENDING);
191 try_return( ntStatus = STATUS_DELETE_PENDING);
195 // Check if the directory requires verification
198 if( BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_FLAGS_VERIFY) &&
199 ( pCurrentObject->FileType != AFS_FILE_TYPE_DIRECTORY ||
200 !AFSIsEnumerationInProcess( pCurrentObject)))
203 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
204 AFS_TRACE_LEVEL_VERBOSE,
205 "AFSLocateNameEntry (FO: %p) Verifying parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
207 &pDirEntry->NameInformation.FileName,
208 pCurrentObject->FileId.Cell,
209 pCurrentObject->FileId.Volume,
210 pCurrentObject->FileId.Vnode,
211 pCurrentObject->FileId.Unique);
214 // Directory TreeLock should be exclusively held
217 AFSAcquireExcl( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
220 ntStatus = AFSVerifyEntry( AuthGroup,
223 AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
225 if( !NT_SUCCESS( ntStatus))
228 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
229 AFS_TRACE_LEVEL_ERROR,
230 "AFSLocateNameEntry (FO: %p) Failed to verify parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
232 &pDirEntry->NameInformation.FileName,
233 pCurrentObject->FileId.Cell,
234 pCurrentObject->FileId.Volume,
235 pCurrentObject->FileId.Vnode,
236 pCurrentObject->FileId.Unique,
239 try_return( ntStatus);
244 // Ensure the parent node has been evaluated, if not then go do it now
247 if( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) ||
248 pCurrentObject->FileType == AFS_FILE_TYPE_UNKNOWN)
251 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
252 AFS_TRACE_LEVEL_VERBOSE,
253 "AFSLocateNameEntry (FO: %p) Evaluating parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
255 &pDirEntry->NameInformation.FileName,
256 pCurrentObject->FileId.Cell,
257 pCurrentObject->FileId.Volume,
258 pCurrentObject->FileId.Vnode,
259 pCurrentObject->FileId.Unique);
261 ntStatus = AFSEvaluateNode( AuthGroup,
264 if( !NT_SUCCESS( ntStatus))
267 if ( ntStatus == STATUS_NOT_A_DIRECTORY)
270 if ( !BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
273 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
274 AFS_TRACE_LEVEL_ERROR,
275 "AFSLocateNameEntry (FO: %p) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT NULL Status %08lX\n",
277 &pDirEntry->NameInformation.FileName,
278 pCurrentObject->FileId.Cell,
279 pCurrentObject->FileId.Volume,
280 pCurrentObject->FileId.Vnode,
281 pCurrentObject->FileId.Unique,
287 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
288 AFS_TRACE_LEVEL_ERROR,
289 "AFSLocateNameEntry (FO: %p) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT %08lX-%08lX-%08lX-%08lX Status %08lX\n",
291 &pDirEntry->NameInformation.FileName,
292 pCurrentObject->FileId.Cell,
293 pCurrentObject->FileId.Volume,
294 pCurrentObject->FileId.Vnode,
295 pCurrentObject->FileId.Unique,
296 pCurrentObject->ParentFileId.Cell,
297 pCurrentObject->ParentFileId.Volume,
298 pCurrentObject->ParentFileId.Vnode,
299 pCurrentObject->ParentFileId.Unique,
305 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
306 AFS_TRACE_LEVEL_ERROR,
307 "AFSLocateNameEntry (FO: %p) Failed to evaluate parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
309 &pDirEntry->NameInformation.FileName,
310 pCurrentObject->FileId.Cell,
311 pCurrentObject->FileId.Volume,
312 pCurrentObject->FileId.Vnode,
313 pCurrentObject->FileId.Unique,
317 try_return( ntStatus);
320 ClearFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
324 // If this is a mount point or symlink then go get the real directory node
327 switch( pCurrentObject->FileType)
330 case AFS_FILE_TYPE_SYMLINK:
333 UNICODE_STRING uniTempName;
334 WCHAR *pTmpBuffer = NULL;
338 // Check if the flag is set to NOT evaluate a symlink
339 // and we are done with the parsing
342 if( BooleanFlagOn( Flags, AFS_LOCATE_FLAGS_NO_SL_TARGET_EVAL) &&
343 uniRemainingPath.Length == 0)
347 // Pass back the directory entries
350 *ParentDirectoryCB = pParentDirEntry;
352 *DirectoryCB = pDirEntry;
354 *VolumeCB = pCurrentVolume;
356 *RootPathName = uniFullPathName;
358 try_return( ntStatus);
361 AFSAcquireExcl( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
364 AFSAcquireExcl( &pDirEntry->NonPaged->Lock,
367 if( pDirEntry->NameInformation.TargetName.Length == 0)
371 // We'll reset the DV to ensure we validate the metadata content
374 pCurrentObject->DataVersion.QuadPart = (ULONGLONG)-1;
376 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_VERIFY);
378 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
379 AFS_TRACE_LEVEL_VERBOSE,
380 "AFSLocateNameEntry (FO: %p) Verifying symlink parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
382 &pDirEntry->NameInformation.FileName,
383 pCurrentObject->FileId.Cell,
384 pCurrentObject->FileId.Volume,
385 pCurrentObject->FileId.Vnode,
386 pCurrentObject->FileId.Unique);
389 // Directory TreeLock should be exclusively held
392 ntStatus = AFSVerifyEntry( AuthGroup,
395 AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
397 if( !NT_SUCCESS( ntStatus))
400 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
401 AFS_TRACE_LEVEL_ERROR,
402 "AFSLocateNameEntry (FO: %p) Failed to verify symlink parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
404 &pDirEntry->NameInformation.FileName,
405 pCurrentObject->FileId.Cell,
406 pCurrentObject->FileId.Volume,
407 pCurrentObject->FileId.Vnode,
408 pCurrentObject->FileId.Unique,
411 AFSReleaseResource( &pDirEntry->NonPaged->Lock);
413 try_return( ntStatus);
417 // If the type changed then reprocess this entry
420 if( pCurrentObject->FileType != AFS_FILE_TYPE_SYMLINK)
423 AFSReleaseResource( &pDirEntry->NonPaged->Lock);
431 AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
435 // If we were given a zero length target name then deny access to the entry
438 if( pDirEntry->NameInformation.TargetName.Length == 0)
441 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
443 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
444 AFS_TRACE_LEVEL_ERROR,
445 "AFSLocateNameEntry (FO: %p) Failed to retrieve target name for symlink %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
447 &pDirEntry->NameInformation.FileName,
448 pCurrentObject->FileId.Cell,
449 pCurrentObject->FileId.Volume,
450 pCurrentObject->FileId.Vnode,
451 pCurrentObject->FileId.Unique,
454 AFSReleaseResource( &pDirEntry->NonPaged->Lock);
456 try_return( ntStatus);
459 if( AFSIsRelativeName( &pDirEntry->NameInformation.TargetName))
462 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
463 AFS_TRACE_LEVEL_VERBOSE,
464 "AFSLocateNameEntry (FO: %p) Processing relative symlink target %wZ for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
466 &pDirEntry->NameInformation.TargetName,
467 &pDirEntry->NameInformation.FileName,
468 pCurrentObject->FileId.Cell,
469 pCurrentObject->FileId.Volume,
470 pCurrentObject->FileId.Vnode,
471 pCurrentObject->FileId.Unique);
474 // We'll substitute this name into the current process name
475 // starting at where we sit in the path
478 uniTempName.Length = 0;
479 uniTempName.MaximumLength = (USHORT)((char *)uniComponentName.Buffer - (char *)uniFullPathName.Buffer) +
480 pDirEntry->NameInformation.TargetName.Length +
482 uniRemainingPath.Length;
484 uniTempName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
485 uniTempName.MaximumLength,
486 AFS_NAME_BUFFER_ONE_TAG);
488 if( uniTempName.Buffer == NULL)
491 AFSReleaseResource( &pDirEntry->NonPaged->Lock);
493 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
497 // We have so first copy in the portion up to the component
501 RtlCopyMemory( uniTempName.Buffer,
502 uniFullPathName.Buffer,
503 (ULONG)((char *)uniComponentName.Buffer - (char *)uniFullPathName.Buffer));
505 uniTempName.Length = (USHORT)((char *)uniComponentName.Buffer - (char *)uniFullPathName.Buffer);
507 if( bAllocatedSymLinkBuffer ||
511 pTmpBuffer = uniFullPathName.Buffer;
514 bAllocatedSymLinkBuffer = TRUE;
517 // Have we parsed this name yet? Better have at least once ...
520 if( uniComponentName.Length == 0)
526 // Copy in the target name ...
529 RtlCopyMemory( &uniTempName.Buffer[ uniTempName.Length/sizeof( WCHAR)],
530 pDirEntry->NameInformation.TargetName.Buffer,
531 pDirEntry->NameInformation.TargetName.Length);
533 uniPathName.Buffer = &uniTempName.Buffer[ uniTempName.Length/sizeof( WCHAR)];
535 uniPathName.Length += pDirEntry->NameInformation.TargetName.Length;
536 uniPathName.MaximumLength = uniTempName.MaximumLength;
538 uniTempName.Length += pDirEntry->NameInformation.TargetName.Length;
541 // And now any remaining portion of the name
544 if( uniRemainingPath.Length > 0)
547 if( uniRemainingPath.Buffer[ 0] != L'\\')
550 uniRemainingPath.Buffer--;
551 uniRemainingPath.Length += sizeof( WCHAR);
553 uniPathName.Length += sizeof( WCHAR);
556 RtlCopyMemory( &uniTempName.Buffer[ uniTempName.Length/sizeof( WCHAR)],
557 uniRemainingPath.Buffer,
558 uniRemainingPath.Length);
560 uniTempName.Length += uniRemainingPath.Length;
563 uniFullPathName = uniTempName;
565 if( pTmpBuffer != NULL)
568 AFSExFreePoolWithTag( pTmpBuffer, 0);
571 AFSReleaseResource( &pDirEntry->NonPaged->Lock);
574 // Dereference the current entry ..
577 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
579 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
580 AFS_TRACE_LEVEL_VERBOSE,
581 "AFSLocateNameEntry Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
582 &pDirEntry->NameInformation.FileName,
587 ASSERT( lCount >= 0);
590 // OK, need to back up one entry for the correct parent since the current
591 // entry we are on is the symlink itself
594 pDirEntry = AFSBackupEntry( pNameArray);
597 // Increment our reference on this dir entry
600 lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
602 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
603 AFS_TRACE_LEVEL_VERBOSE,
604 "AFSLocateNameEntry Increment1 count on %wZ DE %p Ccb %p Cnt %d\n",
605 &pDirEntry->NameInformation.FileName,
610 if( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_ROOT_VOLUME))
613 pParentDirEntry = NULL;
618 pParentDirEntry = AFSGetParentEntry( pNameArray);
620 ASSERT( pParentDirEntry != pDirEntry);
626 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
627 AFS_TRACE_LEVEL_VERBOSE,
628 "AFSLocateNameEntry (FO: %p) Processing absolute symlink target %wZ for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
630 &pDirEntry->NameInformation.TargetName,
631 &pDirEntry->NameInformation.FileName,
632 pCurrentObject->FileId.Cell,
633 pCurrentObject->FileId.Volume,
634 pCurrentObject->FileId.Vnode,
635 pCurrentObject->FileId.Unique);
637 if ( !AFSIsAbsoluteAFSName( &pDirEntry->NameInformation.TargetName))
640 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
641 AFS_TRACE_LEVEL_ERROR,
642 "AFSLocateNameEntry Name %wZ contains invalid server name\n",
643 &pDirEntry->NameInformation.TargetName);
646 // The correct response would be STATUS_OBJECT_PATH_INVALID
647 // but that prevents cmd.exe from performing a recursive
648 // directory enumeration when opening a directory entry
649 // that represents a symlink to an invalid path is discovered.
652 AFSReleaseResource( &pDirEntry->NonPaged->Lock);
654 try_return( ntStatus = STATUS_OBJECT_PATH_NOT_FOUND);
658 // We'll substitute this name into the current process name
659 // starting at where we sit in the path
662 uniTempName.Length = 0;
663 uniTempName.MaximumLength = pDirEntry->NameInformation.TargetName.Length +
665 uniRemainingPath.Length;
667 uniTempName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
668 uniTempName.MaximumLength,
669 AFS_NAME_BUFFER_TWO_TAG);
671 if( uniTempName.Buffer == NULL)
674 AFSReleaseResource( &pDirEntry->NonPaged->Lock);
676 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
679 if( bAllocatedSymLinkBuffer ||
683 pTmpBuffer = uniFullPathName.Buffer;
686 bAllocatedSymLinkBuffer = TRUE;
689 // Have we parsed this name yet? Better have at least once ...
692 if( uniComponentName.Length == 0)
698 // Copy in the target name ...
701 RtlCopyMemory( uniTempName.Buffer,
702 &pDirEntry->NameInformation.TargetName.Buffer[ AFSMountRootName.Length/sizeof( WCHAR)],
703 pDirEntry->NameInformation.TargetName.Length - AFSMountRootName.Length);
705 uniTempName.Length = pDirEntry->NameInformation.TargetName.Length - AFSMountRootName.Length;
708 // And now any remaining portion of the name
711 if( uniRemainingPath.Length > 0)
714 if( uniRemainingPath.Buffer[ 0] != L'\\')
717 uniRemainingPath.Buffer--;
718 uniRemainingPath.Length += sizeof( WCHAR);
721 RtlCopyMemory( &uniTempName.Buffer[ uniTempName.Length/sizeof( WCHAR)],
722 uniRemainingPath.Buffer,
723 uniRemainingPath.Length);
725 uniTempName.Length += uniRemainingPath.Length;
728 uniFullPathName = uniTempName;
730 uniPathName = uniTempName;
732 if( pTmpBuffer != NULL)
735 AFSExFreePoolWithTag( pTmpBuffer, 0);
738 AFSReleaseResource( &pDirEntry->NonPaged->Lock);
741 // If our current volume is not the global root then make it so ...
744 if( pCurrentVolume != AFSGlobalRoot)
747 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
748 AFS_TRACE_LEVEL_VERBOSE,
749 "AFSLocateNameEntry (FO: %p) Current volume not global, resetting for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
751 &pDirEntry->NameInformation.FileName,
752 pCurrentObject->FileId.Cell,
753 pCurrentObject->FileId.Volume,
754 pCurrentObject->FileId.Vnode,
755 pCurrentObject->FileId.Unique);
757 lCount = InterlockedDecrement( &pCurrentVolume->VolumeReferenceCount);
759 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
760 AFS_TRACE_LEVEL_VERBOSE,
761 "AFSLocateNameEntry Decrement count on volume %p Cnt %d\n",
765 pCurrentVolume = AFSGlobalRoot;
767 lCount = InterlockedIncrement( &pCurrentVolume->VolumeReferenceCount);
769 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
770 AFS_TRACE_LEVEL_VERBOSE,
771 "AFSLocateNameEntry Increment count on volume %p Cnt %d\n",
777 // Dereference our current dir entry
780 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
782 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
783 AFS_TRACE_LEVEL_VERBOSE,
784 "AFSLocateNameEntry Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
785 &pDirEntry->NameInformation.FileName,
790 ASSERT( lCount >= 0);
792 pDirEntry = pCurrentVolume->DirectoryCB;
795 // Reference the new dir entry
798 lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
800 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
801 AFS_TRACE_LEVEL_VERBOSE,
802 "AFSLocateNameEntry Increment2 count on %wZ DE %p Ccb %p Cnt %d\n",
803 &pDirEntry->NameInformation.FileName,
809 // Reset the name array
810 // Persist the link count in the name array
813 lLinkCount = pNameArray->LinkCount;
815 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
816 AFS_TRACE_LEVEL_VERBOSE,
817 "AFSLocateNameEntry (FO: %p) Resetting name array for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
819 &pDirEntry->NameInformation.FileName,
820 pCurrentObject->FileId.Cell,
821 pCurrentObject->FileId.Volume,
822 pCurrentObject->FileId.Vnode,
823 pCurrentObject->FileId.Unique);
825 AFSResetNameArray( pNameArray,
828 pNameArray->LinkCount = lLinkCount;
830 pParentDirEntry = NULL;
834 // Increment our link count
837 lCount = InterlockedIncrement( &pNameArray->LinkCount);
842 case AFS_FILE_TYPE_MOUNTPOINT:
846 // Check if the flag is set to NOT evaluate a mount point
847 // and we are done with the parsing
850 if( BooleanFlagOn( Flags, AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL) &&
851 uniRemainingPath.Length == 0)
855 // Pass back the directory entries
858 *ParentDirectoryCB = pParentDirEntry;
860 *DirectoryCB = pDirEntry;
862 *VolumeCB = pCurrentVolume;
864 *RootPathName = uniFullPathName;
866 try_return( ntStatus);
869 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
870 AFS_TRACE_LEVEL_VERBOSE,
871 "AFSLocateNameEntry (FO: %p) Building MP target for parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
873 &pDirEntry->NameInformation.FileName,
874 pCurrentObject->FileId.Cell,
875 pCurrentObject->FileId.Volume,
876 pCurrentObject->FileId.Vnode,
877 pCurrentObject->FileId.Unique);
880 // Go retrieve the target entry for this node
881 // Release the current volume cb entry since we would
882 // have lock inversion in the following call
883 // Also decrement the ref count on the volume
886 ASSERT( pCurrentVolume->VolumeReferenceCount > 1);
888 lCount = InterlockedDecrement( &pCurrentVolume->VolumeReferenceCount);
890 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
891 AFS_TRACE_LEVEL_VERBOSE,
892 "AFSLocateNameEntry Decrement2 count on volume %p Cnt %d\n",
896 ntStatus = AFSBuildMountPointTarget( AuthGroup,
900 if( !NT_SUCCESS( ntStatus))
903 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
904 AFS_TRACE_LEVEL_ERROR,
905 "AFSLocateNameEntry (FO: %p) Failed to build MP target for parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
907 &pDirEntry->NameInformation.FileName,
908 pCurrentObject->FileId.Cell,
909 pCurrentObject->FileId.Volume,
910 pCurrentObject->FileId.Vnode,
911 pCurrentObject->FileId.Unique,
915 // We already decremented the current volume above
918 bReleaseCurrentVolume = FALSE;
920 try_return( ntStatus);
923 ASSERT( pCurrentVolume->VolumeReferenceCount > 1);
926 // We want to restart processing here on the new parent ...
927 // Deref and ref count the entries
930 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
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 ASSERT( lCount >= 0);
942 pDirEntry = pCurrentVolume->DirectoryCB;
944 lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
946 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
947 AFS_TRACE_LEVEL_VERBOSE,
948 "AFSLocateNameEntry Increment3 count on %wZ DE %p Ccb %p Cnt %d\n",
949 &pDirEntry->NameInformation.FileName,
955 // The name array stores both the mount point and the target.
956 // Insert the target.
959 AFSInsertNextElement( pNameArray,
962 pParentDirEntry = NULL;
965 // Increment our link count
968 lCount = InterlockedIncrement( &pNameArray->LinkCount);
973 case AFS_FILE_TYPE_DFSLINK:
976 if( BooleanFlagOn( Flags, AFS_LOCATE_FLAGS_NO_DFS_LINK_EVAL))
980 // Pass back the directory entries
983 *ParentDirectoryCB = pParentDirEntry;
985 *DirectoryCB = pDirEntry;
987 *VolumeCB = pCurrentVolume;
989 *RootPathName = uniFullPathName;
991 try_return( ntStatus);
995 // This is a DFS link so we need to update the file name and return STATUS_REPARSE to the
996 // system for it to reevaluate it
999 if( FileObject != NULL)
1002 ntStatus = AFSProcessDFSLink( pDirEntry,
1011 // This is where we have been re-entered from an NP evaluation call via the BuildBranch()
1015 ntStatus = STATUS_INVALID_PARAMETER;
1018 if( ntStatus != STATUS_SUCCESS &&
1019 ntStatus != STATUS_REPARSE)
1022 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1023 AFS_TRACE_LEVEL_ERROR,
1024 "AFSLocateNameEntry (FO: %p) Failed to process DFSLink parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1026 &pDirEntry->NameInformation.FileName,
1027 pCurrentObject->FileId.Cell,
1028 pCurrentObject->FileId.Volume,
1029 pCurrentObject->FileId.Vnode,
1030 pCurrentObject->FileId.Unique,
1034 try_return( ntStatus);
1037 case AFS_FILE_TYPE_UNKNOWN:
1038 case AFS_FILE_TYPE_INVALID:
1042 // Something was not processed ...
1045 try_return( ntStatus = STATUS_ACCESS_DENIED);
1048 } /* end of switch */
1051 // If the parent is not initialized then do it now
1054 if( pCurrentObject->FileType == AFS_FILE_TYPE_DIRECTORY &&
1055 !BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
1058 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1059 AFS_TRACE_LEVEL_VERBOSE,
1060 "AFSLocateNameEntry (FO: %p) Enumerating parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1062 &pDirEntry->NameInformation.FileName,
1063 pCurrentObject->FileId.Cell,
1064 pCurrentObject->FileId.Volume,
1065 pCurrentObject->FileId.Vnode,
1066 pCurrentObject->FileId.Unique);
1068 AFSAcquireExcl( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
1071 if( !BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
1074 ntStatus = AFSEnumerateDirectory( AuthGroup,
1078 if( !NT_SUCCESS( ntStatus))
1081 AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
1083 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1084 AFS_TRACE_LEVEL_ERROR,
1085 "AFSLocateNameEntry (FO: %p) Failed to enumerate parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1087 &pDirEntry->NameInformation.FileName,
1088 pCurrentObject->FileId.Cell,
1089 pCurrentObject->FileId.Volume,
1090 pCurrentObject->FileId.Vnode,
1091 pCurrentObject->FileId.Unique,
1094 try_return( ntStatus);
1097 SetFlag( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
1100 AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
1102 else if( pCurrentObject->FileType == AFS_FILE_TYPE_FILE)
1105 if( uniPathName.Length > 0)
1108 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1109 AFS_TRACE_LEVEL_ERROR,
1110 "AFSLocateNameEntry (FO: %p) Encountered file node %wZ FID %08lX-%08lX-%08lX-%08lX in path processing\n",
1112 &pDirEntry->NameInformation.FileName,
1113 pCurrentObject->FileId.Cell,
1114 pCurrentObject->FileId.Volume,
1115 pCurrentObject->FileId.Vnode,
1116 pCurrentObject->FileId.Unique);
1118 // The proper error code to return would be STATUS_OBJECT_PATH_INVALID because
1119 // one of the components of the path is not a directory. However, returning
1120 // that error prevents IIS 7 and 7.5 from being able to serve data out of AFS.
1121 // Instead IIS insists on treating the target file as if it is a directory containing
1122 // a potential web.config file. NTFS and LanMan return STATUS_OBJECT_PATH_NOT_FOUND.
1123 // AFS will follow suit.
1125 ntStatus = STATUS_OBJECT_PATH_NOT_FOUND;
1130 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1131 AFS_TRACE_LEVEL_VERBOSE,
1132 "AFSLocateNameEntry (FO: %p) Returning file %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1134 &pDirEntry->NameInformation.FileName,
1135 pCurrentObject->FileId.Cell,
1136 pCurrentObject->FileId.Volume,
1137 pCurrentObject->FileId.Vnode,
1138 pCurrentObject->FileId.Unique);
1141 // Pass back the directory entries
1144 *ParentDirectoryCB = pParentDirEntry;
1146 *DirectoryCB = pDirEntry;
1148 *VolumeCB = pCurrentVolume;
1150 *RootPathName = uniFullPathName;
1153 try_return( ntStatus);
1157 // If we are at the end of the processing, set our returned information and get out
1160 if( uniPathName.Length == 0)
1163 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1164 AFS_TRACE_LEVEL_VERBOSE,
1165 "AFSLocateNameEntry (FO: %p) Completed processing returning %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1167 &pDirEntry->NameInformation.FileName,
1168 pCurrentObject->FileId.Cell,
1169 pCurrentObject->FileId.Volume,
1170 pCurrentObject->FileId.Vnode,
1171 pCurrentObject->FileId.Unique);
1174 // Pass back the directory entries
1177 *ParentDirectoryCB = pParentDirEntry;
1179 *DirectoryCB = pDirEntry;
1181 *VolumeCB = pCurrentVolume;
1183 *RootPathName = uniFullPathName;
1185 try_return( ntStatus);
1189 // We may have returned to the top of the while( TRUE)
1191 if( bSubstituteName &&
1192 uniSearchName.Buffer != NULL)
1195 AFSExFreePoolWithTag( uniSearchName.Buffer, 0);
1197 bSubstituteName = FALSE;
1199 uniSearchName.Length = uniSearchName.MaximumLength = 0;
1200 uniSearchName.Buffer = NULL;
1203 ulSubstituteIndex = 1;
1205 ntStatus = STATUS_SUCCESS;
1208 // Get the next component name
1211 FsRtlDissectName( uniPathName,
1216 // Check for the . and .. in the path
1219 if( RtlCompareUnicodeString( &uniComponentName,
1224 uniPathName = uniRemainingPath;
1229 if( RtlCompareUnicodeString( &uniComponentName,
1234 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1235 AFS_TRACE_LEVEL_VERBOSE,
1236 "AFSLocateNameEntry (FO: %p) Backing up entry from %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1238 &pDirEntry->NameInformation.FileName,
1239 pCurrentObject->FileId.Cell,
1240 pCurrentObject->FileId.Volume,
1241 pCurrentObject->FileId.Vnode,
1242 pCurrentObject->FileId.Unique);
1245 // Need to back up one entry in the name array
1247 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
1249 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1250 AFS_TRACE_LEVEL_VERBOSE,
1251 "AFSLocateNameEntry Decrement4 count on %wZ DE %p Ccb %p Cnt %d\n",
1252 &pDirEntry->NameInformation.FileName,
1257 ASSERT( lCount >= 0);
1259 pDirEntry = AFSBackupEntry( NameArray);
1261 if( pDirEntry == NULL)
1264 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1265 AFS_TRACE_LEVEL_ERROR,
1266 "AFSLocateNameEntry AFSBackupEntry failed\n");
1268 try_return(ntStatus = STATUS_OBJECT_PATH_INVALID);
1271 lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
1273 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1274 AFS_TRACE_LEVEL_VERBOSE,
1275 "AFSLocateNameEntry Increment4 count on %wZ DE %p Ccb %p Cnt %d\n",
1276 &pDirEntry->NameInformation.FileName,
1281 if( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_ROOT_VOLUME))
1284 pParentDirEntry = NULL;
1289 pParentDirEntry = AFSGetParentEntry( pNameArray);
1291 ASSERT( pParentDirEntry != pDirEntry);
1294 uniPathName = uniRemainingPath;
1300 // Update our pointers
1303 pParentDirEntry = pDirEntry;
1307 uniSearchName = uniComponentName;
1309 while( pDirEntry == NULL)
1313 // If the SearchName contains @SYS then we perform the substitution.
1314 // If there is no substitution we give up.
1317 if( !bSubstituteName &&
1318 FsRtlIsNameInExpression( &uniSysName,
1324 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1325 AFS_TRACE_LEVEL_VERBOSE_2,
1326 "AFSLocateNameEntry (FO: %p) Processing @SYS substitution for %wZ Index %08lX\n",
1331 ntStatus = AFSSubstituteSysName( &uniComponentName,
1335 if ( NT_SUCCESS( ntStatus))
1338 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1339 AFS_TRACE_LEVEL_VERBOSE_2,
1340 "AFSLocateNameEntry (FO: %p) Located substitution %wZ for %wZ Index %08lX\n",
1347 // Go reparse the name again
1350 bSubstituteName = TRUE;
1352 ulSubstituteIndex++; // For the next entry, if needed
1354 continue; // while( pDirEntry == NULL)
1359 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1360 AFS_TRACE_LEVEL_ERROR,
1361 "AFSLocateNameEntry (FO: %p) Failed to locate substitute string for %wZ Index %08lX Status %08lX\n",
1367 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
1371 // Pass back the directory entries
1374 *ParentDirectoryCB = pParentDirEntry;
1376 *DirectoryCB = NULL;
1378 *VolumeCB = pCurrentVolume;
1380 if( ComponentName != NULL)
1383 *ComponentName = uniComponentName;
1386 *RootPathName = uniFullPathName;
1390 // We can't possibly have a pDirEntry since the lookup failed
1392 try_return( ntStatus);
1397 // Generate the CRC on the node and perform a case sensitive lookup
1400 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1401 AFS_TRACE_LEVEL_VERBOSE_2,
1402 "AFSLocateNameEntry (FO: %p) Searching for entry %wZ case sensitive\n",
1406 ulCRC = AFSGenerateCRC( &uniSearchName,
1409 AFSAcquireShared( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
1412 AFSLocateCaseSensitiveDirEntry( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
1416 if( pDirEntry == NULL)
1420 // Missed so perform a case insensitive lookup
1423 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1424 AFS_TRACE_LEVEL_VERBOSE_2,
1425 "AFSLocateNameEntry (FO: %p) Searching for entry %wZ case insensitive\n",
1429 ulCRC = AFSGenerateCRC( &uniSearchName,
1432 AFSLocateCaseInsensitiveDirEntry( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
1436 if( pDirEntry == NULL)
1440 // OK, if this component is a valid short name then try
1441 // a lookup in the short name tree
1444 if( !BooleanFlagOn( pDevExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
1445 RtlIsNameLegalDOS8Dot3( &uniSearchName,
1450 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1451 AFS_TRACE_LEVEL_VERBOSE_2,
1452 "AFSLocateNameEntry (FO: %p) Searching for entry %wZ short name\n",
1456 AFSLocateShortNameDirEntry( pParentDirEntry->ObjectInformation->Specific.Directory.ShortNameTree,
1461 if ( pDirEntry == NULL &&
1462 pParentDirEntry->ObjectInformation->VolumeCB == AFSGlobalRoot)
1466 // Check with the service to see if this is a valid cell name
1467 // that can be automatically resolved. Drop the shared TreeLock
1468 // since AFSCheckCellName must acquire it exclusively.
1471 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1473 ntStatus = AFSCheckCellName( AuthGroup,
1477 AFSAcquireShared( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
1481 if( pDirEntry == NULL)
1485 // If we substituted a name then reset our search name and try again
1488 if( bSubstituteName)
1491 AFSExFreePoolWithTag( uniSearchName.Buffer, 0);
1493 uniSearchName = uniComponentName;
1495 bSubstituteName = FALSE;
1497 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1499 continue; // while( pDirEntry == NULL)
1502 if( uniRemainingPath.Length > 0)
1505 ntStatus = STATUS_OBJECT_PATH_NOT_FOUND;
1507 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1508 AFS_TRACE_LEVEL_VERBOSE,
1509 "AFSLocateNameEntry (FO: %p) Returning path not found for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1512 pCurrentObject->FileId.Cell,
1513 pCurrentObject->FileId.Volume,
1514 pCurrentObject->FileId.Vnode,
1515 pCurrentObject->FileId.Unique);
1520 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
1522 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1523 AFS_TRACE_LEVEL_VERBOSE,
1524 "AFSLocateNameEntry (FO: %p) Returning name not found for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1527 pCurrentObject->FileId.Cell,
1528 pCurrentObject->FileId.Volume,
1529 pCurrentObject->FileId.Vnode,
1530 pCurrentObject->FileId.Unique);
1533 // Pass back the directory entries
1536 *ParentDirectoryCB = pParentDirEntry;
1538 *DirectoryCB = NULL;
1540 *VolumeCB = pCurrentVolume;
1542 if( ComponentName != NULL)
1545 *ComponentName = uniComponentName;
1548 *RootPathName = uniFullPathName;
1551 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1554 // Node name not found so get out
1557 try_return( ntStatus); // while( pDirEntry == NULL)
1564 // Here we have a match on the case insensitive lookup for the name. If there
1565 // Is more than one link entry for this node then fail the lookup request
1568 if( !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD) ||
1569 pDirEntry->CaseInsensitiveList.fLink != NULL)
1573 // Increment our dir entry ref count since we will decrement it on exit
1576 lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
1578 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1579 AFS_TRACE_LEVEL_VERBOSE,
1580 "AFSLocateNameEntry Increment5 count on %wZ DE %p Ccb %p Cnt %d\n",
1581 &pDirEntry->NameInformation.FileName,
1586 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1588 try_return(ntStatus = STATUS_OBJECT_NAME_COLLISION);
1593 if( pDirEntry != NULL)
1597 // If the verify flag is set on the parent and the current entry is deleted
1598 // revalidate the parent and search again.
1601 if( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED) &&
1602 BooleanFlagOn( pParentDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY))
1605 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1607 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1608 AFS_TRACE_LEVEL_VERBOSE,
1609 "AFSLocateNameEntry (FO: %p) Verifying(2) parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1611 &pParentDirEntry->NameInformation.FileName,
1612 pParentDirEntry->ObjectInformation->FileId.Cell,
1613 pParentDirEntry->ObjectInformation->FileId.Volume,
1614 pParentDirEntry->ObjectInformation->FileId.Vnode,
1615 pParentDirEntry->ObjectInformation->FileId.Unique);
1618 // Directory TreeLock should be exclusively held
1621 AFSAcquireExcl( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
1624 ntStatus = AFSVerifyEntry( AuthGroup,
1627 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1629 if( !NT_SUCCESS( ntStatus))
1632 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1633 AFS_TRACE_LEVEL_ERROR,
1634 "AFSLocateNameEntry (FO: %p) Failed to verify(2) parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1636 &pParentDirEntry->NameInformation.FileName,
1637 pParentDirEntry->ObjectInformation->FileId.Cell,
1638 pParentDirEntry->ObjectInformation->FileId.Volume,
1639 pParentDirEntry->ObjectInformation->FileId.Vnode,
1640 pParentDirEntry->ObjectInformation->FileId.Unique,
1643 try_return( ntStatus);
1646 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1647 AFS_TRACE_LEVEL_VERBOSE,
1648 "AFSLocateNameEntry (FO: %p) Reprocessing component %wZ in parent %wZ\n",
1651 &pParentDirEntry->NameInformation.FileName);
1660 // Increment our dir entry ref count
1663 lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
1665 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1666 AFS_TRACE_LEVEL_VERBOSE,
1667 "AFSLocateNameEntry Increment5 count on %wZ DE %p Ccb %p Cnt %d\n",
1668 &pDirEntry->NameInformation.FileName,
1674 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1676 } // End while( pDirEntry == NULL)
1679 // If we have a dirEntry for this component, perform some basic validation on it
1682 if( pDirEntry != NULL &&
1683 BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
1686 pCurrentObject = pDirEntry->ObjectInformation;
1688 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1689 AFS_TRACE_LEVEL_ERROR,
1690 "AFSLocateNameEntry (FO: %p) Deleted entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1692 &pDirEntry->NameInformation.FileName,
1693 pCurrentObject->FileId.Cell,
1694 pCurrentObject->FileId.Volume,
1695 pCurrentObject->FileId.Vnode,
1696 pCurrentObject->FileId.Unique);
1699 // This entry was deleted through the invalidation call back so perform cleanup
1703 if( BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
1706 pParentObjectInfo = AFSFindObjectInfo( pCurrentObject->VolumeCB,
1707 &pCurrentObject->ParentFileId);
1710 ASSERT( pParentObjectInfo != NULL);
1712 AFSAcquireExcl( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
1715 AFSAcquireExcl( pCurrentObject->VolumeCB->ObjectInfoTree.TreeLock,
1718 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
1720 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1721 AFS_TRACE_LEVEL_VERBOSE,
1722 "AFSLocateNameEntry Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
1723 &pDirEntry->NameInformation.FileName,
1728 ASSERT( lCount >= 0);
1733 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING|AFS_SUBSYSTEM_CLEANUP_PROCESSING,
1734 AFS_TRACE_LEVEL_VERBOSE,
1735 "AFSLocateNameEntry Deleting dir entry %p (%p) for %wZ\n",
1738 &pDirEntry->NameInformation.FileName);
1741 // Remove and delete the directory entry from the parent list
1744 AFSDeleteDirEntry( pParentObjectInfo,
1747 AFSAcquireShared( &pCurrentObject->NonPagedInfo->ObjectInfoLock,
1750 if( pCurrentObject->ObjectReferenceCount <= 0)
1753 if( BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_INSERTED_HASH_TREE))
1756 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
1757 AFS_TRACE_LEVEL_VERBOSE,
1758 "AFSLocateNameEntry Removing object %p from volume tree\n",
1761 AFSRemoveHashEntry( &pCurrentObject->VolumeCB->ObjectInfoTree.TreeHead,
1762 &pCurrentObject->TreeEntry);
1764 ClearFlag( pCurrentObject->Flags, AFS_OBJECT_INSERTED_HASH_TREE);
1768 AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock);
1773 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1774 AFS_TRACE_LEVEL_VERBOSE,
1775 "AFSLocateNameEntry Setting DELETE flag in dir entry %p for %wZ\n",
1777 &pDirEntry->NameInformation.FileName);
1779 SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
1781 AFSRemoveNameEntry( pParentObjectInfo,
1785 AFSReleaseResource( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
1787 AFSReleaseResource( pCurrentObject->VolumeCB->ObjectInfoTree.TreeLock);
1789 AFSReleaseObjectInfo( &pParentObjectInfo);
1792 // We deleted the dir entry so check if there is any remaining portion
1793 // of the name to process.
1796 if( uniRemainingPath.Length > 0)
1799 ntStatus = STATUS_OBJECT_PATH_NOT_FOUND;
1801 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1802 AFS_TRACE_LEVEL_VERBOSE,
1803 "AFSLocateNameEntry (FO: %p) Returning path not found(2) for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1806 pCurrentObject->FileId.Cell,
1807 pCurrentObject->FileId.Volume,
1808 pCurrentObject->FileId.Vnode,
1809 pCurrentObject->FileId.Unique);
1814 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
1816 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1817 AFS_TRACE_LEVEL_VERBOSE,
1818 "AFSLocateNameEntry (FO: %p) Returning name not found(2) for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1821 pCurrentObject->FileId.Cell,
1822 pCurrentObject->FileId.Volume,
1823 pCurrentObject->FileId.Vnode,
1824 pCurrentObject->FileId.Unique);
1827 // Pass back the directory entries
1830 *ParentDirectoryCB = pParentDirEntry;
1832 *DirectoryCB = NULL;
1834 *VolumeCB = pCurrentVolume;
1836 if( ComponentName != NULL)
1839 *ComponentName = uniComponentName;
1842 *RootPathName = uniFullPathName;
1846 if( ntStatus != STATUS_SUCCESS)
1849 try_return( ntStatus);
1853 // Decrement the previous parent
1856 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
1858 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1859 AFS_TRACE_LEVEL_VERBOSE,
1860 "AFSLocateNameEntry Decrement5 count on Parent %wZ DE %p Ccb %p Cnt %d\n",
1861 &pParentDirEntry->NameInformation.FileName,
1866 ASSERT( lCount >= 0);
1869 // If we ended up substituting a name in the component then update
1870 // the full path and update the pointers
1873 if( bSubstituteName)
1876 BOOLEAN bRelativeOpen = FALSE;
1878 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1879 AFS_TRACE_LEVEL_VERBOSE_2,
1880 "AFSLocateNameEntry (FO: %p) Substituting %wZ into %wZ Index %08lX\n",
1886 if( FileObject != NULL &&
1887 FileObject->RelatedFileObject != NULL)
1890 bRelativeOpen = TRUE;
1894 // AFSSubstituteNameInPath will replace the uniFullPathName.Buffer
1895 // and free the prior Buffer contents but only if the fourth
1896 // parameter is TRUE.
1899 ntStatus = AFSSubstituteNameInPath( &uniFullPathName,
1904 bAllocatedSymLinkBuffer ||
1907 if( !NT_SUCCESS( ntStatus))
1910 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1911 AFS_TRACE_LEVEL_ERROR,
1912 "AFSLocateNameEntry (FO: %p) Failure to substitute %wZ into %wZ Index %08lX Status %08lX\n",
1919 try_return( ntStatus);
1923 // We have substituted a name into the buffer so if we do this again for this
1924 // path, we need to free up the buffer we allocated.
1927 bSubstitutedName = TRUE;
1931 // Update the search parameters
1934 uniPathName = uniRemainingPath;
1937 // Check if the is a SymLink entry but has no Target FileID or Name. In this
1938 // case it might be a DFS Link so let's go and evaluate it to be sure
1941 if( pCurrentObject->FileType == AFS_FILE_TYPE_SYMLINK &&
1942 ( pCurrentObject->TargetFileId.Vnode == 0 ||
1943 pDirEntry->NameInformation.TargetName.Length == 0))
1946 ntStatus = AFSValidateSymLink( AuthGroup,
1949 if( !NT_SUCCESS( ntStatus))
1952 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1953 AFS_TRACE_LEVEL_ERROR,
1954 "AFSLocateNameEntry (FO: %p) Failed to evaluate possible DFS Link %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1956 &pDirEntry->NameInformation.FileName,
1957 pCurrentObject->FileId.Cell,
1958 pCurrentObject->FileId.Volume,
1959 pCurrentObject->FileId.Vnode,
1960 pCurrentObject->FileId.Unique,
1963 try_return( ntStatus);
1968 // Update the name array
1971 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1972 AFS_TRACE_LEVEL_VERBOSE,
1973 "AFSLocateNameEntry (FO: %p) Inserting name array entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1975 &pDirEntry->NameInformation.FileName,
1976 pCurrentObject->FileId.Cell,
1977 pCurrentObject->FileId.Volume,
1978 pCurrentObject->FileId.Vnode,
1979 pCurrentObject->FileId.Unique);
1981 ntStatus = AFSInsertNextElement( pNameArray,
1984 if( !NT_SUCCESS( ntStatus))
1987 try_return( ntStatus);
1993 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1994 AFS_TRACE_LEVEL_VERBOSE,
1995 "AFSLocateNameEntry (FO: %p) Completed processing %wZ Status %08lX\n",
2000 if( ( !NT_SUCCESS( ntStatus) &&
2001 ntStatus != STATUS_OBJECT_NAME_NOT_FOUND) ||
2002 ntStatus == STATUS_REPARSE)
2005 if( pDirEntry != NULL)
2008 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
2010 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2011 AFS_TRACE_LEVEL_VERBOSE,
2012 "AFSLocateNameEntry Decrement6 count on %wZ DE %p Ccb %p Cnt %d\n",
2013 &pDirEntry->NameInformation.FileName,
2018 ASSERT( lCount >= 0);
2020 else if( pParentDirEntry != NULL)
2023 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
2025 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2026 AFS_TRACE_LEVEL_VERBOSE,
2027 "AFSLocateNameEntry Decrement7 count on %wZ DE %p Ccb %p Cnt %d\n",
2028 &pParentDirEntry->NameInformation.FileName,
2033 ASSERT( lCount >= 0);
2036 if( bReleaseCurrentVolume)
2039 ASSERT( pCurrentVolume->VolumeReferenceCount > 1);
2041 lCount = InterlockedDecrement( &pCurrentVolume->VolumeReferenceCount);
2043 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2044 AFS_TRACE_LEVEL_VERBOSE,
2045 "AFSLocateNameEntry Decrement3 count on volume %p Cnt %d\n",
2050 if( RootPathName->Buffer != uniFullPathName.Buffer)
2053 AFSExFreePoolWithTag( uniFullPathName.Buffer, 0);
2059 if( *ParentDirectoryCB != NULL)
2062 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2063 AFS_TRACE_LEVEL_VERBOSE,
2064 "AFSLocateNameEntry Count on Parent %wZ DE %p Ccb %p Cnt %d\n",
2065 &(*ParentDirectoryCB)->NameInformation.FileName,
2068 (*ParentDirectoryCB)->DirOpenReferenceCount);
2071 if( *DirectoryCB != NULL)
2074 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2075 AFS_TRACE_LEVEL_VERBOSE,
2076 "AFSLocateNameEntry Count on %wZ DE %p Ccb %p Cnt %d\n",
2077 &(*DirectoryCB)->NameInformation.FileName,
2080 (*DirectoryCB)->DirOpenReferenceCount);
2084 if( bSubstituteName &&
2085 uniSearchName.Buffer != NULL)
2088 AFSExFreePoolWithTag( uniSearchName.Buffer, 0);
2096 AFSCreateDirEntry( IN GUID *AuthGroup,
2097 IN AFSObjectInfoCB *ParentObjectInfo,
2098 IN AFSDirectoryCB *ParentDirCB,
2099 IN PUNICODE_STRING FileName,
2100 IN PUNICODE_STRING ComponentName,
2101 IN ULONG Attributes,
2102 IN OUT AFSDirectoryCB **DirEntry)
2105 UNREFERENCED_PARAMETER(FileName);
2106 NTSTATUS ntStatus = STATUS_SUCCESS;
2107 AFSDirectoryCB *pDirNode = NULL, *pExistingDirNode = NULL;
2108 LARGE_INTEGER liFileSize = {0,0};
2114 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2115 AFS_TRACE_LEVEL_VERBOSE_2,
2116 "AFSCreateDirEntry Creating dir entry in parent %wZ FID %08lX-%08lX-%08lX-%08lX Component %wZ Attribs %08lX\n",
2117 &ParentDirCB->NameInformation.FileName,
2118 ParentObjectInfo->FileId.Cell,
2119 ParentObjectInfo->FileId.Volume,
2120 ParentObjectInfo->FileId.Vnode,
2121 ParentObjectInfo->FileId.Unique,
2126 // OK, before inserting the node into the parent tree, issue
2127 // the request to the service for node creation
2128 // We will need to drop the lock on the parent node since the create
2129 // could cause a callback into the file system to invalidate it's cache
2132 ntStatus = AFSNotifyFileCreate( AuthGroup,
2140 // If the returned status is STATUS_REPARSE then the entry exists
2141 // and we raced, get out.
2143 if( ntStatus == STATUS_REPARSE)
2146 *DirEntry = pDirNode;
2148 try_return( ntStatus = STATUS_SUCCESS);
2151 if( !NT_SUCCESS( ntStatus))
2154 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2155 AFS_TRACE_LEVEL_ERROR,
2156 "AFSCreateDirEntry Failed to create dir entry in parent %wZ FID %08lX-%08lX-%08lX-%08lX Component %wZ Attribs %08lX Status %08lX\n",
2157 &ParentDirCB->NameInformation.FileName,
2158 ParentObjectInfo->FileId.Cell,
2159 ParentObjectInfo->FileId.Volume,
2160 ParentObjectInfo->FileId.Vnode,
2161 ParentObjectInfo->FileId.Unique,
2166 try_return( ntStatus);
2170 // If AFSNotifyFileCreate returns pDirNode != NULL, then its
2171 // DirOpenReferenceCount is held.
2174 AFSAcquireExcl( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2178 // Before attempting to insert the new entry, check if we need to validate the parent
2181 if( BooleanFlagOn( ParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY))
2184 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2185 AFS_TRACE_LEVEL_VERBOSE,
2186 "AFSCreateDirEntry Verifying parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2187 &ParentDirCB->NameInformation.FileName,
2188 ParentObjectInfo->FileId.Cell,
2189 ParentObjectInfo->FileId.Volume,
2190 ParentObjectInfo->FileId.Vnode,
2191 ParentObjectInfo->FileId.Unique);
2193 ntStatus = AFSVerifyEntry( AuthGroup,
2196 if( !NT_SUCCESS( ntStatus))
2199 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2200 AFS_TRACE_LEVEL_ERROR,
2201 "AFSCreateDirEntry Failed to verify parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2202 &ParentDirCB->NameInformation.FileName,
2203 ParentObjectInfo->FileId.Cell,
2204 ParentObjectInfo->FileId.Volume,
2205 ParentObjectInfo->FileId.Vnode,
2206 ParentObjectInfo->FileId.Unique,
2209 AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2211 try_return( ntStatus);
2216 // Check for the entry in the event we raced with some other thread
2219 AFSLocateCaseSensitiveDirEntry( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
2220 (ULONG)pDirNode->CaseSensitiveTreeEntry.HashIndex,
2223 if( pExistingDirNode != NULL)
2225 if (AFSIsEqualFID( &pDirNode->ObjectInformation->FileId,
2226 &pExistingDirNode->ObjectInformation->FileId))
2229 if ( pExistingDirNode != pDirNode)
2232 lCount = InterlockedDecrement( &pDirNode->DirOpenReferenceCount);
2234 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2235 AFS_TRACE_LEVEL_VERBOSE,
2236 "AFSCreateDirEntry Decrement count on %wZ DE %p Cnt %d\n",
2237 &pDirNode->NameInformation.FileName,
2241 AFSDeleteDirEntry( ParentObjectInfo,
2244 lCount = InterlockedIncrement( &pExistingDirNode->DirOpenReferenceCount);
2246 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2247 AFS_TRACE_LEVEL_VERBOSE,
2248 "AFSCreateDirEntry Increment count on %wZ DE %p Cnt %d\n",
2249 &pExistingDirNode->NameInformation.FileName,
2253 *DirEntry = pExistingDirNode;
2256 AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2258 try_return( ntStatus = STATUS_SUCCESS);
2264 // Need to tear down this entry and rebuild it below
2267 if( pExistingDirNode->DirOpenReferenceCount <= 0)
2270 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2271 AFS_TRACE_LEVEL_VERBOSE,
2272 "AFSCreateDirEntry Different FIDs - Deleting DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
2274 &pExistingDirNode->NameInformation.FileName,
2275 pExistingDirNode->ObjectInformation->FileId.Cell,
2276 pExistingDirNode->ObjectInformation->FileId.Volume,
2277 pExistingDirNode->ObjectInformation->FileId.Vnode,
2278 pExistingDirNode->ObjectInformation->FileId.Unique,
2279 pDirNode->ObjectInformation->FileId.Cell,
2280 pDirNode->ObjectInformation->FileId.Volume,
2281 pDirNode->ObjectInformation->FileId.Vnode,
2282 pDirNode->ObjectInformation->FileId.Unique);
2284 AFSDeleteDirEntry( ParentObjectInfo,
2290 SetFlag( pExistingDirNode->Flags, AFS_DIR_ENTRY_DELETED);
2292 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2293 AFS_TRACE_LEVEL_VERBOSE,
2294 "AFSCreateDirEntry Different FIDs - Removing DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
2296 &pExistingDirNode->NameInformation.FileName,
2297 pExistingDirNode->ObjectInformation->FileId.Cell,
2298 pExistingDirNode->ObjectInformation->FileId.Volume,
2299 pExistingDirNode->ObjectInformation->FileId.Vnode,
2300 pExistingDirNode->ObjectInformation->FileId.Unique,
2301 pDirNode->ObjectInformation->FileId.Cell,
2302 pDirNode->ObjectInformation->FileId.Volume,
2303 pDirNode->ObjectInformation->FileId.Vnode,
2304 pDirNode->ObjectInformation->FileId.Unique);
2306 AFSRemoveNameEntry( ParentObjectInfo,
2312 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2313 AFS_TRACE_LEVEL_VERBOSE_2,
2314 "AFSCreateDirEntry Inserting dir entry in parent %wZ FID %08lX-%08lX-%08lX-%08lX Component %wZ\n",
2315 &ParentDirCB->NameInformation.FileName,
2316 ParentObjectInfo->FileId.Cell,
2317 ParentObjectInfo->FileId.Volume,
2318 ParentObjectInfo->FileId.Vnode,
2319 ParentObjectInfo->FileId.Unique,
2323 // Insert the directory node
2326 AFSInsertDirectoryNode( ParentObjectInfo,
2331 // Pass back the dir entry
2334 *DirEntry = pDirNode;
2336 AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2347 AFSInsertDirectoryNode( IN AFSObjectInfoCB *ParentObjectInfo,
2348 IN AFSDirectoryCB *DirEntry,
2349 IN BOOLEAN InsertInEnumList)
2357 ASSERT( ExIsResourceAcquiredExclusiveLite( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock));
2360 // Insert the node into the directory node tree
2363 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2364 AFS_TRACE_LEVEL_VERBOSE,
2365 "AFSInsertDirectoryNode Insert DE %p for %wZ Clearing NOT_IN flag\n",
2367 &DirEntry->NameInformation.FileName);
2369 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
2371 if( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead == NULL)
2374 ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = DirEntry;
2376 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2377 AFS_TRACE_LEVEL_VERBOSE,
2378 "AFSInsertDirectoryNode Insert DE %p to head of case sensitive tree for %wZ\n",
2380 &DirEntry->NameInformation.FileName);
2385 AFSInsertCaseSensitiveDirEntry( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
2388 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2389 AFS_TRACE_LEVEL_VERBOSE,
2390 "AFSInsertDirectoryNode Insert DE %p to case sensitive tree for %wZ\n",
2392 &DirEntry->NameInformation.FileName);
2395 if( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead == NULL)
2398 ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = DirEntry;
2400 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
2402 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2403 AFS_TRACE_LEVEL_VERBOSE,
2404 "AFSInsertDirectoryNode Insert DE %p to head of case insensitive tree for %wZ\n",
2406 &DirEntry->NameInformation.FileName);
2411 AFSInsertCaseInsensitiveDirEntry( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
2414 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2415 AFS_TRACE_LEVEL_VERBOSE,
2416 "AFSInsertDirectoryNode Insert DE %p to case insensitive tree for %wZ\n",
2418 &DirEntry->NameInformation.FileName);
2422 // Into the shortname tree
2425 if( DirEntry->Type.Data.ShortNameTreeEntry.HashIndex != 0)
2428 if( ParentObjectInfo->Specific.Directory.ShortNameTree == NULL)
2431 ParentObjectInfo->Specific.Directory.ShortNameTree = DirEntry;
2433 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2434 AFS_TRACE_LEVEL_VERBOSE,
2435 "AFSInsertDirectoryNode Insert DE %p to head of shortname tree for %wZ\n",
2437 &DirEntry->NameInformation.FileName);
2439 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
2444 if( !NT_SUCCESS( AFSInsertShortNameDirEntry( ParentObjectInfo->Specific.Directory.ShortNameTree,
2447 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2448 AFS_TRACE_LEVEL_VERBOSE,
2449 "AFSInsertDirectoryNode Failed to insert DE %p to shortname tree for %wZ\n",
2451 &DirEntry->NameInformation.FileName);
2455 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
2457 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2458 AFS_TRACE_LEVEL_VERBOSE,
2459 "AFSInsertDirectoryNode Insert DE %p to shortname tree for %wZ\n",
2461 &DirEntry->NameInformation.FileName);
2466 if( InsertInEnumList)
2470 // And insert the node into the directory list
2473 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2474 AFS_TRACE_LEVEL_VERBOSE,
2475 "AFSInsertDirectoryNode Inserting entry %p %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2477 &DirEntry->NameInformation.FileName,
2478 DirEntry->ObjectInformation->FileId.Cell,
2479 DirEntry->ObjectInformation->FileId.Volume,
2480 DirEntry->ObjectInformation->FileId.Vnode,
2481 DirEntry->ObjectInformation->FileId.Unique);
2483 if( ParentObjectInfo->Specific.Directory.DirectoryNodeListHead == NULL)
2486 ParentObjectInfo->Specific.Directory.DirectoryNodeListHead = DirEntry;
2491 ParentObjectInfo->Specific.Directory.DirectoryNodeListTail->ListEntry.fLink = (void *)DirEntry;
2493 DirEntry->ListEntry.bLink = (void *)ParentObjectInfo->Specific.Directory.DirectoryNodeListTail;
2496 ParentObjectInfo->Specific.Directory.DirectoryNodeListTail = DirEntry;
2498 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST);
2500 lCount = InterlockedIncrement( &ParentObjectInfo->Specific.Directory.DirectoryNodeCount);
2502 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
2503 AFS_TRACE_LEVEL_VERBOSE,
2504 "AFSInsertDirectoryNode Adding entry %wZ Inc Count %d to parent FID %08lX-%08lX-%08lX-%08lX\n",
2505 &DirEntry->NameInformation.FileName,
2507 ParentObjectInfo->FileId.Cell,
2508 ParentObjectInfo->FileId.Volume,
2509 ParentObjectInfo->FileId.Vnode,
2510 ParentObjectInfo->FileId.Unique);
2518 AFSDeleteDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
2519 IN AFSDirectoryCB *DirEntry)
2527 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2528 AFS_TRACE_LEVEL_VERBOSE,
2529 "AFSDeleteDirEntry Deleting dir entry in parent %p Entry %p %wZ FID %08lX-%08lX-%08lX-%08lX RefCount %d\n",
2532 &DirEntry->NameInformation.FileName,
2533 DirEntry->ObjectInformation->FileId.Cell,
2534 DirEntry->ObjectInformation->FileId.Volume,
2535 DirEntry->ObjectInformation->FileId.Vnode,
2536 DirEntry->ObjectInformation->FileId.Unique,
2537 DirEntry->DirOpenReferenceCount);
2539 ASSERT( DirEntry->DirOpenReferenceCount == 0);
2541 AFSRemoveDirNodeFromParent( ParentObjectInfo,
2546 // Free up the name buffer if it was reallocated
2549 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_RELEASE_NAME_BUFFER))
2552 AFSExFreePoolWithTag( DirEntry->NameInformation.FileName.Buffer, 0);
2555 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER))
2558 AFSExFreePoolWithTag( DirEntry->NameInformation.TargetName.Buffer, 0);
2562 // Dereference the object for this dir entry
2565 lCount = AFSObjectInfoDecrement( DirEntry->ObjectInformation,
2566 AFS_OBJECT_REFERENCE_DIRENTRY);
2568 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2569 AFS_TRACE_LEVEL_VERBOSE,
2570 "AFSDeleteDirEntry Decrement count on object %p Cnt %d\n",
2571 DirEntry->ObjectInformation,
2574 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_DELETED) &&
2575 DirEntry->ObjectInformation->Links == 0)
2578 SetFlag( DirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED);
2581 ExDeleteResourceLite( &DirEntry->NonPaged->Lock);
2583 AFSExFreePoolWithTag( DirEntry->NonPaged, AFS_DIR_ENTRY_NP_TAG);
2586 // Free up the dir entry
2589 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
2590 AFS_TRACE_LEVEL_VERBOSE,
2591 "AFSDeleteDirEntry AFS_DIR_ENTRY_TAG deallocating %p\n",
2594 AFSExFreePoolWithTag( DirEntry, AFS_DIR_ENTRY_TAG);
2599 AFSRemoveDirNodeFromParent( IN AFSObjectInfoCB *ParentObjectInfo,
2600 IN AFSDirectoryCB *DirEntry,
2601 IN BOOLEAN RemoveFromEnumList)
2604 NTSTATUS ntStatus = STATUS_SUCCESS;
2611 ASSERT( ExIsResourceAcquiredExclusiveLite( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock));
2613 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2614 AFS_TRACE_LEVEL_VERBOSE,
2615 "AFSRemoveDirNodeFromParent Removing DirEntry %p %wZ FID %08lX-%08lX-%08lX-%08lX from Parent %p\n",
2617 &DirEntry->NameInformation.FileName,
2618 DirEntry->ObjectInformation->FileId.Cell,
2619 DirEntry->ObjectInformation->FileId.Volume,
2620 DirEntry->ObjectInformation->FileId.Vnode,
2621 DirEntry->ObjectInformation->FileId.Unique,
2624 if( !BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
2627 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2628 AFS_TRACE_LEVEL_VERBOSE,
2629 "AFSRemoveDirNodeFromParent Removing DirEntry %p name %wZ\n",
2631 &DirEntry->NameInformation.FileName);
2633 AFSRemoveNameEntry( ParentObjectInfo,
2639 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2640 AFS_TRACE_LEVEL_VERBOSE,
2641 "AFSRemoveDirNodeFromParent DE %p for %wZ NOT removing entry due to flag set\n",
2643 &DirEntry->NameInformation.FileName);
2647 if( RemoveFromEnumList &&
2648 BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST))
2652 // And remove the entry from the enumeration list
2655 if( DirEntry->ListEntry.fLink == NULL)
2658 ParentObjectInfo->Specific.Directory.DirectoryNodeListTail = (AFSDirectoryCB *)DirEntry->ListEntry.bLink;
2663 ((AFSDirectoryCB *)DirEntry->ListEntry.fLink)->ListEntry.bLink = DirEntry->ListEntry.bLink;
2666 if( DirEntry->ListEntry.bLink == NULL)
2669 ParentObjectInfo->Specific.Directory.DirectoryNodeListHead = (AFSDirectoryCB *)DirEntry->ListEntry.fLink;
2674 ((AFSDirectoryCB *)DirEntry->ListEntry.bLink)->ListEntry.fLink = DirEntry->ListEntry.fLink;
2677 ASSERT( ParentObjectInfo->Specific.Directory.DirectoryNodeCount > 0);
2679 lCount = InterlockedDecrement( &ParentObjectInfo->Specific.Directory.DirectoryNodeCount);
2681 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST);
2683 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
2684 AFS_TRACE_LEVEL_VERBOSE,
2685 "AFSRemoveDirNodeFromParent Removing entry %wZ Dec Count %d to parent FID %08lX-%08lX-%08lX-%08lX\n",
2686 &DirEntry->NameInformation.FileName,
2688 ParentObjectInfo->FileId.Cell,
2689 ParentObjectInfo->FileId.Volume,
2690 ParentObjectInfo->FileId.Vnode,
2691 ParentObjectInfo->FileId.Unique);
2693 DirEntry->ListEntry.fLink = NULL;
2694 DirEntry->ListEntry.bLink = NULL;
2702 AFSFixupTargetName( IN OUT PUNICODE_STRING FileName,
2703 IN OUT PUNICODE_STRING TargetFileName)
2706 NTSTATUS ntStatus = STATUS_SUCCESS;
2707 UNICODE_STRING uniFileName;
2713 // We will process backwards from the end of the name looking
2714 // for the first \ we encounter
2717 uniFileName.Length = FileName->Length;
2718 uniFileName.MaximumLength = FileName->MaximumLength;
2720 uniFileName.Buffer = FileName->Buffer;
2725 if( uniFileName.Buffer[ (uniFileName.Length/sizeof( WCHAR)) - 1] == L'\\')
2729 // Subtract one more character off of the filename if it is not the root
2732 if( uniFileName.Length > sizeof( WCHAR))
2735 uniFileName.Length -= sizeof( WCHAR);
2739 // Now build up the target name
2742 TargetFileName->Length = FileName->Length - uniFileName.Length;
2745 // If we are not on the root then fixup the name
2748 if( uniFileName.Length > sizeof( WCHAR))
2751 TargetFileName->Length -= sizeof( WCHAR);
2753 TargetFileName->Buffer = &uniFileName.Buffer[ (uniFileName.Length/sizeof( WCHAR)) + 1];
2758 TargetFileName->Buffer = &uniFileName.Buffer[ uniFileName.Length/sizeof( WCHAR)];
2762 // Fixup the passed back filename length
2765 FileName->Length = uniFileName.Length;
2767 TargetFileName->MaximumLength = TargetFileName->Length;
2772 uniFileName.Length -= sizeof( WCHAR);
2780 AFSParseName( IN PIRP Irp,
2782 OUT PUNICODE_STRING FileName,
2783 OUT PUNICODE_STRING ParsedFileName,
2784 OUT PUNICODE_STRING RootFileName,
2785 OUT ULONG *ParseFlags,
2786 OUT AFSVolumeCB **VolumeCB,
2787 OUT AFSDirectoryCB **ParentDirectoryCB,
2788 OUT AFSNameArrayHdr **NameArray)
2791 NTSTATUS ntStatus = STATUS_SUCCESS;
2792 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2793 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2794 UNICODE_STRING uniFullName, uniComponentName, uniRemainingPath;
2796 AFSDirectoryCB *pDirEntry = NULL;
2797 USHORT usIndex = 0, usDriveIndex = 0;
2798 AFSCcb *pRelatedCcb = NULL;
2799 AFSNameArrayHdr *pNameArray = NULL, *pRelatedNameArray = NULL;
2800 USHORT usComponentIndex = 0;
2801 USHORT usComponentLength = 0;
2802 AFSVolumeCB *pVolumeCB = NULL;
2803 AFSFcb *pRelatedFcb = NULL;
2804 BOOLEAN bReleaseTreeLock = FALSE;
2805 BOOLEAN bIsAllShare = FALSE;
2812 // Indicate we are opening a root ...
2815 *ParseFlags = AFS_PARSE_FLAG_ROOT_ACCESS;
2817 *ParentDirectoryCB = NULL;
2819 if( pIrpSp->FileObject->RelatedFileObject != NULL)
2822 pRelatedFcb = (AFSFcb *)pIrpSp->FileObject->RelatedFileObject->FsContext;
2824 pRelatedCcb = (AFSCcb *)pIrpSp->FileObject->RelatedFileObject->FsContext2;
2826 pRelatedNameArray = pRelatedCcb->NameArray;
2828 uniFullName = pIrpSp->FileObject->FileName;
2830 ASSERT( pRelatedFcb != NULL);
2833 // No wild cards in the name
2836 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2837 AFS_TRACE_LEVEL_VERBOSE_2,
2838 "AFSParseName (%p) Relative open for %wZ FID %08lX-%08lX-%08lX-%08lX component %wZ\n",
2840 &pRelatedCcb->DirectoryCB->NameInformation.FileName,
2841 pRelatedCcb->DirectoryCB->ObjectInformation->FileId.Cell,
2842 pRelatedCcb->DirectoryCB->ObjectInformation->FileId.Volume,
2843 pRelatedCcb->DirectoryCB->ObjectInformation->FileId.Vnode,
2844 pRelatedCcb->DirectoryCB->ObjectInformation->FileId.Unique,
2847 if( FsRtlDoesNameContainWildCards( &uniFullName))
2850 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2851 AFS_TRACE_LEVEL_ERROR,
2852 "AFSParseName (%p) Component %wZ contains wild cards\n",
2856 try_return( ntStatus = STATUS_OBJECT_NAME_INVALID);
2859 pVolumeCB = pRelatedFcb->ObjectInformation->VolumeCB;
2861 pDirEntry = pRelatedCcb->DirectoryCB;
2863 *FileName = pIrpSp->FileObject->FileName;
2866 // Grab the root node while checking state
2869 AFSAcquireShared( pVolumeCB->VolumeLock,
2872 if( BooleanFlagOn( pVolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
2873 BooleanFlagOn( pVolumeCB->Flags, AFS_VOLUME_FLAGS_OFFLINE))
2877 // The volume has been taken off line so fail the access
2880 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2881 AFS_TRACE_LEVEL_ERROR,
2882 "AFSParseName (%p) Volume %08lX:%08lX OFFLINE/INVALID\n",
2884 pVolumeCB->ObjectInformation.FileId.Cell,
2885 pVolumeCB->ObjectInformation.FileId.Volume);
2887 AFSReleaseResource( pVolumeCB->VolumeLock);
2889 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
2892 if( BooleanFlagOn( pVolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_VERIFY))
2895 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2896 AFS_TRACE_LEVEL_VERBOSE,
2897 "AFSParseName (%p) Verifying root of volume %08lX:%08lX\n",
2899 pVolumeCB->ObjectInformation.FileId.Cell,
2900 pVolumeCB->ObjectInformation.FileId.Volume);
2902 ntStatus = AFSVerifyVolume( (ULONGLONG)PsGetCurrentProcessId(),
2905 if( !NT_SUCCESS( ntStatus))
2908 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2909 AFS_TRACE_LEVEL_ERROR,
2910 "AFSParseName (%p) Failed verification of root Status %08lX\n",
2914 AFSReleaseResource( pVolumeCB->VolumeLock);
2916 try_return( ntStatus);
2920 AFSReleaseResource( pVolumeCB->VolumeLock);
2922 if( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY))
2925 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2926 AFS_TRACE_LEVEL_VERBOSE,
2927 "AFSParseName (%p) Verifying parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2929 &pDirEntry->NameInformation.FileName,
2930 pDirEntry->ObjectInformation->FileId.Cell,
2931 pDirEntry->ObjectInformation->FileId.Volume,
2932 pDirEntry->ObjectInformation->FileId.Vnode,
2933 pDirEntry->ObjectInformation->FileId.Unique);
2936 // Directory TreeLock should be exclusively held
2939 AFSAcquireExcl( pDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
2942 ntStatus = AFSVerifyEntry( AuthGroup,
2945 AFSReleaseResource( pDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
2947 if( !NT_SUCCESS( ntStatus))
2950 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2951 AFS_TRACE_LEVEL_VERBOSE,
2952 "AFSParseName (%p) Failed verification of parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2954 &pDirEntry->NameInformation.FileName,
2955 pDirEntry->ObjectInformation->FileId.Cell,
2956 pDirEntry->ObjectInformation->FileId.Volume,
2957 pDirEntry->ObjectInformation->FileId.Vnode,
2958 pDirEntry->ObjectInformation->FileId.Unique,
2961 try_return( ntStatus);
2966 // Create our full path name buffer
2969 uniFullName.MaximumLength = pRelatedCcb->FullFileName.Length +
2971 pIrpSp->FileObject->FileName.Length +
2974 uniFullName.Length = 0;
2976 uniFullName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2977 uniFullName.MaximumLength,
2978 AFS_NAME_BUFFER_THREE_TAG);
2980 if( uniFullName.Buffer == NULL)
2983 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2984 AFS_TRACE_LEVEL_ERROR,
2985 "AFSParseName (%p) Failed to allocate full name buffer\n",
2988 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2991 RtlZeroMemory( uniFullName.Buffer,
2992 uniFullName.MaximumLength);
2994 RtlCopyMemory( uniFullName.Buffer,
2995 pRelatedCcb->FullFileName.Buffer,
2996 pRelatedCcb->FullFileName.Length);
2998 uniFullName.Length = pRelatedCcb->FullFileName.Length;
3000 usComponentIndex = (USHORT)(uniFullName.Length/sizeof( WCHAR));
3002 usComponentLength = pIrpSp->FileObject->FileName.Length;
3004 if( uniFullName.Buffer[ (uniFullName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
3005 pIrpSp->FileObject->FileName.Length > 0 &&
3006 pIrpSp->FileObject->FileName.Buffer[ 0] != L'\\' &&
3007 pIrpSp->FileObject->FileName.Buffer[ 0] != L':')
3010 uniFullName.Buffer[ (uniFullName.Length/sizeof( WCHAR))] = L'\\';
3012 uniFullName.Length += sizeof( WCHAR);
3014 usComponentLength += sizeof( WCHAR);
3017 if( pIrpSp->FileObject->FileName.Length > 0)
3020 RtlCopyMemory( &uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)],
3021 pIrpSp->FileObject->FileName.Buffer,
3022 pIrpSp->FileObject->FileName.Length);
3024 uniFullName.Length += pIrpSp->FileObject->FileName.Length;
3027 *RootFileName = uniFullName;
3030 // We populate up to the current parent
3033 if( pRelatedNameArray == NULL)
3037 // Init and populate our name array
3040 pNameArray = AFSInitNameArray( NULL,
3043 if( pNameArray == NULL)
3046 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3047 AFS_TRACE_LEVEL_VERBOSE,
3048 "AFSParseName (%p) Failed to initialize name array\n",
3051 AFSExFreePoolWithTag( uniFullName.Buffer, 0);
3053 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3056 ntStatus = AFSPopulateNameArray( pNameArray,
3058 pRelatedCcb->DirectoryCB);
3064 // Init and populate our name array
3067 pNameArray = AFSInitNameArray( NULL,
3068 pRelatedNameArray->MaxElementCount);
3070 if( pNameArray == NULL)
3073 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3074 AFS_TRACE_LEVEL_VERBOSE,
3075 "AFSParseName (%p) Failed to initialize name array\n",
3078 AFSExFreePoolWithTag( uniFullName.Buffer, 0);
3080 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3083 ntStatus = AFSPopulateNameArrayFromRelatedArray( pNameArray,
3085 pRelatedCcb->DirectoryCB);
3088 if( !NT_SUCCESS( ntStatus))
3091 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3092 AFS_TRACE_LEVEL_VERBOSE,
3093 "AFSParseName (%p) Failed to populate name array\n",
3096 AFSExFreePoolWithTag( uniFullName.Buffer, 0);
3098 try_return( ntStatus);
3101 ParsedFileName->Length = usComponentLength;
3102 ParsedFileName->MaximumLength = uniFullName.MaximumLength;
3104 ParsedFileName->Buffer = &uniFullName.Buffer[ usComponentIndex];
3107 // Indicate to caller that RootFileName must be freed
3110 SetFlag( *ParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
3112 *NameArray = pNameArray;
3115 // Increment our volume reference count
3118 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
3120 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
3121 AFS_TRACE_LEVEL_VERBOSE,
3122 "AFSParseName Increment count on volume %p Cnt %d\n",
3126 *VolumeCB = pVolumeCB;
3128 *ParentDirectoryCB = pDirEntry;
3130 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3131 AFS_TRACE_LEVEL_VERBOSE_2,
3132 "AFSParseName (%p) Returning full name %wZ\n",
3136 try_return( ntStatus);
3140 // No wild cards in the name
3143 uniFullName = pIrpSp->FileObject->FileName;
3145 if( FsRtlDoesNameContainWildCards( &uniFullName) ||
3146 uniFullName.Length < AFSServerName.Length)
3149 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3150 AFS_TRACE_LEVEL_ERROR,
3151 "AFSParseName (%p) Name %wZ contains wild cards or too short\n",
3155 try_return( ntStatus = STATUS_OBJECT_NAME_INVALID);
3159 // The name is a fully qualified name. Parse out the server/share names and
3160 // point to the root qualified name
3161 // First thing is to locate the server name
3164 FsRtlDissectName( uniFullName,
3168 uniFullName = uniRemainingPath;
3171 // This component is the server name we are serving
3174 if( RtlCompareUnicodeString( &uniComponentName,
3180 // Drive letter based name?
3183 uniFullName = pIrpSp->FileObject->FileName;
3185 while( usIndex < uniFullName.Length/sizeof( WCHAR))
3188 if( uniFullName.Buffer[ usIndex] == L':')
3191 uniFullName.Buffer = &uniFullName.Buffer[ usIndex + 2];
3193 uniFullName.Length -= (usIndex + 2) * sizeof( WCHAR);
3195 usDriveIndex = usIndex - 1;
3204 // Do we have the right server name now?
3207 FsRtlDissectName( uniFullName,
3211 uniFullName = uniRemainingPath;
3214 // This component is the server name we are serving
3217 if( RtlCompareUnicodeString( &uniComponentName,
3222 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3223 AFS_TRACE_LEVEL_ERROR,
3224 "AFSParseName (%p) Name %wZ does not have server name\n",
3226 &pIrpSp->FileObject->FileName);
3228 try_return( ntStatus = STATUS_BAD_NETWORK_NAME);
3232 // Validate this drive letter is actively mapped
3235 if( usDriveIndex > 0 &&
3236 !AFSIsDriveMapped( pIrpSp->FileObject->FileName.Buffer[ usDriveIndex]))
3239 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3240 AFS_TRACE_LEVEL_ERROR,
3241 "AFSParseName (%p) Name %wZ contains invalid drive mapping\n",
3243 &pIrpSp->FileObject->FileName);
3245 try_return( ntStatus = STATUS_BAD_NETWORK_NAME);
3249 if( FsRtlDoesNameContainWildCards( &uniFullName))
3252 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3253 AFS_TRACE_LEVEL_ERROR,
3254 "AFSParseName (%p) Component %wZ contains wild cards\n",
3258 try_return( ntStatus = STATUS_OBJECT_NAME_INVALID);
3261 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3262 AFS_TRACE_LEVEL_VERBOSE_2,
3263 "AFSParseName (%p) Processing full name %wZ\n",
3267 if( uniFullName.Length > 0 &&
3268 uniFullName.Buffer[ (uniFullName.Length/sizeof( WCHAR)) - 1] == L'\\')
3271 uniFullName.Length -= sizeof( WCHAR);
3275 // Be sure we are online and ready to go
3278 AFSAcquireShared( AFSGlobalRoot->VolumeLock,
3281 if( BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
3282 BooleanFlagOn( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE))
3286 // The volume has been taken off line so fail the access
3289 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3290 AFS_TRACE_LEVEL_ERROR,
3291 "AFSParseName (%p) Volume %08lX:%08lX OFFLINE/INVALID\n",
3293 AFSGlobalRoot->ObjectInformation.FileId.Cell,
3294 AFSGlobalRoot->ObjectInformation.FileId.Volume);
3296 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3298 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
3301 if( BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_VERIFY))
3304 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3305 AFS_TRACE_LEVEL_VERBOSE,
3306 "AFSParseName (%p) Verifying root of volume %08lX:%08lX\n",
3308 AFSGlobalRoot->ObjectInformation.FileId.Cell,
3309 AFSGlobalRoot->ObjectInformation.FileId.Volume);
3311 ntStatus = AFSVerifyVolume( (ULONGLONG)PsGetCurrentProcessId(),
3314 if( !NT_SUCCESS( ntStatus))
3317 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3318 AFS_TRACE_LEVEL_ERROR,
3319 "AFSParseName (%p) Failed verification of root Status %08lX\n",
3323 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3325 try_return( ntStatus);
3329 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3331 if( !BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
3334 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3335 AFS_TRACE_LEVEL_VERBOSE,
3336 "AFSParseName (%p) Enumerating global root of volume %08lX:%08lX\n",
3338 AFSGlobalRoot->ObjectInformation.FileId.Cell,
3339 AFSGlobalRoot->ObjectInformation.FileId.Volume);
3341 ntStatus = AFSEnumerateGlobalRoot( AuthGroup);
3343 if( !NT_SUCCESS( ntStatus))
3346 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3347 AFS_TRACE_LEVEL_ERROR,
3348 "AFSParseName (%p) Failed enumeraiton of root Status %08lX\n",
3352 try_return( ntStatus);
3357 // Check for the \\Server access and return it as though it were \\Server\Globalroot
3360 if( uniRemainingPath.Buffer == NULL ||
3361 ( uniRemainingPath.Length == sizeof( WCHAR) &&
3362 uniRemainingPath.Buffer[ 0] == L'\\'))
3365 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3366 AFS_TRACE_LEVEL_VERBOSE_2,
3367 "AFSParseName (%p) Returning global root access\n",
3370 lCount = InterlockedIncrement( &AFSGlobalRoot->DirectoryCB->DirOpenReferenceCount);
3372 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3373 AFS_TRACE_LEVEL_VERBOSE,
3374 "AFSParseName Increment2 count on %wZ DE %p Ccb %p Cnt %d\n",
3375 &AFSGlobalRoot->DirectoryCB->NameInformation.FileName,
3376 AFSGlobalRoot->DirectoryCB,
3382 FileName->Length = 0;
3383 FileName->MaximumLength = 0;
3384 FileName->Buffer = NULL;
3386 try_return( ntStatus = STATUS_SUCCESS);
3389 *RootFileName = uniFullName;
3392 // Include the starting \ in the root name
3395 if( RootFileName->Buffer[ 0] != L'\\')
3397 RootFileName->Buffer--;
3398 RootFileName->Length += sizeof( WCHAR);
3399 RootFileName->MaximumLength += sizeof( WCHAR);
3403 // Get the 'share' name
3406 FsRtlDissectName( uniFullName,
3410 if( FsRtlDoesNameContainWildCards( &uniFullName))
3413 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3414 AFS_TRACE_LEVEL_ERROR,
3415 "AFSParseName (%p) Component %wZ contains wild cards\n",
3419 try_return( ntStatus = STATUS_OBJECT_NAME_INVALID);
3423 // If this is the ALL access then perform some additional processing
3426 if( uniComponentName.Length == 0 ||
3427 RtlCompareUnicodeString( &uniComponentName,
3435 // If there is nothing else then get out
3438 if( uniRemainingPath.Buffer == NULL ||
3439 uniRemainingPath.Length == 0 ||
3440 ( uniRemainingPath.Length == sizeof( WCHAR) &&
3441 uniRemainingPath.Buffer[ 0] == L'\\'))
3444 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3445 AFS_TRACE_LEVEL_VERBOSE_2,
3446 "AFSParseName (%p) Returning global root access\n",
3449 lCount = InterlockedIncrement( &AFSGlobalRoot->DirectoryCB->DirOpenReferenceCount);
3451 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3452 AFS_TRACE_LEVEL_VERBOSE,
3453 "AFSParseName Increment3 count on %wZ DE %p Ccb %p Cnt %d\n",
3454 &AFSGlobalRoot->DirectoryCB->NameInformation.FileName,
3455 AFSGlobalRoot->DirectoryCB,
3461 FileName->Length = 0;
3462 FileName->MaximumLength = 0;
3463 FileName->Buffer = NULL;
3465 try_return( ntStatus = STATUS_SUCCESS);
3469 // Process the name again to strip off the ALL portion
3472 uniFullName = uniRemainingPath;
3474 FsRtlDissectName( uniFullName,
3479 // Check for the PIOCtl name
3482 if( RtlCompareUnicodeString( &uniComponentName,
3487 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3488 AFS_TRACE_LEVEL_VERBOSE_2,
3489 "AFSParseName (%p) Returning root PIOCtl access\n",
3492 lCount = InterlockedIncrement( &AFSGlobalRoot->DirectoryCB->DirOpenReferenceCount);
3494 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3495 AFS_TRACE_LEVEL_VERBOSE,
3496 "AFSParseName Increment4 count on %wZ DE %p Ccb %p Cnt %d\n",
3497 &AFSGlobalRoot->DirectoryCB->NameInformation.FileName,
3498 AFSGlobalRoot->DirectoryCB,
3502 ClearFlag( *ParseFlags, AFS_PARSE_FLAG_ROOT_ACCESS);
3506 *FileName = AFSPIOCtlName;
3508 try_return( ntStatus = STATUS_SUCCESS);
3511 else if( (pDirEntry = AFSGetSpecialShareNameEntry( &uniComponentName,
3512 &uniRemainingPath)) != NULL)
3515 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3516 AFS_TRACE_LEVEL_VERBOSE_2,
3517 "AFSParseName (%p) Returning root share name %wZ access\n",
3522 // Add in the full share name to pass back
3525 if( uniRemainingPath.Buffer != NULL)
3529 // This routine strips off the leading slash so add it back in
3532 uniRemainingPath.Buffer--;
3533 uniRemainingPath.Length += sizeof( WCHAR);
3534 uniRemainingPath.MaximumLength += sizeof( WCHAR);
3537 // And the cell name
3540 uniRemainingPath.Buffer -= (uniComponentName.Length/sizeof( WCHAR));
3541 uniRemainingPath.Length += uniComponentName.Length;
3542 uniRemainingPath.MaximumLength += uniComponentName.Length;
3544 uniComponentName = uniRemainingPath;
3549 *FileName = uniComponentName;
3551 ClearFlag( *ParseFlags, AFS_PARSE_FLAG_ROOT_ACCESS);
3553 *ParentDirectoryCB = pDirEntry;
3555 try_return( ntStatus = STATUS_SUCCESS);
3559 // Determine the 'share' we are accessing
3562 ulCRC = AFSGenerateCRC( &uniComponentName,
3565 AFSAcquireShared( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
3568 bReleaseTreeLock = TRUE;
3570 AFSLocateCaseSensitiveDirEntry( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
3574 if( pDirEntry == NULL)
3577 ulCRC = AFSGenerateCRC( &uniComponentName,
3580 AFSLocateCaseInsensitiveDirEntry( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
3584 if( pDirEntry == NULL)
3588 // OK, if this component is a valid short name then try
3589 // a lookup in the short name tree
3592 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
3593 RtlIsNameLegalDOS8Dot3( &uniComponentName,
3598 AFSLocateShortNameDirEntry( AFSGlobalRoot->ObjectInformation.Specific.Directory.ShortNameTree,
3603 if( pDirEntry == NULL)
3607 // Check with the service whether it is a valid cell name
3610 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
3612 bReleaseTreeLock = FALSE;
3614 ntStatus = AFSCheckCellName( AuthGroup,
3618 if( !NT_SUCCESS( ntStatus))
3622 uniRemainingPath.Length == 0 &&
3623 ntStatus == STATUS_OBJECT_PATH_NOT_FOUND)
3626 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3627 AFS_TRACE_LEVEL_VERBOSE,
3628 "AFSParseName (%p) AFSCheckCellName %wZ returned path not found; ntStatus %08X\n",
3631 STATUS_OBJECT_NAME_NOT_FOUND);
3633 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
3636 try_return( ntStatus);
3642 if( bReleaseTreeLock)
3644 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
3649 // Be sure we are starting from the correct volume
3652 if( pDirEntry->ObjectInformation->VolumeCB != AFSGlobalRoot)
3656 // We dropped the global root in the CheckCellName routine which is the
3657 // only way we can be here
3660 pVolumeCB = pDirEntry->ObjectInformation->VolumeCB;
3663 // Init our name array
3666 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
3669 if( pNameArray == NULL)
3672 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3673 AFS_TRACE_LEVEL_VERBOSE,
3674 "AFSParseName (%p) Failed to initialize name array\n",
3677 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3680 ntStatus = AFSInsertNextElement( pNameArray,
3681 pVolumeCB->DirectoryCB);
3686 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3687 AFS_TRACE_LEVEL_VERBOSE,
3688 "AFSParseName (%p) Failed to insert name array element\n",
3691 try_return( ntStatus);
3695 // In this case don't add back in the 'share' name since that is where we are
3696 // starting. Just put the leading slash back in
3699 if( uniRemainingPath.Buffer != NULL)
3702 uniRemainingPath.Buffer--;
3703 uniRemainingPath.Length += sizeof( WCHAR);
3704 uniRemainingPath.MaximumLength += sizeof( WCHAR);
3706 if( uniRemainingPath.Length > sizeof( WCHAR))
3709 ClearFlag( *ParseFlags, AFS_PARSE_FLAG_ROOT_ACCESS);
3713 // Pass back the parent being the root of the volume
3716 *ParentDirectoryCB = pVolumeCB->DirectoryCB;
3722 // Pass back a root slash
3725 uniRemainingPath = uniComponentName;
3727 uniRemainingPath.Buffer--;
3728 uniRemainingPath.Length = sizeof( WCHAR);
3729 uniRemainingPath.MaximumLength = sizeof( WCHAR);
3732 // This is a root open so pass back no parent
3739 pVolumeCB = AFSGlobalRoot;
3742 // Init our name array
3745 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
3747 if( pNameArray == NULL)
3750 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3751 AFS_TRACE_LEVEL_VERBOSE,
3752 "AFSParseName (%p) Failed to initialize name array\n",
3755 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3759 // Add back in the 'share' portion of the name since we will parse it out on return
3762 if( uniRemainingPath.Buffer != NULL)
3766 // This routine strips off the leading slash so add it back in
3769 uniRemainingPath.Buffer--;
3770 uniRemainingPath.Length += sizeof( WCHAR);
3771 uniRemainingPath.MaximumLength += sizeof( WCHAR);
3773 if( uniRemainingPath.Length > sizeof( WCHAR))
3776 ClearFlag( *ParseFlags, AFS_PARSE_FLAG_ROOT_ACCESS);
3780 // And the cell name
3783 uniRemainingPath.Buffer -= (uniComponentName.Length/sizeof( WCHAR));
3784 uniRemainingPath.Length += uniComponentName.Length;
3785 uniRemainingPath.MaximumLength += uniComponentName.Length;
3790 uniRemainingPath = uniComponentName;
3794 // And the leading slash again ...
3797 uniRemainingPath.Buffer--;
3798 uniRemainingPath.Length += sizeof( WCHAR);
3799 uniRemainingPath.MaximumLength += sizeof( WCHAR);
3802 // Pass back the parent being the volume root
3805 *ParentDirectoryCB = pVolumeCB->DirectoryCB;
3809 // Return the remaining portion as the file name
3812 *FileName = uniRemainingPath;
3814 *ParsedFileName = uniRemainingPath;
3816 *NameArray = pNameArray;
3818 *VolumeCB = pVolumeCB;
3821 // Increment our reference on the volume
3824 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
3826 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
3827 AFS_TRACE_LEVEL_VERBOSE,
3828 "AFSParseName Increment2 count on global volume %p Cnt %d\n",
3834 if( NT_SUCCESS( ntStatus))
3837 if( *ParentDirectoryCB != NULL)
3840 lCount = InterlockedIncrement( &(*ParentDirectoryCB)->DirOpenReferenceCount);
3842 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3843 AFS_TRACE_LEVEL_VERBOSE,
3844 "AFSParseName Increment1 count on %wZ DE %p Ccb %p Cnt %d\n",
3845 &(*ParentDirectoryCB)->NameInformation.FileName,
3846 (*ParentDirectoryCB),
3852 if( *VolumeCB != NULL)
3854 ASSERT( (*VolumeCB)->VolumeReferenceCount > 1);
3857 if( ntStatus != STATUS_SUCCESS)
3860 if( pNameArray != NULL)
3863 AFSFreeNameArray( pNameArray);
3872 AFSCheckCellName( IN GUID *AuthGroup,
3873 IN UNICODE_STRING *CellName,
3874 OUT AFSDirectoryCB **ShareDirEntry)
3877 NTSTATUS ntStatus = STATUS_SUCCESS;
3878 UNICODE_STRING uniName;
3879 AFSDirEnumEntry *pDirEnumEntry = NULL;
3880 AFSDirHdr *pDirHdr = &AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr;
3881 AFSDirectoryCB *pDirNode = NULL;
3882 UNICODE_STRING uniDirName, uniTargetName;
3883 AFSVolumeCB *pVolumeCB = NULL;
3890 // Look for some default names we will not handle
3893 RtlInitUnicodeString( &uniName,
3896 if( RtlCompareUnicodeString( &uniName,
3901 try_return( ntStatus = STATUS_NO_SUCH_FILE);
3904 RtlInitUnicodeString( &uniName,
3907 if( RtlCompareUnicodeString( &uniName,
3912 try_return( ntStatus = STATUS_NO_SUCH_FILE);
3915 RtlInitUnicodeString( &uniName,
3918 if( RtlCompareUnicodeString( &uniName,
3923 try_return( ntStatus = STATUS_NO_SUCH_FILE);
3926 RtlInitUnicodeString( &uniName,
3929 if( RtlCompareUnicodeString( &uniName,
3934 try_return( ntStatus = STATUS_NO_SUCH_FILE);
3938 // OK, ask the CM about this component name
3941 ntStatus = AFSEvaluateTargetByName( AuthGroup,
3942 &AFSGlobalRoot->ObjectInformation,
3946 if( !NT_SUCCESS( ntStatus))
3949 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3950 AFS_TRACE_LEVEL_WARNING,
3951 "AFSCheckCellName entry %wZ does not exist parent FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
3953 AFSGlobalRoot->ObjectInformation.FileId.Cell,
3954 AFSGlobalRoot->ObjectInformation.FileId.Volume,
3955 AFSGlobalRoot->ObjectInformation.FileId.Vnode,
3956 AFSGlobalRoot->ObjectInformation.FileId.Unique,
3959 try_return( ntStatus);
3963 // OK, we have a dir enum entry back so add it to the root node
3966 uniDirName = *CellName;
3968 uniTargetName.Length = (USHORT)pDirEnumEntry->TargetNameLength;
3969 uniTargetName.MaximumLength = uniTargetName.Length;
3970 uniTargetName.Buffer = (WCHAR *)((char *)pDirEnumEntry + pDirEnumEntry->TargetNameOffset);
3973 // Is this entry a root volume entry?
3976 if( pDirEnumEntry->FileId.Cell != AFSGlobalRoot->ObjectInformation.FileId.Cell ||
3977 pDirEnumEntry->FileId.Volume != AFSGlobalRoot->ObjectInformation.FileId.Volume)
3981 // Build the root volume entry
3984 ntStatus = AFSBuildRootVolume( AuthGroup,
3985 &pDirEnumEntry->FileId,
3988 if( !NT_SUCCESS( ntStatus))
3990 try_return( ntStatus);
3993 *ShareDirEntry = pVolumeCB->DirectoryCB;
3995 lCount = InterlockedIncrement( &pVolumeCB->DirectoryCB->DirOpenReferenceCount);
3997 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3998 AFS_TRACE_LEVEL_VERBOSE,
3999 "AFSCheckCellName Increment1 count on %wZ DE %p Ccb %p Cnt %d\n",
4000 &pVolumeCB->DirectoryCB->NameInformation.FileName,
4001 pVolumeCB->DirectoryCB,
4005 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
4007 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
4008 AFS_TRACE_LEVEL_VERBOSE,
4009 "AFSCheckCellName Increment count on volume %p Cnt %d\n",
4016 lCount = InterlockedIncrement( &pDirHdr->ContentIndex);
4018 pDirNode = AFSInitDirEntry( &AFSGlobalRoot->ObjectInformation,
4024 if( pDirNode == NULL)
4027 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4031 // Init the short name if we have one
4034 if( pDirEnumEntry->ShortNameLength > 0)
4037 pDirNode->NameInformation.ShortNameLength = pDirEnumEntry->ShortNameLength;
4039 RtlCopyMemory( pDirNode->NameInformation.ShortName,
4040 pDirEnumEntry->ShortName,
4041 pDirNode->NameInformation.ShortNameLength);
4044 AFSAcquireExcl( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
4048 // Insert the node into the name tree
4051 ASSERT( ExIsResourceAcquiredExclusiveLite( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock));
4053 if( pDirHdr->CaseSensitiveTreeHead == NULL)
4056 pDirHdr->CaseSensitiveTreeHead = pDirNode;
4061 if( !NT_SUCCESS( AFSInsertCaseSensitiveDirEntry( pDirHdr->CaseSensitiveTreeHead,
4065 AFSDeleteDirEntry( &AFSGlobalRoot->ObjectInformation,
4068 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
4070 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4074 ClearFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
4076 if( pDirHdr->CaseInsensitiveTreeHead == NULL)
4079 pDirHdr->CaseInsensitiveTreeHead = pDirNode;
4081 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
4086 AFSInsertCaseInsensitiveDirEntry( pDirHdr->CaseInsensitiveTreeHead,
4090 if( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListHead == NULL)
4093 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListHead = pDirNode;
4098 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListTail->ListEntry.fLink = pDirNode;
4100 pDirNode->ListEntry.bLink = AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListTail;
4103 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListTail = pDirNode;
4105 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST);
4107 lCount = InterlockedIncrement( &AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeCount);
4109 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
4110 AFS_TRACE_LEVEL_VERBOSE,
4111 "AFSCheckCellName Adding entry %wZ Inc Count %d to parent FID %08lX-%08lX-%08lX-%08lX\n",
4112 &pDirNode->NameInformation.FileName,
4114 AFSGlobalRoot->ObjectInformation.FileId.Cell,
4115 AFSGlobalRoot->ObjectInformation.FileId.Volume,
4116 AFSGlobalRoot->ObjectInformation.FileId.Vnode,
4117 AFSGlobalRoot->ObjectInformation.FileId.Unique);
4119 lCount = InterlockedIncrement( &pDirNode->DirOpenReferenceCount);
4121 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
4122 AFS_TRACE_LEVEL_VERBOSE,
4123 "AFSCheckCellName Increment2 count on %wZ DE %p Ccb %p Cnt %d\n",
4124 &pDirNode->NameInformation.FileName,
4129 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
4132 // Pass back the dir node
4135 *ShareDirEntry = pDirNode;
4140 if( pDirEnumEntry != NULL)
4143 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_31_TAG);
4151 AFSBuildMountPointTarget( IN GUID *AuthGroup,
4152 IN AFSDirectoryCB *DirectoryCB,
4153 OUT AFSVolumeCB **TargetVolumeCB)
4156 NTSTATUS ntStatus = STATUS_SUCCESS;
4157 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
4158 AFSDirEnumEntry *pDirEntry = NULL;
4159 ULONGLONG ullIndex = 0;
4160 AFSVolumeCB *pVolumeCB = NULL;
4161 AFSFileID stTargetFileID;
4163 BOOLEAN bReleaseVolumeLock = FALSE;
4169 // Loop on each entry, building the chain until we encounter the final target
4172 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4173 AFS_TRACE_LEVEL_VERBOSE_2,
4174 "AFSBuildMountPointTarget Building target directory for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4175 &DirectoryCB->NameInformation.FileName,
4176 DirectoryCB->ObjectInformation->FileId.Cell,
4177 DirectoryCB->ObjectInformation->FileId.Volume,
4178 DirectoryCB->ObjectInformation->FileId.Vnode,
4179 DirectoryCB->ObjectInformation->FileId.Unique);
4182 // Do we need to evaluate the node?
4185 //if( DirectoryCB->ObjectInformation->TargetFileId.Vnode == 0 &&
4186 // DirectoryCB->ObjectInformation->TargetFileId.Unique == 0)
4190 // Go evaluate the current target to get the target fid
4193 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4194 AFS_TRACE_LEVEL_VERBOSE_2,
4195 "AFSBuildMountPointTarget Evaluating target %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4196 &DirectoryCB->NameInformation.FileName,
4197 DirectoryCB->ObjectInformation->FileId.Cell,
4198 DirectoryCB->ObjectInformation->FileId.Volume,
4199 DirectoryCB->ObjectInformation->FileId.Vnode,
4200 DirectoryCB->ObjectInformation->FileId.Unique);
4202 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
4207 if( !NT_SUCCESS( ntStatus))
4210 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4211 AFS_TRACE_LEVEL_ERROR,
4212 "AFSBuildMountPointTarget Failed to evaluate target %wZ Status %08lX\n",
4213 &DirectoryCB->NameInformation.FileName,
4215 try_return( ntStatus);
4218 if( pDirEntry->TargetFileId.Vnode == 0 &&
4219 pDirEntry->TargetFileId.Unique == 0)
4222 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4223 AFS_TRACE_LEVEL_ERROR,
4224 "AFSBuildMountPointTarget Target %wZ FID %08lX-%08lX-%08lX-%08lX service returned zero FID\n",
4225 &DirectoryCB->NameInformation.FileName,
4226 DirectoryCB->ObjectInformation->FileId.Cell,
4227 DirectoryCB->ObjectInformation->FileId.Volume,
4228 DirectoryCB->ObjectInformation->FileId.Vnode,
4229 DirectoryCB->ObjectInformation->FileId.Unique);
4231 try_return( ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED);
4234 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
4237 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
4238 &DirectoryCB->Flags,
4239 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
4240 (USHORT)pDirEntry->TargetNameLength);
4242 if( !NT_SUCCESS( ntStatus))
4245 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
4247 try_return( ntStatus);
4250 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
4252 DirectoryCB->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
4255 stTargetFileID = DirectoryCB->ObjectInformation->TargetFileId;
4258 // Try to locate this FID. First the volume then the
4262 ullIndex = AFSCreateHighIndex( &stTargetFileID);
4264 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4265 AFS_TRACE_LEVEL_VERBOSE,
4266 "AFSBuildMountPointTarget Acquiring RDR VolumeTreeLock lock %p EXCL %08lX\n",
4267 &pDevExt->Specific.RDR.VolumeTreeLock,
4268 PsGetCurrentThread());
4270 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock,
4273 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4274 AFS_TRACE_LEVEL_VERBOSE_2,
4275 "AFSBuildMountPointTarget Locating volume for target %I64X\n",
4278 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
4280 (AFSBTreeEntry **)&pVolumeCB);
4283 // We can be processing a request for a target that is on a volume
4284 // we have never seen before.
4287 if( pVolumeCB == NULL)
4291 // Locking is held correctly in init routine
4294 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
4297 // Go init the root of the volume
4300 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4301 AFS_TRACE_LEVEL_VERBOSE_2,
4302 "AFSBuildMountPointTarget Initializing root for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4303 &DirectoryCB->NameInformation.FileName,
4304 DirectoryCB->ObjectInformation->FileId.Cell,
4305 DirectoryCB->ObjectInformation->FileId.Volume,
4306 DirectoryCB->ObjectInformation->FileId.Vnode,
4307 DirectoryCB->ObjectInformation->FileId.Unique);
4309 ntStatus = AFSInitVolume( AuthGroup,
4313 if( !NT_SUCCESS( ntStatus))
4316 try_return( ntStatus);
4320 // pVolumeCB->VolumeLock held exclusive and
4321 // pVolumeCB->VolumeReferenceCount has been incremented
4322 // pVolumeCB->RootFcb == NULL
4325 bReleaseVolumeLock = TRUE;
4331 // AFSInitVolume returns with a VolumeReferenceCount
4332 // obtain one to match
4335 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
4337 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
4338 AFS_TRACE_LEVEL_VERBOSE,
4339 "AFSBuildMountPointTarget Increment count on volume %p Cnt %d\n",
4343 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
4346 if( pVolumeCB->RootFcb == NULL)
4349 if ( bReleaseVolumeLock == FALSE)
4352 AFSAcquireExcl( pVolumeCB->VolumeLock,
4355 bReleaseVolumeLock = TRUE;
4359 // Initialize the root fcb for this volume
4362 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
4365 if( !NT_SUCCESS( ntStatus))
4368 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
4370 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
4371 AFS_TRACE_LEVEL_VERBOSE,
4372 "AFSBuildMountPoint Decrement count on volume %p Cnt %d\n",
4376 AFSReleaseResource( pVolumeCB->VolumeLock);
4378 try_return( ntStatus);
4382 // Drop the lock acquired above
4385 AFSReleaseResource( &pVolumeCB->RootFcb->NPFcb->Resource);
4388 if ( bReleaseVolumeLock == TRUE)
4391 AFSReleaseResource( pVolumeCB->VolumeLock);
4394 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4395 AFS_TRACE_LEVEL_VERBOSE_2,
4396 "AFSBuildMountPointTarget Evaluated target of %wZ FID %08lX-%08lX-%08lX-%08lX as root volume\n",
4397 &pVolumeCB->DirectoryCB->NameInformation.FileName,
4398 pVolumeCB->ObjectInformation.FileId.Cell,
4399 pVolumeCB->ObjectInformation.FileId.Volume,
4400 pVolumeCB->ObjectInformation.FileId.Vnode,
4401 pVolumeCB->ObjectInformation.FileId.Unique);
4403 *TargetVolumeCB = pVolumeCB;
4410 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
4418 AFSBuildRootVolume( IN GUID *AuthGroup,
4419 IN AFSFileID *FileId,
4420 OUT AFSVolumeCB **TargetVolumeCB)
4423 NTSTATUS ntStatus = STATUS_SUCCESS;
4424 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
4425 ULONGLONG ullIndex = 0;
4426 AFSVolumeCB *pVolumeCB = NULL;
4428 BOOLEAN bReleaseVolumeLock = FALSE;
4433 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4434 AFS_TRACE_LEVEL_VERBOSE_2,
4435 "AFSBuildRootVolume Building target volume for FID %08lX-%08lX-%08lX-%08lX\n",
4441 ullIndex = AFSCreateHighIndex( FileId);
4443 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4444 AFS_TRACE_LEVEL_VERBOSE,
4445 "AFSBuildRootVolume Acquiring RDR VolumeTreeLock lock %p EXCL %08lX\n",
4446 &pDevExt->Specific.RDR.VolumeTreeLock,
4447 PsGetCurrentThread());
4449 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock,
4452 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4453 AFS_TRACE_LEVEL_VERBOSE_2,
4454 "AFSBuildRootVolume Locating volume for target %I64X\n",
4457 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
4459 (AFSBTreeEntry **)&pVolumeCB);
4462 // We can be processing a request for a target that is on a volume
4463 // we have never seen before.
4466 if( pVolumeCB == NULL)
4470 // Locking is held correctly in init routine
4473 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
4476 // Go init the root of the volume
4479 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4480 AFS_TRACE_LEVEL_VERBOSE_2,
4481 "AFSBuildRootVolume Initializing root for FID %08lX-%08lX-%08lX-%08lX\n",
4487 ntStatus = AFSInitVolume( AuthGroup,
4491 if( !NT_SUCCESS( ntStatus))
4494 try_return( ntStatus);
4498 // pVolumeCB->VolumeLock is held exclusive
4499 // pVolumeCB->VolumeReferenceCount has been incremented
4500 // pVolumeCB->RootFcb == NULL
4503 bReleaseVolumeLock = TRUE;
4509 // AFSInitVolume returns with a VolumeReferenceCount
4510 // obtain one to match
4513 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
4515 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
4516 AFS_TRACE_LEVEL_VERBOSE,
4517 "AFSBuildRootVolume Increment count on volume %p Cnt %d\n",
4521 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
4525 if( pVolumeCB->RootFcb == NULL)
4528 if ( bReleaseVolumeLock == FALSE)
4531 AFSAcquireExcl( pVolumeCB->VolumeLock,
4534 bReleaseVolumeLock = TRUE;
4538 // Initialize the root fcb for this volume
4541 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
4544 if( !NT_SUCCESS( ntStatus))
4547 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
4549 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
4550 AFS_TRACE_LEVEL_VERBOSE,
4551 "AFSBuildRootVolume Decrement count on volume %p Cnt %d\n",
4555 AFSReleaseResource( pVolumeCB->VolumeLock);
4557 try_return( ntStatus);
4561 // Drop the lock acquired above
4564 AFSReleaseResource( &pVolumeCB->RootFcb->NPFcb->Resource);
4567 if ( bReleaseVolumeLock == TRUE)
4570 AFSReleaseResource( pVolumeCB->VolumeLock);
4573 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4574 AFS_TRACE_LEVEL_VERBOSE_2,
4575 "AFSBuildRootVolume Evaluated target of %wZ FID %08lX-%08lX-%08lX-%08lX as root volume\n",
4576 &pVolumeCB->DirectoryCB->NameInformation.FileName,
4577 pVolumeCB->ObjectInformation.FileId.Cell,
4578 pVolumeCB->ObjectInformation.FileId.Volume,
4579 pVolumeCB->ObjectInformation.FileId.Vnode,
4580 pVolumeCB->ObjectInformation.FileId.Unique);
4582 *TargetVolumeCB = pVolumeCB;
4593 AFSProcessDFSLink( IN AFSDirectoryCB *DirEntry,
4594 IN PFILE_OBJECT FileObject,
4595 IN UNICODE_STRING *RemainingPath,
4599 NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
4600 UNICODE_STRING uniReparseName;
4601 UNICODE_STRING uniMUPDeviceName;
4602 UNICODE_STRING uniIOMgrDeviceName;
4603 AFSDirEnumEntry *pDirEntry = NULL;
4609 // Build up the name to reparse
4612 RtlInitUnicodeString( &uniMUPDeviceName,
4615 RtlInitUnicodeString( &uniIOMgrDeviceName,
4618 uniReparseName.Length = 0;
4619 uniReparseName.Buffer = NULL;
4622 // Be sure we have a target name
4625 if( DirEntry->NameInformation.TargetName.Length == 0)
4628 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
4633 if( !NT_SUCCESS( ntStatus) ||
4634 pDirEntry->TargetNameLength == 0)
4637 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4638 AFS_TRACE_LEVEL_ERROR,
4639 "AFSProcessDFSLink EvaluateTargetByID failed for Fcb %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4640 &DirEntry->NameInformation.FileName,
4641 DirEntry->ObjectInformation->FileId.Cell,
4642 DirEntry->ObjectInformation->FileId.Volume,
4643 DirEntry->ObjectInformation->FileId.Vnode,
4644 DirEntry->ObjectInformation->FileId.Unique,
4647 if( NT_SUCCESS( ntStatus))
4650 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
4653 try_return( ntStatus);
4657 // Update the target name
4660 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
4663 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
4665 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
4666 (USHORT)pDirEntry->TargetNameLength);
4668 if( !NT_SUCCESS( ntStatus))
4671 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4672 AFS_TRACE_LEVEL_ERROR,
4673 "AFSProcessDFSLink UpdateTargetName failed for Fcb %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4674 &DirEntry->NameInformation.FileName,
4675 DirEntry->ObjectInformation->FileId.Cell,
4676 DirEntry->ObjectInformation->FileId.Volume,
4677 DirEntry->ObjectInformation->FileId.Vnode,
4678 DirEntry->ObjectInformation->FileId.Unique,
4681 AFSReleaseResource( &DirEntry->NonPaged->Lock);
4683 try_return( ntStatus);
4686 AFSConvertToShared( &DirEntry->NonPaged->Lock);
4690 AFSAcquireShared( &DirEntry->NonPaged->Lock,
4694 uniReparseName.MaximumLength = uniMUPDeviceName.Length +
4696 DirEntry->NameInformation.TargetName.Length +
4699 if( RemainingPath != NULL &&
4700 RemainingPath->Length > 0)
4703 uniReparseName.MaximumLength += RemainingPath->Length;
4707 // Allocate the reparse buffer
4710 uniReparseName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
4711 uniReparseName.MaximumLength,
4712 AFS_REPARSE_NAME_TAG);
4714 if( uniReparseName.Buffer == NULL)
4717 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4718 AFS_TRACE_LEVEL_ERROR,
4719 "AFSProcessDFSLink uniReparseName.Buffer == NULL Fcb %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4720 &DirEntry->NameInformation.FileName,
4721 DirEntry->ObjectInformation->FileId.Cell,
4722 DirEntry->ObjectInformation->FileId.Volume,
4723 DirEntry->ObjectInformation->FileId.Vnode,
4724 DirEntry->ObjectInformation->FileId.Unique,
4725 STATUS_INSUFFICIENT_RESOURCES);
4727 AFSReleaseResource( &DirEntry->NonPaged->Lock);
4729 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4733 // Start building the name
4736 if ( DirEntry->NameInformation.TargetName.Buffer[ 0] != L'\\' &&
4737 DirEntry->NameInformation.TargetName.Buffer[ 1] == L':')
4740 RtlCopyMemory( uniReparseName.Buffer,
4741 uniIOMgrDeviceName.Buffer,
4742 uniIOMgrDeviceName.Length);
4744 uniReparseName.Length = uniIOMgrDeviceName.Length;
4749 RtlCopyMemory( uniReparseName.Buffer,
4750 uniMUPDeviceName.Buffer,
4751 uniMUPDeviceName.Length);
4753 uniReparseName.Length = uniMUPDeviceName.Length;
4755 if( DirEntry->NameInformation.TargetName.Buffer[ 0] != L'\\')
4758 uniReparseName.Buffer[ uniReparseName.Length/sizeof( WCHAR)] = L'\\';
4760 uniReparseName.Length += sizeof( WCHAR);
4764 RtlCopyMemory( &uniReparseName.Buffer[ uniReparseName.Length/sizeof( WCHAR)],
4765 DirEntry->NameInformation.TargetName.Buffer,
4766 DirEntry->NameInformation.TargetName.Length);
4768 uniReparseName.Length += DirEntry->NameInformation.TargetName.Length;
4770 AFSReleaseResource( &DirEntry->NonPaged->Lock);
4772 if( RemainingPath != NULL &&
4773 RemainingPath->Length > 0)
4776 if( uniReparseName.Buffer[ (uniReparseName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
4777 RemainingPath->Buffer[ 0] != L'\\')
4780 uniReparseName.Buffer[ uniReparseName.Length/sizeof( WCHAR)] = L'\\';
4782 uniReparseName.Length += sizeof( WCHAR);
4785 RtlCopyMemory( &uniReparseName.Buffer[ uniReparseName.Length/sizeof( WCHAR)],
4786 RemainingPath->Buffer,
4787 RemainingPath->Length);
4789 uniReparseName.Length += RemainingPath->Length;
4793 // Update the name in the file object
4796 if( FileObject->FileName.Buffer != NULL)
4799 AFSExFreePoolWithTag( FileObject->FileName.Buffer, 0);
4802 FileObject->FileName = uniReparseName;
4804 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4805 AFS_TRACE_LEVEL_VERBOSE,
4806 "AFSProcessDFSLink Reparsing access to Fcb %wZ FID %08lX-%08lX-%08lX-%08lX to %wZ\n",
4807 &DirEntry->NameInformation.FileName,
4808 DirEntry->ObjectInformation->FileId.Cell,
4809 DirEntry->ObjectInformation->FileId.Volume,
4810 DirEntry->ObjectInformation->FileId.Vnode,
4811 DirEntry->ObjectInformation->FileId.Unique,
4815 // Return status reparse ...
4818 ntStatus = STATUS_REPARSE;
4825 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);