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->DirOpenReferenceCount <= 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->DirOpenReferenceCount <= 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;
1527 LARGE_INTEGER liOldDataVersion;
1528 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
1529 BOOLEAN bReleaseParentTreeLock = FALSE;
1537 // Init the control block for the request
1540 RtlZeroMemory( &stCreateCB,
1541 sizeof( AFSFileCreateCB));
1543 stCreateCB.ParentId = ParentObjectInfo->FileId;
1545 stCreateCB.AllocationSize = *FileSize;
1547 stCreateCB.FileAttributes = FileAttributes;
1549 stCreateCB.EaSize = 0;
1551 liOldDataVersion = ParentObjectInfo->DataVersion;
1554 // Allocate our return buffer
1557 pResultCB = (AFSFileCreateResultCB *)AFSExAllocatePoolWithTag( PagedPool,
1559 AFS_GENERIC_MEMORY_1_TAG);
1561 if( pResultCB == NULL)
1564 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1567 RtlZeroMemory( pResultCB,
1570 ulResultLen = PAGE_SIZE;
1573 // Send the call to the service
1576 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_CREATE_FILE,
1577 AFS_REQUEST_FLAG_SYNCHRONOUS | AFS_REQUEST_FLAG_HOLD_FID,
1582 sizeof( AFSFileCreateCB),
1586 if( ntStatus != STATUS_SUCCESS)
1589 if( NT_SUCCESS( ntStatus))
1592 ntStatus = STATUS_DEVICE_NOT_READY;
1595 try_return( ntStatus);
1599 // We may have raced with an invalidation call and a subsequent re-enumeration of this parent
1600 // and though we created the node, it is already in our list. If this is the case then
1601 // look up the entry rather than create a new entry
1602 // The check is to ensure the DV has been modified
1605 AFSAcquireExcl( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
1608 bReleaseParentTreeLock = TRUE;
1610 if( ParentObjectInfo->DataVersion.QuadPart != pResultCB->ParentDataVersion.QuadPart - 1)
1613 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1614 AFS_TRACE_LEVEL_WARNING,
1615 "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",
1617 ParentObjectInfo->FileId.Cell,
1618 ParentObjectInfo->FileId.Volume,
1619 ParentObjectInfo->FileId.Vnode,
1620 ParentObjectInfo->FileId.Unique,
1621 ParentObjectInfo->DataVersion.HighPart,
1622 ParentObjectInfo->DataVersion.LowPart,
1623 pResultCB->ParentDataVersion.HighPart,
1624 pResultCB->ParentDataVersion.LowPart);
1627 // We raced so go and lookup the directory entry in the parent
1630 ulCRC = AFSGenerateCRC( FileName,
1633 AFSLocateCaseSensitiveDirEntry( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
1637 if( pDirNode != NULL)
1640 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1641 AFS_TRACE_LEVEL_VERBOSE,
1642 "AFSNotifyFileCreate Located dir entry %p for file %wZ\n",
1646 if ( AFSIsEqualFID( &pDirNode->ObjectInformation->FileId,
1647 &pResultCB->DirEnum.FileId))
1650 *DirNode = pDirNode;
1652 try_return( ntStatus = STATUS_REPARSE);
1658 // We found an entry that matches the desired name but it is not the
1659 // same as the one that was created for us by the file server.
1662 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1663 AFS_TRACE_LEVEL_ERROR,
1664 "AFSNotifyFileCreate Found matching name entry %wZ DE %p FID %08lX-%08lX-%08lX-%08lX != FID %08lX-%08lX-%08lX-%08lX\n",
1667 pDirNode->ObjectInformation->FileId.Cell,
1668 pDirNode->ObjectInformation->FileId.Volume,
1669 pDirNode->ObjectInformation->FileId.Vnode,
1670 pDirNode->ObjectInformation->FileId.Unique,
1671 pResultCB->DirEnum.FileId.Cell,
1672 pResultCB->DirEnum.FileId.Volume,
1673 pResultCB->DirEnum.FileId.Vnode,
1674 pResultCB->DirEnum.FileId.Unique);
1676 if( pDirNode->DirOpenReferenceCount <= 0)
1679 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1680 AFS_TRACE_LEVEL_VERBOSE,
1681 "AFSNotifyFileCreate Different FIDs - Deleting DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
1683 &pDirNode->NameInformation.FileName,
1684 pDirNode->ObjectInformation->FileId.Cell,
1685 pDirNode->ObjectInformation->FileId.Volume,
1686 pDirNode->ObjectInformation->FileId.Vnode,
1687 pDirNode->ObjectInformation->FileId.Unique,
1688 pResultCB->DirEnum.FileId.Cell,
1689 pResultCB->DirEnum.FileId.Volume,
1690 pResultCB->DirEnum.FileId.Vnode,
1691 pResultCB->DirEnum.FileId.Unique);
1693 AFSDeleteDirEntry( ParentObjectInfo,
1699 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_DELETED);
1701 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1702 AFS_TRACE_LEVEL_VERBOSE,
1703 "AFSNotifyFileCreate Different FIDs - Removing DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
1705 &pDirNode->NameInformation.FileName,
1706 pDirNode->ObjectInformation->FileId.Cell,
1707 pDirNode->ObjectInformation->FileId.Volume,
1708 pDirNode->ObjectInformation->FileId.Vnode,
1709 pDirNode->ObjectInformation->FileId.Unique,
1710 pResultCB->DirEnum.FileId.Cell,
1711 pResultCB->DirEnum.FileId.Volume,
1712 pResultCB->DirEnum.FileId.Vnode,
1713 pResultCB->DirEnum.FileId.Unique);
1715 AFSRemoveNameEntry( ParentObjectInfo,
1724 // We are unsure of our current data so set the verify flag. It may already be set
1725 // but no big deal to reset it
1728 SetFlag( ParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
1730 ParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
1733 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1734 AFS_TRACE_LEVEL_VERBOSE,
1735 "AFSNotifyFileCreate Creating new entry %wZ\n",
1739 // Initialize the directory entry
1742 uniTargetName.Length = (USHORT)pResultCB->DirEnum.TargetNameLength;
1744 uniTargetName.MaximumLength = uniTargetName.Length;
1746 uniTargetName.Buffer = (WCHAR *)((char *)&pResultCB->DirEnum + pResultCB->DirEnum.TargetNameOffset);
1748 pDirNode = AFSInitDirEntry( ParentObjectInfo,
1751 &pResultCB->DirEnum,
1752 (ULONG)InterlockedIncrement( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.ContentIndex));
1754 if( pDirNode == NULL)
1757 SetFlag( ParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
1759 ParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
1761 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1765 // Init the short name if we have one
1768 if( !BooleanFlagOn( pDevExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
1769 pResultCB->DirEnum.ShortNameLength > 0)
1772 UNICODE_STRING uniShortName;
1774 pDirNode->NameInformation.ShortNameLength = pResultCB->DirEnum.ShortNameLength;
1776 RtlCopyMemory( pDirNode->NameInformation.ShortName,
1777 pResultCB->DirEnum.ShortName,
1778 pDirNode->NameInformation.ShortNameLength);
1781 // Generate the short name index
1784 uniShortName.Length = pDirNode->NameInformation.ShortNameLength;
1785 uniShortName.Buffer = pDirNode->NameInformation.ShortName;
1787 pDirNode->Type.Data.ShortNameTreeEntry.HashIndex = AFSGenerateCRC( &uniShortName,
1790 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1791 AFS_TRACE_LEVEL_VERBOSE,
1792 "AFSNotifyFileCreate Initialized short name %wZ for DE %p for %wZ\n",
1795 &pDirNode->NameInformation.FileName);
1800 // No short name or short names are disabled
1803 pDirNode->Type.Data.ShortNameTreeEntry.HashIndex = 0;
1806 if ( !BooleanFlagOn( ParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY))
1810 // Update the parent data version
1813 ParentObjectInfo->DataVersion = pResultCB->ParentDataVersion;
1815 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1816 AFS_TRACE_LEVEL_VERBOSE,
1817 "AFSNotifyFileCreate entry %wZ ParentFID %08lX-%08lX-%08lX-%08lX Version %08lX:%08lX\n",
1819 ParentObjectInfo->FileId.Cell,
1820 ParentObjectInfo->FileId.Volume,
1821 ParentObjectInfo->FileId.Vnode,
1822 ParentObjectInfo->FileId.Unique,
1823 ParentObjectInfo->DataVersion.QuadPart);
1827 // Return the directory node
1830 *DirNode = pDirNode;
1834 if ( *DirNode != NULL)
1837 lCount = InterlockedIncrement( &(*DirNode)->DirOpenReferenceCount);
1839 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1840 AFS_TRACE_LEVEL_VERBOSE,
1841 "AFSNotifyFileCreate Increment count on %wZ DE %p Cnt %d\n",
1842 &(*DirNode)->NameInformation.FileName,
1846 ASSERT( lCount >= 0);
1849 if ( bReleaseParentTreeLock)
1852 AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
1855 if( pResultCB != NULL)
1858 AFSExFreePoolWithTag( pResultCB, AFS_GENERIC_MEMORY_1_TAG);
1866 AFSUpdateFileInformation( IN AFSFileID *ParentFid,
1867 IN AFSObjectInfoCB *ObjectInfo,
1871 NTSTATUS ntStatus = STATUS_SUCCESS;
1872 AFSFileUpdateCB stUpdateCB;
1873 ULONG ulResultLen = 0;
1874 AFSFileUpdateResultCB *pUpdateResultCB = NULL;
1880 // Init the control block for the request
1883 RtlZeroMemory( &stUpdateCB,
1884 sizeof( AFSFileUpdateCB));
1886 stUpdateCB.AllocationSize = ObjectInfo->EndOfFile;
1888 stUpdateCB.FileAttributes = ObjectInfo->FileAttributes;
1890 stUpdateCB.EaSize = ObjectInfo->EaSize;
1892 stUpdateCB.ParentId = *ParentFid;
1894 stUpdateCB.LastAccessTime = ObjectInfo->LastAccessTime;
1896 stUpdateCB.CreateTime = ObjectInfo->CreationTime;
1898 stUpdateCB.ChangeTime = ObjectInfo->ChangeTime;
1900 stUpdateCB.LastWriteTime = ObjectInfo->LastWriteTime;
1902 pUpdateResultCB = (AFSFileUpdateResultCB *)AFSExAllocatePoolWithTag( PagedPool,
1904 AFS_UPDATE_RESULT_TAG);
1906 if( pUpdateResultCB == NULL)
1909 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1912 ulResultLen = PAGE_SIZE;
1914 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_UPDATE_FILE,
1915 AFS_REQUEST_FLAG_SYNCHRONOUS,
1918 &ObjectInfo->FileId,
1920 sizeof( AFSFileUpdateCB),
1924 if( ntStatus != STATUS_SUCCESS)
1927 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1928 AFS_TRACE_LEVEL_ERROR,
1929 "AFSUpdateFileInformation failed FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1930 ObjectInfo->FileId.Cell,
1931 ObjectInfo->FileId.Volume,
1932 ObjectInfo->FileId.Vnode,
1933 ObjectInfo->FileId.Unique,
1936 try_return( ntStatus);
1940 // Update the data version
1943 AFSAcquireExcl( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
1946 if ( !BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY))
1949 ObjectInfo->DataVersion = pUpdateResultCB->DirEnum.DataVersion;
1952 AFSReleaseResource( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
1956 if( pUpdateResultCB != NULL)
1959 AFSExFreePoolWithTag( pUpdateResultCB, AFS_UPDATE_RESULT_TAG);
1967 AFSNotifyDelete( IN AFSDirectoryCB *DirectoryCB,
1969 IN BOOLEAN CheckOnly)
1971 NTSTATUS ntStatus = STATUS_SUCCESS;
1972 ULONG ulResultLen = 0;
1973 AFSFileDeleteCB stDelete;
1974 AFSFileDeleteResultCB stDeleteResult;
1975 ULONG ulRequestFlags = AFS_REQUEST_FLAG_SYNCHRONOUS;
1980 stDelete.ParentId = DirectoryCB->ObjectInformation->ParentObjectInformation->FileId;
1982 stDelete.ProcessId = (ULONGLONG)PsGetCurrentProcessId();
1984 ulResultLen = sizeof( AFSFileDeleteResultCB);
1988 ulRequestFlags |= AFS_REQUEST_FLAG_CHECK_ONLY;
1991 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_DELETE_FILE,
1994 &DirectoryCB->NameInformation.FileName,
1995 &DirectoryCB->ObjectInformation->FileId,
1997 sizeof( AFSFileDeleteCB),
2001 if( ntStatus != STATUS_SUCCESS)
2004 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2005 AFS_TRACE_LEVEL_ERROR,
2006 "AFSNotifyDelete failed ParentFID %08lX-%08lX-%08lX-%08lX %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2007 stDelete.ParentId.Cell,
2008 stDelete.ParentId.Volume,
2009 stDelete.ParentId.Vnode,
2010 stDelete.ParentId.Unique,
2011 &DirectoryCB->NameInformation.FileName,
2012 DirectoryCB->ObjectInformation->FileId.Cell,
2013 DirectoryCB->ObjectInformation->FileId.Volume,
2014 DirectoryCB->ObjectInformation->FileId.Vnode,
2015 DirectoryCB->ObjectInformation->FileId.Unique,
2018 try_return( ntStatus);
2021 AFSAcquireExcl( DirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
2028 // Validate the parent data version
2031 if( DirectoryCB->ObjectInformation->ParentObjectInformation->DataVersion.QuadPart != stDeleteResult.ParentDataVersion.QuadPart)
2034 SetFlag( DirectoryCB->ObjectInformation->ParentObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
2036 DirectoryCB->ObjectInformation->ParentObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
2043 // Update the parent data version
2046 if( DirectoryCB->ObjectInformation->ParentObjectInformation->DataVersion.QuadPart != stDeleteResult.ParentDataVersion.QuadPart - 1)
2049 SetFlag( DirectoryCB->ObjectInformation->ParentObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
2051 DirectoryCB->ObjectInformation->ParentObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
2057 // TODO -- The entry must be removed from the directory at which point the
2058 // Directory data version number can be updated. Until then we must force
2061 // DirectoryCB->ObjectInformation->ParentObjectInformation->DataVersion.QuadPart = stDeleteResult.ParentDataVersion.QuadPart;
2064 SetFlag( DirectoryCB->ObjectInformation->ParentObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
2066 DirectoryCB->ObjectInformation->ParentObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
2070 AFSReleaseResource( DirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
2082 AFSNotifyHardLink( IN AFSObjectInfoCB *ObjectInfo,
2084 IN AFSObjectInfoCB *ParentObjectInfo,
2085 IN AFSObjectInfoCB *TargetParentObjectInfo,
2086 IN AFSDirectoryCB *SourceDirectoryCB,
2087 IN UNICODE_STRING *TargetName,
2088 IN BOOLEAN bReplaceIfExists,
2089 OUT AFSDirectoryCB **TargetDirectoryCB)
2092 NTSTATUS ntStatus = STATUS_SUCCESS;
2093 AFSFileHardLinkCB *pHardLinkCB = NULL;
2094 AFSFileHardLinkResultCB *pResultCB = NULL;
2095 ULONG ulResultLen = 0;
2096 AFSDirectoryCB *pDirNode = NULL;
2098 BOOLEAN bReleaseParentLock = FALSE, bReleaseTargetParentLock = FALSE;
2099 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
2106 // Init the control block for the request
2109 pHardLinkCB = (AFSFileHardLinkCB *)AFSExAllocatePoolWithTag( PagedPool,
2111 AFS_HARDLINK_REQUEST_TAG);
2113 if( pHardLinkCB == NULL)
2116 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2119 RtlZeroMemory( pHardLinkCB,
2122 pHardLinkCB->SourceParentId = ParentObjectInfo->FileId;
2124 pHardLinkCB->TargetParentId = TargetParentObjectInfo->FileId;
2126 pHardLinkCB->TargetNameLength = TargetName->Length;
2128 RtlCopyMemory( pHardLinkCB->TargetName,
2130 TargetName->Length);
2132 pHardLinkCB->bReplaceIfExists = bReplaceIfExists;
2135 // Use the same buffer for the result control block
2138 pResultCB = (AFSFileHardLinkResultCB *)pHardLinkCB;
2140 ulResultLen = PAGE_SIZE;
2142 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_HARDLINK_FILE,
2143 AFS_REQUEST_FLAG_SYNCHRONOUS,
2145 &SourceDirectoryCB->NameInformation.FileName,
2146 &ObjectInfo->FileId,
2148 sizeof( AFSFileHardLinkCB) + TargetName->Length,
2152 if( ntStatus != STATUS_SUCCESS)
2155 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2156 AFS_TRACE_LEVEL_ERROR,
2157 "AFSNotifyHardLink failed FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2158 ObjectInfo->FileId.Cell,
2159 ObjectInfo->FileId.Volume,
2160 ObjectInfo->FileId.Vnode,
2161 ObjectInfo->FileId.Unique,
2164 try_return( ntStatus);
2168 // Update the information from the returned data
2171 if ( ParentObjectInfo != TargetParentObjectInfo)
2174 AFSAcquireExcl( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2177 bReleaseParentLock = TRUE;
2179 if ( ParentObjectInfo->DataVersion.QuadPart == pResultCB->SourceParentDataVersion.QuadPart - 1)
2182 ParentObjectInfo->DataVersion = pResultCB->SourceParentDataVersion;
2187 SetFlag( ParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2189 ParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
2193 AFSAcquireExcl( TargetParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2196 bReleaseTargetParentLock = TRUE;
2198 if ( TargetParentObjectInfo->DataVersion.QuadPart == pResultCB->TargetParentDataVersion.QuadPart - 1)
2201 TargetParentObjectInfo->DataVersion = pResultCB->TargetParentDataVersion;
2206 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2207 AFS_TRACE_LEVEL_WARNING,
2208 "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",
2210 TargetParentObjectInfo->FileId.Cell,
2211 TargetParentObjectInfo->FileId.Volume,
2212 TargetParentObjectInfo->FileId.Vnode,
2213 TargetParentObjectInfo->FileId.Unique,
2214 TargetParentObjectInfo->DataVersion.HighPart,
2215 TargetParentObjectInfo->DataVersion.LowPart,
2216 pResultCB->TargetParentDataVersion.HighPart,
2217 pResultCB->TargetParentDataVersion.LowPart);
2220 // We raced so go and lookup the directory entry in the parent
2223 ulCRC = AFSGenerateCRC( TargetName,
2226 AFSLocateCaseSensitiveDirEntry( TargetParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
2230 if( pDirNode != NULL)
2233 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2234 AFS_TRACE_LEVEL_VERBOSE,
2235 "AFSNotifyHardLink Located dir entry %p for file %wZ\n",
2239 if ( AFSIsEqualFID( &pDirNode->ObjectInformation->FileId,
2240 &pResultCB->DirEnum.FileId))
2243 try_return( ntStatus = STATUS_REPARSE);
2249 // We found an entry that matches the desired name but it is not the
2250 // same as the one that was created for us by the file server.
2253 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2254 AFS_TRACE_LEVEL_ERROR,
2255 "AFSNotifyHardLink Found matching name entry %wZ DE %p FID %08lX-%08lX-%08lX-%08lX != FID %08lX-%08lX-%08lX-%08lX\n",
2258 pDirNode->ObjectInformation->FileId.Cell,
2259 pDirNode->ObjectInformation->FileId.Volume,
2260 pDirNode->ObjectInformation->FileId.Vnode,
2261 pDirNode->ObjectInformation->FileId.Unique,
2262 pResultCB->DirEnum.FileId.Cell,
2263 pResultCB->DirEnum.FileId.Volume,
2264 pResultCB->DirEnum.FileId.Vnode,
2265 pResultCB->DirEnum.FileId.Unique);
2267 if( pDirNode->DirOpenReferenceCount <= 0)
2270 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2271 AFS_TRACE_LEVEL_VERBOSE,
2272 "AFSNotifyHardLink Different FIDs - Deleting DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
2274 &pDirNode->NameInformation.FileName,
2275 pDirNode->ObjectInformation->FileId.Cell,
2276 pDirNode->ObjectInformation->FileId.Volume,
2277 pDirNode->ObjectInformation->FileId.Vnode,
2278 pDirNode->ObjectInformation->FileId.Unique,
2279 pResultCB->DirEnum.FileId.Cell,
2280 pResultCB->DirEnum.FileId.Volume,
2281 pResultCB->DirEnum.FileId.Vnode,
2282 pResultCB->DirEnum.FileId.Unique);
2284 AFSDeleteDirEntry( TargetParentObjectInfo,
2290 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_DELETED);
2292 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2293 AFS_TRACE_LEVEL_VERBOSE,
2294 "AFSNotifyHardLink Different FIDs - Removing DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
2296 &pDirNode->NameInformation.FileName,
2297 pDirNode->ObjectInformation->FileId.Cell,
2298 pDirNode->ObjectInformation->FileId.Volume,
2299 pDirNode->ObjectInformation->FileId.Vnode,
2300 pDirNode->ObjectInformation->FileId.Unique,
2301 pResultCB->DirEnum.FileId.Cell,
2302 pResultCB->DirEnum.FileId.Volume,
2303 pResultCB->DirEnum.FileId.Vnode,
2304 pResultCB->DirEnum.FileId.Unique);
2306 AFSRemoveNameEntry( TargetParentObjectInfo,
2315 // We are unsure of our current data so set the verify flag. It may already be set
2316 // but no big deal to reset it
2319 SetFlag( TargetParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2321 TargetParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
2325 // Create the hard link entry
2328 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2329 AFS_TRACE_LEVEL_VERBOSE,
2330 "AFSNotifyHardLink Creating new entry %wZ\n",
2334 // Initialize the directory entry
2337 pDirNode = AFSInitDirEntry( TargetParentObjectInfo,
2340 &pResultCB->DirEnum,
2341 (ULONG)InterlockedIncrement( &TargetParentObjectInfo->Specific.Directory.DirectoryNodeHdr.ContentIndex));
2343 if( pDirNode == NULL)
2346 SetFlag( TargetParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2348 TargetParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
2350 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2354 // Init the short name if we have one
2357 if( !BooleanFlagOn( pDevExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
2358 pResultCB->DirEnum.ShortNameLength > 0)
2361 UNICODE_STRING uniShortName;
2363 pDirNode->NameInformation.ShortNameLength = pResultCB->DirEnum.ShortNameLength;
2365 RtlCopyMemory( pDirNode->NameInformation.ShortName,
2366 pResultCB->DirEnum.ShortName,
2367 pDirNode->NameInformation.ShortNameLength);
2370 // Generate the short name index
2373 uniShortName.Length = pDirNode->NameInformation.ShortNameLength;
2374 uniShortName.Buffer = pDirNode->NameInformation.ShortName;
2376 pDirNode->Type.Data.ShortNameTreeEntry.HashIndex = AFSGenerateCRC( &uniShortName,
2379 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2380 AFS_TRACE_LEVEL_VERBOSE,
2381 "AFSNotifyHardLink Initialized short name %wZ for DE %p for %wZ\n",
2384 &pDirNode->NameInformation.FileName);
2389 // No short name or short names are disabled
2392 pDirNode->Type.Data.ShortNameTreeEntry.HashIndex = 0;
2395 if ( !BooleanFlagOn( TargetParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY))
2399 // Update the target parent data version
2402 TargetParentObjectInfo->DataVersion = pResultCB->TargetParentDataVersion;
2404 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2405 AFS_TRACE_LEVEL_VERBOSE,
2406 "AFSNotifyHardLink entry %wZ ParentFID %08lX-%08lX-%08lX-%08lX Version %08lX:%08lX\n",
2408 TargetParentObjectInfo->FileId.Cell,
2409 TargetParentObjectInfo->FileId.Volume,
2410 TargetParentObjectInfo->FileId.Vnode,
2411 TargetParentObjectInfo->FileId.Unique,
2412 TargetParentObjectInfo->DataVersion.QuadPart);
2417 if ( TargetDirectoryCB != NULL)
2420 lCount = InterlockedIncrement( &pDirNode->DirOpenReferenceCount);
2422 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2423 AFS_TRACE_LEVEL_VERBOSE,
2424 "AFSNotifyHardLink Increment count on %wZ DE %p Cnt %d\n",
2425 &pDirNode->NameInformation.FileName,
2429 ASSERT( lCount >= 0);
2431 *TargetDirectoryCB = pDirNode;
2434 if ( bReleaseTargetParentLock)
2437 AFSReleaseResource( TargetParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2440 if ( bReleaseParentLock)
2443 AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2446 if( pHardLinkCB != NULL)
2449 AFSExFreePoolWithTag( pHardLinkCB, AFS_HARDLINK_REQUEST_TAG);
2459 AFSNotifyRename( IN AFSObjectInfoCB *ObjectInfo,
2461 IN AFSObjectInfoCB *ParentObjectInfo,
2462 IN AFSObjectInfoCB *TargetParentObjectInfo,
2463 IN AFSDirectoryCB *DirectoryCB,
2464 IN UNICODE_STRING *TargetName,
2465 OUT AFSFileID *UpdatedFID)
2468 NTSTATUS ntStatus = STATUS_SUCCESS;
2469 AFSFileRenameCB *pRenameCB = NULL;
2470 AFSFileRenameResultCB *pRenameResultCB = NULL;
2471 ULONG ulResultLen = 0;
2472 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
2478 // Init the control block for the request
2481 pRenameCB = (AFSFileRenameCB *)AFSExAllocatePoolWithTag( PagedPool,
2483 AFS_RENAME_REQUEST_TAG);
2485 if( pRenameCB == NULL)
2488 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2491 RtlZeroMemory( pRenameCB,
2494 pRenameCB->SourceParentId = ParentObjectInfo->FileId;
2496 pRenameCB->TargetParentId = TargetParentObjectInfo->FileId;
2498 pRenameCB->TargetNameLength = TargetName->Length;
2500 RtlCopyMemory( pRenameCB->TargetName,
2502 TargetName->Length);
2505 // Use the same buffer for the result control block
2508 pRenameResultCB = (AFSFileRenameResultCB *)pRenameCB;
2510 ulResultLen = PAGE_SIZE;
2512 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_RENAME_FILE,
2513 AFS_REQUEST_FLAG_SYNCHRONOUS,
2515 &DirectoryCB->NameInformation.FileName,
2516 &ObjectInfo->FileId,
2518 sizeof( AFSFileRenameCB) + TargetName->Length,
2522 if( ntStatus != STATUS_SUCCESS)
2525 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2526 AFS_TRACE_LEVEL_ERROR,
2527 "AFSNotifyRename failed FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2528 ObjectInfo->FileId.Cell,
2529 ObjectInfo->FileId.Volume,
2530 ObjectInfo->FileId.Vnode,
2531 ObjectInfo->FileId.Unique,
2534 try_return( ntStatus);
2538 // Update the information from the returned data
2541 AFSAcquireExcl( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2544 if ( ParentObjectInfo->DataVersion.QuadPart == pRenameResultCB->SourceParentDataVersion.QuadPart - 1)
2547 ParentObjectInfo->DataVersion = pRenameResultCB->SourceParentDataVersion;
2552 SetFlag( ParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2554 ParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
2557 if ( ParentObjectInfo != TargetParentObjectInfo)
2560 AFSAcquireExcl( TargetParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2563 if ( TargetParentObjectInfo->DataVersion.QuadPart == pRenameResultCB->TargetParentDataVersion.QuadPart - 1)
2566 TargetParentObjectInfo->DataVersion = pRenameResultCB->TargetParentDataVersion;
2571 SetFlag( TargetParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2573 TargetParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
2578 // Move over the short name
2581 DirectoryCB->NameInformation.ShortNameLength = pRenameResultCB->DirEnum.ShortNameLength;
2583 if( !BooleanFlagOn( pDevExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
2584 DirectoryCB->NameInformation.ShortNameLength > 0)
2587 UNICODE_STRING uniShortName;
2589 uniShortName.Length = DirectoryCB->NameInformation.ShortNameLength;
2590 uniShortName.MaximumLength = uniShortName.Length;
2591 uniShortName.Buffer = DirectoryCB->NameInformation.ShortName;
2593 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2594 AFS_TRACE_LEVEL_VERBOSE,
2595 "AFSNotifyRename Update old short name %wZ for DE %p for %wZ\n",
2598 &DirectoryCB->NameInformation.FileName);
2600 DirectoryCB->NameInformation.ShortNameLength = pRenameResultCB->DirEnum.ShortNameLength;
2602 RtlCopyMemory( DirectoryCB->NameInformation.ShortName,
2603 pRenameResultCB->DirEnum.ShortName,
2604 DirectoryCB->NameInformation.ShortNameLength);
2606 uniShortName.Length = DirectoryCB->NameInformation.ShortNameLength;
2607 uniShortName.MaximumLength = uniShortName.Length;
2608 uniShortName.Buffer = DirectoryCB->NameInformation.ShortName;
2610 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2611 AFS_TRACE_LEVEL_VERBOSE,
2612 "AFSNotifyRename Initialized short name %wZ for DE %p for %wZ\n",
2615 &DirectoryCB->NameInformation.FileName);
2620 UNICODE_STRING uniShortName;
2622 uniShortName.Length = DirectoryCB->NameInformation.ShortNameLength;
2623 uniShortName.MaximumLength = uniShortName.Length;
2624 uniShortName.Buffer = DirectoryCB->NameInformation.ShortName;
2626 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2627 AFS_TRACE_LEVEL_VERBOSE,
2628 "AFSNotifyRename Removing old short name %wZ for DE %p for %wZ\n",
2631 &DirectoryCB->NameInformation.FileName);
2633 DirectoryCB->NameInformation.ShortNameLength = 0;
2635 DirectoryCB->Type.Data.ShortNameTreeEntry.HashIndex = 0;
2638 if ( ParentObjectInfo != TargetParentObjectInfo)
2641 AFSReleaseResource( TargetParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2644 AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2646 if( UpdatedFID != NULL)
2648 *UpdatedFID = pRenameResultCB->DirEnum.FileId;
2653 if( pRenameCB != NULL)
2656 AFSExFreePoolWithTag( pRenameCB, AFS_RENAME_REQUEST_TAG);
2664 AFSEvaluateTargetByID( IN AFSObjectInfoCB *ObjectInfo,
2666 IN BOOLEAN FastCall,
2667 OUT AFSDirEnumEntry **DirEnumEntry)
2670 NTSTATUS ntStatus = STATUS_SUCCESS;
2671 AFSEvalTargetCB stTargetID;
2672 ULONG ulResultBufferLength;
2673 AFSFileEvalResultCB *pEvalResultCB = NULL;
2674 AFSDirEnumEntry *pDirEnumCB = NULL;
2675 ULONG ulRequestFlags = AFS_REQUEST_FLAG_SYNCHRONOUS;
2676 AFSObjectInfoCB *pParentInfo = NULL;
2681 RtlZeroMemory( &stTargetID,
2682 sizeof( AFSEvalTargetCB));
2684 pParentInfo = ObjectInfo->ParentObjectInformation;
2686 if( pParentInfo != NULL)
2689 stTargetID.ParentId = pParentInfo->FileId;
2693 // Allocate our response buffer
2696 pEvalResultCB = (AFSFileEvalResultCB *)AFSExAllocatePoolWithTag( PagedPool,
2698 AFS_GENERIC_MEMORY_30_TAG);
2700 if( pEvalResultCB == NULL)
2703 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2707 // Call to the service to evaluate the fid
2710 ulResultBufferLength = PAGE_SIZE;
2715 ulRequestFlags |= AFS_REQUEST_FLAG_FAST_REQUEST;
2718 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_EVAL_TARGET_BY_ID,
2722 &ObjectInfo->FileId,
2724 sizeof( AFSEvalTargetCB),
2726 &ulResultBufferLength);
2728 if( ntStatus != STATUS_SUCCESS)
2732 // If we received back a STATUS_INVALID_HANDLE then mark the parent as requiring
2736 if( ntStatus == STATUS_OBJECT_PATH_INVALID)
2739 if( pParentInfo != NULL)
2742 AFSAcquireExcl( pParentInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2745 SetFlag( pParentInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2747 pParentInfo->DataVersion.QuadPart = (ULONGLONG)-1;
2749 AFSReleaseResource( pParentInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2753 try_return( ntStatus);
2757 // Validate the parent data version
2760 if ( pParentInfo != NULL)
2763 AFSAcquireExcl( pParentInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2766 if ( pParentInfo->DataVersion.QuadPart != pEvalResultCB->ParentDataVersion.QuadPart)
2769 SetFlag( pParentInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2771 pParentInfo->DataVersion.QuadPart = (ULONGLONG)-1;
2774 AFSReleaseResource( pParentInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2778 // Pass back the dir enum entry
2781 if( DirEnumEntry != NULL)
2784 pDirEnumCB = (AFSDirEnumEntry *)AFSExAllocatePoolWithTag( PagedPool,
2786 AFS_GENERIC_MEMORY_2_TAG);
2788 if( pDirEnumCB == NULL)
2791 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2794 RtlCopyMemory( pDirEnumCB, &pEvalResultCB->DirEnum,
2795 ulResultBufferLength - sizeof( AFSFileEvalResultCB) + sizeof( AFSDirEnumEntry));
2797 *DirEnumEntry = pDirEnumCB;
2802 if( pEvalResultCB != NULL)
2805 AFSExFreePoolWithTag( pEvalResultCB, AFS_GENERIC_MEMORY_30_TAG);
2808 if( !NT_SUCCESS( ntStatus))
2811 if( pDirEnumCB != NULL)
2814 AFSExFreePoolWithTag( pDirEnumCB, AFS_GENERIC_MEMORY_2_TAG);
2817 *DirEnumEntry = NULL;
2825 AFSEvaluateTargetByName( IN GUID *AuthGroup,
2826 IN AFSObjectInfoCB *ParentObjectInfo,
2827 IN PUNICODE_STRING SourceName,
2828 OUT AFSDirEnumEntry **DirEnumEntry)
2831 NTSTATUS ntStatus = STATUS_SUCCESS;
2832 AFSEvalTargetCB stTargetID;
2833 ULONG ulResultBufferLength;
2834 AFSFileEvalResultCB *pEvalResultCB = NULL;
2835 AFSDirEnumEntry *pDirEnumCB = NULL;
2840 stTargetID.ParentId = ParentObjectInfo->FileId;
2843 // Allocate our response buffer
2846 pEvalResultCB = (AFSFileEvalResultCB *)AFSExAllocatePoolWithTag( PagedPool,
2848 AFS_GENERIC_MEMORY_31_TAG);
2850 if( pEvalResultCB == NULL)
2853 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2857 // Call to the service to evaluate the fid
2860 ulResultBufferLength = PAGE_SIZE;
2862 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_EVAL_TARGET_BY_NAME,
2863 AFS_REQUEST_FLAG_SYNCHRONOUS,
2868 sizeof( AFSEvalTargetCB),
2870 &ulResultBufferLength);
2872 if( ntStatus != STATUS_SUCCESS)
2875 if( ntStatus == STATUS_OBJECT_PATH_INVALID)
2878 AFSAcquireExcl( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2881 SetFlag( ParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2883 ParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
2885 AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2888 try_return( ntStatus);
2892 // Validate the parent data version
2895 AFSAcquireExcl( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2898 if ( ParentObjectInfo->DataVersion.QuadPart != pEvalResultCB->ParentDataVersion.QuadPart)
2901 SetFlag( ParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2903 ParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
2906 AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2909 // Pass back the dir enum entry
2912 if( DirEnumEntry != NULL)
2915 pDirEnumCB = (AFSDirEnumEntry *)AFSExAllocatePoolWithTag( PagedPool,
2917 AFS_GENERIC_MEMORY_3_TAG);
2919 if( pDirEnumCB == NULL)
2922 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2925 RtlCopyMemory( pDirEnumCB, &pEvalResultCB->DirEnum,
2926 ulResultBufferLength - sizeof( AFSFileEvalResultCB) + sizeof( AFSDirEnumEntry));
2928 *DirEnumEntry = pDirEnumCB;
2933 if( pEvalResultCB != NULL)
2936 AFSExFreePoolWithTag( pEvalResultCB, AFS_GENERIC_MEMORY_31_TAG);
2939 if( !NT_SUCCESS( ntStatus))
2942 if( pDirEnumCB != NULL)
2945 AFSExFreePoolWithTag( pDirEnumCB, AFS_GENERIC_MEMORY_3_TAG);
2948 *DirEnumEntry = NULL;
2956 AFSRetrieveVolumeInformation( IN GUID *AuthGroup,
2957 IN AFSFileID *FileID,
2958 OUT AFSVolumeInfoCB *VolumeInformation)
2961 NTSTATUS ntStatus = STATUS_SUCCESS;
2962 ULONG ulResultLen = 0;
2967 ulResultLen = sizeof( AFSVolumeInfoCB);
2969 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_GET_VOLUME_INFO,
2970 AFS_REQUEST_FLAG_SYNCHRONOUS,
2979 if( ntStatus != STATUS_SUCCESS)
2982 try_return( ntStatus);
2994 AFSRetrieveVolumeSizeInformation( IN GUID *AuthGroup,
2995 IN AFSFileID *FileID,
2996 OUT AFSVolumeSizeInfoCB *VolumeSizeInformation)
2999 NTSTATUS ntStatus = STATUS_SUCCESS;
3000 ULONG ulResultLen = 0;
3005 ulResultLen = sizeof( AFSVolumeSizeInfoCB);
3007 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_GET_VOLUME_SIZE_INFO,
3008 AFS_REQUEST_FLAG_SYNCHRONOUS,
3014 VolumeSizeInformation,
3017 if( ntStatus != STATUS_SUCCESS)
3020 try_return( ntStatus);
3032 AFSNotifyPipeTransceive( IN AFSCcb *Ccb,
3033 IN ULONG InputLength,
3034 IN ULONG OutputLength,
3035 IN void *InputDataBuffer,
3036 OUT void *OutputDataBuffer,
3037 OUT ULONG *BytesReturned)
3040 NTSTATUS ntStatus = STATUS_SUCCESS;
3041 ULONG ulResultLen = 0;
3042 MDL *pInputMdl = NULL, *pOutputMdl = NULL;
3043 void *pInputSystemBuffer = NULL, *pOutputSystemBuffer = NULL;
3044 AFSPipeIORequestCB *pIoRequest = NULL;
3050 // Map the user buffer to a system address
3053 pInputSystemBuffer = AFSLockUserBuffer( InputDataBuffer,
3057 if( pInputSystemBuffer == NULL)
3060 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3063 pIoRequest = (AFSPipeIORequestCB *)AFSExAllocatePoolWithTag( PagedPool,
3064 sizeof( AFSPipeIORequestCB) +
3066 AFS_GENERIC_MEMORY_4_TAG);
3068 if( pIoRequest == NULL)
3071 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3074 RtlZeroMemory( pIoRequest,
3075 sizeof( AFSPipeIORequestCB) + InputLength);
3077 pIoRequest->RequestId = Ccb->RequestID;
3079 pIoRequest->RootId = Ccb->DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation.FileId;
3081 pIoRequest->BufferLength = InputLength;
3083 RtlCopyMemory( (void *)((char *)pIoRequest + sizeof( AFSPipeIORequestCB)),
3087 pOutputSystemBuffer = AFSLockUserBuffer( OutputDataBuffer,
3091 if( pOutputSystemBuffer == NULL)
3094 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3098 // Send the call to the service
3101 ulResultLen = OutputLength;
3103 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIPE_TRANSCEIVE,
3104 AFS_REQUEST_FLAG_SYNCHRONOUS,
3106 &Ccb->DirectoryCB->NameInformation.FileName,
3109 sizeof( AFSPipeIORequestCB) + InputLength,
3110 pOutputSystemBuffer,
3113 if( ntStatus != STATUS_SUCCESS &&
3114 ntStatus != STATUS_BUFFER_OVERFLOW)
3117 if( NT_SUCCESS( ntStatus))
3120 ntStatus = STATUS_DEVICE_NOT_READY;
3123 try_return( ntStatus);
3127 // Return the bytes processed
3130 *BytesReturned = ulResultLen;
3134 if( pInputMdl != NULL)
3137 MmUnlockPages( pInputMdl);
3139 IoFreeMdl( pInputMdl);
3142 if( pOutputMdl != NULL)
3145 MmUnlockPages( pOutputMdl);
3147 IoFreeMdl( pOutputMdl);
3150 if( pIoRequest != NULL)
3153 AFSExFreePoolWithTag( pIoRequest, AFS_GENERIC_MEMORY_4_TAG);
3161 AFSNotifySetPipeInfo( IN AFSCcb *Ccb,
3162 IN ULONG InformationClass,
3163 IN ULONG InputLength,
3164 IN void *DataBuffer)
3167 NTSTATUS ntStatus = STATUS_SUCCESS;
3168 AFSPipeInfoRequestCB *pInfoRequest = NULL;
3173 pInfoRequest = (AFSPipeInfoRequestCB *)AFSExAllocatePoolWithTag( PagedPool,
3174 sizeof( AFSPipeInfoRequestCB) +
3176 AFS_GENERIC_MEMORY_5_TAG);
3178 if( pInfoRequest == NULL)
3181 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3184 RtlZeroMemory( pInfoRequest,
3185 sizeof( AFSPipeInfoRequestCB) + InputLength);
3187 pInfoRequest->RequestId = Ccb->RequestID;
3189 pInfoRequest->RootId = Ccb->DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation.FileId;
3191 pInfoRequest->BufferLength = InputLength;
3193 pInfoRequest->InformationClass = InformationClass;
3195 RtlCopyMemory( (void *)((char *)pInfoRequest + sizeof( AFSPipeInfoRequestCB)),
3200 // Send the call to the service
3203 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIPE_SET_INFO,
3204 AFS_REQUEST_FLAG_SYNCHRONOUS,
3206 &Ccb->DirectoryCB->NameInformation.FileName,
3209 sizeof( AFSPipeInfoRequestCB) + InputLength,
3213 if( ntStatus != STATUS_SUCCESS)
3216 if( NT_SUCCESS( ntStatus))
3219 ntStatus = STATUS_DEVICE_NOT_READY;
3222 try_return( ntStatus);
3227 if( pInfoRequest != NULL)
3230 AFSExFreePoolWithTag( pInfoRequest, AFS_GENERIC_MEMORY_5_TAG);
3238 AFSNotifyQueryPipeInfo( IN AFSCcb *Ccb,
3239 IN ULONG InformationClass,
3240 IN ULONG OutputLength,
3241 IN void *DataBuffer,
3242 OUT ULONG *BytesReturned)
3245 NTSTATUS ntStatus = STATUS_SUCCESS;
3246 AFSPipeInfoRequestCB stInfoRequest;
3247 ULONG ulBytesProcessed = 0;
3252 RtlZeroMemory( &stInfoRequest,
3253 sizeof( AFSPipeInfoRequestCB));
3255 stInfoRequest.RequestId = Ccb->RequestID;
3257 stInfoRequest.RootId = Ccb->DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation.FileId;
3259 stInfoRequest.BufferLength = OutputLength;
3261 stInfoRequest.InformationClass = InformationClass;
3263 ulBytesProcessed = OutputLength;
3266 // Send the call to the service
3269 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIPE_QUERY_INFO,
3270 AFS_REQUEST_FLAG_SYNCHRONOUS,
3272 &Ccb->DirectoryCB->NameInformation.FileName,
3275 sizeof( AFSPipeInfoRequestCB),
3279 if( ntStatus != STATUS_SUCCESS)
3282 if( NT_SUCCESS( ntStatus))
3285 ntStatus = STATUS_DEVICE_NOT_READY;
3288 try_return( ntStatus);
3291 *BytesReturned = ulBytesProcessed;
3302 AFSReleaseFid( IN AFSFileID *FileId)
3305 NTSTATUS ntStatus = STATUS_SUCCESS;
3310 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_RELEASE_FID,
3325 AFSIsExtentRequestQueued( IN AFSFileID *FileID,
3326 IN LARGE_INTEGER *ExtentOffset,
3330 BOOLEAN bRequestQueued = FALSE;
3331 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
3332 AFSCommSrvcCB *pCommSrvc = NULL;
3333 AFSPoolEntry *pPoolEntry = NULL;
3334 AFSRequestExtentsCB *pRequestExtents = NULL;
3340 pCommSrvc = &pControlDevExt->Specific.Control.CommServiceCB;
3342 AFSAcquireShared( &pCommSrvc->IrpPoolLock,
3345 pPoolEntry = pCommSrvc->RequestPoolHead;
3347 while( pPoolEntry != NULL)
3350 if( pPoolEntry->RequestType == AFS_REQUEST_TYPE_REQUEST_FILE_EXTENTS)
3353 if( AFSIsEqualFID( &pPoolEntry->FileId, FileID))
3356 pRequestExtents = (AFSRequestExtentsCB *)pPoolEntry->Data;
3358 if( pRequestExtents->ByteOffset.QuadPart == ExtentOffset->QuadPart &&
3359 pRequestExtents->Length == Length)
3362 bRequestQueued = TRUE;
3367 pPoolEntry = pPoolEntry->fLink;
3370 AFSReleaseResource( &pCommSrvc->IrpPoolLock);
3373 return bRequestQueued;