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 ( pCurrentObject->ParentObjectInformation == NULL)
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->ParentObjectInformation->FileId.Cell,
297 pCurrentObject->ParentObjectInformation->FileId.Volume,
298 pCurrentObject->ParentObjectInformation->FileId.Vnode,
299 pCurrentObject->ParentObjectInformation->FileId.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: %08lX) 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 pParentObjectInfo = pCurrentObject->ParentObjectInformation;
1705 ASSERT( pParentObjectInfo != NULL);
1707 AFSAcquireExcl( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
1710 AFSAcquireExcl( pCurrentObject->VolumeCB->ObjectInfoTree.TreeLock,
1713 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
1715 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1716 AFS_TRACE_LEVEL_VERBOSE,
1717 "AFSLocateNameEntry Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
1718 &pDirEntry->NameInformation.FileName,
1723 ASSERT( lCount >= 0);
1728 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING|AFS_SUBSYSTEM_CLEANUP_PROCESSING,
1729 AFS_TRACE_LEVEL_VERBOSE,
1730 "AFSLocateNameEntry Deleting dir entry %p (%p) for %wZ\n",
1733 &pDirEntry->NameInformation.FileName);
1736 // Remove and delete the directory entry from the parent list
1739 AFSDeleteDirEntry( pParentObjectInfo,
1742 AFSAcquireShared( &pCurrentObject->NonPagedInfo->ObjectInfoLock,
1745 if( pCurrentObject->ObjectReferenceCount <= 0)
1748 if( BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_INSERTED_HASH_TREE))
1751 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
1752 AFS_TRACE_LEVEL_VERBOSE,
1753 "AFSLocateNameEntry Removing object %p from volume tree\n",
1756 AFSRemoveHashEntry( &pCurrentObject->VolumeCB->ObjectInfoTree.TreeHead,
1757 &pCurrentObject->TreeEntry);
1759 ClearFlag( pCurrentObject->Flags, AFS_OBJECT_INSERTED_HASH_TREE);
1763 AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock);
1768 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1769 AFS_TRACE_LEVEL_VERBOSE,
1770 "AFSLocateNameEntry Setting DELETE flag in dir entry %p for %wZ\n",
1772 &pDirEntry->NameInformation.FileName);
1774 SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
1776 AFSRemoveNameEntry( pParentObjectInfo,
1780 AFSReleaseResource( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
1782 AFSReleaseResource( pCurrentObject->VolumeCB->ObjectInfoTree.TreeLock);
1785 // We deleted the dir entry so check if there is any remaining portion
1786 // of the name to process.
1789 if( uniRemainingPath.Length > 0)
1792 ntStatus = STATUS_OBJECT_PATH_NOT_FOUND;
1794 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1795 AFS_TRACE_LEVEL_VERBOSE,
1796 "AFSLocateNameEntry (FO: %08lX) Returning path not found(2) for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1799 pCurrentObject->FileId.Cell,
1800 pCurrentObject->FileId.Volume,
1801 pCurrentObject->FileId.Vnode,
1802 pCurrentObject->FileId.Unique);
1807 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
1809 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1810 AFS_TRACE_LEVEL_VERBOSE,
1811 "AFSLocateNameEntry (FO: %p) Returning name not found(2) for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1814 pCurrentObject->FileId.Cell,
1815 pCurrentObject->FileId.Volume,
1816 pCurrentObject->FileId.Vnode,
1817 pCurrentObject->FileId.Unique);
1820 // Pass back the directory entries
1823 *ParentDirectoryCB = pParentDirEntry;
1825 *DirectoryCB = NULL;
1827 *VolumeCB = pCurrentVolume;
1829 if( ComponentName != NULL)
1832 *ComponentName = uniComponentName;
1835 *RootPathName = uniFullPathName;
1839 if( ntStatus != STATUS_SUCCESS)
1842 try_return( ntStatus);
1846 // Decrement the previous parent
1849 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
1851 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1852 AFS_TRACE_LEVEL_VERBOSE,
1853 "AFSLocateNameEntry Decrement5 count on Parent %wZ DE %p Ccb %p Cnt %d\n",
1854 &pParentDirEntry->NameInformation.FileName,
1859 ASSERT( lCount >= 0);
1862 // If we ended up substituting a name in the component then update
1863 // the full path and update the pointers
1866 if( bSubstituteName)
1869 BOOLEAN bRelativeOpen = FALSE;
1871 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1872 AFS_TRACE_LEVEL_VERBOSE_2,
1873 "AFSLocateNameEntry (FO: %p) Substituting %wZ into %wZ Index %08lX\n",
1879 if( FileObject != NULL &&
1880 FileObject->RelatedFileObject != NULL)
1883 bRelativeOpen = TRUE;
1887 // AFSSubstituteNameInPath will replace the uniFullPathName.Buffer
1888 // and free the prior Buffer contents but only if the fourth
1889 // parameter is TRUE.
1892 ntStatus = AFSSubstituteNameInPath( &uniFullPathName,
1897 bAllocatedSymLinkBuffer ||
1900 if( !NT_SUCCESS( ntStatus))
1903 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1904 AFS_TRACE_LEVEL_ERROR,
1905 "AFSLocateNameEntry (FO: %p) Failure to substitute %wZ into %wZ Index %08lX Status %08lX\n",
1912 try_return( ntStatus);
1916 // We have substituted a name into the buffer so if we do this again for this
1917 // path, we need to free up the buffer we allocated.
1920 bSubstitutedName = TRUE;
1924 // Update the search parameters
1927 uniPathName = uniRemainingPath;
1930 // Check if the is a SymLink entry but has no Target FileID or Name. In this
1931 // case it might be a DFS Link so let's go and evaluate it to be sure
1934 if( pCurrentObject->FileType == AFS_FILE_TYPE_SYMLINK &&
1935 ( pCurrentObject->TargetFileId.Vnode == 0 ||
1936 pDirEntry->NameInformation.TargetName.Length == 0))
1939 ntStatus = AFSValidateSymLink( AuthGroup,
1942 if( !NT_SUCCESS( ntStatus))
1945 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1946 AFS_TRACE_LEVEL_ERROR,
1947 "AFSLocateNameEntry (FO: %p) Failed to evaluate possible DFS Link %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1949 &pDirEntry->NameInformation.FileName,
1950 pCurrentObject->FileId.Cell,
1951 pCurrentObject->FileId.Volume,
1952 pCurrentObject->FileId.Vnode,
1953 pCurrentObject->FileId.Unique,
1956 try_return( ntStatus);
1961 // Update the name array
1964 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1965 AFS_TRACE_LEVEL_VERBOSE,
1966 "AFSLocateNameEntry (FO: %p) Inserting name array entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1968 &pDirEntry->NameInformation.FileName,
1969 pCurrentObject->FileId.Cell,
1970 pCurrentObject->FileId.Volume,
1971 pCurrentObject->FileId.Vnode,
1972 pCurrentObject->FileId.Unique);
1974 ntStatus = AFSInsertNextElement( pNameArray,
1977 if( !NT_SUCCESS( ntStatus))
1980 try_return( ntStatus);
1986 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1987 AFS_TRACE_LEVEL_VERBOSE,
1988 "AFSLocateNameEntry (FO: %p) Completed processing %wZ Status %08lX\n",
1993 if( ( !NT_SUCCESS( ntStatus) &&
1994 ntStatus != STATUS_OBJECT_NAME_NOT_FOUND) ||
1995 ntStatus == STATUS_REPARSE)
1998 if( pDirEntry != NULL)
2001 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
2003 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2004 AFS_TRACE_LEVEL_VERBOSE,
2005 "AFSLocateNameEntry Decrement6 count on %wZ DE %p Ccb %p Cnt %d\n",
2006 &pDirEntry->NameInformation.FileName,
2011 ASSERT( lCount >= 0);
2013 else if( pParentDirEntry != NULL)
2016 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
2018 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2019 AFS_TRACE_LEVEL_VERBOSE,
2020 "AFSLocateNameEntry Decrement7 count on %wZ DE %p Ccb %p Cnt %d\n",
2021 &pParentDirEntry->NameInformation.FileName,
2026 ASSERT( lCount >= 0);
2029 if( bReleaseCurrentVolume)
2032 ASSERT( pCurrentVolume->VolumeReferenceCount > 1);
2034 lCount = InterlockedDecrement( &pCurrentVolume->VolumeReferenceCount);
2036 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2037 AFS_TRACE_LEVEL_VERBOSE,
2038 "AFSLocateNameEntry Decrement3 count on volume %p Cnt %d\n",
2043 if( RootPathName->Buffer != uniFullPathName.Buffer)
2046 AFSExFreePoolWithTag( uniFullPathName.Buffer, 0);
2052 if( *ParentDirectoryCB != NULL)
2055 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2056 AFS_TRACE_LEVEL_VERBOSE,
2057 "AFSLocateNameEntry Count on Parent %wZ DE %p Ccb %p Cnt %d\n",
2058 &(*ParentDirectoryCB)->NameInformation.FileName,
2061 (*ParentDirectoryCB)->DirOpenReferenceCount);
2064 if( *DirectoryCB != NULL)
2067 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2068 AFS_TRACE_LEVEL_VERBOSE,
2069 "AFSLocateNameEntry Count on %wZ DE %p Ccb %p Cnt %d\n",
2070 &(*DirectoryCB)->NameInformation.FileName,
2073 (*DirectoryCB)->DirOpenReferenceCount);
2077 if( bSubstituteName &&
2078 uniSearchName.Buffer != NULL)
2081 AFSExFreePoolWithTag( uniSearchName.Buffer, 0);
2089 AFSCreateDirEntry( IN GUID *AuthGroup,
2090 IN AFSObjectInfoCB *ParentObjectInfo,
2091 IN AFSDirectoryCB *ParentDirCB,
2092 IN PUNICODE_STRING FileName,
2093 IN PUNICODE_STRING ComponentName,
2094 IN ULONG Attributes,
2095 IN OUT AFSDirectoryCB **DirEntry)
2098 UNREFERENCED_PARAMETER(FileName);
2099 NTSTATUS ntStatus = STATUS_SUCCESS;
2100 AFSDirectoryCB *pDirNode = NULL, *pExistingDirNode = NULL;
2101 LARGE_INTEGER liFileSize = {0,0};
2107 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2108 AFS_TRACE_LEVEL_VERBOSE_2,
2109 "AFSCreateDirEntry Creating dir entry in parent %wZ FID %08lX-%08lX-%08lX-%08lX Component %wZ Attribs %08lX\n",
2110 &ParentDirCB->NameInformation.FileName,
2111 ParentObjectInfo->FileId.Cell,
2112 ParentObjectInfo->FileId.Volume,
2113 ParentObjectInfo->FileId.Vnode,
2114 ParentObjectInfo->FileId.Unique,
2119 // OK, before inserting the node into the parent tree, issue
2120 // the request to the service for node creation
2121 // We will need to drop the lock on the parent node since the create
2122 // could cause a callback into the file system to invalidate it's cache
2125 ntStatus = AFSNotifyFileCreate( AuthGroup,
2133 // If the returned status is STATUS_REPARSE then the entry exists
2134 // and we raced, get out.
2136 if( ntStatus == STATUS_REPARSE)
2139 *DirEntry = pDirNode;
2141 try_return( ntStatus = STATUS_SUCCESS);
2144 if( !NT_SUCCESS( ntStatus))
2147 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2148 AFS_TRACE_LEVEL_ERROR,
2149 "AFSCreateDirEntry Failed to create dir entry in parent %wZ FID %08lX-%08lX-%08lX-%08lX Component %wZ Attribs %08lX Status %08lX\n",
2150 &ParentDirCB->NameInformation.FileName,
2151 ParentObjectInfo->FileId.Cell,
2152 ParentObjectInfo->FileId.Volume,
2153 ParentObjectInfo->FileId.Vnode,
2154 ParentObjectInfo->FileId.Unique,
2159 try_return( ntStatus);
2163 // If AFSNotifyFileCreate returns pDirNode != NULL, then its
2164 // DirOpenReferenceCount is held.
2167 AFSAcquireExcl( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2171 // Before attempting to insert the new entry, check if we need to validate the parent
2174 if( BooleanFlagOn( ParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY))
2177 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2178 AFS_TRACE_LEVEL_VERBOSE,
2179 "AFSCreateDirEntry Verifying parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2180 &ParentDirCB->NameInformation.FileName,
2181 ParentObjectInfo->FileId.Cell,
2182 ParentObjectInfo->FileId.Volume,
2183 ParentObjectInfo->FileId.Vnode,
2184 ParentObjectInfo->FileId.Unique);
2186 ntStatus = AFSVerifyEntry( AuthGroup,
2189 if( !NT_SUCCESS( ntStatus))
2192 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2193 AFS_TRACE_LEVEL_ERROR,
2194 "AFSCreateDirEntry Failed to verify parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2195 &ParentDirCB->NameInformation.FileName,
2196 ParentObjectInfo->FileId.Cell,
2197 ParentObjectInfo->FileId.Volume,
2198 ParentObjectInfo->FileId.Vnode,
2199 ParentObjectInfo->FileId.Unique,
2202 AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2204 try_return( ntStatus);
2209 // Check for the entry in the event we raced with some other thread
2212 AFSLocateCaseSensitiveDirEntry( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
2213 (ULONG)pDirNode->CaseSensitiveTreeEntry.HashIndex,
2216 if( pExistingDirNode != NULL)
2218 if (AFSIsEqualFID( &pDirNode->ObjectInformation->FileId,
2219 &pExistingDirNode->ObjectInformation->FileId))
2222 if ( pExistingDirNode != pDirNode)
2225 lCount = InterlockedDecrement( &pDirNode->DirOpenReferenceCount);
2227 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2228 AFS_TRACE_LEVEL_VERBOSE,
2229 "AFSCreateDirEntry Decrement count on %wZ DE %p Cnt %d\n",
2230 &pDirNode->NameInformation.FileName,
2234 AFSDeleteDirEntry( ParentObjectInfo,
2237 lCount = InterlockedIncrement( &pExistingDirNode->DirOpenReferenceCount);
2239 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2240 AFS_TRACE_LEVEL_VERBOSE,
2241 "AFSCreateDirEntry Increment count on %wZ DE %p Cnt %d\n",
2242 &pExistingDirNode->NameInformation.FileName,
2246 *DirEntry = pExistingDirNode;
2249 AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2251 try_return( ntStatus = STATUS_SUCCESS);
2257 // Need to tear down this entry and rebuild it below
2260 if( pExistingDirNode->DirOpenReferenceCount <= 0)
2263 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2264 AFS_TRACE_LEVEL_VERBOSE,
2265 "AFSCreateDirEntry Different FIDs - Deleting DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
2267 &pExistingDirNode->NameInformation.FileName,
2268 pExistingDirNode->ObjectInformation->FileId.Cell,
2269 pExistingDirNode->ObjectInformation->FileId.Volume,
2270 pExistingDirNode->ObjectInformation->FileId.Vnode,
2271 pExistingDirNode->ObjectInformation->FileId.Unique,
2272 pDirNode->ObjectInformation->FileId.Cell,
2273 pDirNode->ObjectInformation->FileId.Volume,
2274 pDirNode->ObjectInformation->FileId.Vnode,
2275 pDirNode->ObjectInformation->FileId.Unique);
2277 AFSDeleteDirEntry( ParentObjectInfo,
2283 SetFlag( pExistingDirNode->Flags, AFS_DIR_ENTRY_DELETED);
2285 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2286 AFS_TRACE_LEVEL_VERBOSE,
2287 "AFSCreateDirEntry Different FIDs - Removing DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
2289 &pExistingDirNode->NameInformation.FileName,
2290 pExistingDirNode->ObjectInformation->FileId.Cell,
2291 pExistingDirNode->ObjectInformation->FileId.Volume,
2292 pExistingDirNode->ObjectInformation->FileId.Vnode,
2293 pExistingDirNode->ObjectInformation->FileId.Unique,
2294 pDirNode->ObjectInformation->FileId.Cell,
2295 pDirNode->ObjectInformation->FileId.Volume,
2296 pDirNode->ObjectInformation->FileId.Vnode,
2297 pDirNode->ObjectInformation->FileId.Unique);
2299 AFSRemoveNameEntry( ParentObjectInfo,
2305 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2306 AFS_TRACE_LEVEL_VERBOSE_2,
2307 "AFSCreateDirEntry Inserting dir entry in parent %wZ FID %08lX-%08lX-%08lX-%08lX Component %wZ\n",
2308 &ParentDirCB->NameInformation.FileName,
2309 ParentObjectInfo->FileId.Cell,
2310 ParentObjectInfo->FileId.Volume,
2311 ParentObjectInfo->FileId.Vnode,
2312 ParentObjectInfo->FileId.Unique,
2316 // Insert the directory node
2319 AFSInsertDirectoryNode( ParentObjectInfo,
2324 // Pass back the dir entry
2327 *DirEntry = pDirNode;
2329 AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2340 AFSInsertDirectoryNode( IN AFSObjectInfoCB *ParentObjectInfo,
2341 IN AFSDirectoryCB *DirEntry,
2342 IN BOOLEAN InsertInEnumList)
2350 ASSERT( ExIsResourceAcquiredExclusiveLite( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock));
2353 // Insert the node into the directory node tree
2356 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2357 AFS_TRACE_LEVEL_VERBOSE,
2358 "AFSInsertDirectoryNode Insert DE %p for %wZ Clearing NOT_IN flag\n",
2360 &DirEntry->NameInformation.FileName);
2362 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
2364 if( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead == NULL)
2367 ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = DirEntry;
2369 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2370 AFS_TRACE_LEVEL_VERBOSE,
2371 "AFSInsertDirectoryNode Insert DE %p to head of case sensitive tree for %wZ\n",
2373 &DirEntry->NameInformation.FileName);
2378 AFSInsertCaseSensitiveDirEntry( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
2381 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2382 AFS_TRACE_LEVEL_VERBOSE,
2383 "AFSInsertDirectoryNode Insert DE %p to case sensitive tree for %wZ\n",
2385 &DirEntry->NameInformation.FileName);
2388 if( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead == NULL)
2391 ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = DirEntry;
2393 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
2395 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2396 AFS_TRACE_LEVEL_VERBOSE,
2397 "AFSInsertDirectoryNode Insert DE %p to head of case insensitive tree for %wZ\n",
2399 &DirEntry->NameInformation.FileName);
2404 AFSInsertCaseInsensitiveDirEntry( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
2407 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2408 AFS_TRACE_LEVEL_VERBOSE,
2409 "AFSInsertDirectoryNode Insert DE %p to case insensitive tree for %wZ\n",
2411 &DirEntry->NameInformation.FileName);
2415 // Into the shortname tree
2418 if( DirEntry->Type.Data.ShortNameTreeEntry.HashIndex != 0)
2421 if( ParentObjectInfo->Specific.Directory.ShortNameTree == NULL)
2424 ParentObjectInfo->Specific.Directory.ShortNameTree = DirEntry;
2426 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2427 AFS_TRACE_LEVEL_VERBOSE,
2428 "AFSInsertDirectoryNode Insert DE %p to head of shortname tree for %wZ\n",
2430 &DirEntry->NameInformation.FileName);
2432 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
2437 if( !NT_SUCCESS( AFSInsertShortNameDirEntry( ParentObjectInfo->Specific.Directory.ShortNameTree,
2440 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2441 AFS_TRACE_LEVEL_VERBOSE,
2442 "AFSInsertDirectoryNode Failed to insert DE %p to shortname tree for %wZ\n",
2444 &DirEntry->NameInformation.FileName);
2448 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
2450 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2451 AFS_TRACE_LEVEL_VERBOSE,
2452 "AFSInsertDirectoryNode Insert DE %p to shortname tree for %wZ\n",
2454 &DirEntry->NameInformation.FileName);
2459 if( InsertInEnumList)
2463 // And insert the node into the directory list
2466 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2467 AFS_TRACE_LEVEL_VERBOSE,
2468 "AFSInsertDirectoryNode Inserting entry %p %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2470 &DirEntry->NameInformation.FileName,
2471 DirEntry->ObjectInformation->FileId.Cell,
2472 DirEntry->ObjectInformation->FileId.Volume,
2473 DirEntry->ObjectInformation->FileId.Vnode,
2474 DirEntry->ObjectInformation->FileId.Unique);
2476 if( ParentObjectInfo->Specific.Directory.DirectoryNodeListHead == NULL)
2479 ParentObjectInfo->Specific.Directory.DirectoryNodeListHead = DirEntry;
2484 ParentObjectInfo->Specific.Directory.DirectoryNodeListTail->ListEntry.fLink = (void *)DirEntry;
2486 DirEntry->ListEntry.bLink = (void *)ParentObjectInfo->Specific.Directory.DirectoryNodeListTail;
2489 ParentObjectInfo->Specific.Directory.DirectoryNodeListTail = DirEntry;
2491 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST);
2493 lCount = InterlockedIncrement( &ParentObjectInfo->Specific.Directory.DirectoryNodeCount);
2495 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
2496 AFS_TRACE_LEVEL_VERBOSE,
2497 "AFSInsertDirectoryNode Adding entry %wZ Inc Count %d to parent FID %08lX-%08lX-%08lX-%08lX\n",
2498 &DirEntry->NameInformation.FileName,
2500 ParentObjectInfo->FileId.Cell,
2501 ParentObjectInfo->FileId.Volume,
2502 ParentObjectInfo->FileId.Vnode,
2503 ParentObjectInfo->FileId.Unique);
2511 AFSDeleteDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
2512 IN AFSDirectoryCB *DirEntry)
2515 NTSTATUS ntStatus = STATUS_SUCCESS;
2521 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2522 AFS_TRACE_LEVEL_VERBOSE,
2523 "AFSDeleteDirEntry Deleting dir entry in parent %08lX Entry %p %wZ FID %08lX-%08lX-%08lX-%08lX RefCount %d\n",
2526 &DirEntry->NameInformation.FileName,
2527 DirEntry->ObjectInformation->FileId.Cell,
2528 DirEntry->ObjectInformation->FileId.Volume,
2529 DirEntry->ObjectInformation->FileId.Vnode,
2530 DirEntry->ObjectInformation->FileId.Unique,
2531 DirEntry->DirOpenReferenceCount);
2533 ASSERT( DirEntry->DirOpenReferenceCount == 0);
2535 AFSRemoveDirNodeFromParent( ParentObjectInfo,
2540 // Free up the name buffer if it was reallocated
2543 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_RELEASE_NAME_BUFFER))
2546 AFSExFreePoolWithTag( DirEntry->NameInformation.FileName.Buffer, 0);
2549 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER))
2552 AFSExFreePoolWithTag( DirEntry->NameInformation.TargetName.Buffer, 0);
2556 // Dereference the object for this dir entry
2559 lCount = AFSObjectInfoDecrement( DirEntry->ObjectInformation,
2560 AFS_OBJECT_REFERENCE_DIRENTRY);
2562 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2563 AFS_TRACE_LEVEL_VERBOSE,
2564 "AFSDeleteDirEntry Decrement count on object %p Cnt %d\n",
2565 DirEntry->ObjectInformation,
2568 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_DELETED) &&
2569 DirEntry->ObjectInformation->Links == 0)
2572 SetFlag( DirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED);
2575 ExDeleteResourceLite( &DirEntry->NonPaged->Lock);
2577 AFSExFreePoolWithTag( DirEntry->NonPaged, AFS_DIR_ENTRY_NP_TAG);
2580 // Free up the dir entry
2583 AFSExFreePoolWithTag( DirEntry, AFS_DIR_ENTRY_TAG);
2590 AFSRemoveDirNodeFromParent( IN AFSObjectInfoCB *ParentObjectInfo,
2591 IN AFSDirectoryCB *DirEntry,
2592 IN BOOLEAN RemoveFromEnumList)
2595 NTSTATUS ntStatus = STATUS_SUCCESS;
2602 ASSERT( ExIsResourceAcquiredExclusiveLite( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock));
2604 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2605 AFS_TRACE_LEVEL_VERBOSE,
2606 "AFSRemoveDirNodeFromParent Removing DirEntry %p %wZ FID %08lX-%08lX-%08lX-%08lX from Parent %p\n",
2608 &DirEntry->NameInformation.FileName,
2609 DirEntry->ObjectInformation->FileId.Cell,
2610 DirEntry->ObjectInformation->FileId.Volume,
2611 DirEntry->ObjectInformation->FileId.Vnode,
2612 DirEntry->ObjectInformation->FileId.Unique,
2615 if( !BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
2618 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2619 AFS_TRACE_LEVEL_VERBOSE,
2620 "AFSRemoveDirNodeFromParent Removing DirEntry %p name %wZ\n",
2622 &DirEntry->NameInformation.FileName);
2624 AFSRemoveNameEntry( ParentObjectInfo,
2630 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2631 AFS_TRACE_LEVEL_VERBOSE,
2632 "AFSRemoveDirNodeFromParent DE %p for %wZ NOT removing entry due to flag set\n",
2634 &DirEntry->NameInformation.FileName);
2638 if( RemoveFromEnumList &&
2639 BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST))
2643 // And remove the entry from the enumeration list
2646 if( DirEntry->ListEntry.fLink == NULL)
2649 ParentObjectInfo->Specific.Directory.DirectoryNodeListTail = (AFSDirectoryCB *)DirEntry->ListEntry.bLink;
2654 ((AFSDirectoryCB *)DirEntry->ListEntry.fLink)->ListEntry.bLink = DirEntry->ListEntry.bLink;
2657 if( DirEntry->ListEntry.bLink == NULL)
2660 ParentObjectInfo->Specific.Directory.DirectoryNodeListHead = (AFSDirectoryCB *)DirEntry->ListEntry.fLink;
2665 ((AFSDirectoryCB *)DirEntry->ListEntry.bLink)->ListEntry.fLink = DirEntry->ListEntry.fLink;
2668 ASSERT( ParentObjectInfo->Specific.Directory.DirectoryNodeCount > 0);
2670 lCount = InterlockedDecrement( &ParentObjectInfo->Specific.Directory.DirectoryNodeCount);
2672 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST);
2674 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
2675 AFS_TRACE_LEVEL_VERBOSE,
2676 "AFSRemoveDirNodeFromParent Removing entry %wZ Dec Count %d to parent FID %08lX-%08lX-%08lX-%08lX\n",
2677 &DirEntry->NameInformation.FileName,
2679 ParentObjectInfo->FileId.Cell,
2680 ParentObjectInfo->FileId.Volume,
2681 ParentObjectInfo->FileId.Vnode,
2682 ParentObjectInfo->FileId.Unique);
2684 DirEntry->ListEntry.fLink = NULL;
2685 DirEntry->ListEntry.bLink = NULL;
2693 AFSFixupTargetName( IN OUT PUNICODE_STRING FileName,
2694 IN OUT PUNICODE_STRING TargetFileName)
2697 NTSTATUS ntStatus = STATUS_SUCCESS;
2698 UNICODE_STRING uniFileName;
2704 // We will process backwards from the end of the name looking
2705 // for the first \ we encounter
2708 uniFileName.Length = FileName->Length;
2709 uniFileName.MaximumLength = FileName->MaximumLength;
2711 uniFileName.Buffer = FileName->Buffer;
2716 if( uniFileName.Buffer[ (uniFileName.Length/sizeof( WCHAR)) - 1] == L'\\')
2720 // Subtract one more character off of the filename if it is not the root
2723 if( uniFileName.Length > sizeof( WCHAR))
2726 uniFileName.Length -= sizeof( WCHAR);
2730 // Now build up the target name
2733 TargetFileName->Length = FileName->Length - uniFileName.Length;
2736 // If we are not on the root then fixup the name
2739 if( uniFileName.Length > sizeof( WCHAR))
2742 TargetFileName->Length -= sizeof( WCHAR);
2744 TargetFileName->Buffer = &uniFileName.Buffer[ (uniFileName.Length/sizeof( WCHAR)) + 1];
2749 TargetFileName->Buffer = &uniFileName.Buffer[ uniFileName.Length/sizeof( WCHAR)];
2753 // Fixup the passed back filename length
2756 FileName->Length = uniFileName.Length;
2758 TargetFileName->MaximumLength = TargetFileName->Length;
2763 uniFileName.Length -= sizeof( WCHAR);
2771 AFSParseName( IN PIRP Irp,
2773 OUT PUNICODE_STRING FileName,
2774 OUT PUNICODE_STRING ParsedFileName,
2775 OUT PUNICODE_STRING RootFileName,
2776 OUT ULONG *ParseFlags,
2777 OUT AFSVolumeCB **VolumeCB,
2778 OUT AFSDirectoryCB **ParentDirectoryCB,
2779 OUT AFSNameArrayHdr **NameArray)
2782 NTSTATUS ntStatus = STATUS_SUCCESS;
2783 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2784 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2785 UNICODE_STRING uniFullName, uniComponentName, uniRemainingPath;
2787 AFSDirectoryCB *pDirEntry = NULL;
2788 USHORT usIndex = 0, usDriveIndex = 0;
2789 AFSCcb *pRelatedCcb = NULL;
2790 AFSNameArrayHdr *pNameArray = NULL, *pRelatedNameArray = NULL;
2791 USHORT usComponentIndex = 0;
2792 USHORT usComponentLength = 0;
2793 AFSVolumeCB *pVolumeCB = NULL;
2794 AFSFcb *pRelatedFcb = NULL;
2795 BOOLEAN bReleaseTreeLock = FALSE;
2796 BOOLEAN bIsAllShare = FALSE;
2803 // Indicate we are opening a root ...
2806 *ParseFlags = AFS_PARSE_FLAG_ROOT_ACCESS;
2808 *ParentDirectoryCB = NULL;
2810 if( pIrpSp->FileObject->RelatedFileObject != NULL)
2813 pRelatedFcb = (AFSFcb *)pIrpSp->FileObject->RelatedFileObject->FsContext;
2815 pRelatedCcb = (AFSCcb *)pIrpSp->FileObject->RelatedFileObject->FsContext2;
2817 pRelatedNameArray = pRelatedCcb->NameArray;
2819 uniFullName = pIrpSp->FileObject->FileName;
2821 ASSERT( pRelatedFcb != NULL);
2824 // No wild cards in the name
2827 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2828 AFS_TRACE_LEVEL_VERBOSE_2,
2829 "AFSParseName (%p) Relative open for %wZ FID %08lX-%08lX-%08lX-%08lX component %wZ\n",
2831 &pRelatedCcb->DirectoryCB->NameInformation.FileName,
2832 pRelatedCcb->DirectoryCB->ObjectInformation->FileId.Cell,
2833 pRelatedCcb->DirectoryCB->ObjectInformation->FileId.Volume,
2834 pRelatedCcb->DirectoryCB->ObjectInformation->FileId.Vnode,
2835 pRelatedCcb->DirectoryCB->ObjectInformation->FileId.Unique,
2838 if( FsRtlDoesNameContainWildCards( &uniFullName))
2841 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2842 AFS_TRACE_LEVEL_ERROR,
2843 "AFSParseName (%p) Component %wZ contains wild cards\n",
2847 try_return( ntStatus = STATUS_OBJECT_NAME_INVALID);
2850 pVolumeCB = pRelatedFcb->ObjectInformation->VolumeCB;
2852 pDirEntry = pRelatedCcb->DirectoryCB;
2854 *FileName = pIrpSp->FileObject->FileName;
2857 // Grab the root node while checking state
2860 AFSAcquireShared( pVolumeCB->VolumeLock,
2863 if( BooleanFlagOn( pVolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
2864 BooleanFlagOn( pVolumeCB->Flags, AFS_VOLUME_FLAGS_OFFLINE))
2868 // The volume has been taken off line so fail the access
2871 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2872 AFS_TRACE_LEVEL_ERROR,
2873 "AFSParseName (%p) Volume %08lX:%08lX OFFLINE/INVALID\n",
2875 pVolumeCB->ObjectInformation.FileId.Cell,
2876 pVolumeCB->ObjectInformation.FileId.Volume);
2878 AFSReleaseResource( pVolumeCB->VolumeLock);
2880 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
2883 if( BooleanFlagOn( pVolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_VERIFY))
2886 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2887 AFS_TRACE_LEVEL_VERBOSE,
2888 "AFSParseName (%p) Verifying root of volume %08lX:%08lX\n",
2890 pVolumeCB->ObjectInformation.FileId.Cell,
2891 pVolumeCB->ObjectInformation.FileId.Volume);
2893 ntStatus = AFSVerifyVolume( (ULONGLONG)PsGetCurrentProcessId(),
2896 if( !NT_SUCCESS( ntStatus))
2899 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2900 AFS_TRACE_LEVEL_ERROR,
2901 "AFSParseName (%p) Failed verification of root Status %08lX\n",
2905 AFSReleaseResource( pVolumeCB->VolumeLock);
2907 try_return( ntStatus);
2911 AFSReleaseResource( pVolumeCB->VolumeLock);
2913 if( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY))
2916 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2917 AFS_TRACE_LEVEL_VERBOSE,
2918 "AFSParseName (%p) Verifying parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2920 &pDirEntry->NameInformation.FileName,
2921 pDirEntry->ObjectInformation->FileId.Cell,
2922 pDirEntry->ObjectInformation->FileId.Volume,
2923 pDirEntry->ObjectInformation->FileId.Vnode,
2924 pDirEntry->ObjectInformation->FileId.Unique);
2927 // Directory TreeLock should be exclusively held
2930 AFSAcquireExcl( pDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
2933 ntStatus = AFSVerifyEntry( AuthGroup,
2936 AFSReleaseResource( pDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
2938 if( !NT_SUCCESS( ntStatus))
2941 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2942 AFS_TRACE_LEVEL_VERBOSE,
2943 "AFSParseName (%p) Failed verification of parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2945 &pDirEntry->NameInformation.FileName,
2946 pDirEntry->ObjectInformation->FileId.Cell,
2947 pDirEntry->ObjectInformation->FileId.Volume,
2948 pDirEntry->ObjectInformation->FileId.Vnode,
2949 pDirEntry->ObjectInformation->FileId.Unique,
2952 try_return( ntStatus);
2957 // Create our full path name buffer
2960 uniFullName.MaximumLength = pRelatedCcb->FullFileName.Length +
2962 pIrpSp->FileObject->FileName.Length +
2965 uniFullName.Length = 0;
2967 uniFullName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2968 uniFullName.MaximumLength,
2969 AFS_NAME_BUFFER_THREE_TAG);
2971 if( uniFullName.Buffer == NULL)
2974 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2975 AFS_TRACE_LEVEL_ERROR,
2976 "AFSParseName (%p) Failed to allocate full name buffer\n",
2979 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2982 RtlZeroMemory( uniFullName.Buffer,
2983 uniFullName.MaximumLength);
2985 RtlCopyMemory( uniFullName.Buffer,
2986 pRelatedCcb->FullFileName.Buffer,
2987 pRelatedCcb->FullFileName.Length);
2989 uniFullName.Length = pRelatedCcb->FullFileName.Length;
2991 usComponentIndex = (USHORT)(uniFullName.Length/sizeof( WCHAR));
2993 usComponentLength = pIrpSp->FileObject->FileName.Length;
2995 if( uniFullName.Buffer[ (uniFullName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
2996 pIrpSp->FileObject->FileName.Length > 0 &&
2997 pIrpSp->FileObject->FileName.Buffer[ 0] != L'\\' &&
2998 pIrpSp->FileObject->FileName.Buffer[ 0] != L':')
3001 uniFullName.Buffer[ (uniFullName.Length/sizeof( WCHAR))] = L'\\';
3003 uniFullName.Length += sizeof( WCHAR);
3005 usComponentLength += sizeof( WCHAR);
3008 if( pIrpSp->FileObject->FileName.Length > 0)
3011 RtlCopyMemory( &uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)],
3012 pIrpSp->FileObject->FileName.Buffer,
3013 pIrpSp->FileObject->FileName.Length);
3015 uniFullName.Length += pIrpSp->FileObject->FileName.Length;
3018 *RootFileName = uniFullName;
3021 // We populate up to the current parent
3024 if( pRelatedNameArray == NULL)
3028 // Init and populate our name array
3031 pNameArray = AFSInitNameArray( NULL,
3034 if( pNameArray == NULL)
3037 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3038 AFS_TRACE_LEVEL_VERBOSE,
3039 "AFSParseName (%p) Failed to initialize name array\n",
3042 AFSExFreePoolWithTag( uniFullName.Buffer, 0);
3044 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3047 ntStatus = AFSPopulateNameArray( pNameArray,
3049 pRelatedCcb->DirectoryCB);
3055 // Init and populate our name array
3058 pNameArray = AFSInitNameArray( NULL,
3059 pRelatedNameArray->MaxElementCount);
3061 if( pNameArray == NULL)
3064 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3065 AFS_TRACE_LEVEL_VERBOSE,
3066 "AFSParseName (%p) Failed to initialize name array\n",
3069 AFSExFreePoolWithTag( uniFullName.Buffer, 0);
3071 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3074 ntStatus = AFSPopulateNameArrayFromRelatedArray( pNameArray,
3076 pRelatedCcb->DirectoryCB);
3079 if( !NT_SUCCESS( ntStatus))
3082 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3083 AFS_TRACE_LEVEL_VERBOSE,
3084 "AFSParseName (%p) Failed to populate name array\n",
3087 AFSExFreePoolWithTag( uniFullName.Buffer, 0);
3089 try_return( ntStatus);
3092 ParsedFileName->Length = usComponentLength;
3093 ParsedFileName->MaximumLength = uniFullName.MaximumLength;
3095 ParsedFileName->Buffer = &uniFullName.Buffer[ usComponentIndex];
3098 // Indicate to caller that RootFileName must be freed
3101 SetFlag( *ParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
3103 *NameArray = pNameArray;
3106 // Increment our volume reference count
3109 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
3111 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
3112 AFS_TRACE_LEVEL_VERBOSE,
3113 "AFSParseName Increment count on volume %p Cnt %d\n",
3117 *VolumeCB = pVolumeCB;
3119 *ParentDirectoryCB = pDirEntry;
3121 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3122 AFS_TRACE_LEVEL_VERBOSE_2,
3123 "AFSParseName (%p) Returning full name %wZ\n",
3127 try_return( ntStatus);
3131 // No wild cards in the name
3134 uniFullName = pIrpSp->FileObject->FileName;
3136 if( FsRtlDoesNameContainWildCards( &uniFullName) ||
3137 uniFullName.Length < AFSServerName.Length)
3140 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3141 AFS_TRACE_LEVEL_ERROR,
3142 "AFSParseName (%p) Name %wZ contains wild cards or too short\n",
3146 try_return( ntStatus = STATUS_OBJECT_NAME_INVALID);
3150 // The name is a fully qualified name. Parse out the server/share names and
3151 // point to the root qualified name
3152 // First thing is to locate the server name
3155 FsRtlDissectName( uniFullName,
3159 uniFullName = uniRemainingPath;
3162 // This component is the server name we are serving
3165 if( RtlCompareUnicodeString( &uniComponentName,
3171 // Drive letter based name?
3174 uniFullName = pIrpSp->FileObject->FileName;
3176 while( usIndex < uniFullName.Length/sizeof( WCHAR))
3179 if( uniFullName.Buffer[ usIndex] == L':')
3182 uniFullName.Buffer = &uniFullName.Buffer[ usIndex + 2];
3184 uniFullName.Length -= (usIndex + 2) * sizeof( WCHAR);
3186 usDriveIndex = usIndex - 1;
3195 // Do we have the right server name now?
3198 FsRtlDissectName( uniFullName,
3202 uniFullName = uniRemainingPath;
3205 // This component is the server name we are serving
3208 if( RtlCompareUnicodeString( &uniComponentName,
3213 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3214 AFS_TRACE_LEVEL_ERROR,
3215 "AFSParseName (%p) Name %wZ does not have server name\n",
3217 &pIrpSp->FileObject->FileName);
3219 try_return( ntStatus = STATUS_BAD_NETWORK_NAME);
3223 // Validate this drive letter is actively mapped
3226 if( usDriveIndex > 0 &&
3227 !AFSIsDriveMapped( pIrpSp->FileObject->FileName.Buffer[ usDriveIndex]))
3230 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3231 AFS_TRACE_LEVEL_ERROR,
3232 "AFSParseName (%p) Name %wZ contains invalid drive mapping\n",
3234 &pIrpSp->FileObject->FileName);
3236 try_return( ntStatus = STATUS_BAD_NETWORK_NAME);
3240 if( FsRtlDoesNameContainWildCards( &uniFullName))
3243 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3244 AFS_TRACE_LEVEL_ERROR,
3245 "AFSParseName (%p) Component %wZ contains wild cards\n",
3249 try_return( ntStatus = STATUS_OBJECT_NAME_INVALID);
3252 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3253 AFS_TRACE_LEVEL_VERBOSE_2,
3254 "AFSParseName (%p) Processing full name %wZ\n",
3258 if( uniFullName.Length > 0 &&
3259 uniFullName.Buffer[ (uniFullName.Length/sizeof( WCHAR)) - 1] == L'\\')
3262 uniFullName.Length -= sizeof( WCHAR);
3266 // Be sure we are online and ready to go
3269 AFSAcquireShared( AFSGlobalRoot->VolumeLock,
3272 if( BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
3273 BooleanFlagOn( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE))
3277 // The volume has been taken off line so fail the access
3280 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3281 AFS_TRACE_LEVEL_ERROR,
3282 "AFSParseName (%p) Volume %08lX:%08lX OFFLINE/INVALID\n",
3284 AFSGlobalRoot->ObjectInformation.FileId.Cell,
3285 AFSGlobalRoot->ObjectInformation.FileId.Volume);
3287 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3289 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
3292 if( BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_VERIFY))
3295 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3296 AFS_TRACE_LEVEL_VERBOSE,
3297 "AFSParseName (%p) Verifying root of volume %08lX:%08lX\n",
3299 AFSGlobalRoot->ObjectInformation.FileId.Cell,
3300 AFSGlobalRoot->ObjectInformation.FileId.Volume);
3302 ntStatus = AFSVerifyVolume( (ULONGLONG)PsGetCurrentProcessId(),
3305 if( !NT_SUCCESS( ntStatus))
3308 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3309 AFS_TRACE_LEVEL_ERROR,
3310 "AFSParseName (%p) Failed verification of root Status %08lX\n",
3314 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3316 try_return( ntStatus);
3320 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3322 if( !BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
3325 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3326 AFS_TRACE_LEVEL_VERBOSE,
3327 "AFSParseName (%p) Enumerating global root of volume %08lX:%08lX\n",
3329 AFSGlobalRoot->ObjectInformation.FileId.Cell,
3330 AFSGlobalRoot->ObjectInformation.FileId.Volume);
3332 ntStatus = AFSEnumerateGlobalRoot( AuthGroup);
3334 if( !NT_SUCCESS( ntStatus))
3337 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3338 AFS_TRACE_LEVEL_ERROR,
3339 "AFSParseName (%p) Failed enumeraiton of root Status %08lX\n",
3343 try_return( ntStatus);
3348 // Check for the \\Server access and return it as though it were \\Server\Globalroot
3351 if( uniRemainingPath.Buffer == NULL ||
3352 ( uniRemainingPath.Length == sizeof( WCHAR) &&
3353 uniRemainingPath.Buffer[ 0] == L'\\'))
3356 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3357 AFS_TRACE_LEVEL_VERBOSE_2,
3358 "AFSParseName (%p) Returning global root access\n",
3361 lCount = InterlockedIncrement( &AFSGlobalRoot->DirectoryCB->DirOpenReferenceCount);
3363 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3364 AFS_TRACE_LEVEL_VERBOSE,
3365 "AFSParseName Increment2 count on %wZ DE %p Ccb %p Cnt %d\n",
3366 &AFSGlobalRoot->DirectoryCB->NameInformation.FileName,
3367 AFSGlobalRoot->DirectoryCB,
3373 FileName->Length = 0;
3374 FileName->MaximumLength = 0;
3375 FileName->Buffer = NULL;
3377 try_return( ntStatus = STATUS_SUCCESS);
3380 *RootFileName = uniFullName;
3383 // Include the starting \ in the root name
3386 if( RootFileName->Buffer[ 0] != L'\\')
3388 RootFileName->Buffer--;
3389 RootFileName->Length += sizeof( WCHAR);
3390 RootFileName->MaximumLength += sizeof( WCHAR);
3394 // Get the 'share' name
3397 FsRtlDissectName( uniFullName,
3401 if( FsRtlDoesNameContainWildCards( &uniFullName))
3404 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3405 AFS_TRACE_LEVEL_ERROR,
3406 "AFSParseName (%p) Component %wZ contains wild cards\n",
3410 try_return( ntStatus = STATUS_OBJECT_NAME_INVALID);
3414 // If this is the ALL access then perform some additional processing
3417 if( uniComponentName.Length == 0 ||
3418 RtlCompareUnicodeString( &uniComponentName,
3426 // If there is nothing else then get out
3429 if( uniRemainingPath.Buffer == NULL ||
3430 uniRemainingPath.Length == 0 ||
3431 ( uniRemainingPath.Length == sizeof( WCHAR) &&
3432 uniRemainingPath.Buffer[ 0] == L'\\'))
3435 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3436 AFS_TRACE_LEVEL_VERBOSE_2,
3437 "AFSParseName (%p) Returning global root access\n",
3440 lCount = InterlockedIncrement( &AFSGlobalRoot->DirectoryCB->DirOpenReferenceCount);
3442 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3443 AFS_TRACE_LEVEL_VERBOSE,
3444 "AFSParseName Increment3 count on %wZ DE %p Ccb %p Cnt %d\n",
3445 &AFSGlobalRoot->DirectoryCB->NameInformation.FileName,
3446 AFSGlobalRoot->DirectoryCB,
3452 FileName->Length = 0;
3453 FileName->MaximumLength = 0;
3454 FileName->Buffer = NULL;
3456 try_return( ntStatus = STATUS_SUCCESS);
3460 // Process the name again to strip off the ALL portion
3463 uniFullName = uniRemainingPath;
3465 FsRtlDissectName( uniFullName,
3470 // Check for the PIOCtl name
3473 if( RtlCompareUnicodeString( &uniComponentName,
3478 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3479 AFS_TRACE_LEVEL_VERBOSE_2,
3480 "AFSParseName (%p) Returning root PIOCtl access\n",
3483 lCount = InterlockedIncrement( &AFSGlobalRoot->DirectoryCB->DirOpenReferenceCount);
3485 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3486 AFS_TRACE_LEVEL_VERBOSE,
3487 "AFSParseName Increment4 count on %wZ DE %p Ccb %p Cnt %d\n",
3488 &AFSGlobalRoot->DirectoryCB->NameInformation.FileName,
3489 AFSGlobalRoot->DirectoryCB,
3493 ClearFlag( *ParseFlags, AFS_PARSE_FLAG_ROOT_ACCESS);
3497 *FileName = AFSPIOCtlName;
3499 try_return( ntStatus = STATUS_SUCCESS);
3502 else if( (pDirEntry = AFSGetSpecialShareNameEntry( &uniComponentName,
3503 &uniRemainingPath)) != NULL)
3506 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3507 AFS_TRACE_LEVEL_VERBOSE_2,
3508 "AFSParseName (%p) Returning root share name %wZ access\n",
3513 // Add in the full share name to pass back
3516 if( uniRemainingPath.Buffer != NULL)
3520 // This routine strips off the leading slash so add it back in
3523 uniRemainingPath.Buffer--;
3524 uniRemainingPath.Length += sizeof( WCHAR);
3525 uniRemainingPath.MaximumLength += sizeof( WCHAR);
3528 // And the cell name
3531 uniRemainingPath.Buffer -= (uniComponentName.Length/sizeof( WCHAR));
3532 uniRemainingPath.Length += uniComponentName.Length;
3533 uniRemainingPath.MaximumLength += uniComponentName.Length;
3535 uniComponentName = uniRemainingPath;
3540 *FileName = uniComponentName;
3542 ClearFlag( *ParseFlags, AFS_PARSE_FLAG_ROOT_ACCESS);
3544 *ParentDirectoryCB = pDirEntry;
3546 try_return( ntStatus = STATUS_SUCCESS);
3550 // Determine the 'share' we are accessing
3553 ulCRC = AFSGenerateCRC( &uniComponentName,
3556 AFSAcquireShared( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
3559 bReleaseTreeLock = TRUE;
3561 AFSLocateCaseSensitiveDirEntry( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
3565 if( pDirEntry == NULL)
3568 ulCRC = AFSGenerateCRC( &uniComponentName,
3571 AFSLocateCaseInsensitiveDirEntry( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
3575 if( pDirEntry == NULL)
3579 // OK, if this component is a valid short name then try
3580 // a lookup in the short name tree
3583 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
3584 RtlIsNameLegalDOS8Dot3( &uniComponentName,
3589 AFSLocateShortNameDirEntry( AFSGlobalRoot->ObjectInformation.Specific.Directory.ShortNameTree,
3594 if( pDirEntry == NULL)
3598 // Check with the service whether it is a valid cell name
3601 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
3603 bReleaseTreeLock = FALSE;
3605 ntStatus = AFSCheckCellName( AuthGroup,
3609 if( !NT_SUCCESS( ntStatus))
3613 uniRemainingPath.Length == 0 &&
3614 ntStatus == STATUS_OBJECT_PATH_NOT_FOUND)
3617 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3618 AFS_TRACE_LEVEL_VERBOSE,
3619 "AFSParseName (%08lX) AFSCheckCellName %wZ returned path not found; ntStatus %08X\n",
3622 STATUS_OBJECT_NAME_NOT_FOUND);
3624 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
3627 try_return( ntStatus);
3633 if( bReleaseTreeLock)
3635 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
3640 // Be sure we are starting from the correct volume
3643 if( pDirEntry->ObjectInformation->VolumeCB != AFSGlobalRoot)
3647 // We dropped the global root in the CheckCellName routine which is the
3648 // only way we can be here
3651 pVolumeCB = pDirEntry->ObjectInformation->VolumeCB;
3654 // Init our name array
3657 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
3660 if( pNameArray == NULL)
3663 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3664 AFS_TRACE_LEVEL_VERBOSE,
3665 "AFSParseName (%p) Failed to initialize name array\n",
3668 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3671 ntStatus = AFSInsertNextElement( pNameArray,
3672 pVolumeCB->DirectoryCB);
3677 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3678 AFS_TRACE_LEVEL_VERBOSE,
3679 "AFSParseName (%p) Failed to insert name array element\n",
3682 try_return( ntStatus);
3686 // In this case don't add back in the 'share' name since that is where we are
3687 // starting. Just put the leading slash back in
3690 if( uniRemainingPath.Buffer != NULL)
3693 uniRemainingPath.Buffer--;
3694 uniRemainingPath.Length += sizeof( WCHAR);
3695 uniRemainingPath.MaximumLength += sizeof( WCHAR);
3697 if( uniRemainingPath.Length > sizeof( WCHAR))
3700 ClearFlag( *ParseFlags, AFS_PARSE_FLAG_ROOT_ACCESS);
3704 // Pass back the parent being the root of the volume
3707 *ParentDirectoryCB = pVolumeCB->DirectoryCB;
3713 // Pass back a root slash
3716 uniRemainingPath = uniComponentName;
3718 uniRemainingPath.Buffer--;
3719 uniRemainingPath.Length = sizeof( WCHAR);
3720 uniRemainingPath.MaximumLength = sizeof( WCHAR);
3723 // This is a root open so pass back no parent
3730 pVolumeCB = AFSGlobalRoot;
3733 // Init our name array
3736 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
3738 if( pNameArray == NULL)
3741 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3742 AFS_TRACE_LEVEL_VERBOSE,
3743 "AFSParseName (%p) Failed to initialize name array\n",
3746 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3750 // Add back in the 'share' portion of the name since we will parse it out on return
3753 if( uniRemainingPath.Buffer != NULL)
3757 // This routine strips off the leading slash so add it back in
3760 uniRemainingPath.Buffer--;
3761 uniRemainingPath.Length += sizeof( WCHAR);
3762 uniRemainingPath.MaximumLength += sizeof( WCHAR);
3764 if( uniRemainingPath.Length > sizeof( WCHAR))
3767 ClearFlag( *ParseFlags, AFS_PARSE_FLAG_ROOT_ACCESS);
3771 // And the cell name
3774 uniRemainingPath.Buffer -= (uniComponentName.Length/sizeof( WCHAR));
3775 uniRemainingPath.Length += uniComponentName.Length;
3776 uniRemainingPath.MaximumLength += uniComponentName.Length;
3781 uniRemainingPath = uniComponentName;
3785 // And the leading slash again ...
3788 uniRemainingPath.Buffer--;
3789 uniRemainingPath.Length += sizeof( WCHAR);
3790 uniRemainingPath.MaximumLength += sizeof( WCHAR);
3793 // Pass back the parent being the volume root
3796 *ParentDirectoryCB = pVolumeCB->DirectoryCB;
3800 // Return the remaining portion as the file name
3803 *FileName = uniRemainingPath;
3805 *ParsedFileName = uniRemainingPath;
3807 *NameArray = pNameArray;
3809 *VolumeCB = pVolumeCB;
3812 // Increment our reference on the volume
3815 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
3817 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
3818 AFS_TRACE_LEVEL_VERBOSE,
3819 "AFSParseName Increment2 count on global volume %p Cnt %d\n",
3825 if( NT_SUCCESS( ntStatus))
3828 if( *ParentDirectoryCB != NULL)
3831 lCount = InterlockedIncrement( &(*ParentDirectoryCB)->DirOpenReferenceCount);
3833 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3834 AFS_TRACE_LEVEL_VERBOSE,
3835 "AFSParseName Increment1 count on %wZ DE %p Ccb %p Cnt %d\n",
3836 &(*ParentDirectoryCB)->NameInformation.FileName,
3837 (*ParentDirectoryCB),
3843 if( *VolumeCB != NULL)
3845 ASSERT( (*VolumeCB)->VolumeReferenceCount > 1);
3848 if( ntStatus != STATUS_SUCCESS)
3851 if( pNameArray != NULL)
3854 AFSFreeNameArray( pNameArray);
3863 AFSCheckCellName( IN GUID *AuthGroup,
3864 IN UNICODE_STRING *CellName,
3865 OUT AFSDirectoryCB **ShareDirEntry)
3868 NTSTATUS ntStatus = STATUS_SUCCESS;
3869 UNICODE_STRING uniName;
3870 AFSDirEnumEntry *pDirEnumEntry = NULL;
3871 AFSDirHdr *pDirHdr = &AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr;
3872 AFSDirectoryCB *pDirNode = NULL;
3873 UNICODE_STRING uniDirName, uniTargetName;
3874 AFSVolumeCB *pVolumeCB = NULL;
3881 // Look for some default names we will not handle
3884 RtlInitUnicodeString( &uniName,
3887 if( RtlCompareUnicodeString( &uniName,
3892 try_return( ntStatus = STATUS_NO_SUCH_FILE);
3895 RtlInitUnicodeString( &uniName,
3898 if( RtlCompareUnicodeString( &uniName,
3903 try_return( ntStatus = STATUS_NO_SUCH_FILE);
3906 RtlInitUnicodeString( &uniName,
3909 if( RtlCompareUnicodeString( &uniName,
3914 try_return( ntStatus = STATUS_NO_SUCH_FILE);
3917 RtlInitUnicodeString( &uniName,
3920 if( RtlCompareUnicodeString( &uniName,
3925 try_return( ntStatus = STATUS_NO_SUCH_FILE);
3929 // OK, ask the CM about this component name
3932 ntStatus = AFSEvaluateTargetByName( AuthGroup,
3933 &AFSGlobalRoot->ObjectInformation,
3937 if( !NT_SUCCESS( ntStatus))
3940 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3941 AFS_TRACE_LEVEL_WARNING,
3942 "AFSCheckCellName entry %wZ does not exist parent FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
3944 AFSGlobalRoot->ObjectInformation.FileId.Cell,
3945 AFSGlobalRoot->ObjectInformation.FileId.Volume,
3946 AFSGlobalRoot->ObjectInformation.FileId.Vnode,
3947 AFSGlobalRoot->ObjectInformation.FileId.Unique,
3950 try_return( ntStatus);
3954 // OK, we have a dir enum entry back so add it to the root node
3957 uniDirName = *CellName;
3959 uniTargetName.Length = (USHORT)pDirEnumEntry->TargetNameLength;
3960 uniTargetName.MaximumLength = uniTargetName.Length;
3961 uniTargetName.Buffer = (WCHAR *)((char *)pDirEnumEntry + pDirEnumEntry->TargetNameOffset);
3964 // Is this entry a root volume entry?
3967 if( pDirEnumEntry->FileId.Cell != AFSGlobalRoot->ObjectInformation.FileId.Cell ||
3968 pDirEnumEntry->FileId.Volume != AFSGlobalRoot->ObjectInformation.FileId.Volume)
3972 // Build the root volume entry
3975 ntStatus = AFSBuildRootVolume( AuthGroup,
3976 &pDirEnumEntry->FileId,
3979 if( !NT_SUCCESS( ntStatus))
3981 try_return( ntStatus);
3984 *ShareDirEntry = pVolumeCB->DirectoryCB;
3986 lCount = InterlockedIncrement( &pVolumeCB->DirectoryCB->DirOpenReferenceCount);
3988 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3989 AFS_TRACE_LEVEL_VERBOSE,
3990 "AFSCheckCellName Increment1 count on %wZ DE %p Ccb %p Cnt %d\n",
3991 &pVolumeCB->DirectoryCB->NameInformation.FileName,
3992 pVolumeCB->DirectoryCB,
3996 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
3998 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
3999 AFS_TRACE_LEVEL_VERBOSE,
4000 "AFSCheckCellName Increment count on volume %p Cnt %d\n",
4007 lCount = InterlockedIncrement( &pDirHdr->ContentIndex);
4009 pDirNode = AFSInitDirEntry( &AFSGlobalRoot->ObjectInformation,
4015 if( pDirNode == NULL)
4018 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4022 // Init the short name if we have one
4025 if( pDirEnumEntry->ShortNameLength > 0)
4028 pDirNode->NameInformation.ShortNameLength = pDirEnumEntry->ShortNameLength;
4030 RtlCopyMemory( pDirNode->NameInformation.ShortName,
4031 pDirEnumEntry->ShortName,
4032 pDirNode->NameInformation.ShortNameLength);
4035 AFSAcquireExcl( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
4039 // Insert the node into the name tree
4042 ASSERT( ExIsResourceAcquiredExclusiveLite( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock));
4044 if( pDirHdr->CaseSensitiveTreeHead == NULL)
4047 pDirHdr->CaseSensitiveTreeHead = pDirNode;
4052 if( !NT_SUCCESS( AFSInsertCaseSensitiveDirEntry( pDirHdr->CaseSensitiveTreeHead,
4056 AFSDeleteDirEntry( &AFSGlobalRoot->ObjectInformation,
4059 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
4061 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4065 ClearFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
4067 if( pDirHdr->CaseInsensitiveTreeHead == NULL)
4070 pDirHdr->CaseInsensitiveTreeHead = pDirNode;
4072 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
4077 AFSInsertCaseInsensitiveDirEntry( pDirHdr->CaseInsensitiveTreeHead,
4081 if( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListHead == NULL)
4084 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListHead = pDirNode;
4089 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListTail->ListEntry.fLink = pDirNode;
4091 pDirNode->ListEntry.bLink = AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListTail;
4094 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListTail = pDirNode;
4096 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST);
4098 lCount = InterlockedIncrement( &AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeCount);
4100 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
4101 AFS_TRACE_LEVEL_VERBOSE,
4102 "AFSCheckCellName Adding entry %wZ Inc Count %d to parent FID %08lX-%08lX-%08lX-%08lX\n",
4103 &pDirNode->NameInformation.FileName,
4105 AFSGlobalRoot->ObjectInformation.FileId.Cell,
4106 AFSGlobalRoot->ObjectInformation.FileId.Volume,
4107 AFSGlobalRoot->ObjectInformation.FileId.Vnode,
4108 AFSGlobalRoot->ObjectInformation.FileId.Unique);
4110 lCount = InterlockedIncrement( &pDirNode->DirOpenReferenceCount);
4112 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
4113 AFS_TRACE_LEVEL_VERBOSE,
4114 "AFSCheckCellName Increment2 count on %wZ DE %p Ccb %p Cnt %d\n",
4115 &pDirNode->NameInformation.FileName,
4120 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
4123 // Pass back the dir node
4126 *ShareDirEntry = pDirNode;
4131 if( pDirEnumEntry != NULL)
4134 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_31_TAG);
4142 AFSBuildMountPointTarget( IN GUID *AuthGroup,
4143 IN AFSDirectoryCB *DirectoryCB,
4144 OUT AFSVolumeCB **TargetVolumeCB)
4147 NTSTATUS ntStatus = STATUS_SUCCESS;
4148 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
4149 AFSDirEnumEntry *pDirEntry = NULL;
4150 ULONGLONG ullIndex = 0;
4151 AFSVolumeCB *pVolumeCB = NULL;
4152 AFSFileID stTargetFileID;
4154 BOOLEAN bReleaseVolumeLock = FALSE;
4160 // Loop on each entry, building the chain until we encounter the final target
4163 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4164 AFS_TRACE_LEVEL_VERBOSE_2,
4165 "AFSBuildMountPointTarget Building target directory for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4166 &DirectoryCB->NameInformation.FileName,
4167 DirectoryCB->ObjectInformation->FileId.Cell,
4168 DirectoryCB->ObjectInformation->FileId.Volume,
4169 DirectoryCB->ObjectInformation->FileId.Vnode,
4170 DirectoryCB->ObjectInformation->FileId.Unique);
4173 // Do we need to evaluate the node?
4176 //if( DirectoryCB->ObjectInformation->TargetFileId.Vnode == 0 &&
4177 // DirectoryCB->ObjectInformation->TargetFileId.Unique == 0)
4181 // Go evaluate the current target to get the target fid
4184 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4185 AFS_TRACE_LEVEL_VERBOSE_2,
4186 "AFSBuildMountPointTarget Evaluating target %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4187 &DirectoryCB->NameInformation.FileName,
4188 DirectoryCB->ObjectInformation->FileId.Cell,
4189 DirectoryCB->ObjectInformation->FileId.Volume,
4190 DirectoryCB->ObjectInformation->FileId.Vnode,
4191 DirectoryCB->ObjectInformation->FileId.Unique);
4193 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
4198 if( !NT_SUCCESS( ntStatus))
4201 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4202 AFS_TRACE_LEVEL_ERROR,
4203 "AFSBuildMountPointTarget Failed to evaluate target %wZ Status %08lX\n",
4204 &DirectoryCB->NameInformation.FileName,
4206 try_return( ntStatus);
4209 if( pDirEntry->TargetFileId.Vnode == 0 &&
4210 pDirEntry->TargetFileId.Unique == 0)
4213 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4214 AFS_TRACE_LEVEL_ERROR,
4215 "AFSBuildMountPointTarget Target %wZ FID %08lX-%08lX-%08lX-%08lX service returned zero FID\n",
4216 &DirectoryCB->NameInformation.FileName,
4217 DirectoryCB->ObjectInformation->FileId.Cell,
4218 DirectoryCB->ObjectInformation->FileId.Volume,
4219 DirectoryCB->ObjectInformation->FileId.Vnode,
4220 DirectoryCB->ObjectInformation->FileId.Unique);
4222 try_return( ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED);
4225 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
4228 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
4229 &DirectoryCB->Flags,
4230 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
4231 (USHORT)pDirEntry->TargetNameLength);
4233 if( !NT_SUCCESS( ntStatus))
4236 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
4238 try_return( ntStatus);
4241 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
4243 DirectoryCB->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
4246 stTargetFileID = DirectoryCB->ObjectInformation->TargetFileId;
4249 // Try to locate this FID. First the volume then the
4253 ullIndex = AFSCreateHighIndex( &stTargetFileID);
4255 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4256 AFS_TRACE_LEVEL_VERBOSE,
4257 "AFSBuildMountPointTarget Acquiring RDR VolumeTreeLock lock %p EXCL %08lX\n",
4258 &pDevExt->Specific.RDR.VolumeTreeLock,
4259 PsGetCurrentThread());
4261 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock,
4264 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4265 AFS_TRACE_LEVEL_VERBOSE_2,
4266 "AFSBuildMountPointTarget Locating volume for target %I64X\n",
4269 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
4271 (AFSBTreeEntry **)&pVolumeCB);
4274 // We can be processing a request for a target that is on a volume
4275 // we have never seen before.
4278 if( pVolumeCB == NULL)
4282 // Locking is held correctly in init routine
4285 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
4288 // Go init the root of the volume
4291 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4292 AFS_TRACE_LEVEL_VERBOSE_2,
4293 "AFSBuildMountPointTarget Initializing root for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4294 &DirectoryCB->NameInformation.FileName,
4295 DirectoryCB->ObjectInformation->FileId.Cell,
4296 DirectoryCB->ObjectInformation->FileId.Volume,
4297 DirectoryCB->ObjectInformation->FileId.Vnode,
4298 DirectoryCB->ObjectInformation->FileId.Unique);
4300 ntStatus = AFSInitVolume( AuthGroup,
4304 if( !NT_SUCCESS( ntStatus))
4307 try_return( ntStatus);
4311 // pVolumeCB->VolumeLock held exclusive and
4312 // pVolumeCB->VolumeReferenceCount has been incremented
4313 // pVolumeCB->RootFcb == NULL
4316 bReleaseVolumeLock = TRUE;
4322 // AFSInitVolume returns with a VolumeReferenceCount
4323 // obtain one to match
4326 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
4328 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
4329 AFS_TRACE_LEVEL_VERBOSE,
4330 "AFSBuildMountPointTarget Increment count on volume %p Cnt %d\n",
4334 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
4337 if( pVolumeCB->RootFcb == NULL)
4340 if ( bReleaseVolumeLock == FALSE)
4343 AFSAcquireExcl( pVolumeCB->VolumeLock,
4346 bReleaseVolumeLock = TRUE;
4350 // Initialize the root fcb for this volume
4353 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
4356 if( !NT_SUCCESS( ntStatus))
4359 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
4361 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
4362 AFS_TRACE_LEVEL_VERBOSE,
4363 "AFSBuildMountPoint Decrement count on volume %p Cnt %d\n",
4367 AFSReleaseResource( pVolumeCB->VolumeLock);
4369 try_return( ntStatus);
4373 // Drop the lock acquired above
4376 AFSReleaseResource( &pVolumeCB->RootFcb->NPFcb->Resource);
4379 if ( bReleaseVolumeLock == TRUE)
4382 AFSReleaseResource( pVolumeCB->VolumeLock);
4385 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4386 AFS_TRACE_LEVEL_VERBOSE_2,
4387 "AFSBuildMountPointTarget Evaluated target of %wZ FID %08lX-%08lX-%08lX-%08lX as root volume\n",
4388 &pVolumeCB->DirectoryCB->NameInformation.FileName,
4389 pVolumeCB->ObjectInformation.FileId.Cell,
4390 pVolumeCB->ObjectInformation.FileId.Volume,
4391 pVolumeCB->ObjectInformation.FileId.Vnode,
4392 pVolumeCB->ObjectInformation.FileId.Unique);
4394 *TargetVolumeCB = pVolumeCB;
4401 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
4409 AFSBuildRootVolume( IN GUID *AuthGroup,
4410 IN AFSFileID *FileId,
4411 OUT AFSVolumeCB **TargetVolumeCB)
4414 NTSTATUS ntStatus = STATUS_SUCCESS;
4415 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
4416 ULONGLONG ullIndex = 0;
4417 AFSVolumeCB *pVolumeCB = NULL;
4419 BOOLEAN bReleaseVolumeLock = FALSE;
4424 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4425 AFS_TRACE_LEVEL_VERBOSE_2,
4426 "AFSBuildRootVolume Building target volume for FID %08lX-%08lX-%08lX-%08lX\n",
4432 ullIndex = AFSCreateHighIndex( FileId);
4434 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4435 AFS_TRACE_LEVEL_VERBOSE,
4436 "AFSBuildRootVolume Acquiring RDR VolumeTreeLock lock %p EXCL %08lX\n",
4437 &pDevExt->Specific.RDR.VolumeTreeLock,
4438 PsGetCurrentThread());
4440 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock,
4443 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4444 AFS_TRACE_LEVEL_VERBOSE_2,
4445 "AFSBuildRootVolume Locating volume for target %I64X\n",
4448 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
4450 (AFSBTreeEntry **)&pVolumeCB);
4453 // We can be processing a request for a target that is on a volume
4454 // we have never seen before.
4457 if( pVolumeCB == NULL)
4461 // Locking is held correctly in init routine
4464 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
4467 // Go init the root of the volume
4470 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4471 AFS_TRACE_LEVEL_VERBOSE_2,
4472 "AFSBuildRootVolume Initializing root for FID %08lX-%08lX-%08lX-%08lX\n",
4478 ntStatus = AFSInitVolume( AuthGroup,
4482 if( !NT_SUCCESS( ntStatus))
4485 try_return( ntStatus);
4489 // pVolumeCB->VolumeLock is held exclusive
4490 // pVolumeCB->VolumeReferenceCount has been incremented
4491 // pVolumeCB->RootFcb == NULL
4494 bReleaseVolumeLock = TRUE;
4500 // AFSInitVolume returns with a VolumeReferenceCount
4501 // obtain one to match
4504 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
4506 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
4507 AFS_TRACE_LEVEL_VERBOSE,
4508 "AFSBuildRootVolume Increment count on volume %p Cnt %d\n",
4512 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
4516 if( pVolumeCB->RootFcb == NULL)
4519 if ( bReleaseVolumeLock == FALSE)
4522 AFSAcquireExcl( pVolumeCB->VolumeLock,
4525 bReleaseVolumeLock = TRUE;
4529 // Initialize the root fcb for this volume
4532 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
4535 if( !NT_SUCCESS( ntStatus))
4538 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
4540 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
4541 AFS_TRACE_LEVEL_VERBOSE,
4542 "AFSBuildRootVolume Decrement count on volume %p Cnt %d\n",
4546 AFSReleaseResource( pVolumeCB->VolumeLock);
4548 try_return( ntStatus);
4552 // Drop the lock acquired above
4555 AFSReleaseResource( &pVolumeCB->RootFcb->NPFcb->Resource);
4558 if ( bReleaseVolumeLock == TRUE)
4561 AFSReleaseResource( pVolumeCB->VolumeLock);
4564 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4565 AFS_TRACE_LEVEL_VERBOSE_2,
4566 "AFSBuildRootVolume Evaluated target of %wZ FID %08lX-%08lX-%08lX-%08lX as root volume\n",
4567 &pVolumeCB->DirectoryCB->NameInformation.FileName,
4568 pVolumeCB->ObjectInformation.FileId.Cell,
4569 pVolumeCB->ObjectInformation.FileId.Volume,
4570 pVolumeCB->ObjectInformation.FileId.Vnode,
4571 pVolumeCB->ObjectInformation.FileId.Unique);
4573 *TargetVolumeCB = pVolumeCB;
4584 AFSProcessDFSLink( IN AFSDirectoryCB *DirEntry,
4585 IN PFILE_OBJECT FileObject,
4586 IN UNICODE_STRING *RemainingPath,
4590 NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
4591 UNICODE_STRING uniReparseName;
4592 UNICODE_STRING uniMUPDeviceName;
4593 UNICODE_STRING uniIOMgrDeviceName;
4594 AFSDirEnumEntry *pDirEntry = NULL;
4600 // Build up the name to reparse
4603 RtlInitUnicodeString( &uniMUPDeviceName,
4606 RtlInitUnicodeString( &uniIOMgrDeviceName,
4609 uniReparseName.Length = 0;
4610 uniReparseName.Buffer = NULL;
4613 // Be sure we have a target name
4616 if( DirEntry->NameInformation.TargetName.Length == 0)
4619 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
4624 if( !NT_SUCCESS( ntStatus) ||
4625 pDirEntry->TargetNameLength == 0)
4628 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4629 AFS_TRACE_LEVEL_ERROR,
4630 "AFSProcessDFSLink EvaluateTargetByID failed for Fcb %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4631 &DirEntry->NameInformation.FileName,
4632 DirEntry->ObjectInformation->FileId.Cell,
4633 DirEntry->ObjectInformation->FileId.Volume,
4634 DirEntry->ObjectInformation->FileId.Vnode,
4635 DirEntry->ObjectInformation->FileId.Unique,
4638 if( NT_SUCCESS( ntStatus))
4641 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
4644 try_return( ntStatus);
4648 // Update the target name
4651 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
4654 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
4656 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
4657 (USHORT)pDirEntry->TargetNameLength);
4659 if( !NT_SUCCESS( ntStatus))
4662 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4663 AFS_TRACE_LEVEL_ERROR,
4664 "AFSProcessDFSLink UpdateTargetName failed for Fcb %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4665 &DirEntry->NameInformation.FileName,
4666 DirEntry->ObjectInformation->FileId.Cell,
4667 DirEntry->ObjectInformation->FileId.Volume,
4668 DirEntry->ObjectInformation->FileId.Vnode,
4669 DirEntry->ObjectInformation->FileId.Unique,
4672 AFSReleaseResource( &DirEntry->NonPaged->Lock);
4674 try_return( ntStatus);
4677 AFSConvertToShared( &DirEntry->NonPaged->Lock);
4681 AFSAcquireShared( &DirEntry->NonPaged->Lock,
4685 uniReparseName.MaximumLength = uniMUPDeviceName.Length +
4687 DirEntry->NameInformation.TargetName.Length +
4690 if( RemainingPath != NULL &&
4691 RemainingPath->Length > 0)
4694 uniReparseName.MaximumLength += RemainingPath->Length;
4698 // Allocate the reparse buffer
4701 uniReparseName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
4702 uniReparseName.MaximumLength,
4703 AFS_REPARSE_NAME_TAG);
4705 if( uniReparseName.Buffer == NULL)
4708 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4709 AFS_TRACE_LEVEL_ERROR,
4710 "AFSProcessDFSLink uniReparseName.Buffer == NULL Fcb %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4711 &DirEntry->NameInformation.FileName,
4712 DirEntry->ObjectInformation->FileId.Cell,
4713 DirEntry->ObjectInformation->FileId.Volume,
4714 DirEntry->ObjectInformation->FileId.Vnode,
4715 DirEntry->ObjectInformation->FileId.Unique,
4716 STATUS_INSUFFICIENT_RESOURCES);
4718 AFSReleaseResource( &DirEntry->NonPaged->Lock);
4720 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4724 // Start building the name
4727 if ( DirEntry->NameInformation.TargetName.Buffer[ 0] != L'\\' &&
4728 DirEntry->NameInformation.TargetName.Buffer[ 1] == L':')
4731 RtlCopyMemory( uniReparseName.Buffer,
4732 uniIOMgrDeviceName.Buffer,
4733 uniIOMgrDeviceName.Length);
4735 uniReparseName.Length = uniIOMgrDeviceName.Length;
4740 RtlCopyMemory( uniReparseName.Buffer,
4741 uniMUPDeviceName.Buffer,
4742 uniMUPDeviceName.Length);
4744 uniReparseName.Length = uniMUPDeviceName.Length;
4746 if( DirEntry->NameInformation.TargetName.Buffer[ 0] != L'\\')
4749 uniReparseName.Buffer[ uniReparseName.Length/sizeof( WCHAR)] = L'\\';
4751 uniReparseName.Length += sizeof( WCHAR);
4755 RtlCopyMemory( &uniReparseName.Buffer[ uniReparseName.Length/sizeof( WCHAR)],
4756 DirEntry->NameInformation.TargetName.Buffer,
4757 DirEntry->NameInformation.TargetName.Length);
4759 uniReparseName.Length += DirEntry->NameInformation.TargetName.Length;
4761 AFSReleaseResource( &DirEntry->NonPaged->Lock);
4763 if( RemainingPath != NULL &&
4764 RemainingPath->Length > 0)
4767 if( uniReparseName.Buffer[ (uniReparseName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
4768 RemainingPath->Buffer[ 0] != L'\\')
4771 uniReparseName.Buffer[ uniReparseName.Length/sizeof( WCHAR)] = L'\\';
4773 uniReparseName.Length += sizeof( WCHAR);
4776 RtlCopyMemory( &uniReparseName.Buffer[ uniReparseName.Length/sizeof( WCHAR)],
4777 RemainingPath->Buffer,
4778 RemainingPath->Length);
4780 uniReparseName.Length += RemainingPath->Length;
4784 // Update the name in the file object
4787 if( FileObject->FileName.Buffer != NULL)
4790 AFSExFreePoolWithTag( FileObject->FileName.Buffer, 0);
4793 FileObject->FileName = uniReparseName;
4795 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4796 AFS_TRACE_LEVEL_VERBOSE,
4797 "AFSProcessDFSLink Reparsing access to Fcb %wZ FID %08lX-%08lX-%08lX-%08lX to %wZ\n",
4798 &DirEntry->NameInformation.FileName,
4799 DirEntry->ObjectInformation->FileId.Cell,
4800 DirEntry->ObjectInformation->FileId.Volume,
4801 DirEntry->ObjectInformation->FileId.Vnode,
4802 DirEntry->ObjectInformation->FileId.Unique,
4806 // Return status reparse ...
4809 ntStatus = STATUS_REPARSE;
4816 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);