2 * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
3 * Copyright (c) 2009, 2010, 2011 Your File System, Inc.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * - Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
14 * this list of conditions and the following disclaimer in the
16 * and/or other materials provided with the distribution.
17 * - Neither the names of Kernel Drivers, LLC and Your File System, Inc.
18 * nor the names of their contributors may be used to endorse or promote
19 * products derived from this software without specific prior written
20 * permission from Kernel Drivers, LLC and Your File System, Inc.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
26 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 // File: AFSNameSupport.cpp
39 #include "AFSCommon.h"
44 // On entry, *VolumeCB must have a held ReferenceCount provided by
45 // the caller which will be released. On successful exit, *VolumeCB
46 // will be assigned the new current volume with a held ReferenceCount.
48 // On entry, *ParentDirectoryCB must have a held DirOpenReferenceCount
49 // provided by the caller.
53 AFSLocateNameEntry( IN GUID *AuthGroup,
54 IN PFILE_OBJECT FileObject,
55 IN UNICODE_STRING *RootPathName,
56 IN UNICODE_STRING *ParsedPathName,
57 IN AFSNameArrayHdr *NameArray,
59 IN OUT AFSVolumeCB **VolumeCB,
60 IN OUT LONG *pVolumeReferenceReason,
61 IN OUT AFSDirectoryCB **ParentDirectoryCB,
62 OUT AFSDirectoryCB **DirectoryCB,
63 OUT PUNICODE_STRING ComponentName)
66 NTSTATUS ntStatus = STATUS_SUCCESS;
67 UNICODE_STRING uniPathName, uniComponentName, uniRemainingPath, uniSearchName, uniFullPathName;
69 AFSDirectoryCB *pDirEntry = NULL, *pParentDirEntry = NULL;
70 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
71 UNICODE_STRING uniSysName;
72 ULONG ulSubstituteIndex = 0;
73 BOOLEAN bSubstituteName = FALSE;
74 AFSNameArrayHdr *pNameArray = NameArray;
75 BOOLEAN bAllocatedSymLinkBuffer = FALSE;
76 UNICODE_STRING uniRelativeName, uniNoOpName;
77 AFSObjectInfoCB *pCurrentObject = NULL;
78 AFSObjectInfoCB *pParentObjectInfo = NULL;
79 AFSVolumeCB *pCurrentVolume = *VolumeCB;
80 BOOLEAN bReleaseCurrentVolume = TRUE;
81 LONG VolumeReferenceReason = *pVolumeReferenceReason;
82 BOOLEAN bSubstitutedName = FALSE;
88 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
89 AFS_TRACE_LEVEL_VERBOSE_2,
90 "AFSLocateNameEntry (FO: %p) Processing full name %wZ\n",
94 RtlInitUnicodeString( &uniSysName,
97 RtlInitUnicodeString( &uniRelativeName,
100 RtlInitUnicodeString( &uniNoOpName,
104 // Cleanup some parameters
107 if( ComponentName != NULL)
110 ComponentName->Length = 0;
111 ComponentName->MaximumLength = 0;
112 ComponentName->Buffer = NULL;
116 // We will parse through the filename, locating the directory nodes until we encounter a cache miss
117 // Starting at the root node
120 pParentDirEntry = NULL;
122 pDirEntry = *ParentDirectoryCB;
124 uniPathName = *ParsedPathName;
126 uniFullPathName = *RootPathName;
128 uniComponentName.Length = uniComponentName.MaximumLength = 0;
129 uniComponentName.Buffer = NULL;
131 uniRemainingPath.Length = uniRemainingPath.MaximumLength = 0;
132 uniRemainingPath.Buffer = NULL;
134 uniSearchName.Length = uniSearchName.MaximumLength = 0;
135 uniSearchName.Buffer = NULL;
140 ASSERT( pCurrentVolume->VolumeReferenceCount > 0);
142 ASSERT( pDirEntry->DirOpenReferenceCount > 0);
145 // Check our total link count for this name array
148 if( pNameArray->LinkCount >= (LONG)pDevExt->Specific.RDR.MaxLinkCount)
151 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
154 pCurrentObject = pDirEntry->ObjectInformation;
156 KeQueryTickCount( &pCurrentObject->LastAccessCount);
159 // Check that the directory entry is not deleted or pending delete
162 if( BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED))
165 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
166 AFS_TRACE_LEVEL_ERROR,
167 "AFSLocateNameEntry (FO: %p) Deleted parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
169 &pDirEntry->NameInformation.FileName,
170 pCurrentObject->FileId.Cell,
171 pCurrentObject->FileId.Volume,
172 pCurrentObject->FileId.Vnode,
173 pCurrentObject->FileId.Unique,
174 STATUS_FILE_DELETED);
176 try_return( ntStatus = STATUS_FILE_DELETED);
179 if( BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_PENDING_DELETE))
182 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
183 AFS_TRACE_LEVEL_ERROR,
184 "AFSLocateNameEntry (FO: %p) Delete pending on %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
186 &pDirEntry->NameInformation.FileName,
187 pCurrentObject->FileId.Cell,
188 pCurrentObject->FileId.Volume,
189 pCurrentObject->FileId.Vnode,
190 pCurrentObject->FileId.Unique,
191 STATUS_DELETE_PENDING);
193 try_return( ntStatus = STATUS_DELETE_PENDING);
197 // Check if the directory requires verification
200 if( BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_FLAGS_VERIFY) &&
201 ( pCurrentObject->FileType != AFS_FILE_TYPE_DIRECTORY ||
202 !AFSIsEnumerationInProcess( pCurrentObject)))
205 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
206 AFS_TRACE_LEVEL_VERBOSE,
207 "AFSLocateNameEntry (FO: %p) Verifying parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
209 &pDirEntry->NameInformation.FileName,
210 pCurrentObject->FileId.Cell,
211 pCurrentObject->FileId.Volume,
212 pCurrentObject->FileId.Vnode,
213 pCurrentObject->FileId.Unique);
216 // Directory TreeLock should be exclusively held
219 AFSAcquireExcl( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
222 ntStatus = AFSVerifyEntry( AuthGroup,
225 AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
227 if( !NT_SUCCESS( ntStatus))
230 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
231 AFS_TRACE_LEVEL_ERROR,
232 "AFSLocateNameEntry (FO: %p) Failed to verify parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
234 &pDirEntry->NameInformation.FileName,
235 pCurrentObject->FileId.Cell,
236 pCurrentObject->FileId.Volume,
237 pCurrentObject->FileId.Vnode,
238 pCurrentObject->FileId.Unique,
241 try_return( ntStatus);
246 // Ensure the parent node has been evaluated, if not then go do it now
249 if( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) ||
250 pCurrentObject->FileType == AFS_FILE_TYPE_UNKNOWN)
253 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
254 AFS_TRACE_LEVEL_VERBOSE,
255 "AFSLocateNameEntry (FO: %p) Evaluating parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
257 &pDirEntry->NameInformation.FileName,
258 pCurrentObject->FileId.Cell,
259 pCurrentObject->FileId.Volume,
260 pCurrentObject->FileId.Vnode,
261 pCurrentObject->FileId.Unique);
263 ntStatus = AFSEvaluateNode( AuthGroup,
266 if( !NT_SUCCESS( ntStatus))
269 if ( ntStatus == STATUS_NOT_A_DIRECTORY)
272 if ( !BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
275 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
276 AFS_TRACE_LEVEL_ERROR,
277 "AFSLocateNameEntry (FO: %p) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT NULL Status %08lX\n",
279 &pDirEntry->NameInformation.FileName,
280 pCurrentObject->FileId.Cell,
281 pCurrentObject->FileId.Volume,
282 pCurrentObject->FileId.Vnode,
283 pCurrentObject->FileId.Unique,
289 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
290 AFS_TRACE_LEVEL_ERROR,
291 "AFSLocateNameEntry (FO: %p) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT %08lX-%08lX-%08lX-%08lX Status %08lX\n",
293 &pDirEntry->NameInformation.FileName,
294 pCurrentObject->FileId.Cell,
295 pCurrentObject->FileId.Volume,
296 pCurrentObject->FileId.Vnode,
297 pCurrentObject->FileId.Unique,
298 pCurrentObject->ParentFileId.Cell,
299 pCurrentObject->ParentFileId.Volume,
300 pCurrentObject->ParentFileId.Vnode,
301 pCurrentObject->ParentFileId.Unique,
307 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
308 AFS_TRACE_LEVEL_ERROR,
309 "AFSLocateNameEntry (FO: %p) Failed to evaluate parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
311 &pDirEntry->NameInformation.FileName,
312 pCurrentObject->FileId.Cell,
313 pCurrentObject->FileId.Volume,
314 pCurrentObject->FileId.Vnode,
315 pCurrentObject->FileId.Unique,
319 try_return( ntStatus);
322 ClearFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
326 // If this is a mount point or symlink then go get the real directory node
329 switch( pCurrentObject->FileType)
332 case AFS_FILE_TYPE_SYMLINK:
335 UNICODE_STRING uniTempName;
336 WCHAR *pTmpBuffer = NULL;
340 // Check if the flag is set to NOT evaluate a symlink
341 // and we are done with the parsing
344 if( BooleanFlagOn( Flags, AFS_LOCATE_FLAGS_NO_SL_TARGET_EVAL) &&
345 uniRemainingPath.Length == 0)
349 // Pass back the directory entries
352 *ParentDirectoryCB = pParentDirEntry;
354 *DirectoryCB = pDirEntry;
356 *VolumeCB = pCurrentVolume;
358 *RootPathName = uniFullPathName;
360 try_return( ntStatus);
363 AFSAcquireExcl( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
366 AFSAcquireExcl( &pDirEntry->NonPaged->Lock,
369 if( pDirEntry->NameInformation.TargetName.Length == 0)
373 // We'll reset the DV to ensure we validate the metadata content
376 pCurrentObject->DataVersion.QuadPart = (ULONGLONG)-1;
378 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_VERIFY);
380 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
381 AFS_TRACE_LEVEL_VERBOSE,
382 "AFSLocateNameEntry (FO: %p) Verifying symlink parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
384 &pDirEntry->NameInformation.FileName,
385 pCurrentObject->FileId.Cell,
386 pCurrentObject->FileId.Volume,
387 pCurrentObject->FileId.Vnode,
388 pCurrentObject->FileId.Unique);
391 // Directory TreeLock should be exclusively held
394 ntStatus = AFSVerifyEntry( AuthGroup,
397 AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
399 if( !NT_SUCCESS( ntStatus))
402 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
403 AFS_TRACE_LEVEL_ERROR,
404 "AFSLocateNameEntry (FO: %p) Failed to verify symlink parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
406 &pDirEntry->NameInformation.FileName,
407 pCurrentObject->FileId.Cell,
408 pCurrentObject->FileId.Volume,
409 pCurrentObject->FileId.Vnode,
410 pCurrentObject->FileId.Unique,
413 AFSReleaseResource( &pDirEntry->NonPaged->Lock);
415 try_return( ntStatus);
419 // If the type changed then reprocess this entry
422 if( pCurrentObject->FileType != AFS_FILE_TYPE_SYMLINK)
425 AFSReleaseResource( &pDirEntry->NonPaged->Lock);
433 AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
437 // If we were given a zero length target name then deny access to the entry
440 if( pDirEntry->NameInformation.TargetName.Length == 0)
443 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
445 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
446 AFS_TRACE_LEVEL_ERROR,
447 "AFSLocateNameEntry (FO: %p) Failed to retrieve target name for symlink %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
449 &pDirEntry->NameInformation.FileName,
450 pCurrentObject->FileId.Cell,
451 pCurrentObject->FileId.Volume,
452 pCurrentObject->FileId.Vnode,
453 pCurrentObject->FileId.Unique,
456 AFSReleaseResource( &pDirEntry->NonPaged->Lock);
458 try_return( ntStatus);
461 if( AFSIsRelativeName( &pDirEntry->NameInformation.TargetName))
464 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
465 AFS_TRACE_LEVEL_VERBOSE,
466 "AFSLocateNameEntry (FO: %p) Processing relative symlink target %wZ for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
468 &pDirEntry->NameInformation.TargetName,
469 &pDirEntry->NameInformation.FileName,
470 pCurrentObject->FileId.Cell,
471 pCurrentObject->FileId.Volume,
472 pCurrentObject->FileId.Vnode,
473 pCurrentObject->FileId.Unique);
476 // We'll substitute this name into the current process name
477 // starting at where we sit in the path
480 uniTempName.Length = 0;
481 uniTempName.MaximumLength = (USHORT)((char *)uniComponentName.Buffer - (char *)uniFullPathName.Buffer) +
482 pDirEntry->NameInformation.TargetName.Length +
484 uniRemainingPath.Length;
486 uniTempName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
487 uniTempName.MaximumLength,
488 AFS_NAME_BUFFER_ONE_TAG);
490 if( uniTempName.Buffer == NULL)
493 AFSReleaseResource( &pDirEntry->NonPaged->Lock);
495 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
499 // We have so first copy in the portion up to the component
503 RtlCopyMemory( uniTempName.Buffer,
504 uniFullPathName.Buffer,
505 (ULONG)((char *)uniComponentName.Buffer - (char *)uniFullPathName.Buffer));
507 uniTempName.Length = (USHORT)((char *)uniComponentName.Buffer - (char *)uniFullPathName.Buffer);
509 if( bAllocatedSymLinkBuffer ||
513 pTmpBuffer = uniFullPathName.Buffer;
516 bAllocatedSymLinkBuffer = TRUE;
519 // Have we parsed this name yet? Better have at least once ...
522 if( uniComponentName.Length == 0)
528 // Copy in the target name ...
531 RtlCopyMemory( &uniTempName.Buffer[ uniTempName.Length/sizeof( WCHAR)],
532 pDirEntry->NameInformation.TargetName.Buffer,
533 pDirEntry->NameInformation.TargetName.Length);
535 uniPathName.Buffer = &uniTempName.Buffer[ uniTempName.Length/sizeof( WCHAR)];
537 uniPathName.Length += pDirEntry->NameInformation.TargetName.Length;
538 uniPathName.MaximumLength = uniTempName.MaximumLength;
540 uniTempName.Length += pDirEntry->NameInformation.TargetName.Length;
543 // And now any remaining portion of the name
546 if( uniRemainingPath.Length > 0)
549 if( uniRemainingPath.Buffer[ 0] != L'\\')
552 uniRemainingPath.Buffer--;
553 uniRemainingPath.Length += sizeof( WCHAR);
555 uniPathName.Length += sizeof( WCHAR);
558 RtlCopyMemory( &uniTempName.Buffer[ uniTempName.Length/sizeof( WCHAR)],
559 uniRemainingPath.Buffer,
560 uniRemainingPath.Length);
562 uniTempName.Length += uniRemainingPath.Length;
565 uniFullPathName = uniTempName;
567 if( pTmpBuffer != NULL)
570 AFSExFreePoolWithTag( pTmpBuffer, 0);
573 AFSReleaseResource( &pDirEntry->NonPaged->Lock);
576 // Dereference the current entry ..
579 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
581 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
582 AFS_TRACE_LEVEL_VERBOSE,
583 "AFSLocateNameEntry Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
584 &pDirEntry->NameInformation.FileName,
589 ASSERT( lCount >= 0);
592 // OK, need to back up one entry for the correct parent since the current
593 // entry we are on is the symlink itself
596 pDirEntry = AFSBackupEntry( pNameArray);
599 // Increment our reference on this dir entry
602 lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
604 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
605 AFS_TRACE_LEVEL_VERBOSE,
606 "AFSLocateNameEntry Increment1 count on %wZ DE %p Ccb %p Cnt %d\n",
607 &pDirEntry->NameInformation.FileName,
612 if( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_ROOT_VOLUME))
615 pParentDirEntry = NULL;
620 pParentDirEntry = AFSGetParentEntry( pNameArray);
622 ASSERT( pParentDirEntry != pDirEntry);
628 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
629 AFS_TRACE_LEVEL_VERBOSE,
630 "AFSLocateNameEntry (FO: %p) Processing absolute symlink target %wZ for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
632 &pDirEntry->NameInformation.TargetName,
633 &pDirEntry->NameInformation.FileName,
634 pCurrentObject->FileId.Cell,
635 pCurrentObject->FileId.Volume,
636 pCurrentObject->FileId.Vnode,
637 pCurrentObject->FileId.Unique);
639 if ( !AFSIsAbsoluteAFSName( &pDirEntry->NameInformation.TargetName))
642 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
643 AFS_TRACE_LEVEL_ERROR,
644 "AFSLocateNameEntry Name %wZ contains invalid server name\n",
645 &pDirEntry->NameInformation.TargetName);
648 // The correct response would be STATUS_OBJECT_PATH_INVALID
649 // but that prevents cmd.exe from performing a recursive
650 // directory enumeration when opening a directory entry
651 // that represents a symlink to an invalid path is discovered.
654 AFSReleaseResource( &pDirEntry->NonPaged->Lock);
656 try_return( ntStatus = STATUS_OBJECT_PATH_NOT_FOUND);
660 // We'll substitute this name into the current process name
661 // starting at where we sit in the path
664 uniTempName.Length = 0;
665 uniTempName.MaximumLength = pDirEntry->NameInformation.TargetName.Length +
667 uniRemainingPath.Length;
669 uniTempName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
670 uniTempName.MaximumLength,
671 AFS_NAME_BUFFER_TWO_TAG);
673 if( uniTempName.Buffer == NULL)
676 AFSReleaseResource( &pDirEntry->NonPaged->Lock);
678 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
681 if( bAllocatedSymLinkBuffer ||
685 pTmpBuffer = uniFullPathName.Buffer;
688 bAllocatedSymLinkBuffer = TRUE;
691 // Have we parsed this name yet? Better have at least once ...
694 if( uniComponentName.Length == 0)
700 // Copy in the target name ...
703 RtlCopyMemory( uniTempName.Buffer,
704 &pDirEntry->NameInformation.TargetName.Buffer[ AFSMountRootName.Length/sizeof( WCHAR)],
705 pDirEntry->NameInformation.TargetName.Length - AFSMountRootName.Length);
707 uniTempName.Length = pDirEntry->NameInformation.TargetName.Length - AFSMountRootName.Length;
710 // And now any remaining portion of the name
713 if( uniRemainingPath.Length > 0)
716 if( uniRemainingPath.Buffer[ 0] != L'\\')
719 uniRemainingPath.Buffer--;
720 uniRemainingPath.Length += sizeof( WCHAR);
723 RtlCopyMemory( &uniTempName.Buffer[ uniTempName.Length/sizeof( WCHAR)],
724 uniRemainingPath.Buffer,
725 uniRemainingPath.Length);
727 uniTempName.Length += uniRemainingPath.Length;
730 uniFullPathName = uniTempName;
732 uniPathName = uniTempName;
734 if( pTmpBuffer != NULL)
737 AFSExFreePoolWithTag( pTmpBuffer, 0);
740 AFSReleaseResource( &pDirEntry->NonPaged->Lock);
743 // If our current volume is not the global root then make it so ...
746 if( pCurrentVolume != AFSGlobalRoot)
749 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
750 AFS_TRACE_LEVEL_VERBOSE,
751 "AFSLocateNameEntry (FO: %p) Current volume not global, resetting for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
753 &pDirEntry->NameInformation.FileName,
754 pCurrentObject->FileId.Cell,
755 pCurrentObject->FileId.Volume,
756 pCurrentObject->FileId.Vnode,
757 pCurrentObject->FileId.Unique);
759 lCount = AFSVolumeDecrement( pCurrentVolume,
760 VolumeReferenceReason);
762 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
763 AFS_TRACE_LEVEL_VERBOSE,
764 "AFSLocateNameEntry Decrement count on volume %p Reason %u Cnt %d\n",
766 VolumeReferenceReason,
769 pCurrentVolume = AFSGlobalRoot;
771 VolumeReferenceReason = AFS_VOLUME_REFERENCE_LOCATE_NAME;
773 lCount = AFSVolumeIncrement( pCurrentVolume,
774 VolumeReferenceReason);
776 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
777 AFS_TRACE_LEVEL_VERBOSE,
778 "AFSLocateNameEntry Increment count on volume %p Reason %u Cnt %d\n",
780 VolumeReferenceReason,
785 // Dereference our current dir entry
788 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
790 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
791 AFS_TRACE_LEVEL_VERBOSE,
792 "AFSLocateNameEntry Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
793 &pDirEntry->NameInformation.FileName,
798 ASSERT( lCount >= 0);
800 pDirEntry = pCurrentVolume->DirectoryCB;
803 // Reference the new dir entry
806 lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
808 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
809 AFS_TRACE_LEVEL_VERBOSE,
810 "AFSLocateNameEntry Increment2 count on %wZ DE %p Ccb %p Cnt %d\n",
811 &pDirEntry->NameInformation.FileName,
817 // Reset the name array
818 // Persist the link count in the name array
821 lLinkCount = pNameArray->LinkCount;
823 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
824 AFS_TRACE_LEVEL_VERBOSE,
825 "AFSLocateNameEntry (FO: %p) Resetting name array for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
827 &pDirEntry->NameInformation.FileName,
828 pCurrentObject->FileId.Cell,
829 pCurrentObject->FileId.Volume,
830 pCurrentObject->FileId.Vnode,
831 pCurrentObject->FileId.Unique);
833 AFSResetNameArray( pNameArray,
836 pNameArray->LinkCount = lLinkCount;
838 pParentDirEntry = NULL;
842 // Increment our link count
845 lCount = InterlockedIncrement( &pNameArray->LinkCount);
850 case AFS_FILE_TYPE_MOUNTPOINT:
854 // Check if the flag is set to NOT evaluate a mount point
855 // and we are done with the parsing
858 if( BooleanFlagOn( Flags, AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL) &&
859 uniRemainingPath.Length == 0)
863 // Pass back the directory entries
866 *ParentDirectoryCB = pParentDirEntry;
868 *DirectoryCB = pDirEntry;
870 *VolumeCB = pCurrentVolume;
872 *RootPathName = uniFullPathName;
874 try_return( ntStatus);
877 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
878 AFS_TRACE_LEVEL_VERBOSE,
879 "AFSLocateNameEntry (FO: %p) Building MP target for parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
881 &pDirEntry->NameInformation.FileName,
882 pCurrentObject->FileId.Cell,
883 pCurrentObject->FileId.Volume,
884 pCurrentObject->FileId.Vnode,
885 pCurrentObject->FileId.Unique);
888 // Go retrieve the target entry for this node
889 // Release the current volume cb entry since we would
890 // have lock inversion in the following call
891 // Also decrement the ref count on the volume
894 ASSERT( pCurrentVolume->VolumeReferenceCount > 0);
896 lCount = AFSVolumeDecrement( pCurrentVolume,
897 VolumeReferenceReason);
899 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
900 AFS_TRACE_LEVEL_VERBOSE,
901 "AFSLocateNameEntry Decrement2 count on volume %p Reason %u Cnt %d\n",
903 VolumeReferenceReason,
906 bReleaseCurrentVolume = FALSE;
908 ntStatus = AFSBuildMountPointTarget( AuthGroup,
912 if( !NT_SUCCESS( ntStatus))
915 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
916 AFS_TRACE_LEVEL_ERROR,
917 "AFSLocateNameEntry (FO: %p) Failed to build MP target for parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
919 &pDirEntry->NameInformation.FileName,
920 pCurrentObject->FileId.Cell,
921 pCurrentObject->FileId.Volume,
922 pCurrentObject->FileId.Vnode,
923 pCurrentObject->FileId.Unique,
926 try_return( ntStatus);
929 ASSERT( pCurrentVolume->VolumeReferenceCount > 0);
931 bReleaseCurrentVolume = TRUE;
933 VolumeReferenceReason = AFS_VOLUME_REFERENCE_MOUNTPT;
936 // We want to restart processing here on the new parent ...
937 // Deref and ref count the entries
940 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
942 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
943 AFS_TRACE_LEVEL_VERBOSE,
944 "AFSLocateNameEntry Decrement3 count on %wZ DE %p Ccb %p Cnt %d\n",
945 &pDirEntry->NameInformation.FileName,
950 ASSERT( lCount >= 0);
952 pDirEntry = pCurrentVolume->DirectoryCB;
954 lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
956 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
957 AFS_TRACE_LEVEL_VERBOSE,
958 "AFSLocateNameEntry Increment3 count on %wZ DE %p Ccb %p Cnt %d\n",
959 &pDirEntry->NameInformation.FileName,
965 // The name array stores both the mount point and the target.
966 // Insert the target.
969 AFSInsertNextElement( pNameArray,
972 pParentDirEntry = NULL;
975 // Increment our link count
978 lCount = InterlockedIncrement( &pNameArray->LinkCount);
983 case AFS_FILE_TYPE_DFSLINK:
986 if( BooleanFlagOn( Flags, AFS_LOCATE_FLAGS_NO_DFS_LINK_EVAL))
990 // Pass back the directory entries
993 *ParentDirectoryCB = pParentDirEntry;
995 *DirectoryCB = pDirEntry;
997 *VolumeCB = pCurrentVolume;
999 *RootPathName = uniFullPathName;
1001 try_return( ntStatus);
1005 // This is a DFS link so we need to update the file name and return STATUS_REPARSE to the
1006 // system for it to reevaluate it
1009 if( FileObject != NULL)
1012 ntStatus = AFSProcessDFSLink( pDirEntry,
1021 // This is where we have been re-entered from an NP evaluation call via the BuildBranch()
1025 ntStatus = STATUS_INVALID_PARAMETER;
1028 if( ntStatus != STATUS_SUCCESS &&
1029 ntStatus != STATUS_REPARSE)
1032 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1033 AFS_TRACE_LEVEL_ERROR,
1034 "AFSLocateNameEntry (FO: %p) Failed to process DFSLink parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1036 &pDirEntry->NameInformation.FileName,
1037 pCurrentObject->FileId.Cell,
1038 pCurrentObject->FileId.Volume,
1039 pCurrentObject->FileId.Vnode,
1040 pCurrentObject->FileId.Unique,
1044 try_return( ntStatus);
1047 case AFS_FILE_TYPE_UNKNOWN:
1048 case AFS_FILE_TYPE_INVALID:
1052 // Something was not processed ...
1055 try_return( ntStatus = STATUS_ACCESS_DENIED);
1058 } /* end of switch */
1061 // If the parent is not initialized then do it now
1064 if( pCurrentObject->FileType == AFS_FILE_TYPE_DIRECTORY &&
1065 !BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
1068 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1069 AFS_TRACE_LEVEL_VERBOSE,
1070 "AFSLocateNameEntry (FO: %p) Enumerating parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1072 &pDirEntry->NameInformation.FileName,
1073 pCurrentObject->FileId.Cell,
1074 pCurrentObject->FileId.Volume,
1075 pCurrentObject->FileId.Vnode,
1076 pCurrentObject->FileId.Unique);
1078 AFSAcquireExcl( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
1081 if( !BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
1084 ntStatus = AFSEnumerateDirectory( AuthGroup,
1088 if( !NT_SUCCESS( ntStatus))
1091 AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
1093 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1094 AFS_TRACE_LEVEL_ERROR,
1095 "AFSLocateNameEntry (FO: %p) Failed to enumerate parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1097 &pDirEntry->NameInformation.FileName,
1098 pCurrentObject->FileId.Cell,
1099 pCurrentObject->FileId.Volume,
1100 pCurrentObject->FileId.Vnode,
1101 pCurrentObject->FileId.Unique,
1104 try_return( ntStatus);
1107 SetFlag( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
1110 AFSReleaseResource( pCurrentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
1112 else if( pCurrentObject->FileType == AFS_FILE_TYPE_FILE)
1115 if( uniPathName.Length > 0)
1118 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1119 AFS_TRACE_LEVEL_ERROR,
1120 "AFSLocateNameEntry (FO: %p) Encountered file node %wZ FID %08lX-%08lX-%08lX-%08lX in path processing\n",
1122 &pDirEntry->NameInformation.FileName,
1123 pCurrentObject->FileId.Cell,
1124 pCurrentObject->FileId.Volume,
1125 pCurrentObject->FileId.Vnode,
1126 pCurrentObject->FileId.Unique);
1128 // The proper error code to return would be STATUS_OBJECT_PATH_INVALID because
1129 // one of the components of the path is not a directory. However, returning
1130 // that error prevents IIS 7 and 7.5 from being able to serve data out of AFS.
1131 // Instead IIS insists on treating the target file as if it is a directory containing
1132 // a potential web.config file. NTFS and LanMan return STATUS_OBJECT_PATH_NOT_FOUND.
1133 // AFS will follow suit.
1135 ntStatus = STATUS_OBJECT_PATH_NOT_FOUND;
1140 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1141 AFS_TRACE_LEVEL_VERBOSE,
1142 "AFSLocateNameEntry (FO: %p) Returning file %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1144 &pDirEntry->NameInformation.FileName,
1145 pCurrentObject->FileId.Cell,
1146 pCurrentObject->FileId.Volume,
1147 pCurrentObject->FileId.Vnode,
1148 pCurrentObject->FileId.Unique);
1151 // Pass back the directory entries
1154 *ParentDirectoryCB = pParentDirEntry;
1156 *DirectoryCB = pDirEntry;
1158 *VolumeCB = pCurrentVolume;
1160 *RootPathName = uniFullPathName;
1163 try_return( ntStatus);
1167 // If we are at the end of the processing, set our returned information and get out
1170 if( uniPathName.Length == 0)
1173 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1174 AFS_TRACE_LEVEL_VERBOSE,
1175 "AFSLocateNameEntry (FO: %p) Completed processing returning %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1177 &pDirEntry->NameInformation.FileName,
1178 pCurrentObject->FileId.Cell,
1179 pCurrentObject->FileId.Volume,
1180 pCurrentObject->FileId.Vnode,
1181 pCurrentObject->FileId.Unique);
1184 // Pass back the directory entries
1187 *ParentDirectoryCB = pParentDirEntry;
1189 *DirectoryCB = pDirEntry;
1191 *VolumeCB = pCurrentVolume;
1193 *RootPathName = uniFullPathName;
1195 try_return( ntStatus);
1199 // We may have returned to the top of the while( TRUE)
1201 if( bSubstituteName &&
1202 uniSearchName.Buffer != NULL)
1205 AFSExFreePoolWithTag( uniSearchName.Buffer, 0);
1207 bSubstituteName = FALSE;
1209 uniSearchName.Length = uniSearchName.MaximumLength = 0;
1210 uniSearchName.Buffer = NULL;
1213 ulSubstituteIndex = 1;
1215 ntStatus = STATUS_SUCCESS;
1218 // Get the next component name
1221 FsRtlDissectName( uniPathName,
1226 // Check for the . and .. in the path
1229 if( RtlCompareUnicodeString( &uniComponentName,
1234 uniPathName = uniRemainingPath;
1239 if( RtlCompareUnicodeString( &uniComponentName,
1244 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1245 AFS_TRACE_LEVEL_VERBOSE,
1246 "AFSLocateNameEntry (FO: %p) Backing up entry from %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1248 &pDirEntry->NameInformation.FileName,
1249 pCurrentObject->FileId.Cell,
1250 pCurrentObject->FileId.Volume,
1251 pCurrentObject->FileId.Vnode,
1252 pCurrentObject->FileId.Unique);
1255 // Need to back up one entry in the name array
1257 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
1259 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1260 AFS_TRACE_LEVEL_VERBOSE,
1261 "AFSLocateNameEntry Decrement4 count on %wZ DE %p Ccb %p Cnt %d\n",
1262 &pDirEntry->NameInformation.FileName,
1267 ASSERT( lCount >= 0);
1269 pDirEntry = AFSBackupEntry( NameArray);
1271 if( pDirEntry == NULL)
1274 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1275 AFS_TRACE_LEVEL_ERROR,
1276 "AFSLocateNameEntry AFSBackupEntry failed\n");
1278 try_return(ntStatus = STATUS_OBJECT_PATH_INVALID);
1281 lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
1283 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1284 AFS_TRACE_LEVEL_VERBOSE,
1285 "AFSLocateNameEntry Increment4 count on %wZ DE %p Ccb %p Cnt %d\n",
1286 &pDirEntry->NameInformation.FileName,
1291 if( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_ROOT_VOLUME))
1294 pParentDirEntry = NULL;
1299 pParentDirEntry = AFSGetParentEntry( pNameArray);
1301 ASSERT( pParentDirEntry != pDirEntry);
1304 uniPathName = uniRemainingPath;
1310 // Update our pointers
1313 pParentDirEntry = pDirEntry;
1317 uniSearchName = uniComponentName;
1319 while( pDirEntry == NULL)
1323 // If the SearchName contains @SYS then we perform the substitution.
1324 // If there is no substitution we give up.
1327 if( !bSubstituteName &&
1328 FsRtlIsNameInExpression( &uniSysName,
1334 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1335 AFS_TRACE_LEVEL_VERBOSE_2,
1336 "AFSLocateNameEntry (FO: %p) Processing @SYS substitution for %wZ Index %08lX\n",
1341 ntStatus = AFSSubstituteSysName( &uniComponentName,
1345 if ( NT_SUCCESS( ntStatus))
1348 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1349 AFS_TRACE_LEVEL_VERBOSE_2,
1350 "AFSLocateNameEntry (FO: %p) Located substitution %wZ for %wZ Index %08lX\n",
1357 // Go reparse the name again
1360 bSubstituteName = TRUE;
1362 ulSubstituteIndex++; // For the next entry, if needed
1364 continue; // while( pDirEntry == NULL)
1369 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1370 AFS_TRACE_LEVEL_ERROR,
1371 "AFSLocateNameEntry (FO: %p) Failed to locate substitute string for %wZ Index %08lX Status %08lX\n",
1377 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
1381 // Pass back the directory entries
1384 *ParentDirectoryCB = pParentDirEntry;
1386 *DirectoryCB = NULL;
1388 *VolumeCB = pCurrentVolume;
1390 if( ComponentName != NULL)
1393 *ComponentName = uniComponentName;
1396 *RootPathName = uniFullPathName;
1400 // We can't possibly have a pDirEntry since the lookup failed
1402 try_return( ntStatus);
1407 // Generate the CRC on the node and perform a case sensitive lookup
1410 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1411 AFS_TRACE_LEVEL_VERBOSE_2,
1412 "AFSLocateNameEntry (FO: %p) Searching for entry %wZ case sensitive\n",
1416 ulCRC = AFSGenerateCRC( &uniSearchName,
1419 AFSAcquireShared( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
1422 AFSLocateCaseSensitiveDirEntry( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
1426 if( pDirEntry == NULL)
1430 // Missed so perform a case insensitive lookup
1433 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1434 AFS_TRACE_LEVEL_VERBOSE_2,
1435 "AFSLocateNameEntry (FO: %p) Searching for entry %wZ case insensitive\n",
1439 ulCRC = AFSGenerateCRC( &uniSearchName,
1442 AFSLocateCaseInsensitiveDirEntry( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
1446 if( pDirEntry == NULL)
1450 // OK, if this component is a valid short name then try
1451 // a lookup in the short name tree
1454 if( !BooleanFlagOn( pDevExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
1455 RtlIsNameLegalDOS8Dot3( &uniSearchName,
1460 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1461 AFS_TRACE_LEVEL_VERBOSE_2,
1462 "AFSLocateNameEntry (FO: %p) Searching for entry %wZ short name\n",
1466 AFSLocateShortNameDirEntry( pParentDirEntry->ObjectInformation->Specific.Directory.ShortNameTree,
1471 if ( pDirEntry == NULL &&
1472 pParentDirEntry->ObjectInformation->VolumeCB == AFSGlobalRoot)
1476 // Check with the service to see if this is a valid cell name
1477 // that can be automatically resolved. Drop the shared TreeLock
1478 // since AFSCheckCellName must acquire it exclusively.
1481 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1483 ntStatus = AFSCheckCellName( AuthGroup,
1487 AFSAcquireShared( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
1491 if( pDirEntry == NULL)
1495 // If we substituted a name then reset our search name and try again
1498 if( bSubstituteName)
1501 AFSExFreePoolWithTag( uniSearchName.Buffer, 0);
1503 uniSearchName = uniComponentName;
1505 bSubstituteName = FALSE;
1507 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1509 continue; // while( pDirEntry == NULL)
1512 if( uniRemainingPath.Length > 0)
1515 ntStatus = STATUS_OBJECT_PATH_NOT_FOUND;
1517 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1518 AFS_TRACE_LEVEL_VERBOSE,
1519 "AFSLocateNameEntry (FO: %p) Returning path not found for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1522 pCurrentObject->FileId.Cell,
1523 pCurrentObject->FileId.Volume,
1524 pCurrentObject->FileId.Vnode,
1525 pCurrentObject->FileId.Unique);
1530 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
1532 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1533 AFS_TRACE_LEVEL_VERBOSE,
1534 "AFSLocateNameEntry (FO: %p) Returning name not found for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1537 pCurrentObject->FileId.Cell,
1538 pCurrentObject->FileId.Volume,
1539 pCurrentObject->FileId.Vnode,
1540 pCurrentObject->FileId.Unique);
1543 // Pass back the directory entries
1546 *ParentDirectoryCB = pParentDirEntry;
1548 *DirectoryCB = NULL;
1550 *VolumeCB = pCurrentVolume;
1552 if( ComponentName != NULL)
1555 *ComponentName = uniComponentName;
1558 *RootPathName = uniFullPathName;
1561 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1564 // Node name not found so get out
1567 try_return( ntStatus); // while( pDirEntry == NULL)
1574 // Here we have a match on the case insensitive lookup for the name. If there
1575 // Is more than one link entry for this node then fail the lookup request
1578 if( !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD) ||
1579 pDirEntry->CaseInsensitiveList.fLink != NULL)
1583 // Increment our dir entry ref count since we will decrement it on exit
1586 lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
1588 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1589 AFS_TRACE_LEVEL_VERBOSE,
1590 "AFSLocateNameEntry Increment5 count on %wZ DE %p Ccb %p Cnt %d\n",
1591 &pDirEntry->NameInformation.FileName,
1596 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1598 try_return(ntStatus = STATUS_OBJECT_NAME_COLLISION);
1603 if( pDirEntry != NULL)
1607 // If the verify flag is set on the parent and the current entry is deleted
1608 // revalidate the parent and search again.
1611 if( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED) &&
1612 BooleanFlagOn( pParentDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY))
1615 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1617 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1618 AFS_TRACE_LEVEL_VERBOSE,
1619 "AFSLocateNameEntry (FO: %p) Verifying(2) parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1621 &pParentDirEntry->NameInformation.FileName,
1622 pParentDirEntry->ObjectInformation->FileId.Cell,
1623 pParentDirEntry->ObjectInformation->FileId.Volume,
1624 pParentDirEntry->ObjectInformation->FileId.Vnode,
1625 pParentDirEntry->ObjectInformation->FileId.Unique);
1628 // Directory TreeLock should be exclusively held
1631 AFSAcquireExcl( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
1634 ntStatus = AFSVerifyEntry( AuthGroup,
1637 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1639 if( !NT_SUCCESS( ntStatus))
1642 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1643 AFS_TRACE_LEVEL_ERROR,
1644 "AFSLocateNameEntry (FO: %p) Failed to verify(2) parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1646 &pParentDirEntry->NameInformation.FileName,
1647 pParentDirEntry->ObjectInformation->FileId.Cell,
1648 pParentDirEntry->ObjectInformation->FileId.Volume,
1649 pParentDirEntry->ObjectInformation->FileId.Vnode,
1650 pParentDirEntry->ObjectInformation->FileId.Unique,
1653 try_return( ntStatus);
1656 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1657 AFS_TRACE_LEVEL_VERBOSE,
1658 "AFSLocateNameEntry (FO: %p) Reprocessing component %wZ in parent %wZ\n",
1661 &pParentDirEntry->NameInformation.FileName);
1670 // Increment our dir entry ref count
1673 lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
1675 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1676 AFS_TRACE_LEVEL_VERBOSE,
1677 "AFSLocateNameEntry Increment5 count on %wZ DE %p Ccb %p Cnt %d\n",
1678 &pDirEntry->NameInformation.FileName,
1684 AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1686 } // End while( pDirEntry == NULL)
1689 // If we have a dirEntry for this component, perform some basic validation on it
1692 if( pDirEntry != NULL &&
1693 BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
1696 pCurrentObject = pDirEntry->ObjectInformation;
1698 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1699 AFS_TRACE_LEVEL_ERROR,
1700 "AFSLocateNameEntry (FO: %p) Deleted entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1702 &pDirEntry->NameInformation.FileName,
1703 pCurrentObject->FileId.Cell,
1704 pCurrentObject->FileId.Volume,
1705 pCurrentObject->FileId.Vnode,
1706 pCurrentObject->FileId.Unique);
1709 // This entry was deleted through the invalidation call back so perform cleanup
1713 if( BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
1716 pParentObjectInfo = AFSFindObjectInfo( pCurrentObject->VolumeCB,
1717 &pCurrentObject->ParentFileId);
1720 ASSERT( pParentObjectInfo != NULL);
1722 AFSAcquireExcl( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
1725 AFSAcquireExcl( pCurrentObject->VolumeCB->ObjectInfoTree.TreeLock,
1728 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
1730 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1731 AFS_TRACE_LEVEL_VERBOSE,
1732 "AFSLocateNameEntry Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
1733 &pDirEntry->NameInformation.FileName,
1738 ASSERT( lCount >= 0);
1743 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING|AFS_SUBSYSTEM_CLEANUP_PROCESSING,
1744 AFS_TRACE_LEVEL_VERBOSE,
1745 "AFSLocateNameEntry Deleting dir entry %p (%p) for %wZ\n",
1748 &pDirEntry->NameInformation.FileName);
1751 // Remove and delete the directory entry from the parent list
1754 AFSDeleteDirEntry( pParentObjectInfo,
1757 AFSAcquireShared( &pCurrentObject->NonPagedInfo->ObjectInfoLock,
1760 if( pCurrentObject->ObjectReferenceCount <= 0)
1763 if( BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_INSERTED_HASH_TREE))
1766 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
1767 AFS_TRACE_LEVEL_VERBOSE,
1768 "AFSLocateNameEntry Removing object %p from volume tree\n",
1771 AFSRemoveHashEntry( &pCurrentObject->VolumeCB->ObjectInfoTree.TreeHead,
1772 &pCurrentObject->TreeEntry);
1774 ClearFlag( pCurrentObject->Flags, AFS_OBJECT_INSERTED_HASH_TREE);
1778 AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock);
1783 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1784 AFS_TRACE_LEVEL_VERBOSE,
1785 "AFSLocateNameEntry Setting DELETE flag in dir entry %p for %wZ\n",
1787 &pDirEntry->NameInformation.FileName);
1789 SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
1791 AFSRemoveNameEntry( pParentObjectInfo,
1795 AFSReleaseResource( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
1797 AFSReleaseResource( pCurrentObject->VolumeCB->ObjectInfoTree.TreeLock);
1799 AFSReleaseObjectInfo( &pParentObjectInfo);
1802 // We deleted the dir entry so check if there is any remaining portion
1803 // of the name to process.
1806 if( uniRemainingPath.Length > 0)
1809 ntStatus = STATUS_OBJECT_PATH_NOT_FOUND;
1811 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1812 AFS_TRACE_LEVEL_VERBOSE,
1813 "AFSLocateNameEntry (FO: %p) Returning path not found(2) for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1816 pCurrentObject->FileId.Cell,
1817 pCurrentObject->FileId.Volume,
1818 pCurrentObject->FileId.Vnode,
1819 pCurrentObject->FileId.Unique);
1824 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
1826 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1827 AFS_TRACE_LEVEL_VERBOSE,
1828 "AFSLocateNameEntry (FO: %p) Returning name not found(2) for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1831 pCurrentObject->FileId.Cell,
1832 pCurrentObject->FileId.Volume,
1833 pCurrentObject->FileId.Vnode,
1834 pCurrentObject->FileId.Unique);
1837 // Pass back the directory entries
1840 *ParentDirectoryCB = pParentDirEntry;
1842 *DirectoryCB = NULL;
1844 *VolumeCB = pCurrentVolume;
1846 if( ComponentName != NULL)
1849 *ComponentName = uniComponentName;
1852 *RootPathName = uniFullPathName;
1856 if( ntStatus != STATUS_SUCCESS)
1859 try_return( ntStatus);
1863 // Decrement the previous parent
1866 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
1868 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1869 AFS_TRACE_LEVEL_VERBOSE,
1870 "AFSLocateNameEntry Decrement5 count on Parent %wZ DE %p Ccb %p Cnt %d\n",
1871 &pParentDirEntry->NameInformation.FileName,
1876 ASSERT( lCount >= 0);
1879 // If we ended up substituting a name in the component then update
1880 // the full path and update the pointers
1883 if( bSubstituteName)
1886 BOOLEAN bRelativeOpen = FALSE;
1888 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1889 AFS_TRACE_LEVEL_VERBOSE_2,
1890 "AFSLocateNameEntry (FO: %p) Substituting %wZ into %wZ Index %08lX\n",
1896 if( FileObject != NULL &&
1897 FileObject->RelatedFileObject != NULL)
1900 bRelativeOpen = TRUE;
1904 // AFSSubstituteNameInPath will replace the uniFullPathName.Buffer
1905 // and free the prior Buffer contents but only if the fourth
1906 // parameter is TRUE.
1909 ntStatus = AFSSubstituteNameInPath( &uniFullPathName,
1914 bAllocatedSymLinkBuffer ||
1917 if( !NT_SUCCESS( ntStatus))
1920 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1921 AFS_TRACE_LEVEL_ERROR,
1922 "AFSLocateNameEntry (FO: %p) Failure to substitute %wZ into %wZ Index %08lX Status %08lX\n",
1929 try_return( ntStatus);
1933 // We have substituted a name into the buffer so if we do this again for this
1934 // path, we need to free up the buffer we allocated.
1937 bSubstitutedName = TRUE;
1941 // Update the search parameters
1944 uniPathName = uniRemainingPath;
1947 // Check if the is a SymLink entry but has no Target FileID or Name. In this
1948 // case it might be a DFS Link so let's go and evaluate it to be sure
1951 if( pCurrentObject->FileType == AFS_FILE_TYPE_SYMLINK &&
1952 ( pCurrentObject->TargetFileId.Vnode == 0 ||
1953 pDirEntry->NameInformation.TargetName.Length == 0))
1956 ntStatus = AFSValidateSymLink( AuthGroup,
1959 if( !NT_SUCCESS( ntStatus))
1962 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1963 AFS_TRACE_LEVEL_ERROR,
1964 "AFSLocateNameEntry (FO: %p) Failed to evaluate possible DFS Link %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1966 &pDirEntry->NameInformation.FileName,
1967 pCurrentObject->FileId.Cell,
1968 pCurrentObject->FileId.Volume,
1969 pCurrentObject->FileId.Vnode,
1970 pCurrentObject->FileId.Unique,
1973 try_return( ntStatus);
1978 // Update the name array
1981 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1982 AFS_TRACE_LEVEL_VERBOSE,
1983 "AFSLocateNameEntry (FO: %p) Inserting name array entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1985 &pDirEntry->NameInformation.FileName,
1986 pCurrentObject->FileId.Cell,
1987 pCurrentObject->FileId.Volume,
1988 pCurrentObject->FileId.Vnode,
1989 pCurrentObject->FileId.Unique);
1991 ntStatus = AFSInsertNextElement( pNameArray,
1994 if( !NT_SUCCESS( ntStatus))
1997 try_return( ntStatus);
2003 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2004 AFS_TRACE_LEVEL_VERBOSE,
2005 "AFSLocateNameEntry (FO: %p) Completed processing %wZ Status %08lX\n",
2010 if( ( !NT_SUCCESS( ntStatus) &&
2011 ntStatus != STATUS_OBJECT_NAME_NOT_FOUND) ||
2012 ntStatus == STATUS_REPARSE)
2015 if( pDirEntry != NULL)
2018 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
2020 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2021 AFS_TRACE_LEVEL_VERBOSE,
2022 "AFSLocateNameEntry Decrement6 count on %wZ DE %p Ccb %p Cnt %d\n",
2023 &pDirEntry->NameInformation.FileName,
2028 ASSERT( lCount >= 0);
2030 else if( pParentDirEntry != NULL)
2033 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
2035 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2036 AFS_TRACE_LEVEL_VERBOSE,
2037 "AFSLocateNameEntry Decrement7 count on %wZ DE %p Ccb %p Cnt %d\n",
2038 &pParentDirEntry->NameInformation.FileName,
2043 ASSERT( lCount >= 0);
2046 if( bReleaseCurrentVolume)
2049 ASSERT( pCurrentVolume->VolumeReferenceCount > 0);
2051 lCount = AFSVolumeDecrement( pCurrentVolume,
2052 VolumeReferenceReason);
2054 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2055 AFS_TRACE_LEVEL_VERBOSE,
2056 "AFSLocateNameEntry Decrement3 count on volume %p Reason %u Cnt %d\n",
2058 VolumeReferenceReason,
2061 bReleaseCurrentVolume = FALSE;
2064 if( RootPathName->Buffer != uniFullPathName.Buffer)
2067 AFSExFreePoolWithTag( uniFullPathName.Buffer, 0);
2073 if( *ParentDirectoryCB != NULL)
2076 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2077 AFS_TRACE_LEVEL_VERBOSE,
2078 "AFSLocateNameEntry Count on Parent %wZ DE %p Ccb %p Cnt %d\n",
2079 &(*ParentDirectoryCB)->NameInformation.FileName,
2082 (*ParentDirectoryCB)->DirOpenReferenceCount);
2085 if( *DirectoryCB != NULL)
2088 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2089 AFS_TRACE_LEVEL_VERBOSE,
2090 "AFSLocateNameEntry Count on %wZ DE %p Ccb %p Cnt %d\n",
2091 &(*DirectoryCB)->NameInformation.FileName,
2094 (*DirectoryCB)->DirOpenReferenceCount);
2098 if( bSubstituteName &&
2099 uniSearchName.Buffer != NULL)
2102 AFSExFreePoolWithTag( uniSearchName.Buffer, 0);
2105 if ( bReleaseCurrentVolume) {
2107 *pVolumeReferenceReason = VolumeReferenceReason;
2115 AFSCreateDirEntry( IN GUID *AuthGroup,
2116 IN AFSObjectInfoCB *ParentObjectInfo,
2117 IN AFSDirectoryCB *ParentDirCB,
2118 IN PUNICODE_STRING FileName,
2119 IN PUNICODE_STRING ComponentName,
2120 IN ULONG Attributes,
2121 IN OUT AFSDirectoryCB **DirEntry)
2124 UNREFERENCED_PARAMETER(FileName);
2125 NTSTATUS ntStatus = STATUS_SUCCESS;
2126 AFSDirectoryCB *pDirNode = NULL, *pExistingDirNode = NULL;
2127 LARGE_INTEGER liFileSize = {0,0};
2133 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2134 AFS_TRACE_LEVEL_VERBOSE_2,
2135 "AFSCreateDirEntry Creating dir entry in parent %wZ FID %08lX-%08lX-%08lX-%08lX Component %wZ Attribs %08lX\n",
2136 &ParentDirCB->NameInformation.FileName,
2137 ParentObjectInfo->FileId.Cell,
2138 ParentObjectInfo->FileId.Volume,
2139 ParentObjectInfo->FileId.Vnode,
2140 ParentObjectInfo->FileId.Unique,
2145 // OK, before inserting the node into the parent tree, issue
2146 // the request to the service for node creation
2147 // We will need to drop the lock on the parent node since the create
2148 // could cause a callback into the file system to invalidate it's cache
2151 ntStatus = AFSNotifyFileCreate( AuthGroup,
2159 // If the returned status is STATUS_REPARSE then the entry exists
2160 // and we raced, get out.
2162 if( ntStatus == STATUS_REPARSE)
2165 *DirEntry = pDirNode;
2167 try_return( ntStatus = STATUS_SUCCESS);
2170 if( !NT_SUCCESS( ntStatus))
2173 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2174 AFS_TRACE_LEVEL_ERROR,
2175 "AFSCreateDirEntry Failed to create dir entry in parent %wZ FID %08lX-%08lX-%08lX-%08lX Component %wZ Attribs %08lX Status %08lX\n",
2176 &ParentDirCB->NameInformation.FileName,
2177 ParentObjectInfo->FileId.Cell,
2178 ParentObjectInfo->FileId.Volume,
2179 ParentObjectInfo->FileId.Vnode,
2180 ParentObjectInfo->FileId.Unique,
2185 try_return( ntStatus);
2189 // If AFSNotifyFileCreate returns pDirNode != NULL, then its
2190 // DirOpenReferenceCount is held.
2193 AFSAcquireExcl( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2197 // Before attempting to insert the new entry, check if we need to validate the parent
2200 if( BooleanFlagOn( ParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY))
2203 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2204 AFS_TRACE_LEVEL_VERBOSE,
2205 "AFSCreateDirEntry Verifying parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2206 &ParentDirCB->NameInformation.FileName,
2207 ParentObjectInfo->FileId.Cell,
2208 ParentObjectInfo->FileId.Volume,
2209 ParentObjectInfo->FileId.Vnode,
2210 ParentObjectInfo->FileId.Unique);
2212 ntStatus = AFSVerifyEntry( AuthGroup,
2215 if( !NT_SUCCESS( ntStatus))
2218 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2219 AFS_TRACE_LEVEL_ERROR,
2220 "AFSCreateDirEntry Failed to verify parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2221 &ParentDirCB->NameInformation.FileName,
2222 ParentObjectInfo->FileId.Cell,
2223 ParentObjectInfo->FileId.Volume,
2224 ParentObjectInfo->FileId.Vnode,
2225 ParentObjectInfo->FileId.Unique,
2228 AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2230 try_return( ntStatus);
2235 // Check for the entry in the event we raced with some other thread
2238 AFSLocateCaseSensitiveDirEntry( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
2239 (ULONG)pDirNode->CaseSensitiveTreeEntry.HashIndex,
2242 if( pExistingDirNode != NULL)
2244 if (AFSIsEqualFID( &pDirNode->ObjectInformation->FileId,
2245 &pExistingDirNode->ObjectInformation->FileId))
2248 if ( pExistingDirNode != pDirNode)
2251 lCount = InterlockedDecrement( &pDirNode->DirOpenReferenceCount);
2253 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2254 AFS_TRACE_LEVEL_VERBOSE,
2255 "AFSCreateDirEntry Decrement count on %wZ DE %p Cnt %d\n",
2256 &pDirNode->NameInformation.FileName,
2260 AFSDeleteDirEntry( ParentObjectInfo,
2263 lCount = InterlockedIncrement( &pExistingDirNode->DirOpenReferenceCount);
2265 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2266 AFS_TRACE_LEVEL_VERBOSE,
2267 "AFSCreateDirEntry Increment count on %wZ DE %p Cnt %d\n",
2268 &pExistingDirNode->NameInformation.FileName,
2272 *DirEntry = pExistingDirNode;
2275 AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2277 try_return( ntStatus = STATUS_SUCCESS);
2283 // Need to tear down this entry and rebuild it below
2286 if( pExistingDirNode->DirOpenReferenceCount <= 0)
2289 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2290 AFS_TRACE_LEVEL_VERBOSE,
2291 "AFSCreateDirEntry Different FIDs - Deleting DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
2293 &pExistingDirNode->NameInformation.FileName,
2294 pExistingDirNode->ObjectInformation->FileId.Cell,
2295 pExistingDirNode->ObjectInformation->FileId.Volume,
2296 pExistingDirNode->ObjectInformation->FileId.Vnode,
2297 pExistingDirNode->ObjectInformation->FileId.Unique,
2298 pDirNode->ObjectInformation->FileId.Cell,
2299 pDirNode->ObjectInformation->FileId.Volume,
2300 pDirNode->ObjectInformation->FileId.Vnode,
2301 pDirNode->ObjectInformation->FileId.Unique);
2303 AFSDeleteDirEntry( ParentObjectInfo,
2309 SetFlag( pExistingDirNode->Flags, AFS_DIR_ENTRY_DELETED);
2311 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2312 AFS_TRACE_LEVEL_VERBOSE,
2313 "AFSCreateDirEntry Different FIDs - Removing DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
2315 &pExistingDirNode->NameInformation.FileName,
2316 pExistingDirNode->ObjectInformation->FileId.Cell,
2317 pExistingDirNode->ObjectInformation->FileId.Volume,
2318 pExistingDirNode->ObjectInformation->FileId.Vnode,
2319 pExistingDirNode->ObjectInformation->FileId.Unique,
2320 pDirNode->ObjectInformation->FileId.Cell,
2321 pDirNode->ObjectInformation->FileId.Volume,
2322 pDirNode->ObjectInformation->FileId.Vnode,
2323 pDirNode->ObjectInformation->FileId.Unique);
2325 AFSRemoveNameEntry( ParentObjectInfo,
2331 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2332 AFS_TRACE_LEVEL_VERBOSE_2,
2333 "AFSCreateDirEntry Inserting dir entry in parent %wZ FID %08lX-%08lX-%08lX-%08lX Component %wZ\n",
2334 &ParentDirCB->NameInformation.FileName,
2335 ParentObjectInfo->FileId.Cell,
2336 ParentObjectInfo->FileId.Volume,
2337 ParentObjectInfo->FileId.Vnode,
2338 ParentObjectInfo->FileId.Unique,
2342 // Insert the directory node
2345 AFSInsertDirectoryNode( ParentObjectInfo,
2350 // Pass back the dir entry
2353 *DirEntry = pDirNode;
2355 AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2366 AFSInsertDirectoryNode( IN AFSObjectInfoCB *ParentObjectInfo,
2367 IN AFSDirectoryCB *DirEntry,
2368 IN BOOLEAN InsertInEnumList)
2376 ASSERT( ExIsResourceAcquiredExclusiveLite( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock));
2379 // Insert the node into the directory node tree
2382 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2383 AFS_TRACE_LEVEL_VERBOSE,
2384 "AFSInsertDirectoryNode Insert DE %p for %wZ Clearing NOT_IN flag\n",
2386 &DirEntry->NameInformation.FileName);
2388 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
2390 if( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead == NULL)
2393 ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = DirEntry;
2395 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2396 AFS_TRACE_LEVEL_VERBOSE,
2397 "AFSInsertDirectoryNode Insert DE %p to head of case sensitive tree for %wZ\n",
2399 &DirEntry->NameInformation.FileName);
2404 AFSInsertCaseSensitiveDirEntry( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
2407 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2408 AFS_TRACE_LEVEL_VERBOSE,
2409 "AFSInsertDirectoryNode Insert DE %p to case sensitive tree for %wZ\n",
2411 &DirEntry->NameInformation.FileName);
2414 if( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead == NULL)
2417 ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = DirEntry;
2419 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
2421 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2422 AFS_TRACE_LEVEL_VERBOSE,
2423 "AFSInsertDirectoryNode Insert DE %p to head of case insensitive tree for %wZ\n",
2425 &DirEntry->NameInformation.FileName);
2430 AFSInsertCaseInsensitiveDirEntry( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
2433 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2434 AFS_TRACE_LEVEL_VERBOSE,
2435 "AFSInsertDirectoryNode Insert DE %p to case insensitive tree for %wZ\n",
2437 &DirEntry->NameInformation.FileName);
2441 // Into the shortname tree
2444 if( DirEntry->Type.Data.ShortNameTreeEntry.HashIndex != 0)
2447 if( ParentObjectInfo->Specific.Directory.ShortNameTree == NULL)
2450 ParentObjectInfo->Specific.Directory.ShortNameTree = DirEntry;
2452 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2453 AFS_TRACE_LEVEL_VERBOSE,
2454 "AFSInsertDirectoryNode Insert DE %p to head of shortname tree for %wZ\n",
2456 &DirEntry->NameInformation.FileName);
2458 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
2463 if( !NT_SUCCESS( AFSInsertShortNameDirEntry( ParentObjectInfo->Specific.Directory.ShortNameTree,
2466 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2467 AFS_TRACE_LEVEL_VERBOSE,
2468 "AFSInsertDirectoryNode Failed to insert DE %p to shortname tree for %wZ\n",
2470 &DirEntry->NameInformation.FileName);
2474 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
2476 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2477 AFS_TRACE_LEVEL_VERBOSE,
2478 "AFSInsertDirectoryNode Insert DE %p to shortname tree for %wZ\n",
2480 &DirEntry->NameInformation.FileName);
2485 if( InsertInEnumList)
2489 // And insert the node into the directory list
2492 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2493 AFS_TRACE_LEVEL_VERBOSE,
2494 "AFSInsertDirectoryNode Inserting entry %p %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2496 &DirEntry->NameInformation.FileName,
2497 DirEntry->ObjectInformation->FileId.Cell,
2498 DirEntry->ObjectInformation->FileId.Volume,
2499 DirEntry->ObjectInformation->FileId.Vnode,
2500 DirEntry->ObjectInformation->FileId.Unique);
2502 if( ParentObjectInfo->Specific.Directory.DirectoryNodeListHead == NULL)
2505 ParentObjectInfo->Specific.Directory.DirectoryNodeListHead = DirEntry;
2510 ParentObjectInfo->Specific.Directory.DirectoryNodeListTail->ListEntry.fLink = (void *)DirEntry;
2512 DirEntry->ListEntry.bLink = (void *)ParentObjectInfo->Specific.Directory.DirectoryNodeListTail;
2515 ParentObjectInfo->Specific.Directory.DirectoryNodeListTail = DirEntry;
2517 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST);
2519 lCount = InterlockedIncrement( &ParentObjectInfo->Specific.Directory.DirectoryNodeCount);
2521 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
2522 AFS_TRACE_LEVEL_VERBOSE,
2523 "AFSInsertDirectoryNode Adding entry %wZ Inc Count %d to parent FID %08lX-%08lX-%08lX-%08lX\n",
2524 &DirEntry->NameInformation.FileName,
2526 ParentObjectInfo->FileId.Cell,
2527 ParentObjectInfo->FileId.Volume,
2528 ParentObjectInfo->FileId.Vnode,
2529 ParentObjectInfo->FileId.Unique);
2537 AFSDeleteDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
2538 IN AFSDirectoryCB *DirEntry)
2546 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2547 AFS_TRACE_LEVEL_VERBOSE,
2548 "AFSDeleteDirEntry Deleting dir entry in parent %p Entry %p %wZ FID %08lX-%08lX-%08lX-%08lX RefCount %d\n",
2551 &DirEntry->NameInformation.FileName,
2552 DirEntry->ObjectInformation->FileId.Cell,
2553 DirEntry->ObjectInformation->FileId.Volume,
2554 DirEntry->ObjectInformation->FileId.Vnode,
2555 DirEntry->ObjectInformation->FileId.Unique,
2556 DirEntry->DirOpenReferenceCount);
2558 ASSERT( DirEntry->DirOpenReferenceCount == 0);
2560 AFSRemoveDirNodeFromParent( ParentObjectInfo,
2565 // Free up the name buffer if it was reallocated
2568 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_RELEASE_NAME_BUFFER))
2571 AFSExFreePoolWithTag( DirEntry->NameInformation.FileName.Buffer, 0);
2574 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER))
2577 AFSExFreePoolWithTag( DirEntry->NameInformation.TargetName.Buffer, 0);
2581 // Dereference the object for this dir entry
2584 lCount = AFSObjectInfoDecrement( DirEntry->ObjectInformation,
2585 AFS_OBJECT_REFERENCE_DIRENTRY);
2587 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2588 AFS_TRACE_LEVEL_VERBOSE,
2589 "AFSDeleteDirEntry Decrement count on object %p Cnt %d\n",
2590 DirEntry->ObjectInformation,
2593 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_DELETED) &&
2594 DirEntry->ObjectInformation->Links == 0)
2597 SetFlag( DirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED);
2600 ExDeleteResourceLite( &DirEntry->NonPaged->Lock);
2602 AFSExFreePoolWithTag( DirEntry->NonPaged, AFS_DIR_ENTRY_NP_TAG);
2605 // Free up the dir entry
2608 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
2609 AFS_TRACE_LEVEL_VERBOSE,
2610 "AFSDeleteDirEntry AFS_DIR_ENTRY_TAG deallocating %p\n",
2613 AFSExFreePoolWithTag( DirEntry, AFS_DIR_ENTRY_TAG);
2618 AFSRemoveDirNodeFromParent( IN AFSObjectInfoCB *ParentObjectInfo,
2619 IN AFSDirectoryCB *DirEntry,
2620 IN BOOLEAN RemoveFromEnumList)
2623 NTSTATUS ntStatus = STATUS_SUCCESS;
2630 ASSERT( ExIsResourceAcquiredExclusiveLite( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock));
2632 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2633 AFS_TRACE_LEVEL_VERBOSE,
2634 "AFSRemoveDirNodeFromParent Removing DirEntry %p %wZ FID %08lX-%08lX-%08lX-%08lX from Parent %p\n",
2636 &DirEntry->NameInformation.FileName,
2637 DirEntry->ObjectInformation->FileId.Cell,
2638 DirEntry->ObjectInformation->FileId.Volume,
2639 DirEntry->ObjectInformation->FileId.Vnode,
2640 DirEntry->ObjectInformation->FileId.Unique,
2643 if( !BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
2646 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2647 AFS_TRACE_LEVEL_VERBOSE,
2648 "AFSRemoveDirNodeFromParent Removing DirEntry %p name %wZ\n",
2650 &DirEntry->NameInformation.FileName);
2652 AFSRemoveNameEntry( ParentObjectInfo,
2658 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2659 AFS_TRACE_LEVEL_VERBOSE,
2660 "AFSRemoveDirNodeFromParent DE %p for %wZ NOT removing entry due to flag set\n",
2662 &DirEntry->NameInformation.FileName);
2666 if( RemoveFromEnumList &&
2667 BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST))
2671 // And remove the entry from the enumeration list
2674 if( DirEntry->ListEntry.fLink == NULL)
2677 ParentObjectInfo->Specific.Directory.DirectoryNodeListTail = (AFSDirectoryCB *)DirEntry->ListEntry.bLink;
2682 ((AFSDirectoryCB *)DirEntry->ListEntry.fLink)->ListEntry.bLink = DirEntry->ListEntry.bLink;
2685 if( DirEntry->ListEntry.bLink == NULL)
2688 ParentObjectInfo->Specific.Directory.DirectoryNodeListHead = (AFSDirectoryCB *)DirEntry->ListEntry.fLink;
2693 ((AFSDirectoryCB *)DirEntry->ListEntry.bLink)->ListEntry.fLink = DirEntry->ListEntry.fLink;
2696 ASSERT( ParentObjectInfo->Specific.Directory.DirectoryNodeCount > 0);
2698 lCount = InterlockedDecrement( &ParentObjectInfo->Specific.Directory.DirectoryNodeCount);
2700 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST);
2702 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
2703 AFS_TRACE_LEVEL_VERBOSE,
2704 "AFSRemoveDirNodeFromParent Removing entry %wZ Dec Count %d to parent FID %08lX-%08lX-%08lX-%08lX\n",
2705 &DirEntry->NameInformation.FileName,
2707 ParentObjectInfo->FileId.Cell,
2708 ParentObjectInfo->FileId.Volume,
2709 ParentObjectInfo->FileId.Vnode,
2710 ParentObjectInfo->FileId.Unique);
2712 DirEntry->ListEntry.fLink = NULL;
2713 DirEntry->ListEntry.bLink = NULL;
2721 AFSFixupTargetName( IN OUT PUNICODE_STRING FileName,
2722 IN OUT PUNICODE_STRING TargetFileName)
2725 NTSTATUS ntStatus = STATUS_SUCCESS;
2726 UNICODE_STRING uniFileName;
2732 // We will process backwards from the end of the name looking
2733 // for the first \ we encounter
2736 uniFileName.Length = FileName->Length;
2737 uniFileName.MaximumLength = FileName->MaximumLength;
2739 uniFileName.Buffer = FileName->Buffer;
2744 if( uniFileName.Buffer[ (uniFileName.Length/sizeof( WCHAR)) - 1] == L'\\')
2748 // Subtract one more character off of the filename if it is not the root
2751 if( uniFileName.Length > sizeof( WCHAR))
2754 uniFileName.Length -= sizeof( WCHAR);
2758 // Now build up the target name
2761 TargetFileName->Length = FileName->Length - uniFileName.Length;
2764 // If we are not on the root then fixup the name
2767 if( uniFileName.Length > sizeof( WCHAR))
2770 TargetFileName->Length -= sizeof( WCHAR);
2772 TargetFileName->Buffer = &uniFileName.Buffer[ (uniFileName.Length/sizeof( WCHAR)) + 1];
2777 TargetFileName->Buffer = &uniFileName.Buffer[ uniFileName.Length/sizeof( WCHAR)];
2781 // Fixup the passed back filename length
2784 FileName->Length = uniFileName.Length;
2786 TargetFileName->MaximumLength = TargetFileName->Length;
2791 uniFileName.Length -= sizeof( WCHAR);
2799 AFSParseName( IN PIRP Irp,
2801 OUT PUNICODE_STRING FileName,
2802 OUT PUNICODE_STRING ParsedFileName,
2803 OUT PUNICODE_STRING RootFileName,
2804 OUT ULONG *ParseFlags,
2805 OUT AFSVolumeCB **VolumeCB,
2806 OUT AFSDirectoryCB **ParentDirectoryCB,
2807 OUT AFSNameArrayHdr **NameArray)
2810 NTSTATUS ntStatus = STATUS_SUCCESS;
2811 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2812 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2813 UNICODE_STRING uniFullName, uniComponentName, uniRemainingPath;
2815 AFSDirectoryCB *pDirEntry = NULL;
2816 USHORT usIndex = 0, usDriveIndex = 0;
2817 AFSCcb *pRelatedCcb = NULL;
2818 AFSNameArrayHdr *pNameArray = NULL, *pRelatedNameArray = NULL;
2819 USHORT usComponentIndex = 0;
2820 USHORT usComponentLength = 0;
2821 AFSVolumeCB *pVolumeCB = NULL;
2822 AFSFcb *pRelatedFcb = NULL;
2823 BOOLEAN bReleaseTreeLock = FALSE;
2824 BOOLEAN bIsAllShare = FALSE;
2831 // Indicate we are opening a root ...
2834 *ParseFlags = AFS_PARSE_FLAG_ROOT_ACCESS;
2836 *ParentDirectoryCB = NULL;
2838 if( pIrpSp->FileObject->RelatedFileObject != NULL)
2841 pRelatedFcb = (AFSFcb *)pIrpSp->FileObject->RelatedFileObject->FsContext;
2843 pRelatedCcb = (AFSCcb *)pIrpSp->FileObject->RelatedFileObject->FsContext2;
2845 pRelatedNameArray = pRelatedCcb->NameArray;
2847 uniFullName = pIrpSp->FileObject->FileName;
2849 ASSERT( pRelatedFcb != NULL);
2852 // No wild cards in the name
2855 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2856 AFS_TRACE_LEVEL_VERBOSE_2,
2857 "AFSParseName (%p) Relative open for %wZ FID %08lX-%08lX-%08lX-%08lX component %wZ\n",
2859 &pRelatedCcb->DirectoryCB->NameInformation.FileName,
2860 pRelatedCcb->DirectoryCB->ObjectInformation->FileId.Cell,
2861 pRelatedCcb->DirectoryCB->ObjectInformation->FileId.Volume,
2862 pRelatedCcb->DirectoryCB->ObjectInformation->FileId.Vnode,
2863 pRelatedCcb->DirectoryCB->ObjectInformation->FileId.Unique,
2866 if( FsRtlDoesNameContainWildCards( &uniFullName))
2869 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2870 AFS_TRACE_LEVEL_ERROR,
2871 "AFSParseName (%p) Component %wZ contains wild cards\n",
2875 try_return( ntStatus = STATUS_OBJECT_NAME_INVALID);
2878 pVolumeCB = pRelatedFcb->ObjectInformation->VolumeCB;
2880 pDirEntry = pRelatedCcb->DirectoryCB;
2882 *FileName = pIrpSp->FileObject->FileName;
2885 // Grab the root node while checking state
2888 AFSAcquireShared( pVolumeCB->VolumeLock,
2891 if( BooleanFlagOn( pVolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
2892 BooleanFlagOn( pVolumeCB->Flags, AFS_VOLUME_FLAGS_OFFLINE))
2896 // The volume has been taken off line so fail the access
2899 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2900 AFS_TRACE_LEVEL_ERROR,
2901 "AFSParseName (%p) Volume %08lX:%08lX OFFLINE/INVALID\n",
2903 pVolumeCB->ObjectInformation.FileId.Cell,
2904 pVolumeCB->ObjectInformation.FileId.Volume);
2906 AFSReleaseResource( pVolumeCB->VolumeLock);
2908 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
2911 if( BooleanFlagOn( pVolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_VERIFY))
2914 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2915 AFS_TRACE_LEVEL_VERBOSE,
2916 "AFSParseName (%p) Verifying root of volume %08lX:%08lX\n",
2918 pVolumeCB->ObjectInformation.FileId.Cell,
2919 pVolumeCB->ObjectInformation.FileId.Volume);
2921 ntStatus = AFSVerifyVolume( (ULONGLONG)PsGetCurrentProcessId(),
2924 if( !NT_SUCCESS( ntStatus))
2927 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2928 AFS_TRACE_LEVEL_ERROR,
2929 "AFSParseName (%p) Failed verification of root Status %08lX\n",
2933 AFSReleaseResource( pVolumeCB->VolumeLock);
2935 try_return( ntStatus);
2939 AFSReleaseResource( pVolumeCB->VolumeLock);
2941 if( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY))
2944 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2945 AFS_TRACE_LEVEL_VERBOSE,
2946 "AFSParseName (%p) Verifying parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2948 &pDirEntry->NameInformation.FileName,
2949 pDirEntry->ObjectInformation->FileId.Cell,
2950 pDirEntry->ObjectInformation->FileId.Volume,
2951 pDirEntry->ObjectInformation->FileId.Vnode,
2952 pDirEntry->ObjectInformation->FileId.Unique);
2955 // Directory TreeLock should be exclusively held
2958 AFSAcquireExcl( pDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
2961 ntStatus = AFSVerifyEntry( AuthGroup,
2964 AFSReleaseResource( pDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
2966 if( !NT_SUCCESS( ntStatus))
2969 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2970 AFS_TRACE_LEVEL_VERBOSE,
2971 "AFSParseName (%p) Failed verification of parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2973 &pDirEntry->NameInformation.FileName,
2974 pDirEntry->ObjectInformation->FileId.Cell,
2975 pDirEntry->ObjectInformation->FileId.Volume,
2976 pDirEntry->ObjectInformation->FileId.Vnode,
2977 pDirEntry->ObjectInformation->FileId.Unique,
2980 try_return( ntStatus);
2985 // Create our full path name buffer
2988 uniFullName.MaximumLength = pRelatedCcb->FullFileName.Length +
2990 pIrpSp->FileObject->FileName.Length +
2993 uniFullName.Length = 0;
2995 uniFullName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2996 uniFullName.MaximumLength,
2997 AFS_NAME_BUFFER_THREE_TAG);
2999 if( uniFullName.Buffer == NULL)
3002 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3003 AFS_TRACE_LEVEL_ERROR,
3004 "AFSParseName (%p) Failed to allocate full name buffer\n",
3007 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3010 RtlZeroMemory( uniFullName.Buffer,
3011 uniFullName.MaximumLength);
3013 RtlCopyMemory( uniFullName.Buffer,
3014 pRelatedCcb->FullFileName.Buffer,
3015 pRelatedCcb->FullFileName.Length);
3017 uniFullName.Length = pRelatedCcb->FullFileName.Length;
3019 usComponentIndex = (USHORT)(uniFullName.Length/sizeof( WCHAR));
3021 usComponentLength = pIrpSp->FileObject->FileName.Length;
3023 if( uniFullName.Buffer[ (uniFullName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
3024 pIrpSp->FileObject->FileName.Length > 0 &&
3025 pIrpSp->FileObject->FileName.Buffer[ 0] != L'\\' &&
3026 pIrpSp->FileObject->FileName.Buffer[ 0] != L':')
3029 uniFullName.Buffer[ (uniFullName.Length/sizeof( WCHAR))] = L'\\';
3031 uniFullName.Length += sizeof( WCHAR);
3033 usComponentLength += sizeof( WCHAR);
3036 if( pIrpSp->FileObject->FileName.Length > 0)
3039 RtlCopyMemory( &uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)],
3040 pIrpSp->FileObject->FileName.Buffer,
3041 pIrpSp->FileObject->FileName.Length);
3043 uniFullName.Length += pIrpSp->FileObject->FileName.Length;
3046 *RootFileName = uniFullName;
3049 // We populate up to the current parent
3052 if( pRelatedNameArray == NULL)
3056 // Init and populate our name array
3059 pNameArray = AFSInitNameArray( NULL,
3062 if( pNameArray == NULL)
3065 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3066 AFS_TRACE_LEVEL_VERBOSE,
3067 "AFSParseName (%p) Failed to initialize name array\n",
3070 AFSExFreePoolWithTag( uniFullName.Buffer, 0);
3072 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3075 ntStatus = AFSPopulateNameArray( pNameArray,
3077 pRelatedCcb->DirectoryCB);
3083 // Init and populate our name array
3086 pNameArray = AFSInitNameArray( NULL,
3087 pRelatedNameArray->MaxElementCount);
3089 if( pNameArray == NULL)
3092 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3093 AFS_TRACE_LEVEL_VERBOSE,
3094 "AFSParseName (%p) Failed to initialize name array\n",
3097 AFSExFreePoolWithTag( uniFullName.Buffer, 0);
3099 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3102 ntStatus = AFSPopulateNameArrayFromRelatedArray( pNameArray,
3104 pRelatedCcb->DirectoryCB);
3107 if( !NT_SUCCESS( ntStatus))
3110 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3111 AFS_TRACE_LEVEL_VERBOSE,
3112 "AFSParseName (%p) Failed to populate name array\n",
3115 AFSExFreePoolWithTag( uniFullName.Buffer, 0);
3117 try_return( ntStatus);
3120 ParsedFileName->Length = usComponentLength;
3121 ParsedFileName->MaximumLength = uniFullName.MaximumLength;
3123 ParsedFileName->Buffer = &uniFullName.Buffer[ usComponentIndex];
3126 // Indicate to caller that RootFileName must be freed
3129 SetFlag( *ParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
3131 *NameArray = pNameArray;
3134 // Increment our volume reference count
3137 lCount = AFSVolumeIncrement( pVolumeCB,
3138 AFS_VOLUME_REFERENCE_PARSE_NAME);
3140 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
3141 AFS_TRACE_LEVEL_VERBOSE,
3142 "AFSParseName Increment count on volume %p Cnt %d\n",
3146 *VolumeCB = pVolumeCB;
3148 *ParentDirectoryCB = pDirEntry;
3150 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3151 AFS_TRACE_LEVEL_VERBOSE_2,
3152 "AFSParseName (%p) Returning full name %wZ\n",
3156 try_return( ntStatus);
3160 // No wild cards in the name
3163 uniFullName = pIrpSp->FileObject->FileName;
3165 if( FsRtlDoesNameContainWildCards( &uniFullName) ||
3166 uniFullName.Length < AFSServerName.Length)
3169 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3170 AFS_TRACE_LEVEL_ERROR,
3171 "AFSParseName (%p) Name %wZ contains wild cards or too short\n",
3175 try_return( ntStatus = STATUS_OBJECT_NAME_INVALID);
3179 // The name is a fully qualified name. Parse out the server/share names and
3180 // point to the root qualified name
3181 // First thing is to locate the server name
3184 FsRtlDissectName( uniFullName,
3188 uniFullName = uniRemainingPath;
3191 // This component is the server name we are serving
3194 if( RtlCompareUnicodeString( &uniComponentName,
3200 // Drive letter based name?
3203 uniFullName = pIrpSp->FileObject->FileName;
3205 while( usIndex < uniFullName.Length/sizeof( WCHAR))
3208 if( uniFullName.Buffer[ usIndex] == L':')
3211 uniFullName.Buffer = &uniFullName.Buffer[ usIndex + 2];
3213 uniFullName.Length -= (usIndex + 2) * sizeof( WCHAR);
3215 usDriveIndex = usIndex - 1;
3224 // Do we have the right server name now?
3227 FsRtlDissectName( uniFullName,
3231 uniFullName = uniRemainingPath;
3234 // This component is the server name we are serving
3237 if( RtlCompareUnicodeString( &uniComponentName,
3242 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3243 AFS_TRACE_LEVEL_ERROR,
3244 "AFSParseName (%p) Name %wZ does not have server name\n",
3246 &pIrpSp->FileObject->FileName);
3248 try_return( ntStatus = STATUS_BAD_NETWORK_NAME);
3252 // Validate this drive letter is actively mapped
3255 if( usDriveIndex > 0 &&
3256 !AFSIsDriveMapped( pIrpSp->FileObject->FileName.Buffer[ usDriveIndex]))
3259 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3260 AFS_TRACE_LEVEL_ERROR,
3261 "AFSParseName (%p) Name %wZ contains invalid drive mapping\n",
3263 &pIrpSp->FileObject->FileName);
3265 try_return( ntStatus = STATUS_BAD_NETWORK_NAME);
3269 if( FsRtlDoesNameContainWildCards( &uniFullName))
3272 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3273 AFS_TRACE_LEVEL_ERROR,
3274 "AFSParseName (%p) Component %wZ contains wild cards\n",
3278 try_return( ntStatus = STATUS_OBJECT_NAME_INVALID);
3281 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3282 AFS_TRACE_LEVEL_VERBOSE_2,
3283 "AFSParseName (%p) Processing full name %wZ\n",
3287 if( uniFullName.Length > 0 &&
3288 uniFullName.Buffer[ (uniFullName.Length/sizeof( WCHAR)) - 1] == L'\\')
3291 uniFullName.Length -= sizeof( WCHAR);
3295 // Be sure we are online and ready to go
3298 AFSAcquireShared( AFSGlobalRoot->VolumeLock,
3301 if( BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
3302 BooleanFlagOn( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE))
3306 // The volume has been taken off line so fail the access
3309 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3310 AFS_TRACE_LEVEL_ERROR,
3311 "AFSParseName (%p) Volume %08lX:%08lX OFFLINE/INVALID\n",
3313 AFSGlobalRoot->ObjectInformation.FileId.Cell,
3314 AFSGlobalRoot->ObjectInformation.FileId.Volume);
3316 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3318 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
3321 if( BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_VERIFY))
3324 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3325 AFS_TRACE_LEVEL_VERBOSE,
3326 "AFSParseName (%p) Verifying root of volume %08lX:%08lX\n",
3328 AFSGlobalRoot->ObjectInformation.FileId.Cell,
3329 AFSGlobalRoot->ObjectInformation.FileId.Volume);
3331 ntStatus = AFSVerifyVolume( (ULONGLONG)PsGetCurrentProcessId(),
3334 if( !NT_SUCCESS( ntStatus))
3337 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3338 AFS_TRACE_LEVEL_ERROR,
3339 "AFSParseName (%p) Failed verification of root Status %08lX\n",
3343 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3345 try_return( ntStatus);
3349 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3351 if( !BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
3354 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3355 AFS_TRACE_LEVEL_VERBOSE,
3356 "AFSParseName (%p) Enumerating global root of volume %08lX:%08lX\n",
3358 AFSGlobalRoot->ObjectInformation.FileId.Cell,
3359 AFSGlobalRoot->ObjectInformation.FileId.Volume);
3361 ntStatus = AFSEnumerateGlobalRoot( AuthGroup);
3363 if( !NT_SUCCESS( ntStatus))
3366 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3367 AFS_TRACE_LEVEL_ERROR,
3368 "AFSParseName (%p) Failed enumeraiton of root Status %08lX\n",
3372 try_return( ntStatus);
3377 // Check for the \\Server access and return it as though it were \\Server\Globalroot
3380 if( uniRemainingPath.Buffer == NULL ||
3381 ( uniRemainingPath.Length == sizeof( WCHAR) &&
3382 uniRemainingPath.Buffer[ 0] == L'\\'))
3385 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3386 AFS_TRACE_LEVEL_VERBOSE_2,
3387 "AFSParseName (%p) 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 Increment2 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);
3409 *RootFileName = uniFullName;
3412 // Include the starting \ in the root name
3415 if( RootFileName->Buffer[ 0] != L'\\')
3417 RootFileName->Buffer--;
3418 RootFileName->Length += sizeof( WCHAR);
3419 RootFileName->MaximumLength += sizeof( WCHAR);
3423 // Get the 'share' name
3426 FsRtlDissectName( uniFullName,
3430 if( FsRtlDoesNameContainWildCards( &uniFullName))
3433 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3434 AFS_TRACE_LEVEL_ERROR,
3435 "AFSParseName (%p) Component %wZ contains wild cards\n",
3439 try_return( ntStatus = STATUS_OBJECT_NAME_INVALID);
3443 // If this is the ALL access then perform some additional processing
3446 if( uniComponentName.Length == 0 ||
3447 RtlCompareUnicodeString( &uniComponentName,
3455 // If there is nothing else then get out
3458 if( uniRemainingPath.Buffer == NULL ||
3459 uniRemainingPath.Length == 0 ||
3460 ( uniRemainingPath.Length == sizeof( WCHAR) &&
3461 uniRemainingPath.Buffer[ 0] == L'\\'))
3464 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3465 AFS_TRACE_LEVEL_VERBOSE_2,
3466 "AFSParseName (%p) Returning global root access\n",
3469 lCount = InterlockedIncrement( &AFSGlobalRoot->DirectoryCB->DirOpenReferenceCount);
3471 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3472 AFS_TRACE_LEVEL_VERBOSE,
3473 "AFSParseName Increment3 count on %wZ DE %p Ccb %p Cnt %d\n",
3474 &AFSGlobalRoot->DirectoryCB->NameInformation.FileName,
3475 AFSGlobalRoot->DirectoryCB,
3481 FileName->Length = 0;
3482 FileName->MaximumLength = 0;
3483 FileName->Buffer = NULL;
3485 try_return( ntStatus = STATUS_SUCCESS);
3489 // Process the name again to strip off the ALL portion
3492 uniFullName = uniRemainingPath;
3494 FsRtlDissectName( uniFullName,
3499 // Check for the PIOCtl name
3502 if( RtlCompareUnicodeString( &uniComponentName,
3507 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3508 AFS_TRACE_LEVEL_VERBOSE_2,
3509 "AFSParseName (%p) Returning root PIOCtl access\n",
3512 lCount = InterlockedIncrement( &AFSGlobalRoot->DirectoryCB->DirOpenReferenceCount);
3514 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3515 AFS_TRACE_LEVEL_VERBOSE,
3516 "AFSParseName Increment4 count on %wZ DE %p Ccb %p Cnt %d\n",
3517 &AFSGlobalRoot->DirectoryCB->NameInformation.FileName,
3518 AFSGlobalRoot->DirectoryCB,
3522 ClearFlag( *ParseFlags, AFS_PARSE_FLAG_ROOT_ACCESS);
3526 *FileName = AFSPIOCtlName;
3528 try_return( ntStatus = STATUS_SUCCESS);
3531 else if( (pDirEntry = AFSGetSpecialShareNameEntry( &uniComponentName,
3532 &uniRemainingPath)) != NULL)
3535 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3536 AFS_TRACE_LEVEL_VERBOSE_2,
3537 "AFSParseName (%p) Returning root share name %wZ access\n",
3542 // Add in the full share name to pass back
3545 if( uniRemainingPath.Buffer != NULL)
3549 // This routine strips off the leading slash so add it back in
3552 uniRemainingPath.Buffer--;
3553 uniRemainingPath.Length += sizeof( WCHAR);
3554 uniRemainingPath.MaximumLength += sizeof( WCHAR);
3557 // And the cell name
3560 uniRemainingPath.Buffer -= (uniComponentName.Length/sizeof( WCHAR));
3561 uniRemainingPath.Length += uniComponentName.Length;
3562 uniRemainingPath.MaximumLength += uniComponentName.Length;
3564 uniComponentName = uniRemainingPath;
3569 *FileName = uniComponentName;
3571 ClearFlag( *ParseFlags, AFS_PARSE_FLAG_ROOT_ACCESS);
3573 *ParentDirectoryCB = pDirEntry;
3575 try_return( ntStatus = STATUS_SUCCESS);
3579 // Determine the 'share' we are accessing
3582 ulCRC = AFSGenerateCRC( &uniComponentName,
3585 AFSAcquireShared( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
3588 bReleaseTreeLock = TRUE;
3590 AFSLocateCaseSensitiveDirEntry( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
3594 if( pDirEntry == NULL)
3597 ulCRC = AFSGenerateCRC( &uniComponentName,
3600 AFSLocateCaseInsensitiveDirEntry( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
3604 if( pDirEntry == NULL)
3608 // OK, if this component is a valid short name then try
3609 // a lookup in the short name tree
3612 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
3613 RtlIsNameLegalDOS8Dot3( &uniComponentName,
3618 AFSLocateShortNameDirEntry( AFSGlobalRoot->ObjectInformation.Specific.Directory.ShortNameTree,
3623 if( pDirEntry == NULL)
3627 // Check with the service whether it is a valid cell name
3630 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
3632 bReleaseTreeLock = FALSE;
3634 ntStatus = AFSCheckCellName( AuthGroup,
3638 if( !NT_SUCCESS( ntStatus))
3642 uniRemainingPath.Length == 0 &&
3643 ntStatus == STATUS_OBJECT_PATH_NOT_FOUND)
3646 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3647 AFS_TRACE_LEVEL_VERBOSE,
3648 "AFSParseName (%p) AFSCheckCellName %wZ returned path not found; ntStatus %08X\n",
3651 STATUS_OBJECT_NAME_NOT_FOUND);
3653 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
3656 try_return( ntStatus);
3662 if( bReleaseTreeLock)
3664 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
3669 // Be sure we are starting from the correct volume
3672 if( pDirEntry->ObjectInformation->VolumeCB != AFSGlobalRoot)
3676 // We dropped the global root in the CheckCellName routine which is the
3677 // only way we can be here
3680 pVolumeCB = pDirEntry->ObjectInformation->VolumeCB;
3683 // Init our name array
3686 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
3689 if( pNameArray == NULL)
3692 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3693 AFS_TRACE_LEVEL_VERBOSE,
3694 "AFSParseName (%p) Failed to initialize name array\n",
3697 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3700 ntStatus = AFSInsertNextElement( pNameArray,
3701 pVolumeCB->DirectoryCB);
3706 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3707 AFS_TRACE_LEVEL_VERBOSE,
3708 "AFSParseName (%p) Failed to insert name array element\n",
3711 try_return( ntStatus);
3715 // In this case don't add back in the 'share' name since that is where we are
3716 // starting. Just put the leading slash back in
3719 if( uniRemainingPath.Buffer != NULL)
3722 uniRemainingPath.Buffer--;
3723 uniRemainingPath.Length += sizeof( WCHAR);
3724 uniRemainingPath.MaximumLength += sizeof( WCHAR);
3726 if( uniRemainingPath.Length > sizeof( WCHAR))
3729 ClearFlag( *ParseFlags, AFS_PARSE_FLAG_ROOT_ACCESS);
3733 // Pass back the parent being the root of the volume
3736 *ParentDirectoryCB = pVolumeCB->DirectoryCB;
3742 // Pass back a root slash
3745 uniRemainingPath = uniComponentName;
3747 uniRemainingPath.Buffer--;
3748 uniRemainingPath.Length = sizeof( WCHAR);
3749 uniRemainingPath.MaximumLength = sizeof( WCHAR);
3752 // This is a root open so pass back no parent
3759 pVolumeCB = AFSGlobalRoot;
3762 // Init our name array
3765 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
3767 if( pNameArray == NULL)
3770 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3771 AFS_TRACE_LEVEL_VERBOSE,
3772 "AFSParseName (%p) Failed to initialize name array\n",
3775 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3779 // Add back in the 'share' portion of the name since we will parse it out on return
3782 if( uniRemainingPath.Buffer != NULL)
3786 // This routine strips off the leading slash so add it back in
3789 uniRemainingPath.Buffer--;
3790 uniRemainingPath.Length += sizeof( WCHAR);
3791 uniRemainingPath.MaximumLength += sizeof( WCHAR);
3793 if( uniRemainingPath.Length > sizeof( WCHAR))
3796 ClearFlag( *ParseFlags, AFS_PARSE_FLAG_ROOT_ACCESS);
3800 // And the cell name
3803 uniRemainingPath.Buffer -= (uniComponentName.Length/sizeof( WCHAR));
3804 uniRemainingPath.Length += uniComponentName.Length;
3805 uniRemainingPath.MaximumLength += uniComponentName.Length;
3810 uniRemainingPath = uniComponentName;
3814 // And the leading slash again ...
3817 uniRemainingPath.Buffer--;
3818 uniRemainingPath.Length += sizeof( WCHAR);
3819 uniRemainingPath.MaximumLength += sizeof( WCHAR);
3822 // Pass back the parent being the volume root
3825 *ParentDirectoryCB = pVolumeCB->DirectoryCB;
3829 // Return the remaining portion as the file name
3832 *FileName = uniRemainingPath;
3834 *ParsedFileName = uniRemainingPath;
3836 *NameArray = pNameArray;
3838 *VolumeCB = pVolumeCB;
3841 // Increment our reference on the volume
3844 lCount = AFSVolumeIncrement( pVolumeCB,
3845 AFS_VOLUME_REFERENCE_PARSE_NAME);
3847 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
3848 AFS_TRACE_LEVEL_VERBOSE,
3849 "AFSParseName Increment2 count on global volume %p Cnt %d\n",
3855 if( NT_SUCCESS( ntStatus))
3858 if( *ParentDirectoryCB != NULL)
3861 lCount = InterlockedIncrement( &(*ParentDirectoryCB)->DirOpenReferenceCount);
3863 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3864 AFS_TRACE_LEVEL_VERBOSE,
3865 "AFSParseName Increment1 count on %wZ DE %p Ccb %p Cnt %d\n",
3866 &(*ParentDirectoryCB)->NameInformation.FileName,
3867 (*ParentDirectoryCB),
3873 if( *VolumeCB != NULL)
3875 ASSERT( (*VolumeCB)->VolumeReferenceCount > 0);
3878 if( ntStatus != STATUS_SUCCESS)
3881 if( pNameArray != NULL)
3884 AFSFreeNameArray( pNameArray);
3893 AFSCheckCellName( IN GUID *AuthGroup,
3894 IN UNICODE_STRING *CellName,
3895 OUT AFSDirectoryCB **ShareDirEntry)
3898 NTSTATUS ntStatus = STATUS_SUCCESS;
3899 UNICODE_STRING uniName;
3900 AFSDirEnumEntry *pDirEnumEntry = NULL;
3901 AFSDirHdr *pDirHdr = &AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr;
3902 AFSDirectoryCB *pDirNode = NULL;
3903 UNICODE_STRING uniDirName, uniTargetName;
3904 AFSVolumeCB *pVolumeCB = NULL;
3911 // Look for some default names we will not handle
3914 RtlInitUnicodeString( &uniName,
3917 if( RtlCompareUnicodeString( &uniName,
3922 try_return( ntStatus = STATUS_NO_SUCH_FILE);
3925 RtlInitUnicodeString( &uniName,
3928 if( RtlCompareUnicodeString( &uniName,
3933 try_return( ntStatus = STATUS_NO_SUCH_FILE);
3936 RtlInitUnicodeString( &uniName,
3939 if( RtlCompareUnicodeString( &uniName,
3944 try_return( ntStatus = STATUS_NO_SUCH_FILE);
3947 RtlInitUnicodeString( &uniName,
3950 if( RtlCompareUnicodeString( &uniName,
3955 try_return( ntStatus = STATUS_NO_SUCH_FILE);
3959 // OK, ask the CM about this component name
3962 ntStatus = AFSEvaluateTargetByName( AuthGroup,
3963 &AFSGlobalRoot->ObjectInformation,
3967 if( !NT_SUCCESS( ntStatus))
3970 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3971 AFS_TRACE_LEVEL_WARNING,
3972 "AFSCheckCellName entry %wZ does not exist parent FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
3974 AFSGlobalRoot->ObjectInformation.FileId.Cell,
3975 AFSGlobalRoot->ObjectInformation.FileId.Volume,
3976 AFSGlobalRoot->ObjectInformation.FileId.Vnode,
3977 AFSGlobalRoot->ObjectInformation.FileId.Unique,
3980 try_return( ntStatus);
3984 // OK, we have a dir enum entry back so add it to the root node
3987 uniDirName = *CellName;
3989 uniTargetName.Length = (USHORT)pDirEnumEntry->TargetNameLength;
3990 uniTargetName.MaximumLength = uniTargetName.Length;
3991 uniTargetName.Buffer = (WCHAR *)((char *)pDirEnumEntry + pDirEnumEntry->TargetNameOffset);
3994 // Is this entry a root volume entry?
3997 if( pDirEnumEntry->FileId.Cell != AFSGlobalRoot->ObjectInformation.FileId.Cell ||
3998 pDirEnumEntry->FileId.Volume != AFSGlobalRoot->ObjectInformation.FileId.Volume)
4002 // Build the root volume entry
4005 ntStatus = AFSBuildRootVolume( AuthGroup,
4006 &pDirEnumEntry->FileId,
4010 // On success returns with a volume reference count held
4013 if( !NT_SUCCESS( ntStatus))
4015 try_return( ntStatus);
4018 *ShareDirEntry = pVolumeCB->DirectoryCB;
4020 lCount = InterlockedIncrement( &pVolumeCB->DirectoryCB->DirOpenReferenceCount);
4022 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
4023 AFS_TRACE_LEVEL_VERBOSE,
4024 "AFSCheckCellName Increment1 count on %wZ DE %p Ccb %p Cnt %d\n",
4025 &pVolumeCB->DirectoryCB->NameInformation.FileName,
4026 pVolumeCB->DirectoryCB,
4030 lCount = AFSVolumeDecrement( pVolumeCB,
4031 AFS_VOLUME_REFERENCE_BUILD_ROOT);
4033 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
4034 AFS_TRACE_LEVEL_VERBOSE,
4035 "AFSCheckCellName Decrement count on volume %p Cnt %d\n",
4042 lCount = InterlockedIncrement( &pDirHdr->ContentIndex);
4044 pDirNode = AFSInitDirEntry( &AFSGlobalRoot->ObjectInformation,
4050 if( pDirNode == NULL)
4053 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4057 // Init the short name if we have one
4060 if( pDirEnumEntry->ShortNameLength > 0)
4063 pDirNode->NameInformation.ShortNameLength = pDirEnumEntry->ShortNameLength;
4065 RtlCopyMemory( pDirNode->NameInformation.ShortName,
4066 pDirEnumEntry->ShortName,
4067 pDirNode->NameInformation.ShortNameLength);
4070 AFSAcquireExcl( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
4074 // Insert the node into the name tree
4077 ASSERT( ExIsResourceAcquiredExclusiveLite( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock));
4079 if( pDirHdr->CaseSensitiveTreeHead == NULL)
4082 pDirHdr->CaseSensitiveTreeHead = pDirNode;
4087 if( !NT_SUCCESS( AFSInsertCaseSensitiveDirEntry( pDirHdr->CaseSensitiveTreeHead,
4091 AFSDeleteDirEntry( &AFSGlobalRoot->ObjectInformation,
4094 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
4096 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4100 ClearFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
4102 if( pDirHdr->CaseInsensitiveTreeHead == NULL)
4105 pDirHdr->CaseInsensitiveTreeHead = pDirNode;
4107 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
4112 AFSInsertCaseInsensitiveDirEntry( pDirHdr->CaseInsensitiveTreeHead,
4116 if( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListHead == NULL)
4119 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListHead = pDirNode;
4124 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListTail->ListEntry.fLink = pDirNode;
4126 pDirNode->ListEntry.bLink = AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListTail;
4129 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListTail = pDirNode;
4131 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST);
4133 lCount = InterlockedIncrement( &AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeCount);
4135 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
4136 AFS_TRACE_LEVEL_VERBOSE,
4137 "AFSCheckCellName Adding entry %wZ Inc Count %d to parent FID %08lX-%08lX-%08lX-%08lX\n",
4138 &pDirNode->NameInformation.FileName,
4140 AFSGlobalRoot->ObjectInformation.FileId.Cell,
4141 AFSGlobalRoot->ObjectInformation.FileId.Volume,
4142 AFSGlobalRoot->ObjectInformation.FileId.Vnode,
4143 AFSGlobalRoot->ObjectInformation.FileId.Unique);
4145 lCount = InterlockedIncrement( &pDirNode->DirOpenReferenceCount);
4147 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
4148 AFS_TRACE_LEVEL_VERBOSE,
4149 "AFSCheckCellName Increment2 count on %wZ DE %p Ccb %p Cnt %d\n",
4150 &pDirNode->NameInformation.FileName,
4155 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
4158 // Pass back the dir node
4161 *ShareDirEntry = pDirNode;
4166 if( pDirEnumEntry != NULL)
4169 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_31_TAG);
4177 AFSBuildMountPointTarget( IN GUID *AuthGroup,
4178 IN AFSDirectoryCB *DirectoryCB,
4179 OUT AFSVolumeCB **TargetVolumeCB)
4182 NTSTATUS ntStatus = STATUS_SUCCESS;
4183 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
4184 AFSDirEnumEntry *pDirEntry = NULL;
4185 ULONGLONG ullIndex = 0;
4186 AFSVolumeCB *pVolumeCB = NULL;
4187 AFSFileID stTargetFileID;
4189 BOOLEAN bReleaseVolumeLock = FALSE;
4195 // Loop on each entry, building the chain until we encounter the final target
4198 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4199 AFS_TRACE_LEVEL_VERBOSE_2,
4200 "AFSBuildMountPointTarget Building target directory for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4201 &DirectoryCB->NameInformation.FileName,
4202 DirectoryCB->ObjectInformation->FileId.Cell,
4203 DirectoryCB->ObjectInformation->FileId.Volume,
4204 DirectoryCB->ObjectInformation->FileId.Vnode,
4205 DirectoryCB->ObjectInformation->FileId.Unique);
4208 // Do we need to evaluate the node?
4211 //if( DirectoryCB->ObjectInformation->TargetFileId.Vnode == 0 &&
4212 // DirectoryCB->ObjectInformation->TargetFileId.Unique == 0)
4216 // Go evaluate the current target to get the target fid
4219 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4220 AFS_TRACE_LEVEL_VERBOSE_2,
4221 "AFSBuildMountPointTarget Evaluating target %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4222 &DirectoryCB->NameInformation.FileName,
4223 DirectoryCB->ObjectInformation->FileId.Cell,
4224 DirectoryCB->ObjectInformation->FileId.Volume,
4225 DirectoryCB->ObjectInformation->FileId.Vnode,
4226 DirectoryCB->ObjectInformation->FileId.Unique);
4228 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
4233 if( !NT_SUCCESS( ntStatus))
4236 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4237 AFS_TRACE_LEVEL_ERROR,
4238 "AFSBuildMountPointTarget Failed to evaluate target %wZ Status %08lX\n",
4239 &DirectoryCB->NameInformation.FileName,
4241 try_return( ntStatus);
4244 if( pDirEntry->TargetFileId.Vnode == 0 &&
4245 pDirEntry->TargetFileId.Unique == 0)
4248 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4249 AFS_TRACE_LEVEL_ERROR,
4250 "AFSBuildMountPointTarget Target %wZ FID %08lX-%08lX-%08lX-%08lX service returned zero FID\n",
4251 &DirectoryCB->NameInformation.FileName,
4252 DirectoryCB->ObjectInformation->FileId.Cell,
4253 DirectoryCB->ObjectInformation->FileId.Volume,
4254 DirectoryCB->ObjectInformation->FileId.Vnode,
4255 DirectoryCB->ObjectInformation->FileId.Unique);
4257 try_return( ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED);
4260 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
4263 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
4264 &DirectoryCB->Flags,
4265 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
4266 (USHORT)pDirEntry->TargetNameLength);
4268 if( !NT_SUCCESS( ntStatus))
4271 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
4273 try_return( ntStatus);
4276 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
4278 DirectoryCB->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
4281 stTargetFileID = DirectoryCB->ObjectInformation->TargetFileId;
4284 // Try to locate this FID. First the volume then the
4288 ullIndex = AFSCreateHighIndex( &stTargetFileID);
4290 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4291 AFS_TRACE_LEVEL_VERBOSE,
4292 "AFSBuildMountPointTarget Acquiring RDR VolumeTreeLock lock %p EXCL %08lX\n",
4293 &pDevExt->Specific.RDR.VolumeTreeLock,
4294 PsGetCurrentThread());
4296 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock,
4299 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4300 AFS_TRACE_LEVEL_VERBOSE_2,
4301 "AFSBuildMountPointTarget Locating volume for target %I64X\n",
4304 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
4306 (AFSBTreeEntry **)&pVolumeCB);
4309 // We can be processing a request for a target that is on a volume
4310 // we have never seen before.
4313 if( pVolumeCB == NULL)
4317 // Locking is held correctly in init routine
4320 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
4323 // Go init the root of the volume
4326 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4327 AFS_TRACE_LEVEL_VERBOSE_2,
4328 "AFSBuildMountPointTarget Initializing root for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4329 &DirectoryCB->NameInformation.FileName,
4330 DirectoryCB->ObjectInformation->FileId.Cell,
4331 DirectoryCB->ObjectInformation->FileId.Volume,
4332 DirectoryCB->ObjectInformation->FileId.Vnode,
4333 DirectoryCB->ObjectInformation->FileId.Unique);
4335 ntStatus = AFSInitVolume( AuthGroup,
4337 AFS_VOLUME_REFERENCE_MOUNTPT,
4340 if( !NT_SUCCESS( ntStatus))
4343 try_return( ntStatus);
4347 // pVolumeCB->VolumeLock held exclusive and
4348 // pVolumeCB->VolumeReferenceCount has been incremented
4349 // pVolumeCB->RootFcb == NULL
4352 bReleaseVolumeLock = TRUE;
4358 // AFSInitVolume returns with a VolumeReferenceCount
4359 // obtain one to match
4362 lCount = AFSVolumeIncrement( pVolumeCB,
4363 AFS_VOLUME_REFERENCE_MOUNTPT);
4365 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
4366 AFS_TRACE_LEVEL_VERBOSE,
4367 "AFSBuildMountPointTarget Increment count on volume %p Cnt %d\n",
4371 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
4374 if( pVolumeCB->RootFcb == NULL)
4377 if ( bReleaseVolumeLock == FALSE)
4380 AFSAcquireExcl( pVolumeCB->VolumeLock,
4383 bReleaseVolumeLock = TRUE;
4387 // Initialize the root fcb for this volume
4390 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
4393 if( !NT_SUCCESS( ntStatus))
4396 lCount = AFSVolumeDecrement( pVolumeCB,
4397 AFS_VOLUME_REFERENCE_MOUNTPT);
4399 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
4400 AFS_TRACE_LEVEL_VERBOSE,
4401 "AFSBuildMountPoint Decrement count on volume %p Cnt %d\n",
4405 AFSReleaseResource( pVolumeCB->VolumeLock);
4407 try_return( ntStatus);
4411 // Drop the lock acquired above
4414 AFSReleaseResource( &pVolumeCB->RootFcb->NPFcb->Resource);
4417 if ( bReleaseVolumeLock == TRUE)
4420 AFSReleaseResource( pVolumeCB->VolumeLock);
4423 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4424 AFS_TRACE_LEVEL_VERBOSE_2,
4425 "AFSBuildMountPointTarget Evaluated target of %wZ FID %08lX-%08lX-%08lX-%08lX as root volume\n",
4426 &pVolumeCB->DirectoryCB->NameInformation.FileName,
4427 pVolumeCB->ObjectInformation.FileId.Cell,
4428 pVolumeCB->ObjectInformation.FileId.Volume,
4429 pVolumeCB->ObjectInformation.FileId.Vnode,
4430 pVolumeCB->ObjectInformation.FileId.Unique);
4432 *TargetVolumeCB = pVolumeCB;
4439 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
4447 AFSBuildRootVolume( IN GUID *AuthGroup,
4448 IN AFSFileID *FileId,
4449 OUT AFSVolumeCB **TargetVolumeCB)
4452 NTSTATUS ntStatus = STATUS_SUCCESS;
4453 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
4454 ULONGLONG ullIndex = 0;
4455 AFSVolumeCB *pVolumeCB = NULL;
4457 BOOLEAN bReleaseVolumeLock = FALSE;
4462 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4463 AFS_TRACE_LEVEL_VERBOSE_2,
4464 "AFSBuildRootVolume Building target volume for FID %08lX-%08lX-%08lX-%08lX\n",
4470 ullIndex = AFSCreateHighIndex( FileId);
4472 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4473 AFS_TRACE_LEVEL_VERBOSE,
4474 "AFSBuildRootVolume Acquiring RDR VolumeTreeLock lock %p EXCL %08lX\n",
4475 &pDevExt->Specific.RDR.VolumeTreeLock,
4476 PsGetCurrentThread());
4478 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock,
4481 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4482 AFS_TRACE_LEVEL_VERBOSE_2,
4483 "AFSBuildRootVolume Locating volume for target %I64X\n",
4486 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
4488 (AFSBTreeEntry **)&pVolumeCB);
4491 // We can be processing a request for a target that is on a volume
4492 // we have never seen before.
4495 if( pVolumeCB == NULL)
4499 // Locking is held correctly in init routine
4502 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
4505 // Go init the root of the volume
4508 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4509 AFS_TRACE_LEVEL_VERBOSE_2,
4510 "AFSBuildRootVolume Initializing root for FID %08lX-%08lX-%08lX-%08lX\n",
4516 ntStatus = AFSInitVolume( AuthGroup,
4518 AFS_VOLUME_REFERENCE_BUILD_ROOT,
4521 if( !NT_SUCCESS( ntStatus))
4524 try_return( ntStatus);
4528 // pVolumeCB->VolumeLock is held exclusive
4529 // pVolumeCB->VolumeReferenceCount has been incremented
4530 // pVolumeCB->RootFcb == NULL
4533 bReleaseVolumeLock = TRUE;
4539 // AFSInitVolume returns with a VolumeReferenceCount
4540 // obtain one to match
4543 lCount = AFSVolumeIncrement( pVolumeCB,
4544 AFS_VOLUME_REFERENCE_BUILD_ROOT);
4546 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
4547 AFS_TRACE_LEVEL_VERBOSE,
4548 "AFSBuildRootVolume Increment count on volume %p Cnt %d\n",
4552 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
4556 if( pVolumeCB->RootFcb == NULL)
4559 if ( bReleaseVolumeLock == FALSE)
4562 AFSAcquireExcl( pVolumeCB->VolumeLock,
4565 bReleaseVolumeLock = TRUE;
4569 // Initialize the root fcb for this volume
4572 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
4575 if( !NT_SUCCESS( ntStatus))
4578 lCount = AFSVolumeDecrement( pVolumeCB,
4579 AFS_VOLUME_REFERENCE_BUILD_ROOT);
4581 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
4582 AFS_TRACE_LEVEL_VERBOSE,
4583 "AFSBuildRootVolume Decrement count on volume %p Cnt %d\n",
4587 AFSReleaseResource( pVolumeCB->VolumeLock);
4589 try_return( ntStatus);
4593 // Drop the lock acquired above
4596 AFSReleaseResource( &pVolumeCB->RootFcb->NPFcb->Resource);
4599 if ( bReleaseVolumeLock == TRUE)
4602 AFSReleaseResource( pVolumeCB->VolumeLock);
4605 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4606 AFS_TRACE_LEVEL_VERBOSE_2,
4607 "AFSBuildRootVolume Evaluated target of %wZ FID %08lX-%08lX-%08lX-%08lX as root volume\n",
4608 &pVolumeCB->DirectoryCB->NameInformation.FileName,
4609 pVolumeCB->ObjectInformation.FileId.Cell,
4610 pVolumeCB->ObjectInformation.FileId.Volume,
4611 pVolumeCB->ObjectInformation.FileId.Vnode,
4612 pVolumeCB->ObjectInformation.FileId.Unique);
4614 *TargetVolumeCB = pVolumeCB;
4625 AFSProcessDFSLink( IN AFSDirectoryCB *DirEntry,
4626 IN PFILE_OBJECT FileObject,
4627 IN UNICODE_STRING *RemainingPath,
4631 NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
4632 UNICODE_STRING uniReparseName;
4633 UNICODE_STRING uniMUPDeviceName;
4634 UNICODE_STRING uniIOMgrDeviceName;
4635 AFSDirEnumEntry *pDirEntry = NULL;
4641 // Build up the name to reparse
4644 RtlInitUnicodeString( &uniMUPDeviceName,
4647 RtlInitUnicodeString( &uniIOMgrDeviceName,
4650 uniReparseName.Length = 0;
4651 uniReparseName.Buffer = NULL;
4654 // Be sure we have a target name
4657 if( DirEntry->NameInformation.TargetName.Length == 0)
4660 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
4665 if( !NT_SUCCESS( ntStatus) ||
4666 pDirEntry->TargetNameLength == 0)
4669 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4670 AFS_TRACE_LEVEL_ERROR,
4671 "AFSProcessDFSLink EvaluateTargetByID failed for Fcb %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4672 &DirEntry->NameInformation.FileName,
4673 DirEntry->ObjectInformation->FileId.Cell,
4674 DirEntry->ObjectInformation->FileId.Volume,
4675 DirEntry->ObjectInformation->FileId.Vnode,
4676 DirEntry->ObjectInformation->FileId.Unique,
4679 if( NT_SUCCESS( ntStatus))
4682 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
4685 try_return( ntStatus);
4689 // Update the target name
4692 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
4695 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
4697 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
4698 (USHORT)pDirEntry->TargetNameLength);
4700 if( !NT_SUCCESS( ntStatus))
4703 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4704 AFS_TRACE_LEVEL_ERROR,
4705 "AFSProcessDFSLink UpdateTargetName failed for Fcb %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4706 &DirEntry->NameInformation.FileName,
4707 DirEntry->ObjectInformation->FileId.Cell,
4708 DirEntry->ObjectInformation->FileId.Volume,
4709 DirEntry->ObjectInformation->FileId.Vnode,
4710 DirEntry->ObjectInformation->FileId.Unique,
4713 AFSReleaseResource( &DirEntry->NonPaged->Lock);
4715 try_return( ntStatus);
4718 AFSConvertToShared( &DirEntry->NonPaged->Lock);
4722 AFSAcquireShared( &DirEntry->NonPaged->Lock,
4726 uniReparseName.MaximumLength = uniMUPDeviceName.Length +
4728 DirEntry->NameInformation.TargetName.Length +
4731 if( RemainingPath != NULL &&
4732 RemainingPath->Length > 0)
4735 uniReparseName.MaximumLength += RemainingPath->Length;
4739 // Allocate the reparse buffer
4742 uniReparseName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
4743 uniReparseName.MaximumLength,
4744 AFS_REPARSE_NAME_TAG);
4746 if( uniReparseName.Buffer == NULL)
4749 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4750 AFS_TRACE_LEVEL_ERROR,
4751 "AFSProcessDFSLink uniReparseName.Buffer == NULL Fcb %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4752 &DirEntry->NameInformation.FileName,
4753 DirEntry->ObjectInformation->FileId.Cell,
4754 DirEntry->ObjectInformation->FileId.Volume,
4755 DirEntry->ObjectInformation->FileId.Vnode,
4756 DirEntry->ObjectInformation->FileId.Unique,
4757 STATUS_INSUFFICIENT_RESOURCES);
4759 AFSReleaseResource( &DirEntry->NonPaged->Lock);
4761 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4765 // Start building the name
4768 if ( DirEntry->NameInformation.TargetName.Buffer[ 0] != L'\\' &&
4769 DirEntry->NameInformation.TargetName.Buffer[ 1] == L':')
4772 RtlCopyMemory( uniReparseName.Buffer,
4773 uniIOMgrDeviceName.Buffer,
4774 uniIOMgrDeviceName.Length);
4776 uniReparseName.Length = uniIOMgrDeviceName.Length;
4781 RtlCopyMemory( uniReparseName.Buffer,
4782 uniMUPDeviceName.Buffer,
4783 uniMUPDeviceName.Length);
4785 uniReparseName.Length = uniMUPDeviceName.Length;
4787 if( DirEntry->NameInformation.TargetName.Buffer[ 0] != L'\\')
4790 uniReparseName.Buffer[ uniReparseName.Length/sizeof( WCHAR)] = L'\\';
4792 uniReparseName.Length += sizeof( WCHAR);
4796 RtlCopyMemory( &uniReparseName.Buffer[ uniReparseName.Length/sizeof( WCHAR)],
4797 DirEntry->NameInformation.TargetName.Buffer,
4798 DirEntry->NameInformation.TargetName.Length);
4800 uniReparseName.Length += DirEntry->NameInformation.TargetName.Length;
4802 AFSReleaseResource( &DirEntry->NonPaged->Lock);
4804 if( RemainingPath != NULL &&
4805 RemainingPath->Length > 0)
4808 if( uniReparseName.Buffer[ (uniReparseName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
4809 RemainingPath->Buffer[ 0] != L'\\')
4812 uniReparseName.Buffer[ uniReparseName.Length/sizeof( WCHAR)] = L'\\';
4814 uniReparseName.Length += sizeof( WCHAR);
4817 RtlCopyMemory( &uniReparseName.Buffer[ uniReparseName.Length/sizeof( WCHAR)],
4818 RemainingPath->Buffer,
4819 RemainingPath->Length);
4821 uniReparseName.Length += RemainingPath->Length;
4825 // Update the name in the file object
4828 if( FileObject->FileName.Buffer != NULL)
4831 AFSExFreePoolWithTag( FileObject->FileName.Buffer, 0);
4834 FileObject->FileName = uniReparseName;
4836 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4837 AFS_TRACE_LEVEL_VERBOSE,
4838 "AFSProcessDFSLink Reparsing access to Fcb %wZ FID %08lX-%08lX-%08lX-%08lX to %wZ\n",
4839 &DirEntry->NameInformation.FileName,
4840 DirEntry->ObjectInformation->FileId.Cell,
4841 DirEntry->ObjectInformation->FileId.Volume,
4842 DirEntry->ObjectInformation->FileId.Vnode,
4843 DirEntry->ObjectInformation->FileId.Unique,
4847 // Return status reparse ...
4850 ntStatus = STATUS_REPARSE;
4857 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);