2 * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
3 * Copyright (c) 2009, 2010, 2011 Your File System, Inc.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * - Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
14 * this list of conditions and the following disclaimer in the
16 * and/or other materials provided with the distribution.
17 * - Neither the names of Kernel Drivers, LLC and Your File System, Inc.
18 * nor the names of their contributors may be used to endorse or promote
19 * products derived from this software without specific prior written
20 * permission from Kernel Drivers, LLC and Your File System, Inc.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
26 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 // File: AFSNameSupport.cpp
39 #include "AFSCommon.h"
42 AFSLocateNameEntry( IN GUID *AuthGroup,
43 IN PFILE_OBJECT FileObject,
44 IN UNICODE_STRING *RootPathName,
45 IN UNICODE_STRING *ParsedPathName,
46 IN AFSNameArrayHdr *NameArray,
48 IN OUT AFSVolumeCB **VolumeCB,
49 IN OUT AFSDirectoryCB **ParentDirectoryCB,
50 OUT AFSDirectoryCB **DirectoryCB,
51 OUT PUNICODE_STRING ComponentName)
54 NTSTATUS ntStatus = STATUS_SUCCESS;
55 UNICODE_STRING uniPathName, uniComponentName, uniRemainingPath, uniSearchName, uniFullPathName;
57 AFSDirectoryCB *pDirEntry = NULL, *pParentDirEntry = NULL;
58 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
59 UNICODE_STRING uniSysName;
60 ULONG ulSubstituteIndex = 0;
61 BOOLEAN bSubstituteName = FALSE;
62 AFSNameArrayHdr *pNameArray = NameArray;
63 BOOLEAN bAllocatedSymLinkBuffer = FALSE;
64 UNICODE_STRING uniRelativeName, uniNoOpName;
65 AFSObjectInfoCB *pCurrentObject = NULL;
66 AFSObjectInfoCB *pParentObjectInfo = NULL;
67 AFSVolumeCB *pCurrentVolume = *VolumeCB;
68 BOOLEAN bReleaseCurrentVolume = TRUE;
69 BOOLEAN bSubstitutedName = FALSE;
75 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
76 AFS_TRACE_LEVEL_VERBOSE_2,
77 "AFSLocateNameEntry (FO: %p) Processing full name %wZ\n",
81 RtlInitUnicodeString( &uniSysName,
84 RtlInitUnicodeString( &uniRelativeName,
87 RtlInitUnicodeString( &uniNoOpName,
91 // Cleanup some parameters
94 if( ComponentName != NULL)
97 ComponentName->Length = 0;
98 ComponentName->MaximumLength = 0;
99 ComponentName->Buffer = NULL;
103 // We will parse through the filename, locating the directory nodes until we encounter a cache miss
104 // Starting at the root node
107 pParentDirEntry = NULL;
109 pDirEntry = *ParentDirectoryCB;
111 uniPathName = *ParsedPathName;
113 uniFullPathName = *RootPathName;
115 uniComponentName.Length = uniComponentName.MaximumLength = 0;
116 uniComponentName.Buffer = NULL;
118 uniRemainingPath.Length = uniRemainingPath.MaximumLength = 0;
119 uniRemainingPath.Buffer = NULL;
121 uniSearchName.Length = uniSearchName.MaximumLength = 0;
122 uniSearchName.Buffer = NULL;
127 ASSERT( pCurrentVolume->VolumeReferenceCount > 1);
129 ASSERT( pDirEntry->DirOpenReferenceCount > 0);
132 // Check our total link count for this name array
135 if( pNameArray->LinkCount >= (LONG)pDevExt->Specific.RDR.MaxLinkCount)
138 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
141 pCurrentObject = pDirEntry->ObjectInformation;
143 KeQueryTickCount( &pCurrentObject->LastAccessCount);
146 // Check that the directory entry is not deleted or pending delete
149 if( BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED))
152 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
153 AFS_TRACE_LEVEL_ERROR,
154 "AFSLocateNameEntry (FO: %p) Deleted parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
156 &pDirEntry->NameInformation.FileName,
157 pCurrentObject->FileId.Cell,
158 pCurrentObject->FileId.Volume,
159 pCurrentObject->FileId.Vnode,
160 pCurrentObject->FileId.Unique,
161 STATUS_FILE_DELETED);
163 try_return( ntStatus = STATUS_FILE_DELETED);
166 if( BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_PENDING_DELETE))
169 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
170 AFS_TRACE_LEVEL_ERROR,
171 "AFSLocateNameEntry (FO: %p) Delete pending on %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
173 &pDirEntry->NameInformation.FileName,
174 pCurrentObject->FileId.Cell,
175 pCurrentObject->FileId.Volume,
176 pCurrentObject->FileId.Vnode,
177 pCurrentObject->FileId.Unique,
178 STATUS_DELETE_PENDING);
180 try_return( ntStatus = STATUS_DELETE_PENDING);
184 // Check if the directory requires verification
187 if( BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_FLAGS_VERIFY) &&
188 ( pCurrentObject->FileType != AFS_FILE_TYPE_DIRECTORY ||
189 !AFSIsEnumerationInProcess( pCurrentObject)))
192 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
193 AFS_TRACE_LEVEL_VERBOSE,
194 "AFSLocateNameEntry (FO: %p) Verifying parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
196 &pDirEntry->NameInformation.FileName,
197 pCurrentObject->FileId.Cell,
198 pCurrentObject->FileId.Volume,
199 pCurrentObject->FileId.Vnode,
200 pCurrentObject->FileId.Unique);
203 // Directory TreeLock should be exclusively held
206 AFSAcquireExcl( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
209 ntStatus = AFSVerifyEntry( AuthGroup,
212 AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
214 if( !NT_SUCCESS( ntStatus))
217 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
218 AFS_TRACE_LEVEL_ERROR,
219 "AFSLocateNameEntry (FO: %p) Failed to verify parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
221 &pDirEntry->NameInformation.FileName,
222 pCurrentObject->FileId.Cell,
223 pCurrentObject->FileId.Volume,
224 pCurrentObject->FileId.Vnode,
225 pCurrentObject->FileId.Unique,
228 try_return( ntStatus);
233 // Ensure the parent node has been evaluated, if not then go do it now
236 if( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) ||
237 pCurrentObject->FileType == AFS_FILE_TYPE_UNKNOWN)
240 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
241 AFS_TRACE_LEVEL_VERBOSE,
242 "AFSLocateNameEntry (FO: %p) Evaluating parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
244 &pDirEntry->NameInformation.FileName,
245 pCurrentObject->FileId.Cell,
246 pCurrentObject->FileId.Volume,
247 pCurrentObject->FileId.Vnode,
248 pCurrentObject->FileId.Unique);
250 ntStatus = AFSEvaluateNode( AuthGroup,
253 if( !NT_SUCCESS( ntStatus))
256 if ( ntStatus == STATUS_NOT_A_DIRECTORY)
259 if ( pCurrentObject->ParentObjectInformation == NULL)
262 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
263 AFS_TRACE_LEVEL_ERROR,
264 "AFSLocateNameEntry (FO: %p) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT NULL Status %08lX\n",
266 &pDirEntry->NameInformation.FileName,
267 pCurrentObject->FileId.Cell,
268 pCurrentObject->FileId.Volume,
269 pCurrentObject->FileId.Vnode,
270 pCurrentObject->FileId.Unique,
276 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
277 AFS_TRACE_LEVEL_ERROR,
278 "AFSLocateNameEntry (FO: %p) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT %08lX-%08lX-%08lX-%08lX Status %08lX\n",
280 &pDirEntry->NameInformation.FileName,
281 pCurrentObject->FileId.Cell,
282 pCurrentObject->FileId.Volume,
283 pCurrentObject->FileId.Vnode,
284 pCurrentObject->FileId.Unique,
285 pCurrentObject->ParentObjectInformation->FileId.Cell,
286 pCurrentObject->ParentObjectInformation->FileId.Volume,
287 pCurrentObject->ParentObjectInformation->FileId.Vnode,
288 pCurrentObject->ParentObjectInformation->FileId.Unique,
294 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
295 AFS_TRACE_LEVEL_ERROR,
296 "AFSLocateNameEntry (FO: %p) Failed to evaluate parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
298 &pDirEntry->NameInformation.FileName,
299 pCurrentObject->FileId.Cell,
300 pCurrentObject->FileId.Volume,
301 pCurrentObject->FileId.Vnode,
302 pCurrentObject->FileId.Unique,
306 try_return( ntStatus);
309 ClearFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
313 // If this is a mount point or symlink then go get the real directory node
316 switch( pCurrentObject->FileType)
319 case AFS_FILE_TYPE_SYMLINK:
322 UNICODE_STRING uniTempName;
323 WCHAR *pTmpBuffer = NULL;
327 // Check if the flag is set to NOT evaluate a symlink
328 // and we are done with the parsing
331 if( BooleanFlagOn( Flags, AFS_LOCATE_FLAGS_NO_SL_TARGET_EVAL) &&
332 uniRemainingPath.Length == 0)
336 // Pass back the directory entries
339 *ParentDirectoryCB = pParentDirEntry;
341 *DirectoryCB = pDirEntry;
343 *VolumeCB = pCurrentVolume;
345 *RootPathName = uniFullPathName;
347 try_return( ntStatus);
350 AFSAcquireExcl( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
353 AFSAcquireExcl( &pDirEntry->NonPaged->Lock,
356 if( pDirEntry->NameInformation.TargetName.Length == 0)
360 // We'll reset the DV to ensure we validate the metadata content
363 pCurrentObject->DataVersion.QuadPart = (ULONGLONG)-1;
365 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_VERIFY);
367 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
368 AFS_TRACE_LEVEL_VERBOSE,
369 "AFSLocateNameEntry (FO: %p) Verifying symlink parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
371 &pDirEntry->NameInformation.FileName,
372 pCurrentObject->FileId.Cell,
373 pCurrentObject->FileId.Volume,
374 pCurrentObject->FileId.Vnode,
375 pCurrentObject->FileId.Unique);
378 // Directory TreeLock should be exclusively held
381 ntStatus = AFSVerifyEntry( AuthGroup,
384 AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
386 if( !NT_SUCCESS( ntStatus))
389 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
390 AFS_TRACE_LEVEL_ERROR,
391 "AFSLocateNameEntry (FO: %p) Failed to verify symlink parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
393 &pDirEntry->NameInformation.FileName,
394 pCurrentObject->FileId.Cell,
395 pCurrentObject->FileId.Volume,
396 pCurrentObject->FileId.Vnode,
397 pCurrentObject->FileId.Unique,
400 AFSReleaseResource( &pDirEntry->NonPaged->Lock);
402 try_return( ntStatus);
406 // If the type changed then reprocess this entry
409 if( pCurrentObject->FileType != AFS_FILE_TYPE_SYMLINK)
412 AFSReleaseResource( &pDirEntry->NonPaged->Lock);
420 AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
424 // If we were given a zero length target name then deny access to the entry
427 if( pDirEntry->NameInformation.TargetName.Length == 0)
430 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
432 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
433 AFS_TRACE_LEVEL_ERROR,
434 "AFSLocateNameEntry (FO: %p) Failed to retrieve target name for symlink %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
436 &pDirEntry->NameInformation.FileName,
437 pCurrentObject->FileId.Cell,
438 pCurrentObject->FileId.Volume,
439 pCurrentObject->FileId.Vnode,
440 pCurrentObject->FileId.Unique,
443 AFSReleaseResource( &pDirEntry->NonPaged->Lock);
445 try_return( ntStatus);
448 if( AFSIsRelativeName( &pDirEntry->NameInformation.TargetName))
451 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
452 AFS_TRACE_LEVEL_VERBOSE,
453 "AFSLocateNameEntry (FO: %p) Processing relative symlink target %wZ for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
455 &pDirEntry->NameInformation.TargetName,
456 &pDirEntry->NameInformation.FileName,
457 pCurrentObject->FileId.Cell,
458 pCurrentObject->FileId.Volume,
459 pCurrentObject->FileId.Vnode,
460 pCurrentObject->FileId.Unique);
463 // We'll substitute this name into the current process name
464 // starting at where we sit in the path
467 uniTempName.Length = 0;
468 uniTempName.MaximumLength = (USHORT)((char *)uniComponentName.Buffer - (char *)uniFullPathName.Buffer) +
469 pDirEntry->NameInformation.TargetName.Length +
471 uniRemainingPath.Length;
473 uniTempName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
474 uniTempName.MaximumLength,
475 AFS_NAME_BUFFER_ONE_TAG);
477 if( uniTempName.Buffer == NULL)
480 AFSReleaseResource( &pDirEntry->NonPaged->Lock);
482 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
486 // We have so first copy in the portion up to the component
490 RtlCopyMemory( uniTempName.Buffer,
491 uniFullPathName.Buffer,
492 (ULONG)((char *)uniComponentName.Buffer - (char *)uniFullPathName.Buffer));
494 uniTempName.Length = (USHORT)((char *)uniComponentName.Buffer - (char *)uniFullPathName.Buffer);
496 if( bAllocatedSymLinkBuffer ||
500 pTmpBuffer = uniFullPathName.Buffer;
503 bAllocatedSymLinkBuffer = TRUE;
506 // Have we parsed this name yet? Better have at least once ...
509 if( uniComponentName.Length == 0)
515 // Copy in the target name ...
518 RtlCopyMemory( &uniTempName.Buffer[ uniTempName.Length/sizeof( WCHAR)],
519 pDirEntry->NameInformation.TargetName.Buffer,
520 pDirEntry->NameInformation.TargetName.Length);
522 uniPathName.Buffer = &uniTempName.Buffer[ uniTempName.Length/sizeof( WCHAR)];
524 uniPathName.Length += pDirEntry->NameInformation.TargetName.Length;
525 uniPathName.MaximumLength = uniTempName.MaximumLength;
527 uniTempName.Length += pDirEntry->NameInformation.TargetName.Length;
530 // And now any remaining portion of the name
533 if( uniRemainingPath.Length > 0)
536 if( uniRemainingPath.Buffer[ 0] != L'\\')
539 uniRemainingPath.Buffer--;
540 uniRemainingPath.Length += sizeof( WCHAR);
542 uniPathName.Length += sizeof( WCHAR);
545 RtlCopyMemory( &uniTempName.Buffer[ uniTempName.Length/sizeof( WCHAR)],
546 uniRemainingPath.Buffer,
547 uniRemainingPath.Length);
549 uniTempName.Length += uniRemainingPath.Length;
552 uniFullPathName = uniTempName;
554 if( pTmpBuffer != NULL)
557 AFSExFreePoolWithTag( pTmpBuffer, 0);
560 AFSReleaseResource( &pDirEntry->NonPaged->Lock);
563 // Dereference the current entry ..
566 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
568 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
569 AFS_TRACE_LEVEL_VERBOSE,
570 "AFSLocateNameEntry Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
571 &pDirEntry->NameInformation.FileName,
576 ASSERT( lCount >= 0);
579 // OK, need to back up one entry for the correct parent since the current
580 // entry we are on is the symlink itself
583 pDirEntry = AFSBackupEntry( pNameArray);
586 // Increment our reference on this dir entry
589 lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
591 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
592 AFS_TRACE_LEVEL_VERBOSE,
593 "AFSLocateNameEntry Increment1 count on %wZ DE %p Ccb %p Cnt %d\n",
594 &pDirEntry->NameInformation.FileName,
599 if( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_ROOT_VOLUME))
602 pParentDirEntry = NULL;
607 pParentDirEntry = AFSGetParentEntry( pNameArray);
609 ASSERT( pParentDirEntry != pDirEntry);
615 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
616 AFS_TRACE_LEVEL_VERBOSE,
617 "AFSLocateNameEntry (FO: %p) Processing absolute symlink target %wZ for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
619 &pDirEntry->NameInformation.TargetName,
620 &pDirEntry->NameInformation.FileName,
621 pCurrentObject->FileId.Cell,
622 pCurrentObject->FileId.Volume,
623 pCurrentObject->FileId.Vnode,
624 pCurrentObject->FileId.Unique);
626 if ( !AFSIsAbsoluteAFSName( &pDirEntry->NameInformation.TargetName))
629 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
630 AFS_TRACE_LEVEL_ERROR,
631 "AFSLocateNameEntry Name %wZ contains invalid server name\n",
632 &pDirEntry->NameInformation.TargetName);
635 // The correct response would be STATUS_OBJECT_PATH_INVALID
636 // but that prevents cmd.exe from performing a recursive
637 // directory enumeration when opening a directory entry
638 // that represents a symlink to an invalid path is discovered.
641 AFSReleaseResource( &pDirEntry->NonPaged->Lock);
643 try_return( ntStatus = STATUS_OBJECT_PATH_NOT_FOUND);
647 // We'll substitute this name into the current process name
648 // starting at where we sit in the path
651 uniTempName.Length = 0;
652 uniTempName.MaximumLength = pDirEntry->NameInformation.TargetName.Length +
654 uniRemainingPath.Length;
656 uniTempName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
657 uniTempName.MaximumLength,
658 AFS_NAME_BUFFER_TWO_TAG);
660 if( uniTempName.Buffer == NULL)
663 AFSReleaseResource( &pDirEntry->NonPaged->Lock);
665 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
668 if( bAllocatedSymLinkBuffer ||
672 pTmpBuffer = uniFullPathName.Buffer;
675 bAllocatedSymLinkBuffer = TRUE;
678 // Have we parsed this name yet? Better have at least once ...
681 if( uniComponentName.Length == 0)
687 // Copy in the target name ...
690 RtlCopyMemory( uniTempName.Buffer,
691 &pDirEntry->NameInformation.TargetName.Buffer[ AFSMountRootName.Length/sizeof( WCHAR)],
692 pDirEntry->NameInformation.TargetName.Length - AFSMountRootName.Length);
694 uniTempName.Length = pDirEntry->NameInformation.TargetName.Length - AFSMountRootName.Length;
697 // And now any remaining portion of the name
700 if( uniRemainingPath.Length > 0)
703 if( uniRemainingPath.Buffer[ 0] != L'\\')
706 uniRemainingPath.Buffer--;
707 uniRemainingPath.Length += sizeof( WCHAR);
710 RtlCopyMemory( &uniTempName.Buffer[ uniTempName.Length/sizeof( WCHAR)],
711 uniRemainingPath.Buffer,
712 uniRemainingPath.Length);
714 uniTempName.Length += uniRemainingPath.Length;
717 uniFullPathName = uniTempName;
719 uniPathName = uniTempName;
721 if( pTmpBuffer != NULL)
724 AFSExFreePoolWithTag( pTmpBuffer, 0);
727 AFSReleaseResource( &pDirEntry->NonPaged->Lock);
730 // If our current volume is not the global root then make it so ...
733 if( pCurrentVolume != AFSGlobalRoot)
736 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
737 AFS_TRACE_LEVEL_VERBOSE,
738 "AFSLocateNameEntry (FO: %p) Current volume not global, resetting for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
740 &pDirEntry->NameInformation.FileName,
741 pCurrentObject->FileId.Cell,
742 pCurrentObject->FileId.Volume,
743 pCurrentObject->FileId.Vnode,
744 pCurrentObject->FileId.Unique);
746 lCount = InterlockedDecrement( &pCurrentVolume->VolumeReferenceCount);
748 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
749 AFS_TRACE_LEVEL_VERBOSE,
750 "AFSLocateNameEntry Decrement count on volume %p Cnt %d\n",
754 pCurrentVolume = AFSGlobalRoot;
756 lCount = InterlockedIncrement( &pCurrentVolume->VolumeReferenceCount);
758 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
759 AFS_TRACE_LEVEL_VERBOSE,
760 "AFSLocateNameEntry Increment count on volume %p Cnt %d\n",
766 // Dereference our current dir entry
769 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
771 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
772 AFS_TRACE_LEVEL_VERBOSE,
773 "AFSLocateNameEntry Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
774 &pDirEntry->NameInformation.FileName,
779 ASSERT( lCount >= 0);
781 pDirEntry = pCurrentVolume->DirectoryCB;
784 // Reference the new dir entry
787 lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
789 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
790 AFS_TRACE_LEVEL_VERBOSE,
791 "AFSLocateNameEntry Increment2 count on %wZ DE %p Ccb %p Cnt %d\n",
792 &pDirEntry->NameInformation.FileName,
798 // Reset the name array
799 // Persist the link count in the name array
802 lLinkCount = pNameArray->LinkCount;
804 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
805 AFS_TRACE_LEVEL_VERBOSE,
806 "AFSLocateNameEntry (FO: %p) Resetting name array for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
808 &pDirEntry->NameInformation.FileName,
809 pCurrentObject->FileId.Cell,
810 pCurrentObject->FileId.Volume,
811 pCurrentObject->FileId.Vnode,
812 pCurrentObject->FileId.Unique);
814 AFSResetNameArray( pNameArray,
817 pNameArray->LinkCount = lLinkCount;
819 pParentDirEntry = NULL;
823 // Increment our link count
826 lCount = InterlockedIncrement( &pNameArray->LinkCount);
831 case AFS_FILE_TYPE_MOUNTPOINT:
835 // Check if the flag is set to NOT evaluate a mount point
836 // and we are done with the parsing
839 if( BooleanFlagOn( Flags, AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL) &&
840 uniRemainingPath.Length == 0)
844 // Pass back the directory entries
847 *ParentDirectoryCB = pParentDirEntry;
849 *DirectoryCB = pDirEntry;
851 *VolumeCB = pCurrentVolume;
853 *RootPathName = uniFullPathName;
855 try_return( ntStatus);
858 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
859 AFS_TRACE_LEVEL_VERBOSE,
860 "AFSLocateNameEntry (FO: %p) Building MP target for parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
862 &pDirEntry->NameInformation.FileName,
863 pCurrentObject->FileId.Cell,
864 pCurrentObject->FileId.Volume,
865 pCurrentObject->FileId.Vnode,
866 pCurrentObject->FileId.Unique);
869 // Go retrieve the target entry for this node
870 // Release the current volume cb entry since we would
871 // have lock inversion in the following call
872 // Also decrement the ref count on the volume
875 ASSERT( pCurrentVolume->VolumeReferenceCount > 1);
877 lCount = InterlockedDecrement( &pCurrentVolume->VolumeReferenceCount);
879 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
880 AFS_TRACE_LEVEL_VERBOSE,
881 "AFSLocateNameEntry Decrement2 count on volume %p Cnt %d\n",
885 ntStatus = AFSBuildMountPointTarget( AuthGroup,
889 if( !NT_SUCCESS( ntStatus))
892 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
893 AFS_TRACE_LEVEL_ERROR,
894 "AFSLocateNameEntry (FO: %p) Failed to build MP target for parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
896 &pDirEntry->NameInformation.FileName,
897 pCurrentObject->FileId.Cell,
898 pCurrentObject->FileId.Volume,
899 pCurrentObject->FileId.Vnode,
900 pCurrentObject->FileId.Unique,
904 // We already decremented the current volume above
907 bReleaseCurrentVolume = FALSE;
909 try_return( ntStatus);
912 ASSERT( pCurrentVolume->VolumeReferenceCount > 1);
915 // We want to restart processing here on the new parent ...
916 // Deref and ref count the entries
919 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
921 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
922 AFS_TRACE_LEVEL_VERBOSE,
923 "AFSLocateNameEntry Decrement3 count on %wZ DE %p Ccb %p Cnt %d\n",
924 &pDirEntry->NameInformation.FileName,
929 ASSERT( lCount >= 0);
931 pDirEntry = pCurrentVolume->DirectoryCB;
933 lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
935 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
936 AFS_TRACE_LEVEL_VERBOSE,
937 "AFSLocateNameEntry Increment3 count on %wZ DE %p Ccb %p Cnt %d\n",
938 &pDirEntry->NameInformation.FileName,
944 // The name array stores both the mount point and the target.
945 // Insert the target.
948 AFSInsertNextElement( pNameArray,
951 pParentDirEntry = NULL;
954 // Increment our link count
957 lCount = InterlockedIncrement( &pNameArray->LinkCount);
962 case AFS_FILE_TYPE_DFSLINK:
965 if( BooleanFlagOn( Flags, AFS_LOCATE_FLAGS_NO_DFS_LINK_EVAL))
969 // Pass back the directory entries
972 *ParentDirectoryCB = pParentDirEntry;
974 *DirectoryCB = pDirEntry;
976 *VolumeCB = pCurrentVolume;
978 *RootPathName = uniFullPathName;
980 try_return( ntStatus);
984 // This is a DFS link so we need to update the file name and return STATUS_REPARSE to the
985 // system for it to reevaluate it
988 if( FileObject != NULL)
991 ntStatus = AFSProcessDFSLink( pDirEntry,
1000 // This is where we have been re-entered from an NP evaluation call via the BuildBranch()
1004 ntStatus = STATUS_INVALID_PARAMETER;
1007 if( ntStatus != STATUS_SUCCESS &&
1008 ntStatus != STATUS_REPARSE)
1011 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1012 AFS_TRACE_LEVEL_ERROR,
1013 "AFSLocateNameEntry (FO: %p) Failed to process DFSLink parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1015 &pDirEntry->NameInformation.FileName,
1016 pCurrentObject->FileId.Cell,
1017 pCurrentObject->FileId.Volume,
1018 pCurrentObject->FileId.Vnode,
1019 pCurrentObject->FileId.Unique,
1023 try_return( ntStatus);
1026 case AFS_FILE_TYPE_UNKNOWN:
1027 case AFS_FILE_TYPE_INVALID:
1031 // Something was not processed ...
1034 try_return( ntStatus = STATUS_ACCESS_DENIED);
1037 } /* end of switch */
1040 // If the parent is not initialized then do it now
1043 if( pCurrentObject->FileType == AFS_FILE_TYPE_DIRECTORY &&
1044 !BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
1047 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1048 AFS_TRACE_LEVEL_VERBOSE,
1049 "AFSLocateNameEntry (FO: %p) Enumerating parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1051 &pDirEntry->NameInformation.FileName,
1052 pCurrentObject->FileId.Cell,
1053 pCurrentObject->FileId.Volume,
1054 pCurrentObject->FileId.Vnode,
1055 pCurrentObject->FileId.Unique);
1057 AFSAcquireExcl( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
1060 if( !BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
1063 ntStatus = AFSEnumerateDirectory( AuthGroup,
1067 if( !NT_SUCCESS( ntStatus))
1070 AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
1072 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1073 AFS_TRACE_LEVEL_ERROR,
1074 "AFSLocateNameEntry (FO: %p) Failed to enumerate parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1076 &pDirEntry->NameInformation.FileName,
1077 pCurrentObject->FileId.Cell,
1078 pCurrentObject->FileId.Volume,
1079 pCurrentObject->FileId.Vnode,
1080 pCurrentObject->FileId.Unique,
1083 try_return( ntStatus);
1086 SetFlag( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
1089 AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
1091 else if( pCurrentObject->FileType == AFS_FILE_TYPE_FILE)
1094 if( uniPathName.Length > 0)
1097 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1098 AFS_TRACE_LEVEL_ERROR,
1099 "AFSLocateNameEntry (FO: %p) Encountered file node %wZ FID %08lX-%08lX-%08lX-%08lX in path processing\n",
1101 &pDirEntry->NameInformation.FileName,
1102 pCurrentObject->FileId.Cell,
1103 pCurrentObject->FileId.Volume,
1104 pCurrentObject->FileId.Vnode,
1105 pCurrentObject->FileId.Unique);
1107 // The proper error code to return would be STATUS_OBJECT_PATH_INVALID because
1108 // one of the components of the path is not a directory. However, returning
1109 // that error prevents IIS 7 and 7.5 from being able to serve data out of AFS.
1110 // Instead IIS insists on treating the target file as if it is a directory containing
1111 // a potential web.config file. NTFS and LanMan return STATUS_OBJECT_PATH_NOT_FOUND.
1112 // AFS will follow suit.
1114 ntStatus = STATUS_OBJECT_PATH_NOT_FOUND;
1119 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1120 AFS_TRACE_LEVEL_VERBOSE,
1121 "AFSLocateNameEntry (FO: %p) Returning file %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1123 &pDirEntry->NameInformation.FileName,
1124 pCurrentObject->FileId.Cell,
1125 pCurrentObject->FileId.Volume,
1126 pCurrentObject->FileId.Vnode,
1127 pCurrentObject->FileId.Unique);
1130 // Pass back the directory entries
1133 *ParentDirectoryCB = pParentDirEntry;
1135 *DirectoryCB = pDirEntry;
1137 *VolumeCB = pCurrentVolume;
1139 *RootPathName = uniFullPathName;
1142 try_return( ntStatus);
1146 // If we are at the end of the processing, set our returned information and get out
1149 if( uniPathName.Length == 0)
1152 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1153 AFS_TRACE_LEVEL_VERBOSE,
1154 "AFSLocateNameEntry (FO: %p) Completed processing returning %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1156 &pDirEntry->NameInformation.FileName,
1157 pCurrentObject->FileId.Cell,
1158 pCurrentObject->FileId.Volume,
1159 pCurrentObject->FileId.Vnode,
1160 pCurrentObject->FileId.Unique);
1163 // Pass back the directory entries
1166 *ParentDirectoryCB = pParentDirEntry;
1168 *DirectoryCB = pDirEntry;
1170 *VolumeCB = pCurrentVolume;
1172 *RootPathName = uniFullPathName;
1174 try_return( ntStatus);
1178 // We may have returned to the top of the while( TRUE)
1180 if( bSubstituteName &&
1181 uniSearchName.Buffer != NULL)
1184 AFSExFreePoolWithTag( uniSearchName.Buffer, 0);
1186 bSubstituteName = FALSE;
1188 uniSearchName.Length = uniSearchName.MaximumLength = 0;
1189 uniSearchName.Buffer = NULL;
1192 ulSubstituteIndex = 1;
1194 ntStatus = STATUS_SUCCESS;
1197 // Get the next component name
1200 FsRtlDissectName( uniPathName,
1205 // Check for the . and .. in the path
1208 if( RtlCompareUnicodeString( &uniComponentName,
1213 uniPathName = uniRemainingPath;
1218 if( RtlCompareUnicodeString( &uniComponentName,
1223 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1224 AFS_TRACE_LEVEL_VERBOSE,
1225 "AFSLocateNameEntry (FO: %p) Backing up entry from %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1227 &pDirEntry->NameInformation.FileName,
1228 pCurrentObject->FileId.Cell,
1229 pCurrentObject->FileId.Volume,
1230 pCurrentObject->FileId.Vnode,
1231 pCurrentObject->FileId.Unique);
1234 // Need to back up one entry in the name array
1236 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
1238 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1239 AFS_TRACE_LEVEL_VERBOSE,
1240 "AFSLocateNameEntry Decrement4 count on %wZ DE %p Ccb %p Cnt %d\n",
1241 &pDirEntry->NameInformation.FileName,
1246 ASSERT( lCount >= 0);
1248 pDirEntry = AFSBackupEntry( NameArray);
1250 if( pDirEntry == NULL)
1253 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1254 AFS_TRACE_LEVEL_ERROR,
1255 "AFSLocateNameEntry AFSBackupEntry failed\n");
1257 try_return(ntStatus = STATUS_OBJECT_PATH_INVALID);
1260 lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
1262 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1263 AFS_TRACE_LEVEL_VERBOSE,
1264 "AFSLocateNameEntry Increment4 count on %wZ DE %p Ccb %p Cnt %d\n",
1265 &pDirEntry->NameInformation.FileName,
1270 if( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_ROOT_VOLUME))
1273 pParentDirEntry = NULL;
1278 pParentDirEntry = AFSGetParentEntry( pNameArray);
1280 ASSERT( pParentDirEntry != pDirEntry);
1283 uniPathName = uniRemainingPath;
1289 // Update our pointers
1292 pParentDirEntry = pDirEntry;
1296 uniSearchName = uniComponentName;
1298 while( pDirEntry == NULL)
1302 // If the SearchName contains @SYS then we perform the substitution.
1303 // If there is no substitution we give up.
1306 if( !bSubstituteName &&
1307 FsRtlIsNameInExpression( &uniSysName,
1313 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1314 AFS_TRACE_LEVEL_VERBOSE_2,
1315 "AFSLocateNameEntry (FO: %p) Processing @SYS substitution for %wZ Index %08lX\n",
1320 ntStatus = AFSSubstituteSysName( &uniComponentName,
1324 if ( NT_SUCCESS( ntStatus))
1327 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1328 AFS_TRACE_LEVEL_VERBOSE_2,
1329 "AFSLocateNameEntry (FO: %p) Located substitution %wZ for %wZ Index %08lX\n",
1336 // Go reparse the name again
1339 bSubstituteName = TRUE;
1341 ulSubstituteIndex++; // For the next entry, if needed
1343 continue; // while( pDirEntry == NULL)
1348 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1349 AFS_TRACE_LEVEL_ERROR,
1350 "AFSLocateNameEntry (FO: %p) Failed to locate substitute string for %wZ Index %08lX Status %08lX\n",
1356 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
1360 // Pass back the directory entries
1363 *ParentDirectoryCB = pParentDirEntry;
1365 *DirectoryCB = NULL;
1367 *VolumeCB = pCurrentVolume;
1369 if( ComponentName != NULL)
1372 *ComponentName = uniComponentName;
1375 *RootPathName = uniFullPathName;
1379 // We can't possibly have a pDirEntry since the lookup failed
1381 try_return( ntStatus);
1386 // Generate the CRC on the node and perform a case sensitive lookup
1389 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1390 AFS_TRACE_LEVEL_VERBOSE_2,
1391 "AFSLocateNameEntry (FO: %p) Searching for entry %wZ case sensitive\n",
1395 ulCRC = AFSGenerateCRC( &uniSearchName,
1398 AFSAcquireShared( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
1401 AFSLocateCaseSensitiveDirEntry( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
1405 if( pDirEntry == NULL)
1409 // Missed so perform a case insensitive lookup
1412 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1413 AFS_TRACE_LEVEL_VERBOSE_2,
1414 "AFSLocateNameEntry (FO: %p) Searching for entry %wZ case insensitive\n",
1418 ulCRC = AFSGenerateCRC( &uniSearchName,
1421 AFSLocateCaseInsensitiveDirEntry( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
1425 if( pDirEntry == NULL)
1429 // OK, if this component is a valid short name then try
1430 // a lookup in the short name tree
1433 if( !BooleanFlagOn( pDevExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
1434 RtlIsNameLegalDOS8Dot3( &uniSearchName,
1439 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1440 AFS_TRACE_LEVEL_VERBOSE_2,
1441 "AFSLocateNameEntry (FO: %p) Searching for entry %wZ short name\n",
1445 AFSLocateShortNameDirEntry( pParentDirEntry->ObjectInformation->Specific.Directory.ShortNameTree,
1450 if ( pDirEntry == NULL &&
1451 pParentDirEntry->ObjectInformation->VolumeCB == AFSGlobalRoot)
1455 // Check with the service to see if this is a valid cell name
1456 // that can be automatically resolved. Drop the shared TreeLock
1457 // since AFSCheckCellName must acquire it exclusively.
1460 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1462 ntStatus = AFSCheckCellName( AuthGroup,
1466 AFSAcquireShared( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
1470 if( pDirEntry == NULL)
1474 // If we substituted a name then reset our search name and try again
1477 if( bSubstituteName)
1480 AFSExFreePoolWithTag( uniSearchName.Buffer, 0);
1482 uniSearchName = uniComponentName;
1484 bSubstituteName = FALSE;
1486 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1488 continue; // while( pDirEntry == NULL)
1491 if( uniRemainingPath.Length > 0)
1494 ntStatus = STATUS_OBJECT_PATH_NOT_FOUND;
1499 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
1501 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1502 AFS_TRACE_LEVEL_VERBOSE,
1503 "AFSLocateNameEntry (FO: %p) Returning name not found for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1506 pCurrentObject->FileId.Cell,
1507 pCurrentObject->FileId.Volume,
1508 pCurrentObject->FileId.Vnode,
1509 pCurrentObject->FileId.Unique);
1512 // Pass back the directory entries
1515 *ParentDirectoryCB = pParentDirEntry;
1517 *DirectoryCB = NULL;
1519 *VolumeCB = pCurrentVolume;
1521 if( ComponentName != NULL)
1524 *ComponentName = uniComponentName;
1527 *RootPathName = uniFullPathName;
1530 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1533 // Node name not found so get out
1536 try_return( ntStatus); // while( pDirEntry == NULL)
1543 // Here we have a match on the case insensitive lookup for the name. If there
1544 // Is more than one link entry for this node then fail the lookup request
1547 if( !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD) ||
1548 pDirEntry->CaseInsensitiveList.fLink != NULL)
1552 // Increment our dir entry ref count since we will decrement it on exit
1555 lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
1557 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1558 AFS_TRACE_LEVEL_VERBOSE,
1559 "AFSLocateNameEntry Increment5 count on %wZ DE %p Ccb %p Cnt %d\n",
1560 &pDirEntry->NameInformation.FileName,
1565 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1567 try_return(ntStatus = STATUS_OBJECT_NAME_COLLISION);
1572 if( pDirEntry != NULL)
1576 // If the verify flag is set on the parent and the current entry is deleted
1577 // revalidate the parent and search again.
1580 if( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED) &&
1581 BooleanFlagOn( pParentDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY))
1584 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1586 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1587 AFS_TRACE_LEVEL_VERBOSE,
1588 "AFSLocateNameEntry (FO: %p) Verifying(2) parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1590 &pParentDirEntry->NameInformation.FileName,
1591 pParentDirEntry->ObjectInformation->FileId.Cell,
1592 pParentDirEntry->ObjectInformation->FileId.Volume,
1593 pParentDirEntry->ObjectInformation->FileId.Vnode,
1594 pParentDirEntry->ObjectInformation->FileId.Unique);
1597 // Directory TreeLock should be exclusively held
1600 AFSAcquireExcl( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
1603 ntStatus = AFSVerifyEntry( AuthGroup,
1606 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1608 if( !NT_SUCCESS( ntStatus))
1611 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1612 AFS_TRACE_LEVEL_ERROR,
1613 "AFSLocateNameEntry (FO: %p) Failed to verify(2) parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1615 &pParentDirEntry->NameInformation.FileName,
1616 pParentDirEntry->ObjectInformation->FileId.Cell,
1617 pParentDirEntry->ObjectInformation->FileId.Volume,
1618 pParentDirEntry->ObjectInformation->FileId.Vnode,
1619 pParentDirEntry->ObjectInformation->FileId.Unique,
1622 try_return( ntStatus);
1625 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1626 AFS_TRACE_LEVEL_VERBOSE,
1627 "AFSLocateNameEntry (FO: %p) Reprocessing component %wZ in parent %wZ\n",
1630 &pParentDirEntry->NameInformation.FileName);
1639 // Increment our dir entry ref count
1642 lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
1644 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1645 AFS_TRACE_LEVEL_VERBOSE,
1646 "AFSLocateNameEntry Increment5 count on %wZ DE %p Ccb %p Cnt %d\n",
1647 &pDirEntry->NameInformation.FileName,
1653 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1655 } // End while( pDirEntry == NULL)
1658 // If we have a dirEntry for this component, perform some basic validation on it
1661 if( pDirEntry != NULL &&
1662 BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
1665 pCurrentObject = pDirEntry->ObjectInformation;
1667 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1668 AFS_TRACE_LEVEL_ERROR,
1669 "AFSLocateNameEntry (FO: %p) Deleted entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1671 &pDirEntry->NameInformation.FileName,
1672 pCurrentObject->FileId.Cell,
1673 pCurrentObject->FileId.Volume,
1674 pCurrentObject->FileId.Vnode,
1675 pCurrentObject->FileId.Unique);
1678 // This entry was deleted through the invalidation call back so perform cleanup
1682 pParentObjectInfo = pCurrentObject->ParentObjectInformation;
1684 ASSERT( pParentObjectInfo != NULL);
1686 AFSAcquireExcl( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
1689 AFSAcquireExcl( pCurrentObject->VolumeCB->ObjectInfoTree.TreeLock,
1692 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
1694 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1695 AFS_TRACE_LEVEL_VERBOSE,
1696 "AFSLocateNameEntry Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
1697 &pDirEntry->NameInformation.FileName,
1702 ASSERT( lCount >= 0);
1707 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING|AFS_SUBSYSTEM_CLEANUP_PROCESSING,
1708 AFS_TRACE_LEVEL_VERBOSE,
1709 "AFSLocateNameEntry Deleting dir entry %p (%p) for %wZ\n",
1712 &pDirEntry->NameInformation.FileName);
1715 // Remove and delete the directory entry from the parent list
1718 AFSDeleteDirEntry( pParentObjectInfo,
1721 AFSAcquireShared( &pCurrentObject->NonPagedInfo->ObjectInfoLock,
1724 if( pCurrentObject->ObjectReferenceCount <= 0)
1727 if( BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_INSERTED_HASH_TREE))
1730 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
1731 AFS_TRACE_LEVEL_VERBOSE,
1732 "AFSLocateNameEntry Removing object %p from volume tree\n",
1735 AFSRemoveHashEntry( &pCurrentObject->VolumeCB->ObjectInfoTree.TreeHead,
1736 &pCurrentObject->TreeEntry);
1738 ClearFlag( pCurrentObject->Flags, AFS_OBJECT_INSERTED_HASH_TREE);
1742 AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock);
1747 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1748 AFS_TRACE_LEVEL_VERBOSE,
1749 "AFSLocateNameEntry Setting DELETE flag in dir entry %p for %wZ\n",
1751 &pDirEntry->NameInformation.FileName);
1753 SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
1755 AFSRemoveNameEntry( pParentObjectInfo,
1759 AFSReleaseResource( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
1761 AFSReleaseResource( pCurrentObject->VolumeCB->ObjectInfoTree.TreeLock);
1764 // We deleted the dir entry so check if there is any remaining portion
1765 // of the name to process.
1768 if( uniRemainingPath.Length > 0)
1770 ntStatus = STATUS_OBJECT_PATH_NOT_FOUND;
1775 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
1777 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1778 AFS_TRACE_LEVEL_VERBOSE,
1779 "AFSLocateNameEntry (FO: %p) Returning name not found(2) for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1782 pCurrentObject->FileId.Cell,
1783 pCurrentObject->FileId.Volume,
1784 pCurrentObject->FileId.Vnode,
1785 pCurrentObject->FileId.Unique);
1788 // Pass back the directory entries
1791 *ParentDirectoryCB = pParentDirEntry;
1793 *DirectoryCB = NULL;
1795 *VolumeCB = pCurrentVolume;
1797 if( ComponentName != NULL)
1800 *ComponentName = uniComponentName;
1803 *RootPathName = uniFullPathName;
1807 if( ntStatus != STATUS_SUCCESS)
1810 try_return( ntStatus);
1814 // Decrement the previous parent
1817 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
1819 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1820 AFS_TRACE_LEVEL_VERBOSE,
1821 "AFSLocateNameEntry Decrement5 count on Parent %wZ DE %p Ccb %p Cnt %d\n",
1822 &pParentDirEntry->NameInformation.FileName,
1827 ASSERT( lCount >= 0);
1830 // If we ended up substituting a name in the component then update
1831 // the full path and update the pointers
1834 if( bSubstituteName)
1837 BOOLEAN bRelativeOpen = FALSE;
1839 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1840 AFS_TRACE_LEVEL_VERBOSE_2,
1841 "AFSLocateNameEntry (FO: %p) Substituting %wZ into %wZ Index %08lX\n",
1847 if( FileObject != NULL &&
1848 FileObject->RelatedFileObject != NULL)
1851 bRelativeOpen = TRUE;
1855 // AFSSubstituteNameInPath will replace the uniFullPathName.Buffer
1856 // and free the prior Buffer contents but only if the fourth
1857 // parameter is TRUE.
1860 ntStatus = AFSSubstituteNameInPath( &uniFullPathName,
1865 bAllocatedSymLinkBuffer ||
1868 if( !NT_SUCCESS( ntStatus))
1871 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1872 AFS_TRACE_LEVEL_ERROR,
1873 "AFSLocateNameEntry (FO: %p) Failure to substitute %wZ into %wZ Index %08lX Status %08lX\n",
1880 try_return( ntStatus);
1884 // We have substituted a name into the buffer so if we do this again for this
1885 // path, we need to free up the buffer we allocated.
1888 bSubstitutedName = TRUE;
1892 // Update the search parameters
1895 uniPathName = uniRemainingPath;
1898 // Check if the is a SymLink entry but has no Target FileID or Name. In this
1899 // case it might be a DFS Link so let's go and evaluate it to be sure
1902 if( pCurrentObject->FileType == AFS_FILE_TYPE_SYMLINK &&
1903 ( pCurrentObject->TargetFileId.Vnode == 0 ||
1904 pDirEntry->NameInformation.TargetName.Length == 0))
1907 ntStatus = AFSValidateSymLink( AuthGroup,
1910 if( !NT_SUCCESS( ntStatus))
1913 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1914 AFS_TRACE_LEVEL_ERROR,
1915 "AFSLocateNameEntry (FO: %p) Failed to evaluate possible DFS Link %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1917 &pDirEntry->NameInformation.FileName,
1918 pCurrentObject->FileId.Cell,
1919 pCurrentObject->FileId.Volume,
1920 pCurrentObject->FileId.Vnode,
1921 pCurrentObject->FileId.Unique,
1924 try_return( ntStatus);
1929 // Update the name array
1932 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1933 AFS_TRACE_LEVEL_VERBOSE,
1934 "AFSLocateNameEntry (FO: %p) Inserting name array entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1936 &pDirEntry->NameInformation.FileName,
1937 pCurrentObject->FileId.Cell,
1938 pCurrentObject->FileId.Volume,
1939 pCurrentObject->FileId.Vnode,
1940 pCurrentObject->FileId.Unique);
1942 ntStatus = AFSInsertNextElement( pNameArray,
1945 if( !NT_SUCCESS( ntStatus))
1948 try_return( ntStatus);
1954 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1955 AFS_TRACE_LEVEL_VERBOSE,
1956 "AFSLocateNameEntry (FO: %p) Completed processing %wZ Status %08lX\n",
1961 if( ( !NT_SUCCESS( ntStatus) &&
1962 ntStatus != STATUS_OBJECT_NAME_NOT_FOUND) ||
1963 ntStatus == STATUS_REPARSE)
1966 if( pDirEntry != NULL)
1969 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
1971 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1972 AFS_TRACE_LEVEL_VERBOSE,
1973 "AFSLocateNameEntry Decrement6 count on %wZ DE %p Ccb %p Cnt %d\n",
1974 &pDirEntry->NameInformation.FileName,
1979 ASSERT( lCount >= 0);
1981 else if( pParentDirEntry != NULL)
1984 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
1986 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1987 AFS_TRACE_LEVEL_VERBOSE,
1988 "AFSLocateNameEntry Decrement7 count on %wZ DE %p Ccb %p Cnt %d\n",
1989 &pParentDirEntry->NameInformation.FileName,
1994 ASSERT( lCount >= 0);
1997 if( bReleaseCurrentVolume)
2000 ASSERT( pCurrentVolume->VolumeReferenceCount > 1);
2002 lCount = InterlockedDecrement( &pCurrentVolume->VolumeReferenceCount);
2004 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2005 AFS_TRACE_LEVEL_VERBOSE,
2006 "AFSLocateNameEntry Decrement3 count on volume %p Cnt %d\n",
2011 if( RootPathName->Buffer != uniFullPathName.Buffer)
2014 AFSExFreePoolWithTag( uniFullPathName.Buffer, 0);
2020 if( *ParentDirectoryCB != NULL)
2023 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2024 AFS_TRACE_LEVEL_VERBOSE,
2025 "AFSLocateNameEntry Count on Parent %wZ DE %p Ccb %p Cnt %d\n",
2026 &(*ParentDirectoryCB)->NameInformation.FileName,
2029 (*ParentDirectoryCB)->DirOpenReferenceCount);
2032 if( *DirectoryCB != NULL)
2035 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2036 AFS_TRACE_LEVEL_VERBOSE,
2037 "AFSLocateNameEntry Count on %wZ DE %p Ccb %p Cnt %d\n",
2038 &(*DirectoryCB)->NameInformation.FileName,
2041 (*DirectoryCB)->DirOpenReferenceCount);
2045 if( bSubstituteName &&
2046 uniSearchName.Buffer != NULL)
2049 AFSExFreePoolWithTag( uniSearchName.Buffer, 0);
2057 AFSCreateDirEntry( IN GUID *AuthGroup,
2058 IN AFSObjectInfoCB *ParentObjectInfo,
2059 IN AFSDirectoryCB *ParentDirCB,
2060 IN PUNICODE_STRING FileName,
2061 IN PUNICODE_STRING ComponentName,
2062 IN ULONG Attributes,
2063 IN OUT AFSDirectoryCB **DirEntry)
2066 UNREFERENCED_PARAMETER(FileName);
2067 NTSTATUS ntStatus = STATUS_SUCCESS;
2068 AFSDirectoryCB *pDirNode = NULL, *pExistingDirNode = NULL;
2069 LARGE_INTEGER liFileSize = {0,0};
2075 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2076 AFS_TRACE_LEVEL_VERBOSE_2,
2077 "AFSCreateDirEntry Creating dir entry in parent %wZ FID %08lX-%08lX-%08lX-%08lX Component %wZ Attribs %08lX\n",
2078 &ParentDirCB->NameInformation.FileName,
2079 ParentObjectInfo->FileId.Cell,
2080 ParentObjectInfo->FileId.Volume,
2081 ParentObjectInfo->FileId.Vnode,
2082 ParentObjectInfo->FileId.Unique,
2087 // OK, before inserting the node into the parent tree, issue
2088 // the request to the service for node creation
2089 // We will need to drop the lock on the parent node since the create
2090 // could cause a callback into the file system to invalidate it's cache
2093 ntStatus = AFSNotifyFileCreate( AuthGroup,
2101 // If the returned status is STATUS_REPARSE then the entry exists
2102 // and we raced, get out.
2104 if( ntStatus == STATUS_REPARSE)
2107 *DirEntry = pDirNode;
2109 try_return( ntStatus = STATUS_SUCCESS);
2112 if( !NT_SUCCESS( ntStatus))
2115 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2116 AFS_TRACE_LEVEL_ERROR,
2117 "AFSCreateDirEntry Failed to create dir entry in parent %wZ FID %08lX-%08lX-%08lX-%08lX Component %wZ Attribs %08lX Status %08lX\n",
2118 &ParentDirCB->NameInformation.FileName,
2119 ParentObjectInfo->FileId.Cell,
2120 ParentObjectInfo->FileId.Volume,
2121 ParentObjectInfo->FileId.Vnode,
2122 ParentObjectInfo->FileId.Unique,
2127 try_return( ntStatus);
2130 AFSAcquireExcl( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2134 // Before attempting to insert the new entry, check if we need to validate the parent
2137 if( BooleanFlagOn( ParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY))
2140 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2141 AFS_TRACE_LEVEL_VERBOSE,
2142 "AFSCreateDirEntry Verifying parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2143 &ParentDirCB->NameInformation.FileName,
2144 ParentObjectInfo->FileId.Cell,
2145 ParentObjectInfo->FileId.Volume,
2146 ParentObjectInfo->FileId.Vnode,
2147 ParentObjectInfo->FileId.Unique);
2149 ntStatus = AFSVerifyEntry( AuthGroup,
2152 if( !NT_SUCCESS( ntStatus))
2155 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2156 AFS_TRACE_LEVEL_ERROR,
2157 "AFSCreateDirEntry Failed to verify parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2158 &ParentDirCB->NameInformation.FileName,
2159 ParentObjectInfo->FileId.Cell,
2160 ParentObjectInfo->FileId.Volume,
2161 ParentObjectInfo->FileId.Vnode,
2162 ParentObjectInfo->FileId.Unique,
2165 AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2167 try_return( ntStatus);
2172 // Check for the entry in the event we raced with some other thread
2175 AFSLocateCaseSensitiveDirEntry( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
2176 (ULONG)pDirNode->CaseSensitiveTreeEntry.HashIndex,
2179 if( pExistingDirNode != NULL)
2181 if (AFSIsEqualFID( &pDirNode->ObjectInformation->FileId,
2182 &pExistingDirNode->ObjectInformation->FileId))
2185 AFSDeleteDirEntry( ParentObjectInfo,
2188 lCount = InterlockedIncrement( &pExistingDirNode->DirOpenReferenceCount);
2190 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2191 AFS_TRACE_LEVEL_VERBOSE,
2192 "AFSCreateDirEntry Increment count on %wZ DE %p Cnt %d\n",
2193 &pExistingDirNode->NameInformation.FileName,
2197 *DirEntry = pExistingDirNode;
2199 AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2201 try_return( ntStatus = STATUS_SUCCESS);
2207 // Need to tear down this entry and rebuild it below
2210 if( pExistingDirNode->DirOpenReferenceCount <= 0)
2213 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2214 AFS_TRACE_LEVEL_VERBOSE,
2215 "AFSCreateDirEntry Different FIDs - Deleting DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
2217 &pExistingDirNode->NameInformation.FileName,
2218 pExistingDirNode->ObjectInformation->FileId.Cell,
2219 pExistingDirNode->ObjectInformation->FileId.Volume,
2220 pExistingDirNode->ObjectInformation->FileId.Vnode,
2221 pExistingDirNode->ObjectInformation->FileId.Unique,
2222 pDirNode->ObjectInformation->FileId.Cell,
2223 pDirNode->ObjectInformation->FileId.Volume,
2224 pDirNode->ObjectInformation->FileId.Vnode,
2225 pDirNode->ObjectInformation->FileId.Unique);
2227 AFSDeleteDirEntry( ParentObjectInfo,
2233 SetFlag( pExistingDirNode->Flags, AFS_DIR_ENTRY_DELETED);
2235 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2236 AFS_TRACE_LEVEL_VERBOSE,
2237 "AFSCreateDirEntry Different FIDs - Removing DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
2239 &pExistingDirNode->NameInformation.FileName,
2240 pExistingDirNode->ObjectInformation->FileId.Cell,
2241 pExistingDirNode->ObjectInformation->FileId.Volume,
2242 pExistingDirNode->ObjectInformation->FileId.Vnode,
2243 pExistingDirNode->ObjectInformation->FileId.Unique,
2244 pDirNode->ObjectInformation->FileId.Cell,
2245 pDirNode->ObjectInformation->FileId.Volume,
2246 pDirNode->ObjectInformation->FileId.Vnode,
2247 pDirNode->ObjectInformation->FileId.Unique);
2249 AFSRemoveNameEntry( ParentObjectInfo,
2256 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2257 AFS_TRACE_LEVEL_VERBOSE_2,
2258 "AFSCreateDirEntry Inserting dir entry in parent %wZ FID %08lX-%08lX-%08lX-%08lX Component %wZ\n",
2259 &ParentDirCB->NameInformation.FileName,
2260 ParentObjectInfo->FileId.Cell,
2261 ParentObjectInfo->FileId.Volume,
2262 ParentObjectInfo->FileId.Vnode,
2263 ParentObjectInfo->FileId.Unique,
2267 // Insert the directory node
2270 AFSInsertDirectoryNode( ParentObjectInfo,
2274 lCount = InterlockedIncrement( &pDirNode->DirOpenReferenceCount);
2276 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2277 AFS_TRACE_LEVEL_VERBOSE,
2278 "AFSCreateDirEntry Increment2 count on %wZ DE %p Cnt %d\n",
2279 &pDirNode->NameInformation.FileName,
2284 // Pass back the dir entry
2287 *DirEntry = pDirNode;
2289 AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2300 AFSInsertDirectoryNode( IN AFSObjectInfoCB *ParentObjectInfo,
2301 IN AFSDirectoryCB *DirEntry,
2302 IN BOOLEAN InsertInEnumList)
2310 ASSERT( ExIsResourceAcquiredExclusiveLite( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock));
2313 // Insert the node into the directory node tree
2316 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2317 AFS_TRACE_LEVEL_VERBOSE,
2318 "AFSInsertDirectoryNode Insert DE %p for %wZ Clearing NOT_IN flag\n",
2320 &DirEntry->NameInformation.FileName);
2322 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
2324 if( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead == NULL)
2327 ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = DirEntry;
2329 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2330 AFS_TRACE_LEVEL_VERBOSE,
2331 "AFSInsertDirectoryNode Insert DE %p to head of case sensitive tree for %wZ\n",
2333 &DirEntry->NameInformation.FileName);
2338 AFSInsertCaseSensitiveDirEntry( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
2341 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2342 AFS_TRACE_LEVEL_VERBOSE,
2343 "AFSInsertDirectoryNode Insert DE %p to case sensitive tree for %wZ\n",
2345 &DirEntry->NameInformation.FileName);
2348 if( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead == NULL)
2351 ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = DirEntry;
2353 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
2355 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2356 AFS_TRACE_LEVEL_VERBOSE,
2357 "AFSInsertDirectoryNode Insert DE %p to head of case insensitive tree for %wZ\n",
2359 &DirEntry->NameInformation.FileName);
2364 AFSInsertCaseInsensitiveDirEntry( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
2367 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2368 AFS_TRACE_LEVEL_VERBOSE,
2369 "AFSInsertDirectoryNode Insert DE %p to case insensitive tree for %wZ\n",
2371 &DirEntry->NameInformation.FileName);
2375 // Into the shortname tree
2378 if( DirEntry->Type.Data.ShortNameTreeEntry.HashIndex != 0)
2381 if( ParentObjectInfo->Specific.Directory.ShortNameTree == NULL)
2384 ParentObjectInfo->Specific.Directory.ShortNameTree = DirEntry;
2386 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2387 AFS_TRACE_LEVEL_VERBOSE,
2388 "AFSInsertDirectoryNode Insert DE %p to head of shortname tree for %wZ\n",
2390 &DirEntry->NameInformation.FileName);
2392 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
2397 if( !NT_SUCCESS( AFSInsertShortNameDirEntry( ParentObjectInfo->Specific.Directory.ShortNameTree,
2400 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2401 AFS_TRACE_LEVEL_VERBOSE,
2402 "AFSInsertDirectoryNode Failed to insert DE %p to shortname tree for %wZ\n",
2404 &DirEntry->NameInformation.FileName);
2408 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
2410 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2411 AFS_TRACE_LEVEL_VERBOSE,
2412 "AFSInsertDirectoryNode Insert DE %p to shortname tree for %wZ\n",
2414 &DirEntry->NameInformation.FileName);
2419 if( InsertInEnumList)
2423 // And insert the node into the directory list
2426 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2427 AFS_TRACE_LEVEL_VERBOSE,
2428 "AFSInsertDirectoryNode Inserting entry %p %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2430 &DirEntry->NameInformation.FileName,
2431 DirEntry->ObjectInformation->FileId.Cell,
2432 DirEntry->ObjectInformation->FileId.Volume,
2433 DirEntry->ObjectInformation->FileId.Vnode,
2434 DirEntry->ObjectInformation->FileId.Unique);
2436 if( ParentObjectInfo->Specific.Directory.DirectoryNodeListHead == NULL)
2439 ParentObjectInfo->Specific.Directory.DirectoryNodeListHead = DirEntry;
2444 ParentObjectInfo->Specific.Directory.DirectoryNodeListTail->ListEntry.fLink = (void *)DirEntry;
2446 DirEntry->ListEntry.bLink = (void *)ParentObjectInfo->Specific.Directory.DirectoryNodeListTail;
2449 ParentObjectInfo->Specific.Directory.DirectoryNodeListTail = DirEntry;
2451 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST);
2453 lCount = InterlockedIncrement( &ParentObjectInfo->Specific.Directory.DirectoryNodeCount);
2455 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
2456 AFS_TRACE_LEVEL_VERBOSE,
2457 "AFSInsertDirectoryNode Adding entry %wZ Inc Count %d to parent FID %08lX-%08lX-%08lX-%08lX\n",
2458 &DirEntry->NameInformation.FileName,
2460 ParentObjectInfo->FileId.Cell,
2461 ParentObjectInfo->FileId.Volume,
2462 ParentObjectInfo->FileId.Vnode,
2463 ParentObjectInfo->FileId.Unique);
2471 AFSDeleteDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
2472 IN AFSDirectoryCB *DirEntry)
2475 NTSTATUS ntStatus = STATUS_SUCCESS;
2481 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2482 AFS_TRACE_LEVEL_VERBOSE,
2483 "AFSDeleteDirEntry Deleting dir entry in parent %08lX Entry %p %wZ FID %08lX-%08lX-%08lX-%08lX RefCount %d\n",
2486 &DirEntry->NameInformation.FileName,
2487 DirEntry->ObjectInformation->FileId.Cell,
2488 DirEntry->ObjectInformation->FileId.Volume,
2489 DirEntry->ObjectInformation->FileId.Vnode,
2490 DirEntry->ObjectInformation->FileId.Unique,
2491 DirEntry->DirOpenReferenceCount);
2493 ASSERT( DirEntry->DirOpenReferenceCount == 0);
2495 AFSRemoveDirNodeFromParent( ParentObjectInfo,
2500 // Free up the name buffer if it was reallocated
2503 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_RELEASE_NAME_BUFFER))
2506 AFSExFreePoolWithTag( DirEntry->NameInformation.FileName.Buffer, 0);
2509 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER))
2512 AFSExFreePoolWithTag( DirEntry->NameInformation.TargetName.Buffer, 0);
2516 // Dereference the object for this dir entry
2519 ASSERT( DirEntry->ObjectInformation->ObjectReferenceCount > 0);
2521 lCount = AFSObjectInfoDecrement( DirEntry->ObjectInformation);
2523 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2524 AFS_TRACE_LEVEL_VERBOSE,
2525 "AFSDeleteDirEntry Decrement count on object %p Cnt %d\n",
2526 DirEntry->ObjectInformation,
2529 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_DELETED) &&
2530 DirEntry->ObjectInformation->Links == 0)
2533 SetFlag( DirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED);
2536 ExDeleteResourceLite( &DirEntry->NonPaged->Lock);
2538 AFSExFreePoolWithTag( DirEntry->NonPaged, AFS_DIR_ENTRY_NP_TAG);
2541 // Free up the dir entry
2544 AFSExFreePoolWithTag( DirEntry, AFS_DIR_ENTRY_TAG);
2551 AFSRemoveDirNodeFromParent( IN AFSObjectInfoCB *ParentObjectInfo,
2552 IN AFSDirectoryCB *DirEntry,
2553 IN BOOLEAN RemoveFromEnumList)
2556 NTSTATUS ntStatus = STATUS_SUCCESS;
2563 ASSERT( ExIsResourceAcquiredExclusiveLite( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock));
2565 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2566 AFS_TRACE_LEVEL_VERBOSE,
2567 "AFSRemoveDirNodeFromParent Removing DirEntry %p %wZ FID %08lX-%08lX-%08lX-%08lX from Parent %p\n",
2569 &DirEntry->NameInformation.FileName,
2570 DirEntry->ObjectInformation->FileId.Cell,
2571 DirEntry->ObjectInformation->FileId.Volume,
2572 DirEntry->ObjectInformation->FileId.Vnode,
2573 DirEntry->ObjectInformation->FileId.Unique,
2576 if( !BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
2579 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2580 AFS_TRACE_LEVEL_VERBOSE,
2581 "AFSRemoveDirNodeFromParent Removing DirEntry %p name %wZ\n",
2583 &DirEntry->NameInformation.FileName);
2585 AFSRemoveNameEntry( ParentObjectInfo,
2591 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2592 AFS_TRACE_LEVEL_VERBOSE,
2593 "AFSRemoveDirNodeFromParent DE %p for %wZ NOT removing entry due to flag set\n",
2595 &DirEntry->NameInformation.FileName);
2599 if( RemoveFromEnumList &&
2600 BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST))
2604 // And remove the entry from the enumeration list
2607 if( DirEntry->ListEntry.fLink == NULL)
2610 ParentObjectInfo->Specific.Directory.DirectoryNodeListTail = (AFSDirectoryCB *)DirEntry->ListEntry.bLink;
2615 ((AFSDirectoryCB *)DirEntry->ListEntry.fLink)->ListEntry.bLink = DirEntry->ListEntry.bLink;
2618 if( DirEntry->ListEntry.bLink == NULL)
2621 ParentObjectInfo->Specific.Directory.DirectoryNodeListHead = (AFSDirectoryCB *)DirEntry->ListEntry.fLink;
2626 ((AFSDirectoryCB *)DirEntry->ListEntry.bLink)->ListEntry.fLink = DirEntry->ListEntry.fLink;
2629 ASSERT( ParentObjectInfo->Specific.Directory.DirectoryNodeCount > 0);
2631 lCount = InterlockedDecrement( &ParentObjectInfo->Specific.Directory.DirectoryNodeCount);
2633 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST);
2635 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
2636 AFS_TRACE_LEVEL_VERBOSE,
2637 "AFSRemoveDirNodeFromParent Removing entry %wZ Dec Count %d to parent FID %08lX-%08lX-%08lX-%08lX\n",
2638 &DirEntry->NameInformation.FileName,
2640 ParentObjectInfo->FileId.Cell,
2641 ParentObjectInfo->FileId.Volume,
2642 ParentObjectInfo->FileId.Vnode,
2643 ParentObjectInfo->FileId.Unique);
2645 DirEntry->ListEntry.fLink = NULL;
2646 DirEntry->ListEntry.bLink = NULL;
2654 AFSFixupTargetName( IN OUT PUNICODE_STRING FileName,
2655 IN OUT PUNICODE_STRING TargetFileName)
2658 NTSTATUS ntStatus = STATUS_SUCCESS;
2659 UNICODE_STRING uniFileName;
2665 // We will process backwards from the end of the name looking
2666 // for the first \ we encounter
2669 uniFileName.Length = FileName->Length;
2670 uniFileName.MaximumLength = FileName->MaximumLength;
2672 uniFileName.Buffer = FileName->Buffer;
2677 if( uniFileName.Buffer[ (uniFileName.Length/sizeof( WCHAR)) - 1] == L'\\')
2681 // Subtract one more character off of the filename if it is not the root
2684 if( uniFileName.Length > sizeof( WCHAR))
2687 uniFileName.Length -= sizeof( WCHAR);
2691 // Now build up the target name
2694 TargetFileName->Length = FileName->Length - uniFileName.Length;
2697 // If we are not on the root then fixup the name
2700 if( uniFileName.Length > sizeof( WCHAR))
2703 TargetFileName->Length -= sizeof( WCHAR);
2705 TargetFileName->Buffer = &uniFileName.Buffer[ (uniFileName.Length/sizeof( WCHAR)) + 1];
2710 TargetFileName->Buffer = &uniFileName.Buffer[ uniFileName.Length/sizeof( WCHAR)];
2714 // Fixup the passed back filename length
2717 FileName->Length = uniFileName.Length;
2719 TargetFileName->MaximumLength = TargetFileName->Length;
2724 uniFileName.Length -= sizeof( WCHAR);
2732 AFSParseName( IN PIRP Irp,
2734 OUT PUNICODE_STRING FileName,
2735 OUT PUNICODE_STRING ParsedFileName,
2736 OUT PUNICODE_STRING RootFileName,
2737 OUT ULONG *ParseFlags,
2738 OUT AFSVolumeCB **VolumeCB,
2739 OUT AFSDirectoryCB **ParentDirectoryCB,
2740 OUT AFSNameArrayHdr **NameArray)
2743 NTSTATUS ntStatus = STATUS_SUCCESS;
2744 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2745 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2746 UNICODE_STRING uniFullName, uniComponentName, uniRemainingPath;
2748 AFSDirectoryCB *pDirEntry = NULL;
2749 USHORT usIndex = 0, usDriveIndex = 0;
2750 AFSCcb *pRelatedCcb = NULL;
2751 AFSNameArrayHdr *pNameArray = NULL, *pRelatedNameArray = NULL;
2752 USHORT usComponentIndex = 0;
2753 USHORT usComponentLength = 0;
2754 AFSVolumeCB *pVolumeCB = NULL;
2755 AFSFcb *pRelatedFcb = NULL;
2756 BOOLEAN bReleaseTreeLock = FALSE;
2757 BOOLEAN bIsAllShare = FALSE;
2764 // Indicate we are opening a root ...
2767 *ParseFlags = AFS_PARSE_FLAG_ROOT_ACCESS;
2769 if( pIrpSp->FileObject->RelatedFileObject != NULL)
2772 pRelatedFcb = (AFSFcb *)pIrpSp->FileObject->RelatedFileObject->FsContext;
2774 pRelatedCcb = (AFSCcb *)pIrpSp->FileObject->RelatedFileObject->FsContext2;
2776 pRelatedNameArray = pRelatedCcb->NameArray;
2778 uniFullName = pIrpSp->FileObject->FileName;
2780 ASSERT( pRelatedFcb != NULL);
2783 // No wild cards in the name
2786 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2787 AFS_TRACE_LEVEL_VERBOSE_2,
2788 "AFSParseName (%p) Relative open for %wZ FID %08lX-%08lX-%08lX-%08lX component %wZ\n",
2790 &pRelatedCcb->DirectoryCB->NameInformation.FileName,
2791 pRelatedCcb->DirectoryCB->ObjectInformation->FileId.Cell,
2792 pRelatedCcb->DirectoryCB->ObjectInformation->FileId.Volume,
2793 pRelatedCcb->DirectoryCB->ObjectInformation->FileId.Vnode,
2794 pRelatedCcb->DirectoryCB->ObjectInformation->FileId.Unique,
2797 if( FsRtlDoesNameContainWildCards( &uniFullName))
2800 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2801 AFS_TRACE_LEVEL_ERROR,
2802 "AFSParseName (%p) Component %wZ contains wild cards\n",
2806 try_return( ntStatus = STATUS_OBJECT_NAME_INVALID);
2809 pVolumeCB = pRelatedFcb->ObjectInformation->VolumeCB;
2811 pDirEntry = pRelatedCcb->DirectoryCB;
2813 *FileName = pIrpSp->FileObject->FileName;
2816 // Grab the root node while checking state
2819 AFSAcquireShared( pVolumeCB->VolumeLock,
2822 if( BooleanFlagOn( pVolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
2823 BooleanFlagOn( pVolumeCB->Flags, AFS_VOLUME_FLAGS_OFFLINE))
2827 // The volume has been taken off line so fail the access
2830 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2831 AFS_TRACE_LEVEL_ERROR,
2832 "AFSParseName (%p) Volume %08lX:%08lX OFFLINE/INVALID\n",
2834 pVolumeCB->ObjectInformation.FileId.Cell,
2835 pVolumeCB->ObjectInformation.FileId.Volume);
2837 AFSReleaseResource( pVolumeCB->VolumeLock);
2839 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
2842 if( BooleanFlagOn( pVolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_VERIFY))
2845 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2846 AFS_TRACE_LEVEL_VERBOSE,
2847 "AFSParseName (%p) Verifying root of volume %08lX:%08lX\n",
2849 pVolumeCB->ObjectInformation.FileId.Cell,
2850 pVolumeCB->ObjectInformation.FileId.Volume);
2852 ntStatus = AFSVerifyVolume( (ULONGLONG)PsGetCurrentProcessId(),
2855 if( !NT_SUCCESS( ntStatus))
2858 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2859 AFS_TRACE_LEVEL_ERROR,
2860 "AFSParseName (%p) Failed verification of root Status %08lX\n",
2864 AFSReleaseResource( pVolumeCB->VolumeLock);
2866 try_return( ntStatus);
2870 AFSReleaseResource( pVolumeCB->VolumeLock);
2872 if( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY))
2875 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2876 AFS_TRACE_LEVEL_VERBOSE,
2877 "AFSParseName (%p) Verifying parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2879 &pDirEntry->NameInformation.FileName,
2880 pDirEntry->ObjectInformation->FileId.Cell,
2881 pDirEntry->ObjectInformation->FileId.Volume,
2882 pDirEntry->ObjectInformation->FileId.Vnode,
2883 pDirEntry->ObjectInformation->FileId.Unique);
2886 // Directory TreeLock should be exclusively held
2889 AFSAcquireExcl( pDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
2892 ntStatus = AFSVerifyEntry( AuthGroup,
2895 AFSReleaseResource( pDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
2897 if( !NT_SUCCESS( ntStatus))
2900 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2901 AFS_TRACE_LEVEL_VERBOSE,
2902 "AFSParseName (%p) Failed verification of parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2904 &pDirEntry->NameInformation.FileName,
2905 pDirEntry->ObjectInformation->FileId.Cell,
2906 pDirEntry->ObjectInformation->FileId.Volume,
2907 pDirEntry->ObjectInformation->FileId.Vnode,
2908 pDirEntry->ObjectInformation->FileId.Unique,
2911 try_return( ntStatus);
2916 // Create our full path name buffer
2919 uniFullName.MaximumLength = pRelatedCcb->FullFileName.Length +
2921 pIrpSp->FileObject->FileName.Length +
2924 uniFullName.Length = 0;
2926 uniFullName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2927 uniFullName.MaximumLength,
2928 AFS_NAME_BUFFER_THREE_TAG);
2930 if( uniFullName.Buffer == NULL)
2933 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2934 AFS_TRACE_LEVEL_ERROR,
2935 "AFSParseName (%p) Failed to allocate full name buffer\n",
2938 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2941 RtlZeroMemory( uniFullName.Buffer,
2942 uniFullName.MaximumLength);
2944 RtlCopyMemory( uniFullName.Buffer,
2945 pRelatedCcb->FullFileName.Buffer,
2946 pRelatedCcb->FullFileName.Length);
2948 uniFullName.Length = pRelatedCcb->FullFileName.Length;
2950 usComponentIndex = (USHORT)(uniFullName.Length/sizeof( WCHAR));
2952 usComponentLength = pIrpSp->FileObject->FileName.Length;
2954 if( uniFullName.Buffer[ (uniFullName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
2955 pIrpSp->FileObject->FileName.Length > 0 &&
2956 pIrpSp->FileObject->FileName.Buffer[ 0] != L'\\' &&
2957 pIrpSp->FileObject->FileName.Buffer[ 0] != L':')
2960 uniFullName.Buffer[ (uniFullName.Length/sizeof( WCHAR))] = L'\\';
2962 uniFullName.Length += sizeof( WCHAR);
2964 usComponentLength += sizeof( WCHAR);
2967 if( pIrpSp->FileObject->FileName.Length > 0)
2970 RtlCopyMemory( &uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)],
2971 pIrpSp->FileObject->FileName.Buffer,
2972 pIr
\epSp->FileObject->FileName.Length);
2974 uniFullName.Length += pIrpSp->FileObject->FileName.Length;
2977 *RootFileName = uniFullName;
2980 // We populate up to the current parent
2983 if( pRelatedNameArray == NULL)
2987 // Init and populate our name array
2990 pNameArray = AFSInitNameArray( NULL,
2993 if( pNameArray == NULL)
2996 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2997 AFS_TRACE_LEVEL_VERBOSE,
2998 "AFSParseName (%p) Failed to initialize name array\n",
3001 AFSExFreePoolWithTag( uniFullName.Buffer, 0);
3003 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3006 ntStatus = AFSPopulateNameArray( pNameArray,
3008 pRelatedCcb->DirectoryCB);
3014 // Init and populate our name array
3017 pNameArray = AFSInitNameArray( NULL,
3018 pRelatedNameArray->MaxElementCount);
3020 if( pNameArray == NULL)
3023 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3024 AFS_TRACE_LEVEL_VERBOSE,
3025 "AFSParseName (%p) Failed to initialize name array\n",
3028 AFSExFreePoolWithTag( uniFullName.Buffer, 0);
3030 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3033 ntStatus = AFSPopulateNameArrayFromRelatedArray( pNameArray,
3035 pRelatedCcb->DirectoryCB);
3038 if( !NT_SUCCESS( ntStatus))
3041 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3042 AFS_TRACE_LEVEL_VERBOSE,
3043 "AFSParseName (%p) Failed to populate name array\n",
3046 AFSExFreePoolWithTag( uniFullName.Buffer, 0);
3048 try_return( ntStatus);
3051 ParsedFileName->Length = usComponentLength;
3052 ParsedFileName->MaximumLength = uniFullName.MaximumLength;
3054 ParsedFileName->Buffer = &uniFullName.Buffer[ usComponentIndex];
3057 // Indicate to caller that RootFileName must be freed
3060 SetFlag( *ParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
3062 *NameArray = pNameArray;
3064 *VolumeCB = pVolumeCB;
3067 // Increment our volume reference count
3070 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
3072 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
3073 AFS_TRACE_LEVEL_VERBOSE,
3074 "AFSParseName Increment count on volume %p Cnt %d\n",
3078 *ParentDirectoryCB = pDirEntry;
3080 lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
3082 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3083 AFS_TRACE_LEVEL_VERBOSE,
3084 "AFSParseName Increment1 count on %wZ DE %p Ccb %p Cnt %d\n",
3085 &pDirEntry->NameInformation.FileName,
3090 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3091 AFS_TRACE_LEVEL_VERBOSE_2,
3092 "AFSParseName (%p) Returning full name %wZ\n",
3096 try_return( ntStatus);
3100 // No wild cards in the name
3103 uniFullName = pIrpSp->FileObject->FileName;
3105 if( FsRtlDoesNameContainWildCards( &uniFullName) ||
3106 uniFullName.Length < AFSServerName.Length)
3109 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3110 AFS_TRACE_LEVEL_ERROR,
3111 "AFSParseName (%p) Name %wZ contains wild cards or too short\n",
3115 try_return( ntStatus = STATUS_OBJECT_NAME_INVALID);
3119 // The name is a fully qualified name. Parse out the server/share names and
3120 // point to the root qualified name
3121 // First thing is to locate the server name
3124 FsRtlDissectName( uniFullName,
3128 uniFullName = uniRemainingPath;
3131 // This component is the server name we are serving
3134 if( RtlCompareUnicodeString( &uniComponentName,
3140 // Drive letter based name?
3143 uniFullName = pIrpSp->FileObject->FileName;
3145 while( usIndex < uniFullName.Length/sizeof( WCHAR))
3148 if( uniFullName.Buffer[ usIndex] == L':')
3151 uniFullName.Buffer = &uniFullName.Buffer[ usIndex + 2];
3153 uniFullName.Length -= (usIndex + 2) * sizeof( WCHAR);
3155 usDriveIndex = usIndex - 1;
3164 // Do we have the right server name now?
3167 FsRtlDissectName( uniFullName,
3171 uniFullName = uniRemainingPath;
3174 // This component is the server name we are serving
3177 if( RtlCompareUnicodeString( &uniComponentName,
3182 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3183 AFS_TRACE_LEVEL_ERROR,
3184 "AFSParseName (%p) Name %wZ does not have server name\n",
3186 &pIrpSp->FileObject->FileName);
3188 try_return( ntStatus = STATUS_BAD_NETWORK_NAME);
3192 // Validate this drive letter is actively mapped
3195 if( usDriveIndex > 0 &&
3196 !AFSIsDriveMapped( pIrpSp->FileObject->FileName.Buffer[ usDriveIndex]))
3199 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3200 AFS_TRACE_LEVEL_ERROR,
3201 "AFSParseName (%p) Name %wZ contains invalid drive mapping\n",
3203 &pIrpSp->FileObject->FileName);
3205 try_return( ntStatus = STATUS_BAD_NETWORK_NAME);
3209 if( FsRtlDoesNameContainWildCards( &uniFullName))
3212 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3213 AFS_TRACE_LEVEL_ERROR,
3214 "AFSParseName (%p) Component %wZ contains wild cards\n",
3218 try_return( ntStatus = STATUS_OBJECT_NAME_INVALID);
3221 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3222 AFS_TRACE_LEVEL_VERBOSE_2,
3223 "AFSParseName (%p) Processing full name %wZ\n",
3227 if( uniFullName.Length > 0 &&
3228 uniFullName.Buffer[ (uniFullName.Length/sizeof( WCHAR)) - 1] == L'\\')
3231 uniFullName.Length -= sizeof( WCHAR);
3235 // Be sure we are online and ready to go
3238 AFSAcquireShared( AFSGlobalRoot->VolumeLock,
3241 if( BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
3242 BooleanFlagOn( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE))
3246 // The volume has been taken off line so fail the access
3249 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3250 AFS_TRACE_LEVEL_ERROR,
3251 "AFSParseName (%p) Volume %08lX:%08lX OFFLINE/INVALID\n",
3253 AFSGlobalRoot->ObjectInformation.FileId.Cell,
3254 AFSGlobalRoot->ObjectInformation.FileId.Volume);
3256 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3258 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
3261 if( BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_VERIFY))
3264 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3265 AFS_TRACE_LEVEL_VERBOSE,
3266 "AFSParseName (%p) Verifying root of volume %08lX:%08lX\n",
3268 AFSGlobalRoot->ObjectInformation.FileId.Cell,
3269 AFSGlobalRoot->ObjectInformation.FileId.Volume);
3271 ntStatus = AFSVerifyVolume( (ULONGLONG)PsGetCurrentProcessId(),
3274 if( !NT_SUCCESS( ntStatus))
3277 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3278 AFS_TRACE_LEVEL_ERROR,
3279 "AFSParseName (%p) Failed verification of root Status %08lX\n",
3283 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3285 try_return( ntStatus);
3289 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3291 if( !BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
3294 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3295 AFS_TRACE_LEVEL_VERBOSE,
3296 "AFSParseName (%p) Enumerating global root of volume %08lX:%08lX\n",
3298 AFSGlobalRoot->ObjectInformation.FileId.Cell,
3299 AFSGlobalRoot->ObjectInformation.FileId.Volume);
3301 ntStatus = AFSEnumerateGlobalRoot( AuthGroup);
3303 if( !NT_SUCCESS( ntStatus))
3306 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3307 AFS_TRACE_LEVEL_ERROR,
3308 "AFSParseName (%p) Failed enumeraiton of root Status %08lX\n",
3312 try_return( ntStatus);
3317 // Check for the \\Server access and return it as though it where \\Server\Globalroot
3320 if( uniRemainingPath.Buffer == NULL ||
3321 ( uniRemainingPath.Length == sizeof( WCHAR) &&
3322 uniRemainingPath.Buffer[ 0] == L'\\'))
3325 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3326 AFS_TRACE_LEVEL_VERBOSE_2,
3327 "AFSParseName (%p) Returning global root access\n",
3330 lCount = InterlockedIncrement( &AFSGlobalRoot->DirectoryCB->DirOpenReferenceCount);
3332 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3333 AFS_TRACE_LEVEL_VERBOSE,
3334 "AFSParseName Increment2 count on %wZ DE %p Ccb %p Cnt %d\n",
3335 &AFSGlobalRoot->DirectoryCB->NameInformation.FileName,
3336 AFSGlobalRoot->DirectoryCB,
3342 FileName->Length = 0;
3343 FileName->MaximumLength = 0;
3344 FileName->Buffer = NULL;
3346 try_return( ntStatus = STATUS_SUCCESS);
3349 *RootFileName = uniFullName;
3352 // Include the starting \ in the root name
3355 if( RootFileName->Buffer[ 0] != L'\\')
3357 RootFileName->Buffer--;
3358 RootFileName->Length += sizeof( WCHAR);
3359 RootFileName->MaximumLength += sizeof( WCHAR);
3363 // Get the 'share' name
3366 FsRtlDissectName( uniFullName,
3370 if( FsRtlDoesNameContainWildCards( &uniFullName))
3373 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3374 AFS_TRACE_LEVEL_ERROR,
3375 "AFSParseName (%p) Component %wZ contains wild cards\n",
3379 try_return( ntStatus = STATUS_OBJECT_NAME_INVALID);
3383 // If this is the ALL access then perform some additional processing
3386 if( uniComponentName.Length == 0 ||
3387 RtlCompareUnicodeString( &uniComponentName,
3395 // If there is nothing else then get out
3398 if( uniRemainingPath.Buffer == NULL ||
3399 uniRemainingPath.Length == 0 ||
3400 ( uniRemainingPath.Length == sizeof( WCHAR) &&
3401 uniRemainingPath.Buffer[ 0] == L'\\'))
3404 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3405 AFS_TRACE_LEVEL_VERBOSE_2,
3406 "AFSParseName (%p) Returning global root access\n",
3409 lCount = InterlockedIncrement( &AFSGlobalRoot->DirectoryCB->DirOpenReferenceCount);
3411 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3412 AFS_TRACE_LEVEL_VERBOSE,
3413 "AFSParseName Increment3 count on %wZ DE %p Ccb %p Cnt %d\n",
3414 &AFSGlobalRoot->DirectoryCB->NameInformation.FileName,
3415 AFSGlobalRoot->DirectoryCB,
3421 FileName->Length = 0;
3422 FileName->MaximumLength = 0;
3423 FileName->Buffer = NULL;
3425 try_return( ntStatus = STATUS_SUCCESS);
3429 // Process the name again to strip off the ALL portion
3432 uniFullName = uniRemainingPath;
3434 FsRtlDissectName( uniFullName,
3439 // Check for the PIOCtl name
3442 if( RtlCompareUnicodeString( &uniComponentName,
3447 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3448 AFS_TRACE_LEVEL_VERBOSE_2,
3449 "AFSParseName (%p) Returning root PIOCtl access\n",
3452 lCount = InterlockedIncrement( &AFSGlobalRoot->DirectoryCB->DirOpenReferenceCount);
3454 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3455 AFS_TRACE_LEVEL_VERBOSE,
3456 "AFSParseName Increment4 count on %wZ DE %p Ccb %p Cnt %d\n",
3457 &AFSGlobalRoot->DirectoryCB->NameInformation.FileName,
3458 AFSGlobalRoot->DirectoryCB,
3462 ClearFlag( *ParseFlags, AFS_PARSE_FLAG_ROOT_ACCESS);
3466 *FileName = AFSPIOCtlName;
3468 try_return( ntStatus = STATUS_SUCCESS);
3471 else if( (pDirEntry = AFSGetSpecialShareNameEntry( &uniComponentName,
3472 &uniRemainingPath)) != NULL)
3475 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3476 AFS_TRACE_LEVEL_VERBOSE_2,
3477 "AFSParseName (%p) Returning root share name %wZ access\n",
3482 // Add in the full share name to pass back
3485 if( uniRemainingPath.Buffer != NULL)
3489 // This routine strips off the leading slash so add it back in
3492 uniRemainingPath.Buffer--;
3493 uniRemainingPath.Length += sizeof( WCHAR);
3494 uniRemainingPath.MaximumLength += sizeof( WCHAR);
3497 // And the cell name
3500 uniRemainingPath.Buffer -= (uniComponentName.Length/sizeof( WCHAR));
3501 uniRemainingPath.Length += uniComponentName.Length;
3502 uniRemainingPath.MaximumLength += uniComponentName.Length;
3504 uniComponentName = uniRemainingPath;
3509 *FileName = uniComponentName;
3511 *ParentDirectoryCB = pDirEntry;
3513 ClearFlag( *ParseFlags, AFS_PARSE_FLAG_ROOT_ACCESS);
3515 lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
3517 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3518 AFS_TRACE_LEVEL_VERBOSE,
3519 "AFSParseName Increment5 count on %wZ DE %p Ccb %p Cnt %d\n",
3520 &pDirEntry->NameInformation.FileName,
3525 try_return( ntStatus = STATUS_SUCCESS);
3529 // Determine the 'share' we are accessing
3532 ulCRC = AFSGenerateCRC( &uniComponentName,
3535 AFSAcquireShared( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
3538 bReleaseTreeLock = TRUE;
3540 AFSLocateCaseSensitiveDirEntry( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
3544 if( pDirEntry == NULL)
3547 ulCRC = AFSGenerateCRC( &uniComponentName,
3550 AFSLocateCaseInsensitiveDirEntry( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
3554 if( pDirEntry == NULL)
3558 // OK, if this component is a valid short name then try
3559 // a lookup in the short name tree
3562 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
3563 RtlIsNameLegalDOS8Dot3( &uniComponentName,
3568 AFSLocateShortNameDirEntry( AFSGlobalRoot->ObjectInformation.Specific.Directory.ShortNameTree,
3573 if( pDirEntry == NULL)
3577 // Check with the service whether it is a valid cell name
3580 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
3582 bReleaseTreeLock = FALSE;
3584 ntStatus = AFSCheckCellName( AuthGroup,
3588 if( !NT_SUCCESS( ntStatus))
3592 uniRemainingPath.Length == 0 &&
3593 ntStatus == STATUS_OBJECT_PATH_NOT_FOUND)
3596 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
3599 try_return( ntStatus);
3605 if( bReleaseTreeLock)
3607 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
3612 // Be sure we are starting from the correct volume
3615 if( pDirEntry->ObjectInformation->VolumeCB != AFSGlobalRoot)
3619 // We dropped the global root in the CheckCellName routine which is the
3620 // only way we can be here
3623 pVolumeCB = pDirEntry->ObjectInformation->VolumeCB;
3626 // Init our name array
3629 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
3632 if( pNameArray == NULL)
3635 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3636 AFS_TRACE_LEVEL_VERBOSE,
3637 "AFSParseName (%p) Failed to initialize name array\n",
3640 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3643 ntStatus = AFSInsertNextElement( pNameArray,
3644 pVolumeCB->DirectoryCB);
3649 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3650 AFS_TRACE_LEVEL_VERBOSE,
3651 "AFSParseName (%p) Failed to insert name array element\n",
3654 try_return( ntStatus);
3658 // In this case don't add back in the 'share' name since that is where we are
3659 // starting. Just put the leading slash back in
3662 if( uniRemainingPath.Buffer != NULL)
3665 uniRemainingPath.Buffer--;
3666 uniRemainingPath.Length += sizeof( WCHAR);
3667 uniRemainingPath.MaximumLength += sizeof( WCHAR);
3669 if( uniRemainingPath.Length > sizeof( WCHAR))
3672 ClearFlag( *ParseFlags, AFS_PARSE_FLAG_ROOT_ACCESS);
3676 // Pass back the parent being the root of the volume
3679 *ParentDirectoryCB = pVolumeCB->DirectoryCB;
3685 // Pass back a root slash
3688 uniRemainingPath = uniComponentName;
3690 uniRemainingPath.Buffer--;
3691 uniRemainingPath.Length = sizeof( WCHAR);
3692 uniRemainingPath.MaximumLength = sizeof( WCHAR);
3695 // This is a root open so pass back no parent
3698 *ParentDirectoryCB = NULL;
3704 pVolumeCB = AFSGlobalRoot;
3707 // Init our name array
3710 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
3712 if( pNameArray == NULL)
3715 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3716 AFS_TRACE_LEVEL_VERBOSE,
3717 "AFSParseName (%p) Failed to initialize name array\n",
3720 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3724 // Add back in the 'share' portion of the name since we will parse it out on return
3727 if( uniRemainingPath.Buffer != NULL)
3731 // This routine strips off the leading slash so add it back in
3734 uniRemainingPath.Buffer--;
3735 uniRemainingPath.Length += sizeof( WCHAR);
3736 uniRemainingPath.MaximumLength += sizeof( WCHAR);
3738 if( uniRemainingPath.Length > sizeof( WCHAR))
3741 ClearFlag( *ParseFlags, AFS_PARSE_FLAG_ROOT_ACCESS);
3745 // And the cell name
3748 uniRemainingPath.Buffer -= (uniComponentName.Length/sizeof( WCHAR));
3749 uniRemainingPath.Length += uniComponentName.Length;
3750 uniRemainingPath.MaximumLength += uniComponentName.Length;
3755 uniRemainingPath = uniComponentName;
3759 // And the leading slash again ...
3762 uniRemainingPath.Buffer--;
3763 uniRemainingPath.Length += sizeof( WCHAR);
3764 uniRemainingPath.MaximumLength += sizeof( WCHAR);
3766 lCount = InterlockedIncrement( &pVolumeCB->DirectoryCB->DirOpenReferenceCount);
3768 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3769 AFS_TRACE_LEVEL_VERBOSE,
3770 "AFSParseName Increment6 count on %wZ DE %p Ccb %p Cnt %d\n",
3771 &pVolumeCB->DirectoryCB->NameInformation.FileName,
3772 pVolumeCB->DirectoryCB,
3777 // Pass back the parent being the volume root
3780 *ParentDirectoryCB = pVolumeCB->DirectoryCB;
3785 // Return the remaining portion as the file name
3788 *FileName = uniRemainingPath;
3790 *ParsedFileName = uniRemainingPath;
3792 *NameArray = pNameArray;
3794 *VolumeCB = pVolumeCB;
3797 // Increment our reference on the volume
3800 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
3802 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
3803 AFS_TRACE_LEVEL_VERBOSE,
3804 "AFSParseName Increment2 count on global volume %p Cnt %d\n",
3810 if( NT_SUCCESS( ntStatus))
3813 if( *ParentDirectoryCB != NULL)
3816 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3817 AFS_TRACE_LEVEL_VERBOSE,
3818 "AFSParseName Count on %wZ DE %p Ccb %p Cnt %d\n",
3819 &(*ParentDirectoryCB)->NameInformation.FileName,
3822 (*ParentDirectoryCB)->DirOpenReferenceCount);
3826 if( *VolumeCB != NULL)
3828 ASSERT( (*VolumeCB)->VolumeReferenceCount > 1);
3831 if( ntStatus != STATUS_SUCCESS)
3834 if( pNameArray != NULL)
3837 AFSFreeNameArray( pNameArray);
3846 AFSCheckCellName( IN GUID *AuthGroup,
3847 IN UNICODE_STRING *CellName,
3848 OUT AFSDirectoryCB **ShareDirEntry)
3851 NTSTATUS ntStatus = STATUS_SUCCESS;
3852 UNICODE_STRING uniName;
3853 AFSDirEnumEntry *pDirEnumEntry = NULL;
3854 AFSDirHdr *pDirHdr = &AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr;
3855 AFSDirectoryCB *pDirNode = NULL;
3856 UNICODE_STRING uniDirName, uniTargetName;
3857 AFSVolumeCB *pVolumeCB = NULL;
3864 // Look for some default names we will not handle
3867 RtlInitUnicodeString( &uniName,
3870 if( RtlCompareUnicodeString( &uniName,
3875 try_return( ntStatus = STATUS_NO_SUCH_FILE);
3878 RtlInitUnicodeString( &uniName,
3881 if( RtlCompareUnicodeString( &uniName,
3886 try_return( ntStatus = STATUS_NO_SUCH_FILE);
3889 RtlInitUnicodeString( &uniName,
3892 if( RtlCompareUnicodeString( &uniName,
3897 try_return( ntStatus = STATUS_NO_SUCH_FILE);
3900 RtlInitUnicodeString( &uniName,
3903 if( RtlCompareUnicodeString( &uniName,
3908 try_return( ntStatus = STATUS_NO_SUCH_FILE);
3912 // OK, ask the CM about this component name
3915 ntStatus = AFSEvaluateTargetByName( AuthGroup,
3916 &AFSGlobalRoot->ObjectInformation,
3920 if( !NT_SUCCESS( ntStatus))
3923 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3924 AFS_TRACE_LEVEL_WARNING,
3925 "AFSCheckCellName entry %wZ does not exist parent FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
3927 AFSGlobalRoot->ObjectInformation.FileId.Cell,
3928 AFSGlobalRoot->ObjectInformation.FileId.Volume,
3929 AFSGlobalRoot->ObjectInformation.FileId.Vnode,
3930 AFSGlobalRoot->ObjectInformation.FileId.Unique,
3933 try_return( ntStatus);
3937 // OK, we have a dir enum entry back so add it to the root node
3940 uniDirName = *CellName;
3942 uniTargetName.Length = (USHORT)pDirEnumEntry->TargetNameLength;
3943 uniTargetName.MaximumLength = uniTargetName.Length;
3944 uniTargetName.Buffer = (WCHAR *)((char *)pDirEnumEntry + pDirEnumEntry->TargetNameOffset);
3947 // Is this entry a root volume entry?
3950 if( pDirEnumEntry->FileId.Cell != AFSGlobalRoot->ObjectInformation.FileId.Cell ||
3951 pDirEnumEntry->FileId.Volume != AFSGlobalRoot->ObjectInformation.FileId.Volume)
3955 // Build the root volume entry
3958 ntStatus = AFSBuildRootVolume( AuthGroup,
3959 &pDirEnumEntry->FileId,
3962 if( !NT_SUCCESS( ntStatus))
3964 try_return( ntStatus);
3967 *ShareDirEntry = pVolumeCB->DirectoryCB;
3969 lCount = InterlockedIncrement( &pVolumeCB->DirectoryCB->DirOpenReferenceCount);
3971 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3972 AFS_TRACE_LEVEL_VERBOSE,
3973 "AFSCheckCellName Increment1 count on %wZ DE %p Ccb %p Cnt %d\n",
3974 &pVolumeCB->DirectoryCB->NameInformation.FileName,
3975 pVolumeCB->DirectoryCB,
3979 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
3981 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
3982 AFS_TRACE_LEVEL_VERBOSE,
3983 "AFSCheckCellName Increment count on volume %p Cnt %d\n",
3990 lCount = InterlockedIncrement( &pDirHdr->ContentIndex);
3992 pDirNode = AFSInitDirEntry( &AFSGlobalRoot->ObjectInformation,
3998 if( pDirNode == NULL)
4001 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4005 // Init the short name if we have one
4008 if( pDirEnumEntry->ShortNameLength > 0)
4011 pDirNode->NameInformation.ShortNameLength = pDirEnumEntry->ShortNameLength;
4013 RtlCopyMemory( pDirNode->NameInformation.ShortName,
4014 pDirEnumEntry->ShortName,
4015 pDirNode->NameInformation.ShortNameLength);
4018 AFSAcquireExcl( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
4022 // Insert the node into the name tree
4025 ASSERT( ExIsResourceAcquiredExclusiveLite( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock));
4027 if( pDirHdr->CaseSensitiveTreeHead == NULL)
4030 pDirHdr->CaseSensitiveTreeHead = pDirNode;
4035 if( !NT_SUCCESS( AFSInsertCaseSensitiveDirEntry( pDirHdr->CaseSensitiveTreeHead,
4039 AFSDeleteDirEntry( &AFSGlobalRoot->ObjectInformation,
4042 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
4044 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4048 ClearFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
4050 if( pDirHdr->CaseInsensitiveTreeHead == NULL)
4053 pDirHdr->CaseInsensitiveTreeHead = pDirNode;
4055 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
4060 AFSInsertCaseInsensitiveDirEntry( pDirHdr->CaseInsensitiveTreeHead,
4064 if( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListHead == NULL)
4067 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListHead = pDirNode;
4072 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListTail->ListEntry.fLink = pDirNode;
4074 pDirNode->ListEntry.bLink = AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListTail;
4077 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListTail = pDirNode;
4079 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST);
4081 lCount = InterlockedIncrement( &AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeCount);
4083 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
4084 AFS_TRACE_LEVEL_VERBOSE,
4085 "AFSCheckCellName Adding entry %wZ Inc Count %d to parent FID %08lX-%08lX-%08lX-%08lX\n",
4086 &pDirNode->NameInformation.FileName,
4088 AFSGlobalRoot->ObjectInformation.FileId.Cell,
4089 AFSGlobalRoot->ObjectInformation.FileId.Volume,
4090 AFSGlobalRoot->ObjectInformation.FileId.Vnode,
4091 AFSGlobalRoot->ObjectInformation.FileId.Unique);
4093 lCount = InterlockedIncrement( &pDirNode->DirOpenReferenceCount);
4095 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
4096 AFS_TRACE_LEVEL_VERBOSE,
4097 "AFSCheckCellName Increment2 count on %wZ DE %p Ccb %p Cnt %d\n",
4098 &pDirNode->NameInformation.FileName,
4103 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
4106 // Pass back the dir node
4109 *ShareDirEntry = pDirNode;
4114 if( pDirEnumEntry != NULL)
4117 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_31_TAG);
4125 AFSBuildMountPointTarget( IN GUID *AuthGroup,
4126 IN AFSDirectoryCB *DirectoryCB,
4127 OUT AFSVolumeCB **TargetVolumeCB)
4130 NTSTATUS ntStatus = STATUS_SUCCESS;
4131 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
4132 AFSDirEnumEntry *pDirEntry = NULL;
4133 ULONGLONG ullIndex = 0;
4134 AFSVolumeCB *pVolumeCB = NULL;
4135 AFSFileID stTargetFileID;
4137 BOOLEAN bReleaseVolumeLock = FALSE;
4143 // Loop on each entry, building the chain until we encounter the final target
4146 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4147 AFS_TRACE_LEVEL_VERBOSE_2,
4148 "AFSBuildMountPointTarget Building target directory for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4149 &DirectoryCB->NameInformation.FileName,
4150 DirectoryCB->ObjectInformation->FileId.Cell,
4151 DirectoryCB->ObjectInformation->FileId.Volume,
4152 DirectoryCB->ObjectInformation->FileId.Vnode,
4153 DirectoryCB->ObjectInformation->FileId.Unique);
4156 // Do we need to evaluate the node?
4159 //if( DirectoryCB->ObjectInformation->TargetFileId.Vnode == 0 &&
4160 // DirectoryCB->ObjectInformation->TargetFileId.Unique == 0)
4164 // Go evaluate the current target to get the target fid
4167 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4168 AFS_TRACE_LEVEL_VERBOSE_2,
4169 "AFSBuildMountPointTarget Evaluating target %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4170 &DirectoryCB->NameInformation.FileName,
4171 DirectoryCB->ObjectInformation->FileId.Cell,
4172 DirectoryCB->ObjectInformation->FileId.Volume,
4173 DirectoryCB->ObjectInformation->FileId.Vnode,
4174 DirectoryCB->ObjectInformation->FileId.Unique);
4176 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
4181 if( !NT_SUCCESS( ntStatus))
4184 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4185 AFS_TRACE_LEVEL_ERROR,
4186 "AFSBuildMountPointTarget Failed to evaluate target %wZ Status %08lX\n",
4187 &DirectoryCB->NameInformation.FileName,
4189 try_return( ntStatus);
4192 if( pDirEntry->TargetFileId.Vnode == 0 &&
4193 pDirEntry->TargetFileId.Unique == 0)
4196 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4197 AFS_TRACE_LEVEL_ERROR,
4198 "AFSBuildMountPointTarget Target %wZ FID %08lX-%08lX-%08lX-%08lX service returned zero FID\n",
4199 &DirectoryCB->NameInformation.FileName,
4200 DirectoryCB->ObjectInformation->FileId.Cell,
4201 DirectoryCB->ObjectInformation->FileId.Volume,
4202 DirectoryCB->ObjectInformation->FileId.Vnode,
4203 DirectoryCB->ObjectInformation->FileId.Unique);
4205 try_return( ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED);
4208 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
4211 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
4212 &DirectoryCB->Flags,
4213 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
4214 (USHORT)pDirEntry->TargetNameLength);
4216 if( !NT_SUCCESS( ntStatus))
4219 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
4221 try_return( ntStatus);
4224 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
4226 DirectoryCB->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
4229 stTargetFileID = DirectoryCB->ObjectInformation->TargetFileId;
4232 // Try to locate this FID. First the volume then the
4236 ullIndex = AFSCreateHighIndex( &stTargetFileID);
4238 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4239 AFS_TRACE_LEVEL_VERBOSE,
4240 "AFSBuildMountPointTarget Acquiring RDR VolumeTreeLock lock %p EXCL %08lX\n",
4241 &pDevExt->Specific.RDR.VolumeTreeLock,
4242 PsGetCurrentThread());
4244 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock,
4247 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4248 AFS_TRACE_LEVEL_VERBOSE_2,
4249 "AFSBuildMountPointTarget Locating volume for target %I64X\n",
4252 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
4254 (AFSBTreeEntry **)&pVolumeCB);
4257 // We can be processing a request for a target that is on a volume
4258 // we have never seen before.
4261 if( pVolumeCB == NULL)
4265 // Locking is held correctly in init routine
4268 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
4271 // Go init the root of the volume
4274 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4275 AFS_TRACE_LEVEL_VERBOSE_2,
4276 "AFSBuildMountPointTarget Initializing root for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4277 &DirectoryCB->NameInformation.FileName,
4278 DirectoryCB->ObjectInformation->FileId.Cell,
4279 DirectoryCB->ObjectInformation->FileId.Volume,
4280 DirectoryCB->ObjectInformation->FileId.Vnode,
4281 DirectoryCB->ObjectInformation->FileId.Unique);
4283 ntStatus = AFSInitVolume( AuthGroup,
4287 if( !NT_SUCCESS( ntStatus))
4290 try_return( ntStatus);
4294 // pVolumeCB->VolumeLock held exclusive and
4295 // pVolumeCB->VolumeReferenceCount has been incremented
4296 // pVolumeCB->RootFcb == NULL
4299 bReleaseVolumeLock = TRUE;
4305 // AFSInitVolume returns with a VolumeReferenceCount
4306 // obtain one to match
4309 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
4311 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
4312 AFS_TRACE_LEVEL_VERBOSE,
4313 "AFSBuildMountPointTarget Increment count on volume %p Cnt %d\n",
4317 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
4320 if( pVolumeCB->RootFcb == NULL)
4323 if ( bReleaseVolumeLock == FALSE)
4326 AFSAcquireExcl( pVolumeCB->VolumeLock,
4329 bReleaseVolumeLock = TRUE;
4333 // Initialize the root fcb for this volume
4336 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
4339 if( !NT_SUCCESS( ntStatus))
4342 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
4344 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
4345 AFS_TRACE_LEVEL_VERBOSE,
4346 "AFSBuildMountPoint Decrement count on volume %p Cnt %d\n",
4350 AFSReleaseResource( pVolumeCB->VolumeLock);
4352 try_return( ntStatus);
4356 // Drop the lock acquired above
4359 AFSReleaseResource( &pVolumeCB->RootFcb->NPFcb->Resource);
4362 if ( bReleaseVolumeLock == TRUE)
4365 AFSReleaseResource( pVolumeCB->VolumeLock);
4368 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4369 AFS_TRACE_LEVEL_VERBOSE_2,
4370 "AFSBuildMountPointTarget Evaluated target of %wZ FID %08lX-%08lX-%08lX-%08lX as root volume\n",
4371 &pVolumeCB->DirectoryCB->NameInformation.FileName,
4372 pVolumeCB->ObjectInformation.FileId.Cell,
4373 pVolumeCB->ObjectInformation.FileId.Volume,
4374 pVolumeCB->ObjectInformation.FileId.Vnode,
4375 pVolumeCB->ObjectInformation.FileId.Unique);
4377 *TargetVolumeCB = pVolumeCB;
4384 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
4392 AFSBuildRootVolume( IN GUID *AuthGroup,
4393 IN AFSFileID *FileId,
4394 OUT AFSVolumeCB **TargetVolumeCB)
4397 NTSTATUS ntStatus = STATUS_SUCCESS;
4398 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
4399 ULONGLONG ullIndex = 0;
4400 AFSVolumeCB *pVolumeCB = NULL;
4402 BOOLEAN bReleaseVolumeLock = FALSE;
4407 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4408 AFS_TRACE_LEVEL_VERBOSE_2,
4409 "AFSBuildRootVolume Building target volume for FID %08lX-%08lX-%08lX-%08lX\n",
4415 ullIndex = AFSCreateHighIndex( FileId);
4417 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4418 AFS_TRACE_LEVEL_VERBOSE,
4419 "AFSBuildRootVolume Acquiring RDR VolumeTreeLock lock %p EXCL %08lX\n",
4420 &pDevExt->Specific.RDR.VolumeTreeLock,
4421 PsGetCurrentThread());
4423 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock,
4426 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4427 AFS_TRACE_LEVEL_VERBOSE_2,
4428 "AFSBuildRootVolume Locating volume for target %I64X\n",
4431 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
4433 (AFSBTreeEntry **)&pVolumeCB);
4436 // We can be processing a request for a target that is on a volume
4437 // we have never seen before.
4440 if( pVolumeCB == NULL)
4444 // Locking is held correctly in init routine
4447 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
4450 // Go init the root of the volume
4453 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4454 AFS_TRACE_LEVEL_VERBOSE_2,
4455 "AFSBuildRootVolume Initializing root for FID %08lX-%08lX-%08lX-%08lX\n",
4461 ntStatus = AFSInitVolume( AuthGroup,
4465 if( !NT_SUCCESS( ntStatus))
4468 try_return( ntStatus);
4472 // pVolumeCB->VolumeLock is held exclusive
4473 // pVolumeCB->VolumeReferenceCount has been incremented
4474 // pVolumeCB->RootFcb == NULL
4477 bReleaseVolumeLock = TRUE;
4483 // AFSInitVolume returns with a VolumeReferenceCount
4484 // obtain one to match
4487 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
4489 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
4490 AFS_TRACE_LEVEL_VERBOSE,
4491 "AFSBuildRootVolume Increment count on volume %p Cnt %d\n",
4495 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
4499 if( pVolumeCB->RootFcb == NULL)
4502 if ( bReleaseVolumeLock == FALSE)
4505 AFSAcquireExcl( pVolumeCB->VolumeLock,
4508 bReleaseVolumeLock = TRUE;
4512 // Initialize the root fcb for this volume
4515 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
4518 if( !NT_SUCCESS( ntStatus))
4521 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
4523 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
4524 AFS_TRACE_LEVEL_VERBOSE,
4525 "AFSBuildRootVolume Decrement count on volume %p Cnt %d\n",
4529 AFSReleaseResource( pVolumeCB->VolumeLock);
4531 try_return( ntStatus);
4535 // Drop the lock acquired above
4538 AFSReleaseResource( &pVolumeCB->RootFcb->NPFcb->Resource);
4541 if ( bReleaseVolumeLock == TRUE)
4544 AFSReleaseResource( pVolumeCB->VolumeLock);
4547 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4548 AFS_TRACE_LEVEL_VERBOSE_2,
4549 "AFSBuildRootVolume Evaluated target of %wZ FID %08lX-%08lX-%08lX-%08lX as root volume\n",
4550 &pVolumeCB->DirectoryCB->NameInformation.FileName,
4551 pVolumeCB->ObjectInformation.FileId.Cell,
4552 pVolumeCB->ObjectInformation.FileId.Volume,
4553 pVolumeCB->ObjectInformation.FileId.Vnode,
4554 pVolumeCB->ObjectInformation.FileId.Unique);
4556 *TargetVolumeCB = pVolumeCB;
4567 AFSProcessDFSLink( IN AFSDirectoryCB *DirEntry,
4568 IN PFILE_OBJECT FileObject,
4569 IN UNICODE_STRING *RemainingPath,
4573 NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
4574 UNICODE_STRING uniReparseName;
4575 UNICODE_STRING uniMUPDeviceName;
4576 UNICODE_STRING uniIOMgrDeviceName;
4577 AFSDirEnumEntry *pDirEntry = NULL;
4583 // Build up the name to reparse
4586 RtlInitUnicodeString( &uniMUPDeviceName,
4589 RtlInitUnicodeString( &uniIOMgrDeviceName,
4592 uniReparseName.Length = 0;
4593 uniReparseName.Buffer = NULL;
4596 // Be sure we have a target name
4599 if( DirEntry->NameInformation.TargetName.Length == 0)
4602 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
4607 if( !NT_SUCCESS( ntStatus) ||
4608 pDirEntry->TargetNameLength == 0)
4611 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4612 AFS_TRACE_LEVEL_ERROR,
4613 "AFSProcessDFSLink EvaluateTargetByID failed for Fcb %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4614 &DirEntry->NameInformation.FileName,
4615 DirEntry->ObjectInformation->FileId.Cell,
4616 DirEntry->ObjectInformation->FileId.Volume,
4617 DirEntry->ObjectInformation->FileId.Vnode,
4618 DirEntry->ObjectInformation->FileId.Unique,
4621 if( NT_SUCCESS( ntStatus))
4624 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
4627 try_return( ntStatus);
4631 // Update the target name
4634 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
4637 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
4639 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
4640 (USHORT)pDirEntry->TargetNameLength);
4642 if( !NT_SUCCESS( ntStatus))
4645 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4646 AFS_TRACE_LEVEL_ERROR,
4647 "AFSProcessDFSLink UpdateTargetName failed for Fcb %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4648 &DirEntry->NameInformation.FileName,
4649 DirEntry->ObjectInformation->FileId.Cell,
4650 DirEntry->ObjectInformation->FileId.Volume,
4651 DirEntry->ObjectInformation->FileId.Vnode,
4652 DirEntry->ObjectInformation->FileId.Unique,
4655 AFSReleaseResource( &DirEntry->NonPaged->Lock);
4657 try_return( ntStatus);
4660 AFSConvertToShared( &DirEntry->NonPaged->Lock);
4664 AFSAcquireShared( &DirEntry->NonPaged->Lock,
4668 uniReparseName.MaximumLength = uniMUPDeviceName.Length +
4670 DirEntry->NameInformation.TargetName.Length +
4673 if( RemainingPath != NULL &&
4674 RemainingPath->Length > 0)
4677 uniReparseName.MaximumLength += RemainingPath->Length;
4681 // Allocate the reparse buffer
4684 uniReparseName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
4685 uniReparseName.MaximumLength,
4686 AFS_REPARSE_NAME_TAG);
4688 if( uniReparseName.Buffer == NULL)
4691 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4692 AFS_TRACE_LEVEL_ERROR,
4693 "AFSProcessDFSLink uniReparseName.Buffer == NULL Fcb %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4694 &DirEntry->NameInformation.FileName,
4695 DirEntry->ObjectInformation->FileId.Cell,
4696 DirEntry->ObjectInformation->FileId.Volume,
4697 DirEntry->ObjectInformation->FileId.Vnode,
4698 DirEntry->ObjectInformation->FileId.Unique,
4699 STATUS_INSUFFICIENT_RESOURCES);
4701 AFSReleaseResource( &DirEntry->NonPaged->Lock);
4703 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4707 // Start building the name
4710 if ( DirEntry->NameInformation.TargetName.Buffer[ 0] != L'\\' &&
4711 DirEntry->NameInformation.TargetName.Buffer[ 1] == L':')
4714 RtlCopyMemory( uniReparseName.Buffer,
4715 uniIOMgrDeviceName.Buffer,
4716 uniIOMgrDeviceName.Length);
4718 uniReparseName.Length = uniIOMgrDeviceName.Length;
4723 RtlCopyMemory( uniReparseName.Buffer,
4724 uniMUPDeviceName.Buffer,
4725 uniMUPDeviceName.Length);
4727 uniReparseName.Length = uniMUPDeviceName.Length;
4729 if( DirEntry->NameInformation.TargetName.Buffer[ 0] != L'\\')
4732 uniReparseName.Buffer[ uniReparseName.Length/sizeof( WCHAR)] = L'\\';
4734 uniReparseName.Length += sizeof( WCHAR);
4738 RtlCopyMemory( &uniReparseName.Buffer[ uniReparseName.Length/sizeof( WCHAR)],
4739 DirEntry->NameInformation.TargetName.Buffer,
4740 DirEntry->NameInformation.TargetName.Length);
4742 uniReparseName.Length += DirEntry->NameInformation.TargetName.Length;
4744 AFSReleaseResource( &DirEntry->NonPaged->Lock);
4746 if( RemainingPath != NULL &&
4747 RemainingPath->Length > 0)
4750 if( uniReparseName.Buffer[ (uniReparseName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
4751 RemainingPath->Buffer[ 0] != L'\\')
4754 uniReparseName.Buffer[ uniReparseName.Length/sizeof( WCHAR)] = L'\\';
4756 uniReparseName.Length += sizeof( WCHAR);
4759 RtlCopyMemory( &uniReparseName.Buffer[ uniReparseName.Length/sizeof( WCHAR)],
4760 RemainingPath->Buffer,
4761 RemainingPath->Length);
4763 uniReparseName.Length += RemainingPath->Length;
4767 // Update the name in the file object
4770 if( FileObject->FileName.Buffer != NULL)
4773 AFSExFreePoolWithTag( FileObject->FileName.Buffer, 0);
4776 FileObject->FileName = uniReparseName;
4778 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4779 AFS_TRACE_LEVEL_VERBOSE,
4780 "AFSProcessDFSLink Reparsing access to Fcb %wZ FID %08lX-%08lX-%08lX-%08lX to %wZ\n",
4781 &DirEntry->NameInformation.FileName,
4782 DirEntry->ObjectInformation->FileId.Cell,
4783 DirEntry->ObjectInformation->FileId.Volume,
4784 DirEntry->ObjectInformation->FileId.Vnode,
4785 DirEntry->ObjectInformation->FileId.Unique,
4789 // Return status reparse ...
4792 ntStatus = STATUS_REPARSE;
4799 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);