2 * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
3 * Copyright (c) 2009, 2010, 2011 Your File System, Inc.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * - Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
14 * this list of conditions and the following disclaimer in the
16 * and/or other materials provided with the distribution.
17 * - Neither the names of Kernel Drivers, LLC and Your File System, Inc.
18 * nor the names of their contributors may be used to endorse or promote
19 * products derived from this software without specific prior written
20 * permission from Kernel Drivers, LLC and Your File System, Inc.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
26 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 // File: AFSNameSupport.cpp
39 #include "AFSCommon.h"
42 AFSLocateNameEntry( IN GUID *AuthGroup,
43 IN PFILE_OBJECT FileObject,
44 IN UNICODE_STRING *RootPathName,
45 IN UNICODE_STRING *ParsedPathName,
46 IN AFSNameArrayHdr *NameArray,
48 OUT AFSVolumeCB **VolumeCB,
49 IN OUT AFSDirectoryCB **ParentDirectoryCB,
50 OUT AFSDirectoryCB **DirectoryCB,
51 OUT PUNICODE_STRING ComponentName)
54 NTSTATUS ntStatus = STATUS_SUCCESS;
55 UNICODE_STRING uniPathName, uniComponentName, uniRemainingPath, uniSearchName, uniFullPathName;
57 AFSDirectoryCB *pDirEntry = NULL, *pParentDirEntry = NULL;
58 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
59 UNICODE_STRING uniSysName;
60 ULONG ulSubstituteIndex = 0;
61 BOOLEAN bSubstituteName = FALSE;
62 AFSNameArrayHdr *pNameArray = NameArray;
63 BOOLEAN bAllocatedSymLinkBuffer = FALSE;
64 UNICODE_STRING uniRelativeName, uniNoOpName;
65 AFSObjectInfoCB *pCurrentObject = NULL;
66 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: %08lX) 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: %08lX) 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: %08lX) 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: %08lX) 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: %08lX) 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: %08lX) 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: %08lX) 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: %08lX) 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: %08lX) 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: %08lX) 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: %08lX) 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: %08lX) 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: %08lX) 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: %08lX) 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: %08lX) 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 %08lX 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 %08lX 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: %08lX) 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: %08lX) 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 %08lX 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: %08lX) 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: %08lX) 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: %08lX) 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: %08lX) 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: %08lX) 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: %08lX) 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: %08lX) 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: %08lX) 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: %08lX) 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: %08lX) 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: %08lX) 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: %08lX) 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: %08lX) 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: %08lX) Searching for entry %wZ short name\n",
1445 AFSLocateShortNameDirEntry( pParentDirEntry->ObjectInformation->Specific.Directory.ShortNameTree,
1450 if( pDirEntry == NULL)
1454 // If we substituted a name then reset our search name and try again
1457 if( bSubstituteName)
1460 AFSExFreePoolWithTag( uniSearchName.Buffer, 0);
1462 uniSearchName = uniComponentName;
1464 bSubstituteName = FALSE;
1466 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1468 continue; // while( pDirEntry == NULL)
1471 if( uniRemainingPath.Length > 0)
1474 ntStatus = STATUS_OBJECT_PATH_NOT_FOUND;
1479 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
1481 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1482 AFS_TRACE_LEVEL_VERBOSE,
1483 "AFSLocateNameEntry (FO: %08lX) Returning name not found for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1486 pCurrentObject->FileId.Cell,
1487 pCurrentObject->FileId.Volume,
1488 pCurrentObject->FileId.Vnode,
1489 pCurrentObject->FileId.Unique);
1492 // Pass back the directory entries
1495 *ParentDirectoryCB = pParentDirEntry;
1497 *DirectoryCB = NULL;
1499 *VolumeCB = pCurrentVolume;
1501 if( ComponentName != NULL)
1504 *ComponentName = uniComponentName;
1507 *RootPathName = uniFullPathName;
1510 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1513 // Node name not found so get out
1516 try_return( ntStatus); // while( pDirEntry == NULL)
1523 // Here we have a match on the case insensitive lookup for the name. If there
1524 // Is more than one link entry for this node then fail the lookup request
1527 if( !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD) ||
1528 pDirEntry->CaseInsensitiveList.fLink != NULL)
1532 // Increment our dir entry ref count since we will decrement it on exit
1535 lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
1537 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1538 AFS_TRACE_LEVEL_VERBOSE,
1539 "AFSLocateNameEntry Increment5 count on %wZ DE %p Ccb %p Cnt %d\n",
1540 &pDirEntry->NameInformation.FileName,
1545 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1547 try_return(ntStatus = STATUS_OBJECT_NAME_COLLISION);
1552 if( pDirEntry != NULL)
1556 // If the verify flag is set on the parent and the current entry is deleted
1557 // revalidate the parent and search again.
1560 if( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED) &&
1561 BooleanFlagOn( pParentDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY))
1564 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1566 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1567 AFS_TRACE_LEVEL_VERBOSE,
1568 "AFSLocateNameEntry (FO: %08lX) Verifying(2) parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1570 &pParentDirEntry->NameInformation.FileName,
1571 pParentDirEntry->ObjectInformation->FileId.Cell,
1572 pParentDirEntry->ObjectInformation->FileId.Volume,
1573 pParentDirEntry->ObjectInformation->FileId.Vnode,
1574 pParentDirEntry->ObjectInformation->FileId.Unique);
1577 // Directory TreeLock should be exclusively held
1580 AFSAcquireExcl( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
1583 ntStatus = AFSVerifyEntry( AuthGroup,
1586 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1588 if( !NT_SUCCESS( ntStatus))
1591 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1592 AFS_TRACE_LEVEL_ERROR,
1593 "AFSLocateNameEntry (FO: %08lX) Failed to verify(2) parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1595 &pParentDirEntry->NameInformation.FileName,
1596 pParentDirEntry->ObjectInformation->FileId.Cell,
1597 pParentDirEntry->ObjectInformation->FileId.Volume,
1598 pParentDirEntry->ObjectInformation->FileId.Vnode,
1599 pParentDirEntry->ObjectInformation->FileId.Unique,
1602 try_return( ntStatus);
1605 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1606 AFS_TRACE_LEVEL_VERBOSE,
1607 "AFSLocateNameEntry (FO: %08lX) Reprocessing component %wZ in parent %wZ\n",
1610 &pParentDirEntry->NameInformation.FileName);
1619 // Increment our dir entry ref count
1622 lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
1624 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1625 AFS_TRACE_LEVEL_VERBOSE,
1626 "AFSLocateNameEntry Increment5 count on %wZ DE %p Ccb %p Cnt %d\n",
1627 &pDirEntry->NameInformation.FileName,
1633 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1635 } // End while( pDirEntry == NULL)
1638 // If we have a dirEntry for this component, perform some basic validation on it
1641 if( pDirEntry != NULL &&
1642 BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
1645 pCurrentObject = pDirEntry->ObjectInformation;
1647 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1648 AFS_TRACE_LEVEL_ERROR,
1649 "AFSLocateNameEntry (FO: %08lX) Deleted entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1651 &pDirEntry->NameInformation.FileName,
1652 pCurrentObject->FileId.Cell,
1653 pCurrentObject->FileId.Volume,
1654 pCurrentObject->FileId.Vnode,
1655 pCurrentObject->FileId.Unique);
1658 // This entry was deleted through the invalidation call back so perform cleanup
1662 pParentObjectInfo = pCurrentObject->ParentObjectInformation;
1664 ASSERT( pParentObjectInfo != NULL);
1666 AFSAcquireExcl( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
1669 AFSAcquireExcl( pCurrentObject->VolumeCB->ObjectInfoTree.TreeLock,
1672 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
1674 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1675 AFS_TRACE_LEVEL_VERBOSE,
1676 "AFSLocateNameEntry Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
1677 &pDirEntry->NameInformation.FileName,
1682 ASSERT( lCount >= 0);
1687 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING|AFS_SUBSYSTEM_CLEANUP_PROCESSING,
1688 AFS_TRACE_LEVEL_VERBOSE,
1689 "AFSLocateNameEntry Deleting dir entry %08lX (%08lX) for %wZ\n",
1692 &pDirEntry->NameInformation.FileName);
1695 // Remove and delete the directory entry from the parent list
1698 AFSDeleteDirEntry( pParentObjectInfo,
1701 AFSAcquireShared( &pCurrentObject->NonPagedInfo->ObjectInfoLock,
1704 if( pCurrentObject->ObjectReferenceCount <= 0)
1707 if( BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_INSERTED_HASH_TREE))
1710 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
1711 AFS_TRACE_LEVEL_VERBOSE,
1712 "AFSLocateNameEntry Removing object %08lX from volume tree\n",
1715 AFSRemoveHashEntry( &pCurrentObject->VolumeCB->ObjectInfoTree.TreeHead,
1716 &pCurrentObject->TreeEntry);
1718 ClearFlag( pCurrentObject->Flags, AFS_OBJECT_INSERTED_HASH_TREE);
1722 AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock);
1727 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1728 AFS_TRACE_LEVEL_VERBOSE,
1729 "AFSLocateNameEntry Setting DELETE flag in dir entry %p for %wZ\n",
1731 &pDirEntry->NameInformation.FileName);
1733 SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
1735 AFSRemoveNameEntry( pParentObjectInfo,
1739 AFSReleaseResource( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
1741 AFSReleaseResource( pCurrentObject->VolumeCB->ObjectInfoTree.TreeLock);
1744 // We deleted the dir entry so check if there is any remaining portion
1745 // of the name to process.
1748 if( uniRemainingPath.Length > 0)
1750 ntStatus = STATUS_OBJECT_PATH_NOT_FOUND;
1755 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
1757 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1758 AFS_TRACE_LEVEL_VERBOSE,
1759 "AFSLocateNameEntry (FO: %08lX) Returning name not found(2) for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1762 pCurrentObject->FileId.Cell,
1763 pCurrentObject->FileId.Volume,
1764 pCurrentObject->FileId.Vnode,
1765 pCurrentObject->FileId.Unique);
1768 // Pass back the directory entries
1771 *ParentDirectoryCB = pParentDirEntry;
1773 *DirectoryCB = NULL;
1775 *VolumeCB = pCurrentVolume;
1777 if( ComponentName != NULL)
1780 *ComponentName = uniComponentName;
1783 *RootPathName = uniFullPathName;
1787 if( ntStatus != STATUS_SUCCESS)
1790 try_return( ntStatus);
1794 // Decrement the previous parent
1797 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
1799 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1800 AFS_TRACE_LEVEL_VERBOSE,
1801 "AFSLocateNameEntry Decrement5 count on Parent %wZ DE %p Ccb %p Cnt %d\n",
1802 &pParentDirEntry->NameInformation.FileName,
1807 ASSERT( lCount >= 0);
1810 // If we ended up substituting a name in the component then update
1811 // the full path and update the pointers
1814 if( bSubstituteName)
1817 BOOLEAN bRelativeOpen = FALSE;
1819 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1820 AFS_TRACE_LEVEL_VERBOSE_2,
1821 "AFSLocateNameEntry (FO: %08lX) Substituting %wZ into %wZ Index %08lX\n",
1827 if( FileObject != NULL &&
1828 FileObject->RelatedFileObject != NULL)
1831 bRelativeOpen = TRUE;
1835 // AFSSubstituteNameInPath will replace the uniFullPathName.Buffer
1836 // and free the prior Buffer contents but only if the fourth
1837 // parameter is TRUE.
1840 ntStatus = AFSSubstituteNameInPath( &uniFullPathName,
1845 bAllocatedSymLinkBuffer ||
1848 if( !NT_SUCCESS( ntStatus))
1851 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1852 AFS_TRACE_LEVEL_ERROR,
1853 "AFSLocateNameEntry (FO: %08lX) Failure to substitute %wZ into %wZ Index %08lX Status %08lX\n",
1860 try_return( ntStatus);
1864 // We have substituted a name into the buffer so if we do this again for this
1865 // path, we need to free up the buffer we allocated.
1868 bSubstitutedName = TRUE;
1872 // Update the search parameters
1875 uniPathName = uniRemainingPath;
1878 // Check if the is a SymLink entry but has no Target FileID or Name. In this
1879 // case it might be a DFS Link so let's go and evaluate it to be sure
1882 if( pCurrentObject->FileType == AFS_FILE_TYPE_SYMLINK &&
1883 pCurrentObject->TargetFileId.Vnode == 0 &&
1884 pCurrentObject->TargetFileId.Unique == 0 &&
1885 pDirEntry->NameInformation.TargetName.Length == 0)
1888 ntStatus = AFSValidateSymLink( AuthGroup,
1891 if( !NT_SUCCESS( ntStatus))
1894 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1895 AFS_TRACE_LEVEL_ERROR,
1896 "AFSLocateNameEntry (FO: %08lX) Failed to evaluate possible DFS Link %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1898 &pDirEntry->NameInformation.FileName,
1899 pCurrentObject->FileId.Cell,
1900 pCurrentObject->FileId.Volume,
1901 pCurrentObject->FileId.Vnode,
1902 pCurrentObject->FileId.Unique,
1905 try_return( ntStatus);
1910 // Update the name array
1913 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1914 AFS_TRACE_LEVEL_VERBOSE,
1915 "AFSLocateNameEntry (FO: %08lX) Inserting name array entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1917 &pDirEntry->NameInformation.FileName,
1918 pCurrentObject->FileId.Cell,
1919 pCurrentObject->FileId.Volume,
1920 pCurrentObject->FileId.Vnode,
1921 pCurrentObject->FileId.Unique);
1923 ntStatus = AFSInsertNextElement( pNameArray,
1926 if( !NT_SUCCESS( ntStatus))
1929 try_return( ntStatus);
1935 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1936 AFS_TRACE_LEVEL_VERBOSE,
1937 "AFSLocateNameEntry (FO: %08lX) Completed processing %wZ Status %08lX\n",
1942 if( ( !NT_SUCCESS( ntStatus) &&
1943 ntStatus != STATUS_OBJECT_NAME_NOT_FOUND) ||
1944 ntStatus == STATUS_REPARSE)
1947 if( pDirEntry != NULL)
1950 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
1952 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1953 AFS_TRACE_LEVEL_VERBOSE,
1954 "AFSLocateNameEntry Decrement6 count on %wZ DE %p Ccb %p Cnt %d\n",
1955 &pDirEntry->NameInformation.FileName,
1960 ASSERT( lCount >= 0);
1962 else if( pParentDirEntry != NULL)
1965 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
1967 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1968 AFS_TRACE_LEVEL_VERBOSE,
1969 "AFSLocateNameEntry Decrement7 count on %wZ DE %p Ccb %p Cnt %d\n",
1970 &pParentDirEntry->NameInformation.FileName,
1975 ASSERT( lCount >= 0);
1978 if( bReleaseCurrentVolume)
1981 ASSERT( pCurrentVolume->VolumeReferenceCount > 1);
1983 lCount = InterlockedDecrement( &pCurrentVolume->VolumeReferenceCount);
1985 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
1986 AFS_TRACE_LEVEL_VERBOSE,
1987 "AFSLocateNameEntry Decrement3 count on volume %08lX Cnt %d\n",
1992 if( RootPathName->Buffer != uniFullPathName.Buffer)
1995 AFSExFreePoolWithTag( uniFullPathName.Buffer, 0);
2001 if( *ParentDirectoryCB != NULL)
2004 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2005 AFS_TRACE_LEVEL_VERBOSE,
2006 "AFSLocateNameEntry Count on Parent %wZ DE %p Ccb %p Cnt %d\n",
2007 &(*ParentDirectoryCB)->NameInformation.FileName,
2010 (*ParentDirectoryCB)->DirOpenReferenceCount);
2013 if( *DirectoryCB != NULL)
2016 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2017 AFS_TRACE_LEVEL_VERBOSE,
2018 "AFSLocateNameEntry Count on %wZ DE %p Ccb %p Cnt %d\n",
2019 &(*DirectoryCB)->NameInformation.FileName,
2022 (*DirectoryCB)->DirOpenReferenceCount);
2026 if( bSubstituteName &&
2027 uniSearchName.Buffer != NULL)
2030 AFSExFreePoolWithTag( uniSearchName.Buffer, 0);
2038 AFSCreateDirEntry( IN GUID *AuthGroup,
2039 IN AFSObjectInfoCB *ParentObjectInfo,
2040 IN AFSDirectoryCB *ParentDirCB,
2041 IN PUNICODE_STRING FileName,
2042 IN PUNICODE_STRING ComponentName,
2043 IN ULONG Attributes,
2044 IN OUT AFSDirectoryCB **DirEntry)
2047 NTSTATUS ntStatus = STATUS_SUCCESS;
2048 AFSDirectoryCB *pDirNode = NULL, *pExistingDirNode = NULL;
2049 UNICODE_STRING uniShortName;
2050 LARGE_INTEGER liFileSize = {0,0};
2056 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2057 AFS_TRACE_LEVEL_VERBOSE_2,
2058 "AFSCreateDirEntry Creating dir entry in parent %wZ FID %08lX-%08lX-%08lX-%08lX Component %wZ Attribs %08lX\n",
2059 &ParentDirCB->NameInformation.FileName,
2060 ParentObjectInfo->FileId.Cell,
2061 ParentObjectInfo->FileId.Volume,
2062 ParentObjectInfo->FileId.Vnode,
2063 ParentObjectInfo->FileId.Unique,
2068 // OK, before inserting the node into the parent tree, issue
2069 // the request to the service for node creation
2070 // We will need to drop the lock on the parent node since the create
2071 // could cause a callback into the file system to invalidate it's cache
2074 ntStatus = AFSNotifyFileCreate( AuthGroup,
2082 // If the returned status is STATUS_REPARSE then the entry exists
2083 // and we raced, get out.
2085 if( ntStatus == STATUS_REPARSE)
2088 *DirEntry = pDirNode;
2090 try_return( ntStatus = STATUS_SUCCESS);
2093 if( !NT_SUCCESS( ntStatus))
2096 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2097 AFS_TRACE_LEVEL_ERROR,
2098 "AFSCreateDirEntry Failed to create dir entry in parent %wZ FID %08lX-%08lX-%08lX-%08lX Component %wZ Attribs %08lX Status %08lX\n",
2099 &ParentDirCB->NameInformation.FileName,
2100 ParentObjectInfo->FileId.Cell,
2101 ParentObjectInfo->FileId.Volume,
2102 ParentObjectInfo->FileId.Vnode,
2103 ParentObjectInfo->FileId.Unique,
2108 try_return( ntStatus);
2111 AFSAcquireExcl( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2115 // Before attempting to insert the new entry, check if we need to validate the parent
2118 if( BooleanFlagOn( ParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY))
2121 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2122 AFS_TRACE_LEVEL_VERBOSE,
2123 "AFSCreateDirEntry Verifying parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2124 &ParentDirCB->NameInformation.FileName,
2125 ParentObjectInfo->FileId.Cell,
2126 ParentObjectInfo->FileId.Volume,
2127 ParentObjectInfo->FileId.Vnode,
2128 ParentObjectInfo->FileId.Unique);
2130 ntStatus = AFSVerifyEntry( AuthGroup,
2133 if( !NT_SUCCESS( ntStatus))
2136 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2137 AFS_TRACE_LEVEL_ERROR,
2138 "AFSCreateDirEntry Failed to verify parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2139 &ParentDirCB->NameInformation.FileName,
2140 ParentObjectInfo->FileId.Cell,
2141 ParentObjectInfo->FileId.Volume,
2142 ParentObjectInfo->FileId.Vnode,
2143 ParentObjectInfo->FileId.Unique,
2146 AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2148 try_return( ntStatus);
2153 // Check for the entry in the event we raced with some other thread
2156 AFSLocateCaseSensitiveDirEntry( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
2157 (ULONG)pDirNode->CaseSensitiveTreeEntry.HashIndex,
2160 if( pExistingDirNode != NULL)
2162 if (AFSIsEqualFID( &pDirNode->ObjectInformation->FileId,
2163 &pExistingDirNode->ObjectInformation->FileId))
2166 AFSDeleteDirEntry( ParentObjectInfo,
2169 lCount = InterlockedIncrement( &pExistingDirNode->DirOpenReferenceCount);
2171 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2172 AFS_TRACE_LEVEL_VERBOSE,
2173 "AFSCreateDirEntry Increment count on %wZ DE %p Cnt %d\n",
2174 &pExistingDirNode->NameInformation.FileName,
2178 *DirEntry = pExistingDirNode;
2180 AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2182 try_return( ntStatus = STATUS_SUCCESS);
2188 // Need to tear down this entry and rebuild it below
2191 if( pExistingDirNode->DirOpenReferenceCount <= 0)
2194 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2195 AFS_TRACE_LEVEL_VERBOSE,
2196 "AFSCreateDirEntry Different FIDs - Deleting DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
2198 &pExistingDirNode->NameInformation.FileName,
2199 pExistingDirNode->ObjectInformation->FileId.Cell,
2200 pExistingDirNode->ObjectInformation->FileId.Volume,
2201 pExistingDirNode->ObjectInformation->FileId.Vnode,
2202 pExistingDirNode->ObjectInformation->FileId.Unique,
2203 pDirNode->ObjectInformation->FileId.Cell,
2204 pDirNode->ObjectInformation->FileId.Volume,
2205 pDirNode->ObjectInformation->FileId.Vnode,
2206 pDirNode->ObjectInformation->FileId.Unique);
2208 AFSDeleteDirEntry( ParentObjectInfo,
2214 SetFlag( pExistingDirNode->Flags, AFS_DIR_ENTRY_DELETED);
2216 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2217 AFS_TRACE_LEVEL_VERBOSE,
2218 "AFSCreateDirEntry Different FIDs - Removing DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
2220 &pExistingDirNode->NameInformation.FileName,
2221 pExistingDirNode->ObjectInformation->FileId.Cell,
2222 pExistingDirNode->ObjectInformation->FileId.Volume,
2223 pExistingDirNode->ObjectInformation->FileId.Vnode,
2224 pExistingDirNode->ObjectInformation->FileId.Unique,
2225 pDirNode->ObjectInformation->FileId.Cell,
2226 pDirNode->ObjectInformation->FileId.Volume,
2227 pDirNode->ObjectInformation->FileId.Vnode,
2228 pDirNode->ObjectInformation->FileId.Unique);
2230 AFSRemoveNameEntry( ParentObjectInfo,
2237 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2238 AFS_TRACE_LEVEL_VERBOSE_2,
2239 "AFSCreateDirEntry Inserting dir entry in parent %wZ FID %08lX-%08lX-%08lX-%08lX Component %wZ\n",
2240 &ParentDirCB->NameInformation.FileName,
2241 ParentObjectInfo->FileId.Cell,
2242 ParentObjectInfo->FileId.Volume,
2243 ParentObjectInfo->FileId.Vnode,
2244 ParentObjectInfo->FileId.Unique,
2248 // Insert the directory node
2251 AFSInsertDirectoryNode( ParentObjectInfo,
2255 lCount = InterlockedIncrement( &pDirNode->DirOpenReferenceCount);
2257 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2258 AFS_TRACE_LEVEL_VERBOSE,
2259 "AFSCreateDirEntry Increment2 count on %wZ DE %p Cnt %d\n",
2260 &pDirNode->NameInformation.FileName,
2265 // Pass back the dir entry
2268 *DirEntry = pDirNode;
2270 AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2281 AFSInsertDirectoryNode( IN AFSObjectInfoCB *ParentObjectInfo,
2282 IN AFSDirectoryCB *DirEntry,
2283 IN BOOLEAN InsertInEnumList)
2291 ASSERT( ExIsResourceAcquiredExclusiveLite( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock));
2294 // Insert the node into the directory node tree
2297 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2298 AFS_TRACE_LEVEL_VERBOSE,
2299 "AFSInsertDirectoryNode Insert DE %p for %wZ Clearing NOT_IN flag\n",
2301 &DirEntry->NameInformation.FileName);
2303 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
2305 if( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead == NULL)
2308 ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = DirEntry;
2310 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2311 AFS_TRACE_LEVEL_VERBOSE,
2312 "AFSInsertDirectoryNode Insert DE %p to head of case sensitive tree for %wZ\n",
2314 &DirEntry->NameInformation.FileName);
2319 AFSInsertCaseSensitiveDirEntry( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
2322 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2323 AFS_TRACE_LEVEL_VERBOSE,
2324 "AFSInsertDirectoryNode Insert DE %p to case sensitive tree for %wZ\n",
2326 &DirEntry->NameInformation.FileName);
2329 if( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead == NULL)
2332 ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = DirEntry;
2334 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
2336 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2337 AFS_TRACE_LEVEL_VERBOSE,
2338 "AFSInsertDirectoryNode Insert DE %p to head of case insensitive tree for %wZ\n",
2340 &DirEntry->NameInformation.FileName);
2345 AFSInsertCaseInsensitiveDirEntry( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
2348 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2349 AFS_TRACE_LEVEL_VERBOSE,
2350 "AFSInsertDirectoryNode Insert DE %p to case insensitive tree for %wZ\n",
2352 &DirEntry->NameInformation.FileName);
2356 // Into the shortname tree
2359 if( DirEntry->Type.Data.ShortNameTreeEntry.HashIndex != 0)
2362 if( ParentObjectInfo->Specific.Directory.ShortNameTree == NULL)
2365 ParentObjectInfo->Specific.Directory.ShortNameTree = DirEntry;
2367 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2368 AFS_TRACE_LEVEL_VERBOSE,
2369 "AFSInsertDirectoryNode Insert DE %p to head of shortname tree for %wZ\n",
2371 &DirEntry->NameInformation.FileName);
2373 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
2378 if( !NT_SUCCESS( AFSInsertShortNameDirEntry( ParentObjectInfo->Specific.Directory.ShortNameTree,
2381 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2382 AFS_TRACE_LEVEL_VERBOSE,
2383 "AFSInsertDirectoryNode Failed to insert DE %p to shortname tree for %wZ\n",
2385 &DirEntry->NameInformation.FileName);
2389 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
2391 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2392 AFS_TRACE_LEVEL_VERBOSE,
2393 "AFSInsertDirectoryNode Insert DE %p to shortname tree for %wZ\n",
2395 &DirEntry->NameInformation.FileName);
2400 if( InsertInEnumList)
2404 // And insert the node into the directory list
2407 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2408 AFS_TRACE_LEVEL_VERBOSE,
2409 "AFSInsertDirectoryNode Inserting entry %08lX %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2411 &DirEntry->NameInformation.FileName,
2412 DirEntry->ObjectInformation->FileId.Cell,
2413 DirEntry->ObjectInformation->FileId.Volume,
2414 DirEntry->ObjectInformation->FileId.Vnode,
2415 DirEntry->ObjectInformation->FileId.Unique);
2417 if( ParentObjectInfo->Specific.Directory.DirectoryNodeListHead == NULL)
2420 ParentObjectInfo->Specific.Directory.DirectoryNodeListHead = DirEntry;
2425 ParentObjectInfo->Specific.Directory.DirectoryNodeListTail->ListEntry.fLink = (void *)DirEntry;
2427 DirEntry->ListEntry.bLink = (void *)ParentObjectInfo->Specific.Directory.DirectoryNodeListTail;
2430 ParentObjectInfo->Specific.Directory.DirectoryNodeListTail = DirEntry;
2432 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST);
2434 lCount = InterlockedIncrement( &ParentObjectInfo->Specific.Directory.DirectoryNodeCount);
2436 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
2437 AFS_TRACE_LEVEL_VERBOSE,
2438 "AFSInsertDirectoryNode Adding entry %wZ Inc Count %d to parent FID %08lX-%08lX-%08lX-%08lX\n",
2439 &DirEntry->NameInformation.FileName,
2441 ParentObjectInfo->FileId.Cell,
2442 ParentObjectInfo->FileId.Volume,
2443 ParentObjectInfo->FileId.Vnode,
2444 ParentObjectInfo->FileId.Unique);
2452 AFSDeleteDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
2453 IN AFSDirectoryCB *DirEntry)
2456 NTSTATUS ntStatus = STATUS_SUCCESS;
2462 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2463 AFS_TRACE_LEVEL_VERBOSE,
2464 "AFSDeleteDirEntry Deleting dir entry in parent %08lX Entry %08lX %wZ FID %08lX-%08lX-%08lX-%08lX RefCount %08lX\n",
2467 &DirEntry->NameInformation.FileName,
2468 DirEntry->ObjectInformation->FileId.Cell,
2469 DirEntry->ObjectInformation->FileId.Volume,
2470 DirEntry->ObjectInformation->FileId.Vnode,
2471 DirEntry->ObjectInformation->FileId.Unique,
2472 DirEntry->DirOpenReferenceCount);
2474 ASSERT( DirEntry->DirOpenReferenceCount == 0);
2476 AFSRemoveDirNodeFromParent( ParentObjectInfo,
2481 // Free up the name buffer if it was reallocated
2484 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_RELEASE_NAME_BUFFER))
2487 AFSExFreePoolWithTag( DirEntry->NameInformation.FileName.Buffer, 0);
2490 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER))
2493 AFSExFreePoolWithTag( DirEntry->NameInformation.TargetName.Buffer, 0);
2497 // Dereference the object for this dir entry
2500 ASSERT( DirEntry->ObjectInformation->ObjectReferenceCount > 0);
2502 lCount = AFSObjectInfoDecrement( DirEntry->ObjectInformation);
2504 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2505 AFS_TRACE_LEVEL_VERBOSE,
2506 "AFSDeleteDirEntry Decrement count on object %08lX Cnt %d\n",
2507 DirEntry->ObjectInformation,
2510 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_DELETED) &&
2511 DirEntry->ObjectInformation->Links == 0)
2514 SetFlag( DirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED);
2517 ExDeleteResourceLite( &DirEntry->NonPaged->Lock);
2519 AFSExFreePoolWithTag( DirEntry->NonPaged, AFS_DIR_ENTRY_NP_TAG);
2522 // Free up the dir entry
2525 AFSExFreePoolWithTag( DirEntry, AFS_DIR_ENTRY_TAG);
2532 AFSRemoveDirNodeFromParent( IN AFSObjectInfoCB *ParentObjectInfo,
2533 IN AFSDirectoryCB *DirEntry,
2534 IN BOOLEAN RemoveFromEnumList)
2537 NTSTATUS ntStatus = STATUS_SUCCESS;
2544 ASSERT( ExIsResourceAcquiredExclusiveLite( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock));
2546 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2547 AFS_TRACE_LEVEL_VERBOSE,
2548 "AFSRemoveDirNodeFromParent Removing DirEntry %08lX %wZ FID %08lX-%08lX-%08lX-%08lX from Parent %08lX\n",
2550 &DirEntry->NameInformation.FileName,
2551 DirEntry->ObjectInformation->FileId.Cell,
2552 DirEntry->ObjectInformation->FileId.Volume,
2553 DirEntry->ObjectInformation->FileId.Vnode,
2554 DirEntry->ObjectInformation->FileId.Unique,
2557 if( !BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
2560 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2561 AFS_TRACE_LEVEL_VERBOSE,
2562 "AFSRemoveDirNodeFromParent Removing DirEntry %08lX name %wZ\n",
2564 &DirEntry->NameInformation.FileName);
2566 AFSRemoveNameEntry( ParentObjectInfo,
2572 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2573 AFS_TRACE_LEVEL_VERBOSE,
2574 "AFSRemoveDirNodeFromParent DE %p for %wZ NOT removing entry due to flag set\n",
2576 &DirEntry->NameInformation.FileName);
2580 if( RemoveFromEnumList &&
2581 BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST))
2585 // And remove the entry from the enumeration list
2588 if( DirEntry->ListEntry.fLink == NULL)
2591 ParentObjectInfo->Specific.Directory.DirectoryNodeListTail = (AFSDirectoryCB *)DirEntry->ListEntry.bLink;
2596 ((AFSDirectoryCB *)DirEntry->ListEntry.fLink)->ListEntry.bLink = DirEntry->ListEntry.bLink;
2599 if( DirEntry->ListEntry.bLink == NULL)
2602 ParentObjectInfo->Specific.Directory.DirectoryNodeListHead = (AFSDirectoryCB *)DirEntry->ListEntry.fLink;
2607 ((AFSDirectoryCB *)DirEntry->ListEntry.bLink)->ListEntry.fLink = DirEntry->ListEntry.fLink;
2610 ASSERT( ParentObjectInfo->Specific.Directory.DirectoryNodeCount > 0);
2612 lCount = InterlockedDecrement( &ParentObjectInfo->Specific.Directory.DirectoryNodeCount);
2614 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST);
2616 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
2617 AFS_TRACE_LEVEL_VERBOSE,
2618 "AFSRemoveDirNodeFromParent Removing entry %wZ Dec Count %d to parent FID %08lX-%08lX-%08lX-%08lX\n",
2619 &DirEntry->NameInformation.FileName,
2621 ParentObjectInfo->FileId.Cell,
2622 ParentObjectInfo->FileId.Volume,
2623 ParentObjectInfo->FileId.Vnode,
2624 ParentObjectInfo->FileId.Unique);
2626 DirEntry->ListEntry.fLink = NULL;
2627 DirEntry->ListEntry.bLink = NULL;
2635 AFSFixupTargetName( IN OUT PUNICODE_STRING FileName,
2636 IN OUT PUNICODE_STRING TargetFileName)
2639 NTSTATUS ntStatus = STATUS_SUCCESS;
2640 UNICODE_STRING uniFileName;
2646 // We will process backwards from the end of the name looking
2647 // for the first \ we encounter
2650 uniFileName.Length = FileName->Length;
2651 uniFileName.MaximumLength = FileName->MaximumLength;
2653 uniFileName.Buffer = FileName->Buffer;
2658 if( uniFileName.Buffer[ (uniFileName.Length/sizeof( WCHAR)) - 1] == L'\\')
2662 // Subtract one more character off of the filename if it is not the root
2665 if( uniFileName.Length > sizeof( WCHAR))
2668 uniFileName.Length -= sizeof( WCHAR);
2672 // Now build up the target name
2675 TargetFileName->Length = FileName->Length - uniFileName.Length;
2678 // If we are not on the root then fixup the name
2681 if( uniFileName.Length > sizeof( WCHAR))
2684 TargetFileName->Length -= sizeof( WCHAR);
2686 TargetFileName->Buffer = &uniFileName.Buffer[ (uniFileName.Length/sizeof( WCHAR)) + 1];
2691 TargetFileName->Buffer = &uniFileName.Buffer[ uniFileName.Length/sizeof( WCHAR)];
2695 // Fixup the passed back filename length
2698 FileName->Length = uniFileName.Length;
2700 TargetFileName->MaximumLength = TargetFileName->Length;
2705 uniFileName.Length -= sizeof( WCHAR);
2713 AFSParseName( IN PIRP Irp,
2715 OUT PUNICODE_STRING FileName,
2716 OUT PUNICODE_STRING ParsedFileName,
2717 OUT PUNICODE_STRING RootFileName,
2718 OUT ULONG *ParseFlags,
2719 OUT AFSVolumeCB **VolumeCB,
2720 OUT AFSDirectoryCB **ParentDirectoryCB,
2721 OUT AFSNameArrayHdr **NameArray)
2724 NTSTATUS ntStatus = STATUS_SUCCESS;
2725 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2726 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2727 UNICODE_STRING uniFullName, uniComponentName, uniRemainingPath;
2729 AFSDirectoryCB *pDirEntry = NULL, *pShareDirEntry = NULL, *pTargetDirEntry = NULL;
2730 USHORT usIndex = 0, usDriveIndex = 0;
2731 AFSCcb *pRelatedCcb = NULL;
2732 AFSNameArrayHdr *pNameArray = NULL, *pRelatedNameArray = NULL;
2733 USHORT usComponentIndex = 0;
2734 USHORT usComponentLength = 0;
2735 AFSVolumeCB *pVolumeCB = NULL;
2736 AFSFcb *pRelatedFcb = NULL;
2737 BOOLEAN bReleaseTreeLock = FALSE;
2738 BOOLEAN bIsAllShare = FALSE;
2745 // Indicate we are opening a root ...
2748 *ParseFlags = AFS_PARSE_FLAG_ROOT_ACCESS;
2750 if( pIrpSp->FileObject->RelatedFileObject != NULL)
2753 pRelatedFcb = (AFSFcb *)pIrpSp->FileObject->RelatedFileObject->FsContext;
2755 pRelatedCcb = (AFSCcb *)pIrpSp->FileObject->RelatedFileObject->FsContext2;
2757 pRelatedNameArray = pRelatedCcb->NameArray;
2759 uniFullName = pIrpSp->FileObject->FileName;
2761 ASSERT( pRelatedFcb != NULL);
2764 // No wild cards in the name
2767 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2768 AFS_TRACE_LEVEL_VERBOSE_2,
2769 "AFSParseName (%08lX) Relative open for %wZ FID %08lX-%08lX-%08lX-%08lX component %wZ\n",
2771 &pRelatedCcb->DirectoryCB->NameInformation.FileName,
2772 pRelatedCcb->DirectoryCB->ObjectInformation->FileId.Cell,
2773 pRelatedCcb->DirectoryCB->ObjectInformation->FileId.Volume,
2774 pRelatedCcb->DirectoryCB->ObjectInformation->FileId.Vnode,
2775 pRelatedCcb->DirectoryCB->ObjectInformation->FileId.Unique,
2778 if( FsRtlDoesNameContainWildCards( &uniFullName))
2781 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2782 AFS_TRACE_LEVEL_ERROR,
2783 "AFSParseName (%08lX) Component %wZ contains wild cards\n",
2787 try_return( ntStatus = STATUS_OBJECT_NAME_INVALID);
2790 pVolumeCB = pRelatedFcb->ObjectInformation->VolumeCB;
2792 pDirEntry = pRelatedCcb->DirectoryCB;
2794 *FileName = pIrpSp->FileObject->FileName;
2797 // Grab the root node while checking state
2800 AFSAcquireShared( pVolumeCB->VolumeLock,
2803 if( BooleanFlagOn( pVolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
2804 BooleanFlagOn( pVolumeCB->Flags, AFS_VOLUME_FLAGS_OFFLINE))
2808 // The volume has been taken off line so fail the access
2811 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2812 AFS_TRACE_LEVEL_ERROR,
2813 "AFSParseName (%08lX) Volume %08lX:%08lX OFFLINE/INVALID\n",
2815 pVolumeCB->ObjectInformation.FileId.Cell,
2816 pVolumeCB->ObjectInformation.FileId.Volume);
2818 AFSReleaseResource( pVolumeCB->VolumeLock);
2820 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
2823 if( BooleanFlagOn( pVolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_VERIFY))
2826 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2827 AFS_TRACE_LEVEL_VERBOSE,
2828 "AFSParseName (%08lX) Verifying root of volume %08lX:%08lX\n",
2830 pVolumeCB->ObjectInformation.FileId.Cell,
2831 pVolumeCB->ObjectInformation.FileId.Volume);
2833 ntStatus = AFSVerifyVolume( (ULONGLONG)PsGetCurrentProcessId(),
2836 if( !NT_SUCCESS( ntStatus))
2839 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2840 AFS_TRACE_LEVEL_ERROR,
2841 "AFSParseName (%08lX) Failed verification of root Status %08lX\n",
2845 AFSReleaseResource( pVolumeCB->VolumeLock);
2847 try_return( ntStatus);
2851 AFSReleaseResource( pVolumeCB->VolumeLock);
2853 if( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY))
2856 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2857 AFS_TRACE_LEVEL_VERBOSE,
2858 "AFSParseName (%08lX) Verifying parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2860 &pDirEntry->NameInformation.FileName,
2861 pDirEntry->ObjectInformation->FileId.Cell,
2862 pDirEntry->ObjectInformation->FileId.Volume,
2863 pDirEntry->ObjectInformation->FileId.Vnode,
2864 pDirEntry->ObjectInformation->FileId.Unique);
2867 // Directory TreeLock should be exclusively held
2870 AFSAcquireExcl( pDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
2873 ntStatus = AFSVerifyEntry( AuthGroup,
2876 AFSReleaseResource( pDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
2878 if( !NT_SUCCESS( ntStatus))
2881 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2882 AFS_TRACE_LEVEL_VERBOSE,
2883 "AFSParseName (%08lX) Failed verification of parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2885 &pDirEntry->NameInformation.FileName,
2886 pDirEntry->ObjectInformation->FileId.Cell,
2887 pDirEntry->ObjectInformation->FileId.Volume,
2888 pDirEntry->ObjectInformation->FileId.Vnode,
2889 pDirEntry->ObjectInformation->FileId.Unique,
2892 try_return( ntStatus);
2897 // Create our full path name buffer
2900 uniFullName.MaximumLength = pRelatedCcb->FullFileName.Length +
2902 pIrpSp->FileObject->FileName.Length +
2905 uniFullName.Length = 0;
2907 uniFullName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2908 uniFullName.MaximumLength,
2909 AFS_NAME_BUFFER_THREE_TAG);
2911 if( uniFullName.Buffer == NULL)
2914 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2915 AFS_TRACE_LEVEL_ERROR,
2916 "AFSParseName (%08lX) Failed to allocate full name buffer\n",
2919 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2922 RtlZeroMemory( uniFullName.Buffer,
2923 uniFullName.MaximumLength);
2925 RtlCopyMemory( uniFullName.Buffer,
2926 pRelatedCcb->FullFileName.Buffer,
2927 pRelatedCcb->FullFileName.Length);
2929 uniFullName.Length = pRelatedCcb->FullFileName.Length;
2931 usComponentIndex = (USHORT)(uniFullName.Length/sizeof( WCHAR));
2933 usComponentLength = pIrpSp->FileObject->FileName.Length;
2935 if( uniFullName.Buffer[ (uniFullName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
2936 pIrpSp->FileObject->FileName.Length > 0 &&
2937 pIrpSp->FileObject->FileName.Buffer[ 0] != L'\\' &&
2938 pIrpSp->FileObject->FileName.Buffer[ 0] != L':')
2941 uniFullName.Buffer[ (uniFullName.Length/sizeof( WCHAR))] = L'\\';
2943 uniFullName.Length += sizeof( WCHAR);
2945 usComponentLength += sizeof( WCHAR);
2948 if( pIrpSp->FileObject->FileName.Length > 0)
2951 RtlCopyMemory( &uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)],
2952 pIrpSp->FileObject->FileName.Buffer,
2953 pIr
\epSp->FileObject->FileName.Length);
2955 uniFullName.Length += pIrpSp->FileObject->FileName.Length;
2958 *RootFileName = uniFullName;
2961 // We populate up to the current parent
2964 if( pRelatedNameArray == NULL)
2968 // Init and populate our name array
2971 pNameArray = AFSInitNameArray( NULL,
2974 if( pNameArray == NULL)
2977 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2978 AFS_TRACE_LEVEL_VERBOSE,
2979 "AFSParseName (%08lX) Failed to initialize name array\n",
2982 AFSExFreePoolWithTag( uniFullName.Buffer, 0);
2984 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2987 ntStatus = AFSPopulateNameArray( pNameArray,
2989 pRelatedCcb->DirectoryCB);
2995 // Init and populate our name array
2998 pNameArray = AFSInitNameArray( NULL,
2999 pRelatedNameArray->MaxElementCount);
3001 if( pNameArray == NULL)
3004 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3005 AFS_TRACE_LEVEL_VERBOSE,
3006 "AFSParseName (%08lX) Failed to initialize name array\n",
3009 AFSExFreePoolWithTag( uniFullName.Buffer, 0);
3011 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3014 ntStatus = AFSPopulateNameArrayFromRelatedArray( pNameArray,
3016 pRelatedCcb->DirectoryCB);
3019 if( !NT_SUCCESS( ntStatus))
3022 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3023 AFS_TRACE_LEVEL_VERBOSE,
3024 "AFSParseName (%08lX) Failed to populate name array\n",
3027 AFSExFreePoolWithTag( uniFullName.Buffer, 0);
3029 try_return( ntStatus);
3032 ParsedFileName->Length = usComponentLength;
3033 ParsedFileName->MaximumLength = uniFullName.MaximumLength;
3035 ParsedFileName->Buffer = &uniFullName.Buffer[ usComponentIndex];
3038 // Indicate to caller that RootFileName must be freed
3041 SetFlag( *ParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
3043 *NameArray = pNameArray;
3045 *VolumeCB = pVolumeCB;
3048 // Increment our volume reference count
3051 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
3053 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
3054 AFS_TRACE_LEVEL_VERBOSE,
3055 "AFSParseName Increment count on volume %08lX Cnt %d\n",
3059 *ParentDirectoryCB = pDirEntry;
3061 lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
3063 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3064 AFS_TRACE_LEVEL_VERBOSE,
3065 "AFSParseName Increment1 count on %wZ DE %p Ccb %p Cnt %d\n",
3066 &pDirEntry->NameInformation.FileName,
3071 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3072 AFS_TRACE_LEVEL_VERBOSE_2,
3073 "AFSParseName (%08lX) Returning full name %wZ\n",
3077 try_return( ntStatus);
3081 // No wild cards in the name
3084 uniFullName = pIrpSp->FileObject->FileName;
3086 if( FsRtlDoesNameContainWildCards( &uniFullName) ||
3087 uniFullName.Length < AFSServerName.Length)
3090 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3091 AFS_TRACE_LEVEL_ERROR,
3092 "AFSParseName (%08lX) Name %wZ contains wild cards or too short\n",
3096 try_return( ntStatus = STATUS_OBJECT_NAME_INVALID);
3100 // The name is a fully qualified name. Parse out the server/share names and
3101 // point to the root qualified name
3102 // First thing is to locate the server name
3105 FsRtlDissectName( uniFullName,
3109 uniFullName = uniRemainingPath;
3112 // This component is the server name we are serving
3115 if( RtlCompareUnicodeString( &uniComponentName,
3121 // Drive letter based name?
3124 uniFullName = pIrpSp->FileObject->FileName;
3126 while( usIndex < uniFullName.Length/sizeof( WCHAR))
3129 if( uniFullName.Buffer[ usIndex] == L':')
3132 uniFullName.Buffer = &uniFullName.Buffer[ usIndex + 2];
3134 uniFullName.Length -= (usIndex + 2) * sizeof( WCHAR);
3136 usDriveIndex = usIndex - 1;
3145 // Do we have the right server name now?
3148 FsRtlDissectName( uniFullName,
3152 uniFullName = uniRemainingPath;
3155 // This component is the server name we are serving
3158 if( RtlCompareUnicodeString( &uniComponentName,
3163 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3164 AFS_TRACE_LEVEL_ERROR,
3165 "AFSParseName (%08lX) Name %wZ does not have server name\n",
3167 &pIrpSp->FileObject->FileName);
3169 try_return( ntStatus = STATUS_BAD_NETWORK_NAME);
3173 // Validate this drive letter is actively mapped
3176 if( usDriveIndex > 0 &&
3177 !AFSIsDriveMapped( pIrpSp->FileObject->FileName.Buffer[ usDriveIndex]))
3180 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3181 AFS_TRACE_LEVEL_ERROR,
3182 "AFSParseName (%08lX) Name %wZ contains invalid drive mapping\n",
3184 &pIrpSp->FileObject->FileName);
3186 try_return( ntStatus = STATUS_BAD_NETWORK_NAME);
3190 if( FsRtlDoesNameContainWildCards( &uniFullName))
3193 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3194 AFS_TRACE_LEVEL_ERROR,
3195 "AFSParseName (%08lX) Component %wZ contains wild cards\n",
3199 try_return( ntStatus = STATUS_OBJECT_NAME_INVALID);
3202 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3203 AFS_TRACE_LEVEL_VERBOSE_2,
3204 "AFSParseName (%08lX) Processing full name %wZ\n",
3208 if( uniFullName.Length > 0 &&
3209 uniFullName.Buffer[ (uniFullName.Length/sizeof( WCHAR)) - 1] == L'\\')
3212 uniFullName.Length -= sizeof( WCHAR);
3216 // Be sure we are online and ready to go
3219 AFSAcquireShared( AFSGlobalRoot->VolumeLock,
3222 if( BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
3223 BooleanFlagOn( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE))
3227 // The volume has been taken off line so fail the access
3230 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3231 AFS_TRACE_LEVEL_ERROR,
3232 "AFSParseName (%08lX) Volume %08lX:%08lX OFFLINE/INVALID\n",
3234 AFSGlobalRoot->ObjectInformation.FileId.Cell,
3235 AFSGlobalRoot->ObjectInformation.FileId.Volume);
3237 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3239 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
3242 if( BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_VERIFY))
3245 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3246 AFS_TRACE_LEVEL_VERBOSE,
3247 "AFSParseName (%08lX) Verifying root of volume %08lX:%08lX\n",
3249 AFSGlobalRoot->ObjectInformation.FileId.Cell,
3250 AFSGlobalRoot->ObjectInformation.FileId.Volume);
3252 ntStatus = AFSVerifyVolume( (ULONGLONG)PsGetCurrentProcessId(),
3255 if( !NT_SUCCESS( ntStatus))
3258 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3259 AFS_TRACE_LEVEL_ERROR,
3260 "AFSParseName (%08lX) Failed verification of root Status %08lX\n",
3264 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3266 try_return( ntStatus);
3270 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3272 if( !BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
3275 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3276 AFS_TRACE_LEVEL_VERBOSE,
3277 "AFSParseName (%08lX) Enumerating global root of volume %08lX:%08lX\n",
3279 AFSGlobalRoot->ObjectInformation.FileId.Cell,
3280 AFSGlobalRoot->ObjectInformation.FileId.Volume);
3282 ntStatus = AFSEnumerateGlobalRoot( AuthGroup);
3284 if( !NT_SUCCESS( ntStatus))
3287 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3288 AFS_TRACE_LEVEL_ERROR,
3289 "AFSParseName (%08lX) Failed enumeraiton of root Status %08lX\n",
3293 try_return( ntStatus);
3298 // Check for the \\Server access and return it as though it where \\Server\Globalroot
3301 if( uniRemainingPath.Buffer == NULL ||
3302 ( uniRemainingPath.Length == sizeof( WCHAR) &&
3303 uniRemainingPath.Buffer[ 0] == L'\\'))
3306 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3307 AFS_TRACE_LEVEL_VERBOSE_2,
3308 "AFSParseName (%08lX) Returning global root access\n",
3311 lCount = InterlockedIncrement( &AFSGlobalRoot->DirectoryCB->DirOpenReferenceCount);
3313 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3314 AFS_TRACE_LEVEL_VERBOSE,
3315 "AFSParseName Increment2 count on %wZ DE %p Ccb %p Cnt %d\n",
3316 &AFSGlobalRoot->DirectoryCB->NameInformation.FileName,
3317 AFSGlobalRoot->DirectoryCB,
3323 FileName->Length = 0;
3324 FileName->MaximumLength = 0;
3325 FileName->Buffer = NULL;
3327 try_return( ntStatus = STATUS_SUCCESS);
3330 *RootFileName = uniFullName;
3333 // Include the starting \ in the root name
3336 if( RootFileName->Buffer[ 0] != L'\\')
3338 RootFileName->Buffer--;
3339 RootFileName->Length += sizeof( WCHAR);
3340 RootFileName->MaximumLength += sizeof( WCHAR);
3344 // Get the 'share' name
3347 FsRtlDissectName( uniFullName,
3351 if( FsRtlDoesNameContainWildCards( &uniFullName))
3354 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3355 AFS_TRACE_LEVEL_ERROR,
3356 "AFSParseName (%08lX) Component %wZ contains wild cards\n",
3360 try_return( ntStatus = STATUS_OBJECT_NAME_INVALID);
3364 // If this is the ALL access then perform some additional processing
3367 if( uniComponentName.Length == 0 ||
3368 RtlCompareUnicodeString( &uniComponentName,
3376 // If there is nothing else then get out
3379 if( uniRemainingPath.Buffer == NULL ||
3380 uniRemainingPath.Length == 0 ||
3381 ( uniRemainingPath.Length == sizeof( WCHAR) &&
3382 uniRemainingPath.Buffer[ 0] == L'\\'))
3385 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3386 AFS_TRACE_LEVEL_VERBOSE_2,
3387 "AFSParseName (%08lX) Returning global root access\n",
3390 lCount = InterlockedIncrement( &AFSGlobalRoot->DirectoryCB->DirOpenReferenceCount);
3392 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3393 AFS_TRACE_LEVEL_VERBOSE,
3394 "AFSParseName Increment3 count on %wZ DE %p Ccb %p Cnt %d\n",
3395 &AFSGlobalRoot->DirectoryCB->NameInformation.FileName,
3396 AFSGlobalRoot->DirectoryCB,
3402 FileName->Length = 0;
3403 FileName->MaximumLength = 0;
3404 FileName->Buffer = NULL;
3406 try_return( ntStatus = STATUS_SUCCESS);
3410 // Process the name again to strip off the ALL portion
3413 uniFullName = uniRemainingPath;
3415 FsRtlDissectName( uniFullName,
3420 // Check for the PIOCtl name
3423 if( RtlCompareUnicodeString( &uniComponentName,
3428 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3429 AFS_TRACE_LEVEL_VERBOSE_2,
3430 "AFSParseName (%08lX) Returning root PIOCtl access\n",
3433 lCount = InterlockedIncrement( &AFSGlobalRoot->DirectoryCB->DirOpenReferenceCount);
3435 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3436 AFS_TRACE_LEVEL_VERBOSE,
3437 "AFSParseName Increment4 count on %wZ DE %p Ccb %p Cnt %d\n",
3438 &AFSGlobalRoot->DirectoryCB->NameInformation.FileName,
3439 AFSGlobalRoot->DirectoryCB,
3443 ClearFlag( *ParseFlags, AFS_PARSE_FLAG_ROOT_ACCESS);
3447 *FileName = AFSPIOCtlName;
3449 try_return( ntStatus = STATUS_SUCCESS);
3452 else if( (pDirEntry = AFSGetSpecialShareNameEntry( &uniComponentName,
3453 &uniRemainingPath)) != NULL)
3456 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3457 AFS_TRACE_LEVEL_VERBOSE_2,
3458 "AFSParseName (%08lX) Returning root share name %wZ access\n",
3463 // Add in the full share name to pass back
3466 if( uniRemainingPath.Buffer != NULL)
3470 // This routine strips off the leading slash so add it back in
3473 uniRemainingPath.Buffer--;
3474 uniRemainingPath.Length += sizeof( WCHAR);
3475 uniRemainingPath.MaximumLength += sizeof( WCHAR);
3478 // And the cell name
3481 uniRemainingPath.Buffer -= (uniComponentName.Length/sizeof( WCHAR));
3482 uniRemainingPath.Length += uniComponentName.Length;
3483 uniRemainingPath.MaximumLength += uniComponentName.Length;
3485 uniComponentName = uniRemainingPath;
3490 *FileName = uniComponentName;
3492 *ParentDirectoryCB = pDirEntry;
3494 ClearFlag( *ParseFlags, AFS_PARSE_FLAG_ROOT_ACCESS);
3496 lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
3498 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3499 AFS_TRACE_LEVEL_VERBOSE,
3500 "AFSParseName Increment5 count on %wZ DE %p Ccb %p Cnt %d\n",
3501 &pDirEntry->NameInformation.FileName,
3506 try_return( ntStatus = STATUS_SUCCESS);
3510 // Determine the 'share' we are accessing
3513 ulCRC = AFSGenerateCRC( &uniComponentName,
3516 AFSAcquireShared( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
3519 bReleaseTreeLock = TRUE;
3521 AFSLocateCaseSensitiveDirEntry( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
3525 if( pDirEntry == NULL)
3528 ulCRC = AFSGenerateCRC( &uniComponentName,
3531 AFSLocateCaseInsensitiveDirEntry( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
3535 if( pDirEntry == NULL)
3539 // OK, if this component is a valid short name then try
3540 // a lookup in the short name tree
3543 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
3544 RtlIsNameLegalDOS8Dot3( &uniComponentName,
3549 AFSLocateShortNameDirEntry( AFSGlobalRoot->ObjectInformation.Specific.Directory.ShortNameTree,
3554 if( pDirEntry == NULL)
3558 // Check with the service whether it is a valid cell name
3561 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
3563 bReleaseTreeLock = FALSE;
3565 ntStatus = AFSCheckCellName( AuthGroup,
3569 if( !NT_SUCCESS( ntStatus))
3573 uniRemainingPath.Length == 0 &&
3574 ntStatus == STATUS_OBJECT_PATH_NOT_FOUND)
3577 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
3580 try_return( ntStatus);
3586 if( bReleaseTreeLock)
3588 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
3593 // Be sure we are starting from the correct volume
3596 if( pDirEntry->ObjectInformation->VolumeCB != AFSGlobalRoot)
3600 // We dropped the global root in the CheckCellName routine which is the
3601 // only way we can be here
3604 pVolumeCB = pDirEntry->ObjectInformation->VolumeCB;
3607 // Init our name array
3610 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
3613 if( pNameArray == NULL)
3616 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3617 AFS_TRACE_LEVEL_VERBOSE,
3618 "AFSParseName (%08lX) Failed to initialize name array\n",
3621 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3624 ntStatus = AFSInsertNextElement( pNameArray,
3625 pVolumeCB->DirectoryCB);
3630 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3631 AFS_TRACE_LEVEL_VERBOSE,
3632 "AFSParseName (%08lX) Failed to insert name array element\n",
3635 try_return( ntStatus);
3639 // In this case don't add back in the 'share' name since that is where we are
3640 // starting. Just put the leading slash back in
3643 if( uniRemainingPath.Buffer != NULL)
3646 uniRemainingPath.Buffer--;
3647 uniRemainingPath.Length += sizeof( WCHAR);
3648 uniRemainingPath.MaximumLength += sizeof( WCHAR);
3650 if( uniRemainingPath.Length > sizeof( WCHAR))
3653 ClearFlag( *ParseFlags, AFS_PARSE_FLAG_ROOT_ACCESS);
3657 // Pass back the parent being the root of the volume
3660 *ParentDirectoryCB = pVolumeCB->DirectoryCB;
3666 // Pass back a root slash
3669 uniRemainingPath = uniComponentName;
3671 uniRemainingPath.Buffer--;
3672 uniRemainingPath.Length = sizeof( WCHAR);
3673 uniRemainingPath.MaximumLength = sizeof( WCHAR);
3676 // This is a root open so pass back no parent
3679 *ParentDirectoryCB = NULL;
3685 pVolumeCB = AFSGlobalRoot;
3688 // Init our name array
3691 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
3693 if( pNameArray == NULL)
3696 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3697 AFS_TRACE_LEVEL_VERBOSE,
3698 "AFSParseName (%08lX) Failed to initialize name array\n",
3701 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3705 // Add back in the 'share' portion of the name since we will parse it out on return
3708 if( uniRemainingPath.Buffer != NULL)
3712 // This routine strips off the leading slash so add it back in
3715 uniRemainingPath.Buffer--;
3716 uniRemainingPath.Length += sizeof( WCHAR);
3717 uniRemainingPath.MaximumLength += sizeof( WCHAR);
3719 if( uniRemainingPath.Length > sizeof( WCHAR))
3722 ClearFlag( *ParseFlags, AFS_PARSE_FLAG_ROOT_ACCESS);
3726 // And the cell name
3729 uniRemainingPath.Buffer -= (uniComponentName.Length/sizeof( WCHAR));
3730 uniRemainingPath.Length += uniComponentName.Length;
3731 uniRemainingPath.MaximumLength += uniComponentName.Length;
3736 uniRemainingPath = uniComponentName;
3740 // And the leading slash again ...
3743 uniRemainingPath.Buffer--;
3744 uniRemainingPath.Length += sizeof( WCHAR);
3745 uniRemainingPath.MaximumLength += sizeof( WCHAR);
3747 lCount = InterlockedIncrement( &pVolumeCB->DirectoryCB->DirOpenReferenceCount);
3749 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3750 AFS_TRACE_LEVEL_VERBOSE,
3751 "AFSParseName Increment6 count on %wZ DE %p Ccb %p Cnt %d\n",
3752 &pVolumeCB->DirectoryCB->NameInformation.FileName,
3753 pVolumeCB->DirectoryCB,
3758 // Pass back the parent being the volume root
3761 *ParentDirectoryCB = pVolumeCB->DirectoryCB;
3766 // Return the remaining portion as the file name
3769 *FileName = uniRemainingPath;
3771 *ParsedFileName = uniRemainingPath;
3773 *NameArray = pNameArray;
3775 *VolumeCB = pVolumeCB;
3778 // Increment our reference on the volume
3781 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
3783 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
3784 AFS_TRACE_LEVEL_VERBOSE,
3785 "AFSParseName Increment2 count on global volume %08lX Cnt %d\n",
3791 if( NT_SUCCESS( ntStatus))
3794 if( *ParentDirectoryCB != NULL)
3797 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3798 AFS_TRACE_LEVEL_VERBOSE,
3799 "AFSParseName Count on %wZ DE %p Ccb %p Cnt %d\n",
3800 &(*ParentDirectoryCB)->NameInformation.FileName,
3803 (*ParentDirectoryCB)->DirOpenReferenceCount);
3807 if( *VolumeCB != NULL)
3809 ASSERT( (*VolumeCB)->VolumeReferenceCount > 1);
3812 if( ntStatus != STATUS_SUCCESS)
3815 if( pNameArray != NULL)
3818 AFSFreeNameArray( pNameArray);
3827 AFSCheckCellName( IN GUID *AuthGroup,
3828 IN UNICODE_STRING *CellName,
3829 OUT AFSDirectoryCB **ShareDirEntry)
3832 NTSTATUS ntStatus = STATUS_SUCCESS;
3833 UNICODE_STRING uniName;
3834 AFSDirEnumEntry *pDirEnumEntry = NULL;
3835 AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
3836 AFSDirHdr *pDirHdr = &AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr;
3837 AFSDirectoryCB *pDirNode = NULL;
3838 UNICODE_STRING uniDirName, uniTargetName;
3839 AFSVolumeCB *pVolumeCB = NULL;
3846 // Look for some default names we will not handle
3849 RtlInitUnicodeString( &uniName,
3852 if( RtlCompareUnicodeString( &uniName,
3857 try_return( ntStatus = STATUS_NO_SUCH_FILE);
3860 RtlInitUnicodeString( &uniName,
3863 if( RtlCompareUnicodeString( &uniName,
3868 try_return( ntStatus = STATUS_NO_SUCH_FILE);
3871 RtlInitUnicodeString( &uniName,
3874 if( RtlCompareUnicodeString( &uniName,
3879 try_return( ntStatus = STATUS_NO_SUCH_FILE);
3882 RtlInitUnicodeString( &uniName,
3885 if( RtlCompareUnicodeString( &uniName,
3890 try_return( ntStatus = STATUS_NO_SUCH_FILE);
3894 // OK, ask the CM about this component name
3897 ntStatus = AFSEvaluateTargetByName( AuthGroup,
3898 &AFSGlobalRoot->ObjectInformation,
3902 if( !NT_SUCCESS( ntStatus))
3905 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3906 AFS_TRACE_LEVEL_WARNING,
3907 "AFSCheckCellName entry %wZ does not exist parent FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
3909 AFSGlobalRoot->ObjectInformation.FileId.Cell,
3910 AFSGlobalRoot->ObjectInformation.FileId.Volume,
3911 AFSGlobalRoot->ObjectInformation.FileId.Vnode,
3912 AFSGlobalRoot->ObjectInformation.FileId.Unique,
3915 try_return( ntStatus);
3919 // OK, we have a dir enum entry back so add it to the root node
3922 uniDirName = *CellName;
3924 uniTargetName.Length = (USHORT)pDirEnumEntry->TargetNameLength;
3925 uniTargetName.MaximumLength = uniTargetName.Length;
3926 uniTargetName.Buffer = (WCHAR *)((char *)pDirEnumEntry + pDirEnumEntry->TargetNameOffset);
3929 // Is this entry a root volume entry?
3932 if( pDirEnumEntry->FileId.Cell != AFSGlobalRoot->ObjectInformation.FileId.Cell ||
3933 pDirEnumEntry->FileId.Volume != AFSGlobalRoot->ObjectInformation.FileId.Volume)
3937 // Build the root volume entry
3940 ntStatus = AFSBuildRootVolume( AuthGroup,
3941 &pDirEnumEntry->FileId,
3944 if( !NT_SUCCESS( ntStatus))
3946 try_return( ntStatus);
3949 *ShareDirEntry = pVolumeCB->DirectoryCB;
3951 lCount = InterlockedIncrement( &pVolumeCB->DirectoryCB->DirOpenReferenceCount);
3953 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3954 AFS_TRACE_LEVEL_VERBOSE,
3955 "AFSCheckCellName Increment1 count on %wZ DE %p Ccb %p Cnt %d\n",
3956 &pVolumeCB->DirectoryCB->NameInformation.FileName,
3957 pVolumeCB->DirectoryCB,
3961 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
3963 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
3964 AFS_TRACE_LEVEL_VERBOSE,
3965 "AFSCheckCellName Increment count on volume %08lX Cnt %d\n",
3972 lCount = InterlockedIncrement( &pDirHdr->ContentIndex);
3974 pDirNode = AFSInitDirEntry( &AFSGlobalRoot->ObjectInformation,
3980 if( pDirNode == NULL)
3983 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3987 // Init the short name if we have one
3990 if( pDirEnumEntry->ShortNameLength > 0)
3993 pDirNode->NameInformation.ShortNameLength = pDirEnumEntry->ShortNameLength;
3995 RtlCopyMemory( pDirNode->NameInformation.ShortName,
3996 pDirEnumEntry->ShortName,
3997 pDirNode->NameInformation.ShortNameLength);
4000 AFSAcquireExcl( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
4004 // Insert the node into the name tree
4007 ASSERT( ExIsResourceAcquiredExclusiveLite( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock));
4009 if( pDirHdr->CaseSensitiveTreeHead == NULL)
4012 pDirHdr->CaseSensitiveTreeHead = pDirNode;
4017 if( !NT_SUCCESS( AFSInsertCaseSensitiveDirEntry( pDirHdr->CaseSensitiveTreeHead,
4021 AFSDeleteDirEntry( &AFSGlobalRoot->ObjectInformation,
4024 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
4026 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4030 ClearFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
4032 if( pDirHdr->CaseInsensitiveTreeHead == NULL)
4035 pDirHdr->CaseInsensitiveTreeHead = pDirNode;
4037 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
4042 AFSInsertCaseInsensitiveDirEntry( pDirHdr->CaseInsensitiveTreeHead,
4046 if( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListHead == NULL)
4049 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListHead = pDirNode;
4054 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListTail->ListEntry.fLink = pDirNode;
4056 pDirNode->ListEntry.bLink = AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListTail;
4059 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListTail = pDirNode;
4061 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST);
4063 lCount = InterlockedIncrement( &AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeCount);
4065 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
4066 AFS_TRACE_LEVEL_VERBOSE,
4067 "AFSCheckCellName Adding entry %wZ Inc Count %d to parent FID %08lX-%08lX-%08lX-%08lX\n",
4068 &pDirNode->NameInformation.FileName,
4070 AFSGlobalRoot->ObjectInformation.FileId.Cell,
4071 AFSGlobalRoot->ObjectInformation.FileId.Volume,
4072 AFSGlobalRoot->ObjectInformation.FileId.Vnode,
4073 AFSGlobalRoot->ObjectInformation.FileId.Unique);
4075 lCount = InterlockedIncrement( &pDirNode->DirOpenReferenceCount);
4077 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
4078 AFS_TRACE_LEVEL_VERBOSE,
4079 "AFSCheckCellName Increment2 count on %wZ DE %p Ccb %p Cnt %d\n",
4080 &pDirNode->NameInformation.FileName,
4085 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
4088 // Pass back the dir node
4091 *ShareDirEntry = pDirNode;
4096 if( pDirEnumEntry != NULL)
4099 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_31_TAG);
4107 AFSBuildMountPointTarget( IN GUID *AuthGroup,
4108 IN AFSDirectoryCB *DirectoryCB,
4109 OUT AFSVolumeCB **TargetVolumeCB)
4112 NTSTATUS ntStatus = STATUS_SUCCESS;
4113 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
4114 AFSDirEnumEntry *pDirEntry = NULL;
4115 AFSDirectoryCB *pDirNode = NULL;
4116 UNICODE_STRING uniDirName, uniTargetName;
4117 ULONGLONG ullIndex = 0;
4118 AFSVolumeCB *pVolumeCB = NULL;
4119 AFSFileID stTargetFileID;
4121 BOOLEAN bReleaseVolumeLock = FALSE;
4127 // Loop on each entry, building the chain until we encounter the final target
4130 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4131 AFS_TRACE_LEVEL_VERBOSE_2,
4132 "AFSBuildMountPointTarget Building target directory for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4133 &DirectoryCB->NameInformation.FileName,
4134 DirectoryCB->ObjectInformation->FileId.Cell,
4135 DirectoryCB->ObjectInformation->FileId.Volume,
4136 DirectoryCB->ObjectInformation->FileId.Vnode,
4137 DirectoryCB->ObjectInformation->FileId.Unique);
4140 // Do we need to evaluate the node?
4143 //if( DirectoryCB->ObjectInformation->TargetFileId.Vnode == 0 &&
4144 // DirectoryCB->ObjectInformation->TargetFileId.Unique == 0)
4148 // Go evaluate the current target to get the target fid
4151 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4152 AFS_TRACE_LEVEL_VERBOSE_2,
4153 "AFSBuildMountPointTarget Evaluating target %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4154 &DirectoryCB->NameInformation.FileName,
4155 DirectoryCB->ObjectInformation->FileId.Cell,
4156 DirectoryCB->ObjectInformation->FileId.Volume,
4157 DirectoryCB->ObjectInformation->FileId.Vnode,
4158 DirectoryCB->ObjectInformation->FileId.Unique);
4160 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
4165 if( !NT_SUCCESS( ntStatus))
4168 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4169 AFS_TRACE_LEVEL_ERROR,
4170 "AFSBuildMountPointTarget Failed to evaluate target %wZ Status %08lX\n",
4171 &DirectoryCB->NameInformation.FileName,
4173 try_return( ntStatus);
4176 if( pDirEntry->TargetFileId.Vnode == 0 &&
4177 pDirEntry->TargetFileId.Unique == 0)
4180 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4181 AFS_TRACE_LEVEL_ERROR,
4182 "AFSBuildMountPointTarget Target %wZ FID %08lX-%08lX-%08lX-%08lX service returned zero FID\n",
4183 &DirectoryCB->NameInformation.FileName,
4184 DirectoryCB->ObjectInformation->FileId.Cell,
4185 DirectoryCB->ObjectInformation->FileId.Volume,
4186 DirectoryCB->ObjectInformation->FileId.Vnode,
4187 DirectoryCB->ObjectInformation->FileId.Unique);
4189 try_return( ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED);
4192 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
4195 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
4196 &DirectoryCB->Flags,
4197 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
4198 (USHORT)pDirEntry->TargetNameLength);
4200 if( !NT_SUCCESS( ntStatus))
4203 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
4205 try_return( ntStatus);
4208 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
4210 DirectoryCB->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
4213 stTargetFileID = DirectoryCB->ObjectInformation->TargetFileId;
4216 // Try to locate this FID. First the volume then the
4220 ullIndex = AFSCreateHighIndex( &stTargetFileID);
4222 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4223 AFS_TRACE_LEVEL_VERBOSE,
4224 "AFSBuildMountPointTarget Acquiring RDR VolumeTreeLock lock %08lX EXCL %08lX\n",
4225 &pDevExt->Specific.RDR.VolumeTreeLock,
4226 PsGetCurrentThread());
4228 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock,
4231 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4232 AFS_TRACE_LEVEL_VERBOSE_2,
4233 "AFSBuildMountPointTarget Locating volume for target %I64X\n",
4236 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
4238 (AFSBTreeEntry **)&pVolumeCB);
4241 // We can be processing a request for a target that is on a volume
4242 // we have never seen before.
4245 if( pVolumeCB == NULL)
4249 // Locking is held correctly in init routine
4252 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
4255 // Go init the root of the volume
4258 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4259 AFS_TRACE_LEVEL_VERBOSE_2,
4260 "AFSBuildMountPointTarget Initializing root for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4261 &DirectoryCB->NameInformation.FileName,
4262 DirectoryCB->ObjectInformation->FileId.Cell,
4263 DirectoryCB->ObjectInformation->FileId.Volume,
4264 DirectoryCB->ObjectInformation->FileId.Vnode,
4265 DirectoryCB->ObjectInformation->FileId.Unique);
4267 ntStatus = AFSInitVolume( AuthGroup,
4271 if( !NT_SUCCESS( ntStatus))
4274 try_return( ntStatus);
4278 // pVolumeCB->VolumeLock held exclusive and
4279 // pVolumeCB->VolumeReferenceCount has been incremented
4280 // pVolumeCB->RootFcb == NULL
4283 bReleaseVolumeLock = TRUE;
4289 // AFSInitVolume returns with a VolumeReferenceCount
4290 // obtain one to match
4293 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
4295 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
4296 AFS_TRACE_LEVEL_VERBOSE,
4297 "AFSBuildMountPointTarget Increment count on volume %08lX Cnt %d\n",
4301 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
4304 if( pVolumeCB->RootFcb == NULL)
4307 if ( bReleaseVolumeLock == FALSE)
4310 AFSAcquireExcl( pVolumeCB->VolumeLock,
4313 bReleaseVolumeLock = TRUE;
4317 // Initialize the root fcb for this volume
4320 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
4323 if( !NT_SUCCESS( ntStatus))
4326 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
4328 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
4329 AFS_TRACE_LEVEL_VERBOSE,
4330 "AFSBuildMountPoint Decrement count on volume %08lX Cnt %d\n",
4334 AFSReleaseResource( pVolumeCB->VolumeLock);
4336 try_return( ntStatus);
4340 // Drop the lock acquired above
4343 AFSReleaseResource( &pVolumeCB->RootFcb->NPFcb->Resource);
4346 if ( bReleaseVolumeLock == TRUE)
4349 AFSReleaseResource( pVolumeCB->VolumeLock);
4352 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4353 AFS_TRACE_LEVEL_VERBOSE_2,
4354 "AFSBuildMountPointTarget Evaluated target of %wZ FID %08lX-%08lX-%08lX-%08lX as root volume\n",
4355 &pVolumeCB->DirectoryCB->NameInformation.FileName,
4356 pVolumeCB->ObjectInformation.FileId.Cell,
4357 pVolumeCB->ObjectInformation.FileId.Volume,
4358 pVolumeCB->ObjectInformation.FileId.Vnode,
4359 pVolumeCB->ObjectInformation.FileId.Unique);
4361 *TargetVolumeCB = pVolumeCB;
4368 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
4376 AFSBuildRootVolume( IN GUID *AuthGroup,
4377 IN AFSFileID *FileId,
4378 OUT AFSVolumeCB **TargetVolumeCB)
4381 NTSTATUS ntStatus = STATUS_SUCCESS;
4382 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
4383 AFSDirectoryCB *pDirNode = NULL;
4384 UNICODE_STRING uniDirName, uniTargetName;
4385 ULONGLONG ullIndex = 0;
4386 AFSVolumeCB *pVolumeCB = NULL;
4388 BOOLEAN bReleaseVolumeLock = FALSE;
4393 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4394 AFS_TRACE_LEVEL_VERBOSE_2,
4395 "AFSBuildRootVolume Building target volume for FID %08lX-%08lX-%08lX-%08lX\n",
4401 ullIndex = AFSCreateHighIndex( FileId);
4403 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4404 AFS_TRACE_LEVEL_VERBOSE,
4405 "AFSBuildRootVolume Acquiring RDR VolumeTreeLock lock %08lX EXCL %08lX\n",
4406 &pDevExt->Specific.RDR.VolumeTreeLock,
4407 PsGetCurrentThread());
4409 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock,
4412 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4413 AFS_TRACE_LEVEL_VERBOSE_2,
4414 "AFSBuildRootVolume Locating volume for target %I64X\n",
4417 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
4419 (AFSBTreeEntry **)&pVolumeCB);
4422 // We can be processing a request for a target that is on a volume
4423 // we have never seen before.
4426 if( pVolumeCB == NULL)
4430 // Locking is held correctly in init routine
4433 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
4436 // Go init the root of the volume
4439 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4440 AFS_TRACE_LEVEL_VERBOSE_2,
4441 "AFSBuildRootVolume Initializing root for FID %08lX-%08lX-%08lX-%08lX\n",
4447 ntStatus = AFSInitVolume( AuthGroup,
4451 if( !NT_SUCCESS( ntStatus))
4454 try_return( ntStatus);
4458 // pVolumeCB->VolumeLock is held exclusive
4459 // pVolumeCB->VolumeReferenceCount has been incremented
4460 // pVolumeCB->RootFcb == NULL
4463 bReleaseVolumeLock = TRUE;
4469 // AFSInitVolume returns with a VolumeReferenceCount
4470 // obtain one to match
4473 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
4475 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
4476 AFS_TRACE_LEVEL_VERBOSE,
4477 "AFSBuildRootVolume Increment count on volume %08lX Cnt %d\n",
4481 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
4485 if( pVolumeCB->RootFcb == NULL)
4488 if ( bReleaseVolumeLock == FALSE)
4491 AFSAcquireExcl( pVolumeCB->VolumeLock,
4494 bReleaseVolumeLock = TRUE;
4498 // Initialize the root fcb for this volume
4501 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
4504 if( !NT_SUCCESS( ntStatus))
4507 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
4509 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
4510 AFS_TRACE_LEVEL_VERBOSE,
4511 "AFSBuildRootVolume Decrement count on volume %08lX Cnt %d\n",
4515 AFSReleaseResource( pVolumeCB->VolumeLock);
4517 try_return( ntStatus);
4521 // Drop the lock acquired above
4524 AFSReleaseResource( &pVolumeCB->RootFcb->NPFcb->Resource);
4527 if ( bReleaseVolumeLock == TRUE)
4530 AFSReleaseResource( pVolumeCB->VolumeLock);
4533 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4534 AFS_TRACE_LEVEL_VERBOSE_2,
4535 "AFSBuildRootVolume Evaluated target of %wZ FID %08lX-%08lX-%08lX-%08lX as root volume\n",
4536 &pVolumeCB->DirectoryCB->NameInformation.FileName,
4537 pVolumeCB->ObjectInformation.FileId.Cell,
4538 pVolumeCB->ObjectInformation.FileId.Volume,
4539 pVolumeCB->ObjectInformation.FileId.Vnode,
4540 pVolumeCB->ObjectInformation.FileId.Unique);
4542 *TargetVolumeCB = pVolumeCB;
4553 AFSProcessDFSLink( IN AFSDirectoryCB *DirEntry,
4554 IN PFILE_OBJECT FileObject,
4555 IN UNICODE_STRING *RemainingPath,
4559 NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
4560 UNICODE_STRING uniReparseName;
4561 UNICODE_STRING uniMUPDeviceName;
4562 AFSDirEnumEntry *pDirEntry = NULL;
4568 // Build up the name to reparse
4571 RtlInitUnicodeString( &uniMUPDeviceName,
4574 uniReparseName.Length = 0;
4575 uniReparseName.Buffer = NULL;
4578 // Be sure we have a target name
4581 if( DirEntry->NameInformation.TargetName.Length == 0)
4584 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
4589 if( !NT_SUCCESS( ntStatus) ||
4590 pDirEntry->TargetNameLength == 0)
4593 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4594 AFS_TRACE_LEVEL_ERROR,
4595 "AFSProcessDFSLink EvaluateTargetByID failed for Fcb %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4596 &DirEntry->NameInformation.FileName,
4597 DirEntry->ObjectInformation->FileId.Cell,
4598 DirEntry->ObjectInformation->FileId.Volume,
4599 DirEntry->ObjectInformation->FileId.Vnode,
4600 DirEntry->ObjectInformation->FileId.Unique,
4603 if( NT_SUCCESS( ntStatus))
4606 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
4609 try_return( ntStatus);
4613 // Update the target name
4616 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
4619 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
4621 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
4622 (USHORT)pDirEntry->TargetNameLength);
4624 if( !NT_SUCCESS( ntStatus))
4627 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4628 AFS_TRACE_LEVEL_ERROR,
4629 "AFSProcessDFSLink UpdateTargetName failed for Fcb %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4630 &DirEntry->NameInformation.FileName,
4631 DirEntry->ObjectInformation->FileId.Cell,
4632 DirEntry->ObjectInformation->FileId.Volume,
4633 DirEntry->ObjectInformation->FileId.Vnode,
4634 DirEntry->ObjectInformation->FileId.Unique,
4637 AFSReleaseResource( &DirEntry->NonPaged->Lock);
4639 try_return( ntStatus);
4642 AFSConvertToShared( &DirEntry->NonPaged->Lock);
4646 AFSAcquireShared( &DirEntry->NonPaged->Lock,
4650 uniReparseName.MaximumLength = uniMUPDeviceName.Length +
4652 DirEntry->NameInformation.TargetName.Length +
4655 if( RemainingPath != NULL &&
4656 RemainingPath->Length > 0)
4659 uniReparseName.MaximumLength += RemainingPath->Length;
4663 // Allocate the reparse buffer
4666 uniReparseName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
4667 uniReparseName.MaximumLength,
4668 AFS_REPARSE_NAME_TAG);
4670 if( uniReparseName.Buffer == NULL)
4673 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4674 AFS_TRACE_LEVEL_ERROR,
4675 "AFSProcessDFSLink uniReparseName.Buffer == NULL Fcb %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4676 &DirEntry->NameInformation.FileName,
4677 DirEntry->ObjectInformation->FileId.Cell,
4678 DirEntry->ObjectInformation->FileId.Volume,
4679 DirEntry->ObjectInformation->FileId.Vnode,
4680 DirEntry->ObjectInformation->FileId.Unique,
4681 STATUS_INSUFFICIENT_RESOURCES);
4683 AFSReleaseResource( &DirEntry->NonPaged->Lock);
4685 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4689 // Start building the name
4692 RtlCopyMemory( uniReparseName.Buffer,
4693 uniMUPDeviceName.Buffer,
4694 uniMUPDeviceName.Length);
4696 uniReparseName.Length = uniMUPDeviceName.Length;
4698 if( DirEntry->NameInformation.TargetName.Buffer[ 0] != L'\\')
4701 uniReparseName.Buffer[ uniReparseName.Length/sizeof( WCHAR)] = L'\\';
4703 uniReparseName.Length += sizeof( WCHAR);
4706 RtlCopyMemory( &uniReparseName.Buffer[ uniReparseName.Length/sizeof( WCHAR)],
4707 DirEntry->NameInformation.TargetName.Buffer,
4708 DirEntry->NameInformation.TargetName.Length);
4710 uniReparseName.Length += DirEntry->NameInformation.TargetName.Length;
4712 AFSReleaseResource( &DirEntry->NonPaged->Lock);
4714 if( RemainingPath != NULL &&
4715 RemainingPath->Length > 0)
4718 if( uniReparseName.Buffer[ (uniReparseName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
4719 RemainingPath->Buffer[ 0] != L'\\')
4722 uniReparseName.Buffer[ uniReparseName.Length/sizeof( WCHAR)] = L'\\';
4724 uniReparseName.Length += sizeof( WCHAR);
4727 RtlCopyMemory( &uniReparseName.Buffer[ uniReparseName.Length/sizeof( WCHAR)],
4728 RemainingPath->Buffer,
4729 RemainingPath->Length);
4731 uniReparseName.Length += RemainingPath->Length;
4735 // Update the name in the file object
4738 if( FileObject->FileName.Buffer != NULL)
4741 AFSExFreePoolWithTag( FileObject->FileName.Buffer, 0);
4744 FileObject->FileName = uniReparseName;
4746 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4747 AFS_TRACE_LEVEL_VERBOSE,
4748 "AFSProcessDFSLink Reparsing access to Fcb %wZ FID %08lX-%08lX-%08lX-%08lX to %wZ\n",
4749 &DirEntry->NameInformation.FileName,
4750 DirEntry->ObjectInformation->FileId.Cell,
4751 DirEntry->ObjectInformation->FileId.Volume,
4752 DirEntry->ObjectInformation->FileId.Vnode,
4753 DirEntry->ObjectInformation->FileId.Unique,
4757 // Return status reparse ...
4760 ntStatus = STATUS_REPARSE;
4767 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);