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;
59 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
64 ASSERT( ExIsResourceAcquiredExclusiveLite( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock));
67 uniGUID.MaximumLength = 0;
68 uniGUID.Buffer = NULL;
70 if( AuthGroup != NULL)
72 RtlStringFromGUID( *AuthGroup,
76 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
77 AFS_TRACE_LEVEL_VERBOSE,
78 "AFSEnumerateDirectory Enumerating FID %08lX-%08lX-%08lX-%08lX AuthGroup %wZ\n",
79 ObjectInfoCB->FileId.Cell,
80 ObjectInfoCB->FileId.Volume,
81 ObjectInfoCB->FileId.Vnode,
82 ObjectInfoCB->FileId.Unique,
85 if( AuthGroup != NULL)
87 RtlFreeUnicodeString( &uniGUID);
91 // Initialize the directory enumeration buffer for the directory
94 pBuffer = AFSExAllocatePoolWithTag( PagedPool,
95 AFS_DIR_ENUM_BUFFER_LEN,
101 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
104 RtlZeroMemory( pBuffer,
105 AFS_DIR_ENUM_BUFFER_LEN);
107 ulResultLen = AFS_DIR_ENUM_BUFFER_LEN;
110 // Use the payload buffer for information we will pass to the service
113 pDirQueryCB = (AFSDirQueryCB *)pBuffer;
115 pDirQueryCB->EnumHandle = 0;
120 ulRequestFlags |= AFS_REQUEST_FLAG_FAST_REQUEST;
124 // Loop on the information
131 // If the enumeration handle is -1 then we are done
134 if( ((ULONG)-1) == pDirQueryCB->EnumHandle )
137 ntStatus = STATUS_NO_MORE_ENTRIES;
143 // Go and retrieve the directory contents
146 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_DIR_ENUM,
150 &ObjectInfoCB->FileId,
152 sizeof( AFSDirQueryCB),
157 if( ntStatus != STATUS_SUCCESS ||
161 if( ntStatus == STATUS_NO_MORE_FILES ||
162 ntStatus == STATUS_NO_MORE_ENTRIES)
165 ntStatus = STATUS_SUCCESS;
167 pDirEnumResponse = (AFSDirEnumResp *)pBuffer;
169 AFSAcquireExcl( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock,
172 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
173 AFS_TRACE_LEVEL_VERBOSE,
174 "AFSEnumerateDirectory Directory Complete FID %08lX-%08lX-%08lX-%08lX Snapshot-DV %08lX:%08lX Current-DV %08lX:%08lX Status %08lX\n",
175 ObjectInfoCB->FileId.Cell,
176 ObjectInfoCB->FileId.Volume,
177 ObjectInfoCB->FileId.Vnode,
178 ObjectInfoCB->FileId.Unique,
179 pDirEnumResponse->SnapshotDataVersion.HighPart,
180 pDirEnumResponse->SnapshotDataVersion.LowPart,
181 pDirEnumResponse->CurrentDataVersion.HighPart,
182 pDirEnumResponse->CurrentDataVersion.LowPart,
185 ObjectInfoCB->DataVersion = pDirEnumResponse->SnapshotDataVersion;
187 if ( pDirEnumResponse->SnapshotDataVersion.QuadPart != pDirEnumResponse->CurrentDataVersion.QuadPart )
190 SetFlag( ObjectInfoCB->Flags, AFS_OBJECT_FLAGS_VERIFY);
192 ObjectInfoCB->DataVersion.QuadPart = (ULONGLONG)-1;
194 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
195 AFS_TRACE_LEVEL_VERBOSE,
196 "AFSEnumerateDirectory Force Verify due to DV change during enumeration FID %08lX-%08lX-%08lX-%08lX\n",
197 ObjectInfoCB->FileId.Cell,
198 ObjectInfoCB->FileId.Volume,
199 ObjectInfoCB->FileId.Vnode,
200 ObjectInfoCB->FileId.Unique);
203 AFSReleaseResource( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock);
208 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
209 AFS_TRACE_LEVEL_VERBOSE,
210 "AFSEnumerateDirectory Failed to enumerate directory FID %08lX-%08lX-%08lX-%08lX AuthGroup %wZ Status %08lX\n",
211 ObjectInfoCB->FileId.Cell,
212 ObjectInfoCB->FileId.Volume,
213 ObjectInfoCB->FileId.Vnode,
214 ObjectInfoCB->FileId.Unique,
222 pDirEnumResponse = (AFSDirEnumResp *)pBuffer;
224 pCurrentDirEntry = (AFSDirEnumEntry *)pDirEnumResponse->Entry;
226 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
227 AFS_TRACE_LEVEL_VERBOSE,
228 "AFSEnumerateDirectory Enumerating FID %08lX-%08lX-%08lX-%08lX Snapshot-DV %08lX:%08lX Current-DV %08lX:%08lX\n",
229 ObjectInfoCB->FileId.Cell,
230 ObjectInfoCB->FileId.Volume,
231 ObjectInfoCB->FileId.Vnode,
232 ObjectInfoCB->FileId.Unique,
233 pDirEnumResponse->SnapshotDataVersion.HighPart,
234 pDirEnumResponse->SnapshotDataVersion.LowPart,
235 pDirEnumResponse->CurrentDataVersion.HighPart,
236 pDirEnumResponse->CurrentDataVersion.LowPart);
239 // Remove the leading header from the processed length
242 ulResultLen -= FIELD_OFFSET( AFSDirEnumResp, Entry);
244 while( ulResultLen > 0)
247 uniDirName.Length = (USHORT)pCurrentDirEntry->FileNameLength;
249 uniDirName.MaximumLength = uniDirName.Length;
251 uniDirName.Buffer = (WCHAR *)((char *)pCurrentDirEntry + pCurrentDirEntry->FileNameOffset);
253 uniTargetName.Length = (USHORT)pCurrentDirEntry->TargetNameLength;
255 uniTargetName.MaximumLength = uniTargetName.Length;
257 uniTargetName.Buffer = (WCHAR *)((char *)pCurrentDirEntry + pCurrentDirEntry->TargetNameOffset);
260 // Be sure we don't have this entry in the case sensitive tree
263 ulCRC = AFSGenerateCRC( &uniDirName,
266 AFSLocateCaseSensitiveDirEntry( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
270 if( pDirNode != NULL)
274 // Check that the FIDs are the same
277 if( AFSIsEqualFID( &pCurrentDirEntry->FileId,
278 &pDirNode->ObjectInformation->FileId))
282 // Duplicate entry, skip it
285 ulEntryLength = QuadAlign( sizeof( AFSDirEnumEntry) +
287 uniTargetName.Length);
289 pCurrentDirEntry = (AFSDirEnumEntry *)((char *)pCurrentDirEntry + ulEntryLength);
291 if( ulResultLen >= ulEntryLength)
293 ulResultLen -= ulEntryLength;
301 // Update the metadata for the entry
304 if( pDirNode->ObjectInformation->DataVersion.QuadPart != pCurrentDirEntry->DataVersion.QuadPart)
308 AFSObjectInfoCB *pObjectInfo = pDirNode->ObjectInformation;
311 // The ObjectReferenceCount will be freed by AFSPerformObjectInvalidate
314 lCount = AFSObjectInfoIncrement( pObjectInfo);
316 AFSPerformObjectInvalidate( pObjectInfo,
317 AFS_INVALIDATE_DATA_VERSION);
322 AFSUpdateMetaData( pDirNode,
332 // Need to tear down this entry and rebuild it below
335 if( pDirNode->OpenReferenceCount == 0)
338 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
339 AFS_TRACE_LEVEL_VERBOSE,
340 "AFSEnumerateDirectory Different FIDs - Deleting DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
342 &pDirNode->NameInformation.FileName,
343 pDirNode->ObjectInformation->FileId.Cell,
344 pDirNode->ObjectInformation->FileId.Volume,
345 pDirNode->ObjectInformation->FileId.Vnode,
346 pDirNode->ObjectInformation->FileId.Unique,
347 pCurrentDirEntry->FileId.Cell,
348 pCurrentDirEntry->FileId.Volume,
349 pCurrentDirEntry->FileId.Vnode,
350 pCurrentDirEntry->FileId.Unique);
352 AFSDeleteDirEntry( ObjectInfoCB,
358 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_DELETED);
360 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
361 AFS_TRACE_LEVEL_VERBOSE,
362 "AFSEnumerateDirectory Different FIDs - Removing DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
364 &pDirNode->NameInformation.FileName,
365 pDirNode->ObjectInformation->FileId.Cell,
366 pDirNode->ObjectInformation->FileId.Volume,
367 pDirNode->ObjectInformation->FileId.Vnode,
368 pDirNode->ObjectInformation->FileId.Unique,
369 pCurrentDirEntry->FileId.Cell,
370 pCurrentDirEntry->FileId.Volume,
371 pCurrentDirEntry->FileId.Vnode,
372 pCurrentDirEntry->FileId.Unique);
374 AFSRemoveNameEntry( ObjectInfoCB,
382 pDirNode = AFSInitDirEntry( ObjectInfoCB,
386 (ULONG)InterlockedIncrement( &ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.ContentIndex));
388 if( pDirNode == NULL)
391 ntStatus = STATUS_INSUFFICIENT_RESOURCES;
396 AFSUpdateMetaData( pDirNode,
399 if( pDirNode->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY)
402 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
403 AFS_TRACE_LEVEL_VERBOSE,
404 "AFSEnumerateDirectory Setting VERIFY on entry %wZ for FID %08lX-%08lX-%08lX-%08lX\n",
406 pDirNode->ObjectInformation->FileId.Cell,
407 pDirNode->ObjectInformation->FileId.Volume,
408 pDirNode->ObjectInformation->FileId.Vnode,
409 pDirNode->ObjectInformation->FileId.Unique);
411 AFSAcquireExcl( pDirNode->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
414 SetFlag( pDirNode->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
416 pDirNode->ObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
418 AFSReleaseResource( pDirNode->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
422 // Set up the entry length
425 ulEntryLength = QuadAlign( sizeof( AFSDirEnumEntry) +
426 pCurrentDirEntry->FileNameLength +
427 pCurrentDirEntry->TargetNameLength);
430 // Init the short name if we have one
433 if( !BooleanFlagOn( pDevExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
434 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)));
484 // No short name or short names are disabled
487 pDirNode->Type.Data.ShortNameTreeEntry.HashIndex = 0;
491 // Insert the node into the name tree
494 if( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead == NULL)
497 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = pDirNode;
499 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
500 AFS_TRACE_LEVEL_VERBOSE,
501 "AFSEnumerateDirectory Insert DE %p to head of case sensitive tree for %wZ\n",
503 &pDirNode->NameInformation.FileName);
508 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
509 AFS_TRACE_LEVEL_VERBOSE,
510 "AFSEnumerateDirectory Insert DE %p to case sensitive tree for %wZ\n",
512 &pDirNode->NameInformation.FileName);
514 if( !NT_SUCCESS( AFSInsertCaseSensitiveDirEntry( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
519 // Delete this dir entry and continue on
522 AFSDeleteDirEntry( ObjectInfoCB,
525 pCurrentDirEntry = (AFSDirEnumEntry *)((char *)pCurrentDirEntry + ulEntryLength);
527 if( ulResultLen >= ulEntryLength)
529 ulResultLen -= ulEntryLength;
540 ClearFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
542 if( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead == NULL)
545 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
546 AFS_TRACE_LEVEL_VERBOSE,
547 "AFSEnumerateDirectory Insert DE %p to head of case insensitive tree for %wZ\n",
549 &pDirNode->NameInformation.FileName);
551 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = pDirNode;
553 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
558 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
559 AFS_TRACE_LEVEL_VERBOSE,
560 "AFSEnumerateDirectory Insert DE %p to case insensitive tree for %wZ\n",
562 &pDirNode->NameInformation.FileName);
564 AFSInsertCaseInsensitiveDirEntry( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
568 if( ObjectInfoCB->Specific.Directory.DirectoryNodeListHead == NULL)
571 ObjectInfoCB->Specific.Directory.DirectoryNodeListHead = pDirNode;
576 ObjectInfoCB->Specific.Directory.DirectoryNodeListTail->ListEntry.fLink = pDirNode;
578 pDirNode->ListEntry.bLink = ObjectInfoCB->Specific.Directory.DirectoryNodeListTail;
581 ObjectInfoCB->Specific.Directory.DirectoryNodeListTail = pDirNode;
583 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST);
585 InterlockedIncrement( &ObjectInfoCB->Specific.Directory.DirectoryNodeCount);
587 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
588 AFS_TRACE_LEVEL_VERBOSE,
589 "AFSEnumerateDirectory Adding entry %wZ Inc Count %d to parent FID %08lX-%08lX-%08lX-%08lX\n",
590 &pDirNode->NameInformation.FileName,
591 ObjectInfoCB->Specific.Directory.DirectoryNodeCount,
592 ObjectInfoCB->FileId.Cell,
593 ObjectInfoCB->FileId.Volume,
594 ObjectInfoCB->FileId.Vnode,
595 ObjectInfoCB->FileId.Unique);
597 if( pDirNode->Type.Data.ShortNameTreeEntry.HashIndex != 0)
601 // Insert the short name entry if we have a valid short name
604 if( ObjectInfoCB->Specific.Directory.ShortNameTree == NULL)
607 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
608 AFS_TRACE_LEVEL_VERBOSE,
609 "AFSEnumerateDirectory Insert DE %p to head of shortname tree for %wZ\n",
611 &pDirNode->NameInformation.FileName);
613 ObjectInfoCB->Specific.Directory.ShortNameTree = pDirNode;
615 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
620 if( NT_SUCCESS( AFSInsertShortNameDirEntry( ObjectInfoCB->Specific.Directory.ShortNameTree,
623 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
625 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
626 AFS_TRACE_LEVEL_VERBOSE,
627 "AFSEnumerateDirectory Insert DE %p to shortname tree for %wZ\n",
629 &pDirNode->NameInformation.FileName);
638 pCurrentDirEntry = (AFSDirEnumEntry *)((char *)pCurrentDirEntry + ulEntryLength);
640 if( ulResultLen >= ulEntryLength)
642 ulResultLen -= ulEntryLength;
650 ulResultLen = AFS_DIR_ENUM_BUFFER_LEN;
653 // Reset the information in the request buffer since it got trampled
657 pDirQueryCB->EnumHandle = pDirEnumResponse->EnumHandle;
659 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
660 AFS_TRACE_LEVEL_VERBOSE,
661 "AFSEnumerateDirectory EnumHandle %08lX\n",
662 pDirQueryCB->EnumHandle);
674 AFSExFreePoolWithTag( pBuffer, AFS_DIR_BUFFER_TAG);
678 // If the processing failed then we should reset the directory content in the event
679 // it is re-enumerated
682 if( !NT_SUCCESS( ntStatus))
685 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
686 AFS_TRACE_LEVEL_ERROR,
687 "AFSEnumerateDirectory Resetting content for FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
688 ObjectInfoCB->FileId.Cell,
689 ObjectInfoCB->FileId.Volume,
690 ObjectInfoCB->FileId.Vnode,
691 ObjectInfoCB->FileId.Unique,
694 AFSResetDirectoryContent( ObjectInfoCB);
702 AFSEnumerateDirectoryNoResponse( IN GUID *AuthGroup,
703 IN AFSFileID *FileId)
706 NTSTATUS ntStatus = STATUS_SUCCESS;
707 AFSDirQueryCB stDirQueryCB;
708 ULONG ulRequestFlags = 0;
714 // Use the payload buffer for information we will pass to the service
717 stDirQueryCB.EnumHandle = 0;
719 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_DIR_ENUM,
724 (void *)&stDirQueryCB,
725 sizeof( AFSDirQueryCB),
729 if( ntStatus != STATUS_SUCCESS)
732 if( ntStatus == STATUS_NO_MORE_FILES ||
733 ntStatus == STATUS_NO_MORE_ENTRIES)
736 ntStatus = STATUS_SUCCESS;
741 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
742 AFS_TRACE_LEVEL_ERROR,
743 "AFSEnumerateDirectoryNoResponse Failed to enumerate directory Status %08lX\n",
753 AFSVerifyDirectoryContent( IN AFSObjectInfoCB *ObjectInfoCB,
757 NTSTATUS ntStatus = STATUS_SUCCESS;
758 void *pBuffer = NULL;
759 ULONG ulResultLen = 0;
760 AFSDirQueryCB *pDirQueryCB;
761 AFSDirEnumEntry *pCurrentDirEntry = NULL;
762 AFSDirectoryCB *pDirNode = NULL;
763 ULONG ulEntryLength = 0;
764 AFSDirEnumResp *pDirEnumResponse = NULL;
765 UNICODE_STRING uniDirName, uniTargetName;
766 ULONG ulRequestFlags = AFS_REQUEST_FLAG_SYNCHRONOUS | AFS_REQUEST_FLAG_FAST_REQUEST;
768 AFSObjectInfoCB *pObjectInfo = NULL;
769 ULONGLONG ullIndex = 0;
770 UNICODE_STRING uniGUID;
772 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
777 ASSERT( ExIsResourceAcquiredExclusiveLite( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock));
780 uniGUID.MaximumLength = 0;
781 uniGUID.Buffer = NULL;
783 if( AuthGroup != NULL)
785 RtlStringFromGUID( *AuthGroup,
789 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
790 AFS_TRACE_LEVEL_VERBOSE,
791 "AFSVerifyDirectoryContent Verifying content for FID %08lX-%08lX-%08lX-%08lX AuthGroup %wZ\n",
792 ObjectInfoCB->FileId.Cell,
793 ObjectInfoCB->FileId.Volume,
794 ObjectInfoCB->FileId.Vnode,
795 ObjectInfoCB->FileId.Unique,
798 if( AuthGroup != NULL)
800 RtlFreeUnicodeString( &uniGUID);
804 // Initialize the directory enumeration buffer for the directory
807 pBuffer = AFSExAllocatePoolWithTag( PagedPool,
808 AFS_DIR_ENUM_BUFFER_LEN,
814 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
817 RtlZeroMemory( pBuffer,
818 AFS_DIR_ENUM_BUFFER_LEN);
820 ulResultLen = AFS_DIR_ENUM_BUFFER_LEN;
823 // Use the payload buffer for information we will pass to the service
826 pDirQueryCB = (AFSDirQueryCB *)pBuffer;
828 pDirQueryCB->EnumHandle = 0;
831 // Loop on the information
838 // If the enumeration handle is -1 then we are done
841 if( ((ULONG)-1) == pDirQueryCB->EnumHandle )
844 ntStatus = STATUS_NO_MORE_ENTRIES;
850 // Go and retrieve the directory contents
853 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_DIR_ENUM,
857 &ObjectInfoCB->FileId,
859 sizeof( AFSDirQueryCB),
864 if( ntStatus != STATUS_SUCCESS ||
868 if( ntStatus == STATUS_NO_MORE_FILES ||
869 ntStatus == STATUS_NO_MORE_ENTRIES)
872 pDirEnumResponse = (AFSDirEnumResp *)pBuffer;
874 AFSAcquireExcl( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock,
877 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
878 AFS_TRACE_LEVEL_VERBOSE,
879 "AFSVerifyDirectoryContent Directory Complete FID %08lX-%08lX-%08lX-%08lX Snapshot-DV %08lX:%08lX Current-DV %08lX:%08lX Status %08lX\n",
880 ObjectInfoCB->FileId.Cell,
881 ObjectInfoCB->FileId.Volume,
882 ObjectInfoCB->FileId.Vnode,
883 ObjectInfoCB->FileId.Unique,
884 pDirEnumResponse->SnapshotDataVersion.HighPart,
885 pDirEnumResponse->SnapshotDataVersion.LowPart,
886 pDirEnumResponse->CurrentDataVersion.HighPart,
887 pDirEnumResponse->CurrentDataVersion.LowPart,
890 ntStatus = STATUS_SUCCESS;
892 if ( pDirEnumResponse->SnapshotDataVersion.QuadPart != pDirEnumResponse->CurrentDataVersion.QuadPart )
895 SetFlag( ObjectInfoCB->Flags, AFS_OBJECT_FLAGS_VERIFY);
897 ObjectInfoCB->DataVersion.QuadPart = (ULONGLONG)-1;
899 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
900 AFS_TRACE_LEVEL_VERBOSE,
901 "AFSVerifyDirectoryContent Force Verify due to DV change during enumeration FID %08lX-%08lX-%08lX-%08lX\n",
902 ObjectInfoCB->FileId.Cell,
903 ObjectInfoCB->FileId.Volume,
904 ObjectInfoCB->FileId.Vnode,
905 ObjectInfoCB->FileId.Unique);
910 ObjectInfoCB->DataVersion = pDirEnumResponse->SnapshotDataVersion;
913 AFSReleaseResource( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock);
918 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
919 AFS_TRACE_LEVEL_ERROR,
920 "AFSVerifyDirectoryContent Failed to enumerate directory FID %08lX-%08lX-%08lX-%08lX AuthGroup %wZ Status %08lX\n",
921 ObjectInfoCB->FileId.Cell,
922 ObjectInfoCB->FileId.Volume,
923 ObjectInfoCB->FileId.Vnode,
924 ObjectInfoCB->FileId.Unique,
932 pDirEnumResponse = (AFSDirEnumResp *)pBuffer;
934 pCurrentDirEntry = (AFSDirEnumEntry *)pDirEnumResponse->Entry;
936 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
937 AFS_TRACE_LEVEL_VERBOSE,
938 "AFSVerifyDirectoryContent EnumResponse FID %08lX-%08lX-%08lX-%08lX Snapshot-DV %08lX:%08lX Current-DV %08lX:%08lX\n",
939 ObjectInfoCB->FileId.Cell,
940 ObjectInfoCB->FileId.Volume,
941 ObjectInfoCB->FileId.Vnode,
942 ObjectInfoCB->FileId.Unique,
943 pDirEnumResponse->SnapshotDataVersion.HighPart,
944 pDirEnumResponse->SnapshotDataVersion.LowPart,
945 pDirEnumResponse->CurrentDataVersion.HighPart,
946 pDirEnumResponse->CurrentDataVersion.LowPart);
949 // Remove the leading header from the processed length
952 ulResultLen -= FIELD_OFFSET( AFSDirEnumResp, Entry);
954 while( ulResultLen > 0)
957 uniDirName.Length = (USHORT)pCurrentDirEntry->FileNameLength;
959 uniDirName.MaximumLength = uniDirName.Length;
961 uniDirName.Buffer = (WCHAR *)((char *)pCurrentDirEntry + pCurrentDirEntry->FileNameOffset);
963 uniTargetName.Length = (USHORT)pCurrentDirEntry->TargetNameLength;
965 uniTargetName.MaximumLength = uniTargetName.Length;
967 uniTargetName.Buffer = (WCHAR *)((char *)pCurrentDirEntry + pCurrentDirEntry->TargetNameOffset);
970 // Does this entry already exist in the directory?
973 ulCRC = AFSGenerateCRC( &uniDirName,
976 AFSLocateCaseSensitiveDirEntry( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
982 // Set up the entry length
985 ulEntryLength = QuadAlign( sizeof( AFSDirEnumEntry) +
986 pCurrentDirEntry->FileNameLength +
987 pCurrentDirEntry->TargetNameLength);
990 AFSIsEqualFID( &pCurrentDirEntry->FileId,
991 &pDirNode->ObjectInformation->FileId))
995 // Found matching directory entry by name and FileID
998 AFSAcquireShared( ObjectInfoCB->VolumeCB->ObjectInfoTree.TreeLock,
1001 ullIndex = AFSCreateLowIndex( &pCurrentDirEntry->FileId);
1003 ntStatus = AFSLocateHashEntry( ObjectInfoCB->VolumeCB->ObjectInfoTree.TreeHead,
1005 (AFSBTreeEntry **)&pObjectInfo);
1007 AFSReleaseResource( ObjectInfoCB->VolumeCB->ObjectInfoTree.TreeLock);
1009 if( NT_SUCCESS( ntStatus) &&
1010 pObjectInfo != NULL)
1014 // Indicate this is a valid entry
1017 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID);
1019 if( pCurrentDirEntry->ShortNameLength > 0 &&
1020 pDirNode->NameInformation.ShortNameLength > 0)
1022 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1023 AFS_TRACE_LEVEL_VERBOSE,
1024 "AFSVerifyDirectoryContent Verified entry %wZ (%wZ) parent FID %08lX-%08lX-%08lX-%08lX old short name %S New short name %S\n",
1026 &pDirNode->NameInformation.FileName,
1027 ObjectInfoCB->FileId.Cell,
1028 ObjectInfoCB->FileId.Volume,
1029 ObjectInfoCB->FileId.Vnode,
1030 ObjectInfoCB->FileId.Unique,
1031 pDirNode->NameInformation.ShortName,
1032 pCurrentDirEntry->ShortName);
1034 else if( pCurrentDirEntry->ShortNameLength == 0 &&
1035 pDirNode->NameInformation.ShortNameLength > 0)
1038 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1039 AFS_TRACE_LEVEL_VERBOSE,
1040 "AFSVerifyDirectoryContent Verified entry %wZ (%wZ) parent FID %08lX-%08lX-%08lX-%08lX old short name %S New short name NULL\n",
1042 &pDirNode->NameInformation.FileName,
1043 ObjectInfoCB->FileId.Cell,
1044 ObjectInfoCB->FileId.Volume,
1045 ObjectInfoCB->FileId.Vnode,
1046 ObjectInfoCB->FileId.Unique,
1047 pDirNode->NameInformation.ShortName);
1049 else if( pCurrentDirEntry->ShortNameLength > 0 &&
1050 pDirNode->NameInformation.ShortNameLength == 0)
1052 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1053 AFS_TRACE_LEVEL_VERBOSE,
1054 "AFSVerifyDirectoryContent Verified entry %wZ (%wZ) parent FID %08lX-%08lX-%08lX-%08lX old short name NULL New short name %S\n",
1056 &pDirNode->NameInformation.FileName,
1057 ObjectInfoCB->FileId.Cell,
1058 ObjectInfoCB->FileId.Volume,
1059 ObjectInfoCB->FileId.Vnode,
1060 ObjectInfoCB->FileId.Unique,
1061 pCurrentDirEntry->ShortName);
1065 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1066 AFS_TRACE_LEVEL_VERBOSE,
1067 "AFSVerifyDirectoryContent Verified entry %wZ (%wZ) parent FID %08lX-%08lX-%08lX-%08lX old short name NULL New short name NULL\n",
1069 &pDirNode->NameInformation.FileName,
1070 ObjectInfoCB->FileId.Cell,
1071 ObjectInfoCB->FileId.Volume,
1072 ObjectInfoCB->FileId.Vnode,
1073 ObjectInfoCB->FileId.Unique);
1077 // Update the metadata for the entry
1080 if( pObjectInfo->DataVersion.QuadPart != pCurrentDirEntry->DataVersion.QuadPart)
1084 // The ObjectReferenceCount will be freed by AFSPerformObjectInvalidate
1085 // if successfully queued. Cannot call AFSPerformObjectInvalidate directly
1086 // because ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock is
1087 // held during the sequence AFSVerifyEntry->AFSValidateDirectoryCache->
1088 // AFSVerifyDirectoryContent and AFSPerformObjectInvalidate requires the
1089 // Fcb->NPFcb->Resource which must be held prior to the TreeLock in the
1093 lCount = AFSObjectInfoIncrement( pObjectInfo);
1095 if ( !NT_SUCCESS( AFSQueueInvalidateObject( pObjectInfo,
1096 AFS_INVALIDATE_DATA_VERSION)))
1099 lCount = AFSObjectInfoDecrement( pObjectInfo);
1105 AFSUpdateMetaData( pDirNode,
1113 pCurrentDirEntry = (AFSDirEnumEntry *)((char *)pCurrentDirEntry + ulEntryLength);
1115 if( ulResultLen >= ulEntryLength)
1117 ulResultLen -= ulEntryLength;
1131 // File name matches but FileID does not.
1134 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1135 AFS_TRACE_LEVEL_VERBOSE,
1136 "AFSVerifyDirectoryContent Processing dir entry %p %wZ with different FID, same name in parent FID %08lX-%08lX-%08lX-%08lX\n",
1138 &pDirNode->NameInformation.FileName,
1139 ObjectInfoCB->FileId.Cell,
1140 ObjectInfoCB->FileId.Volume,
1141 ObjectInfoCB->FileId.Vnode,
1142 ObjectInfoCB->FileId.Unique);
1145 // Need to tear down this entry and rebuild it below
1148 if( pDirNode->OpenReferenceCount == 0)
1151 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1152 AFS_TRACE_LEVEL_VERBOSE,
1153 "AFSVerifyDirectoryContent Different FIDs - Deleting DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
1155 &pDirNode->NameInformation.FileName,
1156 pDirNode->ObjectInformation->FileId.Cell,
1157 pDirNode->ObjectInformation->FileId.Volume,
1158 pDirNode->ObjectInformation->FileId.Vnode,
1159 pDirNode->ObjectInformation->FileId.Unique,
1160 pCurrentDirEntry->FileId.Cell,
1161 pCurrentDirEntry->FileId.Volume,
1162 pCurrentDirEntry->FileId.Vnode,
1163 pCurrentDirEntry->FileId.Unique);
1165 AFSDeleteDirEntry( ObjectInfoCB,
1171 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_DELETED);
1173 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1174 AFS_TRACE_LEVEL_WARNING,
1175 "AFSVerifyDirectoryContent Different FIDs - removing DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
1177 &pDirNode->NameInformation.FileName,
1178 pDirNode->ObjectInformation->FileId.Cell,
1179 pDirNode->ObjectInformation->FileId.Volume,
1180 pDirNode->ObjectInformation->FileId.Vnode,
1181 pDirNode->ObjectInformation->FileId.Unique,
1182 pCurrentDirEntry->FileId.Cell,
1183 pCurrentDirEntry->FileId.Volume,
1184 pCurrentDirEntry->FileId.Vnode,
1185 pCurrentDirEntry->FileId.Unique);
1187 AFSRemoveNameEntry( ObjectInfoCB,
1194 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1195 AFS_TRACE_LEVEL_VERBOSE,
1196 "AFSVerifyDirectoryContent New entry %wZ for parent FID %08lX-%08lX-%08lX-%08lX\n",
1198 ObjectInfoCB->FileId.Cell,
1199 ObjectInfoCB->FileId.Volume,
1200 ObjectInfoCB->FileId.Vnode,
1201 ObjectInfoCB->FileId.Unique);
1204 pDirNode = AFSInitDirEntry( ObjectInfoCB,
1208 (ULONG)InterlockedIncrement( &ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.ContentIndex));
1210 if( pDirNode == NULL)
1213 ntStatus = STATUS_INSUFFICIENT_RESOURCES;
1218 AFSUpdateMetaData( pDirNode,
1221 if( pDirNode->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY)
1224 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1225 AFS_TRACE_LEVEL_VERBOSE,
1226 "AFSVerifyDirectoryContent Setting VERIFY on entry %wZ for FID %08lX-%08lX-%08lX-%08lX\n",
1228 pDirNode->ObjectInformation->FileId.Cell,
1229 pDirNode->ObjectInformation->FileId.Volume,
1230 pDirNode->ObjectInformation->FileId.Vnode,
1231 pDirNode->ObjectInformation->FileId.Unique);
1233 AFSAcquireExcl( pDirNode->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
1236 SetFlag( pDirNode->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
1238 pDirNode->ObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
1240 AFSReleaseResource( pDirNode->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1244 // Init the short name if we have one
1247 if( !BooleanFlagOn( pDevExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
1248 pCurrentDirEntry->ShortNameLength > 0)
1251 UNICODE_STRING uniShortName;
1253 pDirNode->NameInformation.ShortNameLength = pCurrentDirEntry->ShortNameLength;
1255 RtlCopyMemory( pDirNode->NameInformation.ShortName,
1256 pCurrentDirEntry->ShortName,
1257 pDirNode->NameInformation.ShortNameLength);
1260 // Generate the short name index
1263 uniShortName.Length = pDirNode->NameInformation.ShortNameLength;
1264 uniShortName.MaximumLength = uniShortName.Length;
1265 uniShortName.Buffer = pDirNode->NameInformation.ShortName;
1267 if( !RtlIsNameLegalDOS8Dot3( &pDirNode->NameInformation.FileName,
1272 pDirNode->Type.Data.ShortNameTreeEntry.HashIndex = AFSGenerateCRC( &uniShortName,
1275 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1276 AFS_TRACE_LEVEL_VERBOSE,
1277 "AFSVerifyDirectoryContent Initialized short name %wZ for DE %p for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1280 &pDirNode->NameInformation.FileName,
1281 pCurrentDirEntry->FileId.Cell,
1282 pCurrentDirEntry->FileId.Volume,
1283 pCurrentDirEntry->FileId.Vnode,
1284 pCurrentDirEntry->FileId.Unique);
1288 pDirNode->NameInformation.ShortNameLength = 0;
1290 RtlZeroMemory( pDirNode->NameInformation.ShortName,
1291 (12 * sizeof( WCHAR)));
1298 // No short name or short names have been disabled
1301 pDirNode->Type.Data.ShortNameTreeEntry.HashIndex = 0;
1305 // Insert the node into the name tree
1308 ASSERT( ExIsResourceAcquiredExclusiveLite( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock));
1310 if( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead == NULL)
1313 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = pDirNode;
1315 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1316 AFS_TRACE_LEVEL_VERBOSE,
1317 "AFSVerifyDirectoryContent Insert DE %p to head of case sensitive tree for %wZ\n",
1319 &pDirNode->NameInformation.FileName);
1324 if( !NT_SUCCESS( AFSInsertCaseSensitiveDirEntry( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
1327 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1328 AFS_TRACE_LEVEL_VERBOSE,
1329 "AFSVerifyDirectoryContent Failed to insert DE %p to case sensitive tree for %wZ\n",
1331 &pDirNode->NameInformation.FileName);
1334 // Delete this dir entry and continue on
1337 AFSDeleteDirEntry( ObjectInfoCB,
1340 pCurrentDirEntry = (AFSDirEnumEntry *)((char *)pCurrentDirEntry + ulEntryLength);
1342 if( ulResultLen >= ulEntryLength)
1344 ulResultLen -= ulEntryLength;
1355 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1356 AFS_TRACE_LEVEL_VERBOSE,
1357 "AFSVerifyDirectoryContent Insert DE %p to case sensitive tree for %wZ\n",
1359 &pDirNode->NameInformation.FileName);
1363 ClearFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
1365 if( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead == NULL)
1368 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = pDirNode;
1370 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
1372 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1373 AFS_TRACE_LEVEL_VERBOSE,
1374 "AFSVerifyDirectoryContent Insert DE %p to head of case insensitive tree for %wZ\n",
1376 &pDirNode->NameInformation.FileName);
1381 AFSInsertCaseInsensitiveDirEntry( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
1384 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1385 AFS_TRACE_LEVEL_VERBOSE,
1386 "AFSVerifyDirectoryContent Insert DE %p to case insensitive tree for %wZ\n",
1388 &pDirNode->NameInformation.FileName);
1391 if( ObjectInfoCB->Specific.Directory.DirectoryNodeListHead == NULL)
1394 ObjectInfoCB->Specific.Directory.DirectoryNodeListHead = pDirNode;
1399 (ObjectInfoCB->Specific.Directory.DirectoryNodeListTail)->ListEntry.fLink = pDirNode;
1401 pDirNode->ListEntry.bLink = ObjectInfoCB->Specific.Directory.DirectoryNodeListTail;
1404 ObjectInfoCB->Specific.Directory.DirectoryNodeListTail = pDirNode;
1406 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST);
1408 InterlockedIncrement( &ObjectInfoCB->Specific.Directory.DirectoryNodeCount);
1410 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
1411 AFS_TRACE_LEVEL_VERBOSE,
1412 "AFSVerifyDirectoryContent Adding entry %wZ Inc Count %d to parent FID %08lX-%08lX-%08lX-%08lX\n",
1413 &pDirNode->NameInformation.FileName,
1414 ObjectInfoCB->Specific.Directory.DirectoryNodeCount,
1415 ObjectInfoCB->FileId.Cell,
1416 ObjectInfoCB->FileId.Volume,
1417 ObjectInfoCB->FileId.Vnode,
1418 ObjectInfoCB->FileId.Unique);
1420 if( pDirNode->Type.Data.ShortNameTreeEntry.HashIndex != 0)
1424 // Insert the short name entry if we have a valid short name
1427 if( ObjectInfoCB->Specific.Directory.ShortNameTree == NULL)
1430 ObjectInfoCB->Specific.Directory.ShortNameTree = pDirNode;
1432 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1433 AFS_TRACE_LEVEL_VERBOSE,
1434 "AFSVerifyDirectoryContent Insert DE %p to head of shortname tree for %wZ\n",
1436 &pDirNode->NameInformation.FileName);
1438 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
1443 if( !NT_SUCCESS( AFSInsertShortNameDirEntry( ObjectInfoCB->Specific.Directory.ShortNameTree,
1446 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1447 AFS_TRACE_LEVEL_VERBOSE,
1448 "AFSVerifyDirectoryContent Failed to insert DE %p (%08lX) to shortname tree for %wZ\n",
1450 pDirNode->Type.Data.ShortNameTreeEntry.HashIndex,
1451 &pDirNode->NameInformation.FileName);
1455 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
1457 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1458 AFS_TRACE_LEVEL_VERBOSE,
1459 "AFSVerifyDirectoryContent Insert DE %p to shortname tree for %wZ\n",
1461 &pDirNode->NameInformation.FileName);
1466 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID);
1472 pCurrentDirEntry = (AFSDirEnumEntry *)((char *)pCurrentDirEntry + ulEntryLength);
1474 if( ulResultLen >= ulEntryLength)
1476 ulResultLen -= ulEntryLength;
1484 ulResultLen = AFS_DIR_ENUM_BUFFER_LEN;
1487 // Reset the information in the request buffer since it got trampled
1491 pDirQueryCB->EnumHandle = pDirEnumResponse->EnumHandle;
1500 if( pBuffer != NULL)
1503 AFSExFreePoolWithTag( pBuffer, AFS_DIR_BUFFER_TAG);
1511 AFSNotifyFileCreate( IN GUID *AuthGroup,
1512 IN AFSObjectInfoCB *ParentObjectInfo,
1513 IN PLARGE_INTEGER FileSize,
1514 IN ULONG FileAttributes,
1515 IN UNICODE_STRING *FileName,
1516 OUT AFSDirectoryCB **DirNode)
1519 NTSTATUS ntStatus = STATUS_SUCCESS;
1520 AFSFileCreateCB stCreateCB;
1521 AFSFileCreateResultCB *pResultCB = NULL;
1522 ULONG ulResultLen = 0;
1523 UNICODE_STRING uniTargetName;
1524 AFSDirectoryCB *pDirNode = NULL;
1526 LARGE_INTEGER liOldDataVersion;
1527 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
1533 // Init the control block for the request
1536 RtlZeroMemory( &stCreateCB,
1537 sizeof( AFSFileCreateCB));
1539 stCreateCB.ParentId = ParentObjectInfo->FileId;
1541 stCreateCB.AllocationSize = *FileSize;
1543 stCreateCB.FileAttributes = FileAttributes;
1545 stCreateCB.EaSize = 0;
1547 liOldDataVersion = ParentObjectInfo->DataVersion;
1550 // Allocate our return buffer
1553 pResultCB = (AFSFileCreateResultCB *)AFSExAllocatePoolWithTag( PagedPool,
1555 AFS_GENERIC_MEMORY_1_TAG);
1557 if( pResultCB == NULL)
1560 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1563 RtlZeroMemory( pResultCB,
1566 ulResultLen = PAGE_SIZE;
1569 // Send the call to the service
1572 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_CREATE_FILE,
1573 AFS_REQUEST_FLAG_SYNCHRONOUS | AFS_REQUEST_FLAG_HOLD_FID,
1578 sizeof( AFSFileCreateCB),
1582 if( ntStatus != STATUS_SUCCESS)
1585 if( NT_SUCCESS( ntStatus))
1588 ntStatus = STATUS_DEVICE_NOT_READY;
1591 try_return( ntStatus);
1595 // We may have raced with an invalidation call and a subsequent re-enumeration of this parent
1596 // and though we created the node, it is already in our list. If this is the case then
1597 // look up the entry rather than create a new entry
1598 // The check is to ensure the DV has been modified
1601 AFSAcquireExcl( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
1604 if( ParentObjectInfo->DataVersion.QuadPart != pResultCB->ParentDataVersion.QuadPart - 1)
1607 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1608 AFS_TRACE_LEVEL_WARNING,
1609 "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",
1611 ParentObjectInfo->FileId.Cell,
1612 ParentObjectInfo->FileId.Volume,
1613 ParentObjectInfo->FileId.Vnode,
1614 ParentObjectInfo->FileId.Unique,
1615 ParentObjectInfo->DataVersion.HighPart,
1616 ParentObjectInfo->DataVersion.LowPart,
1617 pResultCB->ParentDataVersion.HighPart,
1618 pResultCB->ParentDataVersion.LowPart);
1621 // We raced so go and lookup the directory entry in the parent
1624 ulCRC = AFSGenerateCRC( FileName,
1627 AFSLocateCaseSensitiveDirEntry( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
1631 if( pDirNode != NULL)
1634 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1635 AFS_TRACE_LEVEL_VERBOSE,
1636 "AFSNotifyFileCreate Located dir entry %p for file %wZ\n",
1640 if ( AFSIsEqualFID( &pDirNode->ObjectInformation->FileId,
1641 &pResultCB->DirEnum.FileId))
1644 InterlockedIncrement( &pDirNode->OpenReferenceCount);
1646 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1647 AFS_TRACE_LEVEL_VERBOSE,
1648 "AFSNotifyFileCreate Increment count on %wZ DE %p Cnt %d\n",
1649 &pDirNode->NameInformation.FileName,
1651 pDirNode->OpenReferenceCount);
1653 *DirNode = pDirNode;
1655 AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
1657 try_return( ntStatus = STATUS_REPARSE);
1663 // We found an entry that matches the desired name but it is not the
1664 // same as the one that was created for us by the file server.
1667 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1668 AFS_TRACE_LEVEL_ERROR,
1669 "AFSNotifyFileCreate Found matching name entry %wZ DE %p FID %08lX-%08lX-%08lX-%08lX != FID %08lX-%08lX-%08lX-%08lX\n",
1672 pDirNode->ObjectInformation->FileId.Cell,
1673 pDirNode->ObjectInformation->FileId.Volume,
1674 pDirNode->ObjectInformation->FileId.Vnode,
1675 pDirNode->ObjectInformation->FileId.Unique,
1676 pResultCB->DirEnum.FileId.Cell,
1677 pResultCB->DirEnum.FileId.Volume,
1678 pResultCB->DirEnum.FileId.Vnode,
1679 pResultCB->DirEnum.FileId.Unique);
1681 if( pDirNode->OpenReferenceCount == 0)
1684 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1685 AFS_TRACE_LEVEL_VERBOSE,
1686 "AFSNotifyFileCreate Different FIDs - Deleting DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
1688 &pDirNode->NameInformation.FileName,
1689 pDirNode->ObjectInformation->FileId.Cell,
1690 pDirNode->ObjectInformation->FileId.Volume,
1691 pDirNode->ObjectInformation->FileId.Vnode,
1692 pDirNode->ObjectInformation->FileId.Unique,
1693 pResultCB->DirEnum.FileId.Cell,
1694 pResultCB->DirEnum.FileId.Volume,
1695 pResultCB->DirEnum.FileId.Vnode,
1696 pResultCB->DirEnum.FileId.Unique);
1698 AFSDeleteDirEntry( ParentObjectInfo,
1704 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_DELETED);
1706 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1707 AFS_TRACE_LEVEL_VERBOSE,
1708 "AFSNotifyFileCreate Different FIDs - Removing DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
1710 &pDirNode->NameInformation.FileName,
1711 pDirNode->ObjectInformation->FileId.Cell,
1712 pDirNode->ObjectInformation->FileId.Volume,
1713 pDirNode->ObjectInformation->FileId.Vnode,
1714 pDirNode->ObjectInformation->FileId.Unique,
1715 pResultCB->DirEnum.FileId.Cell,
1716 pResultCB->DirEnum.FileId.Volume,
1717 pResultCB->DirEnum.FileId.Vnode,
1718 pResultCB->DirEnum.FileId.Unique);
1720 AFSRemoveNameEntry( ParentObjectInfo,
1729 // We are unsure of our current data so set the verify flag. It may already be set
1730 // but no big deal to reset it
1733 SetFlag( ParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
1735 ParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
1738 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1739 AFS_TRACE_LEVEL_VERBOSE,
1740 "AFSNotifyFileCreate Creating new entry %wZ\n",
1744 // Initialize the directory entry
1747 uniTargetName.Length = (USHORT)pResultCB->DirEnum.TargetNameLength;
1749 uniTargetName.MaximumLength = uniTargetName.Length;
1751 uniTargetName.Buffer = (WCHAR *)((char *)&pResultCB->DirEnum + pResultCB->DirEnum.TargetNameOffset);
1753 pDirNode = AFSInitDirEntry( ParentObjectInfo,
1756 &pResultCB->DirEnum,
1757 (ULONG)InterlockedIncrement( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.ContentIndex));
1759 if( pDirNode == NULL)
1762 SetFlag( ParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
1764 ParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
1766 AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
1768 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1772 // Init the short name if we have one
1775 if( !BooleanFlagOn( pDevExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
1776 pResultCB->DirEnum.ShortNameLength > 0)
1779 UNICODE_STRING uniShortName;
1781 pDirNode->NameInformation.ShortNameLength = pResultCB->DirEnum.ShortNameLength;
1783 RtlCopyMemory( pDirNode->NameInformation.ShortName,
1784 pResultCB->DirEnum.ShortName,
1785 pDirNode->NameInformation.ShortNameLength);
1788 // Generate the short name index
1791 uniShortName.Length = pDirNode->NameInformation.ShortNameLength;
1792 uniShortName.Buffer = pDirNode->NameInformation.ShortName;
1794 pDirNode->Type.Data.ShortNameTreeEntry.HashIndex = AFSGenerateCRC( &uniShortName,
1797 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1798 AFS_TRACE_LEVEL_VERBOSE,
1799 "AFSNotifyFileCreate Initialized short name %wZ for DE %p for %wZ\n",
1802 &pDirNode->NameInformation.FileName);
1807 // No short name or short names are disabled
1810 pDirNode->Type.Data.ShortNameTreeEntry.HashIndex = 0;
1813 if ( !BooleanFlagOn( ParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY))
1817 // Update the parent data version
1820 ParentObjectInfo->DataVersion = pResultCB->ParentDataVersion;
1822 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1823 AFS_TRACE_LEVEL_VERBOSE,
1824 "AFSNotifyFileCreate entry %wZ ParentFID %08lX-%08lX-%08lX-%08lX Version %08lX:%08lX\n",
1826 ParentObjectInfo->FileId.Cell,
1827 ParentObjectInfo->FileId.Volume,
1828 ParentObjectInfo->FileId.Vnode,
1829 ParentObjectInfo->FileId.Unique,
1830 ParentObjectInfo->DataVersion.QuadPart);
1833 AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
1836 // Return the directory node
1839 *DirNode = pDirNode;
1843 if( pResultCB != NULL)
1846 AFSExFreePoolWithTag( pResultCB, AFS_GENERIC_MEMORY_1_TAG);
1854 AFSUpdateFileInformation( IN AFSFileID *ParentFid,
1855 IN AFSObjectInfoCB *ObjectInfo,
1859 NTSTATUS ntStatus = STATUS_SUCCESS;
1860 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1861 AFSFileUpdateCB stUpdateCB;
1862 ULONG ulResultLen = 0;
1863 AFSFileUpdateResultCB *pUpdateResultCB = NULL;
1869 // Init the control block for the request
1872 RtlZeroMemory( &stUpdateCB,
1873 sizeof( AFSFileUpdateCB));
1875 stUpdateCB.AllocationSize = ObjectInfo->EndOfFile;
1877 stUpdateCB.FileAttributes = ObjectInfo->FileAttributes;
1879 stUpdateCB.EaSize = ObjectInfo->EaSize;
1881 stUpdateCB.ParentId = *ParentFid;
1883 stUpdateCB.LastAccessTime = ObjectInfo->LastAccessTime;
1885 stUpdateCB.CreateTime = ObjectInfo->CreationTime;
1887 stUpdateCB.ChangeTime = ObjectInfo->ChangeTime;
1889 stUpdateCB.LastWriteTime = ObjectInfo->LastWriteTime;
1891 pUpdateResultCB = (AFSFileUpdateResultCB *)AFSExAllocatePoolWithTag( PagedPool,
1893 AFS_UPDATE_RESULT_TAG);
1895 if( pUpdateResultCB == NULL)
1898 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1901 ulResultLen = PAGE_SIZE;
1903 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_UPDATE_FILE,
1904 AFS_REQUEST_FLAG_SYNCHRONOUS,
1907 &ObjectInfo->FileId,
1909 sizeof( AFSFileUpdateCB),
1913 if( ntStatus != STATUS_SUCCESS)
1916 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1917 AFS_TRACE_LEVEL_ERROR,
1918 "AFSUpdateFileInformation failed FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1919 ObjectInfo->FileId.Cell,
1920 ObjectInfo->FileId.Volume,
1921 ObjectInfo->FileId.Vnode,
1922 ObjectInfo->FileId.Unique,
1925 try_return( ntStatus);
1929 // Update the data version
1932 AFSAcquireExcl( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
1935 if ( !BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY))
1938 ObjectInfo->DataVersion = pUpdateResultCB->DirEnum.DataVersion;
1941 AFSReleaseResource( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
1945 if( pUpdateResultCB != NULL)
1948 AFSExFreePoolWithTag( pUpdateResultCB, AFS_UPDATE_RESULT_TAG);
1956 AFSNotifyDelete( IN AFSDirectoryCB *DirectoryCB,
1958 IN BOOLEAN CheckOnly)
1960 NTSTATUS ntStatus = STATUS_SUCCESS;
1961 ULONG ulResultLen = 0;
1962 AFSFileDeleteCB stDelete;
1963 AFSFileDeleteResultCB stDeleteResult;
1964 ULONG ulRequestFlags = AFS_REQUEST_FLAG_SYNCHRONOUS;
1969 stDelete.ParentId = DirectoryCB->ObjectInformation->ParentObjectInformation->FileId;
1971 stDelete.ProcessId = (ULONGLONG)PsGetCurrentProcessId();
1973 ulResultLen = sizeof( AFSFileDeleteResultCB);
1977 ulRequestFlags |= AFS_REQUEST_FLAG_CHECK_ONLY;
1980 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_DELETE_FILE,
1983 &DirectoryCB->NameInformation.FileName,
1984 &DirectoryCB->ObjectInformation->FileId,
1986 sizeof( AFSFileDeleteCB),
1990 if( ntStatus != STATUS_SUCCESS)
1993 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1994 AFS_TRACE_LEVEL_ERROR,
1995 "AFSNotifyDelete failed ParentFID %08lX-%08lX-%08lX-%08lX %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1996 stDelete.ParentId.Cell,
1997 stDelete.ParentId.Volume,
1998 stDelete.ParentId.Vnode,
1999 stDelete.ParentId.Unique,
2000 &DirectoryCB->NameInformation.FileName,
2001 DirectoryCB->ObjectInformation->FileId.Cell,
2002 DirectoryCB->ObjectInformation->FileId.Volume,
2003 DirectoryCB->ObjectInformation->FileId.Vnode,
2004 DirectoryCB->ObjectInformation->FileId.Unique,
2007 try_return( ntStatus);
2010 AFSAcquireExcl( DirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
2017 // Validate the parent data version
2020 if( DirectoryCB->ObjectInformation->ParentObjectInformation->DataVersion.QuadPart != stDeleteResult.ParentDataVersion.QuadPart)
2023 SetFlag( DirectoryCB->ObjectInformation->ParentObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
2025 DirectoryCB->ObjectInformation->ParentObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
2032 // Update the parent data version
2035 if( DirectoryCB->ObjectInformation->ParentObjectInformation->DataVersion.QuadPart != stDeleteResult.ParentDataVersion.QuadPart - 1)
2038 SetFlag( DirectoryCB->ObjectInformation->ParentObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
2040 DirectoryCB->ObjectInformation->ParentObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
2046 // TODO -- The entry must be removed from the directory at which point the
2047 // Directory data version number can be updated. Until then we must force
2050 // DirectoryCB->ObjectInformation->ParentObjectInformation->DataVersion.QuadPart = stDeleteResult.ParentDataVersion.QuadPart;
2053 SetFlag( DirectoryCB->ObjectInformation->ParentObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
2055 DirectoryCB->ObjectInformation->ParentObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
2059 AFSReleaseResource( DirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
2071 AFSNotifyHardLink( IN AFSObjectInfoCB *ObjectInfo,
2073 IN AFSObjectInfoCB *ParentObjectInfo,
2074 IN AFSObjectInfoCB *TargetParentObjectInfo,
2075 IN AFSDirectoryCB *SourceDirectoryCB,
2076 IN UNICODE_STRING *TargetName,
2077 IN BOOLEAN bReplaceIfExists,
2078 OUT AFSDirectoryCB **TargetDirectoryCB)
2081 NTSTATUS ntStatus = STATUS_SUCCESS;
2082 AFSFileHardLinkCB *pHardLinkCB = NULL;
2083 AFSFileHardLinkResultCB *pResultCB = NULL;
2084 ULONG ulResultLen = 0;
2085 AFSDirectoryCB *pDirNode = NULL;
2087 BOOLEAN bReleaseParentLock = FALSE, bReleaseTargetParentLock = FALSE;
2088 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
2094 // Init the control block for the request
2097 pHardLinkCB = (AFSFileHardLinkCB *)AFSExAllocatePoolWithTag( PagedPool,
2099 AFS_HARDLINK_REQUEST_TAG);
2101 if( pHardLinkCB == NULL)
2104 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2107 RtlZeroMemory( pHardLinkCB,
2110 pHardLinkCB->SourceParentId = ParentObjectInfo->FileId;
2112 pHardLinkCB->TargetParentId = TargetParentObjectInfo->FileId;
2114 pHardLinkCB->TargetNameLength = TargetName->Length;
2116 RtlCopyMemory( pHardLinkCB->TargetName,
2118 TargetName->Length);
2120 pHardLinkCB->bReplaceIfExists = bReplaceIfExists;
2123 // Use the same buffer for the result control block
2126 pResultCB = (AFSFileHardLinkResultCB *)pHardLinkCB;
2128 ulResultLen = PAGE_SIZE;
2130 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_HARDLINK_FILE,
2131 AFS_REQUEST_FLAG_SYNCHRONOUS,
2133 &SourceDirectoryCB->NameInformation.FileName,
2134 &ObjectInfo->FileId,
2136 sizeof( AFSFileHardLinkCB) + TargetName->Length,
2140 if( ntStatus != STATUS_SUCCESS)
2143 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2144 AFS_TRACE_LEVEL_ERROR,
2145 "AFSNotifyHardLink failed FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2146 ObjectInfo->FileId.Cell,
2147 ObjectInfo->FileId.Volume,
2148 ObjectInfo->FileId.Vnode,
2149 ObjectInfo->FileId.Unique,
2152 try_return( ntStatus);
2156 // Update the information from the returned data
2159 if ( ParentObjectInfo != TargetParentObjectInfo)
2162 AFSAcquireExcl( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2165 bReleaseParentLock = TRUE;
2167 if ( ParentObjectInfo->DataVersion.QuadPart == pResultCB->SourceParentDataVersion.QuadPart - 1)
2170 ParentObjectInfo->DataVersion = pResultCB->SourceParentDataVersion;
2175 SetFlag( ParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2177 ParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
2181 AFSAcquireExcl( TargetParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2184 bReleaseTargetParentLock = TRUE;
2186 if ( TargetParentObjectInfo->DataVersion.QuadPart == pResultCB->TargetParentDataVersion.QuadPart - 1)
2189 TargetParentObjectInfo->DataVersion = pResultCB->TargetParentDataVersion;
2194 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2195 AFS_TRACE_LEVEL_WARNING,
2196 "AFSNotifyHardLink Raced with an invalidate call and a re-enumeration for entry %wZ ParentFID %08lX-%08lX-%08lX-%08lX Version (%08lX:%08lX != %08lX:%08lX - 1)\n",
2198 TargetParentObjectInfo->FileId.Cell,
2199 TargetParentObjectInfo->FileId.Volume,
2200 TargetParentObjectInfo->FileId.Vnode,
2201 TargetParentObjectInfo->FileId.Unique,
2202 TargetParentObjectInfo->DataVersion.HighPart,
2203 TargetParentObjectInfo->DataVersion.LowPart,
2204 pResultCB->TargetParentDataVersion.HighPart,
2205 pResultCB->TargetParentDataVersion.LowPart);
2208 // We raced so go and lookup the directory entry in the parent
2211 ulCRC = AFSGenerateCRC( TargetName,
2214 AFSLocateCaseSensitiveDirEntry( TargetParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
2218 if( pDirNode != NULL)
2221 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2222 AFS_TRACE_LEVEL_VERBOSE,
2223 "AFSNotifyHardLink Located dir entry %p for file %wZ\n",
2227 if ( AFSIsEqualFID( &pDirNode->ObjectInformation->FileId,
2228 &pResultCB->DirEnum.FileId))
2231 InterlockedIncrement( &pDirNode->OpenReferenceCount);
2233 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2234 AFS_TRACE_LEVEL_VERBOSE,
2235 "AFSNotifyHardLink Increment count on %wZ DE %p Cnt %d\n",
2236 &pDirNode->NameInformation.FileName,
2238 pDirNode->OpenReferenceCount);
2240 AFSReleaseResource( TargetParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2242 try_return( ntStatus = STATUS_REPARSE);
2248 // We found an entry that matches the desired name but it is not the
2249 // same as the one that was created for us by the file server.
2252 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2253 AFS_TRACE_LEVEL_ERROR,
2254 "AFSNotifyHardLink Found matching name entry %wZ DE %p FID %08lX-%08lX-%08lX-%08lX != FID %08lX-%08lX-%08lX-%08lX\n",
2257 pDirNode->ObjectInformation->FileId.Cell,
2258 pDirNode->ObjectInformation->FileId.Volume,
2259 pDirNode->ObjectInformation->FileId.Vnode,
2260 pDirNode->ObjectInformation->FileId.Unique,
2261 pResultCB->DirEnum.FileId.Cell,
2262 pResultCB->DirEnum.FileId.Volume,
2263 pResultCB->DirEnum.FileId.Vnode,
2264 pResultCB->DirEnum.FileId.Unique);
2266 if( pDirNode->OpenReferenceCount == 0)
2269 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2270 AFS_TRACE_LEVEL_VERBOSE,
2271 "AFSNotifyHardLink Different FIDs - Deleting DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
2273 &pDirNode->NameInformation.FileName,
2274 pDirNode->ObjectInformation->FileId.Cell,
2275 pDirNode->ObjectInformation->FileId.Volume,
2276 pDirNode->ObjectInformation->FileId.Vnode,
2277 pDirNode->ObjectInformation->FileId.Unique,
2278 pResultCB->DirEnum.FileId.Cell,
2279 pResultCB->DirEnum.FileId.Volume,
2280 pResultCB->DirEnum.FileId.Vnode,
2281 pResultCB->DirEnum.FileId.Unique);
2283 AFSDeleteDirEntry( TargetParentObjectInfo,
2289 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_DELETED);
2291 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2292 AFS_TRACE_LEVEL_VERBOSE,
2293 "AFSNotifyHardLink Different FIDs - Removing DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
2295 &pDirNode->NameInformation.FileName,
2296 pDirNode->ObjectInformation->FileId.Cell,
2297 pDirNode->ObjectInformation->FileId.Volume,
2298 pDirNode->ObjectInformation->FileId.Vnode,
2299 pDirNode->ObjectInformation->FileId.Unique,
2300 pResultCB->DirEnum.FileId.Cell,
2301 pResultCB->DirEnum.FileId.Volume,
2302 pResultCB->DirEnum.FileId.Vnode,
2303 pResultCB->DirEnum.FileId.Unique);
2305 AFSRemoveNameEntry( TargetParentObjectInfo,
2314 // We are unsure of our current data so set the verify flag. It may already be set
2315 // but no big deal to reset it
2318 SetFlag( TargetParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2320 TargetParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
2324 // Create the hard link entry
2327 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2328 AFS_TRACE_LEVEL_VERBOSE,
2329 "AFSNotifyHardLink Creating new entry %wZ\n",
2333 // Initialize the directory entry
2336 pDirNode = AFSInitDirEntry( TargetParentObjectInfo,
2339 &pResultCB->DirEnum,
2340 (ULONG)InterlockedIncrement( &TargetParentObjectInfo->Specific.Directory.DirectoryNodeHdr.ContentIndex));
2342 if( pDirNode == NULL)
2345 SetFlag( TargetParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2347 TargetParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
2349 AFSReleaseResource( TargetParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2351 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2355 // Init the short name if we have one
2358 if( !BooleanFlagOn( pDevExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
2359 pResultCB->DirEnum.ShortNameLength > 0)
2362 UNICODE_STRING uniShortName;
2364 pDirNode->NameInformation.ShortNameLength = pResultCB->DirEnum.ShortNameLength;
2366 RtlCopyMemory( pDirNode->NameInformation.ShortName,
2367 pResultCB->DirEnum.ShortName,
2368 pDirNode->NameInformation.ShortNameLength);
2371 // Generate the short name index
2374 uniShortName.Length = pDirNode->NameInformation.ShortNameLength;
2375 uniShortName.Buffer = pDirNode->NameInformation.ShortName;
2377 pDirNode->Type.Data.ShortNameTreeEntry.HashIndex = AFSGenerateCRC( &uniShortName,
2380 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2381 AFS_TRACE_LEVEL_VERBOSE,
2382 "AFSNotifyHardLink Initialized short name %wZ for DE %p for %wZ\n",
2385 &pDirNode->NameInformation.FileName);
2390 // No short name or short names are disabled
2393 pDirNode->Type.Data.ShortNameTreeEntry.HashIndex = 0;
2396 if ( !BooleanFlagOn( TargetParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY))
2400 // Update the target parent data version
2403 TargetParentObjectInfo->DataVersion = pResultCB->TargetParentDataVersion;
2405 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2406 AFS_TRACE_LEVEL_VERBOSE,
2407 "AFSNotifyHardLink entry %wZ ParentFID %08lX-%08lX-%08lX-%08lX Version %08lX:%08lX\n",
2409 TargetParentObjectInfo->FileId.Cell,
2410 TargetParentObjectInfo->FileId.Volume,
2411 TargetParentObjectInfo->FileId.Vnode,
2412 TargetParentObjectInfo->FileId.Unique,
2413 TargetParentObjectInfo->DataVersion.QuadPart);
2418 if ( bReleaseTargetParentLock)
2421 AFSReleaseResource( TargetParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2424 if ( bReleaseParentLock)
2427 AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2430 if( pHardLinkCB != NULL)
2433 AFSExFreePoolWithTag( pHardLinkCB, AFS_HARDLINK_REQUEST_TAG);
2436 if ( TargetDirectoryCB)
2439 *TargetDirectoryCB = pDirNode;
2449 AFSNotifyRename( IN AFSObjectInfoCB *ObjectInfo,
2451 IN AFSObjectInfoCB *ParentObjectInfo,
2452 IN AFSObjectInfoCB *TargetParentObjectInfo,
2453 IN AFSDirectoryCB *DirectoryCB,
2454 IN UNICODE_STRING *TargetName,
2455 OUT AFSFileID *UpdatedFID)
2458 NTSTATUS ntStatus = STATUS_SUCCESS;
2459 AFSFileRenameCB *pRenameCB = NULL;
2460 AFSFileRenameResultCB *pRenameResultCB = NULL;
2461 ULONG ulResultLen = 0;
2462 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
2468 // Init the control block for the request
2471 pRenameCB = (AFSFileRenameCB *)AFSExAllocatePoolWithTag( PagedPool,
2473 AFS_RENAME_REQUEST_TAG);
2475 if( pRenameCB == NULL)
2478 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2481 RtlZeroMemory( pRenameCB,
2484 pRenameCB->SourceParentId = ParentObjectInfo->FileId;
2486 pRenameCB->TargetParentId = TargetParentObjectInfo->FileId;
2488 pRenameCB->TargetNameLength = TargetName->Length;
2490 RtlCopyMemory( pRenameCB->TargetName,
2492 TargetName->Length);
2495 // Use the same buffer for the result control block
2498 pRenameResultCB = (AFSFileRenameResultCB *)pRenameCB;
2500 ulResultLen = PAGE_SIZE;
2502 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_RENAME_FILE,
2503 AFS_REQUEST_FLAG_SYNCHRONOUS,
2505 &DirectoryCB->NameInformation.FileName,
2506 &ObjectInfo->FileId,
2508 sizeof( AFSFileRenameCB) + TargetName->Length,
2512 if( ntStatus != STATUS_SUCCESS)
2515 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2516 AFS_TRACE_LEVEL_ERROR,
2517 "AFSNotifyRename failed FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2518 ObjectInfo->FileId.Cell,
2519 ObjectInfo->FileId.Volume,
2520 ObjectInfo->FileId.Vnode,
2521 ObjectInfo->FileId.Unique,
2524 try_return( ntStatus);
2528 // Update the information from the returned data
2531 AFSAcquireExcl( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2534 if ( ParentObjectInfo->DataVersion.QuadPart == pRenameResultCB->SourceParentDataVersion.QuadPart - 1)
2537 ParentObjectInfo->DataVersion = pRenameResultCB->SourceParentDataVersion;
2542 SetFlag( ParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2544 ParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
2547 if ( ParentObjectInfo != TargetParentObjectInfo)
2550 AFSAcquireExcl( TargetParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2553 if ( TargetParentObjectInfo->DataVersion.QuadPart == pRenameResultCB->TargetParentDataVersion.QuadPart - 1)
2556 TargetParentObjectInfo->DataVersion = pRenameResultCB->TargetParentDataVersion;
2561 SetFlag( TargetParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2563 TargetParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
2568 // Move over the short name
2571 DirectoryCB->NameInformation.ShortNameLength = pRenameResultCB->DirEnum.ShortNameLength;
2573 if( !BooleanFlagOn( pDevExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
2574 DirectoryCB->NameInformation.ShortNameLength > 0)
2577 UNICODE_STRING uniShortName;
2579 uniShortName.Length = DirectoryCB->NameInformation.ShortNameLength;
2580 uniShortName.MaximumLength = uniShortName.Length;
2581 uniShortName.Buffer = DirectoryCB->NameInformation.ShortName;
2583 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2584 AFS_TRACE_LEVEL_VERBOSE,
2585 "AFSNotifyRename Update old short name %wZ for DE %p for %wZ\n",
2588 &DirectoryCB->NameInformation.FileName);
2590 DirectoryCB->NameInformation.ShortNameLength = pRenameResultCB->DirEnum.ShortNameLength;
2592 RtlCopyMemory( DirectoryCB->NameInformation.ShortName,
2593 pRenameResultCB->DirEnum.ShortName,
2594 DirectoryCB->NameInformation.ShortNameLength);
2596 uniShortName.Length = DirectoryCB->NameInformation.ShortNameLength;
2597 uniShortName.MaximumLength = uniShortName.Length;
2598 uniShortName.Buffer = DirectoryCB->NameInformation.ShortName;
2600 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2601 AFS_TRACE_LEVEL_VERBOSE,
2602 "AFSNotifyRename Initialized short name %wZ for DE %p for %wZ\n",
2605 &DirectoryCB->NameInformation.FileName);
2610 UNICODE_STRING uniShortName;
2612 uniShortName.Length = DirectoryCB->NameInformation.ShortNameLength;
2613 uniShortName.MaximumLength = uniShortName.Length;
2614 uniShortName.Buffer = DirectoryCB->NameInformation.ShortName;
2616 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2617 AFS_TRACE_LEVEL_VERBOSE,
2618 "AFSNotifyRename Removing old short name %wZ for DE %p for %wZ\n",
2621 &DirectoryCB->NameInformation.FileName);
2623 DirectoryCB->NameInformation.ShortNameLength = 0;
2625 DirectoryCB->Type.Data.ShortNameTreeEntry.HashIndex = 0;
2628 if ( ParentObjectInfo != TargetParentObjectInfo)
2631 AFSReleaseResource( TargetParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2634 AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2636 if( UpdatedFID != NULL)
2638 *UpdatedFID = pRenameResultCB->DirEnum.FileId;
2643 if( pRenameCB != NULL)
2646 AFSExFreePoolWithTag( pRenameCB, AFS_RENAME_REQUEST_TAG);
2654 AFSEvaluateTargetByID( IN AFSObjectInfoCB *ObjectInfo,
2656 IN BOOLEAN FastCall,
2657 OUT AFSDirEnumEntry **DirEnumEntry)
2660 NTSTATUS ntStatus = STATUS_SUCCESS;
2661 AFSEvalTargetCB stTargetID;
2662 ULONG ulResultBufferLength;
2663 AFSFileEvalResultCB *pEvalResultCB = NULL;
2664 AFSDirEnumEntry *pDirEnumCB = NULL;
2665 ULONG ulRequestFlags = AFS_REQUEST_FLAG_SYNCHRONOUS;
2666 AFSObjectInfoCB *pParentInfo = NULL;
2671 RtlZeroMemory( &stTargetID,
2672 sizeof( AFSEvalTargetCB));
2674 pParentInfo = ObjectInfo->ParentObjectInformation;
2676 if( pParentInfo != NULL)
2679 stTargetID.ParentId = pParentInfo->FileId;
2683 // Allocate our response buffer
2686 pEvalResultCB = (AFSFileEvalResultCB *)AFSExAllocatePoolWithTag( PagedPool,
2688 AFS_GENERIC_MEMORY_30_TAG);
2690 if( pEvalResultCB == NULL)
2693 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2697 // Call to the service to evaluate the fid
2700 ulResultBufferLength = PAGE_SIZE;
2705 ulRequestFlags |= AFS_REQUEST_FLAG_FAST_REQUEST;
2708 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_EVAL_TARGET_BY_ID,
2712 &ObjectInfo->FileId,
2714 sizeof( AFSEvalTargetCB),
2716 &ulResultBufferLength);
2718 if( ntStatus != STATUS_SUCCESS)
2722 // If we received back a STATUS_INVALID_HANDLE then mark the parent as requiring
2726 if( ntStatus == STATUS_OBJECT_PATH_INVALID)
2729 if( pParentInfo != NULL)
2732 AFSAcquireExcl( pParentInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2735 SetFlag( pParentInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2737 pParentInfo->DataVersion.QuadPart = (ULONGLONG)-1;
2739 AFSReleaseResource( pParentInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2743 try_return( ntStatus);
2747 // Validate the parent data version
2750 if ( pParentInfo != NULL)
2753 AFSAcquireExcl( pParentInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2756 if ( pParentInfo->DataVersion.QuadPart != pEvalResultCB->ParentDataVersion.QuadPart)
2759 SetFlag( pParentInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2761 pParentInfo->DataVersion.QuadPart = (ULONGLONG)-1;
2764 AFSReleaseResource( pParentInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2768 // Pass back the dir enum entry
2771 if( DirEnumEntry != NULL)
2774 pDirEnumCB = (AFSDirEnumEntry *)AFSExAllocatePoolWithTag( PagedPool,
2776 AFS_GENERIC_MEMORY_2_TAG);
2778 if( pDirEnumCB == NULL)
2781 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2784 RtlCopyMemory( pDirEnumCB, &pEvalResultCB->DirEnum,
2785 ulResultBufferLength - sizeof( AFSFileEvalResultCB) + sizeof( AFSDirEnumEntry));
2787 *DirEnumEntry = pDirEnumCB;
2792 if( pEvalResultCB != NULL)
2795 AFSExFreePoolWithTag( pEvalResultCB, AFS_GENERIC_MEMORY_30_TAG);
2798 if( !NT_SUCCESS( ntStatus))
2801 if( pDirEnumCB != NULL)
2804 AFSExFreePoolWithTag( pDirEnumCB, AFS_GENERIC_MEMORY_2_TAG);
2807 *DirEnumEntry = NULL;
2815 AFSEvaluateTargetByName( IN GUID *AuthGroup,
2816 IN AFSObjectInfoCB *ParentObjectInfo,
2817 IN PUNICODE_STRING SourceName,
2818 OUT AFSDirEnumEntry **DirEnumEntry)
2821 NTSTATUS ntStatus = STATUS_SUCCESS;
2822 AFSEvalTargetCB stTargetID;
2823 ULONG ulResultBufferLength;
2824 AFSFileEvalResultCB *pEvalResultCB = NULL;
2825 AFSDirEnumEntry *pDirEnumCB = NULL;
2830 stTargetID.ParentId = ParentObjectInfo->FileId;
2833 // Allocate our response buffer
2836 pEvalResultCB = (AFSFileEvalResultCB *)AFSExAllocatePoolWithTag( PagedPool,
2838 AFS_GENERIC_MEMORY_31_TAG);
2840 if( pEvalResultCB == NULL)
2843 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2847 // Call to the service to evaluate the fid
2850 ulResultBufferLength = PAGE_SIZE;
2852 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_EVAL_TARGET_BY_NAME,
2853 AFS_REQUEST_FLAG_SYNCHRONOUS,
2858 sizeof( AFSEvalTargetCB),
2860 &ulResultBufferLength);
2862 if( ntStatus != STATUS_SUCCESS)
2865 if( ntStatus == STATUS_OBJECT_PATH_INVALID)
2868 AFSAcquireExcl( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2871 SetFlag( ParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2873 ParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
2875 AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2878 try_return( ntStatus);
2882 // Validate the parent data version
2885 AFSAcquireExcl( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2888 if ( ParentObjectInfo->DataVersion.QuadPart != pEvalResultCB->ParentDataVersion.QuadPart)
2891 SetFlag( ParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2893 ParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
2896 AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2899 // Pass back the dir enum entry
2902 if( DirEnumEntry != NULL)
2905 pDirEnumCB = (AFSDirEnumEntry *)AFSExAllocatePoolWithTag( PagedPool,
2907 AFS_GENERIC_MEMORY_3_TAG);
2909 if( pDirEnumCB == NULL)
2912 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2915 RtlCopyMemory( pDirEnumCB, &pEvalResultCB->DirEnum,
2916 ulResultBufferLength - sizeof( AFSFileEvalResultCB) + sizeof( AFSDirEnumEntry));
2918 *DirEnumEntry = pDirEnumCB;
2923 if( pEvalResultCB != NULL)
2926 AFSExFreePoolWithTag( pEvalResultCB, AFS_GENERIC_MEMORY_31_TAG);
2929 if( !NT_SUCCESS( ntStatus))
2932 if( pDirEnumCB != NULL)
2935 AFSExFreePoolWithTag( pDirEnumCB, AFS_GENERIC_MEMORY_3_TAG);
2938 *DirEnumEntry = NULL;
2946 AFSRetrieveVolumeInformation( IN GUID *AuthGroup,
2947 IN AFSFileID *FileID,
2948 OUT AFSVolumeInfoCB *VolumeInformation)
2951 NTSTATUS ntStatus = STATUS_SUCCESS;
2952 ULONG ulResultLen = 0;
2957 ulResultLen = sizeof( AFSVolumeInfoCB);
2959 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_GET_VOLUME_INFO,
2960 AFS_REQUEST_FLAG_SYNCHRONOUS,
2969 if( ntStatus != STATUS_SUCCESS)
2972 try_return( ntStatus);
2984 AFSRetrieveVolumeSizeInformation( IN GUID *AuthGroup,
2985 IN AFSFileID *FileID,
2986 OUT AFSVolumeSizeInfoCB *VolumeSizeInformation)
2989 NTSTATUS ntStatus = STATUS_SUCCESS;
2990 ULONG ulResultLen = 0;
2995 ulResultLen = sizeof( AFSVolumeSizeInfoCB);
2997 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_GET_VOLUME_SIZE_INFO,
2998 AFS_REQUEST_FLAG_SYNCHRONOUS,
3004 VolumeSizeInformation,
3007 if( ntStatus != STATUS_SUCCESS)
3010 try_return( ntStatus);
3022 AFSNotifyPipeTransceive( IN AFSCcb *Ccb,
3023 IN ULONG InputLength,
3024 IN ULONG OutputLength,
3025 IN void *InputDataBuffer,
3026 OUT void *OutputDataBuffer,
3027 OUT ULONG *BytesReturned)
3030 NTSTATUS ntStatus = STATUS_SUCCESS;
3031 ULONG ulResultLen = 0;
3032 MDL *pInputMdl = NULL, *pOutputMdl = NULL;
3033 void *pInputSystemBuffer = NULL, *pOutputSystemBuffer = NULL;
3034 ULONG ulBufferLength = OutputLength;
3035 AFSPipeIORequestCB *pIoRequest = NULL;
3041 // Map the user buffer to a system address
3044 pInputSystemBuffer = AFSLockUserBuffer( InputDataBuffer,
3048 if( pInputSystemBuffer == NULL)
3051 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3054 pIoRequest = (AFSPipeIORequestCB *)AFSExAllocatePoolWithTag( PagedPool,
3055 sizeof( AFSPipeIORequestCB) +
3057 AFS_GENERIC_MEMORY_4_TAG);
3059 if( pIoRequest == NULL)
3062 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3065 RtlZeroMemory( pIoRequest,
3066 sizeof( AFSPipeIORequestCB) + InputLength);
3068 pIoRequest->RequestId = Ccb->RequestID;
3070 pIoRequest->RootId = Ccb->DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation.FileId;
3072 pIoRequest->BufferLength = InputLength;
3074 RtlCopyMemory( (void *)((char *)pIoRequest + sizeof( AFSPipeIORequestCB)),
3078 pOutputSystemBuffer = AFSLockUserBuffer( OutputDataBuffer,
3082 if( pOutputSystemBuffer == NULL)
3085 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3089 // Send the call to the service
3092 ulResultLen = OutputLength;
3094 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIPE_TRANSCEIVE,
3095 AFS_REQUEST_FLAG_SYNCHRONOUS,
3097 &Ccb->DirectoryCB->NameInformation.FileName,
3100 sizeof( AFSPipeIORequestCB) + InputLength,
3101 pOutputSystemBuffer,
3104 if( ntStatus != STATUS_SUCCESS &&
3105 ntStatus != STATUS_BUFFER_OVERFLOW)
3108 if( NT_SUCCESS( ntStatus))
3111 ntStatus = STATUS_DEVICE_NOT_READY;
3114 try_return( ntStatus);
3118 // Return the bytes processed
3121 *BytesReturned = ulResultLen;
3125 if( pInputMdl != NULL)
3128 MmUnlockPages( pInputMdl);
3130 IoFreeMdl( pInputMdl);
3133 if( pOutputMdl != NULL)
3136 MmUnlockPages( pOutputMdl);
3138 IoFreeMdl( pOutputMdl);
3141 if( pIoRequest != NULL)
3144 AFSExFreePoolWithTag( pIoRequest, AFS_GENERIC_MEMORY_4_TAG);
3152 AFSNotifySetPipeInfo( IN AFSCcb *Ccb,
3153 IN ULONG InformationClass,
3154 IN ULONG InputLength,
3155 IN void *DataBuffer)
3158 NTSTATUS ntStatus = STATUS_SUCCESS;
3159 AFSPipeInfoRequestCB *pInfoRequest = NULL;
3164 pInfoRequest = (AFSPipeInfoRequestCB *)AFSExAllocatePoolWithTag( PagedPool,
3165 sizeof( AFSPipeInfoRequestCB) +
3167 AFS_GENERIC_MEMORY_5_TAG);
3169 if( pInfoRequest == NULL)
3172 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3175 RtlZeroMemory( pInfoRequest,
3176 sizeof( AFSPipeInfoRequestCB) + InputLength);
3178 pInfoRequest->RequestId = Ccb->RequestID;
3180 pInfoRequest->RootId = Ccb->DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation.FileId;
3182 pInfoRequest->BufferLength = InputLength;
3184 pInfoRequest->InformationClass = InformationClass;
3186 RtlCopyMemory( (void *)((char *)pInfoRequest + sizeof( AFSPipeInfoRequestCB)),
3191 // Send the call to the service
3194 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIPE_SET_INFO,
3195 AFS_REQUEST_FLAG_SYNCHRONOUS,
3197 &Ccb->DirectoryCB->NameInformation.FileName,
3200 sizeof( AFSPipeInfoRequestCB) + InputLength,
3204 if( ntStatus != STATUS_SUCCESS)
3207 if( NT_SUCCESS( ntStatus))
3210 ntStatus = STATUS_DEVICE_NOT_READY;
3213 try_return( ntStatus);
3218 if( pInfoRequest != NULL)
3221 AFSExFreePoolWithTag( pInfoRequest, AFS_GENERIC_MEMORY_5_TAG);
3229 AFSNotifyQueryPipeInfo( IN AFSCcb *Ccb,
3230 IN ULONG InformationClass,
3231 IN ULONG OutputLength,
3232 IN void *DataBuffer,
3233 OUT ULONG *BytesReturned)
3236 NTSTATUS ntStatus = STATUS_SUCCESS;
3237 AFSPipeInfoRequestCB stInfoRequest;
3238 ULONG ulBytesProcessed = 0;
3243 RtlZeroMemory( &stInfoRequest,
3244 sizeof( AFSPipeInfoRequestCB));
3246 stInfoRequest.RequestId = Ccb->RequestID;
3248 stInfoRequest.RootId = Ccb->DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation.FileId;
3250 stInfoRequest.BufferLength = OutputLength;
3252 stInfoRequest.InformationClass = InformationClass;
3254 ulBytesProcessed = OutputLength;
3257 // Send the call to the service
3260 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIPE_QUERY_INFO,
3261 AFS_REQUEST_FLAG_SYNCHRONOUS,
3263 &Ccb->DirectoryCB->NameInformation.FileName,
3266 sizeof( AFSPipeInfoRequestCB),
3270 if( ntStatus != STATUS_SUCCESS)
3273 if( NT_SUCCESS( ntStatus))
3276 ntStatus = STATUS_DEVICE_NOT_READY;
3279 try_return( ntStatus);
3282 *BytesReturned = ulBytesProcessed;
3293 AFSReleaseFid( IN AFSFileID *FileId)
3296 NTSTATUS ntStatus = STATUS_SUCCESS;
3301 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_RELEASE_FID,
3316 AFSIsExtentRequestQueued( IN AFSFileID *FileID,
3317 IN LARGE_INTEGER *ExtentOffset,
3321 BOOLEAN bRequestQueued = FALSE;
3322 NTSTATUS ntStatus = STATUS_SUCCESS;
3323 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
3324 AFSCommSrvcCB *pCommSrvc = NULL;
3325 AFSPoolEntry *pPoolEntry = NULL;
3326 AFSRequestExtentsCB *pRequestExtents = NULL;
3332 pCommSrvc = &pControlDevExt->Specific.Control.CommServiceCB;
3334 AFSAcquireShared( &pCommSrvc->IrpPoolLock,
3337 pPoolEntry = pCommSrvc->RequestPoolHead;
3339 while( pPoolEntry != NULL)
3342 if( pPoolEntry->RequestType == AFS_REQUEST_TYPE_REQUEST_FILE_EXTENTS)
3345 if( AFSIsEqualFID( &pPoolEntry->FileId, FileID))
3348 pRequestExtents = (AFSRequestExtentsCB *)pPoolEntry->Data;
3350 if( pRequestExtents->ByteOffset.QuadPart == ExtentOffset->QuadPart &&
3351 pRequestExtents->Length == Length)
3354 bRequestQueued = TRUE;
3359 pPoolEntry = pPoolEntry->fLink;
3362 AFSReleaseResource( &pCommSrvc->IrpPoolLock);
3365 return bRequestQueued;