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;
64 uniGUID.MaximumLength = 0;
65 uniGUID.Buffer = NULL;
67 if( AuthGroup != NULL)
69 RtlStringFromGUID( *AuthGroup,
73 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
74 AFS_TRACE_LEVEL_VERBOSE,
75 "AFSEnumerateDirectory Enumerating FID %08lX-%08lX-%08lX-%08lX AuthGroup %wZ\n",
76 ObjectInfoCB->FileId.Cell,
77 ObjectInfoCB->FileId.Volume,
78 ObjectInfoCB->FileId.Vnode,
79 ObjectInfoCB->FileId.Unique,
82 if( AuthGroup != NULL)
84 RtlFreeUnicodeString( &uniGUID);
88 // Initialize the directory enumeration buffer for the directory
91 pBuffer = AFSExAllocatePoolWithTag( PagedPool,
92 AFS_DIR_ENUM_BUFFER_LEN,
98 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
101 RtlZeroMemory( pBuffer,
102 AFS_DIR_ENUM_BUFFER_LEN);
104 ulResultLen = AFS_DIR_ENUM_BUFFER_LEN;
107 // Use the payload buffer for information we will pass to the service
110 pDirQueryCB = (AFSDirQueryCB *)pBuffer;
112 pDirQueryCB->EnumHandle = 0;
117 ulRequestFlags |= AFS_REQUEST_FLAG_FAST_REQUEST;
121 // Loop on the information
128 // Go and retrieve the directory contents
131 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_DIR_ENUM,
135 &ObjectInfoCB->FileId,
137 sizeof( AFSDirQueryCB),
141 if( ntStatus != STATUS_SUCCESS ||
145 if( ntStatus == STATUS_NO_MORE_FILES ||
146 ntStatus == STATUS_NO_MORE_ENTRIES)
149 ntStatus = STATUS_SUCCESS;
154 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
155 AFS_TRACE_LEVEL_ERROR,
156 "AFSEnumerateDirectory Failed to enumerate directory Status %08lX\n",
163 pDirEnumResponse = (AFSDirEnumResp *)pBuffer;
165 pCurrentDirEntry = (AFSDirEnumEntry *)pDirEnumResponse->Entry;
168 // Remove the leading header from the processed length
171 ulResultLen -= FIELD_OFFSET( AFSDirEnumResp, Entry);
173 while( ulResultLen > 0)
176 uniDirName.Length = (USHORT)pCurrentDirEntry->FileNameLength;
178 uniDirName.MaximumLength = uniDirName.Length;
180 uniDirName.Buffer = (WCHAR *)((char *)pCurrentDirEntry + pCurrentDirEntry->FileNameOffset);
182 uniTargetName.Length = (USHORT)pCurrentDirEntry->TargetNameLength;
184 uniTargetName.MaximumLength = uniTargetName.Length;
186 uniTargetName.Buffer = (WCHAR *)((char *)pCurrentDirEntry + pCurrentDirEntry->TargetNameOffset);
189 // Be sure we don't have this entry in the case sensitive tree
192 ulCRC = AFSGenerateCRC( &uniDirName,
195 AFSLocateCaseSensitiveDirEntry( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
199 if( pDirNode != NULL)
203 // Duplicate entry, skip it
206 ulEntryLength = QuadAlign( sizeof( AFSDirEnumEntry) +
208 uniTargetName.Length);
210 pCurrentDirEntry = (AFSDirEnumEntry *)((char *)pCurrentDirEntry + ulEntryLength);
212 if( ulResultLen >= ulEntryLength)
214 ulResultLen -= ulEntryLength;
224 pDirNode = AFSInitDirEntry( ObjectInfoCB,
228 (ULONG)InterlockedIncrement( &ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.ContentIndex));
230 if( pDirNode == NULL)
233 ntStatus = STATUS_INSUFFICIENT_RESOURCES;
239 // Set up the entry length
242 ulEntryLength = QuadAlign( sizeof( AFSDirEnumEntry) +
243 pCurrentDirEntry->FileNameLength +
244 pCurrentDirEntry->TargetNameLength);
247 // Init the short name if we have one
250 if( pCurrentDirEntry->ShortNameLength > 0)
253 UNICODE_STRING uniShortName;
255 pDirNode->NameInformation.ShortNameLength = pCurrentDirEntry->ShortNameLength;
257 RtlCopyMemory( pDirNode->NameInformation.ShortName,
258 pCurrentDirEntry->ShortName,
259 pDirNode->NameInformation.ShortNameLength);
262 // Generate the short name index
265 uniShortName.Length = pDirNode->NameInformation.ShortNameLength;
266 uniShortName.Buffer = pDirNode->NameInformation.ShortName;
268 pDirNode->Type.Data.ShortNameTreeEntry.HashIndex = AFSGenerateCRC( &uniShortName,
271 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
272 AFS_TRACE_LEVEL_VERBOSE,
273 "AFSEnumerateDirectory Initialized short name %wZ for DE %p for %wZ\n",
276 &pDirNode->NameInformation.FileName);
280 // Insert the node into the name tree
283 ASSERT( ExIsResourceAcquiredExclusiveLite( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock));
285 if( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead == NULL)
288 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = pDirNode;
290 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
291 AFS_TRACE_LEVEL_VERBOSE,
292 "AFSEnumerateDirectory Insert DE %p to head of case sensitive tree for %wZ\n",
294 &pDirNode->NameInformation.FileName);
299 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
300 AFS_TRACE_LEVEL_VERBOSE,
301 "AFSEnumerateDirectory Insert DE %p to case sensitive tree for %wZ\n",
303 &pDirNode->NameInformation.FileName);
305 AFSInsertCaseSensitiveDirEntry( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
309 if( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead == NULL)
312 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
313 AFS_TRACE_LEVEL_VERBOSE,
314 "AFSEnumerateDirectory Insert DE %p to head of case insensitive tree for %wZ\n",
316 &pDirNode->NameInformation.FileName);
318 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = pDirNode;
320 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
325 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
326 AFS_TRACE_LEVEL_VERBOSE,
327 "AFSEnumerateDirectory Insert DE %p to case insensitive tree for %wZ\n",
329 &pDirNode->NameInformation.FileName);
331 AFSInsertCaseInsensitiveDirEntry( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
335 if( ObjectInfoCB->Specific.Directory.DirectoryNodeListHead == NULL)
338 ObjectInfoCB->Specific.Directory.DirectoryNodeListHead = pDirNode;
343 ObjectInfoCB->Specific.Directory.DirectoryNodeListTail->ListEntry.fLink = pDirNode;
345 pDirNode->ListEntry.bLink = ObjectInfoCB->Specific.Directory.DirectoryNodeListTail;
348 ObjectInfoCB->Specific.Directory.DirectoryNodeListTail = pDirNode;
350 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST);
352 InterlockedIncrement( &ObjectInfoCB->Specific.Directory.DirectoryNodeCount);
354 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
355 AFS_TRACE_LEVEL_VERBOSE,
356 "AFSEnumerateDirectory Adding entry %wZ Inc Count %d to parent FID %08lX-%08lX-%08lX-%08lX\n",
357 &pDirNode->NameInformation.FileName,
358 ObjectInfoCB->Specific.Directory.DirectoryNodeCount,
359 ObjectInfoCB->FileId.Cell,
360 ObjectInfoCB->FileId.Volume,
361 ObjectInfoCB->FileId.Vnode,
362 ObjectInfoCB->FileId.Unique);
364 if( pDirNode->Type.Data.ShortNameTreeEntry.HashIndex != 0)
368 // Insert the short name entry if we have a valid short name
371 if( ObjectInfoCB->Specific.Directory.ShortNameTree == NULL)
374 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
375 AFS_TRACE_LEVEL_VERBOSE,
376 "AFSEnumerateDirectory Insert DE %p to head of shortname tree for %wZ\n",
378 &pDirNode->NameInformation.FileName);
380 ObjectInfoCB->Specific.Directory.ShortNameTree = pDirNode;
385 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
386 AFS_TRACE_LEVEL_VERBOSE,
387 "AFSEnumerateDirectory Insert DE %p to shortname tree for %wZ\n",
389 &pDirNode->NameInformation.FileName);
391 AFSInsertShortNameDirEntry( ObjectInfoCB->Specific.Directory.ShortNameTree,
400 pCurrentDirEntry = (AFSDirEnumEntry *)((char *)pCurrentDirEntry + ulEntryLength);
402 if( ulResultLen >= ulEntryLength)
404 ulResultLen -= ulEntryLength;
412 ulResultLen = AFS_DIR_ENUM_BUFFER_LEN;
415 // Reset the information in the request buffer since it got trampled
419 pDirQueryCB->EnumHandle = pDirEnumResponse->EnumHandle;
421 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
422 AFS_TRACE_LEVEL_VERBOSE,
423 "AFSEnumerateDirectory EnumHandle %08lX\n",
424 pDirQueryCB->EnumHandle);
427 // If the enumeration handle is -1 then we are done
430 if( ((ULONG)-1) == pDirQueryCB->EnumHandle )
446 AFSExFreePool( pBuffer);
450 // If the processing failed then we should reset the directory content in the event
451 // it is re-enumerated
454 if( !NT_SUCCESS( ntStatus))
457 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
458 AFS_TRACE_LEVEL_ERROR,
459 "AFSEnumerateDirectory Resetting content for FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
460 ObjectInfoCB->FileId.Cell,
461 ObjectInfoCB->FileId.Volume,
462 ObjectInfoCB->FileId.Vnode,
463 ObjectInfoCB->FileId.Unique,
466 AFSResetDirectoryContent( ObjectInfoCB);
474 AFSEnumerateDirectoryNoResponse( IN GUID *AuthGroup,
475 IN AFSFileID *FileId)
478 NTSTATUS ntStatus = STATUS_SUCCESS;
479 AFSDirQueryCB stDirQueryCB;
480 ULONG ulRequestFlags = 0;
486 // Use the payload buffer for information we will pass to the service
489 stDirQueryCB.EnumHandle = 0;
491 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_DIR_ENUM,
496 (void *)&stDirQueryCB,
497 sizeof( AFSDirQueryCB),
501 if( ntStatus != STATUS_SUCCESS)
504 if( ntStatus == STATUS_NO_MORE_FILES ||
505 ntStatus == STATUS_NO_MORE_ENTRIES)
508 ntStatus = STATUS_SUCCESS;
513 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
514 AFS_TRACE_LEVEL_ERROR,
515 "AFSEnumerateDirectoryNoResponse Failed to enumerate directory Status %08lX\n",
525 AFSVerifyDirectoryContent( IN AFSObjectInfoCB *ObjectInfoCB,
529 NTSTATUS ntStatus = STATUS_SUCCESS;
530 void *pBuffer = NULL;
531 ULONG ulResultLen = 0;
532 AFSDirQueryCB *pDirQueryCB;
533 AFSDirEnumEntry *pCurrentDirEntry = NULL;
534 AFSDirectoryCB *pDirNode = NULL;
535 ULONG ulEntryLength = 0;
536 AFSDirEnumResp *pDirEnumResponse = NULL;
537 UNICODE_STRING uniDirName, uniTargetName;
538 ULONG ulRequestFlags = AFS_REQUEST_FLAG_SYNCHRONOUS | AFS_REQUEST_FLAG_FAST_REQUEST;
540 AFSObjectInfoCB *pObjectInfo = NULL;
541 ULONGLONG ullIndex = 0;
542 UNICODE_STRING uniGUID;
548 uniGUID.MaximumLength = 0;
549 uniGUID.Buffer = NULL;
551 if( AuthGroup != NULL)
553 RtlStringFromGUID( *AuthGroup,
557 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
558 AFS_TRACE_LEVEL_VERBOSE,
559 "AFSVerifyDirectoryContent Verifying content for FID %08lX-%08lX-%08lX-%08lX AuthGroup %wZ\n",
560 ObjectInfoCB->FileId.Cell,
561 ObjectInfoCB->FileId.Volume,
562 ObjectInfoCB->FileId.Vnode,
563 ObjectInfoCB->FileId.Unique,
566 if( AuthGroup != NULL)
568 RtlFreeUnicodeString( &uniGUID);
572 // Initialize the directory enumeration buffer for the directory
575 pBuffer = AFSExAllocatePoolWithTag( PagedPool,
576 AFS_DIR_ENUM_BUFFER_LEN,
582 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
585 RtlZeroMemory( pBuffer,
586 AFS_DIR_ENUM_BUFFER_LEN);
588 ulResultLen = AFS_DIR_ENUM_BUFFER_LEN;
591 // Use the payload buffer for information we will pass to the service
594 pDirQueryCB = (AFSDirQueryCB *)pBuffer;
596 pDirQueryCB->EnumHandle = 0;
599 // Loop on the information
606 // Go and retrieve the directory contents
609 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_DIR_ENUM,
613 &ObjectInfoCB->FileId,
615 sizeof( AFSDirQueryCB),
619 if( ntStatus != STATUS_SUCCESS ||
623 if( ntStatus == STATUS_NO_MORE_FILES ||
624 ntStatus == STATUS_NO_MORE_ENTRIES)
627 ntStatus = STATUS_SUCCESS;
632 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
633 AFS_TRACE_LEVEL_ERROR,
634 "AFSVerifyDirectoryContent Failed to enumerate directory Status %08lX\n",
641 pDirEnumResponse = (AFSDirEnumResp *)pBuffer;
643 pCurrentDirEntry = (AFSDirEnumEntry *)pDirEnumResponse->Entry;
646 // Remove the leading header from the processed length
649 ulResultLen -= FIELD_OFFSET( AFSDirEnumResp, Entry);
651 while( ulResultLen > 0)
654 uniDirName.Length = (USHORT)pCurrentDirEntry->FileNameLength;
656 uniDirName.MaximumLength = uniDirName.Length;
658 uniDirName.Buffer = (WCHAR *)((char *)pCurrentDirEntry + pCurrentDirEntry->FileNameOffset);
660 uniTargetName.Length = (USHORT)pCurrentDirEntry->TargetNameLength;
662 uniTargetName.MaximumLength = uniTargetName.Length;
664 uniTargetName.Buffer = (WCHAR *)((char *)pCurrentDirEntry + pCurrentDirEntry->TargetNameOffset);
667 // Does this entry already exist in the directory?
670 ulCRC = AFSGenerateCRC( &uniDirName,
673 ASSERT( ExIsResourceAcquiredExclusiveLite( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock));
675 AFSLocateCaseSensitiveDirEntry( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
681 // Set up the entry length
684 ulEntryLength = QuadAlign( sizeof( AFSDirEnumEntry) +
685 pCurrentDirEntry->FileNameLength +
686 pCurrentDirEntry->TargetNameLength);
688 if( pDirNode != NULL)
692 // Check that the FIDs are the same
695 if( AFSIsEqualFID( &pCurrentDirEntry->FileId,
696 &pDirNode->ObjectInformation->FileId))
699 AFSAcquireShared( ObjectInfoCB->VolumeCB->ObjectInfoTree.TreeLock,
702 ullIndex = AFSCreateLowIndex( &pCurrentDirEntry->FileId);
704 ntStatus = AFSLocateHashEntry( ObjectInfoCB->VolumeCB->ObjectInfoTree.TreeHead,
706 (AFSBTreeEntry **)&pObjectInfo);
708 AFSReleaseResource( ObjectInfoCB->VolumeCB->ObjectInfoTree.TreeLock);
710 if( NT_SUCCESS( ntStatus) &&
715 // Indicate this is a valid entry
718 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID);
720 if( pCurrentDirEntry->ShortNameLength > 0 &&
721 pDirNode->NameInformation.ShortNameLength > 0)
723 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
724 AFS_TRACE_LEVEL_VERBOSE,
725 "AFSVerifyDirectoryContent Verified entry %wZ (%wZ) old short name %S New short name %S\n",
727 &pDirNode->NameInformation.FileName,
728 pDirNode->NameInformation.ShortName,
729 pCurrentDirEntry->ShortName);
731 else if( pCurrentDirEntry->ShortNameLength == 0 &&
732 pDirNode->NameInformation.ShortNameLength > 0)
734 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
735 AFS_TRACE_LEVEL_VERBOSE,
736 "AFSVerifyDirectoryContent Verified entry %wZ (%wZ) old short name %S New short name NULL\n",
738 &pDirNode->NameInformation.FileName,
739 pDirNode->NameInformation.ShortName);
741 else if( pCurrentDirEntry->ShortNameLength > 0 &&
742 pDirNode->NameInformation.ShortNameLength == 0)
744 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
745 AFS_TRACE_LEVEL_VERBOSE,
746 "AFSVerifyDirectoryContent Verified entry %wZ (%wZ) old short name NULL New short name %S\n",
748 &pDirNode->NameInformation.FileName,
749 pCurrentDirEntry->ShortName);
753 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
754 AFS_TRACE_LEVEL_VERBOSE,
755 "AFSVerifyDirectoryContent Verified entry %wZ (%wZ) old short name NULL New short name NULL\n",
757 &pDirNode->NameInformation.FileName);
760 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
761 AFS_TRACE_LEVEL_VERBOSE,
762 "AFSVerifyDirectoryContent Verified entry %wZ for parent FID %08lX-%08lX-%08lX-%08lX\n",
764 ObjectInfoCB->FileId.Cell,
765 ObjectInfoCB->FileId.Volume,
766 ObjectInfoCB->FileId.Vnode,
767 ObjectInfoCB->FileId.Unique);
771 // Update the metadata for the entry
774 if( pObjectInfo->DataVersion.QuadPart == 0 ||
775 pObjectInfo->DataVersion.QuadPart != pCurrentDirEntry->DataVersion.QuadPart)
778 AFSUpdateMetaData( pDirNode,
781 if( pObjectInfo->FileType == AFS_FILE_TYPE_DIRECTORY)
784 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
785 AFS_TRACE_LEVEL_VERBOSE,
786 "AFSVerifyDirectoryContent Setting VERIFY on entry %wZ for FID %08lX-%08lX-%08lX-%08lX\n",
788 ObjectInfoCB->FileId.Cell,
789 ObjectInfoCB->FileId.Volume,
790 ObjectInfoCB->FileId.Vnode,
791 ObjectInfoCB->FileId.Unique);
793 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
794 pObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
795 pObjectInfo->Expiration.QuadPart = 0;
803 pCurrentDirEntry = (AFSDirEnumEntry *)((char *)pCurrentDirEntry + ulEntryLength);
805 if( ulResultLen >= ulEntryLength)
807 ulResultLen -= ulEntryLength;
818 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
819 AFS_TRACE_LEVEL_VERBOSE,
820 "AFSVerifyDirectoryContent Processing dir entry %p %wZ with different FID, same name in parent FID %08lX-%08lX-%08lX-%08lX\n",
822 &pDirNode->NameInformation.FileName,
823 ObjectInfoCB->FileId.Cell,
824 ObjectInfoCB->FileId.Volume,
825 ObjectInfoCB->FileId.Vnode,
826 ObjectInfoCB->FileId.Unique);
829 // Need to tear down this entry and rebuild it below
832 if( pDirNode->OpenReferenceCount == 0)
835 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
836 AFS_TRACE_LEVEL_VERBOSE,
837 "AFSVerifyDirectoryContent Different FIDs - Deleting DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
839 &pDirNode->NameInformation.FileName,
840 ObjectInfoCB->FileId.Cell,
841 ObjectInfoCB->FileId.Volume,
842 ObjectInfoCB->FileId.Vnode,
843 ObjectInfoCB->FileId.Unique,
844 pCurrentDirEntry->FileId.Cell,
845 pCurrentDirEntry->FileId.Volume,
846 pCurrentDirEntry->FileId.Vnode,
847 pCurrentDirEntry->FileId.Unique);
849 AFSDeleteDirEntry( ObjectInfoCB,
855 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_DELETED);
857 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
858 AFS_TRACE_LEVEL_VERBOSE,
859 "AFSVerifyDirectoryContent Different FIDs - removing DE %p for %wZ Old FID %08lX-%08lX-%08lX-%08lX New FID %08lX-%08lX-%08lX-%08lX\n",
861 &pDirNode->NameInformation.FileName,
862 ObjectInfoCB->FileId.Cell,
863 ObjectInfoCB->FileId.Volume,
864 ObjectInfoCB->FileId.Vnode,
865 ObjectInfoCB->FileId.Unique,
866 pCurrentDirEntry->FileId.Cell,
867 pCurrentDirEntry->FileId.Volume,
868 pCurrentDirEntry->FileId.Vnode,
869 pCurrentDirEntry->FileId.Unique);
871 AFSRemoveNameEntry( ObjectInfoCB,
876 pDirNode = AFSInitDirEntry( ObjectInfoCB,
880 (ULONG)InterlockedIncrement( &ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.ContentIndex));
882 if( pDirNode == NULL)
885 ntStatus = STATUS_INSUFFICIENT_RESOURCES;
891 // Init the short name if we have one
894 if( pCurrentDirEntry->ShortNameLength > 0)
897 UNICODE_STRING uniShortName;
899 pDirNode->NameInformation.ShortNameLength = pCurrentDirEntry->ShortNameLength;
901 RtlCopyMemory( pDirNode->NameInformation.ShortName,
902 pCurrentDirEntry->ShortName,
903 pDirNode->NameInformation.ShortNameLength);
906 // Generate the short name index
909 uniShortName.Length = pDirNode->NameInformation.ShortNameLength;
910 uniShortName.Buffer = pDirNode->NameInformation.ShortName;
912 pDirNode->Type.Data.ShortNameTreeEntry.HashIndex = AFSGenerateCRC( &uniShortName,
915 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
916 AFS_TRACE_LEVEL_VERBOSE,
917 "AFSVerifyDirectoryContent NO short name for DE %p for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
919 &pDirNode->NameInformation.FileName,
920 pCurrentDirEntry->FileId.Cell,
921 pCurrentDirEntry->FileId.Volume,
922 pCurrentDirEntry->FileId.Vnode,
923 pCurrentDirEntry->FileId.Unique);
927 // Insert the node into the name tree
930 ASSERT( ExIsResourceAcquiredExclusiveLite( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock));
932 if( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead == NULL)
935 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = pDirNode;
937 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
938 AFS_TRACE_LEVEL_VERBOSE,
939 "AFSVerifyDirectoryContent Insert DE %p to head of case sensitive tree for %wZ\n",
941 &pDirNode->NameInformation.FileName);
946 AFSInsertCaseSensitiveDirEntry( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
949 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
950 AFS_TRACE_LEVEL_VERBOSE,
951 "AFSVerifyDirectoryContent Insert DE %p to case sensitive tree for %wZ\n",
953 &pDirNode->NameInformation.FileName);
956 if( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead == NULL)
959 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = pDirNode;
961 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
963 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
964 AFS_TRACE_LEVEL_VERBOSE,
965 "AFSVerifyDirectoryContent Insert DE %p to head of case insensitive tree for %wZ\n",
967 &pDirNode->NameInformation.FileName);
972 AFSInsertCaseInsensitiveDirEntry( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
975 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
976 AFS_TRACE_LEVEL_VERBOSE,
977 "AFSVerifyDirectoryContent Insert DE %p to case insensitive tree for %wZ\n",
979 &pDirNode->NameInformation.FileName);
982 if( ObjectInfoCB->Specific.Directory.DirectoryNodeListHead == NULL)
985 ObjectInfoCB->Specific.Directory.DirectoryNodeListHead = pDirNode;
990 (ObjectInfoCB->Specific.Directory.DirectoryNodeListTail)->ListEntry.fLink = pDirNode;
992 pDirNode->ListEntry.bLink = ObjectInfoCB->Specific.Directory.DirectoryNodeListTail;
995 ObjectInfoCB->Specific.Directory.DirectoryNodeListTail = pDirNode;
997 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST);
999 InterlockedIncrement( &ObjectInfoCB->Specific.Directory.DirectoryNodeCount);
1001 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
1002 AFS_TRACE_LEVEL_VERBOSE,
1003 "AFSVerifyDirectoryContent Adding entry %wZ Inc Count %d to parent FID %08lX-%08lX-%08lX-%08lX\n",
1004 &pDirNode->NameInformation.FileName,
1005 ObjectInfoCB->Specific.Directory.DirectoryNodeCount,
1006 ObjectInfoCB->FileId.Cell,
1007 ObjectInfoCB->FileId.Volume,
1008 ObjectInfoCB->FileId.Vnode,
1009 ObjectInfoCB->FileId.Unique);
1011 if( pDirNode->Type.Data.ShortNameTreeEntry.HashIndex != 0)
1015 // Insert the short name entry if we have a valid short name
1018 if( ObjectInfoCB->Specific.Directory.ShortNameTree == NULL)
1021 ObjectInfoCB->Specific.Directory.ShortNameTree = pDirNode;
1023 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1024 AFS_TRACE_LEVEL_VERBOSE,
1025 "AFSVerifyDirectoryContent Insert DE %p to head of shortname tree for %wZ\n",
1027 &pDirNode->NameInformation.FileName);
1032 AFSInsertShortNameDirEntry( ObjectInfoCB->Specific.Directory.ShortNameTree,
1035 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1036 AFS_TRACE_LEVEL_VERBOSE,
1037 "AFSVerifyDirectoryContent Insert DE %p to shortname tree for %wZ\n",
1039 &pDirNode->NameInformation.FileName);
1047 pCurrentDirEntry = (AFSDirEnumEntry *)((char *)pCurrentDirEntry + ulEntryLength);
1049 if( ulResultLen >= ulEntryLength)
1051 ulResultLen -= ulEntryLength;
1059 ulResultLen = AFS_DIR_ENUM_BUFFER_LEN;
1062 // Reset the information in the request buffer since it got trampled
1066 pDirQueryCB->EnumHandle = pDirEnumResponse->EnumHandle;
1069 // If the enumeration handle is -1 then we are done
1072 if( ((ULONG)-1) == pDirQueryCB->EnumHandle )
1085 if( pBuffer != NULL)
1088 AFSExFreePool( pBuffer);
1096 AFSNotifyFileCreate( IN GUID *AuthGroup,
1097 IN AFSObjectInfoCB *ParentObjectInfo,
1098 IN PLARGE_INTEGER FileSize,
1099 IN ULONG FileAttributes,
1100 IN UNICODE_STRING *FileName,
1101 OUT AFSDirectoryCB **DirNode)
1104 NTSTATUS ntStatus = STATUS_SUCCESS;
1105 AFSFileCreateCB stCreateCB;
1106 AFSFileCreateResultCB *pResultCB = NULL;
1107 ULONG ulResultLen = 0;
1108 UNICODE_STRING uniTargetName;
1109 AFSDirectoryCB *pDirNode = NULL;
1111 LARGE_INTEGER liOldDataVersion;
1117 // Init the control block for the request
1120 RtlZeroMemory( &stCreateCB,
1121 sizeof( AFSFileCreateCB));
1123 stCreateCB.ParentId = ParentObjectInfo->FileId;
1125 stCreateCB.AllocationSize = *FileSize;
1127 stCreateCB.FileAttributes = FileAttributes;
1129 stCreateCB.EaSize = 0;
1131 liOldDataVersion = ParentObjectInfo->DataVersion;
1134 // Allocate our return buffer
1137 pResultCB = (AFSFileCreateResultCB *)AFSExAllocatePoolWithTag( PagedPool,
1139 AFS_GENERIC_MEMORY_1_TAG);
1141 if( pResultCB == NULL)
1144 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1147 RtlZeroMemory( pResultCB,
1150 ulResultLen = PAGE_SIZE;
1153 // Send the call to the service
1156 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_CREATE_FILE,
1157 AFS_REQUEST_FLAG_SYNCHRONOUS | AFS_REQUEST_FLAG_HOLD_FID,
1162 sizeof( AFSFileCreateCB),
1166 if( ntStatus != STATUS_SUCCESS)
1169 if( NT_SUCCESS( ntStatus))
1172 ntStatus = STATUS_DEVICE_NOT_READY;
1175 try_return( ntStatus);
1179 // We may have raced with an invalidation call and a subsequent re-enumeration of this parent
1180 // and though we created the node, it is already in our list. If this is the case then
1181 // look up the entry rather than create a new entry
1182 // The check is to ensure the DV has been modified
1185 if( liOldDataVersion.QuadPart != pResultCB->ParentDataVersion.QuadPart - 1 ||
1186 liOldDataVersion.QuadPart != ParentObjectInfo->DataVersion.QuadPart)
1189 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1190 AFS_TRACE_LEVEL_VERBOSE,
1191 "AFSNotifyFileCreate Raced with an invalidate call and a re-enumeration for entry %wZ\n",
1195 // We raced so go and lookup the directory entry in the parent
1198 ulCRC = AFSGenerateCRC( FileName,
1201 AFSAcquireShared( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
1204 AFSLocateCaseSensitiveDirEntry( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
1208 AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
1210 if( pDirNode != NULL)
1213 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1214 AFS_TRACE_LEVEL_VERBOSE,
1215 "AFSNotifyFileCreate Located dir entry for file %wZ\n",
1218 *DirNode = pDirNode;
1220 try_return( ntStatus = STATUS_REPARSE);
1224 // We are unsure of our current data so set the verify flag. It may already be set
1225 // but no big deal to reset it
1228 SetFlag( ParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
1230 ParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
1236 // Update the parent data version
1239 ParentObjectInfo->DataVersion = pResultCB->ParentDataVersion;
1242 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1243 AFS_TRACE_LEVEL_VERBOSE,
1244 "AFSNotifyFileCreate Creating new entry %wZ\n",
1248 // Initialize the directory entry
1251 uniTargetName.Length = (USHORT)pResultCB->DirEnum.TargetNameLength;
1253 uniTargetName.MaximumLength = uniTargetName.Length;
1255 uniTargetName.Buffer = (WCHAR *)((char *)&pResultCB->DirEnum + pResultCB->DirEnum.TargetNameOffset);
1257 pDirNode = AFSInitDirEntry( ParentObjectInfo,
1260 &pResultCB->DirEnum,
1261 (ULONG)InterlockedIncrement( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.ContentIndex));
1263 if( pDirNode == NULL)
1266 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1270 // Init the short name if we have one
1273 if( pResultCB->DirEnum.ShortNameLength > 0)
1276 UNICODE_STRING uniShortName;
1278 pDirNode->NameInformation.ShortNameLength = pResultCB->DirEnum.ShortNameLength;
1280 RtlCopyMemory( pDirNode->NameInformation.ShortName,
1281 pResultCB->DirEnum.ShortName,
1282 pDirNode->NameInformation.ShortNameLength);
1285 // Generate the short name index
1288 uniShortName.Length = pDirNode->NameInformation.ShortNameLength;
1289 uniShortName.Buffer = pDirNode->NameInformation.ShortName;
1291 pDirNode->Type.Data.ShortNameTreeEntry.HashIndex = AFSGenerateCRC( &uniShortName,
1294 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1295 AFS_TRACE_LEVEL_VERBOSE,
1296 "AFSNotifyFileCreate Initialized short name %wZ for DE %p for %wZ\n",
1299 &pDirNode->NameInformation.FileName);
1303 // Return the directory node
1306 *DirNode = pDirNode;
1310 if( pResultCB != NULL)
1313 AFSExFreePool( pResultCB);
1321 AFSUpdateFileInformation( IN AFSFileID *ParentFid,
1322 IN AFSObjectInfoCB *ObjectInfo,
1326 NTSTATUS ntStatus = STATUS_SUCCESS;
1327 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1328 AFSFileUpdateCB stUpdateCB;
1329 ULONG ulResultLen = 0;
1330 AFSFileUpdateResultCB *pUpdateResultCB = NULL;
1336 // Init the control block for the request
1339 RtlZeroMemory( &stUpdateCB,
1340 sizeof( AFSFileUpdateCB));
1342 stUpdateCB.AllocationSize = ObjectInfo->EndOfFile;
1344 stUpdateCB.FileAttributes = ObjectInfo->FileAttributes;
1346 stUpdateCB.EaSize = ObjectInfo->EaSize;
1348 stUpdateCB.ParentId = *ParentFid;
1350 stUpdateCB.LastAccessTime = ObjectInfo->LastAccessTime;
1352 stUpdateCB.CreateTime = ObjectInfo->CreationTime;
1354 stUpdateCB.ChangeTime = ObjectInfo->ChangeTime;
1356 stUpdateCB.LastWriteTime = ObjectInfo->LastWriteTime;
1358 pUpdateResultCB = (AFSFileUpdateResultCB *)AFSExAllocatePoolWithTag( PagedPool,
1360 AFS_UPDATE_RESULT_TAG);
1362 if( pUpdateResultCB == NULL)
1365 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1368 ulResultLen = PAGE_SIZE;
1370 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_UPDATE_FILE,
1371 AFS_REQUEST_FLAG_SYNCHRONOUS,
1374 &ObjectInfo->FileId,
1376 sizeof( AFSFileUpdateCB),
1380 if( ntStatus != STATUS_SUCCESS)
1383 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1384 AFS_TRACE_LEVEL_ERROR,
1385 "AFSUpdateFileInformation failed FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1386 ObjectInfo->FileId.Cell,
1387 ObjectInfo->FileId.Volume,
1388 ObjectInfo->FileId.Vnode,
1389 ObjectInfo->FileId.Unique,
1392 try_return( ntStatus);
1396 // Update the data version
1399 ObjectInfo->DataVersion = pUpdateResultCB->DirEnum.DataVersion;
1403 if( pUpdateResultCB != NULL)
1406 AFSExFreePool( pUpdateResultCB);
1414 AFSNotifyDelete( IN AFSDirectoryCB *DirectoryCB,
1415 IN BOOLEAN CheckOnly)
1417 NTSTATUS ntStatus = STATUS_SUCCESS;
1418 ULONG ulResultLen = 0;
1419 AFSFileDeleteCB stDelete;
1420 AFSFileDeleteResultCB stDeleteResult;
1421 ULONG ulRequestFlags = AFS_REQUEST_FLAG_SYNCHRONOUS;
1422 GUID *pAuthGroup = NULL;
1427 stDelete.ParentId = DirectoryCB->ObjectInformation->ParentObjectInformation->FileId;
1429 stDelete.ProcessId = (ULONGLONG)PsGetCurrentProcessId();
1431 ulResultLen = sizeof( AFSFileDeleteResultCB);
1435 ulRequestFlags |= AFS_REQUEST_FLAG_CHECK_ONLY;
1438 if( DirectoryCB->ObjectInformation->Fcb != NULL)
1440 pAuthGroup = &DirectoryCB->ObjectInformation->Fcb->AuthGroup;
1443 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_DELETE_FILE,
1446 &DirectoryCB->NameInformation.FileName,
1447 &DirectoryCB->ObjectInformation->FileId,
1449 sizeof( AFSFileDeleteCB),
1453 if( ntStatus != STATUS_SUCCESS)
1456 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1457 AFS_TRACE_LEVEL_ERROR,
1458 "AFSNotifyDelete failed FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1459 &DirectoryCB->ObjectInformation->FileId.Cell,
1460 &DirectoryCB->ObjectInformation->FileId.Volume,
1461 &DirectoryCB->ObjectInformation->FileId.Vnode,
1462 &DirectoryCB->ObjectInformation->FileId.Unique,
1465 try_return( ntStatus);
1472 // Update the parent data version
1475 if( DirectoryCB->ObjectInformation->ParentObjectInformation->DataVersion.QuadPart != stDeleteResult.ParentDataVersion.QuadPart)
1478 SetFlag( DirectoryCB->ObjectInformation->ParentObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
1480 DirectoryCB->ObjectInformation->ParentObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
1493 AFSNotifyRename( IN AFSObjectInfoCB *ObjectInfo,
1494 IN AFSObjectInfoCB *ParentObjectInfo,
1495 IN AFSObjectInfoCB *TargetParentObjectInfo,
1496 IN AFSDirectoryCB *DirectoryCB,
1497 IN UNICODE_STRING *TargetName,
1498 OUT AFSFileID *UpdatedFID)
1501 NTSTATUS ntStatus = STATUS_SUCCESS;
1502 AFSFileRenameCB *pRenameCB = NULL;
1503 AFSFileRenameResultCB *pRenameResultCB = NULL;
1504 ULONG ulResultLen = 0;
1505 GUID *pAuthGroup = NULL;
1511 // Init the control block for the request
1514 pRenameCB = (AFSFileRenameCB *)AFSExAllocatePoolWithTag( PagedPool,
1516 AFS_RENAME_REQUEST_TAG);
1518 if( pRenameCB == NULL)
1521 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1524 RtlZeroMemory( pRenameCB,
1527 pRenameCB->SourceParentId = ParentObjectInfo->FileId;
1529 pRenameCB->TargetParentId = TargetParentObjectInfo->FileId;
1531 pRenameCB->TargetNameLength = TargetName->Length;
1533 RtlCopyMemory( pRenameCB->TargetName,
1535 TargetName->Length);
1537 if( ObjectInfo->Fcb != NULL)
1539 pAuthGroup = &ObjectInfo->Fcb->AuthGroup;
1543 // Use the same buffer for the result control block
1546 pRenameResultCB = (AFSFileRenameResultCB *)pRenameCB;
1548 ulResultLen = PAGE_SIZE;
1550 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_RENAME_FILE,
1551 AFS_REQUEST_FLAG_SYNCHRONOUS,
1553 &DirectoryCB->NameInformation.FileName,
1554 &ObjectInfo->FileId,
1556 sizeof( AFSFileRenameCB) + TargetName->Length,
1560 if( ntStatus != STATUS_SUCCESS)
1563 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1564 AFS_TRACE_LEVEL_ERROR,
1565 "AFSNotifyRename failed FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1566 ObjectInfo->FileId.Cell,
1567 ObjectInfo->FileId.Volume,
1568 ObjectInfo->FileId.Vnode,
1569 ObjectInfo->FileId.Unique,
1572 try_return( ntStatus);
1576 // Update the information from the returned data
1579 ParentObjectInfo->DataVersion = pRenameResultCB->SourceParentDataVersion;
1581 TargetParentObjectInfo->DataVersion = pRenameResultCB->TargetParentDataVersion;
1584 // Move over the short name
1587 DirectoryCB->NameInformation.ShortNameLength = pRenameResultCB->DirEnum.ShortNameLength;
1589 if( DirectoryCB->NameInformation.ShortNameLength > 0)
1592 RtlCopyMemory( DirectoryCB->NameInformation.ShortName,
1593 pRenameResultCB->DirEnum.ShortName,
1594 DirectoryCB->NameInformation.ShortNameLength);
1597 if( UpdatedFID != NULL)
1600 *UpdatedFID = pRenameResultCB->DirEnum.FileId;
1605 if( pRenameCB != NULL)
1608 AFSExFreePool( pRenameCB);
1616 AFSEvaluateTargetByID( IN AFSObjectInfoCB *ObjectInfo,
1618 IN BOOLEAN FastCall,
1619 OUT AFSDirEnumEntry **DirEnumEntry)
1622 NTSTATUS ntStatus = STATUS_SUCCESS;
1623 AFSEvalTargetCB stTargetID;
1624 ULONG ulResultBufferLength;
1625 AFSDirEnumEntry *pDirEnumCB = NULL;
1626 ULONG ulRequestFlags = AFS_REQUEST_FLAG_SYNCHRONOUS;
1631 RtlZeroMemory( &stTargetID,
1632 sizeof( AFSEvalTargetCB));
1634 if( ObjectInfo->ParentObjectInformation != NULL)
1637 stTargetID.ParentId = ObjectInfo->ParentObjectInformation->FileId;
1641 // Allocate our response buffer
1644 pDirEnumCB = (AFSDirEnumEntry *)AFSExAllocatePoolWithTag( PagedPool,
1646 AFS_GENERIC_MEMORY_2_TAG);
1648 if( pDirEnumCB == NULL)
1651 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1655 // Call to the service to evaluate the fid
1658 ulResultBufferLength = PAGE_SIZE;
1663 ulRequestFlags |= AFS_REQUEST_FLAG_FAST_REQUEST;
1666 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_EVAL_TARGET_BY_ID,
1670 &ObjectInfo->FileId,
1672 sizeof( AFSEvalTargetCB),
1674 &ulResultBufferLength);
1676 if( ntStatus != STATUS_SUCCESS)
1680 // If we received back a STATUS_INVALID_HANDLE then mark the parent as requiring
1684 if( ntStatus == STATUS_INVALID_HANDLE)
1687 if( ObjectInfo->ParentObjectInformation != NULL)
1690 SetFlag( ObjectInfo->ParentObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
1694 try_return( ntStatus);
1698 // Pass back the dir enum entry
1701 if( DirEnumEntry != NULL)
1704 *DirEnumEntry = pDirEnumCB;
1709 AFSExFreePool( pDirEnumCB);
1714 if( !NT_SUCCESS( ntStatus))
1717 if( pDirEnumCB != NULL)
1720 AFSExFreePool( pDirEnumCB);
1723 *DirEnumEntry = NULL;
1731 AFSEvaluateTargetByName( IN GUID *AuthGroup,
1732 IN AFSFileID *ParentFileId,
1733 IN PUNICODE_STRING SourceName,
1734 OUT AFSDirEnumEntry **DirEnumEntry)
1737 NTSTATUS ntStatus = STATUS_SUCCESS;
1738 AFSEvalTargetCB stTargetID;
1739 ULONG ulResultBufferLength;
1740 AFSDirEnumEntry *pDirEnumCB = NULL;
1745 stTargetID.ParentId = *ParentFileId;
1748 // Allocate our response buffer
1751 pDirEnumCB = (AFSDirEnumEntry *)AFSExAllocatePoolWithTag( PagedPool,
1753 AFS_GENERIC_MEMORY_3_TAG);
1755 if( pDirEnumCB == NULL)
1758 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1762 // Call to the service to evaluate the fid
1765 ulResultBufferLength = PAGE_SIZE;
1767 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_EVAL_TARGET_BY_NAME,
1768 AFS_REQUEST_FLAG_SYNCHRONOUS,
1773 sizeof( AFSEvalTargetCB),
1775 &ulResultBufferLength);
1777 if( ntStatus != STATUS_SUCCESS)
1780 try_return( ntStatus);
1784 // Pass back the dir enum entry
1787 if( DirEnumEntry != NULL)
1790 *DirEnumEntry = pDirEnumCB;
1795 AFSExFreePool( pDirEnumCB);
1800 if( !NT_SUCCESS( ntStatus))
1803 if( pDirEnumCB != NULL)
1806 AFSExFreePool( pDirEnumCB);
1809 *DirEnumEntry = NULL;
1817 AFSRetrieveVolumeInformation( IN GUID *AuthGroup,
1818 IN AFSFileID *FileID,
1819 OUT AFSVolumeInfoCB *VolumeInformation)
1822 NTSTATUS ntStatus = STATUS_SUCCESS;
1823 ULONG ulResultLen = 0;
1828 ulResultLen = sizeof( AFSVolumeInfoCB);
1830 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_GET_VOLUME_INFO,
1831 AFS_REQUEST_FLAG_SYNCHRONOUS,
1840 if( ntStatus != STATUS_SUCCESS)
1843 try_return( ntStatus);
1855 AFSNotifyPipeTransceive( IN AFSCcb *Ccb,
1856 IN ULONG InputLength,
1857 IN ULONG OutputLength,
1858 IN void *InputDataBuffer,
1859 OUT void *OutputDataBuffer,
1860 OUT ULONG *BytesReturned)
1863 NTSTATUS ntStatus = STATUS_SUCCESS;
1864 ULONG ulResultLen = 0;
1865 MDL *pInputMdl = NULL, *pOutputMdl = NULL;
1866 void *pInputSystemBuffer = NULL, *pOutputSystemBuffer = NULL;
1867 ULONG ulBufferLength = OutputLength;
1868 AFSPipeIORequestCB *pIoRequest = NULL;
1869 GUID *pAuthGroup = NULL;
1875 // Map the user buffer to a system address
1878 pInputSystemBuffer = AFSLockUserBuffer( InputDataBuffer,
1882 if( pInputSystemBuffer == NULL)
1885 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1888 pIoRequest = (AFSPipeIORequestCB *)AFSExAllocatePoolWithTag( PagedPool,
1889 sizeof( AFSPipeIORequestCB) +
1891 AFS_GENERIC_MEMORY_4_TAG);
1893 if( pIoRequest == NULL)
1896 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1899 RtlZeroMemory( pIoRequest,
1900 sizeof( AFSPipeIORequestCB) + InputLength);
1902 pIoRequest->RequestId = Ccb->RequestID;
1904 pIoRequest->RootId = Ccb->DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation.FileId;
1906 pIoRequest->BufferLength = InputLength;
1908 RtlCopyMemory( (void *)((char *)pIoRequest + sizeof( AFSPipeIORequestCB)),
1912 pOutputSystemBuffer = AFSLockUserBuffer( OutputDataBuffer,
1916 if( pOutputSystemBuffer == NULL)
1919 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1922 if( Ccb->DirectoryCB->ObjectInformation->Fcb != NULL)
1924 pAuthGroup = &Ccb->DirectoryCB->ObjectInformation->Fcb->AuthGroup;
1928 // Send the call to the service
1931 ulResultLen = OutputLength;
1933 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIPE_TRANSCEIVE,
1934 AFS_REQUEST_FLAG_SYNCHRONOUS,
1936 &Ccb->DirectoryCB->NameInformation.FileName,
1939 sizeof( AFSPipeIORequestCB) + InputLength,
1940 pOutputSystemBuffer,
1943 if( ntStatus != STATUS_SUCCESS &&
1944 ntStatus != STATUS_BUFFER_OVERFLOW)
1947 if( NT_SUCCESS( ntStatus))
1950 ntStatus = STATUS_DEVICE_NOT_READY;
1953 try_return( ntStatus);
1957 // Return the bytes processed
1960 *BytesReturned = ulResultLen;
1964 if( pInputMdl != NULL)
1967 MmUnlockPages( pInputMdl);
1969 IoFreeMdl( pInputMdl);
1972 if( pOutputMdl != NULL)
1975 MmUnlockPages( pOutputMdl);
1977 IoFreeMdl( pOutputMdl);
1980 if( pIoRequest != NULL)
1983 AFSExFreePool( pIoRequest);
1991 AFSNotifySetPipeInfo( IN AFSCcb *Ccb,
1992 IN ULONG InformationClass,
1993 IN ULONG InputLength,
1994 IN void *DataBuffer)
1997 NTSTATUS ntStatus = STATUS_SUCCESS;
1998 AFSPipeInfoRequestCB *pInfoRequest = NULL;
1999 GUID *pAuthGroup = NULL;
2004 pInfoRequest = (AFSPipeInfoRequestCB *)AFSExAllocatePoolWithTag( PagedPool,
2005 sizeof( AFSPipeInfoRequestCB) +
2007 AFS_GENERIC_MEMORY_5_TAG);
2009 if( pInfoRequest == NULL)
2012 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2015 RtlZeroMemory( pInfoRequest,
2016 sizeof( AFSPipeInfoRequestCB) + InputLength);
2018 pInfoRequest->RequestId = Ccb->RequestID;
2020 pInfoRequest->RootId = Ccb->DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation.FileId;
2022 pInfoRequest->BufferLength = InputLength;
2024 pInfoRequest->InformationClass = InformationClass;
2026 RtlCopyMemory( (void *)((char *)pInfoRequest + sizeof( AFSPipeInfoRequestCB)),
2030 if( Ccb->DirectoryCB->ObjectInformation->Fcb != NULL)
2032 pAuthGroup = &Ccb->DirectoryCB->ObjectInformation->Fcb->AuthGroup;
2036 // Send the call to the service
2039 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIPE_SET_INFO,
2040 AFS_REQUEST_FLAG_SYNCHRONOUS,
2042 &Ccb->DirectoryCB->NameInformation.FileName,
2045 sizeof( AFSPipeInfoRequestCB) + InputLength,
2049 if( ntStatus != STATUS_SUCCESS)
2052 if( NT_SUCCESS( ntStatus))
2055 ntStatus = STATUS_DEVICE_NOT_READY;
2058 try_return( ntStatus);
2063 if( pInfoRequest != NULL)
2066 AFSExFreePool( pInfoRequest);
2074 AFSNotifyQueryPipeInfo( IN AFSCcb *Ccb,
2075 IN ULONG InformationClass,
2076 IN ULONG OutputLength,
2077 IN void *DataBuffer,
2078 OUT ULONG *BytesReturned)
2081 NTSTATUS ntStatus = STATUS_SUCCESS;
2082 AFSPipeInfoRequestCB stInfoRequest;
2083 ULONG ulBytesProcessed = 0;
2084 GUID *pAuthGroup = NULL;
2089 RtlZeroMemory( &stInfoRequest,
2090 sizeof( AFSPipeInfoRequestCB));
2092 stInfoRequest.RequestId = Ccb->RequestID;
2094 stInfoRequest.RootId = Ccb->DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation.FileId;
2096 stInfoRequest.BufferLength = OutputLength;
2098 stInfoRequest.InformationClass = InformationClass;
2100 ulBytesProcessed = OutputLength;
2102 if( Ccb->DirectoryCB->ObjectInformation->Fcb != NULL)
2104 pAuthGroup = &Ccb->DirectoryCB->ObjectInformation->Fcb->AuthGroup;
2108 // Send the call to the service
2111 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIPE_QUERY_INFO,
2112 AFS_REQUEST_FLAG_SYNCHRONOUS,
2114 &Ccb->DirectoryCB->NameInformation.FileName,
2117 sizeof( AFSPipeInfoRequestCB),
2121 if( ntStatus != STATUS_SUCCESS)
2124 if( NT_SUCCESS( ntStatus))
2127 ntStatus = STATUS_DEVICE_NOT_READY;
2130 try_return( ntStatus);
2133 *BytesReturned = ulBytesProcessed;
2144 AFSReleaseFid( IN AFSFileID *FileId)
2147 NTSTATUS ntStatus = STATUS_SUCCESS;
2152 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_RELEASE_FID,
2167 AFSIsExtentRequestQueued( IN AFSFileID *FileID,
2168 IN LARGE_INTEGER *ExtentOffset,
2172 BOOLEAN bRequestQueued = FALSE;
2173 NTSTATUS ntStatus = STATUS_SUCCESS;
2174 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2175 AFSCommSrvcCB *pCommSrvc = NULL;
2176 AFSPoolEntry *pPoolEntry = NULL;
2177 AFSRequestExtentsCB *pRequestExtents = NULL;
2183 pCommSrvc = &pControlDevExt->Specific.Control.CommServiceCB;
2185 AFSAcquireShared( &pCommSrvc->IrpPoolLock,
2188 pPoolEntry = pCommSrvc->RequestPoolHead;
2190 while( pPoolEntry != NULL)
2193 if( pPoolEntry->RequestType == AFS_REQUEST_TYPE_REQUEST_FILE_EXTENTS)
2196 if( AFSIsEqualFID( &pPoolEntry->FileId, FileID))
2199 pRequestExtents = (AFSRequestExtentsCB *)pPoolEntry->Data;
2201 if( pRequestExtents->ByteOffset.QuadPart == ExtentOffset->QuadPart &&
2202 pRequestExtents->Length == Length)
2205 bRequestQueued = TRUE;
2210 pPoolEntry = pPoolEntry->fLink;
2213 AFSReleaseResource( &pCommSrvc->IrpPoolLock);
2216 return bRequestQueued;