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 not be released. On successful exit, *OutVolumeCB
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 OUT UNICODE_STRING *RootPathName,
56 IN UNICODE_STRING *ParsedPathName,
57 IN AFSNameArrayHdr *NameArray,
59 IN AFSVolumeCB *VolumeCB,
60 IN AFSDirectoryCB *ParentDirectoryCB,
61 OUT AFSVolumeCB **OutVolumeCB,
62 OUT LONG *OutVolumeReferenceReason,
63 OUT AFSDirectoryCB **OutParentDirectoryCB,
64 OUT AFSDirectoryCB **OutDirectoryCB,
65 OUT PUNICODE_STRING ComponentName)
68 NTSTATUS ntStatus = STATUS_SUCCESS;
69 UNICODE_STRING uniPathName, uniComponentName, uniRemainingPath, uniSearchName, uniFullPathName;
71 AFSDirectoryCB *pDirEntry = NULL, *pParentDirEntry = NULL;
72 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
73 UNICODE_STRING uniSysName;
74 ULONG ulSubstituteIndex = 0;
75 BOOLEAN bSubstituteName = FALSE;
76 AFSNameArrayHdr *pNameArray = NameArray;
77 BOOLEAN bAllocatedSymLinkBuffer = FALSE;
78 UNICODE_STRING uniRelativeName, uniNoOpName;
79 AFSObjectInfoCB *pCurrentObject = NULL;
80 AFSObjectInfoCB *pParentObjectInfo = NULL;
81 AFSVolumeCB *pCurrentVolume = NULL;
82 AFSVolumeCB *pTargetVolume = NULL;
83 BOOLEAN bReleaseCurrentVolume = FALSE;
84 LONG VolumeReferenceReason;
85 BOOLEAN bSubstitutedName = FALSE;
91 ASSERT( *OutVolumeCB != VolumeCB);
93 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
94 AFS_TRACE_LEVEL_VERBOSE_2,
95 "AFSLocateNameEntry (FO: %p) Processing full name %wZ\n",
99 RtlInitUnicodeString( &uniSysName,
102 RtlInitUnicodeString( &uniRelativeName,
105 RtlInitUnicodeString( &uniNoOpName,
109 // Cleanup some parameters
112 if( ComponentName != NULL)
115 ComponentName->Length = 0;
116 ComponentName->MaximumLength = 0;
117 ComponentName->Buffer = NULL;
121 // We will parse through the filename, locating the directory nodes until we encounter a cache miss
122 // Starting at the root node
125 pParentDirEntry = NULL;
127 pDirEntry = ParentDirectoryCB;
129 pCurrentVolume = VolumeCB;
131 VolumeReferenceReason = AFS_VOLUME_REFERENCE_LOCATE_NAME;
133 lCount = AFSVolumeIncrement( pCurrentVolume,
134 VolumeReferenceReason);
136 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
137 AFS_TRACE_LEVEL_VERBOSE,
138 "AFSLocateNameEntry Increment count on volume %p Reason %u Cnt %d\n",
140 VolumeReferenceReason,
143 bReleaseCurrentVolume = TRUE;
145 uniPathName = *ParsedPathName;
147 uniFullPathName = *RootPathName;
149 uniComponentName.Length = uniComponentName.MaximumLength = 0;
150 uniComponentName.Buffer = NULL;
152 uniRemainingPath.Length = uniRemainingPath.MaximumLength = 0;
153 uniRemainingPath.Buffer = NULL;
155 uniSearchName.Length = uniSearchName.MaximumLength = 0;
156 uniSearchName.Buffer = NULL;
161 ASSERT( pCurrentVolume->VolumeReferenceCount > 0);
163 ASSERT( pDirEntry->DirOpenReferenceCount > 0);
166 // Check our total link count for this name array
169 if( pNameArray->LinkCount >= (LONG)pDevExt->Specific.RDR.MaxLinkCount)
172 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
175 pCurrentObject = pDirEntry->ObjectInformation;
177 KeQueryTickCount( &pCurrentObject->LastAccessCount);
180 // Check that the directory entry is not deleted or pending delete
183 if( BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED))
186 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
187 AFS_TRACE_LEVEL_ERROR,
188 "AFSLocateNameEntry (FO: %p) Deleted parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
190 &pDirEntry->NameInformation.FileName,
191 pCurrentObject->FileId.Cell,
192 pCurrentObject->FileId.Volume,
193 pCurrentObject->FileId.Vnode,
194 pCurrentObject->FileId.Unique,
195 STATUS_FILE_DELETED);
197 try_return( ntStatus = STATUS_FILE_DELETED);
200 if( BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_PENDING_DELETE))
203 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
204 AFS_TRACE_LEVEL_ERROR,
205 "AFSLocateNameEntry (FO: %p) Delete pending on %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
207 &pDirEntry->NameInformation.FileName,
208 pCurrentObject->FileId.Cell,
209 pCurrentObject->FileId.Volume,
210 pCurrentObject->FileId.Vnode,
211 pCurrentObject->FileId.Unique,
212 STATUS_DELETE_PENDING);
214 try_return( ntStatus = STATUS_DELETE_PENDING);
218 // Check if the directory requires verification
221 if( BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_FLAGS_VERIFY) &&
222 ( pCurrentObject->FileType != AFS_FILE_TYPE_DIRECTORY ||
223 !AFSIsEnumerationInProcess( pCurrentObject)))
226 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
227 AFS_TRACE_LEVEL_VERBOSE,
228 "AFSLocateNameEntry (FO: %p) Verifying parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
230 &pDirEntry->NameInformation.FileName,
231 pCurrentObject->FileId.Cell,
232 pCurrentObject->FileId.Volume,
233 pCurrentObject->FileId.Vnode,
234 pCurrentObject->FileId.Unique);
237 // Directory TreeLock should be exclusively held
240 AFSAcquireExcl( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
243 ntStatus = AFSVerifyEntry( AuthGroup,
246 AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
248 if( !NT_SUCCESS( ntStatus))
251 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
252 AFS_TRACE_LEVEL_ERROR,
253 "AFSLocateNameEntry (FO: %p) Failed to verify parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
255 &pDirEntry->NameInformation.FileName,
256 pCurrentObject->FileId.Cell,
257 pCurrentObject->FileId.Volume,
258 pCurrentObject->FileId.Vnode,
259 pCurrentObject->FileId.Unique,
262 try_return( ntStatus);
267 // Ensure the parent node has been evaluated, if not then go do it now
270 if( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) ||
271 pCurrentObject->FileType == AFS_FILE_TYPE_UNKNOWN)
274 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
275 AFS_TRACE_LEVEL_VERBOSE,
276 "AFSLocateNameEntry (FO: %p) Evaluating parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
278 &pDirEntry->NameInformation.FileName,
279 pCurrentObject->FileId.Cell,
280 pCurrentObject->FileId.Volume,
281 pCurrentObject->FileId.Vnode,
282 pCurrentObject->FileId.Unique);
284 ntStatus = AFSEvaluateNode( AuthGroup,
287 if( !NT_SUCCESS( ntStatus))
290 if ( ntStatus == STATUS_NOT_A_DIRECTORY)
293 if ( !BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
296 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
297 AFS_TRACE_LEVEL_ERROR,
298 "AFSLocateNameEntry (FO: %p) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT NULL Status %08lX\n",
300 &pDirEntry->NameInformation.FileName,
301 pCurrentObject->FileId.Cell,
302 pCurrentObject->FileId.Volume,
303 pCurrentObject->FileId.Vnode,
304 pCurrentObject->FileId.Unique,
310 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
311 AFS_TRACE_LEVEL_ERROR,
312 "AFSLocateNameEntry (FO: %p) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT %08lX-%08lX-%08lX-%08lX Status %08lX\n",
314 &pDirEntry->NameInformation.FileName,
315 pCurrentObject->FileId.Cell,
316 pCurrentObject->FileId.Volume,
317 pCurrentObject->FileId.Vnode,
318 pCurrentObject->FileId.Unique,
319 pCurrentObject->ParentFileId.Cell,
320 pCurrentObject->ParentFileId.Volume,
321 pCurrentObject->ParentFileId.Vnode,
322 pCurrentObject->ParentFileId.Unique,
328 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
329 AFS_TRACE_LEVEL_ERROR,
330 "AFSLocateNameEntry (FO: %p) Failed to evaluate parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
332 &pDirEntry->NameInformation.FileName,
333 pCurrentObject->FileId.Cell,
334 pCurrentObject->FileId.Volume,
335 pCurrentObject->FileId.Vnode,
336 pCurrentObject->FileId.Unique,
340 try_return( ntStatus);
343 ClearFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
347 // If this is a mount point or symlink then go get the real directory node
350 switch( pCurrentObject->FileType)
353 case AFS_FILE_TYPE_SYMLINK:
356 UNICODE_STRING uniTempName;
357 WCHAR *pTmpBuffer = NULL;
361 // Check if the flag is set to NOT evaluate a symlink
362 // and we are done with the parsing
365 if( BooleanFlagOn( Flags, AFS_LOCATE_FLAGS_NO_SL_TARGET_EVAL) &&
366 uniRemainingPath.Length == 0)
370 // Pass back the directory entries
373 *OutParentDirectoryCB = pParentDirEntry;
375 *OutDirectoryCB = pDirEntry;
377 *OutVolumeCB = pCurrentVolume;
379 *OutVolumeReferenceReason = VolumeReferenceReason;
381 bReleaseCurrentVolume = FALSE;
383 *RootPathName = uniFullPathName;
385 try_return( ntStatus);
388 AFSAcquireExcl( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
391 AFSAcquireExcl( &pDirEntry->NonPaged->Lock,
394 if( pDirEntry->NameInformation.TargetName.Length == 0)
398 // We'll reset the DV to ensure we validate the metadata content
401 pCurrentObject->DataVersion.QuadPart = (ULONGLONG)-1;
403 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_VERIFY);
405 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
406 AFS_TRACE_LEVEL_VERBOSE,
407 "AFSLocateNameEntry (FO: %p) Verifying symlink parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
409 &pDirEntry->NameInformation.FileName,
410 pCurrentObject->FileId.Cell,
411 pCurrentObject->FileId.Volume,
412 pCurrentObject->FileId.Vnode,
413 pCurrentObject->FileId.Unique);
416 // Directory TreeLock should be exclusively held
419 ntStatus = AFSVerifyEntry( AuthGroup,
422 AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
424 if( !NT_SUCCESS( ntStatus))
427 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
428 AFS_TRACE_LEVEL_ERROR,
429 "AFSLocateNameEntry (FO: %p) Failed to verify symlink parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
431 &pDirEntry->NameInformation.FileName,
432 pCurrentObject->FileId.Cell,
433 pCurrentObject->FileId.Volume,
434 pCurrentObject->FileId.Vnode,
435 pCurrentObject->FileId.Unique,
438 AFSReleaseResource( &pDirEntry->NonPaged->Lock);
440 try_return( ntStatus);
444 // If the type changed then reprocess this entry
447 if( pCurrentObject->FileType != AFS_FILE_TYPE_SYMLINK)
450 AFSReleaseResource( &pDirEntry->NonPaged->Lock);
458 AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
462 // If we were given a zero length target name then deny access to the entry
465 if( pDirEntry->NameInformation.TargetName.Length == 0)
468 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
470 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
471 AFS_TRACE_LEVEL_ERROR,
472 "AFSLocateNameEntry (FO: %p) Failed to retrieve target name for symlink %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
474 &pDirEntry->NameInformation.FileName,
475 pCurrentObject->FileId.Cell,
476 pCurrentObject->FileId.Volume,
477 pCurrentObject->FileId.Vnode,
478 pCurrentObject->FileId.Unique,
481 AFSReleaseResource( &pDirEntry->NonPaged->Lock);
483 try_return( ntStatus);
486 if( AFSIsRelativeName( &pDirEntry->NameInformation.TargetName))
489 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
490 AFS_TRACE_LEVEL_VERBOSE,
491 "AFSLocateNameEntry (FO: %p) Processing relative symlink target %wZ for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
493 &pDirEntry->NameInformation.TargetName,
494 &pDirEntry->NameInformation.FileName,
495 pCurrentObject->FileId.Cell,
496 pCurrentObject->FileId.Volume,
497 pCurrentObject->FileId.Vnode,
498 pCurrentObject->FileId.Unique);
501 // We'll substitute this name into the current process name
502 // starting at where we sit in the path
505 uniTempName.Length = 0;
506 uniTempName.MaximumLength = (USHORT)((char *)uniComponentName.Buffer - (char *)uniFullPathName.Buffer) +
507 pDirEntry->NameInformation.TargetName.Length +
509 uniRemainingPath.Length;
511 uniTempName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
512 uniTempName.MaximumLength,
513 AFS_NAME_BUFFER_ONE_TAG);
515 if( uniTempName.Buffer == NULL)
518 AFSReleaseResource( &pDirEntry->NonPaged->Lock);
520 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
524 // We have so first copy in the portion up to the component
528 RtlCopyMemory( uniTempName.Buffer,
529 uniFullPathName.Buffer,
530 (ULONG)((char *)uniComponentName.Buffer - (char *)uniFullPathName.Buffer));
532 uniTempName.Length = (USHORT)((char *)uniComponentName.Buffer - (char *)uniFullPathName.Buffer);
534 if( bAllocatedSymLinkBuffer ||
538 pTmpBuffer = uniFullPathName.Buffer;
541 bAllocatedSymLinkBuffer = TRUE;
544 // Have we parsed this name yet? Better have at least once ...
547 if( uniComponentName.Length == 0)
553 // Copy in the target name ...
556 RtlCopyMemory( &uniTempName.Buffer[ uniTempName.Length/sizeof( WCHAR)],
557 pDirEntry->NameInformation.TargetName.Buffer,
558 pDirEntry->NameInformation.TargetName.Length);
560 uniPathName.Buffer = &uniTempName.Buffer[ uniTempName.Length/sizeof( WCHAR)];
562 uniPathName.Length += pDirEntry->NameInformation.TargetName.Length;
563 uniPathName.MaximumLength = uniTempName.MaximumLength;
565 uniTempName.Length += pDirEntry->NameInformation.TargetName.Length;
568 // And now any remaining portion of the name
571 if( uniRemainingPath.Length > 0)
574 if( uniRemainingPath.Buffer[ 0] != L'\\')
577 uniRemainingPath.Buffer--;
578 uniRemainingPath.Length += sizeof( WCHAR);
580 uniPathName.Length += sizeof( WCHAR);
583 RtlCopyMemory( &uniTempName.Buffer[ uniTempName.Length/sizeof( WCHAR)],
584 uniRemainingPath.Buffer,
585 uniRemainingPath.Length);
587 uniTempName.Length += uniRemainingPath.Length;
590 uniFullPathName = uniTempName;
592 if( pTmpBuffer != NULL)
595 AFSExFreePoolWithTag( pTmpBuffer, 0);
598 AFSReleaseResource( &pDirEntry->NonPaged->Lock);
601 // Dereference the current entry ..
604 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
606 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
607 AFS_TRACE_LEVEL_VERBOSE,
608 "AFSLocateNameEntry Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
609 &pDirEntry->NameInformation.FileName,
614 ASSERT( lCount >= 0);
617 // OK, need to back up one entry for the correct parent since the current
618 // entry we are on is the symlink itself
621 pDirEntry = AFSBackupEntry( pNameArray);
624 // Increment our reference on this dir entry
627 lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
629 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
630 AFS_TRACE_LEVEL_VERBOSE,
631 "AFSLocateNameEntry Increment1 count on %wZ DE %p Ccb %p Cnt %d\n",
632 &pDirEntry->NameInformation.FileName,
637 if( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_ROOT_VOLUME))
640 pParentDirEntry = NULL;
645 pParentDirEntry = AFSGetParentEntry( pNameArray);
647 ASSERT( pParentDirEntry != pDirEntry);
653 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
654 AFS_TRACE_LEVEL_VERBOSE,
655 "AFSLocateNameEntry (FO: %p) Processing absolute symlink target %wZ for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
657 &pDirEntry->NameInformation.TargetName,
658 &pDirEntry->NameInformation.FileName,
659 pCurrentObject->FileId.Cell,
660 pCurrentObject->FileId.Volume,
661 pCurrentObject->FileId.Vnode,
662 pCurrentObject->FileId.Unique);
664 if ( !AFSIsAbsoluteAFSName( &pDirEntry->NameInformation.TargetName))
667 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
668 AFS_TRACE_LEVEL_ERROR,
669 "AFSLocateNameEntry Name %wZ contains invalid server name\n",
670 &pDirEntry->NameInformation.TargetName);
673 // The correct response would be STATUS_OBJECT_PATH_INVALID
674 // but that prevents cmd.exe from performing a recursive
675 // directory enumeration when opening a directory entry
676 // that represents a symlink to an invalid path is discovered.
679 AFSReleaseResource( &pDirEntry->NonPaged->Lock);
681 try_return( ntStatus = STATUS_OBJECT_PATH_NOT_FOUND);
685 // We'll substitute this name into the current process name
686 // starting at where we sit in the path
689 uniTempName.Length = 0;
690 uniTempName.MaximumLength = pDirEntry->NameInformation.TargetName.Length +
692 uniRemainingPath.Length;
694 uniTempName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
695 uniTempName.MaximumLength,
696 AFS_NAME_BUFFER_TWO_TAG);
698 if( uniTempName.Buffer == NULL)
701 AFSReleaseResource( &pDirEntry->NonPaged->Lock);
703 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
706 if( bAllocatedSymLinkBuffer ||
710 pTmpBuffer = uniFullPathName.Buffer;
713 bAllocatedSymLinkBuffer = TRUE;
716 // Have we parsed this name yet? Better have at least once ...
719 if( uniComponentName.Length == 0)
725 // Copy in the target name ...
728 RtlCopyMemory( uniTempName.Buffer,
729 &pDirEntry->NameInformation.TargetName.Buffer[ AFSMountRootName.Length/sizeof( WCHAR)],
730 pDirEntry->NameInformation.TargetName.Length - AFSMountRootName.Length);
732 uniTempName.Length = pDirEntry->NameInformation.TargetName.Length - AFSMountRootName.Length;
735 // And now any remaining portion of the name
738 if( uniRemainingPath.Length > 0)
741 if( uniRemainingPath.Buffer[ 0] != L'\\')
744 uniRemainingPath.Buffer--;
745 uniRemainingPath.Length += sizeof( WCHAR);
748 RtlCopyMemory( &uniTempName.Buffer[ uniTempName.Length/sizeof( WCHAR)],
749 uniRemainingPath.Buffer,
750 uniRemainingPath.Length);
752 uniTempName.Length += uniRemainingPath.Length;
755 uniFullPathName = uniTempName;
757 uniPathName = uniTempName;
759 if( pTmpBuffer != NULL)
762 AFSExFreePoolWithTag( pTmpBuffer, 0);
765 AFSReleaseResource( &pDirEntry->NonPaged->Lock);
768 // If our current volume is not the global root then make it so ...
771 if( pCurrentVolume != AFSGlobalRoot)
774 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
775 AFS_TRACE_LEVEL_VERBOSE,
776 "AFSLocateNameEntry (FO: %p) Current volume not global, resetting for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
778 &pDirEntry->NameInformation.FileName,
779 pCurrentObject->FileId.Cell,
780 pCurrentObject->FileId.Volume,
781 pCurrentObject->FileId.Vnode,
782 pCurrentObject->FileId.Unique);
784 lCount = AFSVolumeDecrement( pCurrentVolume,
785 VolumeReferenceReason);
787 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
788 AFS_TRACE_LEVEL_VERBOSE,
789 "AFSLocateNameEntry Decrement count on volume %p Reason %u Cnt %d\n",
791 VolumeReferenceReason,
794 pCurrentVolume = AFSGlobalRoot;
796 VolumeReferenceReason = AFS_VOLUME_REFERENCE_LOCATE_NAME;
798 lCount = AFSVolumeIncrement( pCurrentVolume,
799 VolumeReferenceReason);
801 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
802 AFS_TRACE_LEVEL_VERBOSE,
803 "AFSLocateNameEntry Increment count on volume %p Reason %u Cnt %d\n",
805 VolumeReferenceReason,
810 // Dereference our current dir entry
813 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
815 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
816 AFS_TRACE_LEVEL_VERBOSE,
817 "AFSLocateNameEntry Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
818 &pDirEntry->NameInformation.FileName,
823 ASSERT( lCount >= 0);
825 pDirEntry = pCurrentVolume->DirectoryCB;
828 // Reference the new dir entry
831 lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
833 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
834 AFS_TRACE_LEVEL_VERBOSE,
835 "AFSLocateNameEntry Increment2 count on %wZ DE %p Ccb %p Cnt %d\n",
836 &pDirEntry->NameInformation.FileName,
842 // Reset the name array
843 // Persist the link count in the name array
846 lLinkCount = pNameArray->LinkCount;
848 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
849 AFS_TRACE_LEVEL_VERBOSE,
850 "AFSLocateNameEntry (FO: %p) Resetting name array for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
852 &pDirEntry->NameInformation.FileName,
853 pCurrentObject->FileId.Cell,
854 pCurrentObject->FileId.Volume,
855 pCurrentObject->FileId.Vnode,
856 pCurrentObject->FileId.Unique);
858 AFSResetNameArray( pNameArray,
861 pNameArray->LinkCount = lLinkCount;
863 pParentDirEntry = NULL;
867 // Increment our link count
870 lCount = InterlockedIncrement( &pNameArray->LinkCount);
875 case AFS_FILE_TYPE_MOUNTPOINT:
879 // Check if the flag is set to NOT evaluate a mount point
880 // and we are done with the parsing
883 if( BooleanFlagOn( Flags, AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL) &&
884 uniRemainingPath.Length == 0)
888 // Pass back the directory entries
891 *OutParentDirectoryCB = pParentDirEntry;
893 *OutDirectoryCB = pDirEntry;
895 *OutVolumeCB = pCurrentVolume;
897 *OutVolumeReferenceReason = VolumeReferenceReason;
899 bReleaseCurrentVolume = FALSE;
901 *RootPathName = uniFullPathName;
903 try_return( ntStatus);
906 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
907 AFS_TRACE_LEVEL_VERBOSE,
908 "AFSLocateNameEntry (FO: %p) Building MP target for parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
910 &pDirEntry->NameInformation.FileName,
911 pCurrentObject->FileId.Cell,
912 pCurrentObject->FileId.Volume,
913 pCurrentObject->FileId.Vnode,
914 pCurrentObject->FileId.Unique);
917 // Go retrieve the target entry for this node
918 // Release the current volume cb entry since we would
919 // have lock inversion in the following call
920 // Also decrement the ref count on the volume
923 ntStatus = AFSBuildMountPointTarget( AuthGroup,
927 if( !NT_SUCCESS( ntStatus))
930 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
931 AFS_TRACE_LEVEL_ERROR,
932 "AFSLocateNameEntry (FO: %p) Failed to build MP target for parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
934 &pDirEntry->NameInformation.FileName,
935 pCurrentObject->FileId.Cell,
936 pCurrentObject->FileId.Volume,
937 pCurrentObject->FileId.Vnode,
938 pCurrentObject->FileId.Unique,
941 try_return( ntStatus);
944 ASSERT( pCurrentVolume->VolumeReferenceCount > 0);
946 lCount = AFSVolumeDecrement( pCurrentVolume,
947 VolumeReferenceReason);
949 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
950 AFS_TRACE_LEVEL_VERBOSE,
951 "AFSLocateNameEntry Decrement2 count on volume %p Reason %u Cnt %d\n",
953 VolumeReferenceReason,
956 pCurrentVolume = pTargetVolume;
958 pTargetVolume = NULL;
960 ASSERT( pCurrentVolume->VolumeReferenceCount > 0);
962 VolumeReferenceReason = AFS_VOLUME_REFERENCE_MOUNTPT;
965 // We want to restart processing here on the new parent ...
966 // Deref and ref count the entries
969 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
971 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
972 AFS_TRACE_LEVEL_VERBOSE,
973 "AFSLocateNameEntry Decrement3 count on %wZ DE %p Ccb %p Cnt %d\n",
974 &pDirEntry->NameInformation.FileName,
979 ASSERT( lCount >= 0);
981 pDirEntry = pCurrentVolume->DirectoryCB;
983 lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
985 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
986 AFS_TRACE_LEVEL_VERBOSE,
987 "AFSLocateNameEntry Increment3 count on %wZ DE %p Ccb %p Cnt %d\n",
988 &pDirEntry->NameInformation.FileName,
994 // The name array stores both the mount point and the target.
995 // Insert the target.
998 AFSInsertNextElement( pNameArray,
1001 pParentDirEntry = NULL;
1004 // Increment our link count
1007 lCount = InterlockedIncrement( &pNameArray->LinkCount);
1012 case AFS_FILE_TYPE_DFSLINK:
1015 if( BooleanFlagOn( Flags, AFS_LOCATE_FLAGS_NO_DFS_LINK_EVAL))
1019 // Pass back the directory entries
1022 *OutParentDirectoryCB = pParentDirEntry;
1024 *OutDirectoryCB = pDirEntry;
1026 *OutVolumeCB = pCurrentVolume;
1028 *OutVolumeReferenceReason = VolumeReferenceReason;
1030 bReleaseCurrentVolume = FALSE;
1032 *RootPathName = uniFullPathName;
1034 try_return( ntStatus);
1038 // This is a DFS link so we need to update the file name and return STATUS_REPARSE to the
1039 // system for it to reevaluate it
1042 if( FileObject != NULL)
1045 ntStatus = AFSProcessDFSLink( pDirEntry,
1054 // This is where we have been re-entered from an NP evaluation call via the BuildBranch()
1058 ntStatus = STATUS_INVALID_PARAMETER;
1061 if( ntStatus != STATUS_SUCCESS &&
1062 ntStatus != STATUS_REPARSE)
1065 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1066 AFS_TRACE_LEVEL_ERROR,
1067 "AFSLocateNameEntry (FO: %p) Failed to process DFSLink parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1069 &pDirEntry->NameInformation.FileName,
1070 pCurrentObject->FileId.Cell,
1071 pCurrentObject->FileId.Volume,
1072 pCurrentObject->FileId.Vnode,
1073 pCurrentObject->FileId.Unique,
1077 try_return( ntStatus);
1080 case AFS_FILE_TYPE_UNKNOWN:
1081 case AFS_FILE_TYPE_INVALID:
1085 // Something was not processed ...
1088 try_return( ntStatus = STATUS_ACCESS_DENIED);
1091 } /* end of switch */
1094 // If the parent is not initialized then do it now
1097 if( pCurrentObject->FileType == AFS_FILE_TYPE_DIRECTORY &&
1098 !BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
1101 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1102 AFS_TRACE_LEVEL_VERBOSE,
1103 "AFSLocateNameEntry (FO: %p) Enumerating parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1105 &pDirEntry->NameInformation.FileName,
1106 pCurrentObject->FileId.Cell,
1107 pCurrentObject->FileId.Volume,
1108 pCurrentObject->FileId.Vnode,
1109 pCurrentObject->FileId.Unique);
1111 AFSAcquireExcl( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
1114 if( !BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
1117 ntStatus = AFSEnumerateDirectory( AuthGroup,
1121 if( !NT_SUCCESS( ntStatus))
1124 AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
1126 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1127 AFS_TRACE_LEVEL_ERROR,
1128 "AFSLocateNameEntry (FO: %p) Failed to enumerate parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1130 &pDirEntry->NameInformation.FileName,
1131 pCurrentObject->FileId.Cell,
1132 pCurrentObject->FileId.Volume,
1133 pCurrentObject->FileId.Vnode,
1134 pCurrentObject->FileId.Unique,
1137 try_return( ntStatus);
1140 SetFlag( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
1143 AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
1145 else if( pCurrentObject->FileType == AFS_FILE_TYPE_FILE)
1148 if( uniPathName.Length > 0)
1151 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1152 AFS_TRACE_LEVEL_ERROR,
1153 "AFSLocateNameEntry (FO: %p) Encountered file node %wZ FID %08lX-%08lX-%08lX-%08lX in path processing\n",
1155 &pDirEntry->NameInformation.FileName,
1156 pCurrentObject->FileId.Cell,
1157 pCurrentObject->FileId.Volume,
1158 pCurrentObject->FileId.Vnode,
1159 pCurrentObject->FileId.Unique);
1161 // The proper error code to return would be STATUS_OBJECT_PATH_INVALID because
1162 // one of the components of the path is not a directory. However, returning
1163 // that error prevents IIS 7 and 7.5 from being able to serve data out of AFS.
1164 // Instead IIS insists on treating the target file as if it is a directory containing
1165 // a potential web.config file. NTFS and LanMan return STATUS_OBJECT_PATH_NOT_FOUND.
1166 // AFS will follow suit.
1168 ntStatus = STATUS_OBJECT_PATH_NOT_FOUND;
1173 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1174 AFS_TRACE_LEVEL_VERBOSE,
1175 "AFSLocateNameEntry (FO: %p) Returning file %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1177 &pDirEntry->NameInformation.FileName,
1178 pCurrentObject->FileId.Cell,
1179 pCurrentObject->FileId.Volume,
1180 pCurrentObject->FileId.Vnode,
1181 pCurrentObject->FileId.Unique);
1184 // Pass back the directory entries
1187 *OutParentDirectoryCB = pParentDirEntry;
1189 *OutDirectoryCB = pDirEntry;
1191 *OutVolumeCB = pCurrentVolume;
1193 *OutVolumeReferenceReason = VolumeReferenceReason;
1195 bReleaseCurrentVolume = FALSE;
1197 *RootPathName = uniFullPathName;
1200 try_return( ntStatus);
1204 // If we are at the end of the processing, set our returned information and get out
1207 if( uniPathName.Length == 0)
1210 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1211 AFS_TRACE_LEVEL_VERBOSE,
1212 "AFSLocateNameEntry (FO: %p) Completed processing returning %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1214 &pDirEntry->NameInformation.FileName,
1215 pCurrentObject->FileId.Cell,
1216 pCurrentObject->FileId.Volume,
1217 pCurrentObject->FileId.Vnode,
1218 pCurrentObject->FileId.Unique);
1221 // Pass back the directory entries
1224 *OutParentDirectoryCB = pParentDirEntry;
1226 *OutDirectoryCB = pDirEntry;
1228 *OutVolumeCB = pCurrentVolume;
1230 *OutVolumeReferenceReason = VolumeReferenceReason;
1232 bReleaseCurrentVolume = FALSE;
1234 *RootPathName = uniFullPathName;
1236 try_return( ntStatus);
1240 // We may have returned to the top of the while( TRUE)
1242 if( bSubstituteName &&
1243 uniSearchName.Buffer != NULL)
1246 AFSExFreePoolWithTag( uniSearchName.Buffer, 0);
1248 bSubstituteName = FALSE;
1250 uniSearchName.Length = uniSearchName.MaximumLength = 0;
1251 uniSearchName.Buffer = NULL;
1254 ulSubstituteIndex = 1;
1256 ntStatus = STATUS_SUCCESS;
1259 // Get the next component name
1262 FsRtlDissectName( uniPathName,
1267 // Check for the . and .. in the path
1270 if( RtlCompareUnicodeString( &uniComponentName,
1275 uniPathName = uniRemainingPath;
1280 if( RtlCompareUnicodeString( &uniComponentName,
1285 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1286 AFS_TRACE_LEVEL_VERBOSE,
1287 "AFSLocateNameEntry (FO: %p) Backing up entry from %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1289 &pDirEntry->NameInformation.FileName,
1290 pCurrentObject->FileId.Cell,
1291 pCurrentObject->FileId.Volume,
1292 pCurrentObject->FileId.Vnode,
1293 pCurrentObject->FileId.Unique);
1296 // Need to back up one entry in the name array
1298 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
1300 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1301 AFS_TRACE_LEVEL_VERBOSE,
1302 "AFSLocateNameEntry Decrement4 count on %wZ DE %p Ccb %p Cnt %d\n",
1303 &pDirEntry->NameInformation.FileName,
1308 ASSERT( lCount >= 0);
1310 pDirEntry = AFSBackupEntry( NameArray);
1312 if( pDirEntry == NULL)
1315 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1316 AFS_TRACE_LEVEL_ERROR,
1317 "AFSLocateNameEntry AFSBackupEntry failed\n");
1319 try_return(ntStatus = STATUS_OBJECT_PATH_INVALID);
1322 lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
1324 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1325 AFS_TRACE_LEVEL_VERBOSE,
1326 "AFSLocateNameEntry Increment4 count on %wZ DE %p Ccb %p Cnt %d\n",
1327 &pDirEntry->NameInformation.FileName,
1332 if( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_ROOT_VOLUME))
1335 pParentDirEntry = NULL;
1340 pParentDirEntry = AFSGetParentEntry( pNameArray);
1342 ASSERT( pParentDirEntry != pDirEntry);
1345 uniPathName = uniRemainingPath;
1351 // Update our pointers
1354 pParentDirEntry = pDirEntry;
1358 uniSearchName = uniComponentName;
1360 while( pDirEntry == NULL)
1364 // If the SearchName contains @SYS then we perform the substitution.
1365 // If there is no substitution we give up.
1368 if( !bSubstituteName &&
1369 FsRtlIsNameInExpression( &uniSysName,
1375 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1376 AFS_TRACE_LEVEL_VERBOSE_2,
1377 "AFSLocateNameEntry (FO: %p) Processing @SYS substitution for %wZ Index %08lX\n",
1382 ntStatus = AFSSubstituteSysName( &uniComponentName,
1386 if ( NT_SUCCESS( ntStatus))
1389 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1390 AFS_TRACE_LEVEL_VERBOSE_2,
1391 "AFSLocateNameEntry (FO: %p) Located substitution %wZ for %wZ Index %08lX\n",
1398 // Go reparse the name again
1401 bSubstituteName = TRUE;
1403 ulSubstituteIndex++; // For the next entry, if needed
1405 continue; // while( pDirEntry == NULL)
1410 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1411 AFS_TRACE_LEVEL_ERROR,
1412 "AFSLocateNameEntry (FO: %p) Failed to locate substitute string for %wZ Index %08lX Status %08lX\n",
1418 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
1422 // Pass back the directory entries
1425 *OutParentDirectoryCB = pParentDirEntry;
1427 *OutDirectoryCB = NULL;
1429 *OutVolumeCB = pCurrentVolume;
1431 *OutVolumeReferenceReason = VolumeReferenceReason;
1433 bReleaseCurrentVolume = FALSE;
1435 if( ComponentName != NULL)
1438 *ComponentName = uniComponentName;
1441 *RootPathName = uniFullPathName;
1445 // We can't possibly have a pDirEntry since the lookup failed
1447 try_return( ntStatus);
1452 // Generate the CRC on the node and perform a case sensitive lookup
1455 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1456 AFS_TRACE_LEVEL_VERBOSE_2,
1457 "AFSLocateNameEntry (FO: %p) Searching for entry %wZ case sensitive\n",
1461 ulCRC = AFSGenerateCRC( &uniSearchName,
1464 AFSAcquireShared( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
1467 AFSLocateCaseSensitiveDirEntry( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
1471 if( pDirEntry == NULL)
1475 // Missed so perform a case insensitive lookup
1478 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1479 AFS_TRACE_LEVEL_VERBOSE_2,
1480 "AFSLocateNameEntry (FO: %p) Searching for entry %wZ case insensitive\n",
1484 ulCRC = AFSGenerateCRC( &uniSearchName,
1487 AFSLocateCaseInsensitiveDirEntry( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
1491 if( pDirEntry == NULL)
1495 // OK, if this component is a valid short name then try
1496 // a lookup in the short name tree
1499 if( !BooleanFlagOn( pDevExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
1500 RtlIsNameLegalDOS8Dot3( &uniSearchName,
1505 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1506 AFS_TRACE_LEVEL_VERBOSE_2,
1507 "AFSLocateNameEntry (FO: %p) Searching for entry %wZ short name\n",
1511 AFSLocateShortNameDirEntry( pParentDirEntry->ObjectInformation->Specific.Directory.ShortNameTree,
1516 if ( pDirEntry == NULL &&
1517 pParentDirEntry->ObjectInformation->VolumeCB == AFSGlobalRoot)
1521 // Check with the service to see if this is a valid cell name
1522 // that can be automatically resolved. Drop the shared TreeLock
1523 // since AFSCheckCellName must acquire it exclusively.
1526 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1528 ntStatus = AFSCheckCellName( AuthGroup,
1532 AFSAcquireShared( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
1536 if( pDirEntry == NULL)
1540 // If we substituted a name then reset our search name and try again
1543 if( bSubstituteName)
1546 AFSExFreePoolWithTag( uniSearchName.Buffer, 0);
1548 uniSearchName = uniComponentName;
1550 bSubstituteName = FALSE;
1552 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1554 continue; // while( pDirEntry == NULL)
1557 if( uniRemainingPath.Length > 0)
1560 ntStatus = STATUS_OBJECT_PATH_NOT_FOUND;
1562 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1563 AFS_TRACE_LEVEL_VERBOSE,
1564 "AFSLocateNameEntry (FO: %p) Returning path not found for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1567 pCurrentObject->FileId.Cell,
1568 pCurrentObject->FileId.Volume,
1569 pCurrentObject->FileId.Vnode,
1570 pCurrentObject->FileId.Unique);
1575 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
1577 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1578 AFS_TRACE_LEVEL_VERBOSE,
1579 "AFSLocateNameEntry (FO: %p) Returning name not found for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1582 pCurrentObject->FileId.Cell,
1583 pCurrentObject->FileId.Volume,
1584 pCurrentObject->FileId.Vnode,
1585 pCurrentObject->FileId.Unique);
1588 // Pass back the directory entries
1591 *OutParentDirectoryCB = pParentDirEntry;
1593 *OutDirectoryCB = NULL;
1595 *OutVolumeCB = pCurrentVolume;
1597 *OutVolumeReferenceReason = VolumeReferenceReason;
1599 bReleaseCurrentVolume = FALSE;
1601 if( ComponentName != NULL)
1604 *ComponentName = uniComponentName;
1607 *RootPathName = uniFullPathName;
1610 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1613 // Node name not found so get out
1616 try_return( ntStatus); // while( pDirEntry == NULL)
1623 // Here we have a match on the case insensitive lookup for the name. If there
1624 // Is more than one link entry for this node then fail the lookup request
1627 if( !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD) ||
1628 pDirEntry->CaseInsensitiveList.fLink != NULL)
1632 // Increment our dir entry ref count since we will decrement it on exit
1635 lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
1637 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1638 AFS_TRACE_LEVEL_VERBOSE,
1639 "AFSLocateNameEntry Increment5 count on %wZ DE %p Ccb %p Cnt %d\n",
1640 &pDirEntry->NameInformation.FileName,
1645 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1647 try_return(ntStatus = STATUS_OBJECT_NAME_COLLISION);
1652 if( pDirEntry != NULL)
1656 // If the verify flag is set on the parent and the current entry is deleted
1657 // revalidate the parent and search again.
1660 if( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED) &&
1661 BooleanFlagOn( pParentDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY))
1664 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1666 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1667 AFS_TRACE_LEVEL_VERBOSE,
1668 "AFSLocateNameEntry (FO: %p) Verifying(2) parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1670 &pParentDirEntry->NameInformation.FileName,
1671 pParentDirEntry->ObjectInformation->FileId.Cell,
1672 pParentDirEntry->ObjectInformation->FileId.Volume,
1673 pParentDirEntry->ObjectInformation->FileId.Vnode,
1674 pParentDirEntry->ObjectInformation->FileId.Unique);
1677 // Directory TreeLock should be exclusively held
1680 AFSAcquireExcl( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
1683 ntStatus = AFSVerifyEntry( AuthGroup,
1686 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1688 if( !NT_SUCCESS( ntStatus))
1691 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1692 AFS_TRACE_LEVEL_ERROR,
1693 "AFSLocateNameEntry (FO: %p) Failed to verify(2) parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1695 &pParentDirEntry->NameInformation.FileName,
1696 pParentDirEntry->ObjectInformation->FileId.Cell,
1697 pParentDirEntry->ObjectInformation->FileId.Volume,
1698 pParentDirEntry->ObjectInformation->FileId.Vnode,
1699 pParentDirEntry->ObjectInformation->FileId.Unique,
1702 try_return( ntStatus);
1705 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1706 AFS_TRACE_LEVEL_VERBOSE,
1707 "AFSLocateNameEntry (FO: %p) Reprocessing component %wZ in parent %wZ\n",
1710 &pParentDirEntry->NameInformation.FileName);
1719 // Increment our dir entry ref count
1722 lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
1724 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1725 AFS_TRACE_LEVEL_VERBOSE,
1726 "AFSLocateNameEntry Increment6 count on %wZ DE %p Ccb %p Cnt %d\n",
1727 &pDirEntry->NameInformation.FileName,
1733 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1735 } // End while( pDirEntry == NULL)
1738 // If we have a dirEntry for this component, perform some basic validation on it
1741 if( pDirEntry != NULL &&
1742 BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
1745 pCurrentObject = pDirEntry->ObjectInformation;
1747 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1748 AFS_TRACE_LEVEL_ERROR,
1749 "AFSLocateNameEntry (FO: %p) Deleted entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1751 &pDirEntry->NameInformation.FileName,
1752 pCurrentObject->FileId.Cell,
1753 pCurrentObject->FileId.Volume,
1754 pCurrentObject->FileId.Vnode,
1755 pCurrentObject->FileId.Unique);
1758 // This entry was deleted through the invalidation call back so perform cleanup
1762 if( BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
1765 pParentObjectInfo = AFSFindObjectInfo( pCurrentObject->VolumeCB,
1766 &pCurrentObject->ParentFileId);
1769 ASSERT( pParentObjectInfo != NULL);
1771 AFSAcquireExcl( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
1774 AFSAcquireExcl( pCurrentObject->VolumeCB->ObjectInfoTree.TreeLock,
1777 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
1779 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1780 AFS_TRACE_LEVEL_VERBOSE,
1781 "AFSLocateNameEntry Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
1782 &pDirEntry->NameInformation.FileName,
1787 ASSERT( lCount >= 0);
1792 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING|AFS_SUBSYSTEM_CLEANUP_PROCESSING,
1793 AFS_TRACE_LEVEL_VERBOSE,
1794 "AFSLocateNameEntry Deleting dir entry %p (%p) for %wZ\n",
1797 &pDirEntry->NameInformation.FileName);
1800 // Remove and delete the directory entry from the parent list
1803 AFSDeleteDirEntry( pParentObjectInfo,
1806 AFSAcquireShared( &pCurrentObject->NonPagedInfo->ObjectInfoLock,
1809 if( pCurrentObject->ObjectReferenceCount <= 0)
1812 if( BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_INSERTED_HASH_TREE))
1815 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
1816 AFS_TRACE_LEVEL_VERBOSE,
1817 "AFSLocateNameEntry Removing object %p from volume tree\n",
1820 AFSRemoveHashEntry( &pCurrentObject->VolumeCB->ObjectInfoTree.TreeHead,
1821 &pCurrentObject->TreeEntry);
1823 ClearFlag( pCurrentObject->Flags, AFS_OBJECT_INSERTED_HASH_TREE);
1827 AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock);
1832 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1833 AFS_TRACE_LEVEL_VERBOSE,
1834 "AFSLocateNameEntry Setting DELETE flag in dir entry %p for %wZ\n",
1836 &pDirEntry->NameInformation.FileName);
1838 SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
1840 AFSRemoveNameEntry( pParentObjectInfo,
1844 AFSReleaseResource( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
1846 AFSReleaseResource( pCurrentObject->VolumeCB->ObjectInfoTree.TreeLock);
1848 AFSReleaseObjectInfo( &pParentObjectInfo);
1851 // We deleted the dir entry so check if there is any remaining portion
1852 // of the name to process.
1855 if( uniRemainingPath.Length > 0)
1858 ntStatus = STATUS_OBJECT_PATH_NOT_FOUND;
1860 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1861 AFS_TRACE_LEVEL_VERBOSE,
1862 "AFSLocateNameEntry (FO: %p) Returning path not found(2) for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1865 pCurrentObject->FileId.Cell,
1866 pCurrentObject->FileId.Volume,
1867 pCurrentObject->FileId.Vnode,
1868 pCurrentObject->FileId.Unique);
1873 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
1875 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1876 AFS_TRACE_LEVEL_VERBOSE,
1877 "AFSLocateNameEntry (FO: %p) Returning name not found(2) for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1880 pCurrentObject->FileId.Cell,
1881 pCurrentObject->FileId.Volume,
1882 pCurrentObject->FileId.Vnode,
1883 pCurrentObject->FileId.Unique);
1886 // Pass back the directory entries
1889 *OutParentDirectoryCB = pParentDirEntry;
1891 *OutDirectoryCB = NULL;
1893 *OutVolumeCB = pCurrentVolume;
1895 *OutVolumeReferenceReason = VolumeReferenceReason;
1897 bReleaseCurrentVolume = FALSE;
1899 if( ComponentName != NULL)
1902 *ComponentName = uniComponentName;
1905 *RootPathName = uniFullPathName;
1909 if( ntStatus != STATUS_SUCCESS)
1912 try_return( ntStatus);
1916 // Decrement the previous parent
1919 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
1921 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1922 AFS_TRACE_LEVEL_VERBOSE,
1923 "AFSLocateNameEntry Decrement5 count on Parent %wZ DE %p Ccb %p Cnt %d\n",
1924 &pParentDirEntry->NameInformation.FileName,
1929 ASSERT( lCount >= 0);
1932 // If we ended up substituting a name in the component then update
1933 // the full path and update the pointers
1936 if( bSubstituteName)
1939 BOOLEAN bRelativeOpen = FALSE;
1941 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1942 AFS_TRACE_LEVEL_VERBOSE_2,
1943 "AFSLocateNameEntry (FO: %p) Substituting %wZ into %wZ Index %08lX\n",
1949 if( FileObject != NULL &&
1950 FileObject->RelatedFileObject != NULL)
1953 bRelativeOpen = TRUE;
1957 // AFSSubstituteNameInPath will replace the uniFullPathName.Buffer
1958 // and free the prior Buffer contents but only if the fourth
1959 // parameter is TRUE.
1962 ntStatus = AFSSubstituteNameInPath( &uniFullPathName,
1967 bAllocatedSymLinkBuffer ||
1970 if( !NT_SUCCESS( ntStatus))
1973 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1974 AFS_TRACE_LEVEL_ERROR,
1975 "AFSLocateNameEntry (FO: %p) Failure to substitute %wZ into %wZ Index %08lX Status %08lX\n",
1982 try_return( ntStatus);
1986 // We have substituted a name into the buffer so if we do this again for this
1987 // path, we need to free up the buffer we allocated.
1990 bSubstitutedName = TRUE;
1994 // Update the search parameters
1997 uniPathName = uniRemainingPath;
2000 // Check if the is a SymLink entry but has no Target FileID or Name. In this
2001 // case it might be a DFS Link so let's go and evaluate it to be sure
2004 if( pCurrentObject->FileType == AFS_FILE_TYPE_SYMLINK &&
2005 ( pCurrentObject->TargetFileId.Vnode == 0 ||
2006 pDirEntry->NameInformation.TargetName.Length == 0))
2009 ntStatus = AFSValidateSymLink( AuthGroup,
2012 if( !NT_SUCCESS( ntStatus))
2015 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2016 AFS_TRACE_LEVEL_ERROR,
2017 "AFSLocateNameEntry (FO: %p) Failed to evaluate possible DFS Link %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2019 &pDirEntry->NameInformation.FileName,
2020 pCurrentObject->FileId.Cell,
2021 pCurrentObject->FileId.Volume,
2022 pCurrentObject->FileId.Vnode,
2023 pCurrentObject->FileId.Unique,
2026 try_return( ntStatus);
2031 // Update the name array
2034 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2035 AFS_TRACE_LEVEL_VERBOSE,
2036 "AFSLocateNameEntry (FO: %p) Inserting name array entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2038 &pDirEntry->NameInformation.FileName,
2039 pCurrentObject->FileId.Cell,
2040 pCurrentObject->FileId.Volume,
2041 pCurrentObject->FileId.Vnode,
2042 pCurrentObject->FileId.Unique);
2044 ntStatus = AFSInsertNextElement( pNameArray,
2047 if( !NT_SUCCESS( ntStatus))
2050 try_return( ntStatus);
2056 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2057 AFS_TRACE_LEVEL_VERBOSE,
2058 "AFSLocateNameEntry (FO: %p) Completed processing %wZ Status %08lX\n",
2063 if( ( !NT_SUCCESS( ntStatus) &&
2064 ntStatus != STATUS_OBJECT_NAME_NOT_FOUND) ||
2065 ntStatus == STATUS_REPARSE)
2068 if( pDirEntry != NULL)
2071 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
2073 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2074 AFS_TRACE_LEVEL_VERBOSE,
2075 "AFSLocateNameEntry Decrement6 count on %wZ DE %p Ccb %p Cnt %d\n",
2076 &pDirEntry->NameInformation.FileName,
2081 ASSERT( lCount >= 0);
2083 else if( pParentDirEntry != NULL)
2086 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
2088 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2089 AFS_TRACE_LEVEL_VERBOSE,
2090 "AFSLocateNameEntry Decrement7 count on %wZ DE %p Ccb %p Cnt %d\n",
2091 &pParentDirEntry->NameInformation.FileName,
2096 ASSERT( lCount >= 0);
2099 if( RootPathName->Buffer != uniFullPathName.Buffer)
2102 AFSExFreePoolWithTag( uniFullPathName.Buffer, 0);
2108 if( *OutParentDirectoryCB != NULL)
2111 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2112 AFS_TRACE_LEVEL_VERBOSE,
2113 "AFSLocateNameEntry Count on Parent %wZ DE %p Ccb %p Cnt %d\n",
2114 &(*OutParentDirectoryCB)->NameInformation.FileName,
2115 *OutParentDirectoryCB,
2117 (*OutParentDirectoryCB)->DirOpenReferenceCount);
2120 if( *OutDirectoryCB != NULL)
2123 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2124 AFS_TRACE_LEVEL_VERBOSE,
2125 "AFSLocateNameEntry Count on %wZ DE %p Ccb %p Cnt %d\n",
2126 &(*OutDirectoryCB)->NameInformation.FileName,
2129 (*OutDirectoryCB)->DirOpenReferenceCount);
2133 if( bReleaseCurrentVolume)
2136 ASSERT( pCurrentVolume->VolumeReferenceCount > 0);
2138 lCount = AFSVolumeDecrement( pCurrentVolume,
2139 VolumeReferenceReason);
2141 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2142 AFS_TRACE_LEVEL_VERBOSE,
2143 "AFSLocateNameEntry Decrement7 count on volume %p Reason %u Cnt %d\n",
2145 VolumeReferenceReason,
2148 bReleaseCurrentVolume = FALSE;
2151 if( bSubstituteName &&
2152 uniSearchName.Buffer != NULL)
2155 AFSExFreePoolWithTag( uniSearchName.Buffer, 0);
2163 AFSCreateDirEntry( IN GUID *AuthGroup,
2164 IN AFSObjectInfoCB *ParentObjectInfo,
2165 IN AFSDirectoryCB *ParentDirCB,
2166 IN PUNICODE_STRING FileName,
2167 IN PUNICODE_STRING ComponentName,
2168 IN ULONG Attributes,
2169 IN OUT AFSDirectoryCB **DirEntry)
2172 UNREFERENCED_PARAMETER(FileName);
2173 NTSTATUS ntStatus = STATUS_SUCCESS;
2174 AFSDirectoryCB *pDirNode = NULL, *pExistingDirNode = NULL;
2175 LARGE_INTEGER liFileSize = {0,0};
2181 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2182 AFS_TRACE_LEVEL_VERBOSE_2,
2183 "AFSCreateDirEntry Creating dir entry in parent %wZ FID %08lX-%08lX-%08lX-%08lX Component %wZ Attribs %08lX\n",
2184 &ParentDirCB->NameInformation.FileName,
2185 ParentObjectInfo->FileId.Cell,
2186 ParentObjectInfo->FileId.Volume,
2187 ParentObjectInfo->FileId.Vnode,
2188 ParentObjectInfo->FileId.Unique,
2193 // OK, before inserting the node into the parent tree, issue
2194 // the request to the service for node creation
2195 // We will need to drop the lock on the parent node since the create
2196 // could cause a callback into the file system to invalidate it's cache
2199 ntStatus = AFSNotifyFileCreate( AuthGroup,
2207 // If the returned status is STATUS_REPARSE then the entry exists
2208 // and we raced, get out.
2210 if( ntStatus == STATUS_REPARSE)
2213 *DirEntry = pDirNode;
2215 try_return( ntStatus = STATUS_SUCCESS);
2218 if( !NT_SUCCESS( ntStatus))
2221 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2222 AFS_TRACE_LEVEL_ERROR,
2223 "AFSCreateDirEntry Failed to create dir entry in parent %wZ FID %08lX-%08lX-%08lX-%08lX Component %wZ Attribs %08lX Status %08lX\n",
2224 &ParentDirCB->NameInformation.FileName,
2225 ParentObjectInfo->FileId.Cell,
2226 ParentObjectInfo->FileId.Volume,
2227 ParentObjectInfo->FileId.Vnode,
2228 ParentObjectInfo->FileId.Unique,
2233 try_return( ntStatus);
2237 // If AFSNotifyFileCreate returns pDirNode != NULL, then its
2238 // DirOpenReferenceCount is held.
2241 AFSAcquireExcl( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2245 // Before attempting to insert the new entry, check if we need to validate the parent
2248 if( BooleanFlagOn( ParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY))
2251 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2252 AFS_TRACE_LEVEL_VERBOSE,
2253 "AFSCreateDirEntry Verifying parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2254 &ParentDirCB->NameInformation.FileName,
2255 ParentObjectInfo->FileId.Cell,
2256 ParentObjectInfo->FileId.Volume,
2257 ParentObjectInfo->FileId.Vnode,
2258 ParentObjectInfo->FileId.Unique);
2260 ntStatus = AFSVerifyEntry( AuthGroup,
2263 if( !NT_SUCCESS( ntStatus))
2266 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2267 AFS_TRACE_LEVEL_ERROR,
2268 "AFSCreateDirEntry Failed to verify parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2269 &ParentDirCB->NameInformation.FileName,
2270 ParentObjectInfo->FileId.Cell,
2271 ParentObjectInfo->FileId.Volume,
2272 ParentObjectInfo->FileId.Vnode,
2273 ParentObjectInfo->FileId.Unique,
2276 AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2278 try_return( ntStatus);
2283 // Check for the entry in the event we raced with some other thread
2286 AFSLocateCaseSensitiveDirEntry( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
2287 (ULONG)pDirNode->CaseSensitiveTreeEntry.HashIndex,
2290 if( pExistingDirNode != NULL)
2292 if (AFSIsEqualFID( &pDirNode->ObjectInformation->FileId,
2293 &pExistingDirNode->ObjectInformation->FileId))
2296 if ( pExistingDirNode != pDirNode)
2299 lCount = InterlockedDecrement( &pDirNode->DirOpenReferenceCount);
2301 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2302 AFS_TRACE_LEVEL_VERBOSE,
2303 "AFSCreateDirEntry Decrement count on %wZ DE %p Cnt %d\n",
2304 &pDirNode->NameInformation.FileName,
2308 AFSDeleteDirEntry( ParentObjectInfo,
2311 lCount = InterlockedIncrement( &pExistingDirNode->DirOpenReferenceCount);
2313 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2314 AFS_TRACE_LEVEL_VERBOSE,
2315 "AFSCreateDirEntry Increment count on %wZ DE %p Cnt %d\n",
2316 &pExistingDirNode->NameInformation.FileName,
2320 *DirEntry = pExistingDirNode;
2323 AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2325 try_return( ntStatus = STATUS_SUCCESS);
2331 // Need to tear down this entry and rebuild it below
2334 if( pExistingDirNode->DirOpenReferenceCount <= 0)
2337 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2338 AFS_TRACE_LEVEL_VERBOSE,
2339 "AFSCreateDirEntry Different FIDs - Deleting DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
2341 &pExistingDirNode->NameInformation.FileName,
2342 pExistingDirNode->ObjectInformation->FileId.Cell,
2343 pExistingDirNode->ObjectInformation->FileId.Volume,
2344 pExistingDirNode->ObjectInformation->FileId.Vnode,
2345 pExistingDirNode->ObjectInformation->FileId.Unique,
2346 pDirNode->ObjectInformation->FileId.Cell,
2347 pDirNode->ObjectInformation->FileId.Volume,
2348 pDirNode->ObjectInformation->FileId.Vnode,
2349 pDirNode->ObjectInformation->FileId.Unique);
2351 AFSDeleteDirEntry( ParentObjectInfo,
2357 SetFlag( pExistingDirNode->Flags, AFS_DIR_ENTRY_DELETED);
2359 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2360 AFS_TRACE_LEVEL_VERBOSE,
2361 "AFSCreateDirEntry Different FIDs - Removing DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
2363 &pExistingDirNode->NameInformation.FileName,
2364 pExistingDirNode->ObjectInformation->FileId.Cell,
2365 pExistingDirNode->ObjectInformation->FileId.Volume,
2366 pExistingDirNode->ObjectInformation->FileId.Vnode,
2367 pExistingDirNode->ObjectInformation->FileId.Unique,
2368 pDirNode->ObjectInformation->FileId.Cell,
2369 pDirNode->ObjectInformation->FileId.Volume,
2370 pDirNode->ObjectInformation->FileId.Vnode,
2371 pDirNode->ObjectInformation->FileId.Unique);
2373 AFSRemoveNameEntry( ParentObjectInfo,
2379 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2380 AFS_TRACE_LEVEL_VERBOSE_2,
2381 "AFSCreateDirEntry Inserting dir entry in parent %wZ FID %08lX-%08lX-%08lX-%08lX Component %wZ\n",
2382 &ParentDirCB->NameInformation.FileName,
2383 ParentObjectInfo->FileId.Cell,
2384 ParentObjectInfo->FileId.Volume,
2385 ParentObjectInfo->FileId.Vnode,
2386 ParentObjectInfo->FileId.Unique,
2390 // Insert the directory node
2393 AFSInsertDirectoryNode( ParentObjectInfo,
2398 // Pass back the dir entry
2401 *DirEntry = pDirNode;
2403 AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2414 AFSInsertDirectoryNode( IN AFSObjectInfoCB *ParentObjectInfo,
2415 IN AFSDirectoryCB *DirEntry,
2416 IN BOOLEAN InsertInEnumList)
2424 ASSERT( ExIsResourceAcquiredExclusiveLite( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock));
2427 // Insert the node into the directory node tree
2430 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2431 AFS_TRACE_LEVEL_VERBOSE,
2432 "AFSInsertDirectoryNode Insert DE %p for %wZ Clearing NOT_IN flag\n",
2434 &DirEntry->NameInformation.FileName);
2436 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
2438 if( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead == NULL)
2441 ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = DirEntry;
2443 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2444 AFS_TRACE_LEVEL_VERBOSE,
2445 "AFSInsertDirectoryNode Insert DE %p to head of case sensitive tree for %wZ\n",
2447 &DirEntry->NameInformation.FileName);
2452 AFSInsertCaseSensitiveDirEntry( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
2455 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2456 AFS_TRACE_LEVEL_VERBOSE,
2457 "AFSInsertDirectoryNode Insert DE %p to case sensitive tree for %wZ\n",
2459 &DirEntry->NameInformation.FileName);
2462 if( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead == NULL)
2465 ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = DirEntry;
2467 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
2469 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2470 AFS_TRACE_LEVEL_VERBOSE,
2471 "AFSInsertDirectoryNode Insert DE %p to head of case insensitive tree for %wZ\n",
2473 &DirEntry->NameInformation.FileName);
2478 AFSInsertCaseInsensitiveDirEntry( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
2481 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2482 AFS_TRACE_LEVEL_VERBOSE,
2483 "AFSInsertDirectoryNode Insert DE %p to case insensitive tree for %wZ\n",
2485 &DirEntry->NameInformation.FileName);
2489 // Into the shortname tree
2492 if( DirEntry->Type.Data.ShortNameTreeEntry.HashIndex != 0)
2495 if( ParentObjectInfo->Specific.Directory.ShortNameTree == NULL)
2498 ParentObjectInfo->Specific.Directory.ShortNameTree = DirEntry;
2500 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2501 AFS_TRACE_LEVEL_VERBOSE,
2502 "AFSInsertDirectoryNode Insert DE %p to head of shortname tree for %wZ\n",
2504 &DirEntry->NameInformation.FileName);
2506 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
2511 if( !NT_SUCCESS( AFSInsertShortNameDirEntry( ParentObjectInfo->Specific.Directory.ShortNameTree,
2514 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2515 AFS_TRACE_LEVEL_VERBOSE,
2516 "AFSInsertDirectoryNode Failed to insert DE %p to shortname tree for %wZ\n",
2518 &DirEntry->NameInformation.FileName);
2522 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
2524 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2525 AFS_TRACE_LEVEL_VERBOSE,
2526 "AFSInsertDirectoryNode Insert DE %p to shortname tree for %wZ\n",
2528 &DirEntry->NameInformation.FileName);
2533 if( InsertInEnumList)
2537 // And insert the node into the directory list
2540 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2541 AFS_TRACE_LEVEL_VERBOSE,
2542 "AFSInsertDirectoryNode Inserting entry %p %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2544 &DirEntry->NameInformation.FileName,
2545 DirEntry->ObjectInformation->FileId.Cell,
2546 DirEntry->ObjectInformation->FileId.Volume,
2547 DirEntry->ObjectInformation->FileId.Vnode,
2548 DirEntry->ObjectInformation->FileId.Unique);
2550 if( ParentObjectInfo->Specific.Directory.DirectoryNodeListHead == NULL)
2553 ParentObjectInfo->Specific.Directory.DirectoryNodeListHead = DirEntry;
2558 ParentObjectInfo->Specific.Directory.DirectoryNodeListTail->ListEntry.fLink = (void *)DirEntry;
2560 DirEntry->ListEntry.bLink = (void *)ParentObjectInfo->Specific.Directory.DirectoryNodeListTail;
2563 ParentObjectInfo->Specific.Directory.DirectoryNodeListTail = DirEntry;
2565 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST);
2567 lCount = InterlockedIncrement( &ParentObjectInfo->Specific.Directory.DirectoryNodeCount);
2569 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
2570 AFS_TRACE_LEVEL_VERBOSE,
2571 "AFSInsertDirectoryNode Adding entry %wZ Inc Count %d to parent FID %08lX-%08lX-%08lX-%08lX\n",
2572 &DirEntry->NameInformation.FileName,
2574 ParentObjectInfo->FileId.Cell,
2575 ParentObjectInfo->FileId.Volume,
2576 ParentObjectInfo->FileId.Vnode,
2577 ParentObjectInfo->FileId.Unique);
2585 AFSDeleteDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
2586 IN AFSDirectoryCB *DirEntry)
2594 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2595 AFS_TRACE_LEVEL_VERBOSE,
2596 "AFSDeleteDirEntry Deleting dir entry in parent %p Entry %p %wZ FID %08lX-%08lX-%08lX-%08lX RefCount %d\n",
2599 &DirEntry->NameInformation.FileName,
2600 DirEntry->ObjectInformation->FileId.Cell,
2601 DirEntry->ObjectInformation->FileId.Volume,
2602 DirEntry->ObjectInformation->FileId.Vnode,
2603 DirEntry->ObjectInformation->FileId.Unique,
2604 DirEntry->DirOpenReferenceCount);
2606 ASSERT( DirEntry->DirOpenReferenceCount == 0);
2608 AFSRemoveDirNodeFromParent( ParentObjectInfo,
2613 // Free up the name buffer if it was reallocated
2616 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_RELEASE_NAME_BUFFER))
2619 AFSExFreePoolWithTag( DirEntry->NameInformation.FileName.Buffer, 0);
2622 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER))
2625 AFSExFreePoolWithTag( DirEntry->NameInformation.TargetName.Buffer, 0);
2629 // Dereference the object for this dir entry
2632 lCount = AFSObjectInfoDecrement( DirEntry->ObjectInformation,
2633 AFS_OBJECT_REFERENCE_DIRENTRY);
2635 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2636 AFS_TRACE_LEVEL_VERBOSE,
2637 "AFSDeleteDirEntry Decrement count on object %p Cnt %d\n",
2638 DirEntry->ObjectInformation,
2641 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_DELETED) &&
2642 DirEntry->ObjectInformation->Links == 0)
2645 SetFlag( DirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED);
2648 ExDeleteResourceLite( &DirEntry->NonPaged->Lock);
2650 AFSExFreePoolWithTag( DirEntry->NonPaged, AFS_DIR_ENTRY_NP_TAG);
2653 // Free up the dir entry
2656 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
2657 AFS_TRACE_LEVEL_VERBOSE,
2658 "AFSDeleteDirEntry AFS_DIR_ENTRY_TAG deallocating %p\n",
2661 AFSExFreePoolWithTag( DirEntry, AFS_DIR_ENTRY_TAG);
2666 AFSRemoveDirNodeFromParent( IN AFSObjectInfoCB *ParentObjectInfo,
2667 IN AFSDirectoryCB *DirEntry,
2668 IN BOOLEAN RemoveFromEnumList)
2671 NTSTATUS ntStatus = STATUS_SUCCESS;
2678 ASSERT( ExIsResourceAcquiredExclusiveLite( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock));
2680 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2681 AFS_TRACE_LEVEL_VERBOSE,
2682 "AFSRemoveDirNodeFromParent Removing DirEntry %p %wZ FID %08lX-%08lX-%08lX-%08lX from Parent %p\n",
2684 &DirEntry->NameInformation.FileName,
2685 DirEntry->ObjectInformation->FileId.Cell,
2686 DirEntry->ObjectInformation->FileId.Volume,
2687 DirEntry->ObjectInformation->FileId.Vnode,
2688 DirEntry->ObjectInformation->FileId.Unique,
2691 if( !BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
2694 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2695 AFS_TRACE_LEVEL_VERBOSE,
2696 "AFSRemoveDirNodeFromParent Removing DirEntry %p name %wZ\n",
2698 &DirEntry->NameInformation.FileName);
2700 AFSRemoveNameEntry( ParentObjectInfo,
2706 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2707 AFS_TRACE_LEVEL_VERBOSE,
2708 "AFSRemoveDirNodeFromParent DE %p for %wZ NOT removing entry due to flag set\n",
2710 &DirEntry->NameInformation.FileName);
2714 if( RemoveFromEnumList &&
2715 BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST))
2719 // And remove the entry from the enumeration list
2722 if( DirEntry->ListEntry.fLink == NULL)
2725 ParentObjectInfo->Specific.Directory.DirectoryNodeListTail = (AFSDirectoryCB *)DirEntry->ListEntry.bLink;
2730 ((AFSDirectoryCB *)DirEntry->ListEntry.fLink)->ListEntry.bLink = DirEntry->ListEntry.bLink;
2733 if( DirEntry->ListEntry.bLink == NULL)
2736 ParentObjectInfo->Specific.Directory.DirectoryNodeListHead = (AFSDirectoryCB *)DirEntry->ListEntry.fLink;
2741 ((AFSDirectoryCB *)DirEntry->ListEntry.bLink)->ListEntry.fLink = DirEntry->ListEntry.fLink;
2744 ASSERT( ParentObjectInfo->Specific.Directory.DirectoryNodeCount > 0);
2746 lCount = InterlockedDecrement( &ParentObjectInfo->Specific.Directory.DirectoryNodeCount);
2748 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST);
2750 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
2751 AFS_TRACE_LEVEL_VERBOSE,
2752 "AFSRemoveDirNodeFromParent Removing entry %wZ Dec Count %d to parent FID %08lX-%08lX-%08lX-%08lX\n",
2753 &DirEntry->NameInformation.FileName,
2755 ParentObjectInfo->FileId.Cell,
2756 ParentObjectInfo->FileId.Volume,
2757 ParentObjectInfo->FileId.Vnode,
2758 ParentObjectInfo->FileId.Unique);
2760 DirEntry->ListEntry.fLink = NULL;
2761 DirEntry->ListEntry.bLink = NULL;
2769 AFSFixupTargetName( IN OUT PUNICODE_STRING FileName,
2770 IN OUT PUNICODE_STRING TargetFileName)
2773 NTSTATUS ntStatus = STATUS_SUCCESS;
2774 UNICODE_STRING uniFileName;
2780 // We will process backwards from the end of the name looking
2781 // for the first \ we encounter
2784 uniFileName.Length = FileName->Length;
2785 uniFileName.MaximumLength = FileName->MaximumLength;
2787 uniFileName.Buffer = FileName->Buffer;
2792 if( uniFileName.Buffer[ (uniFileName.Length/sizeof( WCHAR)) - 1] == L'\\')
2796 // Subtract one more character off of the filename if it is not the root
2799 if( uniFileName.Length > sizeof( WCHAR))
2802 uniFileName.Length -= sizeof( WCHAR);
2806 // Now build up the target name
2809 TargetFileName->Length = FileName->Length - uniFileName.Length;
2812 // If we are not on the root then fixup the name
2815 if( uniFileName.Length > sizeof( WCHAR))
2818 TargetFileName->Length -= sizeof( WCHAR);
2820 TargetFileName->Buffer = &uniFileName.Buffer[ (uniFileName.Length/sizeof( WCHAR)) + 1];
2825 TargetFileName->Buffer = &uniFileName.Buffer[ uniFileName.Length/sizeof( WCHAR)];
2829 // Fixup the passed back filename length
2832 FileName->Length = uniFileName.Length;
2834 TargetFileName->MaximumLength = TargetFileName->Length;
2839 uniFileName.Length -= sizeof( WCHAR);
2847 AFSParseName( IN PIRP Irp,
2849 OUT PUNICODE_STRING FileName,
2850 OUT PUNICODE_STRING ParsedFileName,
2851 OUT PUNICODE_STRING RootFileName,
2852 OUT ULONG *ParseFlags,
2853 OUT AFSVolumeCB **VolumeCB,
2854 OUT AFSDirectoryCB **ParentDirectoryCB,
2855 OUT AFSNameArrayHdr **NameArray)
2858 NTSTATUS ntStatus = STATUS_SUCCESS;
2859 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2860 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2861 UNICODE_STRING uniFullName, uniComponentName, uniRemainingPath;
2863 AFSDirectoryCB *pDirEntry = NULL;
2864 USHORT usIndex = 0, usDriveIndex = 0;
2865 AFSCcb *pRelatedCcb = NULL;
2866 AFSNameArrayHdr *pNameArray = NULL, *pRelatedNameArray = NULL;
2867 USHORT usComponentIndex = 0;
2868 USHORT usComponentLength = 0;
2869 AFSVolumeCB *pVolumeCB = NULL;
2870 AFSFcb *pRelatedFcb = NULL;
2871 BOOLEAN bReleaseTreeLock = FALSE;
2872 BOOLEAN bIsAllShare = FALSE;
2879 // Indicate we are opening a root ...
2882 *ParseFlags = AFS_PARSE_FLAG_ROOT_ACCESS;
2884 *ParentDirectoryCB = NULL;
2886 if( pIrpSp->FileObject->RelatedFileObject != NULL)
2889 pRelatedFcb = (AFSFcb *)pIrpSp->FileObject->RelatedFileObject->FsContext;
2891 pRelatedCcb = (AFSCcb *)pIrpSp->FileObject->RelatedFileObject->FsContext2;
2893 pRelatedNameArray = pRelatedCcb->NameArray;
2895 uniFullName = pIrpSp->FileObject->FileName;
2897 ASSERT( pRelatedFcb != NULL);
2900 // No wild cards in the name
2903 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2904 AFS_TRACE_LEVEL_VERBOSE_2,
2905 "AFSParseName (%p) Relative open for %wZ FID %08lX-%08lX-%08lX-%08lX component %wZ\n",
2907 &pRelatedCcb->DirectoryCB->NameInformation.FileName,
2908 pRelatedCcb->DirectoryCB->ObjectInformation->FileId.Cell,
2909 pRelatedCcb->DirectoryCB->ObjectInformation->FileId.Volume,
2910 pRelatedCcb->DirectoryCB->ObjectInformation->FileId.Vnode,
2911 pRelatedCcb->DirectoryCB->ObjectInformation->FileId.Unique,
2914 if( FsRtlDoesNameContainWildCards( &uniFullName))
2917 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2918 AFS_TRACE_LEVEL_ERROR,
2919 "AFSParseName (%p) Component %wZ contains wild cards\n",
2923 try_return( ntStatus = STATUS_OBJECT_NAME_INVALID);
2926 pVolumeCB = pRelatedFcb->ObjectInformation->VolumeCB;
2928 pDirEntry = pRelatedCcb->DirectoryCB;
2930 *FileName = pIrpSp->FileObject->FileName;
2933 // Grab the root node while checking state
2936 AFSAcquireShared( pVolumeCB->VolumeLock,
2939 if( BooleanFlagOn( pVolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
2940 BooleanFlagOn( pVolumeCB->Flags, AFS_VOLUME_FLAGS_OFFLINE))
2944 // The volume has been taken off line so fail the access
2947 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2948 AFS_TRACE_LEVEL_ERROR,
2949 "AFSParseName (%p) Volume %08lX:%08lX OFFLINE/INVALID\n",
2951 pVolumeCB->ObjectInformation.FileId.Cell,
2952 pVolumeCB->ObjectInformation.FileId.Volume);
2954 AFSReleaseResource( pVolumeCB->VolumeLock);
2956 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
2959 if( BooleanFlagOn( pVolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_VERIFY))
2962 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2963 AFS_TRACE_LEVEL_VERBOSE,
2964 "AFSParseName (%p) Verifying root of volume %08lX:%08lX\n",
2966 pVolumeCB->ObjectInformation.FileId.Cell,
2967 pVolumeCB->ObjectInformation.FileId.Volume);
2969 ntStatus = AFSVerifyVolume( (ULONGLONG)PsGetCurrentProcessId(),
2972 if( !NT_SUCCESS( ntStatus))
2975 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2976 AFS_TRACE_LEVEL_ERROR,
2977 "AFSParseName (%p) Failed verification of root Status %08lX\n",
2981 AFSReleaseResource( pVolumeCB->VolumeLock);
2983 try_return( ntStatus);
2987 AFSReleaseResource( pVolumeCB->VolumeLock);
2989 if( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY))
2992 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2993 AFS_TRACE_LEVEL_VERBOSE,
2994 "AFSParseName (%p) Verifying parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2996 &pDirEntry->NameInformation.FileName,
2997 pDirEntry->ObjectInformation->FileId.Cell,
2998 pDirEntry->ObjectInformation->FileId.Volume,
2999 pDirEntry->ObjectInformation->FileId.Vnode,
3000 pDirEntry->ObjectInformation->FileId.Unique);
3003 // Directory TreeLock should be exclusively held
3006 AFSAcquireExcl( pDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
3009 ntStatus = AFSVerifyEntry( AuthGroup,
3012 AFSReleaseResource( pDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
3014 if( !NT_SUCCESS( ntStatus))
3017 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3018 AFS_TRACE_LEVEL_VERBOSE,
3019 "AFSParseName (%p) Failed verification of parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
3021 &pDirEntry->NameInformation.FileName,
3022 pDirEntry->ObjectInformation->FileId.Cell,
3023 pDirEntry->ObjectInformation->FileId.Volume,
3024 pDirEntry->ObjectInformation->FileId.Vnode,
3025 pDirEntry->ObjectInformation->FileId.Unique,
3028 try_return( ntStatus);
3033 // Create our full path name buffer
3036 uniFullName.MaximumLength = pRelatedCcb->FullFileName.Length +
3038 pIrpSp->FileObject->FileName.Length +
3041 uniFullName.Length = 0;
3043 uniFullName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
3044 uniFullName.MaximumLength,
3045 AFS_NAME_BUFFER_THREE_TAG);
3047 if( uniFullName.Buffer == NULL)
3050 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3051 AFS_TRACE_LEVEL_ERROR,
3052 "AFSParseName (%p) Failed to allocate full name buffer\n",
3055 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3058 RtlZeroMemory( uniFullName.Buffer,
3059 uniFullName.MaximumLength);
3061 RtlCopyMemory( uniFullName.Buffer,
3062 pRelatedCcb->FullFileName.Buffer,
3063 pRelatedCcb->FullFileName.Length);
3065 uniFullName.Length = pRelatedCcb->FullFileName.Length;
3067 usComponentIndex = (USHORT)(uniFullName.Length/sizeof( WCHAR));
3069 usComponentLength = pIrpSp->FileObject->FileName.Length;
3071 if( uniFullName.Buffer[ (uniFullName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
3072 pIrpSp->FileObject->FileName.Length > 0 &&
3073 pIrpSp->FileObject->FileName.Buffer[ 0] != L'\\' &&
3074 pIrpSp->FileObject->FileName.Buffer[ 0] != L':')
3077 uniFullName.Buffer[ (uniFullName.Length/sizeof( WCHAR))] = L'\\';
3079 uniFullName.Length += sizeof( WCHAR);
3081 usComponentLength += sizeof( WCHAR);
3084 if( pIrpSp->FileObject->FileName.Length > 0)
3087 RtlCopyMemory( &uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)],
3088 pIrpSp->FileObject->FileName.Buffer,
3089 pIrpSp->FileObject->FileName.Length);
3091 uniFullName.Length += pIrpSp->FileObject->FileName.Length;
3094 *RootFileName = uniFullName;
3097 // We populate up to the current parent
3100 if( pRelatedNameArray == NULL)
3104 // Init and populate our name array
3107 pNameArray = AFSInitNameArray( NULL,
3110 if( pNameArray == NULL)
3113 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3114 AFS_TRACE_LEVEL_VERBOSE,
3115 "AFSParseName (%p) Failed to initialize name array\n",
3118 AFSExFreePoolWithTag( uniFullName.Buffer, 0);
3120 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3123 ntStatus = AFSPopulateNameArray( pNameArray,
3125 pRelatedCcb->DirectoryCB);
3131 // Init and populate our name array
3134 pNameArray = AFSInitNameArray( NULL,
3135 pRelatedNameArray->MaxElementCount);
3137 if( pNameArray == NULL)
3140 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3141 AFS_TRACE_LEVEL_VERBOSE,
3142 "AFSParseName (%p) Failed to initialize name array\n",
3145 AFSExFreePoolWithTag( uniFullName.Buffer, 0);
3147 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3150 ntStatus = AFSPopulateNameArrayFromRelatedArray( pNameArray,
3152 pRelatedCcb->DirectoryCB);
3155 if( !NT_SUCCESS( ntStatus))
3158 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3159 AFS_TRACE_LEVEL_VERBOSE,
3160 "AFSParseName (%p) Failed to populate name array\n",
3163 AFSExFreePoolWithTag( uniFullName.Buffer, 0);
3165 try_return( ntStatus);
3168 ParsedFileName->Length = usComponentLength;
3169 ParsedFileName->MaximumLength = uniFullName.MaximumLength;
3171 ParsedFileName->Buffer = &uniFullName.Buffer[ usComponentIndex];
3174 // Indicate to caller that RootFileName must be freed
3177 SetFlag( *ParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
3179 *NameArray = pNameArray;
3182 // Increment our volume reference count
3185 lCount = AFSVolumeIncrement( pVolumeCB,
3186 AFS_VOLUME_REFERENCE_PARSE_NAME);
3188 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
3189 AFS_TRACE_LEVEL_VERBOSE,
3190 "AFSParseName Increment count on volume %p Cnt %d\n",
3194 *VolumeCB = pVolumeCB;
3196 *ParentDirectoryCB = pDirEntry;
3198 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3199 AFS_TRACE_LEVEL_VERBOSE_2,
3200 "AFSParseName (%p) Returning full name %wZ\n",
3204 try_return( ntStatus);
3208 // No wild cards in the name
3211 uniFullName = pIrpSp->FileObject->FileName;
3213 if( FsRtlDoesNameContainWildCards( &uniFullName) ||
3214 uniFullName.Length < AFSServerName.Length)
3217 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3218 AFS_TRACE_LEVEL_ERROR,
3219 "AFSParseName (%p) Name %wZ contains wild cards or too short\n",
3223 try_return( ntStatus = STATUS_OBJECT_NAME_INVALID);
3227 // The name is a fully qualified name. Parse out the server/share names and
3228 // point to the root qualified name
3229 // First thing is to locate the server name
3232 FsRtlDissectName( uniFullName,
3236 uniFullName = uniRemainingPath;
3239 // This component is the server name we are serving
3242 if( RtlCompareUnicodeString( &uniComponentName,
3248 // Drive letter based name?
3251 uniFullName = pIrpSp->FileObject->FileName;
3253 while( usIndex < uniFullName.Length/sizeof( WCHAR))
3256 if( uniFullName.Buffer[ usIndex] == L':')
3259 uniFullName.Buffer = &uniFullName.Buffer[ usIndex + 2];
3261 uniFullName.Length -= (usIndex + 2) * sizeof( WCHAR);
3263 usDriveIndex = usIndex - 1;
3272 // Do we have the right server name now?
3275 FsRtlDissectName( uniFullName,
3279 uniFullName = uniRemainingPath;
3282 // This component is the server name we are serving
3285 if( RtlCompareUnicodeString( &uniComponentName,
3290 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3291 AFS_TRACE_LEVEL_ERROR,
3292 "AFSParseName (%p) Name %wZ does not have server name\n",
3294 &pIrpSp->FileObject->FileName);
3296 try_return( ntStatus = STATUS_BAD_NETWORK_NAME);
3300 // Validate this drive letter is actively mapped
3303 if( usDriveIndex > 0 &&
3304 !AFSIsDriveMapped( pIrpSp->FileObject->FileName.Buffer[ usDriveIndex]))
3307 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3308 AFS_TRACE_LEVEL_ERROR,
3309 "AFSParseName (%p) Name %wZ contains invalid drive mapping\n",
3311 &pIrpSp->FileObject->FileName);
3313 try_return( ntStatus = STATUS_BAD_NETWORK_NAME);
3317 if( FsRtlDoesNameContainWildCards( &uniFullName))
3320 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3321 AFS_TRACE_LEVEL_ERROR,
3322 "AFSParseName (%p) Component %wZ contains wild cards\n",
3326 try_return( ntStatus = STATUS_OBJECT_NAME_INVALID);
3329 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3330 AFS_TRACE_LEVEL_VERBOSE_2,
3331 "AFSParseName (%p) Processing full name %wZ\n",
3335 if( uniFullName.Length > 0 &&
3336 uniFullName.Buffer[ (uniFullName.Length/sizeof( WCHAR)) - 1] == L'\\')
3339 uniFullName.Length -= sizeof( WCHAR);
3343 // Be sure we are online and ready to go
3346 AFSAcquireShared( AFSGlobalRoot->VolumeLock,
3349 if( BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
3350 BooleanFlagOn( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE))
3354 // The volume has been taken off line so fail the access
3357 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3358 AFS_TRACE_LEVEL_ERROR,
3359 "AFSParseName (%p) Volume %08lX:%08lX OFFLINE/INVALID\n",
3361 AFSGlobalRoot->ObjectInformation.FileId.Cell,
3362 AFSGlobalRoot->ObjectInformation.FileId.Volume);
3364 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3366 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
3369 if( BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_VERIFY))
3372 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3373 AFS_TRACE_LEVEL_VERBOSE,
3374 "AFSParseName (%p) Verifying root of volume %08lX:%08lX\n",
3376 AFSGlobalRoot->ObjectInformation.FileId.Cell,
3377 AFSGlobalRoot->ObjectInformation.FileId.Volume);
3379 ntStatus = AFSVerifyVolume( (ULONGLONG)PsGetCurrentProcessId(),
3382 if( !NT_SUCCESS( ntStatus))
3385 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3386 AFS_TRACE_LEVEL_ERROR,
3387 "AFSParseName (%p) Failed verification of root Status %08lX\n",
3391 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3393 try_return( ntStatus);
3397 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3399 if( !BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
3402 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3403 AFS_TRACE_LEVEL_VERBOSE,
3404 "AFSParseName (%p) Enumerating global root of volume %08lX:%08lX\n",
3406 AFSGlobalRoot->ObjectInformation.FileId.Cell,
3407 AFSGlobalRoot->ObjectInformation.FileId.Volume);
3409 ntStatus = AFSEnumerateGlobalRoot( AuthGroup);
3411 if( !NT_SUCCESS( ntStatus))
3414 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3415 AFS_TRACE_LEVEL_ERROR,
3416 "AFSParseName (%p) Failed enumeraiton of root Status %08lX\n",
3420 try_return( ntStatus);
3425 // Check for the \\Server access and return it as though it were \\Server\Globalroot
3428 if( uniRemainingPath.Buffer == NULL ||
3429 ( uniRemainingPath.Length == sizeof( WCHAR) &&
3430 uniRemainingPath.Buffer[ 0] == L'\\'))
3433 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3434 AFS_TRACE_LEVEL_VERBOSE_2,
3435 "AFSParseName (%p) Returning global root access\n",
3438 lCount = InterlockedIncrement( &AFSGlobalRoot->DirectoryCB->DirOpenReferenceCount);
3440 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3441 AFS_TRACE_LEVEL_VERBOSE,
3442 "AFSParseName Increment2 count on %wZ DE %p Ccb %p Cnt %d\n",
3443 &AFSGlobalRoot->DirectoryCB->NameInformation.FileName,
3444 AFSGlobalRoot->DirectoryCB,
3450 FileName->Length = 0;
3451 FileName->MaximumLength = 0;
3452 FileName->Buffer = NULL;
3454 try_return( ntStatus = STATUS_SUCCESS);
3457 *RootFileName = uniFullName;
3460 // Include the starting \ in the root name
3463 if( RootFileName->Buffer[ 0] != L'\\')
3465 RootFileName->Buffer--;
3466 RootFileName->Length += sizeof( WCHAR);
3467 RootFileName->MaximumLength += sizeof( WCHAR);
3471 // Get the 'share' name
3474 FsRtlDissectName( uniFullName,
3478 if( FsRtlDoesNameContainWildCards( &uniFullName))
3481 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3482 AFS_TRACE_LEVEL_ERROR,
3483 "AFSParseName (%p) Component %wZ contains wild cards\n",
3487 try_return( ntStatus = STATUS_OBJECT_NAME_INVALID);
3491 // If this is the ALL access then perform some additional processing
3494 if( uniComponentName.Length == 0 ||
3495 RtlCompareUnicodeString( &uniComponentName,
3503 // If there is nothing else then get out
3506 if( uniRemainingPath.Buffer == NULL ||
3507 uniRemainingPath.Length == 0 ||
3508 ( uniRemainingPath.Length == sizeof( WCHAR) &&
3509 uniRemainingPath.Buffer[ 0] == L'\\'))
3512 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3513 AFS_TRACE_LEVEL_VERBOSE_2,
3514 "AFSParseName (%p) Returning global root access\n",
3517 lCount = InterlockedIncrement( &AFSGlobalRoot->DirectoryCB->DirOpenReferenceCount);
3519 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3520 AFS_TRACE_LEVEL_VERBOSE,
3521 "AFSParseName Increment3 count on %wZ DE %p Ccb %p Cnt %d\n",
3522 &AFSGlobalRoot->DirectoryCB->NameInformation.FileName,
3523 AFSGlobalRoot->DirectoryCB,
3529 FileName->Length = 0;
3530 FileName->MaximumLength = 0;
3531 FileName->Buffer = NULL;
3533 try_return( ntStatus = STATUS_SUCCESS);
3537 // Process the name again to strip off the ALL portion
3540 uniFullName = uniRemainingPath;
3542 FsRtlDissectName( uniFullName,
3547 // Check for the PIOCtl name
3550 if( RtlCompareUnicodeString( &uniComponentName,
3555 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3556 AFS_TRACE_LEVEL_VERBOSE_2,
3557 "AFSParseName (%p) Returning root PIOCtl access\n",
3560 lCount = InterlockedIncrement( &AFSGlobalRoot->DirectoryCB->DirOpenReferenceCount);
3562 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3563 AFS_TRACE_LEVEL_VERBOSE,
3564 "AFSParseName Increment4 count on %wZ DE %p Ccb %p Cnt %d\n",
3565 &AFSGlobalRoot->DirectoryCB->NameInformation.FileName,
3566 AFSGlobalRoot->DirectoryCB,
3570 ClearFlag( *ParseFlags, AFS_PARSE_FLAG_ROOT_ACCESS);
3574 *FileName = AFSPIOCtlName;
3576 try_return( ntStatus = STATUS_SUCCESS);
3579 else if( (pDirEntry = AFSGetSpecialShareNameEntry( &uniComponentName,
3580 &uniRemainingPath)) != NULL)
3583 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3584 AFS_TRACE_LEVEL_VERBOSE_2,
3585 "AFSParseName (%p) Returning root share name %wZ access\n",
3590 // Add in the full share name to pass back
3593 if( uniRemainingPath.Buffer != NULL)
3597 // This routine strips off the leading slash so add it back in
3600 uniRemainingPath.Buffer--;
3601 uniRemainingPath.Length += sizeof( WCHAR);
3602 uniRemainingPath.MaximumLength += sizeof( WCHAR);
3605 // And the cell name
3608 uniRemainingPath.Buffer -= (uniComponentName.Length/sizeof( WCHAR));
3609 uniRemainingPath.Length += uniComponentName.Length;
3610 uniRemainingPath.MaximumLength += uniComponentName.Length;
3612 uniComponentName = uniRemainingPath;
3617 *FileName = uniComponentName;
3619 ClearFlag( *ParseFlags, AFS_PARSE_FLAG_ROOT_ACCESS);
3621 *ParentDirectoryCB = pDirEntry;
3623 try_return( ntStatus = STATUS_SUCCESS);
3627 // Determine the 'share' we are accessing
3630 ulCRC = AFSGenerateCRC( &uniComponentName,
3633 AFSAcquireShared( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
3636 bReleaseTreeLock = TRUE;
3638 AFSLocateCaseSensitiveDirEntry( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
3642 if( pDirEntry == NULL)
3645 ulCRC = AFSGenerateCRC( &uniComponentName,
3648 AFSLocateCaseInsensitiveDirEntry( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
3652 if( pDirEntry == NULL)
3656 // OK, if this component is a valid short name then try
3657 // a lookup in the short name tree
3660 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
3661 RtlIsNameLegalDOS8Dot3( &uniComponentName,
3666 AFSLocateShortNameDirEntry( AFSGlobalRoot->ObjectInformation.Specific.Directory.ShortNameTree,
3671 if( pDirEntry == NULL)
3675 // Check with the service whether it is a valid cell name
3678 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
3680 bReleaseTreeLock = FALSE;
3682 ntStatus = AFSCheckCellName( AuthGroup,
3686 if( !NT_SUCCESS( ntStatus))
3690 uniRemainingPath.Length == 0 &&
3691 ntStatus == STATUS_OBJECT_PATH_NOT_FOUND)
3694 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3695 AFS_TRACE_LEVEL_VERBOSE,
3696 "AFSParseName (%p) AFSCheckCellName %wZ returned path not found; ntStatus %08X\n",
3699 STATUS_OBJECT_NAME_NOT_FOUND);
3701 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
3704 try_return( ntStatus);
3710 if( bReleaseTreeLock)
3712 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
3717 // Be sure we are starting from the correct volume
3720 if( pDirEntry->ObjectInformation->VolumeCB != AFSGlobalRoot)
3724 // We dropped the global root in the CheckCellName routine which is the
3725 // only way we can be here
3728 pVolumeCB = pDirEntry->ObjectInformation->VolumeCB;
3731 // Init our name array
3734 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
3737 if( pNameArray == NULL)
3740 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3741 AFS_TRACE_LEVEL_VERBOSE,
3742 "AFSParseName (%p) Failed to initialize name array\n",
3745 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3748 ntStatus = AFSInsertNextElement( pNameArray,
3749 pVolumeCB->DirectoryCB);
3754 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3755 AFS_TRACE_LEVEL_VERBOSE,
3756 "AFSParseName (%p) Failed to insert name array element\n",
3759 try_return( ntStatus);
3763 // In this case don't add back in the 'share' name since that is where we are
3764 // starting. Just put the leading slash back in
3767 if( uniRemainingPath.Buffer != NULL)
3770 uniRemainingPath.Buffer--;
3771 uniRemainingPath.Length += sizeof( WCHAR);
3772 uniRemainingPath.MaximumLength += sizeof( WCHAR);
3774 if( uniRemainingPath.Length > sizeof( WCHAR))
3777 ClearFlag( *ParseFlags, AFS_PARSE_FLAG_ROOT_ACCESS);
3781 // Pass back the parent being the root of the volume
3784 *ParentDirectoryCB = pVolumeCB->DirectoryCB;
3790 // Pass back a root slash
3793 uniRemainingPath = uniComponentName;
3795 uniRemainingPath.Buffer--;
3796 uniRemainingPath.Length = sizeof( WCHAR);
3797 uniRemainingPath.MaximumLength = sizeof( WCHAR);
3800 // This is a root open so pass back no parent
3807 pVolumeCB = AFSGlobalRoot;
3810 // Init our name array
3813 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
3815 if( pNameArray == NULL)
3818 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3819 AFS_TRACE_LEVEL_VERBOSE,
3820 "AFSParseName (%p) Failed to initialize name array\n",
3823 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3827 // Add back in the 'share' portion of the name since we will parse it out on return
3830 if( uniRemainingPath.Buffer != NULL)
3834 // This routine strips off the leading slash so add it back in
3837 uniRemainingPath.Buffer--;
3838 uniRemainingPath.Length += sizeof( WCHAR);
3839 uniRemainingPath.MaximumLength += sizeof( WCHAR);
3841 if( uniRemainingPath.Length > sizeof( WCHAR))
3844 ClearFlag( *ParseFlags, AFS_PARSE_FLAG_ROOT_ACCESS);
3848 // And the cell name
3851 uniRemainingPath.Buffer -= (uniComponentName.Length/sizeof( WCHAR));
3852 uniRemainingPath.Length += uniComponentName.Length;
3853 uniRemainingPath.MaximumLength += uniComponentName.Length;
3858 uniRemainingPath = uniComponentName;
3862 // And the leading slash again ...
3865 uniRemainingPath.Buffer--;
3866 uniRemainingPath.Length += sizeof( WCHAR);
3867 uniRemainingPath.MaximumLength += sizeof( WCHAR);
3870 // Pass back the parent being the volume root
3873 *ParentDirectoryCB = pVolumeCB->DirectoryCB;
3877 // Return the remaining portion as the file name
3880 *FileName = uniRemainingPath;
3882 *ParsedFileName = uniRemainingPath;
3884 *NameArray = pNameArray;
3886 *VolumeCB = pVolumeCB;
3889 // Increment our reference on the volume
3892 lCount = AFSVolumeIncrement( pVolumeCB,
3893 AFS_VOLUME_REFERENCE_PARSE_NAME);
3895 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
3896 AFS_TRACE_LEVEL_VERBOSE,
3897 "AFSParseName Increment2 count on global volume %p Cnt %d\n",
3903 if( NT_SUCCESS( ntStatus))
3906 if( *ParentDirectoryCB != NULL)
3909 lCount = InterlockedIncrement( &(*ParentDirectoryCB)->DirOpenReferenceCount);
3911 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3912 AFS_TRACE_LEVEL_VERBOSE,
3913 "AFSParseName Increment1 count on %wZ DE %p Ccb %p Cnt %d\n",
3914 &(*ParentDirectoryCB)->NameInformation.FileName,
3915 (*ParentDirectoryCB),
3921 if( *VolumeCB != NULL)
3923 ASSERT( (*VolumeCB)->VolumeReferenceCount > 0);
3926 if( ntStatus != STATUS_SUCCESS)
3929 if( pNameArray != NULL)
3932 AFSFreeNameArray( pNameArray);
3941 AFSCheckCellName( IN GUID *AuthGroup,
3942 IN UNICODE_STRING *CellName,
3943 OUT AFSDirectoryCB **ShareDirEntry)
3946 NTSTATUS ntStatus = STATUS_SUCCESS;
3947 UNICODE_STRING uniName;
3948 AFSDirEnumEntry *pDirEnumEntry = NULL;
3949 AFSDirHdr *pDirHdr = &AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr;
3950 AFSDirectoryCB *pDirNode = NULL;
3951 UNICODE_STRING uniDirName, uniTargetName;
3952 AFSVolumeCB *pVolumeCB = NULL;
3959 // Look for some default names we will not handle
3962 RtlInitUnicodeString( &uniName,
3965 if( RtlCompareUnicodeString( &uniName,
3970 try_return( ntStatus = STATUS_NO_SUCH_FILE);
3973 RtlInitUnicodeString( &uniName,
3976 if( RtlCompareUnicodeString( &uniName,
3981 try_return( ntStatus = STATUS_NO_SUCH_FILE);
3984 RtlInitUnicodeString( &uniName,
3987 if( RtlCompareUnicodeString( &uniName,
3992 try_return( ntStatus = STATUS_NO_SUCH_FILE);
3995 RtlInitUnicodeString( &uniName,
3998 if( RtlCompareUnicodeString( &uniName,
4003 try_return( ntStatus = STATUS_NO_SUCH_FILE);
4007 // OK, ask the CM about this component name
4010 ntStatus = AFSEvaluateTargetByName( AuthGroup,
4011 &AFSGlobalRoot->ObjectInformation,
4015 if( !NT_SUCCESS( ntStatus))
4018 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4019 AFS_TRACE_LEVEL_WARNING,
4020 "AFSCheckCellName entry %wZ does not exist parent FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4022 AFSGlobalRoot->ObjectInformation.FileId.Cell,
4023 AFSGlobalRoot->ObjectInformation.FileId.Volume,
4024 AFSGlobalRoot->ObjectInformation.FileId.Vnode,
4025 AFSGlobalRoot->ObjectInformation.FileId.Unique,
4028 try_return( ntStatus);
4032 // OK, we have a dir enum entry back so add it to the root node
4035 uniDirName = *CellName;
4037 uniTargetName.Length = (USHORT)pDirEnumEntry->TargetNameLength;
4038 uniTargetName.MaximumLength = uniTargetName.Length;
4039 uniTargetName.Buffer = (WCHAR *)((char *)pDirEnumEntry + pDirEnumEntry->TargetNameOffset);
4042 // Is this entry a root volume entry?
4045 if( pDirEnumEntry->FileId.Cell != AFSGlobalRoot->ObjectInformation.FileId.Cell ||
4046 pDirEnumEntry->FileId.Volume != AFSGlobalRoot->ObjectInformation.FileId.Volume)
4050 // Build the root volume entry
4053 ntStatus = AFSBuildRootVolume( AuthGroup,
4054 &pDirEnumEntry->FileId,
4058 // On success returns with a volume reference count held
4061 if( !NT_SUCCESS( ntStatus))
4063 try_return( ntStatus);
4066 *ShareDirEntry = pVolumeCB->DirectoryCB;
4068 lCount = InterlockedIncrement( &pVolumeCB->DirectoryCB->DirOpenReferenceCount);
4070 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
4071 AFS_TRACE_LEVEL_VERBOSE,
4072 "AFSCheckCellName Increment1 count on %wZ DE %p Ccb %p Cnt %d\n",
4073 &pVolumeCB->DirectoryCB->NameInformation.FileName,
4074 pVolumeCB->DirectoryCB,
4078 lCount = AFSVolumeDecrement( pVolumeCB,
4079 AFS_VOLUME_REFERENCE_BUILD_ROOT);
4081 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
4082 AFS_TRACE_LEVEL_VERBOSE,
4083 "AFSCheckCellName Decrement count on volume %p Cnt %d\n",
4090 lCount = InterlockedIncrement( &pDirHdr->ContentIndex);
4092 pDirNode = AFSInitDirEntry( &AFSGlobalRoot->ObjectInformation,
4098 if( pDirNode == NULL)
4101 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4105 // Init the short name if we have one
4108 if( pDirEnumEntry->ShortNameLength > 0)
4111 pDirNode->NameInformation.ShortNameLength = pDirEnumEntry->ShortNameLength;
4113 RtlCopyMemory( pDirNode->NameInformation.ShortName,
4114 pDirEnumEntry->ShortName,
4115 pDirNode->NameInformation.ShortNameLength);
4118 AFSAcquireExcl( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
4122 // Insert the node into the name tree
4125 ASSERT( ExIsResourceAcquiredExclusiveLite( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock));
4127 if( pDirHdr->CaseSensitiveTreeHead == NULL)
4130 pDirHdr->CaseSensitiveTreeHead = pDirNode;
4135 if( !NT_SUCCESS( AFSInsertCaseSensitiveDirEntry( pDirHdr->CaseSensitiveTreeHead,
4139 AFSDeleteDirEntry( &AFSGlobalRoot->ObjectInformation,
4142 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
4144 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4148 ClearFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
4150 if( pDirHdr->CaseInsensitiveTreeHead == NULL)
4153 pDirHdr->CaseInsensitiveTreeHead = pDirNode;
4155 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
4160 AFSInsertCaseInsensitiveDirEntry( pDirHdr->CaseInsensitiveTreeHead,
4164 if( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListHead == NULL)
4167 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListHead = pDirNode;
4172 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListTail->ListEntry.fLink = pDirNode;
4174 pDirNode->ListEntry.bLink = AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListTail;
4177 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListTail = pDirNode;
4179 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST);
4181 lCount = InterlockedIncrement( &AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeCount);
4183 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
4184 AFS_TRACE_LEVEL_VERBOSE,
4185 "AFSCheckCellName Adding entry %wZ Inc Count %d to parent FID %08lX-%08lX-%08lX-%08lX\n",
4186 &pDirNode->NameInformation.FileName,
4188 AFSGlobalRoot->ObjectInformation.FileId.Cell,
4189 AFSGlobalRoot->ObjectInformation.FileId.Volume,
4190 AFSGlobalRoot->ObjectInformation.FileId.Vnode,
4191 AFSGlobalRoot->ObjectInformation.FileId.Unique);
4193 lCount = InterlockedIncrement( &pDirNode->DirOpenReferenceCount);
4195 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
4196 AFS_TRACE_LEVEL_VERBOSE,
4197 "AFSCheckCellName Increment2 count on %wZ DE %p Ccb %p Cnt %d\n",
4198 &pDirNode->NameInformation.FileName,
4203 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
4206 // Pass back the dir node
4209 *ShareDirEntry = pDirNode;
4214 if( pDirEnumEntry != NULL)
4217 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_31_TAG);
4225 AFSBuildMountPointTarget( IN GUID *AuthGroup,
4226 IN AFSDirectoryCB *DirectoryCB,
4227 OUT AFSVolumeCB **TargetVolumeCB)
4230 NTSTATUS ntStatus = STATUS_SUCCESS;
4231 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
4232 AFSDirEnumEntry *pDirEntry = NULL;
4233 ULONGLONG ullIndex = 0;
4234 AFSVolumeCB *pVolumeCB = NULL;
4235 AFSFileID stTargetFileID;
4237 BOOLEAN bReleaseVolumeLock = FALSE;
4243 // Loop on each entry, building the chain until we encounter the final target
4246 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4247 AFS_TRACE_LEVEL_VERBOSE_2,
4248 "AFSBuildMountPointTarget Building target directory for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4249 &DirectoryCB->NameInformation.FileName,
4250 DirectoryCB->ObjectInformation->FileId.Cell,
4251 DirectoryCB->ObjectInformation->FileId.Volume,
4252 DirectoryCB->ObjectInformation->FileId.Vnode,
4253 DirectoryCB->ObjectInformation->FileId.Unique);
4256 // Do we need to evaluate the node?
4259 //if( DirectoryCB->ObjectInformation->TargetFileId.Vnode == 0 &&
4260 // DirectoryCB->ObjectInformation->TargetFileId.Unique == 0)
4264 // Go evaluate the current target to get the target fid
4267 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4268 AFS_TRACE_LEVEL_VERBOSE_2,
4269 "AFSBuildMountPointTarget Evaluating target %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4270 &DirectoryCB->NameInformation.FileName,
4271 DirectoryCB->ObjectInformation->FileId.Cell,
4272 DirectoryCB->ObjectInformation->FileId.Volume,
4273 DirectoryCB->ObjectInformation->FileId.Vnode,
4274 DirectoryCB->ObjectInformation->FileId.Unique);
4276 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
4281 if( !NT_SUCCESS( ntStatus))
4284 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4285 AFS_TRACE_LEVEL_ERROR,
4286 "AFSBuildMountPointTarget Failed to evaluate target %wZ Status %08lX\n",
4287 &DirectoryCB->NameInformation.FileName,
4289 try_return( ntStatus);
4292 if( pDirEntry->TargetFileId.Vnode == 0 &&
4293 pDirEntry->TargetFileId.Unique == 0)
4296 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4297 AFS_TRACE_LEVEL_ERROR,
4298 "AFSBuildMountPointTarget Target %wZ FID %08lX-%08lX-%08lX-%08lX service returned zero FID\n",
4299 &DirectoryCB->NameInformation.FileName,
4300 DirectoryCB->ObjectInformation->FileId.Cell,
4301 DirectoryCB->ObjectInformation->FileId.Volume,
4302 DirectoryCB->ObjectInformation->FileId.Vnode,
4303 DirectoryCB->ObjectInformation->FileId.Unique);
4305 try_return( ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED);
4308 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
4311 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
4312 &DirectoryCB->Flags,
4313 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
4314 (USHORT)pDirEntry->TargetNameLength);
4316 if( !NT_SUCCESS( ntStatus))
4319 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
4321 try_return( ntStatus);
4324 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
4326 DirectoryCB->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
4329 stTargetFileID = DirectoryCB->ObjectInformation->TargetFileId;
4332 // Try to locate this FID. First the volume then the
4336 ullIndex = AFSCreateHighIndex( &stTargetFileID);
4338 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4339 AFS_TRACE_LEVEL_VERBOSE,
4340 "AFSBuildMountPointTarget Acquiring RDR VolumeTreeLock lock %p EXCL %08lX\n",
4341 &pDevExt->Specific.RDR.VolumeTreeLock,
4342 PsGetCurrentThread());
4344 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock,
4347 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4348 AFS_TRACE_LEVEL_VERBOSE_2,
4349 "AFSBuildMountPointTarget Locating volume for target %I64X\n",
4352 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
4354 (AFSBTreeEntry **)&pVolumeCB);
4357 // We can be processing a request for a target that is on a volume
4358 // we have never seen before.
4361 if( pVolumeCB == NULL)
4365 // Locking is held correctly in init routine
4368 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
4371 // Go init the root of the volume
4374 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4375 AFS_TRACE_LEVEL_VERBOSE_2,
4376 "AFSBuildMountPointTarget Initializing root for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4377 &DirectoryCB->NameInformation.FileName,
4378 DirectoryCB->ObjectInformation->FileId.Cell,
4379 DirectoryCB->ObjectInformation->FileId.Volume,
4380 DirectoryCB->ObjectInformation->FileId.Vnode,
4381 DirectoryCB->ObjectInformation->FileId.Unique);
4383 ntStatus = AFSInitVolume( AuthGroup,
4385 AFS_VOLUME_REFERENCE_MOUNTPT,
4388 if( !NT_SUCCESS( ntStatus))
4391 try_return( ntStatus);
4395 // pVolumeCB->VolumeLock held exclusive and
4396 // pVolumeCB->VolumeReferenceCount has been incremented
4397 // pVolumeCB->RootFcb == NULL
4400 bReleaseVolumeLock = TRUE;
4406 // AFSInitVolume returns with a VolumeReferenceCount
4407 // obtain one to match
4410 lCount = AFSVolumeIncrement( pVolumeCB,
4411 AFS_VOLUME_REFERENCE_MOUNTPT);
4413 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
4414 AFS_TRACE_LEVEL_VERBOSE,
4415 "AFSBuildMountPointTarget Increment count on volume %p Cnt %d\n",
4419 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
4422 if( pVolumeCB->RootFcb == NULL)
4425 if ( bReleaseVolumeLock == FALSE)
4428 AFSAcquireExcl( pVolumeCB->VolumeLock,
4431 bReleaseVolumeLock = TRUE;
4435 // Initialize the root fcb for this volume
4438 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
4441 if( !NT_SUCCESS( ntStatus))
4444 lCount = AFSVolumeDecrement( pVolumeCB,
4445 AFS_VOLUME_REFERENCE_MOUNTPT);
4447 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
4448 AFS_TRACE_LEVEL_VERBOSE,
4449 "AFSBuildMountPoint Decrement count on volume %p Cnt %d\n",
4453 AFSReleaseResource( pVolumeCB->VolumeLock);
4455 try_return( ntStatus);
4459 // Drop the lock acquired above
4462 AFSReleaseResource( &pVolumeCB->RootFcb->NPFcb->Resource);
4465 if ( bReleaseVolumeLock == TRUE)
4468 AFSReleaseResource( pVolumeCB->VolumeLock);
4471 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4472 AFS_TRACE_LEVEL_VERBOSE_2,
4473 "AFSBuildMountPointTarget Evaluated target of %wZ FID %08lX-%08lX-%08lX-%08lX as root volume\n",
4474 &pVolumeCB->DirectoryCB->NameInformation.FileName,
4475 pVolumeCB->ObjectInformation.FileId.Cell,
4476 pVolumeCB->ObjectInformation.FileId.Volume,
4477 pVolumeCB->ObjectInformation.FileId.Vnode,
4478 pVolumeCB->ObjectInformation.FileId.Unique);
4480 *TargetVolumeCB = pVolumeCB;
4487 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
4495 AFSBuildRootVolume( IN GUID *AuthGroup,
4496 IN AFSFileID *FileId,
4497 OUT AFSVolumeCB **TargetVolumeCB)
4500 NTSTATUS ntStatus = STATUS_SUCCESS;
4501 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
4502 ULONGLONG ullIndex = 0;
4503 AFSVolumeCB *pVolumeCB = NULL;
4505 BOOLEAN bReleaseVolumeLock = FALSE;
4510 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4511 AFS_TRACE_LEVEL_VERBOSE_2,
4512 "AFSBuildRootVolume Building target volume for FID %08lX-%08lX-%08lX-%08lX\n",
4518 ullIndex = AFSCreateHighIndex( FileId);
4520 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4521 AFS_TRACE_LEVEL_VERBOSE,
4522 "AFSBuildRootVolume Acquiring RDR VolumeTreeLock lock %p EXCL %08lX\n",
4523 &pDevExt->Specific.RDR.VolumeTreeLock,
4524 PsGetCurrentThread());
4526 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock,
4529 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4530 AFS_TRACE_LEVEL_VERBOSE_2,
4531 "AFSBuildRootVolume Locating volume for target %I64X\n",
4534 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
4536 (AFSBTreeEntry **)&pVolumeCB);
4539 // We can be processing a request for a target that is on a volume
4540 // we have never seen before.
4543 if( pVolumeCB == NULL)
4547 // Locking is held correctly in init routine
4550 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
4553 // Go init the root of the volume
4556 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4557 AFS_TRACE_LEVEL_VERBOSE_2,
4558 "AFSBuildRootVolume Initializing root for FID %08lX-%08lX-%08lX-%08lX\n",
4564 ntStatus = AFSInitVolume( AuthGroup,
4566 AFS_VOLUME_REFERENCE_BUILD_ROOT,
4569 if( !NT_SUCCESS( ntStatus))
4572 try_return( ntStatus);
4576 // pVolumeCB->VolumeLock is held exclusive
4577 // pVolumeCB->VolumeReferenceCount has been incremented
4578 // pVolumeCB->RootFcb == NULL
4581 bReleaseVolumeLock = TRUE;
4587 // AFSInitVolume returns with a VolumeReferenceCount
4588 // obtain one to match
4591 lCount = AFSVolumeIncrement( pVolumeCB,
4592 AFS_VOLUME_REFERENCE_BUILD_ROOT);
4594 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
4595 AFS_TRACE_LEVEL_VERBOSE,
4596 "AFSBuildRootVolume Increment count on volume %p Cnt %d\n",
4600 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
4604 if( pVolumeCB->RootFcb == NULL)
4607 if ( bReleaseVolumeLock == FALSE)
4610 AFSAcquireExcl( pVolumeCB->VolumeLock,
4613 bReleaseVolumeLock = TRUE;
4617 // Initialize the root fcb for this volume
4620 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
4623 if( !NT_SUCCESS( ntStatus))
4626 lCount = AFSVolumeDecrement( pVolumeCB,
4627 AFS_VOLUME_REFERENCE_BUILD_ROOT);
4629 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
4630 AFS_TRACE_LEVEL_VERBOSE,
4631 "AFSBuildRootVolume Decrement count on volume %p Cnt %d\n",
4635 AFSReleaseResource( pVolumeCB->VolumeLock);
4637 try_return( ntStatus);
4641 // Drop the lock acquired above
4644 AFSReleaseResource( &pVolumeCB->RootFcb->NPFcb->Resource);
4647 if ( bReleaseVolumeLock == TRUE)
4650 AFSReleaseResource( pVolumeCB->VolumeLock);
4653 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4654 AFS_TRACE_LEVEL_VERBOSE_2,
4655 "AFSBuildRootVolume Evaluated target of %wZ FID %08lX-%08lX-%08lX-%08lX as root volume\n",
4656 &pVolumeCB->DirectoryCB->NameInformation.FileName,
4657 pVolumeCB->ObjectInformation.FileId.Cell,
4658 pVolumeCB->ObjectInformation.FileId.Volume,
4659 pVolumeCB->ObjectInformation.FileId.Vnode,
4660 pVolumeCB->ObjectInformation.FileId.Unique);
4662 *TargetVolumeCB = pVolumeCB;
4673 AFSProcessDFSLink( IN AFSDirectoryCB *DirEntry,
4674 IN PFILE_OBJECT FileObject,
4675 IN UNICODE_STRING *RemainingPath,
4679 NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
4680 UNICODE_STRING uniReparseName;
4681 UNICODE_STRING uniMUPDeviceName;
4682 UNICODE_STRING uniIOMgrDeviceName;
4683 AFSDirEnumEntry *pDirEntry = NULL;
4689 // Build up the name to reparse
4692 RtlInitUnicodeString( &uniMUPDeviceName,
4695 RtlInitUnicodeString( &uniIOMgrDeviceName,
4698 uniReparseName.Length = 0;
4699 uniReparseName.Buffer = NULL;
4702 // Be sure we have a target name
4705 if( DirEntry->NameInformation.TargetName.Length == 0)
4708 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
4713 if( !NT_SUCCESS( ntStatus) ||
4714 pDirEntry->TargetNameLength == 0)
4717 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4718 AFS_TRACE_LEVEL_ERROR,
4719 "AFSProcessDFSLink EvaluateTargetByID failed for Fcb %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4720 &DirEntry->NameInformation.FileName,
4721 DirEntry->ObjectInformation->FileId.Cell,
4722 DirEntry->ObjectInformation->FileId.Volume,
4723 DirEntry->ObjectInformation->FileId.Vnode,
4724 DirEntry->ObjectInformation->FileId.Unique,
4727 if( NT_SUCCESS( ntStatus))
4730 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
4733 try_return( ntStatus);
4737 // Update the target name
4740 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
4743 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
4745 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
4746 (USHORT)pDirEntry->TargetNameLength);
4748 if( !NT_SUCCESS( ntStatus))
4751 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4752 AFS_TRACE_LEVEL_ERROR,
4753 "AFSProcessDFSLink UpdateTargetName failed for Fcb %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4754 &DirEntry->NameInformation.FileName,
4755 DirEntry->ObjectInformation->FileId.Cell,
4756 DirEntry->ObjectInformation->FileId.Volume,
4757 DirEntry->ObjectInformation->FileId.Vnode,
4758 DirEntry->ObjectInformation->FileId.Unique,
4761 AFSReleaseResource( &DirEntry->NonPaged->Lock);
4763 try_return( ntStatus);
4766 AFSConvertToShared( &DirEntry->NonPaged->Lock);
4770 AFSAcquireShared( &DirEntry->NonPaged->Lock,
4774 uniReparseName.MaximumLength = uniMUPDeviceName.Length +
4776 DirEntry->NameInformation.TargetName.Length +
4779 if( RemainingPath != NULL &&
4780 RemainingPath->Length > 0)
4783 uniReparseName.MaximumLength += RemainingPath->Length;
4787 // Allocate the reparse buffer
4790 uniReparseName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
4791 uniReparseName.MaximumLength,
4792 AFS_REPARSE_NAME_TAG);
4794 if( uniReparseName.Buffer == NULL)
4797 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4798 AFS_TRACE_LEVEL_ERROR,
4799 "AFSProcessDFSLink uniReparseName.Buffer == NULL Fcb %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4800 &DirEntry->NameInformation.FileName,
4801 DirEntry->ObjectInformation->FileId.Cell,
4802 DirEntry->ObjectInformation->FileId.Volume,
4803 DirEntry->ObjectInformation->FileId.Vnode,
4804 DirEntry->ObjectInformation->FileId.Unique,
4805 STATUS_INSUFFICIENT_RESOURCES);
4807 AFSReleaseResource( &DirEntry->NonPaged->Lock);
4809 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4813 // Start building the name
4816 if ( DirEntry->NameInformation.TargetName.Buffer[ 0] != L'\\' &&
4817 DirEntry->NameInformation.TargetName.Buffer[ 1] == L':')
4820 RtlCopyMemory( uniReparseName.Buffer,
4821 uniIOMgrDeviceName.Buffer,
4822 uniIOMgrDeviceName.Length);
4824 uniReparseName.Length = uniIOMgrDeviceName.Length;
4829 RtlCopyMemory( uniReparseName.Buffer,
4830 uniMUPDeviceName.Buffer,
4831 uniMUPDeviceName.Length);
4833 uniReparseName.Length = uniMUPDeviceName.Length;
4835 if( DirEntry->NameInformation.TargetName.Buffer[ 0] != L'\\')
4838 uniReparseName.Buffer[ uniReparseName.Length/sizeof( WCHAR)] = L'\\';
4840 uniReparseName.Length += sizeof( WCHAR);
4844 RtlCopyMemory( &uniReparseName.Buffer[ uniReparseName.Length/sizeof( WCHAR)],
4845 DirEntry->NameInformation.TargetName.Buffer,
4846 DirEntry->NameInformation.TargetName.Length);
4848 uniReparseName.Length += DirEntry->NameInformation.TargetName.Length;
4850 AFSReleaseResource( &DirEntry->NonPaged->Lock);
4852 if( RemainingPath != NULL &&
4853 RemainingPath->Length > 0)
4856 if( uniReparseName.Buffer[ (uniReparseName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
4857 RemainingPath->Buffer[ 0] != L'\\')
4860 uniReparseName.Buffer[ uniReparseName.Length/sizeof( WCHAR)] = L'\\';
4862 uniReparseName.Length += sizeof( WCHAR);
4865 RtlCopyMemory( &uniReparseName.Buffer[ uniReparseName.Length/sizeof( WCHAR)],
4866 RemainingPath->Buffer,
4867 RemainingPath->Length);
4869 uniReparseName.Length += RemainingPath->Length;
4873 // Update the name in the file object
4876 if( FileObject->FileName.Buffer != NULL)
4879 AFSExFreePoolWithTag( FileObject->FileName.Buffer, 0);
4882 FileObject->FileName = uniReparseName;
4884 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4885 AFS_TRACE_LEVEL_VERBOSE,
4886 "AFSProcessDFSLink Reparsing access to Fcb %wZ FID %08lX-%08lX-%08lX-%08lX to %wZ\n",
4887 &DirEntry->NameInformation.FileName,
4888 DirEntry->ObjectInformation->FileId.Cell,
4889 DirEntry->ObjectInformation->FileId.Volume,
4890 DirEntry->ObjectInformation->FileId.Vnode,
4891 DirEntry->ObjectInformation->FileId.Unique,
4895 // Return status reparse ...
4898 ntStatus = STATUS_REPARSE;
4905 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);