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,
273 // Insert the node into the name tree
276 ASSERT( ExIsResourceAcquiredExclusiveLite( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock));
278 if( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead == NULL)
281 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = pDirNode;
286 AFSInsertCaseSensitiveDirEntry( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
290 if( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead == NULL)
293 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = pDirNode;
295 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
300 AFSInsertCaseInsensitiveDirEntry( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
304 if( ObjectInfoCB->Specific.Directory.DirectoryNodeListHead == NULL)
307 ObjectInfoCB->Specific.Directory.DirectoryNodeListHead = pDirNode;
312 ObjectInfoCB->Specific.Directory.DirectoryNodeListTail->ListEntry.fLink = pDirNode;
314 pDirNode->ListEntry.bLink = ObjectInfoCB->Specific.Directory.DirectoryNodeListTail;
317 ObjectInfoCB->Specific.Directory.DirectoryNodeListTail = pDirNode;
319 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST);
321 InterlockedIncrement( &ObjectInfoCB->Specific.Directory.DirectoryNodeCount);
323 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
324 AFS_TRACE_LEVEL_VERBOSE,
325 "AFSEnumerateDirectory Adding entry %wZ Inc Count %d to parent FID %08lX-%08lX-%08lX-%08lX\n",
326 &pDirNode->NameInformation.FileName,
327 ObjectInfoCB->Specific.Directory.DirectoryNodeCount,
328 ObjectInfoCB->FileId.Cell,
329 ObjectInfoCB->FileId.Volume,
330 ObjectInfoCB->FileId.Vnode,
331 ObjectInfoCB->FileId.Unique);
333 if( pDirNode->Type.Data.ShortNameTreeEntry.HashIndex != 0)
337 // Insert the short name entry if we have a valid short name
340 if( ObjectInfoCB->Specific.Directory.ShortNameTree == NULL)
343 ObjectInfoCB->Specific.Directory.ShortNameTree = pDirNode;
348 AFSInsertShortNameDirEntry( ObjectInfoCB->Specific.Directory.ShortNameTree,
357 pCurrentDirEntry = (AFSDirEnumEntry *)((char *)pCurrentDirEntry + ulEntryLength);
359 if( ulResultLen >= ulEntryLength)
361 ulResultLen -= ulEntryLength;
369 ulResultLen = AFS_DIR_ENUM_BUFFER_LEN;
372 // Reset the information in the request buffer since it got trampled
376 pDirQueryCB->EnumHandle = pDirEnumResponse->EnumHandle;
378 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
379 AFS_TRACE_LEVEL_VERBOSE,
380 "AFSEnumerateDirectory EnumHandle %08lX\n",
381 pDirQueryCB->EnumHandle);
384 // If the enumeration handle is -1 then we are done
387 if( ((ULONG)-1) == pDirQueryCB->EnumHandle )
403 AFSExFreePool( pBuffer);
407 // If the processing failed then we should reset the directory content in the event
408 // it is re-enumerated
411 if( !NT_SUCCESS( ntStatus))
414 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
415 AFS_TRACE_LEVEL_ERROR,
416 "AFSEnumerateDirectory Resetting content for FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
417 ObjectInfoCB->FileId.Cell,
418 ObjectInfoCB->FileId.Volume,
419 ObjectInfoCB->FileId.Vnode,
420 ObjectInfoCB->FileId.Unique,
423 AFSResetDirectoryContent( ObjectInfoCB);
431 AFSEnumerateDirectoryNoResponse( IN GUID *AuthGroup,
432 IN AFSFileID *FileId)
435 NTSTATUS ntStatus = STATUS_SUCCESS;
436 AFSDirQueryCB stDirQueryCB;
437 ULONG ulRequestFlags = 0;
443 // Use the payload buffer for information we will pass to the service
446 stDirQueryCB.EnumHandle = 0;
448 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_DIR_ENUM,
453 (void *)&stDirQueryCB,
454 sizeof( AFSDirQueryCB),
458 if( ntStatus != STATUS_SUCCESS)
461 if( ntStatus == STATUS_NO_MORE_FILES ||
462 ntStatus == STATUS_NO_MORE_ENTRIES)
465 ntStatus = STATUS_SUCCESS;
470 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
471 AFS_TRACE_LEVEL_ERROR,
472 "AFSEnumerateDirectoryNoResponse Failed to enumerate directory Status %08lX\n",
482 AFSVerifyDirectoryContent( IN AFSObjectInfoCB *ObjectInfoCB,
486 NTSTATUS ntStatus = STATUS_SUCCESS;
487 void *pBuffer = NULL;
488 ULONG ulResultLen = 0;
489 AFSDirQueryCB *pDirQueryCB;
490 AFSDirEnumEntry *pCurrentDirEntry = NULL;
491 AFSDirectoryCB *pDirNode = NULL;
492 ULONG ulEntryLength = 0;
493 AFSDirEnumResp *pDirEnumResponse = NULL;
494 UNICODE_STRING uniDirName, uniTargetName;
495 ULONG ulRequestFlags = AFS_REQUEST_FLAG_SYNCHRONOUS | AFS_REQUEST_FLAG_FAST_REQUEST;
497 AFSObjectInfoCB *pObjectInfo = NULL;
498 ULONGLONG ullIndex = 0;
499 UNICODE_STRING uniGUID;
505 uniGUID.MaximumLength = 0;
506 uniGUID.Buffer = NULL;
508 if( AuthGroup != NULL)
510 RtlStringFromGUID( *AuthGroup,
514 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
515 AFS_TRACE_LEVEL_VERBOSE,
516 "AFSVerifyDirectoryContent Verifying content for FID %08lX-%08lX-%08lX-%08lX AuthGroup %wZ\n",
517 ObjectInfoCB->FileId.Cell,
518 ObjectInfoCB->FileId.Volume,
519 ObjectInfoCB->FileId.Vnode,
520 ObjectInfoCB->FileId.Unique,
523 if( AuthGroup != NULL)
525 RtlFreeUnicodeString( &uniGUID);
529 // Initialize the directory enumeration buffer for the directory
532 pBuffer = AFSExAllocatePoolWithTag( PagedPool,
533 AFS_DIR_ENUM_BUFFER_LEN,
539 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
542 RtlZeroMemory( pBuffer,
543 AFS_DIR_ENUM_BUFFER_LEN);
545 ulResultLen = AFS_DIR_ENUM_BUFFER_LEN;
548 // Use the payload buffer for information we will pass to the service
551 pDirQueryCB = (AFSDirQueryCB *)pBuffer;
553 pDirQueryCB->EnumHandle = 0;
556 // Loop on the information
563 // Go and retrieve the directory contents
566 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_DIR_ENUM,
570 &ObjectInfoCB->FileId,
572 sizeof( AFSDirQueryCB),
576 if( ntStatus != STATUS_SUCCESS ||
580 if( ntStatus == STATUS_NO_MORE_FILES ||
581 ntStatus == STATUS_NO_MORE_ENTRIES)
584 ntStatus = STATUS_SUCCESS;
589 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
590 AFS_TRACE_LEVEL_ERROR,
591 "AFSVerifyDirectoryContent Failed to enumerate directory Status %08lX\n",
598 pDirEnumResponse = (AFSDirEnumResp *)pBuffer;
600 pCurrentDirEntry = (AFSDirEnumEntry *)pDirEnumResponse->Entry;
603 // Remove the leading header from the processed length
606 ulResultLen -= FIELD_OFFSET( AFSDirEnumResp, Entry);
608 while( ulResultLen > 0)
611 uniDirName.Length = (USHORT)pCurrentDirEntry->FileNameLength;
613 uniDirName.MaximumLength = uniDirName.Length;
615 uniDirName.Buffer = (WCHAR *)((char *)pCurrentDirEntry + pCurrentDirEntry->FileNameOffset);
617 uniTargetName.Length = (USHORT)pCurrentDirEntry->TargetNameLength;
619 uniTargetName.MaximumLength = uniTargetName.Length;
621 uniTargetName.Buffer = (WCHAR *)((char *)pCurrentDirEntry + pCurrentDirEntry->TargetNameOffset);
624 // Does this entry already exist in the directory?
627 ulCRC = AFSGenerateCRC( &uniDirName,
630 ASSERT( ExIsResourceAcquiredExclusiveLite( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock));
632 AFSLocateCaseSensitiveDirEntry( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
638 // Set up the entry length
641 ulEntryLength = QuadAlign( sizeof( AFSDirEnumEntry) +
642 pCurrentDirEntry->FileNameLength +
643 pCurrentDirEntry->TargetNameLength);
645 if( pDirNode != NULL)
649 // Check that the FIDs are the same
652 if( AFSIsEqualFID( &pCurrentDirEntry->FileId,
653 &pDirNode->ObjectInformation->FileId))
656 AFSAcquireShared( ObjectInfoCB->VolumeCB->ObjectInfoTree.TreeLock,
659 ullIndex = AFSCreateLowIndex( &pCurrentDirEntry->FileId);
661 ntStatus = AFSLocateHashEntry( ObjectInfoCB->VolumeCB->ObjectInfoTree.TreeHead,
663 (AFSBTreeEntry **)&pObjectInfo);
665 AFSReleaseResource( ObjectInfoCB->VolumeCB->ObjectInfoTree.TreeLock);
667 if( NT_SUCCESS( ntStatus) &&
672 // Indicate this is a valid entry
675 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID);
677 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
678 AFS_TRACE_LEVEL_VERBOSE,
679 "AFSVerifyDirectoryContent Verified entry %wZ for parent FID %08lX-%08lX-%08lX-%08lX\n",
681 ObjectInfoCB->FileId.Cell,
682 ObjectInfoCB->FileId.Volume,
683 ObjectInfoCB->FileId.Vnode,
684 ObjectInfoCB->FileId.Unique);
688 // Update the metadata for the entry
691 if( pObjectInfo->DataVersion.QuadPart == 0 ||
692 pObjectInfo->DataVersion.QuadPart != pCurrentDirEntry->DataVersion.QuadPart)
695 AFSUpdateMetaData( pDirNode,
698 if( pObjectInfo->FileType == AFS_FILE_TYPE_DIRECTORY)
701 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
702 AFS_TRACE_LEVEL_VERBOSE,
703 "AFSVerifyDirectoryContent Setting VERIFY on entry %wZ for FID %08lX-%08lX-%08lX-%08lX\n",
705 ObjectInfoCB->FileId.Cell,
706 ObjectInfoCB->FileId.Volume,
707 ObjectInfoCB->FileId.Vnode,
708 ObjectInfoCB->FileId.Unique);
710 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
711 pObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
712 pObjectInfo->Expiration.QuadPart = 0;
720 pCurrentDirEntry = (AFSDirEnumEntry *)((char *)pCurrentDirEntry + ulEntryLength);
722 if( ulResultLen >= ulEntryLength)
724 ulResultLen -= ulEntryLength;
735 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
736 AFS_TRACE_LEVEL_VERBOSE,
737 "AFSVerifyDirectoryContent Processing dir entry %wZ with different FID, same name in parent FID %08lX-%08lX-%08lX-%08lX\n",
738 &pDirNode->NameInformation.FileName,
739 ObjectInfoCB->FileId.Cell,
740 ObjectInfoCB->FileId.Volume,
741 ObjectInfoCB->FileId.Vnode,
742 ObjectInfoCB->FileId.Unique);
745 // Need to tear down this entry and rebuild it below
748 if( pDirNode->OpenReferenceCount == 0)
751 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
752 AFS_TRACE_LEVEL_VERBOSE,
753 "AFSVerifyDirectoryContent Deleting dir entry %wZ from parent FID %08lX-%08lX-%08lX-%08lX\n",
754 &pDirNode->NameInformation.FileName,
755 ObjectInfoCB->FileId.Cell,
756 ObjectInfoCB->FileId.Volume,
757 ObjectInfoCB->FileId.Vnode,
758 ObjectInfoCB->FileId.Unique);
760 AFSDeleteDirEntry( ObjectInfoCB,
766 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
767 AFS_TRACE_LEVEL_VERBOSE,
768 "AFSVerifyDirectoryContent Setting dir entry %p name %wZ DELETED in parent FID %08lX-%08lX-%08lX-%08lX\n",
770 &pDirNode->NameInformation.FileName,
771 ObjectInfoCB->FileId.Cell,
772 ObjectInfoCB->FileId.Volume,
773 ObjectInfoCB->FileId.Vnode,
774 ObjectInfoCB->FileId.Unique);
776 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_DELETED);
778 AFSRemoveNameEntry( ObjectInfoCB,
783 pDirNode = AFSInitDirEntry( ObjectInfoCB,
787 (ULONG)InterlockedIncrement( &ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.ContentIndex));
789 if( pDirNode == NULL)
792 ntStatus = STATUS_INSUFFICIENT_RESOURCES;
798 // Init the short name if we have one
801 if( pCurrentDirEntry->ShortNameLength > 0)
804 UNICODE_STRING uniShortName;
806 pDirNode->NameInformation.ShortNameLength = pCurrentDirEntry->ShortNameLength;
808 RtlCopyMemory( pDirNode->NameInformation.ShortName,
809 pCurrentDirEntry->ShortName,
810 pDirNode->NameInformation.ShortNameLength);
813 // Generate the short name index
816 uniShortName.Length = pDirNode->NameInformation.ShortNameLength;
817 uniShortName.Buffer = pDirNode->NameInformation.ShortName;
819 pDirNode->Type.Data.ShortNameTreeEntry.HashIndex = AFSGenerateCRC( &uniShortName,
824 // Insert the node into the name tree
827 ASSERT( ExIsResourceAcquiredExclusiveLite( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock));
829 if( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead == NULL)
832 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = pDirNode;
837 AFSInsertCaseSensitiveDirEntry( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
841 if( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead == NULL)
844 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = pDirNode;
846 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
851 AFSInsertCaseInsensitiveDirEntry( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
855 if( ObjectInfoCB->Specific.Directory.DirectoryNodeListHead == NULL)
858 ObjectInfoCB->Specific.Directory.DirectoryNodeListHead = pDirNode;
863 (ObjectInfoCB->Specific.Directory.DirectoryNodeListTail)->ListEntry.fLink = pDirNode;
865 pDirNode->ListEntry.bLink = ObjectInfoCB->Specific.Directory.DirectoryNodeListTail;
868 ObjectInfoCB->Specific.Directory.DirectoryNodeListTail = pDirNode;
870 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST);
872 InterlockedIncrement( &ObjectInfoCB->Specific.Directory.DirectoryNodeCount);
874 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
875 AFS_TRACE_LEVEL_VERBOSE,
876 "AFSVerifyDirectoryContent Adding entry %wZ Inc Count %d to parent FID %08lX-%08lX-%08lX-%08lX\n",
877 &pDirNode->NameInformation.FileName,
878 ObjectInfoCB->Specific.Directory.DirectoryNodeCount,
879 ObjectInfoCB->FileId.Cell,
880 ObjectInfoCB->FileId.Volume,
881 ObjectInfoCB->FileId.Vnode,
882 ObjectInfoCB->FileId.Unique);
884 if( pDirNode->Type.Data.ShortNameTreeEntry.HashIndex != 0)
888 // Insert the short name entry if we have a valid short name
891 if( ObjectInfoCB->Specific.Directory.ShortNameTree == NULL)
894 ObjectInfoCB->Specific.Directory.ShortNameTree = pDirNode;
899 AFSInsertShortNameDirEntry( ObjectInfoCB->Specific.Directory.ShortNameTree,
908 pCurrentDirEntry = (AFSDirEnumEntry *)((char *)pCurrentDirEntry + ulEntryLength);
910 if( ulResultLen >= ulEntryLength)
912 ulResultLen -= ulEntryLength;
920 ulResultLen = AFS_DIR_ENUM_BUFFER_LEN;
923 // Reset the information in the request buffer since it got trampled
927 pDirQueryCB->EnumHandle = pDirEnumResponse->EnumHandle;
930 // If the enumeration handle is -1 then we are done
933 if( ((ULONG)-1) == pDirQueryCB->EnumHandle )
949 AFSExFreePool( pBuffer);
957 AFSNotifyFileCreate( IN GUID *AuthGroup,
958 IN AFSObjectInfoCB *ParentObjectInfo,
959 IN PLARGE_INTEGER FileSize,
960 IN ULONG FileAttributes,
961 IN UNICODE_STRING *FileName,
962 OUT AFSDirectoryCB **DirNode)
965 NTSTATUS ntStatus = STATUS_SUCCESS;
966 AFSFileCreateCB stCreateCB;
967 AFSFileCreateResultCB *pResultCB = NULL;
968 ULONG ulResultLen = 0;
969 UNICODE_STRING uniTargetName;
970 AFSDirectoryCB *pDirNode = NULL;
972 LARGE_INTEGER liOldDataVersion;
978 // Init the control block for the request
981 RtlZeroMemory( &stCreateCB,
982 sizeof( AFSFileCreateCB));
984 stCreateCB.ParentId = ParentObjectInfo->FileId;
986 stCreateCB.AllocationSize = *FileSize;
988 stCreateCB.FileAttributes = FileAttributes;
990 stCreateCB.EaSize = 0;
992 liOldDataVersion = ParentObjectInfo->DataVersion;
995 // Allocate our return buffer
998 pResultCB = (AFSFileCreateResultCB *)AFSExAllocatePoolWithTag( PagedPool,
1000 AFS_GENERIC_MEMORY_1_TAG);
1002 if( pResultCB == NULL)
1005 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1008 RtlZeroMemory( pResultCB,
1011 ulResultLen = PAGE_SIZE;
1014 // Send the call to the service
1017 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_CREATE_FILE,
1018 AFS_REQUEST_FLAG_SYNCHRONOUS | AFS_REQUEST_FLAG_HOLD_FID,
1023 sizeof( AFSFileCreateCB),
1027 if( ntStatus != STATUS_SUCCESS)
1030 if( NT_SUCCESS( ntStatus))
1033 ntStatus = STATUS_DEVICE_NOT_READY;
1036 try_return( ntStatus);
1040 // We may have raced with an invalidation call and a subsequent re-enumeration of this parent
1041 // and though we created the node, it is already in our list. If this is the case then
1042 // look up the entry rather than create a new entry
1043 // The check is to ensure the DV has been modified
1046 if( liOldDataVersion.QuadPart != pResultCB->ParentDataVersion.QuadPart - 1 ||
1047 liOldDataVersion.QuadPart != ParentObjectInfo->DataVersion.QuadPart)
1050 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1051 AFS_TRACE_LEVEL_VERBOSE,
1052 "AFSNotifyFileCreate Raced with an invalidate call and a re-enumeration for entry %wZ\n",
1056 // We raced so go and lookup the directory entry in the parent
1059 ulCRC = AFSGenerateCRC( FileName,
1062 AFSAcquireShared( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
1065 AFSLocateCaseSensitiveDirEntry( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
1069 AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
1071 if( pDirNode != NULL)
1074 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1075 AFS_TRACE_LEVEL_VERBOSE,
1076 "AFSNotifyFileCreate Located dir entry for file %wZ\n",
1079 *DirNode = pDirNode;
1081 try_return( ntStatus = STATUS_REPARSE);
1085 // We are unsure of our current data so set the verify flag. It may already be set
1086 // but no big deal to reset it
1089 SetFlag( ParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
1091 ParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
1097 // Update the parent data version
1100 ParentObjectInfo->DataVersion = pResultCB->ParentDataVersion;
1103 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1104 AFS_TRACE_LEVEL_VERBOSE,
1105 "AFSNotifyFileCreate Creating new entry %wZ\n",
1109 // Initialize the directory entry
1112 uniTargetName.Length = (USHORT)pResultCB->DirEnum.TargetNameLength;
1114 uniTargetName.MaximumLength = uniTargetName.Length;
1116 uniTargetName.Buffer = (WCHAR *)((char *)&pResultCB->DirEnum + pResultCB->DirEnum.TargetNameOffset);
1118 pDirNode = AFSInitDirEntry( ParentObjectInfo,
1121 &pResultCB->DirEnum,
1122 (ULONG)InterlockedIncrement( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.ContentIndex));
1124 if( pDirNode == NULL)
1127 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1131 // Init the short name if we have one
1134 if( pResultCB->DirEnum.ShortNameLength > 0)
1137 UNICODE_STRING uniShortName;
1139 pDirNode->NameInformation.ShortNameLength = pResultCB->DirEnum.ShortNameLength;
1141 RtlCopyMemory( pDirNode->NameInformation.ShortName,
1142 pResultCB->DirEnum.ShortName,
1143 pDirNode->NameInformation.ShortNameLength);
1146 // Generate the short name index
1149 uniShortName.Length = pDirNode->NameInformation.ShortNameLength;
1150 uniShortName.Buffer = pDirNode->NameInformation.ShortName;
1152 pDirNode->Type.Data.ShortNameTreeEntry.HashIndex = AFSGenerateCRC( &uniShortName,
1157 // Return the directory node
1160 *DirNode = pDirNode;
1164 if( pResultCB != NULL)
1167 AFSExFreePool( pResultCB);
1175 AFSUpdateFileInformation( IN AFSFileID *ParentFid,
1176 IN AFSObjectInfoCB *ObjectInfo,
1180 NTSTATUS ntStatus = STATUS_SUCCESS;
1181 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1182 AFSFileUpdateCB stUpdateCB;
1183 ULONG ulResultLen = 0;
1184 AFSFileUpdateResultCB *pUpdateResultCB = NULL;
1190 // Init the control block for the request
1193 RtlZeroMemory( &stUpdateCB,
1194 sizeof( AFSFileUpdateCB));
1196 stUpdateCB.AllocationSize = ObjectInfo->EndOfFile;
1198 stUpdateCB.FileAttributes = ObjectInfo->FileAttributes;
1200 stUpdateCB.EaSize = ObjectInfo->EaSize;
1202 stUpdateCB.ParentId = *ParentFid;
1204 stUpdateCB.LastAccessTime = ObjectInfo->LastAccessTime;
1206 stUpdateCB.CreateTime = ObjectInfo->CreationTime;
1208 stUpdateCB.ChangeTime = ObjectInfo->ChangeTime;
1210 stUpdateCB.LastWriteTime = ObjectInfo->LastWriteTime;
1212 pUpdateResultCB = (AFSFileUpdateResultCB *)AFSExAllocatePoolWithTag( PagedPool,
1214 AFS_UPDATE_RESULT_TAG);
1216 if( pUpdateResultCB == NULL)
1219 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1222 ulResultLen = PAGE_SIZE;
1224 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_UPDATE_FILE,
1225 AFS_REQUEST_FLAG_SYNCHRONOUS,
1228 &ObjectInfo->FileId,
1230 sizeof( AFSFileUpdateCB),
1234 if( ntStatus != STATUS_SUCCESS)
1237 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1238 AFS_TRACE_LEVEL_ERROR,
1239 "AFSUpdateFileInformation failed FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1240 ObjectInfo->FileId.Cell,
1241 ObjectInfo->FileId.Volume,
1242 ObjectInfo->FileId.Vnode,
1243 ObjectInfo->FileId.Unique,
1246 try_return( ntStatus);
1250 // Update the data version
1253 ObjectInfo->DataVersion = pUpdateResultCB->DirEnum.DataVersion;
1257 if( pUpdateResultCB != NULL)
1260 AFSExFreePool( pUpdateResultCB);
1268 AFSNotifyDelete( IN AFSDirectoryCB *DirectoryCB,
1269 IN BOOLEAN CheckOnly)
1271 NTSTATUS ntStatus = STATUS_SUCCESS;
1272 ULONG ulResultLen = 0;
1273 AFSFileDeleteCB stDelete;
1274 AFSFileDeleteResultCB stDeleteResult;
1275 ULONG ulRequestFlags = AFS_REQUEST_FLAG_SYNCHRONOUS;
1276 GUID *pAuthGroup = NULL;
1281 stDelete.ParentId = DirectoryCB->ObjectInformation->ParentObjectInformation->FileId;
1283 stDelete.ProcessId = (ULONGLONG)PsGetCurrentProcessId();
1285 ulResultLen = sizeof( AFSFileDeleteResultCB);
1289 ulRequestFlags |= AFS_REQUEST_FLAG_CHECK_ONLY;
1292 if( DirectoryCB->ObjectInformation->Fcb != NULL)
1294 pAuthGroup = &DirectoryCB->ObjectInformation->Fcb->AuthGroup;
1297 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_DELETE_FILE,
1300 &DirectoryCB->NameInformation.FileName,
1301 &DirectoryCB->ObjectInformation->FileId,
1303 sizeof( AFSFileDeleteCB),
1307 if( ntStatus != STATUS_SUCCESS)
1310 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1311 AFS_TRACE_LEVEL_ERROR,
1312 "AFSNotifyDelete failed FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1313 &DirectoryCB->ObjectInformation->FileId.Cell,
1314 &DirectoryCB->ObjectInformation->FileId.Volume,
1315 &DirectoryCB->ObjectInformation->FileId.Vnode,
1316 &DirectoryCB->ObjectInformation->FileId.Unique,
1319 try_return( ntStatus);
1326 // Update the parent data version
1329 if( DirectoryCB->ObjectInformation->ParentObjectInformation->DataVersion.QuadPart != stDeleteResult.ParentDataVersion.QuadPart)
1332 SetFlag( DirectoryCB->ObjectInformation->ParentObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
1334 DirectoryCB->ObjectInformation->ParentObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
1347 AFSNotifyRename( IN AFSObjectInfoCB *ObjectInfo,
1348 IN AFSObjectInfoCB *ParentObjectInfo,
1349 IN AFSObjectInfoCB *TargetParentObjectInfo,
1350 IN AFSDirectoryCB *DirectoryCB,
1351 IN UNICODE_STRING *TargetName,
1352 OUT AFSFileID *UpdatedFID)
1355 NTSTATUS ntStatus = STATUS_SUCCESS;
1356 AFSFileRenameCB *pRenameCB = NULL;
1357 AFSFileRenameResultCB *pRenameResultCB = NULL;
1358 ULONG ulResultLen = 0;
1359 GUID *pAuthGroup = NULL;
1365 // Init the control block for the request
1368 pRenameCB = (AFSFileRenameCB *)AFSExAllocatePoolWithTag( PagedPool,
1370 AFS_RENAME_REQUEST_TAG);
1372 if( pRenameCB == NULL)
1375 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1378 RtlZeroMemory( pRenameCB,
1381 pRenameCB->SourceParentId = ParentObjectInfo->FileId;
1383 pRenameCB->TargetParentId = TargetParentObjectInfo->FileId;
1385 pRenameCB->TargetNameLength = TargetName->Length;
1387 RtlCopyMemory( pRenameCB->TargetName,
1389 TargetName->Length);
1391 if( ObjectInfo->Fcb != NULL)
1393 pAuthGroup = &ObjectInfo->Fcb->AuthGroup;
1397 // Use the same buffer for the result control block
1400 pRenameResultCB = (AFSFileRenameResultCB *)pRenameCB;
1402 ulResultLen = PAGE_SIZE;
1404 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_RENAME_FILE,
1405 AFS_REQUEST_FLAG_SYNCHRONOUS,
1407 &DirectoryCB->NameInformation.FileName,
1408 &ObjectInfo->FileId,
1410 sizeof( AFSFileRenameCB) + TargetName->Length,
1414 if( ntStatus != STATUS_SUCCESS)
1417 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1418 AFS_TRACE_LEVEL_ERROR,
1419 "AFSNotifyRename failed FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1420 ObjectInfo->FileId.Cell,
1421 ObjectInfo->FileId.Volume,
1422 ObjectInfo->FileId.Vnode,
1423 ObjectInfo->FileId.Unique,
1426 try_return( ntStatus);
1430 // Update the information from the returned data
1433 ParentObjectInfo->DataVersion = pRenameResultCB->SourceParentDataVersion;
1435 TargetParentObjectInfo->DataVersion = pRenameResultCB->TargetParentDataVersion;
1438 // Move over the short name
1441 DirectoryCB->NameInformation.ShortNameLength = pRenameResultCB->DirEnum.ShortNameLength;
1443 if( DirectoryCB->NameInformation.ShortNameLength > 0)
1446 RtlCopyMemory( DirectoryCB->NameInformation.ShortName,
1447 pRenameResultCB->DirEnum.ShortName,
1448 DirectoryCB->NameInformation.ShortNameLength);
1451 if( UpdatedFID != NULL)
1454 *UpdatedFID = pRenameResultCB->DirEnum.FileId;
1459 if( pRenameCB != NULL)
1462 AFSExFreePool( pRenameCB);
1470 AFSEvaluateTargetByID( IN AFSObjectInfoCB *ObjectInfo,
1472 IN BOOLEAN FastCall,
1473 OUT AFSDirEnumEntry **DirEnumEntry)
1476 NTSTATUS ntStatus = STATUS_SUCCESS;
1477 AFSEvalTargetCB stTargetID;
1478 ULONG ulResultBufferLength;
1479 AFSDirEnumEntry *pDirEnumCB = NULL;
1480 ULONG ulRequestFlags = AFS_REQUEST_FLAG_SYNCHRONOUS;
1485 RtlZeroMemory( &stTargetID,
1486 sizeof( AFSEvalTargetCB));
1488 if( ObjectInfo->ParentObjectInformation != NULL)
1491 stTargetID.ParentId = ObjectInfo->ParentObjectInformation->FileId;
1495 // Allocate our response buffer
1498 pDirEnumCB = (AFSDirEnumEntry *)AFSExAllocatePoolWithTag( PagedPool,
1500 AFS_GENERIC_MEMORY_2_TAG);
1502 if( pDirEnumCB == NULL)
1505 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1509 // Call to the service to evaluate the fid
1512 ulResultBufferLength = PAGE_SIZE;
1517 ulRequestFlags |= AFS_REQUEST_FLAG_FAST_REQUEST;
1520 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_EVAL_TARGET_BY_ID,
1524 &ObjectInfo->FileId,
1526 sizeof( AFSEvalTargetCB),
1528 &ulResultBufferLength);
1530 if( ntStatus != STATUS_SUCCESS)
1534 // If we received back a STATUS_INVALID_HANDLE then mark the parent as requiring
1538 if( ntStatus == STATUS_INVALID_HANDLE)
1541 if( ObjectInfo->ParentObjectInformation != NULL)
1544 SetFlag( ObjectInfo->ParentObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
1548 try_return( ntStatus);
1552 // Pass back the dir enum entry
1555 if( DirEnumEntry != NULL)
1558 *DirEnumEntry = pDirEnumCB;
1563 AFSExFreePool( pDirEnumCB);
1568 if( !NT_SUCCESS( ntStatus))
1571 if( pDirEnumCB != NULL)
1574 AFSExFreePool( pDirEnumCB);
1577 *DirEnumEntry = NULL;
1585 AFSEvaluateTargetByName( IN GUID *AuthGroup,
1586 IN AFSFileID *ParentFileId,
1587 IN PUNICODE_STRING SourceName,
1588 OUT AFSDirEnumEntry **DirEnumEntry)
1591 NTSTATUS ntStatus = STATUS_SUCCESS;
1592 AFSEvalTargetCB stTargetID;
1593 ULONG ulResultBufferLength;
1594 AFSDirEnumEntry *pDirEnumCB = NULL;
1599 stTargetID.ParentId = *ParentFileId;
1602 // Allocate our response buffer
1605 pDirEnumCB = (AFSDirEnumEntry *)AFSExAllocatePoolWithTag( PagedPool,
1607 AFS_GENERIC_MEMORY_3_TAG);
1609 if( pDirEnumCB == NULL)
1612 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1616 // Call to the service to evaluate the fid
1619 ulResultBufferLength = PAGE_SIZE;
1621 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_EVAL_TARGET_BY_NAME,
1622 AFS_REQUEST_FLAG_SYNCHRONOUS,
1627 sizeof( AFSEvalTargetCB),
1629 &ulResultBufferLength);
1631 if( ntStatus != STATUS_SUCCESS)
1634 try_return( ntStatus);
1638 // Pass back the dir enum entry
1641 if( DirEnumEntry != NULL)
1644 *DirEnumEntry = pDirEnumCB;
1649 AFSExFreePool( pDirEnumCB);
1654 if( !NT_SUCCESS( ntStatus))
1657 if( pDirEnumCB != NULL)
1660 AFSExFreePool( pDirEnumCB);
1663 *DirEnumEntry = NULL;
1671 AFSRetrieveVolumeInformation( IN GUID *AuthGroup,
1672 IN AFSFileID *FileID,
1673 OUT AFSVolumeInfoCB *VolumeInformation)
1676 NTSTATUS ntStatus = STATUS_SUCCESS;
1677 ULONG ulResultLen = 0;
1682 ulResultLen = sizeof( AFSVolumeInfoCB);
1684 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_GET_VOLUME_INFO,
1685 AFS_REQUEST_FLAG_SYNCHRONOUS,
1694 if( ntStatus != STATUS_SUCCESS)
1697 try_return( ntStatus);
1709 AFSNotifyPipeTransceive( IN AFSCcb *Ccb,
1710 IN ULONG InputLength,
1711 IN ULONG OutputLength,
1712 IN void *InputDataBuffer,
1713 OUT void *OutputDataBuffer,
1714 OUT ULONG *BytesReturned)
1717 NTSTATUS ntStatus = STATUS_SUCCESS;
1718 ULONG ulResultLen = 0;
1719 MDL *pInputMdl = NULL, *pOutputMdl = NULL;
1720 void *pInputSystemBuffer = NULL, *pOutputSystemBuffer = NULL;
1721 ULONG ulBufferLength = OutputLength;
1722 AFSPipeIORequestCB *pIoRequest = NULL;
1723 GUID *pAuthGroup = NULL;
1729 // Map the user buffer to a system address
1732 pInputSystemBuffer = AFSLockUserBuffer( InputDataBuffer,
1736 if( pInputSystemBuffer == NULL)
1739 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1742 pIoRequest = (AFSPipeIORequestCB *)AFSExAllocatePoolWithTag( PagedPool,
1743 sizeof( AFSPipeIORequestCB) +
1745 AFS_GENERIC_MEMORY_4_TAG);
1747 if( pIoRequest == NULL)
1750 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1753 RtlZeroMemory( pIoRequest,
1754 sizeof( AFSPipeIORequestCB) + InputLength);
1756 pIoRequest->RequestId = Ccb->RequestID;
1758 pIoRequest->RootId = Ccb->DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation.FileId;
1760 pIoRequest->BufferLength = InputLength;
1762 RtlCopyMemory( (void *)((char *)pIoRequest + sizeof( AFSPipeIORequestCB)),
1766 pOutputSystemBuffer = AFSLockUserBuffer( OutputDataBuffer,
1770 if( pOutputSystemBuffer == NULL)
1773 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1776 if( Ccb->DirectoryCB->ObjectInformation->Fcb != NULL)
1778 pAuthGroup = &Ccb->DirectoryCB->ObjectInformation->Fcb->AuthGroup;
1782 // Send the call to the service
1785 ulResultLen = OutputLength;
1787 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIPE_TRANSCEIVE,
1788 AFS_REQUEST_FLAG_SYNCHRONOUS,
1790 &Ccb->DirectoryCB->NameInformation.FileName,
1793 sizeof( AFSPipeIORequestCB) + InputLength,
1794 pOutputSystemBuffer,
1797 if( ntStatus != STATUS_SUCCESS &&
1798 ntStatus != STATUS_BUFFER_OVERFLOW)
1801 if( NT_SUCCESS( ntStatus))
1804 ntStatus = STATUS_DEVICE_NOT_READY;
1807 try_return( ntStatus);
1811 // Return the bytes processed
1814 *BytesReturned = ulResultLen;
1818 if( pInputMdl != NULL)
1821 MmUnlockPages( pInputMdl);
1823 IoFreeMdl( pInputMdl);
1826 if( pOutputMdl != NULL)
1829 MmUnlockPages( pOutputMdl);
1831 IoFreeMdl( pOutputMdl);
1834 if( pIoRequest != NULL)
1837 AFSExFreePool( pIoRequest);
1845 AFSNotifySetPipeInfo( IN AFSCcb *Ccb,
1846 IN ULONG InformationClass,
1847 IN ULONG InputLength,
1848 IN void *DataBuffer)
1851 NTSTATUS ntStatus = STATUS_SUCCESS;
1852 AFSPipeInfoRequestCB *pInfoRequest = NULL;
1853 GUID *pAuthGroup = NULL;
1858 pInfoRequest = (AFSPipeInfoRequestCB *)AFSExAllocatePoolWithTag( PagedPool,
1859 sizeof( AFSPipeInfoRequestCB) +
1861 AFS_GENERIC_MEMORY_5_TAG);
1863 if( pInfoRequest == NULL)
1866 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1869 RtlZeroMemory( pInfoRequest,
1870 sizeof( AFSPipeInfoRequestCB) + InputLength);
1872 pInfoRequest->RequestId = Ccb->RequestID;
1874 pInfoRequest->RootId = Ccb->DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation.FileId;
1876 pInfoRequest->BufferLength = InputLength;
1878 pInfoRequest->InformationClass = InformationClass;
1880 RtlCopyMemory( (void *)((char *)pInfoRequest + sizeof( AFSPipeInfoRequestCB)),
1884 if( Ccb->DirectoryCB->ObjectInformation->Fcb != NULL)
1886 pAuthGroup = &Ccb->DirectoryCB->ObjectInformation->Fcb->AuthGroup;
1890 // Send the call to the service
1893 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIPE_SET_INFO,
1894 AFS_REQUEST_FLAG_SYNCHRONOUS,
1896 &Ccb->DirectoryCB->NameInformation.FileName,
1899 sizeof( AFSPipeInfoRequestCB) + InputLength,
1903 if( ntStatus != STATUS_SUCCESS)
1906 if( NT_SUCCESS( ntStatus))
1909 ntStatus = STATUS_DEVICE_NOT_READY;
1912 try_return( ntStatus);
1917 if( pInfoRequest != NULL)
1920 AFSExFreePool( pInfoRequest);
1928 AFSNotifyQueryPipeInfo( IN AFSCcb *Ccb,
1929 IN ULONG InformationClass,
1930 IN ULONG OutputLength,
1931 IN void *DataBuffer,
1932 OUT ULONG *BytesReturned)
1935 NTSTATUS ntStatus = STATUS_SUCCESS;
1936 AFSPipeInfoRequestCB stInfoRequest;
1937 ULONG ulBytesProcessed = 0;
1938 GUID *pAuthGroup = NULL;
1943 RtlZeroMemory( &stInfoRequest,
1944 sizeof( AFSPipeInfoRequestCB));
1946 stInfoRequest.RequestId = Ccb->RequestID;
1948 stInfoRequest.RootId = Ccb->DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation.FileId;
1950 stInfoRequest.BufferLength = OutputLength;
1952 stInfoRequest.InformationClass = InformationClass;
1954 ulBytesProcessed = OutputLength;
1956 if( Ccb->DirectoryCB->ObjectInformation->Fcb != NULL)
1958 pAuthGroup = &Ccb->DirectoryCB->ObjectInformation->Fcb->AuthGroup;
1962 // Send the call to the service
1965 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIPE_QUERY_INFO,
1966 AFS_REQUEST_FLAG_SYNCHRONOUS,
1968 &Ccb->DirectoryCB->NameInformation.FileName,
1971 sizeof( AFSPipeInfoRequestCB),
1975 if( ntStatus != STATUS_SUCCESS)
1978 if( NT_SUCCESS( ntStatus))
1981 ntStatus = STATUS_DEVICE_NOT_READY;
1984 try_return( ntStatus);
1987 *BytesReturned = ulBytesProcessed;
1998 AFSReleaseFid( IN AFSFileID *FileId)
2001 NTSTATUS ntStatus = STATUS_SUCCESS;
2006 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_RELEASE_FID,
2021 AFSIsExtentRequestQueued( IN AFSFileID *FileID,
2022 IN LARGE_INTEGER *ExtentOffset,
2026 BOOLEAN bRequestQueued = FALSE;
2027 NTSTATUS ntStatus = STATUS_SUCCESS;
2028 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2029 AFSCommSrvcCB *pCommSrvc = NULL;
2030 AFSPoolEntry *pPoolEntry = NULL;
2031 AFSRequestExtentsCB *pRequestExtents = NULL;
2037 pCommSrvc = &pControlDevExt->Specific.Control.CommServiceCB;
2039 AFSAcquireShared( &pCommSrvc->IrpPoolLock,
2042 pPoolEntry = pCommSrvc->RequestPoolHead;
2044 while( pPoolEntry != NULL)
2047 if( pPoolEntry->RequestType == AFS_REQUEST_TYPE_REQUEST_FILE_EXTENTS)
2050 if( AFSIsEqualFID( &pPoolEntry->FileId, FileID))
2053 pRequestExtents = (AFSRequestExtentsCB *)pPoolEntry->Data;
2055 if( pRequestExtents->ByteOffset.QuadPart == ExtentOffset->QuadPart &&
2056 pRequestExtents->Length == Length)
2059 bRequestQueued = TRUE;
2064 pPoolEntry = pPoolEntry->fLink;
2067 AFSReleaseResource( &pCommSrvc->IrpPoolLock);
2070 return bRequestQueued;