2 * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
3 * Copyright (c) 2009, 2010, 2011 Your File System, Inc.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * - Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
14 * this list of conditions and the following disclaimer in the
16 * and/or other materials provided with the distribution.
17 * - Neither the names of Kernel Drivers, LLC and Your File System, Inc.
18 * nor the names of their contributors may be used to endorse or promote
19 * products derived from this software without specific prior written
20 * permission from Kernel Drivers, LLC and Your File System, Inc.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
26 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 // File: AFSNameSupport.cpp
39 #include "AFSCommon.h"
42 AFSLocateNameEntry( IN GUID *AuthGroup,
43 IN PFILE_OBJECT FileObject,
44 IN UNICODE_STRING *RootPathName,
45 IN UNICODE_STRING *ParsedPathName,
46 IN AFSNameArrayHdr *NameArray,
48 OUT AFSVolumeCB **VolumeCB,
49 IN OUT AFSDirectoryCB **ParentDirectoryCB,
50 OUT AFSDirectoryCB **DirectoryCB,
51 OUT PUNICODE_STRING ComponentName)
54 NTSTATUS ntStatus = STATUS_SUCCESS;
55 UNICODE_STRING uniPathName, uniComponentName, uniRemainingPath, uniSearchName, uniFullPathName;
57 AFSDirectoryCB *pDirEntry = NULL, *pParentDirEntry = NULL;
58 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
59 UNICODE_STRING uniSysName;
60 ULONG ulSubstituteIndex = 0;
61 BOOLEAN bSubstituteName = FALSE;
62 AFSNameArrayHdr *pNameArray = NameArray;
63 BOOLEAN bAllocatedSymLinkBuffer = FALSE;
64 UNICODE_STRING uniRelativeName, uniNoOpName;
65 AFSObjectInfoCB *pCurrentObject = NULL;
66 AFSVolumeCB *pCurrentVolume = *VolumeCB;
67 BOOLEAN bReleaseCurrentVolume = TRUE;
68 BOOLEAN bSubstitutedName = FALSE;
74 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
75 AFS_TRACE_LEVEL_VERBOSE_2,
76 "AFSLocateNameEntry (FO: %08lX) Processing full name %wZ\n",
80 RtlInitUnicodeString( &uniSysName,
83 RtlInitUnicodeString( &uniRelativeName,
86 RtlInitUnicodeString( &uniNoOpName,
90 // Cleanup some parameters
93 if( ComponentName != NULL)
96 ComponentName->Length = 0;
97 ComponentName->MaximumLength = 0;
98 ComponentName->Buffer = NULL;
102 // We will parse through the filename, locating the directory nodes until we encounter a cache miss
103 // Starting at the root node
106 pParentDirEntry = NULL;
108 pDirEntry = *ParentDirectoryCB;
110 uniPathName = *ParsedPathName;
112 uniFullPathName = *RootPathName;
114 uniComponentName.Length = uniComponentName.MaximumLength = 0;
115 uniComponentName.Buffer = NULL;
117 uniRemainingPath.Length = uniRemainingPath.MaximumLength = 0;
118 uniRemainingPath.Buffer = NULL;
120 uniSearchName.Length = uniSearchName.MaximumLength = 0;
121 uniSearchName.Buffer = NULL;
123 ASSERT( pCurrentVolume->VolumeReferenceCount > 1);
129 // Check our total link count for this name array
132 if( pNameArray->LinkCount >= (LONG)pDevExt->Specific.RDR.MaxLinkCount)
135 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
138 pCurrentObject = pDirEntry->ObjectInformation;
140 KeQueryTickCount( &pCurrentObject->LastAccessCount);
143 // Check that the directory entry is not deleted or pending delete
146 if( BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED))
149 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
150 AFS_TRACE_LEVEL_ERROR,
151 "AFSLocateNameEntry (FO: %08lX) Deleted parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
153 &pDirEntry->NameInformation.FileName,
154 pCurrentObject->FileId.Cell,
155 pCurrentObject->FileId.Volume,
156 pCurrentObject->FileId.Vnode,
157 pCurrentObject->FileId.Unique,
158 STATUS_FILE_DELETED);
160 try_return( ntStatus = STATUS_FILE_DELETED);
163 if( BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_PENDING_DELETE))
166 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
167 AFS_TRACE_LEVEL_ERROR,
168 "AFSLocateNameEntry (FO: %08lX) Delete pending on %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
170 &pDirEntry->NameInformation.FileName,
171 pCurrentObject->FileId.Cell,
172 pCurrentObject->FileId.Volume,
173 pCurrentObject->FileId.Vnode,
174 pCurrentObject->FileId.Unique,
175 STATUS_DELETE_PENDING);
177 try_return( ntStatus = STATUS_DELETE_PENDING);
181 // Check if the directory requires verification
184 if( BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_FLAGS_VERIFY) &&
185 ( pCurrentObject->FileType != AFS_FILE_TYPE_DIRECTORY ||
186 !AFSIsEnumerationInProcess( pCurrentObject)))
189 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
190 AFS_TRACE_LEVEL_VERBOSE,
191 "AFSLocateNameEntry (FO: %08lX) Verifying parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
193 &pDirEntry->NameInformation.FileName,
194 pCurrentObject->FileId.Cell,
195 pCurrentObject->FileId.Volume,
196 pCurrentObject->FileId.Vnode,
197 pCurrentObject->FileId.Unique);
200 // Directory TreeLock should be exclusively held
203 AFSAcquireExcl( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
206 ntStatus = AFSVerifyEntry( AuthGroup,
209 AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
211 if( !NT_SUCCESS( ntStatus))
214 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
215 AFS_TRACE_LEVEL_ERROR,
216 "AFSLocateNameEntry (FO: %08lX) Failed to verify parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
218 &pDirEntry->NameInformation.FileName,
219 pCurrentObject->FileId.Cell,
220 pCurrentObject->FileId.Volume,
221 pCurrentObject->FileId.Vnode,
222 pCurrentObject->FileId.Unique,
225 try_return( ntStatus);
230 // Ensure the parent node has been evaluated, if not then go do it now
233 if( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) ||
234 pCurrentObject->FileType == AFS_FILE_TYPE_UNKNOWN)
237 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
238 AFS_TRACE_LEVEL_VERBOSE,
239 "AFSLocateNameEntry (FO: %08lX) Evaluating parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
241 &pDirEntry->NameInformation.FileName,
242 pCurrentObject->FileId.Cell,
243 pCurrentObject->FileId.Volume,
244 pCurrentObject->FileId.Vnode,
245 pCurrentObject->FileId.Unique);
247 ntStatus = AFSEvaluateNode( AuthGroup,
250 if( !NT_SUCCESS( ntStatus))
253 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
254 AFS_TRACE_LEVEL_ERROR,
255 "AFSLocateNameEntry (FO: %08lX) Failed to evaluate parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
257 &pDirEntry->NameInformation.FileName,
258 pCurrentObject->FileId.Cell,
259 pCurrentObject->FileId.Volume,
260 pCurrentObject->FileId.Vnode,
261 pCurrentObject->FileId.Unique,
264 try_return( ntStatus);
267 ClearFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
271 // If this is a mount point or symlink then go get the real directory node
274 switch( pCurrentObject->FileType)
277 case AFS_FILE_TYPE_SYMLINK:
280 UNICODE_STRING uniTempName;
281 WCHAR *pTmpBuffer = NULL;
285 // Check if the flag is set to NOT evaluate a symlink
286 // and we are done with the parsing
289 if( BooleanFlagOn( Flags, AFS_LOCATE_FLAGS_NO_SL_TARGET_EVAL) &&
290 uniRemainingPath.Length == 0)
294 // Pass back the directory entries
297 *ParentDirectoryCB = pParentDirEntry;
299 *DirectoryCB = pDirEntry;
301 *VolumeCB = pCurrentVolume;
303 *RootPathName = uniFullPathName;
305 try_return( ntStatus);
308 AFSAcquireExcl( &pDirEntry->NonPaged->Lock,
311 if( pDirEntry->NameInformation.TargetName.Length == 0)
315 // We'll reset the DV to ensure we validate the metadata content
318 pCurrentObject->DataVersion.QuadPart = (ULONGLONG)-1;
320 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_VERIFY);
322 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
323 AFS_TRACE_LEVEL_VERBOSE,
324 "AFSLocateNameEntry (FO: %08lX) Verifying symlink parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
326 &pDirEntry->NameInformation.FileName,
327 pCurrentObject->FileId.Cell,
328 pCurrentObject->FileId.Volume,
329 pCurrentObject->FileId.Vnode,
330 pCurrentObject->FileId.Unique);
333 // Directory TreeLock should be exclusively held
336 AFSAcquireExcl( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
339 ntStatus = AFSVerifyEntry( AuthGroup,
342 AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
344 if( !NT_SUCCESS( ntStatus))
347 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
348 AFS_TRACE_LEVEL_ERROR,
349 "AFSLocateNameEntry (FO: %08lX) Failed to verify symlink parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
351 &pDirEntry->NameInformation.FileName,
352 pCurrentObject->FileId.Cell,
353 pCurrentObject->FileId.Volume,
354 pCurrentObject->FileId.Vnode,
355 pCurrentObject->FileId.Unique,
358 AFSReleaseResource( &pDirEntry->NonPaged->Lock);
360 try_return( ntStatus);
364 // If the type changed then reprocess this entry
367 if( pCurrentObject->FileType != AFS_FILE_TYPE_SYMLINK)
370 AFSReleaseResource( &pDirEntry->NonPaged->Lock);
377 // If we were given a zero length target name then deny access to the entry
380 if( pDirEntry->NameInformation.TargetName.Length == 0)
383 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
385 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
386 AFS_TRACE_LEVEL_ERROR,
387 "AFSLocateNameEntry (FO: %08lX) Failed to retrieve target name for symlink %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
389 &pDirEntry->NameInformation.FileName,
390 pCurrentObject->FileId.Cell,
391 pCurrentObject->FileId.Volume,
392 pCurrentObject->FileId.Vnode,
393 pCurrentObject->FileId.Unique,
396 AFSReleaseResource( &pDirEntry->NonPaged->Lock);
398 try_return( ntStatus);
401 if( AFSIsRelativeName( &pDirEntry->NameInformation.TargetName))
404 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
405 AFS_TRACE_LEVEL_VERBOSE,
406 "AFSLocateNameEntry (FO: %08lX) Processing relative symlink target %wZ for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
408 &pDirEntry->NameInformation.TargetName,
409 &pDirEntry->NameInformation.FileName,
410 pCurrentObject->FileId.Cell,
411 pCurrentObject->FileId.Volume,
412 pCurrentObject->FileId.Vnode,
413 pCurrentObject->FileId.Unique);
416 // We'll substitute this name into the current process name
417 // starting at where we sit in the path
420 uniTempName.Length = 0;
421 uniTempName.MaximumLength = (USHORT)((char *)uniComponentName.Buffer - (char *)uniFullPathName.Buffer) +
422 pDirEntry->NameInformation.TargetName.Length +
424 uniRemainingPath.Length;
426 uniTempName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
427 uniTempName.MaximumLength,
428 AFS_NAME_BUFFER_ONE_TAG);
430 if( uniTempName.Buffer == NULL)
433 AFSReleaseResource( &pDirEntry->NonPaged->Lock);
435 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
439 // We have so first copy in the portion up to the component
443 RtlCopyMemory( uniTempName.Buffer,
444 uniFullPathName.Buffer,
445 (ULONG)((char *)uniComponentName.Buffer - (char *)uniFullPathName.Buffer));
447 uniTempName.Length = (USHORT)((char *)uniComponentName.Buffer - (char *)uniFullPathName.Buffer);
449 if( bAllocatedSymLinkBuffer ||
453 pTmpBuffer = uniFullPathName.Buffer;
456 bAllocatedSymLinkBuffer = TRUE;
459 // Have we parsed this name yet? Better have at least once ...
462 if( uniComponentName.Length == 0)
468 // Copy in the target name ...
471 RtlCopyMemory( &uniTempName.Buffer[ uniTempName.Length/sizeof( WCHAR)],
472 pDirEntry->NameInformation.TargetName.Buffer,
473 pDirEntry->NameInformation.TargetName.Length);
475 uniPathName.Buffer = &uniTempName.Buffer[ uniTempName.Length/sizeof( WCHAR)];
477 uniPathName.Length += pDirEntry->NameInformation.TargetName.Length;
478 uniPathName.MaximumLength = uniTempName.MaximumLength;
480 uniTempName.Length += pDirEntry->NameInformation.TargetName.Length;
483 // And now any remaining portion of the name
486 if( uniRemainingPath.Length > 0)
489 if( uniRemainingPath.Buffer[ 0] != L'\\')
492 uniRemainingPath.Buffer--;
493 uniRemainingPath.Length += sizeof( WCHAR);
495 uniPathName.Length += sizeof( WCHAR);
498 RtlCopyMemory( &uniTempName.Buffer[ uniTempName.Length/sizeof( WCHAR)],
499 uniRemainingPath.Buffer,
500 uniRemainingPath.Length);
502 uniTempName.Length += uniRemainingPath.Length;
505 uniFullPathName = uniTempName;
507 if( pTmpBuffer != NULL)
510 AFSExFreePool( pTmpBuffer);
513 AFSReleaseResource( &pDirEntry->NonPaged->Lock);
516 // Dereference the current entry ..
519 lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
521 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
522 AFS_TRACE_LEVEL_VERBOSE,
523 "AFSLocateNameEntry Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
524 &pDirEntry->NameInformation.FileName,
530 // OK, need to back up one entry for the correct parent since the current
531 // entry we are on is the symlink itself
534 pDirEntry = AFSBackupEntry( pNameArray);
537 // Increment our reference on this dir entry
540 lCount = InterlockedIncrement( &pDirEntry->OpenReferenceCount);
542 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
543 AFS_TRACE_LEVEL_VERBOSE,
544 "AFSLocateNameEntry Increment1 count on %wZ DE %p Ccb %p Cnt %d\n",
545 &pDirEntry->NameInformation.FileName,
550 if( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_ROOT_VOLUME))
553 pParentDirEntry = NULL;
558 pParentDirEntry = AFSGetParentEntry( pNameArray);
560 ASSERT( pParentDirEntry != pDirEntry);
566 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
567 AFS_TRACE_LEVEL_VERBOSE,
568 "AFSLocateNameEntry (FO: %08lX) Processing absolute symlink target %wZ for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
570 &pDirEntry->NameInformation.TargetName,
571 &pDirEntry->NameInformation.FileName,
572 pCurrentObject->FileId.Cell,
573 pCurrentObject->FileId.Volume,
574 pCurrentObject->FileId.Vnode,
575 pCurrentObject->FileId.Unique);
578 // We'll substitute this name into the current process name
579 // starting at where we sit in the path
582 uniTempName.Length = 0;
583 uniTempName.MaximumLength = pDirEntry->NameInformation.TargetName.Length +
585 uniRemainingPath.Length;
587 uniTempName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
588 uniTempName.MaximumLength,
589 AFS_NAME_BUFFER_TWO_TAG);
591 if( uniTempName.Buffer == NULL)
594 AFSReleaseResource( &pDirEntry->NonPaged->Lock);
596 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
599 if( bAllocatedSymLinkBuffer ||
603 pTmpBuffer = uniFullPathName.Buffer;
606 bAllocatedSymLinkBuffer = TRUE;
609 // Have we parsed this name yet? Better have at least once ...
612 if( uniComponentName.Length == 0)
618 // Copy in the target name ...
621 RtlCopyMemory( uniTempName.Buffer,
622 pDirEntry->NameInformation.TargetName.Buffer,
623 pDirEntry->NameInformation.TargetName.Length);
625 uniTempName.Length = pDirEntry->NameInformation.TargetName.Length;
628 // And now any remaining portion of the name
631 if( uniRemainingPath.Length > 0)
634 if( uniRemainingPath.Buffer[ 0] != L'\\')
637 uniRemainingPath.Buffer--;
638 uniRemainingPath.Length += sizeof( WCHAR);
641 RtlCopyMemory( &uniTempName.Buffer[ uniTempName.Length/sizeof( WCHAR)],
642 uniRemainingPath.Buffer,
643 uniRemainingPath.Length);
645 uniTempName.Length += uniRemainingPath.Length;
648 uniFullPathName = uniTempName;
650 uniPathName = uniTempName;
652 if( pTmpBuffer != NULL)
655 AFSExFreePool( pTmpBuffer);
658 AFSReleaseResource( &pDirEntry->NonPaged->Lock);
661 // If our current volume is not the global root then make it so ...
664 if( pCurrentVolume != AFSGlobalRoot)
667 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
668 AFS_TRACE_LEVEL_VERBOSE,
669 "AFSLocateNameEntry (FO: %08lX) Current volume not global, resetting for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
671 &pDirEntry->NameInformation.FileName,
672 pCurrentObject->FileId.Cell,
673 pCurrentObject->FileId.Volume,
674 pCurrentObject->FileId.Vnode,
675 pCurrentObject->FileId.Unique);
677 lCount = InterlockedDecrement( &pCurrentVolume->VolumeReferenceCount);
679 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
680 AFS_TRACE_LEVEL_VERBOSE,
681 "AFSLocateNameEntry Decrement count on volume %08lX Cnt %d\n",
685 pCurrentVolume = AFSGlobalRoot;
687 lCount = InterlockedIncrement( &pCurrentVolume->VolumeReferenceCount);
689 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
690 AFS_TRACE_LEVEL_VERBOSE,
691 "AFSLocateNameEntry Increment count on volume %08lX Cnt %d\n",
697 // Dereference our current dir entry
700 lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
702 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
703 AFS_TRACE_LEVEL_VERBOSE,
704 "AFSLocateNameEntry Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
705 &pDirEntry->NameInformation.FileName,
710 pDirEntry = pCurrentVolume->DirectoryCB;
713 // Reference the new dir entry
716 lCount = InterlockedIncrement( &pDirEntry->OpenReferenceCount);
718 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
719 AFS_TRACE_LEVEL_VERBOSE,
720 "AFSLocateNameEntry Increment2 count on %wZ DE %p Ccb %p Cnt %d\n",
721 &pDirEntry->NameInformation.FileName,
727 // Reset the name array
728 // Persist the link count in the name array
731 lLinkCount = pNameArray->LinkCount;
733 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
734 AFS_TRACE_LEVEL_VERBOSE,
735 "AFSLocateNameEntry (FO: %08lX) Resetting name array for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
737 &pDirEntry->NameInformation.FileName,
738 pCurrentObject->FileId.Cell,
739 pCurrentObject->FileId.Volume,
740 pCurrentObject->FileId.Vnode,
741 pCurrentObject->FileId.Unique);
743 AFSResetNameArray( pNameArray,
746 pNameArray->LinkCount = lLinkCount;
749 // Process over the \\<Global root> portion of the name
752 FsRtlDissectName( uniPathName,
756 if( RtlCompareUnicodeString( &uniComponentName,
761 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
762 AFS_TRACE_LEVEL_ERROR,
763 "AFSLocateNameEntry Name %wZ contains invalid server name\n",
767 // The correct response would be STATUS_OBJECT_PATH_INVALID
768 // but that prevents cmd.exe from performing a recursive
769 // directory enumeration when opening a directory entry
770 // that represents a symlink to an invalid path is discovered.
772 try_return( ntStatus = STATUS_OBJECT_PATH_NOT_FOUND);
775 uniPathName = uniRemainingPath;
777 pParentDirEntry = NULL;
781 // Increment our link count
784 lCount = InterlockedIncrement( &pNameArray->LinkCount);
789 case AFS_FILE_TYPE_MOUNTPOINT:
793 // Check if the flag is set to NOT evaluate a mount point
794 // and we are done with the parsing
797 if( BooleanFlagOn( Flags, AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL) &&
798 uniRemainingPath.Length == 0)
802 // Pass back the directory entries
805 *ParentDirectoryCB = pParentDirEntry;
807 *DirectoryCB = pDirEntry;
809 *VolumeCB = pCurrentVolume;
811 *RootPathName = uniFullPathName;
813 try_return( ntStatus);
816 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
817 AFS_TRACE_LEVEL_VERBOSE,
818 "AFSLocateNameEntry (FO: %08lX) Building MP target for parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
820 &pDirEntry->NameInformation.FileName,
821 pCurrentObject->FileId.Cell,
822 pCurrentObject->FileId.Volume,
823 pCurrentObject->FileId.Vnode,
824 pCurrentObject->FileId.Unique);
827 // Go retrieve the target entry for this node
828 // Release the current volume cb entry since we would
829 // have lock inversion in the following call
830 // Also decrement the ref count on the volume
833 ASSERT( pCurrentVolume->VolumeReferenceCount > 1);
835 lCount = InterlockedDecrement( &pCurrentVolume->VolumeReferenceCount);
837 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
838 AFS_TRACE_LEVEL_VERBOSE,
839 "AFSLocateNameEntry Decrement2 count on volume %08lX Cnt %d\n",
841 pCurrentVolume->VolumeReferenceCount);
843 ntStatus = AFSBuildMountPointTarget( AuthGroup,
847 if( !NT_SUCCESS( ntStatus))
850 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
851 AFS_TRACE_LEVEL_ERROR,
852 "AFSLocateNameEntry (FO: %08lX) Failed to build MP target for parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
854 &pDirEntry->NameInformation.FileName,
855 pCurrentObject->FileId.Cell,
856 pCurrentObject->FileId.Volume,
857 pCurrentObject->FileId.Vnode,
858 pCurrentObject->FileId.Unique,
862 // We already decremented the current volume above
865 bReleaseCurrentVolume = FALSE;
867 try_return( ntStatus);
870 ASSERT( pCurrentVolume->VolumeReferenceCount > 1);
873 // Replace the current name for the mp with the volume root of the target
876 AFSReplaceCurrentElement( pNameArray,
877 pCurrentVolume->DirectoryCB);
880 // We want to restart processing here on the new parent ...
881 // Deref and ref count the entries
884 lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
886 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
887 AFS_TRACE_LEVEL_VERBOSE,
888 "AFSLocateNameEntry Decrement3 count on %wZ DE %p Ccb %p Cnt %d\n",
889 &pDirEntry->NameInformation.FileName,
894 pDirEntry = pCurrentVolume->DirectoryCB;
896 lCount = InterlockedIncrement( &pDirEntry->OpenReferenceCount);
898 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
899 AFS_TRACE_LEVEL_VERBOSE,
900 "AFSLocateNameEntry Increment3 count on %wZ DE %p Ccb %p Cnt %d\n",
901 &pDirEntry->NameInformation.FileName,
906 pParentDirEntry = NULL;
909 // Increment our link count
912 lCount = InterlockedIncrement( &pNameArray->LinkCount);
917 case AFS_FILE_TYPE_DFSLINK:
920 if( BooleanFlagOn( Flags, AFS_LOCATE_FLAGS_NO_DFS_LINK_EVAL))
924 // Pass back the directory entries
927 *ParentDirectoryCB = pParentDirEntry;
929 *DirectoryCB = pDirEntry;
931 *VolumeCB = pCurrentVolume;
933 *RootPathName = uniFullPathName;
935 try_return( ntStatus);
939 // This is a DFS link so we need to update the file name and return STATUS_REPARSE to the
940 // system for it to reevaluate it
943 if( FileObject != NULL)
946 ntStatus = AFSProcessDFSLink( pDirEntry,
955 // This is where we have been re-entered from an NP evaluation call via the BuildBranch()
959 ntStatus = STATUS_INVALID_PARAMETER;
962 if( ntStatus != STATUS_SUCCESS &&
963 ntStatus != STATUS_REPARSE)
966 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
967 AFS_TRACE_LEVEL_ERROR,
968 "AFSLocateNameEntry (FO: %08lX) Failed to process DFSLink parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
970 &pDirEntry->NameInformation.FileName,
971 pCurrentObject->FileId.Cell,
972 pCurrentObject->FileId.Volume,
973 pCurrentObject->FileId.Vnode,
974 pCurrentObject->FileId.Unique,
978 try_return( ntStatus);
981 case AFS_FILE_TYPE_UNKNOWN:
982 case AFS_FILE_TYPE_INVALID:
986 // Something was not processed ...
989 try_return( ntStatus = STATUS_ACCESS_DENIED);
992 } /* end of switch */
995 // If the parent is not initialized then do it now
998 if( pCurrentObject->FileType == AFS_FILE_TYPE_DIRECTORY &&
999 !BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
1002 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1003 AFS_TRACE_LEVEL_VERBOSE,
1004 "AFSLocateNameEntry (FO: %08lX) Enumerating parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1006 &pDirEntry->NameInformation.FileName,
1007 pCurrentObject->FileId.Cell,
1008 pCurrentObject->FileId.Volume,
1009 pCurrentObject->FileId.Vnode,
1010 pCurrentObject->FileId.Unique);
1012 AFSAcquireExcl( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
1015 if( !BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
1018 ntStatus = AFSEnumerateDirectory( AuthGroup,
1022 if( !NT_SUCCESS( ntStatus))
1025 AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
1027 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1028 AFS_TRACE_LEVEL_ERROR,
1029 "AFSLocateNameEntry (FO: %08lX) Failed to enumerate parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1031 &pDirEntry->NameInformation.FileName,
1032 pCurrentObject->FileId.Cell,
1033 pCurrentObject->FileId.Volume,
1034 pCurrentObject->FileId.Vnode,
1035 pCurrentObject->FileId.Unique,
1038 try_return( ntStatus);
1041 SetFlag( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
1044 AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
1046 else if( pCurrentObject->FileType == AFS_FILE_TYPE_FILE)
1049 if( uniPathName.Length > 0)
1052 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1053 AFS_TRACE_LEVEL_ERROR,
1054 "AFSLocateNameEntry (FO: %08lX) Encountered file node %wZ FID %08lX-%08lX-%08lX-%08lX in path processing\n",
1056 &pDirEntry->NameInformation.FileName,
1057 pCurrentObject->FileId.Cell,
1058 pCurrentObject->FileId.Volume,
1059 pCurrentObject->FileId.Vnode,
1060 pCurrentObject->FileId.Unique);
1062 // The proper error code to return would be STATUS_OBJECT_PATH_INVALID because
1063 // one of the components of the path is not a directory. However, returning
1064 // that error prevents IIS 7 and 7.5 from being able to serve data out of AFS.
1065 // Instead IIS insists on treating the target file as if it is a directory containing
1066 // a potential web.config file. NTFS and LanMan return STATUS_OBJECT_PATH_NOT_FOUND.
1067 // AFS will follow suit.
1069 ntStatus = STATUS_OBJECT_PATH_NOT_FOUND;
1074 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1075 AFS_TRACE_LEVEL_VERBOSE,
1076 "AFSLocateNameEntry (FO: %08lX) Returning file %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1078 &pDirEntry->NameInformation.FileName,
1079 pCurrentObject->FileId.Cell,
1080 pCurrentObject->FileId.Volume,
1081 pCurrentObject->FileId.Vnode,
1082 pCurrentObject->FileId.Unique);
1085 // Pass back the directory entries
1088 *ParentDirectoryCB = pParentDirEntry;
1090 *DirectoryCB = pDirEntry;
1092 *VolumeCB = pCurrentVolume;
1094 *RootPathName = uniFullPathName;
1097 try_return( ntStatus);
1101 // If we are at the end of the processing, set our returned information and get out
1104 if( uniPathName.Length == 0)
1107 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1108 AFS_TRACE_LEVEL_VERBOSE,
1109 "AFSLocateNameEntry (FO: %08lX) Completed processing returning %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1111 &pDirEntry->NameInformation.FileName,
1112 pCurrentObject->FileId.Cell,
1113 pCurrentObject->FileId.Volume,
1114 pCurrentObject->FileId.Vnode,
1115 pCurrentObject->FileId.Unique);
1118 // Pass back the directory entries
1121 *ParentDirectoryCB = pParentDirEntry;
1123 *DirectoryCB = pDirEntry;
1125 *VolumeCB = pCurrentVolume;
1127 *RootPathName = uniFullPathName;
1129 try_return( ntStatus);
1133 // We may have returned to the top of the while( TRUE)
1135 if( bSubstituteName &&
1136 uniSearchName.Buffer != NULL)
1139 AFSExFreePool( uniSearchName.Buffer);
1141 bSubstituteName = FALSE;
1143 uniSearchName.Length = uniSearchName.MaximumLength = 0;
1144 uniSearchName.Buffer = NULL;
1147 ulSubstituteIndex = 1;
1149 ntStatus = STATUS_SUCCESS;
1152 // Get the next component name
1155 FsRtlDissectName( uniPathName,
1160 // Check for the . and .. in the path
1163 if( RtlCompareUnicodeString( &uniComponentName,
1168 uniPathName = uniRemainingPath;
1173 if( RtlCompareUnicodeString( &uniComponentName,
1178 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1179 AFS_TRACE_LEVEL_VERBOSE,
1180 "AFSLocateNameEntry (FO: %08lX) Backing up entry from %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1182 &pDirEntry->NameInformation.FileName,
1183 pCurrentObject->FileId.Cell,
1184 pCurrentObject->FileId.Volume,
1185 pCurrentObject->FileId.Vnode,
1186 pCurrentObject->FileId.Unique);
1189 // Need to back up one entry in the name array
1191 lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
1193 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1194 AFS_TRACE_LEVEL_VERBOSE,
1195 "AFSLocateNameEntry Decrement4 count on %wZ DE %p Ccb %p Cnt %d\n",
1196 &pDirEntry->NameInformation.FileName,
1201 pDirEntry = AFSBackupEntry( NameArray);
1203 if( pDirEntry == NULL)
1206 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1207 AFS_TRACE_LEVEL_ERROR,
1208 "AFSLocateNameEntry AFSBackupEntry failed\n");
1210 try_return(ntStatus = STATUS_OBJECT_PATH_INVALID);
1213 lCount = InterlockedIncrement( &pDirEntry->OpenReferenceCount);
1215 if( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_ROOT_VOLUME))
1218 pParentDirEntry = NULL;
1223 pParentDirEntry = AFSGetParentEntry( pNameArray);
1225 ASSERT( pParentDirEntry != pDirEntry);
1228 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1229 AFS_TRACE_LEVEL_VERBOSE,
1230 "AFSLocateNameEntry Increment4 count on %wZ DE %p Ccb %p Cnt %d\n",
1231 &pDirEntry->NameInformation.FileName,
1234 pDirEntry->OpenReferenceCount);
1236 uniPathName = uniRemainingPath;
1242 // Update our pointers
1245 pParentDirEntry = pDirEntry;
1249 uniSearchName = uniComponentName;
1251 while( pDirEntry == NULL)
1255 // If the SearchName contains @SYS then we perform the substitution.
1256 // If there is no substitution we give up.
1259 if( !bSubstituteName &&
1260 FsRtlIsNameInExpression( &uniSysName,
1266 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1267 AFS_TRACE_LEVEL_VERBOSE_2,
1268 "AFSLocateNameEntry (FO: %08lX) Processing @SYS substitution for %wZ Index %08lX\n",
1273 ntStatus = AFSSubstituteSysName( &uniComponentName,
1277 if ( NT_SUCCESS( ntStatus))
1280 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1281 AFS_TRACE_LEVEL_VERBOSE_2,
1282 "AFSLocateNameEntry (FO: %08lX) Located substitution %wZ for %wZ Index %08lX\n",
1289 // Go reparse the name again
1292 bSubstituteName = TRUE;
1294 ulSubstituteIndex++; // For the next entry, if needed
1296 continue; // while( pDirEntry == NULL)
1301 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1302 AFS_TRACE_LEVEL_ERROR,
1303 "AFSLocateNameEntry (FO: %08lX) Failed to locate substitute string for %wZ Index %08lX Status %08lX\n",
1309 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
1313 // Pass back the directory entries
1316 *ParentDirectoryCB = pParentDirEntry;
1318 *DirectoryCB = NULL;
1320 *VolumeCB = pCurrentVolume;
1322 if( ComponentName != NULL)
1325 *ComponentName = uniComponentName;
1328 *RootPathName = uniFullPathName;
1332 // We can't possibly have a pDirEntry since the lookup failed
1334 try_return( ntStatus);
1339 // Generate the CRC on the node and perform a case sensitive lookup
1342 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1343 AFS_TRACE_LEVEL_VERBOSE_2,
1344 "AFSLocateNameEntry (FO: %08lX) Searching for entry %wZ case sensitive\n",
1348 ulCRC = AFSGenerateCRC( &uniSearchName,
1351 AFSAcquireShared( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
1354 AFSLocateCaseSensitiveDirEntry( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
1358 if( pDirEntry == NULL)
1362 // Missed so perform a case insensitive lookup
1365 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1366 AFS_TRACE_LEVEL_VERBOSE_2,
1367 "AFSLocateNameEntry (FO: %08lX) Searching for entry %wZ case insensitive\n",
1371 ulCRC = AFSGenerateCRC( &uniSearchName,
1374 AFSLocateCaseInsensitiveDirEntry( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
1378 if( pDirEntry == NULL)
1382 // OK, if this component is a valid short name then try
1383 // a lookup in the short name tree
1386 if( RtlIsNameLegalDOS8Dot3( &uniSearchName,
1391 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1392 AFS_TRACE_LEVEL_VERBOSE_2,
1393 "AFSLocateNameEntry (FO: %08lX) Searching for entry %wZ short name\n",
1397 AFSLocateShortNameDirEntry( pParentDirEntry->ObjectInformation->Specific.Directory.ShortNameTree,
1402 if( pDirEntry == NULL)
1406 // If we substituted a name then reset our search name and try again
1409 if( bSubstituteName)
1412 AFSExFreePool( uniSearchName.Buffer);
1414 uniSearchName = uniComponentName;
1416 bSubstituteName = FALSE;
1418 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1420 continue; // while( pDirEntry == NULL)
1423 if( uniRemainingPath.Length > 0)
1426 ntStatus = STATUS_OBJECT_PATH_NOT_FOUND;
1431 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
1433 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1434 AFS_TRACE_LEVEL_VERBOSE,
1435 "AFSLocateNameEntry (FO: %08lX) Returning name not found for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1438 pCurrentObject->FileId.Cell,
1439 pCurrentObject->FileId.Volume,
1440 pCurrentObject->FileId.Vnode,
1441 pCurrentObject->FileId.Unique);
1444 // Pass back the directory entries
1447 *ParentDirectoryCB = pParentDirEntry;
1449 *DirectoryCB = NULL;
1451 *VolumeCB = pCurrentVolume;
1453 if( ComponentName != NULL)
1456 *ComponentName = uniComponentName;
1459 *RootPathName = uniFullPathName;
1462 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1465 // Node name not found so get out
1468 try_return( ntStatus); // while( pDirEntry == NULL)
1475 // Here we have a match on the case insensitive lookup for the name. If there
1476 // Is more than one link entry for this node then fail the lookup request
1479 if( !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD) ||
1480 pDirEntry->CaseInsensitiveList.fLink != NULL)
1483 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1485 try_return(ntStatus = STATUS_OBJECT_NAME_COLLISION);
1490 if( pDirEntry != NULL)
1494 // If the verify flag is set on the parent and the current entry is deleted
1495 // revalidate the parent and search again.
1498 if( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED) &&
1499 BooleanFlagOn( pParentDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY))
1502 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1504 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1505 AFS_TRACE_LEVEL_VERBOSE,
1506 "AFSLocateNameEntry (FO: %08lX) Verifying(2) parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1508 &pParentDirEntry->NameInformation.FileName,
1509 pParentDirEntry->ObjectInformation->FileId.Cell,
1510 pParentDirEntry->ObjectInformation->FileId.Volume,
1511 pParentDirEntry->ObjectInformation->FileId.Vnode,
1512 pParentDirEntry->ObjectInformation->FileId.Unique);
1515 // Directory TreeLock should be exclusively held
1518 AFSAcquireExcl( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
1521 ntStatus = AFSVerifyEntry( AuthGroup,
1524 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1526 if( !NT_SUCCESS( ntStatus))
1529 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1530 AFS_TRACE_LEVEL_ERROR,
1531 "AFSLocateNameEntry (FO: %08lX) Failed to verify(2) parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1533 &pParentDirEntry->NameInformation.FileName,
1534 pParentDirEntry->ObjectInformation->FileId.Cell,
1535 pParentDirEntry->ObjectInformation->FileId.Volume,
1536 pParentDirEntry->ObjectInformation->FileId.Vnode,
1537 pParentDirEntry->ObjectInformation->FileId.Unique,
1540 try_return( ntStatus);
1543 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1544 AFS_TRACE_LEVEL_VERBOSE,
1545 "AFSLocateNameEntry (FO: %08lX) Reprocessing component %wZ in parent %wZ\n",
1548 &pParentDirEntry->NameInformation.FileName);
1557 // Increment our dir entry ref count
1560 lCount = InterlockedIncrement( &pDirEntry->OpenReferenceCount);
1562 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1563 AFS_TRACE_LEVEL_VERBOSE,
1564 "AFSLocateNameEntry Increment5 count on %wZ DE %p Ccb %p Cnt %d\n",
1565 &pDirEntry->NameInformation.FileName,
1571 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1573 } // End while( pDirEntry == NULL)
1576 // If we have a dirEntry for this component, perform some basic validation on it
1579 if( pDirEntry != NULL &&
1580 BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
1583 pCurrentObject = pDirEntry->ObjectInformation;
1585 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1586 AFS_TRACE_LEVEL_ERROR,
1587 "AFSLocateNameEntry (FO: %08lX) Deleted entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1589 &pDirEntry->NameInformation.FileName,
1590 pCurrentObject->FileId.Cell,
1591 pCurrentObject->FileId.Volume,
1592 pCurrentObject->FileId.Vnode,
1593 pCurrentObject->FileId.Unique);
1596 // This entry was deleted through the invalidation call back so perform cleanup
1600 ASSERT( pCurrentObject->ParentObjectInformation != NULL);
1602 AFSAcquireExcl( pCurrentObject->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
1605 AFSAcquireExcl( pCurrentObject->VolumeCB->ObjectInfoTree.TreeLock,
1608 lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
1613 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING|AFS_SUBSYSTEM_CLEANUP_PROCESSING,
1614 AFS_TRACE_LEVEL_VERBOSE,
1615 "AFSLocateNameEntry Deleting dir entry %08lX (%08lX) for %wZ\n",
1618 &pDirEntry->NameInformation.FileName);
1621 // Remove and delete the directory entry from the parent list
1624 AFSDeleteDirEntry( pCurrentObject->ParentObjectInformation,
1627 if( pCurrentObject->ObjectReferenceCount == 0)
1630 if( BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_INSERTED_HASH_TREE))
1633 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
1634 AFS_TRACE_LEVEL_VERBOSE,
1635 "AFSLocateNameEntry Removing object %08lX from volume tree\n",
1638 AFSRemoveHashEntry( &pCurrentObject->VolumeCB->ObjectInfoTree.TreeHead,
1639 &pCurrentObject->TreeEntry);
1641 ClearFlag( pCurrentObject->Flags, AFS_OBJECT_INSERTED_HASH_TREE);
1648 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1649 AFS_TRACE_LEVEL_VERBOSE,
1650 "AFSLocateNameEntry Setting DELETE flag in dir entry %p for %wZ\n",
1652 &pDirEntry->NameInformation.FileName);
1654 SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
1656 AFSRemoveNameEntry( pCurrentObject->ParentObjectInformation,
1660 AFSReleaseResource( pCurrentObject->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1662 AFSReleaseResource( pCurrentObject->VolumeCB->ObjectInfoTree.TreeLock);
1665 // We deleted the dir entry so check if there is any remaining portion
1666 // of the name to process.
1669 if( uniRemainingPath.Length > 0)
1671 ntStatus = STATUS_OBJECT_PATH_NOT_FOUND;
1676 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
1678 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1679 AFS_TRACE_LEVEL_VERBOSE,
1680 "AFSLocateNameEntry (FO: %08lX) Returning name not found(2) for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1683 pCurrentObject->FileId.Cell,
1684 pCurrentObject->FileId.Volume,
1685 pCurrentObject->FileId.Vnode,
1686 pCurrentObject->FileId.Unique);
1689 // Pass back the directory entries
1692 *ParentDirectoryCB = pParentDirEntry;
1694 *DirectoryCB = NULL;
1696 *VolumeCB = pCurrentVolume;
1698 if( ComponentName != NULL)
1701 *ComponentName = uniComponentName;
1704 *RootPathName = uniFullPathName;
1708 if( ntStatus != STATUS_SUCCESS)
1711 try_return( ntStatus);
1715 // Decrement the previous parent
1718 lCount = InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
1720 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1721 AFS_TRACE_LEVEL_VERBOSE,
1722 "AFSLocateNameEntry Decrement5 count on Parent %wZ DE %p Ccb %p Cnt %d\n",
1723 &pParentDirEntry->NameInformation.FileName,
1729 // If we ended up substituting a name in the component then update
1730 // the full path and update the pointers
1733 if( bSubstituteName)
1736 BOOLEAN bRelativeOpen = FALSE;
1738 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1739 AFS_TRACE_LEVEL_VERBOSE_2,
1740 "AFSLocateNameEntry (FO: %08lX) Substituting %wZ into %wZ Index %08lX\n",
1746 if( FileObject != NULL &&
1747 FileObject->RelatedFileObject != NULL)
1750 bRelativeOpen = TRUE;
1754 // AFSSubstituteNameInPath will replace the uniFullPathName.Buffer
1755 // and free the prior Buffer contents but only if the fourth
1756 // parameter is TRUE.
1759 ntStatus = AFSSubstituteNameInPath( &uniFullPathName,
1764 bAllocatedSymLinkBuffer ||
1767 if( !NT_SUCCESS( ntStatus))
1770 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1771 AFS_TRACE_LEVEL_ERROR,
1772 "AFSLocateNameEntry (FO: %08lX) Failure to substitute %wZ into %wZ Index %08lX Status %08lX\n",
1779 try_return( ntStatus);
1783 // We have substituted a name into the buffer so if we do this again for this
1784 // path, we need to free up the buffer we allocated.
1787 bSubstitutedName = TRUE;
1791 // Update the search parameters
1794 uniPathName = uniRemainingPath;
1797 // Check if the is a SymLink entry but has no Target FileID or Name. In this
1798 // case it might be a DFS Link so let's go and evaluate it to be sure
1801 if( pCurrentObject->FileType == AFS_FILE_TYPE_SYMLINK &&
1802 pCurrentObject->TargetFileId.Vnode == 0 &&
1803 pCurrentObject->TargetFileId.Unique == 0 &&
1804 pDirEntry->NameInformation.TargetName.Length == 0)
1807 ntStatus = AFSValidateSymLink( AuthGroup,
1810 if( !NT_SUCCESS( ntStatus))
1813 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1814 AFS_TRACE_LEVEL_ERROR,
1815 "AFSLocateNameEntry (FO: %08lX) Failed to evaluate possible DFS Link %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1817 &pDirEntry->NameInformation.FileName,
1818 pCurrentObject->FileId.Cell,
1819 pCurrentObject->FileId.Volume,
1820 pCurrentObject->FileId.Vnode,
1821 pCurrentObject->FileId.Unique,
1824 try_return( ntStatus);
1829 // Update the name array
1832 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1833 AFS_TRACE_LEVEL_VERBOSE,
1834 "AFSLocateNameEntry (FO: %08lX) Inserting name array entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1836 &pDirEntry->NameInformation.FileName,
1837 pCurrentObject->FileId.Cell,
1838 pCurrentObject->FileId.Volume,
1839 pCurrentObject->FileId.Vnode,
1840 pCurrentObject->FileId.Unique);
1842 ntStatus = AFSInsertNextElement( pNameArray,
1845 if( !NT_SUCCESS( ntStatus))
1848 try_return( ntStatus);
1854 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1855 AFS_TRACE_LEVEL_VERBOSE,
1856 "AFSLocateNameEntry (FO: %08lX) Completed processing %wZ Status %08lX\n",
1861 if( ( !NT_SUCCESS( ntStatus) &&
1862 ntStatus != STATUS_OBJECT_NAME_NOT_FOUND) ||
1863 ntStatus == STATUS_REPARSE)
1866 if( pDirEntry != NULL)
1869 lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
1871 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1872 AFS_TRACE_LEVEL_VERBOSE,
1873 "AFSLocateNameEntry Decrement6 count on %wZ DE %p Ccb %p Cnt %d\n",
1874 &pDirEntry->NameInformation.FileName,
1879 else if( pParentDirEntry != NULL)
1882 lCount = InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
1884 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1885 AFS_TRACE_LEVEL_VERBOSE,
1886 "AFSLocateNameEntry Decrement7 count on %wZ DE %p Ccb %p Cnt %d\n",
1887 &pParentDirEntry->NameInformation.FileName,
1893 if( bReleaseCurrentVolume)
1896 ASSERT( pCurrentVolume->VolumeReferenceCount > 1);
1898 lCount = InterlockedDecrement( &pCurrentVolume->VolumeReferenceCount);
1900 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
1901 AFS_TRACE_LEVEL_VERBOSE,
1902 "AFSLocateNameEntry Decrement3 count on volume %08lX Cnt %d\n",
1907 if( RootPathName->Buffer != uniFullPathName.Buffer)
1910 AFSExFreePool( uniFullPathName.Buffer);
1916 if( *ParentDirectoryCB != NULL)
1919 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1920 AFS_TRACE_LEVEL_VERBOSE,
1921 "AFSLocateNameEntry Count on Parent %wZ DE %p Ccb %p Cnt %d\n",
1922 &(*ParentDirectoryCB)->NameInformation.FileName,
1925 (*ParentDirectoryCB)->OpenReferenceCount);
1928 if( *DirectoryCB != NULL)
1931 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1932 AFS_TRACE_LEVEL_VERBOSE,
1933 "AFSLocateNameEntry Count on %wZ DE %p Ccb %p Cnt %d\n",
1934 &(*DirectoryCB)->NameInformation.FileName,
1937 (*DirectoryCB)->OpenReferenceCount);
1941 if( bSubstituteName &&
1942 uniSearchName.Buffer != NULL)
1945 AFSExFreePool( uniSearchName.Buffer);
1953 AFSCreateDirEntry( IN GUID *AuthGroup,
1954 IN AFSObjectInfoCB *ParentObjectInfo,
1955 IN AFSDirectoryCB *ParentDirCB,
1956 IN PUNICODE_STRING FileName,
1957 IN PUNICODE_STRING ComponentName,
1958 IN ULONG Attributes,
1959 IN OUT AFSDirectoryCB **DirEntry)
1962 NTSTATUS ntStatus = STATUS_SUCCESS;
1963 AFSDirectoryCB *pDirNode = NULL, *pExistingDirNode = NULL;
1964 UNICODE_STRING uniShortName;
1965 LARGE_INTEGER liFileSize = {0,0};
1971 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1972 AFS_TRACE_LEVEL_VERBOSE_2,
1973 "AFSCreateDirEntry Creating dir entry in parent %wZ FID %08lX-%08lX-%08lX-%08lX Component %wZ Attribs %08lX\n",
1974 &ParentDirCB->NameInformation.FileName,
1975 ParentObjectInfo->FileId.Cell,
1976 ParentObjectInfo->FileId.Volume,
1977 ParentObjectInfo->FileId.Vnode,
1978 ParentObjectInfo->FileId.Unique,
1983 // OK, before inserting the node into the parent tree, issue
1984 // the request to the service for node creation
1985 // We will need to drop the lock on the parent node since the create
1986 // could cause a callback into the file system to invalidate it's cache
1989 ntStatus = AFSNotifyFileCreate( AuthGroup,
1997 // If the returned status is STATUS_REPARSE then the entry exists
1998 // and we raced, get out.
2000 if( ntStatus == STATUS_REPARSE)
2003 *DirEntry = pDirNode;
2005 try_return( ntStatus = STATUS_SUCCESS);
2008 if( !NT_SUCCESS( ntStatus))
2011 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2012 AFS_TRACE_LEVEL_ERROR,
2013 "AFSCreateDirEntry Failed to create dir entry in parent %wZ FID %08lX-%08lX-%08lX-%08lX Component %wZ Attribs %08lX Status %08lX\n",
2014 &ParentDirCB->NameInformation.FileName,
2015 ParentObjectInfo->FileId.Cell,
2016 ParentObjectInfo->FileId.Volume,
2017 ParentObjectInfo->FileId.Vnode,
2018 ParentObjectInfo->FileId.Unique,
2023 try_return( ntStatus);
2026 AFSAcquireExcl( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2030 // Before attempting to insert the new entry, check if we need to validate the parent
2033 if( BooleanFlagOn( ParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY))
2036 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2037 AFS_TRACE_LEVEL_VERBOSE,
2038 "AFSCreateDirEntry Verifying parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2039 &ParentDirCB->NameInformation.FileName,
2040 ParentObjectInfo->FileId.Cell,
2041 ParentObjectInfo->FileId.Volume,
2042 ParentObjectInfo->FileId.Vnode,
2043 ParentObjectInfo->FileId.Unique);
2045 ntStatus = AFSVerifyEntry( AuthGroup,
2048 if( !NT_SUCCESS( ntStatus))
2051 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2052 AFS_TRACE_LEVEL_ERROR,
2053 "AFSCreateDirEntry Failed to verify parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2054 &ParentDirCB->NameInformation.FileName,
2055 ParentObjectInfo->FileId.Cell,
2056 ParentObjectInfo->FileId.Volume,
2057 ParentObjectInfo->FileId.Vnode,
2058 ParentObjectInfo->FileId.Unique,
2061 AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2063 try_return( ntStatus);
2068 // Check for the entry in the event we raced with some other thread
2071 AFSLocateCaseSensitiveDirEntry( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
2072 (ULONG)pDirNode->CaseSensitiveTreeEntry.HashIndex,
2075 if( pExistingDirNode != NULL)
2077 if (AFSIsEqualFID( &pDirNode->ObjectInformation->FileId,
2078 &pExistingDirNode->ObjectInformation->FileId))
2081 AFSDeleteDirEntry( ParentObjectInfo,
2084 lCount = InterlockedIncrement( &pExistingDirNode->OpenReferenceCount);
2086 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2087 AFS_TRACE_LEVEL_VERBOSE,
2088 "AFSCreateDirEntry Increment count on %wZ DE %p Cnt %d\n",
2089 &pExistingDirNode->NameInformation.FileName,
2093 *DirEntry = pExistingDirNode;
2095 AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2097 try_return( ntStatus = STATUS_SUCCESS);
2103 // Need to tear down this entry and rebuild it below
2106 if( pExistingDirNode->OpenReferenceCount == 0)
2109 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2110 AFS_TRACE_LEVEL_VERBOSE,
2111 "AFSCreateDirEntry Different FIDs - Deleting DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
2113 &pExistingDirNode->NameInformation.FileName,
2114 pExistingDirNode->ObjectInformation->FileId.Cell,
2115 pExistingDirNode->ObjectInformation->FileId.Volume,
2116 pExistingDirNode->ObjectInformation->FileId.Vnode,
2117 pExistingDirNode->ObjectInformation->FileId.Unique,
2118 pDirNode->ObjectInformation->FileId.Cell,
2119 pDirNode->ObjectInformation->FileId.Volume,
2120 pDirNode->ObjectInformation->FileId.Vnode,
2121 pDirNode->ObjectInformation->FileId.Unique);
2123 AFSDeleteDirEntry( ParentObjectInfo,
2129 SetFlag( pExistingDirNode->Flags, AFS_DIR_ENTRY_DELETED);
2131 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2132 AFS_TRACE_LEVEL_VERBOSE,
2133 "AFSCreateDirEntry Different FIDs - Removing DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
2135 &pExistingDirNode->NameInformation.FileName,
2136 pExistingDirNode->ObjectInformation->FileId.Cell,
2137 pExistingDirNode->ObjectInformation->FileId.Volume,
2138 pExistingDirNode->ObjectInformation->FileId.Vnode,
2139 pExistingDirNode->ObjectInformation->FileId.Unique,
2140 pDirNode->ObjectInformation->FileId.Cell,
2141 pDirNode->ObjectInformation->FileId.Volume,
2142 pDirNode->ObjectInformation->FileId.Vnode,
2143 pDirNode->ObjectInformation->FileId.Unique);
2145 AFSRemoveNameEntry( ParentObjectInfo,
2152 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2153 AFS_TRACE_LEVEL_VERBOSE_2,
2154 "AFSCreateDirEntry Inserting dir entry in parent %wZ FID %08lX-%08lX-%08lX-%08lX Component %wZ\n",
2155 &ParentDirCB->NameInformation.FileName,
2156 ParentObjectInfo->FileId.Cell,
2157 ParentObjectInfo->FileId.Volume,
2158 ParentObjectInfo->FileId.Vnode,
2159 ParentObjectInfo->FileId.Unique,
2163 // Insert the directory node
2166 AFSInsertDirectoryNode( ParentObjectInfo,
2170 lCount = InterlockedIncrement( &pDirNode->OpenReferenceCount);
2172 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2173 AFS_TRACE_LEVEL_VERBOSE,
2174 "AFSCreateDirEntry Increment2 count on %wZ DE %p Cnt %d\n",
2175 &pDirNode->NameInformation.FileName,
2180 // Pass back the dir entry
2183 *DirEntry = pDirNode;
2185 AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2196 AFSInsertDirectoryNode( IN AFSObjectInfoCB *ParentObjectInfo,
2197 IN AFSDirectoryCB *DirEntry,
2198 IN BOOLEAN InsertInEnumList)
2206 ASSERT( ExIsResourceAcquiredExclusiveLite( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock));
2209 // Insert the node into the directory node tree
2212 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2213 AFS_TRACE_LEVEL_VERBOSE,
2214 "AFSInsertDirectoryNode Insert DE %p for %wZ Clearing NOT_IN flag\n",
2216 &DirEntry->NameInformation.FileName);
2218 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
2220 if( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead == NULL)
2223 ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = DirEntry;
2225 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2226 AFS_TRACE_LEVEL_VERBOSE,
2227 "AFSInsertDirectoryNode Insert DE %p to head of case sensitive tree for %wZ\n",
2229 &DirEntry->NameInformation.FileName);
2234 AFSInsertCaseSensitiveDirEntry( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
2237 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2238 AFS_TRACE_LEVEL_VERBOSE,
2239 "AFSInsertDirectoryNode Insert DE %p to case sensitive tree for %wZ\n",
2241 &DirEntry->NameInformation.FileName);
2244 if( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead == NULL)
2247 ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = DirEntry;
2249 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
2251 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2252 AFS_TRACE_LEVEL_VERBOSE,
2253 "AFSInsertDirectoryNode Insert DE %p to head of case insensitive tree for %wZ\n",
2255 &DirEntry->NameInformation.FileName);
2260 AFSInsertCaseInsensitiveDirEntry( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
2263 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2264 AFS_TRACE_LEVEL_VERBOSE,
2265 "AFSInsertDirectoryNode Insert DE %p to case insensitive tree for %wZ\n",
2267 &DirEntry->NameInformation.FileName);
2271 // Into the shortname tree
2274 if( DirEntry->Type.Data.ShortNameTreeEntry.HashIndex != 0)
2277 if( ParentObjectInfo->Specific.Directory.ShortNameTree == NULL)
2280 ParentObjectInfo->Specific.Directory.ShortNameTree = DirEntry;
2282 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2283 AFS_TRACE_LEVEL_VERBOSE,
2284 "AFSInsertDirectoryNode Insert DE %p to head of shortname tree for %wZ\n",
2286 &DirEntry->NameInformation.FileName);
2288 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
2293 if( !NT_SUCCESS( AFSInsertShortNameDirEntry( ParentObjectInfo->Specific.Directory.ShortNameTree,
2296 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2297 AFS_TRACE_LEVEL_VERBOSE,
2298 "AFSInsertDirectoryNode Failed to insert DE %p to shortname tree for %wZ\n",
2300 &DirEntry->NameInformation.FileName);
2304 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
2306 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2307 AFS_TRACE_LEVEL_VERBOSE,
2308 "AFSInsertDirectoryNode Insert DE %p to shortname tree for %wZ\n",
2310 &DirEntry->NameInformation.FileName);
2315 if( InsertInEnumList)
2319 // And insert the node into the directory list
2322 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2323 AFS_TRACE_LEVEL_VERBOSE,
2324 "AFSInsertDirectoryNode Inserting entry %08lX %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2326 &DirEntry->NameInformation.FileName,
2327 DirEntry->ObjectInformation->FileId.Cell,
2328 DirEntry->ObjectInformation->FileId.Volume,
2329 DirEntry->ObjectInformation->FileId.Vnode,
2330 DirEntry->ObjectInformation->FileId.Unique);
2332 if( ParentObjectInfo->Specific.Directory.DirectoryNodeListHead == NULL)
2335 ParentObjectInfo->Specific.Directory.DirectoryNodeListHead = DirEntry;
2340 ParentObjectInfo->Specific.Directory.DirectoryNodeListTail->ListEntry.fLink = (void *)DirEntry;
2342 DirEntry->ListEntry.bLink = (void *)ParentObjectInfo->Specific.Directory.DirectoryNodeListTail;
2345 ParentObjectInfo->Specific.Directory.DirectoryNodeListTail = DirEntry;
2347 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST);
2349 lCount = InterlockedIncrement( &ParentObjectInfo->Specific.Directory.DirectoryNodeCount);
2351 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
2352 AFS_TRACE_LEVEL_VERBOSE,
2353 "AFSInsertDirectoryNode Adding entry %wZ Inc Count %d to parent FID %08lX-%08lX-%08lX-%08lX\n",
2354 &DirEntry->NameInformation.FileName,
2356 ParentObjectInfo->FileId.Cell,
2357 ParentObjectInfo->FileId.Volume,
2358 ParentObjectInfo->FileId.Vnode,
2359 ParentObjectInfo->FileId.Unique);
2367 AFSDeleteDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
2368 IN AFSDirectoryCB *DirEntry)
2371 NTSTATUS ntStatus = STATUS_SUCCESS;
2377 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2378 AFS_TRACE_LEVEL_VERBOSE,
2379 "AFSDeleteDirEntry Deleting dir entry in parent %08lX Entry %08lX %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2382 &DirEntry->NameInformation.FileName,
2383 DirEntry->ObjectInformation->FileId.Cell,
2384 DirEntry->ObjectInformation->FileId.Volume,
2385 DirEntry->ObjectInformation->FileId.Vnode,
2386 DirEntry->ObjectInformation->FileId.Unique);
2388 AFSRemoveDirNodeFromParent( ParentObjectInfo,
2393 // Free up the name buffer if it was reallocated
2396 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_RELEASE_NAME_BUFFER))
2399 AFSExFreePool( DirEntry->NameInformation.FileName.Buffer);
2402 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER))
2405 AFSExFreePool( DirEntry->NameInformation.TargetName.Buffer);
2409 // Dereference the object for this dir entry
2412 ASSERT( DirEntry->ObjectInformation->ObjectReferenceCount > 0);
2414 lCount = InterlockedDecrement( &DirEntry->ObjectInformation->ObjectReferenceCount);
2418 SetFlag( DirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED);
2421 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2422 AFS_TRACE_LEVEL_VERBOSE,
2423 "AFSDeleteDirEntry Decrement count on object %08lX Cnt %d\n",
2424 DirEntry->ObjectInformation,
2425 DirEntry->ObjectInformation->ObjectReferenceCount);
2427 ExDeleteResourceLite( &DirEntry->NonPaged->Lock);
2429 AFSExFreePool( DirEntry->NonPaged);
2432 // Free up the dir entry
2435 AFSExFreePool( DirEntry);
2442 AFSRemoveDirNodeFromParent( IN AFSObjectInfoCB *ParentObjectInfo,
2443 IN AFSDirectoryCB *DirEntry,
2444 IN BOOLEAN RemoveFromEnumList)
2447 NTSTATUS ntStatus = STATUS_SUCCESS;
2454 ASSERT( ExIsResourceAcquiredExclusiveLite( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock));
2456 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2457 AFS_TRACE_LEVEL_VERBOSE,
2458 "AFSRemoveDirNodeFromParent Removing DirEntry %08lX %wZ FID %08lX-%08lX-%08lX-%08lX from Parent %08lX\n",
2460 &DirEntry->NameInformation.FileName,
2461 DirEntry->ObjectInformation->FileId.Cell,
2462 DirEntry->ObjectInformation->FileId.Volume,
2463 DirEntry->ObjectInformation->FileId.Vnode,
2464 DirEntry->ObjectInformation->FileId.Unique,
2467 if( !BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
2470 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2471 AFS_TRACE_LEVEL_VERBOSE,
2472 "AFSRemoveDirNodeFromParent Removing DirEntry %08lX name %wZ\n",
2474 &DirEntry->NameInformation.FileName);
2476 AFSRemoveNameEntry( ParentObjectInfo,
2482 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2483 AFS_TRACE_LEVEL_VERBOSE,
2484 "AFSRemoveDirNodeFromParent DE %p for %wZ NOT removing entry due to flag set\n",
2486 &DirEntry->NameInformation.FileName);
2490 if( RemoveFromEnumList &&
2491 BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST))
2495 // And remove the entry from the enumeration list
2498 if( DirEntry->ListEntry.fLink == NULL)
2501 ParentObjectInfo->Specific.Directory.DirectoryNodeListTail = (AFSDirectoryCB *)DirEntry->ListEntry.bLink;
2506 ((AFSDirectoryCB *)DirEntry->ListEntry.fLink)->ListEntry.bLink = DirEntry->ListEntry.bLink;
2509 if( DirEntry->ListEntry.bLink == NULL)
2512 ParentObjectInfo->Specific.Directory.DirectoryNodeListHead = (AFSDirectoryCB *)DirEntry->ListEntry.fLink;
2517 ((AFSDirectoryCB *)DirEntry->ListEntry.bLink)->ListEntry.fLink = DirEntry->ListEntry.fLink;
2520 ASSERT( ParentObjectInfo->Specific.Directory.DirectoryNodeCount > 0);
2522 lCount = InterlockedDecrement( &ParentObjectInfo->Specific.Directory.DirectoryNodeCount);
2524 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST);
2526 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
2527 AFS_TRACE_LEVEL_VERBOSE,
2528 "AFSRemoveDirNodeFromParent Removing entry %wZ Dec Count %d to parent FID %08lX-%08lX-%08lX-%08lX\n",
2529 &DirEntry->NameInformation.FileName,
2531 ParentObjectInfo->FileId.Cell,
2532 ParentObjectInfo->FileId.Volume,
2533 ParentObjectInfo->FileId.Vnode,
2534 ParentObjectInfo->FileId.Unique);
2536 DirEntry->ListEntry.fLink = NULL;
2537 DirEntry->ListEntry.bLink = NULL;
2545 AFSFixupTargetName( IN OUT PUNICODE_STRING FileName,
2546 IN OUT PUNICODE_STRING TargetFileName)
2549 NTSTATUS ntStatus = STATUS_SUCCESS;
2550 UNICODE_STRING uniFileName;
2556 // We will process backwards from the end of the name looking
2557 // for the first \ we encounter
2560 uniFileName.Length = FileName->Length;
2561 uniFileName.MaximumLength = FileName->MaximumLength;
2563 uniFileName.Buffer = FileName->Buffer;
2568 if( uniFileName.Buffer[ (uniFileName.Length/sizeof( WCHAR)) - 1] == L'\\')
2572 // Subtract one more character off of the filename if it is not the root
2575 if( uniFileName.Length > sizeof( WCHAR))
2578 uniFileName.Length -= sizeof( WCHAR);
2582 // Now build up the target name
2585 TargetFileName->Length = FileName->Length - uniFileName.Length;
2588 // If we are not on the root then fixup the name
2591 if( uniFileName.Length > sizeof( WCHAR))
2594 TargetFileName->Length -= sizeof( WCHAR);
2596 TargetFileName->Buffer = &uniFileName.Buffer[ (uniFileName.Length/sizeof( WCHAR)) + 1];
2601 TargetFileName->Buffer = &uniFileName.Buffer[ uniFileName.Length/sizeof( WCHAR)];
2605 // Fixup the passed back filename length
2608 FileName->Length = uniFileName.Length;
2610 TargetFileName->MaximumLength = TargetFileName->Length;
2615 uniFileName.Length -= sizeof( WCHAR);
2623 AFSParseName( IN PIRP Irp,
2625 OUT PUNICODE_STRING FileName,
2626 OUT PUNICODE_STRING ParsedFileName,
2627 OUT PUNICODE_STRING RootFileName,
2628 OUT ULONG *ParseFlags,
2629 OUT AFSVolumeCB **VolumeCB,
2630 OUT AFSDirectoryCB **ParentDirectoryCB,
2631 OUT AFSNameArrayHdr **NameArray)
2634 NTSTATUS ntStatus = STATUS_SUCCESS;
2635 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2636 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2637 UNICODE_STRING uniFullName, uniComponentName, uniRemainingPath;
2639 AFSDirectoryCB *pDirEntry = NULL, *pShareDirEntry = NULL, *pTargetDirEntry = NULL;
2640 USHORT usIndex = 0, usDriveIndex = 0;
2641 AFSCcb *pRelatedCcb = NULL;
2642 AFSNameArrayHdr *pNameArray = NULL, *pRelatedNameArray = NULL;
2643 USHORT usComponentIndex = 0;
2644 USHORT usComponentLength = 0;
2645 AFSVolumeCB *pVolumeCB = NULL;
2646 AFSFcb *pRelatedFcb = NULL;
2647 BOOLEAN bReleaseTreeLock = FALSE;
2648 BOOLEAN bIsAllShare = FALSE;
2655 // Indicate we are opening a root ...
2658 *ParseFlags = AFS_PARSE_FLAG_ROOT_ACCESS;
2660 if( pIrpSp->FileObject->RelatedFileObject != NULL)
2663 pRelatedFcb = (AFSFcb *)pIrpSp->FileObject->RelatedFileObject->FsContext;
2665 pRelatedCcb = (AFSCcb *)pIrpSp->FileObject->RelatedFileObject->FsContext2;
2667 pRelatedNameArray = pRelatedCcb->NameArray;
2669 uniFullName = pIrpSp->FileObject->FileName;
2671 ASSERT( pRelatedFcb != NULL);
2674 // No wild cards in the name
2677 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2678 AFS_TRACE_LEVEL_VERBOSE_2,
2679 "AFSParseName (%08lX) Relative open for %wZ FID %08lX-%08lX-%08lX-%08lX component %wZ\n",
2681 &pRelatedCcb->DirectoryCB->NameInformation.FileName,
2682 pRelatedCcb->DirectoryCB->ObjectInformation->FileId.Cell,
2683 pRelatedCcb->DirectoryCB->ObjectInformation->FileId.Volume,
2684 pRelatedCcb->DirectoryCB->ObjectInformation->FileId.Vnode,
2685 pRelatedCcb->DirectoryCB->ObjectInformation->FileId.Unique,
2688 if( FsRtlDoesNameContainWildCards( &uniFullName))
2691 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2692 AFS_TRACE_LEVEL_ERROR,
2693 "AFSParseName (%08lX) Component %wZ contains wild cards\n",
2697 try_return( ntStatus = STATUS_OBJECT_NAME_INVALID);
2700 pVolumeCB = pRelatedFcb->ObjectInformation->VolumeCB;
2702 pDirEntry = pRelatedCcb->DirectoryCB;
2704 *FileName = pIrpSp->FileObject->FileName;
2707 // Grab the root node while checking state
2710 AFSAcquireShared( pVolumeCB->VolumeLock,
2713 if( BooleanFlagOn( pVolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
2714 BooleanFlagOn( pVolumeCB->Flags, AFS_VOLUME_FLAGS_OFFLINE))
2718 // The volume has been taken off line so fail the access
2721 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2722 AFS_TRACE_LEVEL_ERROR,
2723 "AFSParseName (%08lX) Volume %08lX:%08lX OFFLINE/INVALID\n",
2725 pVolumeCB->ObjectInformation.FileId.Cell,
2726 pVolumeCB->ObjectInformation.FileId.Volume);
2728 AFSReleaseResource( pVolumeCB->VolumeLock);
2730 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
2733 if( BooleanFlagOn( pVolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_VERIFY))
2736 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2737 AFS_TRACE_LEVEL_VERBOSE,
2738 "AFSParseName (%08lX) Verifying root of volume %08lX:%08lX\n",
2740 pVolumeCB->ObjectInformation.FileId.Cell,
2741 pVolumeCB->ObjectInformation.FileId.Volume);
2743 ntStatus = AFSVerifyVolume( (ULONGLONG)PsGetCurrentProcessId(),
2746 if( !NT_SUCCESS( ntStatus))
2749 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2750 AFS_TRACE_LEVEL_ERROR,
2751 "AFSParseName (%08lX) Failed verification of root Status %08lX\n",
2755 AFSReleaseResource( pVolumeCB->VolumeLock);
2757 try_return( ntStatus);
2761 AFSReleaseResource( pVolumeCB->VolumeLock);
2763 if( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY))
2766 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2767 AFS_TRACE_LEVEL_VERBOSE,
2768 "AFSParseName (%08lX) Verifying parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2770 &pDirEntry->NameInformation.FileName,
2771 pDirEntry->ObjectInformation->FileId.Cell,
2772 pDirEntry->ObjectInformation->FileId.Volume,
2773 pDirEntry->ObjectInformation->FileId.Vnode,
2774 pDirEntry->ObjectInformation->FileId.Unique);
2777 // Directory TreeLock should be exclusively held
2780 AFSAcquireExcl( pDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
2783 ntStatus = AFSVerifyEntry( AuthGroup,
2786 AFSReleaseResource( pDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
2788 if( !NT_SUCCESS( ntStatus))
2791 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2792 AFS_TRACE_LEVEL_VERBOSE,
2793 "AFSParseName (%08lX) Failed verification of parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2795 &pDirEntry->NameInformation.FileName,
2796 pDirEntry->ObjectInformation->FileId.Cell,
2797 pDirEntry->ObjectInformation->FileId.Volume,
2798 pDirEntry->ObjectInformation->FileId.Vnode,
2799 pDirEntry->ObjectInformation->FileId.Unique,
2802 try_return( ntStatus);
2807 // Create our full path name buffer
2810 uniFullName.MaximumLength = pRelatedCcb->FullFileName.Length +
2812 pIrpSp->FileObject->FileName.Length +
2815 uniFullName.Length = 0;
2817 uniFullName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2818 uniFullName.MaximumLength,
2819 AFS_NAME_BUFFER_THREE_TAG);
2821 if( uniFullName.Buffer == NULL)
2824 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2825 AFS_TRACE_LEVEL_ERROR,
2826 "AFSParseName (%08lX) Failed to allocate full name buffer\n",
2829 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2832 RtlZeroMemory( uniFullName.Buffer,
2833 uniFullName.MaximumLength);
2835 RtlCopyMemory( uniFullName.Buffer,
2836 pRelatedCcb->FullFileName.Buffer,
2837 pRelatedCcb->FullFileName.Length);
2839 uniFullName.Length = pRelatedCcb->FullFileName.Length;
2841 usComponentIndex = (USHORT)(uniFullName.Length/sizeof( WCHAR));
2843 usComponentLength = pIrpSp->FileObject->FileName.Length;
2845 if( uniFullName.Buffer[ (uniFullName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
2846 pIrpSp->FileObject->FileName.Length > 0 &&
2847 pIrpSp->FileObject->FileName.Buffer[ 0] != L'\\' &&
2848 pIrpSp->FileObject->FileName.Buffer[ 0] != L':')
2851 uniFullName.Buffer[ (uniFullName.Length/sizeof( WCHAR))] = L'\\';
2853 uniFullName.Length += sizeof( WCHAR);
2855 usComponentLength += sizeof( WCHAR);
2858 if( pIrpSp->FileObject->FileName.Length > 0)
2861 RtlCopyMemory( &uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)],
2862 pIrpSp->FileObject->FileName.Buffer,
2863 pIr
\epSp->FileObject->FileName.Length);
2865 uniFullName.Length += pIrpSp->FileObject->FileName.Length;
2868 *RootFileName = uniFullName;
2871 // We populate up to the current parent
2874 if( pRelatedNameArray == NULL)
2878 // Init and populate our name array
2881 pNameArray = AFSInitNameArray( NULL,
2884 if( pNameArray == NULL)
2887 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2888 AFS_TRACE_LEVEL_VERBOSE,
2889 "AFSParseName (%08lX) Failed to initialize name array\n",
2892 AFSExFreePool( uniFullName.Buffer);
2894 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2897 ntStatus = AFSPopulateNameArray( pNameArray,
2899 pRelatedCcb->DirectoryCB);
2905 // Init and populate our name array
2908 pNameArray = AFSInitNameArray( NULL,
2909 pRelatedNameArray->MaxElementCount);
2911 if( pNameArray == NULL)
2914 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2915 AFS_TRACE_LEVEL_VERBOSE,
2916 "AFSParseName (%08lX) Failed to initialize name array\n",
2919 AFSExFreePool( uniFullName.Buffer);
2921 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2924 ntStatus = AFSPopulateNameArrayFromRelatedArray( pNameArray,
2926 pRelatedCcb->DirectoryCB);
2929 if( !NT_SUCCESS( ntStatus))
2932 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2933 AFS_TRACE_LEVEL_VERBOSE,
2934 "AFSParseName (%08lX) Failed to populate name array\n",
2937 AFSExFreePool( uniFullName.Buffer);
2939 try_return( ntStatus);
2942 ParsedFileName->Length = usComponentLength;
2943 ParsedFileName->MaximumLength = uniFullName.MaximumLength;
2945 ParsedFileName->Buffer = &uniFullName.Buffer[ usComponentIndex];
2948 // Indicate to caller that RootFileName must be freed
2951 SetFlag( *ParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
2953 *NameArray = pNameArray;
2955 *VolumeCB = pVolumeCB;
2958 // Increment our volume reference count
2961 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
2963 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2964 AFS_TRACE_LEVEL_VERBOSE,
2965 "AFSParseName Increment count on volume %08lX Cnt %d\n",
2969 *ParentDirectoryCB = pDirEntry;
2971 lCount = InterlockedIncrement( &pDirEntry->OpenReferenceCount);
2973 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2974 AFS_TRACE_LEVEL_VERBOSE,
2975 "AFSParseName Increment1 count on %wZ DE %p Ccb %p Cnt %d\n",
2976 &pDirEntry->NameInformation.FileName,
2981 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2982 AFS_TRACE_LEVEL_VERBOSE_2,
2983 "AFSParseName (%08lX) Returning full name %wZ\n",
2987 try_return( ntStatus);
2991 // No wild cards in the name
2994 uniFullName = pIrpSp->FileObject->FileName;
2996 if( FsRtlDoesNameContainWildCards( &uniFullName) ||
2997 uniFullName.Length < AFSServerName.Length)
3000 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3001 AFS_TRACE_LEVEL_ERROR,
3002 "AFSParseName (%08lX) Name %wZ contains wild cards or too short\n",
3006 try_return( ntStatus = STATUS_OBJECT_NAME_INVALID);
3010 // The name is a fully qualified name. Parse out the server/share names and
3011 // point to the root qualified name
3012 // First thing is to locate the server name
3015 FsRtlDissectName( uniFullName,
3019 uniFullName = uniRemainingPath;
3022 // This component is the server name we are serving
3025 if( RtlCompareUnicodeString( &uniComponentName,
3031 // Drive letter based name?
3034 uniFullName = pIrpSp->FileObject->FileName;
3036 while( usIndex < uniFullName.Length/sizeof( WCHAR))
3039 if( uniFullName.Buffer[ usIndex] == L':')
3042 uniFullName.Buffer = &uniFullName.Buffer[ usIndex + 2];
3044 uniFullName.Length -= (usIndex + 2) * sizeof( WCHAR);
3046 usDriveIndex = usIndex - 1;
3055 // Do we have the right server name now?
3058 FsRtlDissectName( uniFullName,
3062 uniFullName = uniRemainingPath;
3065 // This component is the server name we are serving
3068 if( RtlCompareUnicodeString( &uniComponentName,
3073 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3074 AFS_TRACE_LEVEL_ERROR,
3075 "AFSParseName (%08lX) Name %wZ does not have server name\n",
3077 &pIrpSp->FileObject->FileName);
3079 try_return( ntStatus = STATUS_BAD_NETWORK_NAME);
3083 // Validate this drive letter is actively mapped
3086 if( usDriveIndex > 0 &&
3087 !AFSIsDriveMapped( pIrpSp->FileObject->FileName.Buffer[ usDriveIndex]))
3090 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3091 AFS_TRACE_LEVEL_ERROR,
3092 "AFSParseName (%08lX) Name %wZ contains invalid drive mapping\n",
3094 &pIrpSp->FileObject->FileName);
3096 try_return( ntStatus = STATUS_BAD_NETWORK_NAME);
3100 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3101 AFS_TRACE_LEVEL_VERBOSE_2,
3102 "AFSParseName (%08lX) Processing full name %wZ\n",
3106 if( uniFullName.Length > 0 &&
3107 uniFullName.Buffer[ (uniFullName.Length/sizeof( WCHAR)) - 1] == L'\\')
3110 uniFullName.Length -= sizeof( WCHAR);
3114 // Be sure we are online and ready to go
3117 AFSAcquireShared( AFSGlobalRoot->VolumeLock,
3120 if( BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
3121 BooleanFlagOn( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE))
3125 // The volume has been taken off line so fail the access
3128 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3129 AFS_TRACE_LEVEL_ERROR,
3130 "AFSParseName (%08lX) Volume %08lX:%08lX OFFLINE/INVALID\n",
3132 AFSGlobalRoot->ObjectInformation.FileId.Cell,
3133 AFSGlobalRoot->ObjectInformation.FileId.Volume);
3135 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3137 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
3140 if( BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_VERIFY))
3143 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3144 AFS_TRACE_LEVEL_VERBOSE,
3145 "AFSParseName (%08lX) Verifying root of volume %08lX:%08lX\n",
3147 AFSGlobalRoot->ObjectInformation.FileId.Cell,
3148 AFSGlobalRoot->ObjectInformation.FileId.Volume);
3150 ntStatus = AFSVerifyVolume( (ULONGLONG)PsGetCurrentProcessId(),
3153 if( !NT_SUCCESS( ntStatus))
3156 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3157 AFS_TRACE_LEVEL_ERROR,
3158 "AFSParseName (%08lX) Failed verification of root Status %08lX\n",
3162 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3164 try_return( ntStatus);
3168 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3170 if( !BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
3173 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3174 AFS_TRACE_LEVEL_VERBOSE,
3175 "AFSParseName (%08lX) Enumerating global root of volume %08lX:%08lX\n",
3177 AFSGlobalRoot->ObjectInformation.FileId.Cell,
3178 AFSGlobalRoot->ObjectInformation.FileId.Volume);
3180 ntStatus = AFSEnumerateGlobalRoot( AuthGroup);
3182 if( !NT_SUCCESS( ntStatus))
3185 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3186 AFS_TRACE_LEVEL_ERROR,
3187 "AFSParseName (%08lX) Failed enumeraiton of root Status %08lX\n",
3191 try_return( ntStatus);
3196 // Check for the \\Server access and return it as though it where \\Server\Globalroot
3199 if( uniRemainingPath.Buffer == NULL ||
3200 ( uniRemainingPath.Length == sizeof( WCHAR) &&
3201 uniRemainingPath.Buffer[ 0] == L'\\'))
3204 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3205 AFS_TRACE_LEVEL_VERBOSE_2,
3206 "AFSParseName (%08lX) Returning global root access\n",
3209 lCount = InterlockedIncrement( &AFSGlobalRoot->DirectoryCB->OpenReferenceCount);
3211 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3212 AFS_TRACE_LEVEL_VERBOSE,
3213 "AFSParseName Increment2 count on %wZ DE %p Ccb %p Cnt %d\n",
3214 &AFSGlobalRoot->DirectoryCB->NameInformation.FileName,
3215 AFSGlobalRoot->DirectoryCB,
3221 FileName->Length = 0;
3222 FileName->MaximumLength = 0;
3223 FileName->Buffer = NULL;
3225 try_return( ntStatus = STATUS_SUCCESS);
3228 *RootFileName = uniFullName;
3231 // Include the starting \ in the root name
3234 if( RootFileName->Buffer[ 0] != L'\\')
3236 RootFileName->Buffer--;
3237 RootFileName->Length += sizeof( WCHAR);
3238 RootFileName->MaximumLength += sizeof( WCHAR);
3242 // Get the 'share' name
3245 FsRtlDissectName( uniFullName,
3250 // If this is the ALL access then perform some additional processing
3253 if( RtlCompareUnicodeString( &uniComponentName,
3261 // If there is nothing else then get out
3264 if( uniRemainingPath.Buffer == NULL ||
3265 uniRemainingPath.Length == 0 ||
3266 ( uniRemainingPath.Length == sizeof( WCHAR) &&
3267 uniRemainingPath.Buffer[ 0] == L'\\'))
3270 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3271 AFS_TRACE_LEVEL_VERBOSE_2,
3272 "AFSParseName (%08lX) Returning global root access\n",
3275 lCount = InterlockedIncrement( &AFSGlobalRoot->DirectoryCB->OpenReferenceCount);
3277 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3278 AFS_TRACE_LEVEL_VERBOSE,
3279 "AFSParseName Increment3 count on %wZ DE %p Ccb %p Cnt %d\n",
3280 &AFSGlobalRoot->DirectoryCB->NameInformation.FileName,
3281 AFSGlobalRoot->DirectoryCB,