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: AFSCommSupport.cpp
39 #include "AFSCommon.h"
42 AFSEnumerateDirectory( IN GUID *AuthGroup,
43 IN AFSObjectInfoCB *ObjectInfoCB,
47 NTSTATUS ntStatus = STATUS_SUCCESS;
49 ULONG ulResultLen = 0;
50 AFSDirQueryCB *pDirQueryCB;
51 AFSDirEnumEntry *pCurrentDirEntry = NULL;
52 AFSDirectoryCB *pDirNode = NULL;
53 ULONG ulEntryLength = 0;
54 AFSDirEnumResp *pDirEnumResponse = NULL;
55 UNICODE_STRING uniDirName, uniTargetName;
56 ULONG ulRequestFlags = AFS_REQUEST_FLAG_SYNCHRONOUS;
58 UNICODE_STRING uniGUID;
63 ASSERT( ExIsResourceAcquiredExclusiveLite( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock));
66 uniGUID.MaximumLength = 0;
67 uniGUID.Buffer = NULL;
69 if( AuthGroup != NULL)
71 RtlStringFromGUID( *AuthGroup,
75 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
76 AFS_TRACE_LEVEL_VERBOSE,
77 "AFSEnumerateDirectory Enumerating FID %08lX-%08lX-%08lX-%08lX AuthGroup %wZ\n",
78 ObjectInfoCB->FileId.Cell,
79 ObjectInfoCB->FileId.Volume,
80 ObjectInfoCB->FileId.Vnode,
81 ObjectInfoCB->FileId.Unique,
84 if( AuthGroup != NULL)
86 RtlFreeUnicodeString( &uniGUID);
90 // Initialize the directory enumeration buffer for the directory
93 pBuffer = AFSExAllocatePoolWithTag( PagedPool,
94 AFS_DIR_ENUM_BUFFER_LEN,
100 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
103 RtlZeroMemory( pBuffer,
104 AFS_DIR_ENUM_BUFFER_LEN);
106 ulResultLen = AFS_DIR_ENUM_BUFFER_LEN;
109 // Use the payload buffer for information we will pass to the service
112 pDirQueryCB = (AFSDirQueryCB *)pBuffer;
114 pDirQueryCB->EnumHandle = 0;
119 ulRequestFlags |= AFS_REQUEST_FLAG_FAST_REQUEST;
123 // Loop on the information
130 // If the enumeration handle is -1 then we are done
133 if( ((ULONG)-1) == pDirQueryCB->EnumHandle )
136 ntStatus = STATUS_NO_MORE_ENTRIES;
142 // Go and retrieve the directory contents
145 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_DIR_ENUM,
149 &ObjectInfoCB->FileId,
151 sizeof( AFSDirQueryCB),
156 if( ntStatus != STATUS_SUCCESS ||
160 if( ntStatus == STATUS_NO_MORE_FILES ||
161 ntStatus == STATUS_NO_MORE_ENTRIES)
164 ntStatus = STATUS_SUCCESS;
166 pDirEnumResponse = (AFSDirEnumResp *)pBuffer;
168 AFSAcquireExcl( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock,
171 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
172 AFS_TRACE_LEVEL_VERBOSE,
173 "AFSEnumerateDirectory Directory Complete FID %08lX-%08lX-%08lX-%08lX Snapshot-DV %08lX:%08lX Current-DV %08lX:%08lX Status %08lX\n",
174 ObjectInfoCB->FileId.Cell,
175 ObjectInfoCB->FileId.Volume,
176 ObjectInfoCB->FileId.Vnode,
177 ObjectInfoCB->FileId.Unique,
178 pDirEnumResponse->SnapshotDataVersion.HighPart,
179 pDirEnumResponse->SnapshotDataVersion.LowPart,
180 pDirEnumResponse->CurrentDataVersion.HighPart,
181 pDirEnumResponse->CurrentDataVersion.LowPart,
184 ObjectInfoCB->DataVersion = pDirEnumResponse->SnapshotDataVersion;
186 if ( pDirEnumResponse->SnapshotDataVersion.QuadPart != pDirEnumResponse->CurrentDataVersion.QuadPart )
189 SetFlag( ObjectInfoCB->Flags, AFS_OBJECT_FLAGS_VERIFY);
191 ObjectInfoCB->DataVersion.QuadPart = (ULONGLONG)-1;
193 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
194 AFS_TRACE_LEVEL_VERBOSE,
195 "AFSEnumerateDirectory Force Verify due to DV change during enumeration FID %08lX-%08lX-%08lX-%08lX\n",
196 ObjectInfoCB->FileId.Cell,
197 ObjectInfoCB->FileId.Volume,
198 ObjectInfoCB->FileId.Vnode,
199 ObjectInfoCB->FileId.Unique);
202 AFSReleaseResource( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock);
207 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
208 AFS_TRACE_LEVEL_VERBOSE,
209 "AFSEnumerateDirectory Failed to enumerate directory FID %08lX-%08lX-%08lX-%08lX AuthGroup %wZ Status %08lX\n",
210 ObjectInfoCB->FileId.Cell,
211 ObjectInfoCB->FileId.Volume,
212 ObjectInfoCB->FileId.Vnode,
213 ObjectInfoCB->FileId.Unique,
221 pDirEnumResponse = (AFSDirEnumResp *)pBuffer;
223 pCurrentDirEntry = (AFSDirEnumEntry *)pDirEnumResponse->Entry;
225 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
226 AFS_TRACE_LEVEL_VERBOSE,
227 "AFSEnumerateDirectory Enumerating FID %08lX-%08lX-%08lX-%08lX Snapshot-DV %08lX:%08lX Current-DV %08lX:%08lX\n",
228 ObjectInfoCB->FileId.Cell,
229 ObjectInfoCB->FileId.Volume,
230 ObjectInfoCB->FileId.Vnode,
231 ObjectInfoCB->FileId.Unique,
232 pDirEnumResponse->SnapshotDataVersion.HighPart,
233 pDirEnumResponse->SnapshotDataVersion.LowPart,
234 pDirEnumResponse->CurrentDataVersion.HighPart,
235 pDirEnumResponse->CurrentDataVersion.LowPart);
238 // Remove the leading header from the processed length
241 ulResultLen -= FIELD_OFFSET( AFSDirEnumResp, Entry);
243 while( ulResultLen > 0)
246 uniDirName.Length = (USHORT)pCurrentDirEntry->FileNameLength;
248 uniDirName.MaximumLength = uniDirName.Length;
250 uniDirName.Buffer = (WCHAR *)((char *)pCurrentDirEntry + pCurrentDirEntry->FileNameOffset);
252 uniTargetName.Length = (USHORT)pCurrentDirEntry->TargetNameLength;
254 uniTargetName.MaximumLength = uniTargetName.Length;
256 uniTargetName.Buffer = (WCHAR *)((char *)pCurrentDirEntry + pCurrentDirEntry->TargetNameOffset);
259 // Be sure we don't have this entry in the case sensitive tree
262 ulCRC = AFSGenerateCRC( &uniDirName,
265 AFSLocateCaseSensitiveDirEntry( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
269 if( pDirNode != NULL)
273 // Check that the FIDs are the same
276 if( AFSIsEqualFID( &pCurrentDirEntry->FileId,
277 &pDirNode->ObjectInformation->FileId))
281 // Duplicate entry, skip it
284 ulEntryLength = QuadAlign( sizeof( AFSDirEnumEntry) +
286 uniTargetName.Length);
288 pCurrentDirEntry = (AFSDirEnumEntry *)((char *)pCurrentDirEntry + ulEntryLength);
290 if( ulResultLen >= ulEntryLength)
292 ulResultLen -= ulEntryLength;
300 // Update the metadata for the entry
303 if( pDirNode->ObjectInformation->DataVersion.QuadPart != pCurrentDirEntry->DataVersion.QuadPart)
307 AFSObjectInfoCB *pObjectInfo = pDirNode->ObjectInformation;
309 lCount = InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
311 AFSInvalidateObject( &pObjectInfo,
312 AFS_INVALIDATE_DATA_VERSION);
314 if( pObjectInfo != NULL)
317 lCount = InterlockedDecrement( &pObjectInfo->ObjectReferenceCount);
323 AFSUpdateMetaData( pDirNode,
333 // Need to tear down this entry and rebuild it below
336 if( pDirNode->OpenReferenceCount == 0)
339 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
340 AFS_TRACE_LEVEL_VERBOSE,
341 "AFSEnumerateDirectory Different FIDs - Deleting DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
343 &pDirNode->NameInformation.FileName,
344 pDirNode->ObjectInformation->FileId.Cell,
345 pDirNode->ObjectInformation->FileId.Volume,
346 pDirNode->ObjectInformation->FileId.Vnode,
347 pDirNode->ObjectInformation->FileId.Unique,
348 pCurrentDirEntry->FileId.Cell,
349 pCurrentDirEntry->FileId.Volume,
350 pCurrentDirEntry->FileId.Vnode,
351 pCurrentDirEntry->FileId.Unique);
353 AFSDeleteDirEntry( ObjectInfoCB,
359 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_DELETED);
361 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
362 AFS_TRACE_LEVEL_VERBOSE,
363 "AFSEnumerateDirectory Different FIDs - Removing DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
365 &pDirNode->NameInformation.FileName,
366 pDirNode->ObjectInformation->FileId.Cell,
367 pDirNode->ObjectInformation->FileId.Volume,
368 pDirNode->ObjectInformation->FileId.Vnode,
369 pDirNode->ObjectInformation->FileId.Unique,
370 pCurrentDirEntry->FileId.Cell,
371 pCurrentDirEntry->FileId.Volume,
372 pCurrentDirEntry->FileId.Vnode,
373 pCurrentDirEntry->FileId.Unique);
375 AFSRemoveNameEntry( ObjectInfoCB,
383 pDirNode = AFSInitDirEntry( ObjectInfoCB,
387 (ULONG)InterlockedIncrement( &ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.ContentIndex));
389 if( pDirNode == NULL)
392 ntStatus = STATUS_INSUFFICIENT_RESOURCES;
397 AFSUpdateMetaData( pDirNode,
400 if( pDirNode->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY)
403 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
404 AFS_TRACE_LEVEL_VERBOSE,
405 "AFSEnumerateDirectory Setting VERIFY on entry %wZ for FID %08lX-%08lX-%08lX-%08lX\n",
407 pDirNode->ObjectInformation->FileId.Cell,
408 pDirNode->ObjectInformation->FileId.Volume,
409 pDirNode->ObjectInformation->FileId.Vnode,
410 pDirNode->ObjectInformation->FileId.Unique);
412 AFSAcquireExcl( pDirNode->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
415 SetFlag( pDirNode->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
417 pDirNode->ObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
419 AFSReleaseResource( pDirNode->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
423 // Set up the entry length
426 ulEntryLength = QuadAlign( sizeof( AFSDirEnumEntry) +
427 pCurrentDirEntry->FileNameLength +
428 pCurrentDirEntry->TargetNameLength);
431 // Init the short name if we have one
434 if( pCurrentDirEntry->ShortNameLength > 0)
437 UNICODE_STRING uniShortName;
439 pDirNode->NameInformation.ShortNameLength = pCurrentDirEntry->ShortNameLength;
441 RtlCopyMemory( pDirNode->NameInformation.ShortName,
442 pCurrentDirEntry->ShortName,
443 pDirNode->NameInformation.ShortNameLength);
446 // Generate the short name index
449 uniShortName.Length = pDirNode->NameInformation.ShortNameLength;
450 uniShortName.MaximumLength = uniShortName.Length;
451 uniShortName.Buffer = pDirNode->NameInformation.ShortName;
453 if( !RtlIsNameLegalDOS8Dot3( &pDirNode->NameInformation.FileName,
458 pDirNode->Type.Data.ShortNameTreeEntry.HashIndex = AFSGenerateCRC( &uniShortName,
461 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
462 AFS_TRACE_LEVEL_VERBOSE,
463 "AFSEnumerateDirectory Initialized short name %wZ for DE %p for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
466 &pDirNode->NameInformation.FileName,
467 pCurrentDirEntry->FileId.Cell,
468 pCurrentDirEntry->FileId.Volume,
469 pCurrentDirEntry->FileId.Vnode,
470 pCurrentDirEntry->FileId.Unique);
474 pDirNode->NameInformation.ShortNameLength = 0;
476 RtlZeroMemory( pDirNode->NameInformation.ShortName,
477 (12 * sizeof( WCHAR)));
482 // Insert the node into the name tree
485 if( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead == NULL)
488 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = pDirNode;
490 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
491 AFS_TRACE_LEVEL_VERBOSE,
492 "AFSEnumerateDirectory Insert DE %p to head of case sensitive tree for %wZ\n",
494 &pDirNode->NameInformation.FileName);
499 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
500 AFS_TRACE_LEVEL_VERBOSE,
501 "AFSEnumerateDirectory Insert DE %p to case sensitive tree for %wZ\n",
503 &pDirNode->NameInformation.FileName);
505 if( !NT_SUCCESS( AFSInsertCaseSensitiveDirEntry( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
510 // Delete this dir entry and continue on
513 AFSDeleteDirEntry( ObjectInfoCB,
516 pCurrentDirEntry = (AFSDirEnumEntry *)((char *)pCurrentDirEntry + ulEntryLength);
518 if( ulResultLen >= ulEntryLength)
520 ulResultLen -= ulEntryLength;
531 ClearFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
533 if( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead == NULL)
536 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
537 AFS_TRACE_LEVEL_VERBOSE,
538 "AFSEnumerateDirectory Insert DE %p to head of case insensitive tree for %wZ\n",
540 &pDirNode->NameInformation.FileName);
542 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = pDirNode;
544 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
549 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
550 AFS_TRACE_LEVEL_VERBOSE,
551 "AFSEnumerateDirectory Insert DE %p to case insensitive tree for %wZ\n",
553 &pDirNode->NameInformation.FileName);
555 AFSInsertCaseInsensitiveDirEntry( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
559 if( ObjectInfoCB->Specific.Directory.DirectoryNodeListHead == NULL)
562 ObjectInfoCB->Specific.Directory.DirectoryNodeListHead = pDirNode;
567 ObjectInfoCB->Specific.Directory.DirectoryNodeListTail->ListEntry.fLink = pDirNode;
569 pDirNode->ListEntry.bLink = ObjectInfoCB->Specific.Directory.DirectoryNodeListTail;
572 ObjectInfoCB->Specific.Directory.DirectoryNodeListTail = pDirNode;
574 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST);
576 InterlockedIncrement( &ObjectInfoCB->Specific.Directory.DirectoryNodeCount);
578 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
579 AFS_TRACE_LEVEL_VERBOSE,
580 "AFSEnumerateDirectory Adding entry %wZ Inc Count %d to parent FID %08lX-%08lX-%08lX-%08lX\n",
581 &pDirNode->NameInformation.FileName,
582 ObjectInfoCB->Specific.Directory.DirectoryNodeCount,
583 ObjectInfoCB->FileId.Cell,
584 ObjectInfoCB->FileId.Volume,
585 ObjectInfoCB->FileId.Vnode,
586 ObjectInfoCB->FileId.Unique);
588 if( pDirNode->Type.Data.ShortNameTreeEntry.HashIndex != 0)
592 // Insert the short name entry if we have a valid short name
595 if( ObjectInfoCB->Specific.Directory.ShortNameTree == NULL)
598 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
599 AFS_TRACE_LEVEL_VERBOSE,
600 "AFSEnumerateDirectory Insert DE %p to head of shortname tree for %wZ\n",
602 &pDirNode->NameInformation.FileName);
604 ObjectInfoCB->Specific.Directory.ShortNameTree = pDirNode;
606 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
611 if( NT_SUCCESS( AFSInsertShortNameDirEntry( ObjectInfoCB->Specific.Directory.ShortNameTree,
614 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
616 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
617 AFS_TRACE_LEVEL_VERBOSE,
618 "AFSEnumerateDirectory Insert DE %p to shortname tree for %wZ\n",
620 &pDirNode->NameInformation.FileName);
629 pCurrentDirEntry = (AFSDirEnumEntry *)((char *)pCurrentDirEntry + ulEntryLength);
631 if( ulResultLen >= ulEntryLength)
633 ulResultLen -= ulEntryLength;
641 ulResultLen = AFS_DIR_ENUM_BUFFER_LEN;
644 // Reset the information in the request buffer since it got trampled
648 pDirQueryCB->EnumHandle = pDirEnumResponse->EnumHandle;
650 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
651 AFS_TRACE_LEVEL_VERBOSE,
652 "AFSEnumerateDirectory EnumHandle %08lX\n",
653 pDirQueryCB->EnumHandle);
665 AFSExFreePool( pBuffer);
669 // If the processing failed then we should reset the directory content in the event
670 // it is re-enumerated
673 if( !NT_SUCCESS( ntStatus))
676 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
677 AFS_TRACE_LEVEL_ERROR,
678 "AFSEnumerateDirectory Resetting content for FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
679 ObjectInfoCB->FileId.Cell,
680 ObjectInfoCB->FileId.Volume,
681 ObjectInfoCB->FileId.Vnode,
682 ObjectInfoCB->FileId.Unique,
685 AFSResetDirectoryContent( ObjectInfoCB);
693 AFSEnumerateDirectoryNoResponse( IN GUID *AuthGroup,
694 IN AFSFileID *FileId)
697 NTSTATUS ntStatus = STATUS_SUCCESS;
698 AFSDirQueryCB stDirQueryCB;
699 ULONG ulRequestFlags = 0;
705 // Use the payload buffer for information we will pass to the service
708 stDirQueryCB.EnumHandle = 0;
710 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_DIR_ENUM,
715 (void *)&stDirQueryCB,
716 sizeof( AFSDirQueryCB),
720 if( ntStatus != STATUS_SUCCESS)
723 if( ntStatus == STATUS_NO_MORE_FILES ||
724 ntStatus == STATUS_NO_MORE_ENTRIES)
727 ntStatus = STATUS_SUCCESS;
732 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
733 AFS_TRACE_LEVEL_ERROR,
734 "AFSEnumerateDirectoryNoResponse Failed to enumerate directory Status %08lX\n",
744 AFSVerifyDirectoryContent( IN AFSObjectInfoCB *ObjectInfoCB,
748 NTSTATUS ntStatus = STATUS_SUCCESS;
749 void *pBuffer = NULL;
750 ULONG ulResultLen = 0;
751 AFSDirQueryCB *pDirQueryCB;
752 AFSDirEnumEntry *pCurrentDirEntry = NULL;
753 AFSDirectoryCB *pDirNode = NULL;
754 ULONG ulEntryLength = 0;
755 AFSDirEnumResp *pDirEnumResponse = NULL;
756 UNICODE_STRING uniDirName, uniTargetName;
757 ULONG ulRequestFlags = AFS_REQUEST_FLAG_SYNCHRONOUS | AFS_REQUEST_FLAG_FAST_REQUEST;
759 AFSObjectInfoCB *pObjectInfo = NULL;
760 ULONGLONG ullIndex = 0;
761 UNICODE_STRING uniGUID;
767 ASSERT( ExIsResourceAcquiredExclusiveLite( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock));
770 uniGUID.MaximumLength = 0;
771 uniGUID.Buffer = NULL;
773 if( AuthGroup != NULL)
775 RtlStringFromGUID( *AuthGroup,
779 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
780 AFS_TRACE_LEVEL_VERBOSE,
781 "AFSVerifyDirectoryContent Verifying content for FID %08lX-%08lX-%08lX-%08lX AuthGroup %wZ\n",
782 ObjectInfoCB->FileId.Cell,
783 ObjectInfoCB->FileId.Volume,
784 ObjectInfoCB->FileId.Vnode,
785 ObjectInfoCB->FileId.Unique,
788 if( AuthGroup != NULL)
790 RtlFreeUnicodeString( &uniGUID);
794 // Initialize the directory enumeration buffer for the directory
797 pBuffer = AFSExAllocatePoolWithTag( PagedPool,
798 AFS_DIR_ENUM_BUFFER_LEN,
804 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
807 RtlZeroMemory( pBuffer,
808 AFS_DIR_ENUM_BUFFER_LEN);
810 ulResultLen = AFS_DIR_ENUM_BUFFER_LEN;
813 // Use the payload buffer for information we will pass to the service
816 pDirQueryCB = (AFSDirQueryCB *)pBuffer;
818 pDirQueryCB->EnumHandle = 0;
821 // Loop on the information
828 // If the enumeration handle is -1 then we are done
831 if( ((ULONG)-1) == pDirQueryCB->EnumHandle )
834 ntStatus = STATUS_NO_MORE_ENTRIES;
840 // Go and retrieve the directory contents
843 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_DIR_ENUM,
847 &ObjectInfoCB->FileId,
849 sizeof( AFSDirQueryCB),
854 if( ntStatus != STATUS_SUCCESS ||
858 if( ntStatus == STATUS_NO_MORE_FILES ||
859 ntStatus == STATUS_NO_MORE_ENTRIES)
862 pDirEnumResponse = (AFSDirEnumResp *)pBuffer;
864 AFSAcquireExcl( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock,
867 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
868 AFS_TRACE_LEVEL_VERBOSE,
869 "AFSVerifyDirectoryContent Directory Complete FID %08lX-%08lX-%08lX-%08lX Snapshot-DV %08lX:%08lX Current-DV %08lX:%08lX Status %08lX\n",
870 ObjectInfoCB->FileId.Cell,
871 ObjectInfoCB->FileId.Volume,
872 ObjectInfoCB->FileId.Vnode,
873 ObjectInfoCB->FileId.Unique,
874 pDirEnumResponse->SnapshotDataVersion.HighPart,
875 pDirEnumResponse->SnapshotDataVersion.LowPart,
876 pDirEnumResponse->CurrentDataVersion.HighPart,
877 pDirEnumResponse->CurrentDataVersion.LowPart,
880 ntStatus = STATUS_SUCCESS;
882 if ( pDirEnumResponse->SnapshotDataVersion.QuadPart != pDirEnumResponse->CurrentDataVersion.QuadPart )
885 SetFlag( ObjectInfoCB->Flags, AFS_OBJECT_FLAGS_VERIFY);
887 ObjectInfoCB->DataVersion.QuadPart = (ULONGLONG)-1;
889 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
890 AFS_TRACE_LEVEL_VERBOSE,
891 "AFSVerifyDirectoryContent Force Verify due to DV change during enumeration FID %08lX-%08lX-%08lX-%08lX\n",
892 ObjectInfoCB->FileId.Cell,
893 ObjectInfoCB->FileId.Volume,
894 ObjectInfoCB->FileId.Vnode,
895 ObjectInfoCB->FileId.Unique);
900 ObjectInfoCB->DataVersion = pDirEnumResponse->SnapshotDataVersion;
903 AFSReleaseResource( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock);
908 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
909 AFS_TRACE_LEVEL_ERROR,
910 "AFSVerifyDirectoryContent Failed to enumerate directory FID %08lX-%08lX-%08lX-%08lX AuthGroup %wZ Status %08lX\n",
911 ObjectInfoCB->FileId.Cell,
912 ObjectInfoCB->FileId.Volume,
913 ObjectInfoCB->FileId.Vnode,
914 ObjectInfoCB->FileId.Unique,
922 pDirEnumResponse = (AFSDirEnumResp *)pBuffer;
924 pCurrentDirEntry = (AFSDirEnumEntry *)pDirEnumResponse->Entry;
926 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
927 AFS_TRACE_LEVEL_VERBOSE,
928 "AFSVerifyDirectoryContent EnumResponse FID %08lX-%08lX-%08lX-%08lX Snapshot-DV %08lX:%08lX Current-DV %08lX:%08lX\n",
929 ObjectInfoCB->FileId.Cell,
930 ObjectInfoCB->FileId.Volume,
931 ObjectInfoCB->FileId.Vnode,
932 ObjectInfoCB->FileId.Unique,
933 pDirEnumResponse->SnapshotDataVersion.HighPart,
934 pDirEnumResponse->SnapshotDataVersion.LowPart,
935 pDirEnumResponse->CurrentDataVersion.HighPart,
936 pDirEnumResponse->CurrentDataVersion.LowPart);
939 // Remove the leading header from the processed length
942 ulResultLen -= FIELD_OFFSET( AFSDirEnumResp, Entry);
944 while( ulResultLen > 0)
947 uniDirName.Length = (USHORT)pCurrentDirEntry->FileNameLength;
949 uniDirName.MaximumLength = uniDirName.Length;
951 uniDirName.Buffer = (WCHAR *)((char *)pCurrentDirEntry + pCurrentDirEntry->FileNameOffset);
953 uniTargetName.Length = (USHORT)pCurrentDirEntry->TargetNameLength;
955 uniTargetName.MaximumLength = uniTargetName.Length;
957 uniTargetName.Buffer = (WCHAR *)((char *)pCurrentDirEntry + pCurrentDirEntry->TargetNameOffset);
960 // Does this entry already exist in the directory?
963 ulCRC = AFSGenerateCRC( &uniDirName,
966 AFSLocateCaseSensitiveDirEntry( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
972 // Set up the entry length
975 ulEntryLength = QuadAlign( sizeof( AFSDirEnumEntry) +
976 pCurrentDirEntry->FileNameLength +
977 pCurrentDirEntry->TargetNameLength);
980 AFSIsEqualFID( &pCurrentDirEntry->FileId,
981 &pDirNode->ObjectInformation->FileId))
985 // Found matching directory entry by name and FileID
988 AFSAcquireShared( ObjectInfoCB->VolumeCB->ObjectInfoTree.TreeLock,
991 ullIndex = AFSCreateLowIndex( &pCurrentDirEntry->FileId);
993 ntStatus = AFSLocateHashEntry( ObjectInfoCB->VolumeCB->ObjectInfoTree.TreeHead,
995 (AFSBTreeEntry **)&pObjectInfo);
997 AFSReleaseResource( ObjectInfoCB->VolumeCB->ObjectInfoTree.TreeLock);
999 if( NT_SUCCESS( ntStatus) &&
1000 pObjectInfo != NULL)
1004 // Indicate this is a valid entry
1007 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID);
1009 if( pCurrentDirEntry->ShortNameLength > 0 &&
1010 pDirNode->NameInformation.ShortNameLength > 0)
1012 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1013 AFS_TRACE_LEVEL_VERBOSE,
1014 "AFSVerifyDirectoryContent Verified entry %wZ (%wZ) parent FID %08lX-%08lX-%08lX-%08lX old short name %S New short name %S\n",
1016 &pDirNode->NameInformation.FileName,
1017 ObjectInfoCB->FileId.Cell,
1018 ObjectInfoCB->FileId.Volume,
1019 ObjectInfoCB->FileId.Vnode,
1020 ObjectInfoCB->FileId.Unique,
1021 pDirNode->NameInformation.ShortName,
1022 pCurrentDirEntry->ShortName);
1024 else if( pCurrentDirEntry->ShortNameLength == 0 &&
1025 pDirNode->NameInformation.ShortNameLength > 0)
1028 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1029 AFS_TRACE_LEVEL_VERBOSE,
1030 "AFSVerifyDirectoryContent Verified entry %wZ (%wZ) parent FID %08lX-%08lX-%08lX-%08lX old short name %S New short name NULL\n",
1032 &pDirNode->NameInformation.FileName,
1033 ObjectInfoCB->FileId.Cell,
1034 ObjectInfoCB->FileId.Volume,
1035 ObjectInfoCB->FileId.Vnode,
1036 ObjectInfoCB->FileId.Unique,
1037 pDirNode->NameInformation.ShortName);
1039 else if( pCurrentDirEntry->ShortNameLength > 0 &&
1040 pDirNode->NameInformation.ShortNameLength == 0)
1042 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1043 AFS_TRACE_LEVEL_VERBOSE,
1044 "AFSVerifyDirectoryContent Verified entry %wZ (%wZ) parent FID %08lX-%08lX-%08lX-%08lX old short name NULL New short name %S\n",
1046 &pDirNode->NameInformation.FileName,
1047 ObjectInfoCB->FileId.Cell,
1048 ObjectInfoCB->FileId.Volume,
1049 ObjectInfoCB->FileId.Vnode,
1050 ObjectInfoCB->FileId.Unique,
1051 pCurrentDirEntry->ShortName);
1055 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1056 AFS_TRACE_LEVEL_VERBOSE,
1057 "AFSVerifyDirectoryContent Verified entry %wZ (%wZ) parent FID %08lX-%08lX-%08lX-%08lX old short name NULL New short name NULL\n",
1059 &pDirNode->NameInformation.FileName,
1060 ObjectInfoCB->FileId.Cell,
1061 ObjectInfoCB->FileId.Volume,
1062 ObjectInfoCB->FileId.Vnode,
1063 ObjectInfoCB->FileId.Unique);
1067 // Update the metadata for the entry
1070 if( pObjectInfo->DataVersion.QuadPart != pCurrentDirEntry->DataVersion.QuadPart)
1073 lCount = InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
1075 AFSInvalidateObject( &pObjectInfo,
1076 AFS_INVALIDATE_DATA_VERSION);
1078 if( pObjectInfo != NULL)
1081 lCount = InterlockedDecrement( &pObjectInfo->ObjectReferenceCount);
1087 AFSUpdateMetaData( pDirNode,
1095 pCurrentDirEntry = (AFSDirEnumEntry *)((char *)pCurrentDirEntry + ulEntryLength);
1097 if( ulResultLen >= ulEntryLength)
1099 ulResultLen -= ulEntryLength;
1113 // File name matches but FileID does not.
1116 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1117 AFS_TRACE_LEVEL_VERBOSE,
1118 "AFSVerifyDirectoryContent Processing dir entry %p %wZ with different FID, same name in parent FID %08lX-%08lX-%08lX-%08lX\n",
1120 &pDirNode->NameInformation.FileName,
1121 ObjectInfoCB->FileId.Cell,
1122 ObjectInfoCB->FileId.Volume,
1123 ObjectInfoCB->FileId.Vnode,
1124 ObjectInfoCB->FileId.Unique);
1127 // Need to tear down this entry and rebuild it below
1130 if( pDirNode->OpenReferenceCount == 0)
1133 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1134 AFS_TRACE_LEVEL_VERBOSE,
1135 "AFSVerifyDirectoryContent Different FIDs - Deleting DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
1137 &pDirNode->NameInformation.FileName,
1138 pDirNode->ObjectInformation->FileId.Cell,
1139 pDirNode->ObjectInformation->FileId.Volume,
1140 pDirNode->ObjectInformation->FileId.Vnode,
1141 pDirNode->ObjectInformation->FileId.Unique,
1142 pCurrentDirEntry->FileId.Cell,
1143 pCurrentDirEntry->FileId.Volume,
1144 pCurrentDirEntry->FileId.Vnode,
1145 pCurrentDirEntry->FileId.Unique);
1147 AFSDeleteDirEntry( ObjectInfoCB,
1153 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_DELETED);
1155 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1156 AFS_TRACE_LEVEL_WARNING,
1157 "AFSVerifyDirectoryContent Different FIDs - removing DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
1159 &pDirNode->NameInformation.FileName,
1160 pDirNode->ObjectInformation->FileId.Cell,
1161 pDirNode->ObjectInformation->FileId.Volume,
1162 pDirNode->ObjectInformation->FileId.Vnode,
1163 pDirNode->ObjectInformation->FileId.Unique,
1164 pCurrentDirEntry->FileId.Cell,
1165 pCurrentDirEntry->FileId.Volume,
1166 pCurrentDirEntry->FileId.Vnode,
1167 pCurrentDirEntry->FileId.Unique);
1169 AFSRemoveNameEntry( ObjectInfoCB,
1176 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1177 AFS_TRACE_LEVEL_VERBOSE,
1178 "AFSVerifyDirectoryContent New entry %wZ for parent FID %08lX-%08lX-%08lX-%08lX\n",
1180 ObjectInfoCB->FileId.Cell,
1181 ObjectInfoCB->FileId.Volume,
1182 ObjectInfoCB->FileId.Vnode,
1183 ObjectInfoCB->FileId.Unique);
1186 pDirNode = AFSInitDirEntry( ObjectInfoCB,
1190 (ULONG)InterlockedIncrement( &ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.ContentIndex));
1192 if( pDirNode == NULL)
1195 ntStatus = STATUS_INSUFFICIENT_RESOURCES;
1200 AFSUpdateMetaData( pDirNode,
1203 if( pDirNode->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY)
1206 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1207 AFS_TRACE_LEVEL_VERBOSE,
1208 "AFSVerifyDirectoryContent Setting VERIFY on entry %wZ for FID %08lX-%08lX-%08lX-%08lX\n",
1210 pDirNode->ObjectInformation->FileId.Cell,
1211 pDirNode->ObjectInformation->FileId.Volume,
1212 pDirNode->ObjectInformation->FileId.Vnode,
1213 pDirNode->ObjectInformation->FileId.Unique);
1215 AFSAcquireExcl( pDirNode->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
1218 SetFlag( pDirNode->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
1220 pDirNode->ObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
1222 AFSReleaseResource( pDirNode->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1226 // Init the short name if we have one
1229 if( pCurrentDirEntry->ShortNameLength > 0)
1232 UNICODE_STRING uniShortName;
1234 pDirNode->NameInformation.ShortNameLength = pCurrentDirEntry->ShortNameLength;
1236 RtlCopyMemory( pDirNode->NameInformation.ShortName,
1237 pCurrentDirEntry->ShortName,
1238 pDirNode->NameInformation.ShortNameLength);
1241 // Generate the short name index
1244 uniShortName.Length = pDirNode->NameInformation.ShortNameLength;
1245 uniShortName.MaximumLength = uniShortName.Length;
1246 uniShortName.Buffer = pDirNode->NameInformation.ShortName;
1248 if( !RtlIsNameLegalDOS8Dot3( &pDirNode->NameInformation.FileName,
1253 pDirNode->Type.Data.ShortNameTreeEntry.HashIndex = AFSGenerateCRC( &uniShortName,
1256 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1257 AFS_TRACE_LEVEL_VERBOSE,
1258 "AFSVerifyDirectoryContent Initialized short name %wZ for DE %p for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1261 &pDirNode->NameInformation.FileName,
1262 pCurrentDirEntry->FileId.Cell,
1263 pCurrentDirEntry->FileId.Volume,
1264 pCurrentDirEntry->FileId.Vnode,
1265 pCurrentDirEntry->FileId.Unique);
1269 pDirNode->NameInformation.ShortNameLength = 0;
1271 RtlZeroMemory( pDirNode->NameInformation.ShortName,
1272 (12 * sizeof( WCHAR)));
1278 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1279 AFS_TRACE_LEVEL_VERBOSE,
1280 "AFSVerifyDirectoryContent NO short name for DE %p for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1282 &pDirNode->NameInformation.FileName,
1283 pCurrentDirEntry->FileId.Cell,
1284 pCurrentDirEntry->FileId.Volume,
1285 pCurrentDirEntry->FileId.Vnode,
1286 pCurrentDirEntry->FileId.Unique);
1290 // Insert the node into the name tree
1293 ASSERT( ExIsResourceAcquiredExclusiveLite( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock));
1295 if( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead == NULL)
1298 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = pDirNode;
1300 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1301 AFS_TRACE_LEVEL_VERBOSE,
1302 "AFSVerifyDirectoryContent Insert DE %p to head of case sensitive tree for %wZ\n",
1304 &pDirNode->NameInformation.FileName);
1309 if( !NT_SUCCESS( AFSInsertCaseSensitiveDirEntry( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
1312 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1313 AFS_TRACE_LEVEL_VERBOSE,
1314 "AFSVerifyDirectoryContent Failed to insert DE %p to case sensitive tree for %wZ\n",
1316 &pDirNode->NameInformation.FileName);
1319 // Delete this dir entry and continue on
1322 AFSDeleteDirEntry( ObjectInfoCB,
1325 pCurrentDirEntry = (AFSDirEnumEntry *)((char *)pCurrentDirEntry + ulEntryLength);
1327 if( ulResultLen >= ulEntryLength)
1329 ulResultLen -= ulEntryLength;
1340 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1341 AFS_TRACE_LEVEL_VERBOSE,
1342 "AFSVerifyDirectoryContent Insert DE %p to case sensitive tree for %wZ\n",
1344 &pDirNode->NameInformation.FileName);
1348 ClearFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
1350 if( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead == NULL)
1353 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = pDirNode;
1355 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
1357 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1358 AFS_TRACE_LEVEL_VERBOSE,
1359 "AFSVerifyDirectoryContent Insert DE %p to head of case insensitive tree for %wZ\n",
1361 &pDirNode->NameInformation.FileName);
1366 AFSInsertCaseInsensitiveDirEntry( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
1369 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1370 AFS_TRACE_LEVEL_VERBOSE,
1371 "AFSVerifyDirectoryContent Insert DE %p to case insensitive tree for %wZ\n",
1373 &pDirNode->NameInformation.FileName);
1376 if( ObjectInfoCB->Specific.Directory.DirectoryNodeListHead == NULL)
1379 ObjectInfoCB->Specific.Directory.DirectoryNodeListHead = pDirNode;
1384 (ObjectInfoCB->Specific.Directory.DirectoryNodeListTail)->ListEntry.fLink = pDirNode;
1386 pDirNode->ListEntry.bLink = ObjectInfoCB->Specific.Directory.DirectoryNodeListTail;
1389 ObjectInfoCB->Specific.Directory.DirectoryNodeListTail = pDirNode;
1391 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST);
1393 InterlockedIncrement( &ObjectInfoCB->Specific.Directory.DirectoryNodeCount);
1395 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
1396 AFS_TRACE_LEVEL_VERBOSE,
1397 "AFSVerifyDirectoryContent Adding entry %wZ Inc Count %d to parent FID %08lX-%08lX-%08lX-%08lX\n",
1398 &pDirNode->NameInformation.FileName,
1399 ObjectInfoCB->Specific.Directory.DirectoryNodeCount,
1400 ObjectInfoCB->FileId.Cell,
1401 ObjectInfoCB->FileId.Volume,
1402 ObjectInfoCB->FileId.Vnode,
1403 ObjectInfoCB->FileId.Unique);
1405 if( pDirNode->Type.Data.ShortNameTreeEntry.HashIndex != 0)
1409 // Insert the short name entry if we have a valid short name
1412 if( ObjectInfoCB->Specific.Directory.ShortNameTree == NULL)
1415 ObjectInfoCB->Specific.Directory.ShortNameTree = pDirNode;
1417 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1418 AFS_TRACE_LEVEL_VERBOSE,
1419 "AFSVerifyDirectoryContent Insert DE %p to head of shortname tree for %wZ\n",
1421 &pDirNode->NameInformation.FileName);
1423 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
1428 if( !NT_SUCCESS( AFSInsertShortNameDirEntry( ObjectInfoCB->Specific.Directory.ShortNameTree,
1431 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1432 AFS_TRACE_LEVEL_VERBOSE,
1433 "AFSVerifyDirectoryContent Failed to insert DE %p (%08lX) to shortname tree for %wZ\n",
1435 pDirNode->Type.Data.ShortNameTreeEntry.HashIndex,
1436 &pDirNode->NameInformation.FileName);
1440 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
1442 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1443 AFS_TRACE_LEVEL_VERBOSE,
1444 "AFSVerifyDirectoryContent Insert DE %p to shortname tree for %wZ\n",
1446 &pDirNode->NameInformation.FileName);
1451 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID);
1457 pCurrentDirEntry = (AFSDirEnumEntry *)((char *)pCurrentDirEntry + ulEntryLength);
1459 if( ulResultLen >= ulEntryLength)
1461 ulResultLen -= ulEntryLength;
1469 ulResultLen = AFS_DIR_ENUM_BUFFER_LEN;
1472 // Reset the information in the request buffer since it got trampled
1476 pDirQueryCB->EnumHandle = pDirEnumResponse->EnumHandle;
1485 if( pBuffer != NULL)
1488 AFSExFreePool( pBuffer);
1496 AFSNotifyFileCreate( IN GUID *AuthGroup,
1497 IN AFSObjectInfoCB *ParentObjectInfo,
1498 IN PLARGE_INTEGER FileSize,
1499 IN ULONG FileAttributes,
1500 IN UNICODE_STRING *FileName,
1501 OUT AFSDirectoryCB **DirNode)
1504 NTSTATUS ntStatus = STATUS_SUCCESS;
1505 AFSFileCreateCB stCreateCB;
1506 AFSFileCreateResultCB *pResultCB = NULL;
1507 ULONG ulResultLen = 0;
1508 UNICODE_STRING uniTargetName;
1509 AFSDirectoryCB *pDirNode = NULL;
1511 LARGE_INTEGER liOldDataVersion;
1517 // Init the control block for the request
1520 RtlZeroMemory( &stCreateCB,
1521 sizeof( AFSFileCreateCB));
1523 stCreateCB.ParentId = ParentObjectInfo->FileId;
1525 stCreateCB.AllocationSize = *FileSize;
1527 stCreateCB.FileAttributes = FileAttributes;
1529 stCreateCB.EaSize = 0;
1531 liOldDataVersion = ParentObjectInfo->DataVersion;
1534 // Allocate our return buffer
1537 pResultCB = (AFSFileCreateResultCB *)AFSExAllocatePoolWithTag( PagedPool,
1539 AFS_GENERIC_MEMORY_1_TAG);
1541 if( pResultCB == NULL)
1544 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1547 RtlZeroMemory( pResultCB,
1550 ulResultLen = PAGE_SIZE;
1553 // Send the call to the service
1556 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_CREATE_FILE,
1557 AFS_REQUEST_FLAG_SYNCHRONOUS | AFS_REQUEST_FLAG_HOLD_FID,
1562 sizeof( AFSFileCreateCB),
1566 if( ntStatus != STATUS_SUCCESS)
1569 if( NT_SUCCESS( ntStatus))
1572 ntStatus = STATUS_DEVICE_NOT_READY;
1575 try_return( ntStatus);
1579 // We may have raced with an invalidation call and a subsequent re-enumeration of this parent
1580 // and though we created the node, it is already in our list. If this is the case then
1581 // look up the entry rather than create a new entry
1582 // The check is to ensure the DV has been modified
1585 AFSAcquireExcl( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
1588 if( ParentObjectInfo->DataVersion.QuadPart != pResultCB->ParentDataVersion.QuadPart - 1)
1591 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1592 AFS_TRACE_LEVEL_WARNING,
1593 "AFSNotifyFileCreate Raced with an invalidate call and a re-enumeration for entry %wZ ParentFID %08lX-%08lX-%08lX-%08lX Version (%08lX:%08lX != %08lX:%08lX - 1)\n",
1595 ParentObjectInfo->FileId.Cell,
1596 ParentObjectInfo->FileId.Volume,
1597 ParentObjectInfo->FileId.Vnode,
1598 ParentObjectInfo->FileId.Unique,
1599 ParentObjectInfo->DataVersion.QuadPart,
1600 pResultCB->ParentDataVersion.QuadPart);
1603 // We raced so go and lookup the directory entry in the parent
1606 ulCRC = AFSGenerateCRC( FileName,
1609 AFSLocateCaseSensitiveDirEntry( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
1613 if( pDirNode != NULL)
1616 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1617 AFS_TRACE_LEVEL_VERBOSE,
1618 "AFSNotifyFileCreate Located dir entry %p for file %wZ\n",
1622 if ( AFSIsEqualFID( &pDirNode->ObjectInformation->FileId,
1623 &pResultCB->DirEnum.FileId))
1626 InterlockedIncrement( &pDirNode->OpenReferenceCount);
1628 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1629 AFS_TRACE_LEVEL_VERBOSE,
1630 "AFSNotifyFileCreate Increment count on %wZ DE %p Cnt %d\n",
1631 &pDirNode->NameInformation.FileName,
1633 pDirNode->OpenReferenceCount);
1635 *DirNode = pDirNode;
1637 AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
1639 try_return( ntStatus = STATUS_REPARSE);
1645 // We found an entry that matches the desired name but it is not the
1646 // same as the one that was created for us by the file server.
1649 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1650 AFS_TRACE_LEVEL_ERROR,
1651 "AFSNotifyFileCreate Found matching name entry %wZ DE %p FID %08lX-%08lX-%08lX-%08lX != FID %08lX-%08lX-%08lX-%08lX\n",
1654 pDirNode->ObjectInformation->FileId.Cell,
1655 pDirNode->ObjectInformation->FileId.Volume,
1656 pDirNode->ObjectInformation->FileId.Vnode,
1657 pDirNode->ObjectInformation->FileId.Unique,
1658 pResultCB->DirEnum.FileId.Cell,
1659 pResultCB->DirEnum.FileId.Volume,
1660 pResultCB->DirEnum.FileId.Vnode,
1661 pResultCB->DirEnum.FileId.Unique);
1663 if( pDirNode->OpenReferenceCount == 0)
1666 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1667 AFS_TRACE_LEVEL_VERBOSE,
1668 "AFSNotifyFileCreate Different FIDs - Deleting DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
1670 &pDirNode->NameInformation.FileName,
1671 pDirNode->ObjectInformation->FileId.Cell,
1672 pDirNode->ObjectInformation->FileId.Volume,
1673 pDirNode->ObjectInformation->FileId.Vnode,
1674 pDirNode->ObjectInformation->FileId.Unique,
1675 pResultCB->DirEnum.FileId.Cell,
1676 pResultCB->DirEnum.FileId.Volume,
1677 pResultCB->DirEnum.FileId.Vnode,
1678 pResultCB->DirEnum.FileId.Unique);
1680 AFSDeleteDirEntry( ParentObjectInfo,
1686 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_DELETED);
1688 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1689 AFS_TRACE_LEVEL_VERBOSE,
1690 "AFSNotifyFileCreate Different FIDs - Removing DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
1692 &pDirNode->NameInformation.FileName,
1693 pDirNode->ObjectInformation->FileId.Cell,
1694 pDirNode->ObjectInformation->FileId.Volume,
1695 pDirNode->ObjectInformation->FileId.Vnode,
1696 pDirNode->ObjectInformation->FileId.Unique,
1697 pResultCB->DirEnum.FileId.Cell,
1698 pResultCB->DirEnum.FileId.Volume,
1699 pResultCB->DirEnum.FileId.Vnode,
1700 pResultCB->DirEnum.FileId.Unique);
1702 AFSRemoveNameEntry( ParentObjectInfo,
1711 // We are unsure of our current data so set the verify flag. It may already be set
1712 // but no big deal to reset it
1715 SetFlag( ParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
1717 ParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
1720 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1721 AFS_TRACE_LEVEL_VERBOSE,
1722 "AFSNotifyFileCreate Creating new entry %wZ\n",
1726 // Initialize the directory entry
1729 uniTargetName.Length = (USHORT)pResultCB->DirEnum.TargetNameLength;
1731 uniTargetName.MaximumLength = uniTargetName.Length;
1733 uniTargetName.Buffer = (WCHAR *)((char *)&pResultCB->DirEnum + pResultCB->DirEnum.TargetNameOffset);
1735 pDirNode = AFSInitDirEntry( ParentObjectInfo,
1738 &pResultCB->DirEnum,
1739 (ULONG)InterlockedIncrement( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.ContentIndex));
1741 if( pDirNode == NULL)
1744 SetFlag( ParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
1746 ParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
1748 AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
1750 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1754 // Init the short name if we have one
1757 if( pResultCB->DirEnum.ShortNameLength > 0)
1760 UNICODE_STRING uniShortName;
1762 pDirNode->NameInformation.ShortNameLength = pResultCB->DirEnum.ShortNameLength;
1764 RtlCopyMemory( pDirNode->NameInformation.ShortName,
1765 pResultCB->DirEnum.ShortName,
1766 pDirNode->NameInformation.ShortNameLength);
1769 // Generate the short name index
1772 uniShortName.Length = pDirNode->NameInformation.ShortNameLength;
1773 uniShortName.Buffer = pDirNode->NameInformation.ShortName;
1775 pDirNode->Type.Data.ShortNameTreeEntry.HashIndex = AFSGenerateCRC( &uniShortName,
1778 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1779 AFS_TRACE_LEVEL_VERBOSE,
1780 "AFSNotifyFileCreate Initialized short name %wZ for DE %p for %wZ\n",
1783 &pDirNode->NameInformation.FileName);
1786 if ( !BooleanFlagOn( ParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY))
1790 // Update the parent data version
1793 ParentObjectInfo->DataVersion = pResultCB->ParentDataVersion;
1795 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1796 AFS_TRACE_LEVEL_VERBOSE,
1797 "AFSNotifyFileCreate entry %wZ ParentFID %08lX-%08lX-%08lX-%08lX Version %08lX:%08lX\n",
1799 ParentObjectInfo->FileId.Cell,
1800 ParentObjectInfo->FileId.Volume,
1801 ParentObjectInfo->FileId.Vnode,
1802 ParentObjectInfo->FileId.Unique,
1803 ParentObjectInfo->DataVersion.QuadPart);
1806 AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
1809 // Return the directory node
1812 *DirNode = pDirNode;
1816 if( pResultCB != NULL)
1819 AFSExFreePool( pResultCB);
1827 AFSUpdateFileInformation( IN AFSFileID *ParentFid,
1828 IN AFSObjectInfoCB *ObjectInfo,
1832 NTSTATUS ntStatus = STATUS_SUCCESS;
1833 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1834 AFSFileUpdateCB stUpdateCB;
1835 ULONG ulResultLen = 0;
1836 AFSFileUpdateResultCB *pUpdateResultCB = NULL;
1842 // Init the control block for the request
1845 RtlZeroMemory( &stUpdateCB,
1846 sizeof( AFSFileUpdateCB));
1848 stUpdateCB.AllocationSize = ObjectInfo->EndOfFile;
1850 stUpdateCB.FileAttributes = ObjectInfo->FileAttributes;
1852 stUpdateCB.EaSize = ObjectInfo->EaSize;
1854 stUpdateCB.ParentId = *ParentFid;
1856 stUpdateCB.LastAccessTime = ObjectInfo->LastAccessTime;
1858 stUpdateCB.CreateTime = ObjectInfo->CreationTime;
1860 stUpdateCB.ChangeTime = ObjectInfo->ChangeTime;
1862 stUpdateCB.LastWriteTime = ObjectInfo->LastWriteTime;
1864 pUpdateResultCB = (AFSFileUpdateResultCB *)AFSExAllocatePoolWithTag( PagedPool,
1866 AFS_UPDATE_RESULT_TAG);
1868 if( pUpdateResultCB == NULL)
1871 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1874 ulResultLen = PAGE_SIZE;
1876 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_UPDATE_FILE,
1877 AFS_REQUEST_FLAG_SYNCHRONOUS,
1880 &ObjectInfo->FileId,
1882 sizeof( AFSFileUpdateCB),
1886 if( ntStatus != STATUS_SUCCESS)
1889 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1890 AFS_TRACE_LEVEL_ERROR,
1891 "AFSUpdateFileInformation failed FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1892 ObjectInfo->FileId.Cell,
1893 ObjectInfo->FileId.Volume,
1894 ObjectInfo->FileId.Vnode,
1895 ObjectInfo->FileId.Unique,
1898 try_return( ntStatus);
1902 // Update the data version
1905 AFSAcquireExcl( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
1908 if ( !BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY))
1911 ObjectInfo->DataVersion = pUpdateResultCB->DirEnum.DataVersion;
1914 AFSReleaseResource( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
1918 if( pUpdateResultCB != NULL)
1921 AFSExFreePool( pUpdateResultCB);
1929 AFSNotifyDelete( IN AFSDirectoryCB *DirectoryCB,
1931 IN BOOLEAN CheckOnly)
1933 NTSTATUS ntStatus = STATUS_SUCCESS;
1934 ULONG ulResultLen = 0;
1935 AFSFileDeleteCB stDelete;
1936 AFSFileDeleteResultCB stDeleteResult;
1937 ULONG ulRequestFlags = AFS_REQUEST_FLAG_SYNCHRONOUS;
1942 stDelete.ParentId = DirectoryCB->ObjectInformation->ParentObjectInformation->FileId;
1944 stDelete.ProcessId = (ULONGLONG)PsGetCurrentProcessId();
1946 ulResultLen = sizeof( AFSFileDeleteResultCB);
1950 ulRequestFlags |= AFS_REQUEST_FLAG_CHECK_ONLY;
1953 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_DELETE_FILE,
1956 &DirectoryCB->NameInformation.FileName,
1957 &DirectoryCB->ObjectInformation->FileId,
1959 sizeof( AFSFileDeleteCB),
1963 if( ntStatus != STATUS_SUCCESS)
1966 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1967 AFS_TRACE_LEVEL_ERROR,
1968 "AFSNotifyDelete failed ParentFID %08lX-%08lX-%08lX-%08lX %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1969 stDelete.ParentId.Cell,
1970 stDelete.ParentId.Volume,
1971 stDelete.ParentId.Vnode,
1972 stDelete.ParentId.Unique,
1973 &DirectoryCB->NameInformation.FileName,
1974 DirectoryCB->ObjectInformation->FileId.Cell,
1975 DirectoryCB->ObjectInformation->FileId.Volume,
1976 DirectoryCB->ObjectInformation->FileId.Vnode,
1977 DirectoryCB->ObjectInformation->FileId.Unique,
1980 try_return( ntStatus);
1983 AFSAcquireExcl( DirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
1990 // Validate the parent data version
1993 if( DirectoryCB->ObjectInformation->ParentObjectInformation->DataVersion.QuadPart != stDeleteResult.ParentDataVersion.QuadPart)
1996 SetFlag( DirectoryCB->ObjectInformation->ParentObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
1998 DirectoryCB->ObjectInformation->ParentObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
2005 // Update the parent data version
2008 if( DirectoryCB->ObjectInformation->ParentObjectInformation->DataVersion.QuadPart != stDeleteResult.ParentDataVersion.QuadPart - 1)
2011 SetFlag( DirectoryCB->ObjectInformation->ParentObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
2013 DirectoryCB->ObjectInformation->ParentObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
2019 // TODO -- The entry must be removed from the directory at which point the
2020 // Directory data version number can be updated. Until then we must force
2023 // DirectoryCB->ObjectInformation->ParentObjectInformation->DataVersion.QuadPart = stDeleteResult.ParentDataVersion.QuadPart;
2026 SetFlag( DirectoryCB->ObjectInformation->ParentObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
2028 DirectoryCB->ObjectInformation->ParentObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
2032 AFSReleaseResource( DirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
2043 AFSNotifyRename( IN AFSObjectInfoCB *ObjectInfo,
2045 IN AFSObjectInfoCB *ParentObjectInfo,
2046 IN AFSObjectInfoCB *TargetParentObjectInfo,
2047 IN AFSDirectoryCB *DirectoryCB,
2048 IN UNICODE_STRING *TargetName,
2049 OUT AFSFileID *UpdatedFID)
2052 NTSTATUS ntStatus = STATUS_SUCCESS;
2053 AFSFileRenameCB *pRenameCB = NULL;
2054 AFSFileRenameResultCB *pRenameResultCB = NULL;
2055 ULONG ulResultLen = 0;
2061 // Init the control block for the request
2064 pRenameCB = (AFSFileRenameCB *)AFSExAllocatePoolWithTag( PagedPool,
2066 AFS_RENAME_REQUEST_TAG);
2068 if( pRenameCB == NULL)
2071 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2074 RtlZeroMemory( pRenameCB,
2077 pRenameCB->SourceParentId = ParentObjectInfo->FileId;
2079 pRenameCB->TargetParentId = TargetParentObjectInfo->FileId;
2081 pRenameCB->TargetNameLength = TargetName->Length;
2083 RtlCopyMemory( pRenameCB->TargetName,
2085 TargetName->Length);
2088 // Use the same buffer for the result control block
2091 pRenameResultCB = (AFSFileRenameResultCB *)pRenameCB;
2093 ulResultLen = PAGE_SIZE;
2095 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_RENAME_FILE,
2096 AFS_REQUEST_FLAG_SYNCHRONOUS,
2098 &DirectoryCB->NameInformation.FileName,
2099 &ObjectInfo->FileId,
2101 sizeof( AFSFileRenameCB) + TargetName->Length,
2105 if( ntStatus != STATUS_SUCCESS)
2108 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2109 AFS_TRACE_LEVEL_ERROR,
2110 "AFSNotifyRename failed FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2111 ObjectInfo->FileId.Cell,
2112 ObjectInfo->FileId.Volume,
2113 ObjectInfo->FileId.Vnode,
2114 ObjectInfo->FileId.Unique,
2117 try_return( ntStatus);
2121 // Update the information from the returned data
2124 AFSAcquireExcl( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2127 if ( ParentObjectInfo->DataVersion.QuadPart == pRenameResultCB->SourceParentDataVersion.QuadPart - 1)
2130 ParentObjectInfo->DataVersion = pRenameResultCB->SourceParentDataVersion;
2135 SetFlag( ParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2137 ParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
2140 if ( ParentObjectInfo != TargetParentObjectInfo)
2143 if ( TargetParentObjectInfo->DataVersion.QuadPart == pRenameResultCB->TargetParentDataVersion.QuadPart - 1)
2146 TargetParentObjectInfo->DataVersion = pRenameResultCB->TargetParentDataVersion;
2151 SetFlag( TargetParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2153 TargetParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
2158 // Move over the short name
2161 DirectoryCB->NameInformation.ShortNameLength = pRenameResultCB->DirEnum.ShortNameLength;
2163 if( DirectoryCB->NameInformation.ShortNameLength > 0)
2166 UNICODE_STRING uniShortName;
2168 uniShortName.Length = DirectoryCB->NameInformation.ShortNameLength;
2169 uniShortName.MaximumLength = uniShortName.Length;
2170 uniShortName.Buffer = DirectoryCB->NameInformation.ShortName;
2172 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2173 AFS_TRACE_LEVEL_VERBOSE,
2174 "AFSNotifyRename Update old short name %wZ for DE %p for %wZ\n",
2177 &DirectoryCB->NameInformation.FileName);
2179 DirectoryCB->NameInformation.ShortNameLength = pRenameResultCB->DirEnum.ShortNameLength;
2181 RtlCopyMemory( DirectoryCB->NameInformation.ShortName,
2182 pRenameResultCB->DirEnum.ShortName,
2183 DirectoryCB->NameInformation.ShortNameLength);
2185 uniShortName.Length = DirectoryCB->NameInformation.ShortNameLength;
2186 uniShortName.MaximumLength = uniShortName.Length;
2187 uniShortName.Buffer = DirectoryCB->NameInformation.ShortName;
2189 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2190 AFS_TRACE_LEVEL_VERBOSE,
2191 "AFSNotifyRename Initialized short name %wZ for DE %p for %wZ\n",
2194 &DirectoryCB->NameInformation.FileName);
2199 UNICODE_STRING uniShortName;
2201 uniShortName.Length = DirectoryCB->NameInformation.ShortNameLength;
2202 uniShortName.MaximumLength = uniShortName.Length;
2203 uniShortName.Buffer = DirectoryCB->NameInformation.ShortName;
2205 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2206 AFS_TRACE_LEVEL_VERBOSE,
2207 "AFSNotifyRename Removing old short name %wZ for DE %p for %wZ\n",
2210 &DirectoryCB->NameInformation.FileName);
2212 DirectoryCB->NameInformation.ShortNameLength = 0;
2214 DirectoryCB->Type.Data.ShortNameTreeEntry.HashIndex = 0;
2217 AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2219 if( UpdatedFID != NULL)
2221 *UpdatedFID = pRenameResultCB->DirEnum.FileId;
2226 if( pRenameCB != NULL)
2229 AFSExFreePool( pRenameCB);
2237 AFSEvaluateTargetByID( IN AFSObjectInfoCB *ObjectInfo,
2239 IN BOOLEAN FastCall,
2240 OUT AFSDirEnumEntry **DirEnumEntry)
2243 NTSTATUS ntStatus = STATUS_SUCCESS;
2244 AFSEvalTargetCB stTargetID;
2245 ULONG ulResultBufferLength;
2246 AFSFileEvalResultCB *pEvalResultCB = NULL;
2247 AFSDirEnumEntry *pDirEnumCB = NULL;
2248 ULONG ulRequestFlags = AFS_REQUEST_FLAG_SYNCHRONOUS;
2253 RtlZeroMemory( &stTargetID,
2254 sizeof( AFSEvalTargetCB));
2256 if( ObjectInfo->ParentObjectInformation != NULL)
2259 stTargetID.ParentId = ObjectInfo->ParentObjectInformation->FileId;
2263 // Allocate our response buffer
2266 pEvalResultCB = (AFSFileEvalResultCB *)AFSExAllocatePoolWithTag( PagedPool,
2268 AFS_GENERIC_MEMORY_30_TAG);
2270 if( pEvalResultCB == NULL)
2273 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2277 // Call to the service to evaluate the fid
2280 ulResultBufferLength = PAGE_SIZE;
2285 ulRequestFlags |= AFS_REQUEST_FLAG_FAST_REQUEST;
2288 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_EVAL_TARGET_BY_ID,
2292 &ObjectInfo->FileId,
2294 sizeof( AFSEvalTargetCB),
2296 &ulResultBufferLength);
2298 if( ntStatus != STATUS_SUCCESS)
2302 // If we received back a STATUS_INVALID_HANDLE then mark the parent as requiring
2306 if( ntStatus == STATUS_OBJECT_PATH_INVALID)
2309 if( ObjectInfo->ParentObjectInformation != NULL)
2312 AFSAcquireExcl( ObjectInfo->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
2315 SetFlag( ObjectInfo->ParentObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
2317 ObjectInfo->ParentObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
2319 AFSReleaseResource( ObjectInfo->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
2323 try_return( ntStatus);
2327 // Validate the parent data version
2330 if ( ObjectInfo->ParentObjectInformation != NULL)
2333 AFSAcquireExcl( ObjectInfo->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
2336 if ( ObjectInfo->ParentObjectInformation->DataVersion.QuadPart != pEvalResultCB->ParentDataVersion.QuadPart)
2339 SetFlag( ObjectInfo->ParentObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
2341 ObjectInfo->ParentObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
2344 AFSReleaseResource( ObjectInfo->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
2348 // Pass back the dir enum entry
2351 if( DirEnumEntry != NULL)
2354 pDirEnumCB = (AFSDirEnumEntry *)AFSExAllocatePoolWithTag( PagedPool,
2356 AFS_GENERIC_MEMORY_2_TAG);
2358 if( pDirEnumCB == NULL)
2361 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2364 RtlCopyMemory( pDirEnumCB, &pEvalResultCB->DirEnum,
2365 ulResultBufferLength - sizeof( AFSFileEvalResultCB) + sizeof( AFSDirEnumEntry));
2367 *DirEnumEntry = pDirEnumCB;
2372 if( pEvalResultCB != NULL)
2375 AFSExFreePool( pEvalResultCB);
2378 if( !NT_SUCCESS( ntStatus))
2381 if( pDirEnumCB != NULL)
2384 AFSExFreePool( pDirEnumCB);
2387 *DirEnumEntry = NULL;
2395 AFSEvaluateTargetByName( IN GUID *AuthGroup,
2396 IN AFSObjectInfoCB *ParentObjectInfo,
2397 IN PUNICODE_STRING SourceName,
2398 OUT AFSDirEnumEntry **DirEnumEntry)
2401 NTSTATUS ntStatus = STATUS_SUCCESS;
2402 AFSEvalTargetCB stTargetID;
2403 ULONG ulResultBufferLength;
2404 AFSFileEvalResultCB *pEvalResultCB = NULL;
2405 AFSDirEnumEntry *pDirEnumCB = NULL;
2410 stTargetID.ParentId = ParentObjectInfo->FileId;
2413 // Allocate our response buffer
2416 pEvalResultCB = (AFSFileEvalResultCB *)AFSExAllocatePoolWithTag( PagedPool,
2418 AFS_GENERIC_MEMORY_31_TAG);
2420 if( pEvalResultCB == NULL)
2423 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2427 // Call to the service to evaluate the fid
2430 ulResultBufferLength = PAGE_SIZE;
2432 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_EVAL_TARGET_BY_NAME,
2433 AFS_REQUEST_FLAG_SYNCHRONOUS,
2438 sizeof( AFSEvalTargetCB),
2440 &ulResultBufferLength);
2442 if( ntStatus != STATUS_SUCCESS)
2445 if( ntStatus == STATUS_OBJECT_PATH_INVALID)
2448 AFSAcquireExcl( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2451 SetFlag( ParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2453 ParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
2455 AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2458 try_return( ntStatus);
2462 // Validate the parent data version
2465 AFSAcquireExcl( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2468 if ( ParentObjectInfo->DataVersion.QuadPart != pEvalResultCB->ParentDataVersion.QuadPart)
2471 SetFlag( ParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2473 ParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
2476 AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2479 // Pass back the dir enum entry
2482 if( DirEnumEntry != NULL)
2485 pDirEnumCB = (AFSDirEnumEntry *)AFSExAllocatePoolWithTag( PagedPool,
2487 AFS_GENERIC_MEMORY_3_TAG);
2489 if( pDirEnumCB == NULL)
2492 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2495 RtlCopyMemory( pDirEnumCB, &pEvalResultCB->DirEnum,
2496 ulResultBufferLength - sizeof( AFSFileEvalResultCB) + sizeof( AFSDirEnumEntry));
2498 *DirEnumEntry = pDirEnumCB;
2503 if( pEvalResultCB != NULL)
2506 AFSExFreePool( pEvalResultCB);
2509 if( !NT_SUCCESS( ntStatus))
2512 if( pDirEnumCB != NULL)
2515 AFSExFreePool( pDirEnumCB);
2518 *DirEnumEntry = NULL;
2526 AFSRetrieveVolumeInformation( IN GUID *AuthGroup,
2527 IN AFSFileID *FileID,
2528 OUT AFSVolumeInfoCB *VolumeInformation)
2531 NTSTATUS ntStatus = STATUS_SUCCESS;
2532 ULONG ulResultLen = 0;
2537 ulResultLen = sizeof( AFSVolumeInfoCB);
2539 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_GET_VOLUME_INFO,
2540 AFS_REQUEST_FLAG_SYNCHRONOUS,
2549 if( ntStatus != STATUS_SUCCESS)
2552 try_return( ntStatus);
2564 AFSNotifyPipeTransceive( IN AFSCcb *Ccb,
2565 IN ULONG InputLength,
2566 IN ULONG OutputLength,
2567 IN void *InputDataBuffer,
2568 OUT void *OutputDataBuffer,
2569 OUT ULONG *BytesReturned)
2572 NTSTATUS ntStatus = STATUS_SUCCESS;
2573 ULONG ulResultLen = 0;
2574 MDL *pInputMdl = NULL, *pOutputMdl = NULL;
2575 void *pInputSystemBuffer = NULL, *pOutputSystemBuffer = NULL;
2576 ULONG ulBufferLength = OutputLength;
2577 AFSPipeIORequestCB *pIoRequest = NULL;
2583 // Map the user buffer to a system address
2586 pInputSystemBuffer = AFSLockUserBuffer( InputDataBuffer,
2590 if( pInputSystemBuffer == NULL)
2593 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2596 pIoRequest = (AFSPipeIORequestCB *)AFSExAllocatePoolWithTag( PagedPool,
2597 sizeof( AFSPipeIORequestCB) +
2599 AFS_GENERIC_MEMORY_4_TAG);
2601 if( pIoRequest == NULL)
2604 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2607 RtlZeroMemory( pIoRequest,
2608 sizeof( AFSPipeIORequestCB) + InputLength);
2610 pIoRequest->RequestId = Ccb->RequestID;
2612 pIoRequest->RootId = Ccb->DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation.FileId;
2614 pIoRequest->BufferLength = InputLength;
2616 RtlCopyMemory( (void *)((char *)pIoRequest + sizeof( AFSPipeIORequestCB)),
2620 pOutputSystemBuffer = AFSLockUserBuffer( OutputDataBuffer,
2624 if( pOutputSystemBuffer == NULL)
2627 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2631 // Send the call to the service
2634 ulResultLen = OutputLength;
2636 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIPE_TRANSCEIVE,
2637 AFS_REQUEST_FLAG_SYNCHRONOUS,
2639 &Ccb->DirectoryCB->NameInformation.FileName,
2642 sizeof( AFSPipeIORequestCB) + InputLength,
2643 pOutputSystemBuffer,
2646 if( ntStatus != STATUS_SUCCESS &&
2647 ntStatus != STATUS_BUFFER_OVERFLOW)
2650 if( NT_SUCCESS( ntStatus))
2653 ntStatus = STATUS_DEVICE_NOT_READY;
2656 try_return( ntStatus);
2660 // Return the bytes processed
2663 *BytesReturned = ulResultLen;
2667 if( pInputMdl != NULL)
2670 MmUnlockPages( pInputMdl);
2672 IoFreeMdl( pInputMdl);
2675 if( pOutputMdl != NULL)
2678 MmUnlockPages( pOutputMdl);
2680 IoFreeMdl( pOutputMdl);
2683 if( pIoRequest != NULL)
2686 AFSExFreePool( pIoRequest);
2694 AFSNotifySetPipeInfo( IN AFSCcb *Ccb,
2695 IN ULONG InformationClass,
2696 IN ULONG InputLength,
2697 IN void *DataBuffer)
2700 NTSTATUS ntStatus = STATUS_SUCCESS;
2701 AFSPipeInfoRequestCB *pInfoRequest = NULL;
2706 pInfoRequest = (AFSPipeInfoRequestCB *)AFSExAllocatePoolWithTag( PagedPool,
2707 sizeof( AFSPipeInfoRequestCB) +
2709 AFS_GENERIC_MEMORY_5_TAG);
2711 if( pInfoRequest == NULL)
2714 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2717 RtlZeroMemory( pInfoRequest,
2718 sizeof( AFSPipeInfoRequestCB) + InputLength);
2720 pInfoRequest->RequestId = Ccb->RequestID;
2722 pInfoRequest->RootId = Ccb->DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation.FileId;
2724 pInfoRequest->BufferLength = InputLength;
2726 pInfoRequest->InformationClass = InformationClass;
2728 RtlCopyMemory( (void *)((char *)pInfoRequest + sizeof( AFSPipeInfoRequestCB)),
2733 // Send the call to the service
2736 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIPE_SET_INFO,
2737 AFS_REQUEST_FLAG_SYNCHRONOUS,
2739 &Ccb->DirectoryCB->NameInformation.FileName,
2742 sizeof( AFSPipeInfoRequestCB) + InputLength,
2746 if( ntStatus != STATUS_SUCCESS)
2749 if( NT_SUCCESS( ntStatus))
2752 ntStatus = STATUS_DEVICE_NOT_READY;
2755 try_return( ntStatus);
2760 if( pInfoRequest != NULL)
2763 AFSExFreePool( pInfoRequest);
2771 AFSNotifyQueryPipeInfo( IN AFSCcb *Ccb,
2772 IN ULONG InformationClass,
2773 IN ULONG OutputLength,
2774 IN void *DataBuffer,
2775 OUT ULONG *BytesReturned)
2778 NTSTATUS ntStatus = STATUS_SUCCESS;
2779 AFSPipeInfoRequestCB stInfoRequest;
2780 ULONG ulBytesProcessed = 0;
2785 RtlZeroMemory( &stInfoRequest,
2786 sizeof( AFSPipeInfoRequestCB));
2788 stInfoRequest.RequestId = Ccb->RequestID;
2790 stInfoRequest.RootId = Ccb->DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation.FileId;
2792 stInfoRequest.BufferLength = OutputLength;
2794 stInfoRequest.InformationClass = InformationClass;
2796 ulBytesProcessed = OutputLength;
2799 // Send the call to the service
2802 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIPE_QUERY_INFO,
2803 AFS_REQUEST_FLAG_SYNCHRONOUS,
2805 &Ccb->DirectoryCB->NameInformation.FileName,
2808 sizeof( AFSPipeInfoRequestCB),
2812 if( ntStatus != STATUS_SUCCESS)
2815 if( NT_SUCCESS( ntStatus))
2818 ntStatus = STATUS_DEVICE_NOT_READY;
2821 try_return( ntStatus);
2824 *BytesReturned = ulBytesProcessed;
2835 AFSReleaseFid( IN AFSFileID *FileId)
2838 NTSTATUS ntStatus = STATUS_SUCCESS;
2843 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_RELEASE_FID,
2858 AFSIsExtentRequestQueued( IN AFSFileID *FileID,
2859 IN LARGE_INTEGER *ExtentOffset,
2863 BOOLEAN bRequestQueued = FALSE;
2864 NTSTATUS ntStatus = STATUS_SUCCESS;
2865 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2866 AFSCommSrvcCB *pCommSrvc = NULL;
2867 AFSPoolEntry *pPoolEntry = NULL;
2868 AFSRequestExtentsCB *pRequestExtents = NULL;
2874 pCommSrvc = &pControlDevExt->Specific.Control.CommServiceCB;
2876 AFSAcquireShared( &pCommSrvc->IrpPoolLock,
2879 pPoolEntry = pCommSrvc->RequestPoolHead;
2881 while( pPoolEntry != NULL)
2884 if( pPoolEntry->RequestType == AFS_REQUEST_TYPE_REQUEST_FILE_EXTENTS)
2887 if( AFSIsEqualFID( &pPoolEntry->FileId, FileID))
2890 pRequestExtents = (AFSRequestExtentsCB *)pPoolEntry->Data;
2892 if( pRequestExtents->ByteOffset.QuadPart == ExtentOffset->QuadPart &&
2893 pRequestExtents->Length == Length)
2896 bRequestQueued = TRUE;
2901 pPoolEntry = pPoolEntry->fLink;
2904 AFSReleaseResource( &pCommSrvc->IrpPoolLock);
2907 return bRequestQueued;