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: AFSRDRSupport.cpp
38 #include "AFSCommon.h"
40 typedef NTSTATUS (*FsRtlRegisterUncProviderEx_t)( PHANDLE MupHandle, PUNICODE_STRING RedirDevName, PDEVICE_OBJECT DeviceObject, ULONG Flags);
46 NTSTATUS ntStatus = STATUS_SUCCESS;
47 UNICODE_STRING uniDeviceName;
48 AFSDeviceExt *pDeviceExt = NULL;
49 UNICODE_STRING uniFsRtlRegisterUncProviderEx;
50 FsRtlRegisterUncProviderEx_t pFsRtlRegisterUncProviderEx = NULL;
55 RtlInitUnicodeString( &uniDeviceName,
58 RtlInitUnicodeString( &uniFsRtlRegisterUncProviderEx,
59 L"FsRtlRegisterUncProviderEx");
61 pFsRtlRegisterUncProviderEx = (FsRtlRegisterUncProviderEx_t)MmGetSystemRoutineAddress(&uniFsRtlRegisterUncProviderEx);
63 ntStatus = IoCreateDevice( AFSDriverObject,
64 sizeof( AFSDeviceExt),
65 pFsRtlRegisterUncProviderEx ? NULL : &uniDeviceName,
66 FILE_DEVICE_NETWORK_FILE_SYSTEM,
71 if( !NT_SUCCESS( ntStatus))
74 AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING,
75 AFS_TRACE_LEVEL_ERROR,
76 "AFSInitRDRDevice IoCreateDevice failure %08lX\n",
79 try_return( ntStatus);
82 pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
84 RtlZeroMemory( pDeviceExt,
85 sizeof( AFSDeviceExt));
88 // Initialize resources
91 pDeviceExt->Specific.RDR.VolumeTree.TreeLock = &pDeviceExt->Specific.RDR.VolumeTreeLock;
93 ExInitializeResourceLite( pDeviceExt->Specific.RDR.VolumeTree.TreeLock);
95 pDeviceExt->Specific.RDR.VolumeTree.TreeHead = NULL;
97 ExInitializeResourceLite( &pDeviceExt->Specific.RDR.VolumeListLock);
99 pDeviceExt->Specific.RDR.VolumeListHead = NULL;
101 pDeviceExt->Specific.RDR.VolumeListTail = NULL;
103 KeInitializeEvent( &pDeviceExt->Specific.RDR.QueuedReleaseExtentEvent,
107 ExInitializeResourceLite( &pDeviceExt->Specific.RDR.RootCellTreeLock);
109 pDeviceExt->Specific.RDR.RootCellTree.TreeLock = &pDeviceExt->Specific.RDR.RootCellTreeLock;
111 pDeviceExt->Specific.RDR.RootCellTree.TreeHead = NULL;
113 ExInitializeResourceLite( &pDeviceExt->Specific.RDR.ProviderListLock);
115 ntStatus = AFSInitRdrFcb( &pDeviceExt->Fcb);
117 if ( !NT_SUCCESS(ntStatus))
120 AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING,
121 AFS_TRACE_LEVEL_ERROR,
122 "AFSInitRDRDevice AFSInitRdrFcb failure %08lX\n",
125 try_return( ntStatus);
129 // Clear the initializing bit
132 AFSRDRDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
135 // Register this device with MUP with FilterMgr if Vista or above
138 if( pFsRtlRegisterUncProviderEx)
141 ntStatus = pFsRtlRegisterUncProviderEx( &AFSMUPHandle,
145 if ( !NT_SUCCESS( ntStatus))
147 AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING,
148 AFS_TRACE_LEVEL_ERROR,
149 "AFSInitRDRDevice FsRtlRegisterUncProvider failure %08lX\n",
156 ntStatus = FsRtlRegisterUncProvider( &AFSMUPHandle,
160 if ( NT_SUCCESS( ntStatus))
163 IoRegisterFileSystem( AFSRDRDeviceObject);
167 AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING,
168 AFS_TRACE_LEVEL_ERROR,
169 "AFSInitRDRDevice FsRtlRegisterUncProvider failure %08lX\n",
175 // Good to go, all registered and ready to start receiving requests
180 if( !NT_SUCCESS( ntStatus))
184 // Delete our device and bail
187 ExDeleteResourceLite( pDeviceExt->Specific.RDR.VolumeTree.TreeLock);
189 ExDeleteResourceLite( &pDeviceExt->Specific.RDR.VolumeListLock);
191 ExDeleteResourceLite( &pDeviceExt->Specific.RDR.RootCellTreeLock);
193 ExDeleteResourceLite( &pDeviceExt->Specific.RDR.ProviderListLock);
195 IoDeleteDevice( AFSRDRDeviceObject);
197 AFSRDRDeviceObject = NULL;
199 try_return( ntStatus);
207 AFSRDRDeviceControl( IN PDEVICE_OBJECT DeviceObject,
210 UNREFERENCED_PARAMETER(DeviceObject);
212 NTSTATUS ntStatus = STATUS_SUCCESS;
213 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
214 BOOLEAN bCompleteIrp = TRUE;
219 switch( pIrpSp->Parameters.DeviceIoControl.IoControlCode)
222 case IOCTL_REDIR_QUERY_PATH:
225 QUERY_PATH_REQUEST *pPathRequest = (QUERY_PATH_REQUEST *)pIrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
226 QUERY_PATH_RESPONSE *pPathResponse = (QUERY_PATH_RESPONSE *)Irp->UserBuffer;
227 UNICODE_STRING uniPathName;
229 ntStatus = STATUS_BAD_NETWORK_PATH;
231 uniPathName.Length = (USHORT)pPathRequest->PathNameLength;
232 uniPathName.MaximumLength = uniPathName.Length;
234 uniPathName.Buffer = pPathRequest->FilePathName;
236 if( uniPathName.Length >= AFSServerName.Length + sizeof( WCHAR))
239 USHORT usLength = uniPathName.Length;
241 uniPathName.Length = AFSServerName.Length;
244 // Skip over the first slash in the name
247 uniPathName.Buffer = &uniPathName.Buffer[ 1];
251 // Check to see if the first (or only) component
252 // of the path matches the server name
255 if( RtlCompareUnicodeString( &AFSServerName,
258 ( usLength == AFSServerName.Length + sizeof( WCHAR) ||
259 uniPathName.Buffer[ AFSServerName.Length / sizeof( WCHAR)] == '\\'))
262 ntStatus = STATUS_SUCCESS;
264 pPathResponse->LengthAccepted = AFSServerName.Length + sizeof( WCHAR);
271 case IOCTL_REDIR_QUERY_PATH_EX:
274 QUERY_PATH_REQUEST_EX *pPathRequest = (QUERY_PATH_REQUEST_EX *)pIrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
275 QUERY_PATH_RESPONSE *pPathResponse = (QUERY_PATH_RESPONSE *)Irp->UserBuffer;
276 UNICODE_STRING uniPathName;
278 ntStatus = STATUS_BAD_NETWORK_PATH;
280 uniPathName.Length = pPathRequest->PathName.Length;
281 uniPathName.MaximumLength = uniPathName.Length;
283 uniPathName.Buffer = pPathRequest->PathName.Buffer;
285 if( uniPathName.Length >= AFSServerName.Length + sizeof( WCHAR))
288 USHORT usLength = uniPathName.Length;
290 uniPathName.Length = AFSServerName.Length;
293 // Skip over the first slash in the name
296 uniPathName.Buffer = &uniPathName.Buffer[ 1];
300 // Check to see if the first (or only) component
301 // of the path matches the server name
304 if( RtlCompareUnicodeString( &AFSServerName,
307 ( usLength == AFSServerName.Length + sizeof( WCHAR) ||
308 uniPathName.Buffer[ AFSServerName.Length / sizeof( WCHAR)] == '\\'))
311 ntStatus = STATUS_SUCCESS;
313 pPathResponse->LengthAccepted = AFSServerName.Length + sizeof( WCHAR);
322 ntStatus = STATUS_INVALID_DEVICE_REQUEST;
330 // Complete the request
333 AFSCompleteRequest( Irp,
342 AFSInitializeRedirector( IN AFSRedirectorInitInfo *RedirInitInfo)
345 NTSTATUS ntStatus = STATUS_SUCCESS;
346 LARGE_INTEGER cacheSizeBytes;
347 AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
348 OBJECT_ATTRIBUTES stObjectAttribs;
349 IO_STATUS_BLOCK stIoStatus;
350 UNICODE_STRING uniServiceName;
356 // First this is to load the library
359 RtlInitUnicodeString( &uniServiceName,
360 AFS_REDIR_LIBRARY_SERVICE_ENTRY);
362 ntStatus = AFSLoadLibrary( 0,
365 if( !NT_SUCCESS( ntStatus))
368 AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING,
369 AFS_TRACE_LEVEL_ERROR,
370 "AFSInitializeRedirector AFSLoadLibrary failure %08lX\n",
373 try_return( ntStatus);
377 // Save off the cache file information
380 pDevExt->Specific.RDR.CacheBlockSize = RedirInitInfo->CacheBlockSize;
382 pDevExt->Specific.RDR.CacheBlockCount = RedirInitInfo->ExtentCount;
384 pDevExt->Specific.RDR.MaximumRPCLength = RedirInitInfo->MaximumChunkLength;
386 cacheSizeBytes = RedirInitInfo->ExtentCount;
387 cacheSizeBytes.QuadPart *= RedirInitInfo->CacheBlockSize;
389 AFSDumpFileLocation.Length = 0;
391 AFSDumpFileLocation.MaximumLength = (USHORT)RedirInitInfo->DumpFileLocationLength + (4 * sizeof( WCHAR));
393 AFSDumpFileLocation.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
394 AFSDumpFileLocation.MaximumLength,
395 AFS_GENERIC_MEMORY_23_TAG);
397 if( AFSDumpFileLocation.Buffer == NULL)
400 AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING,
401 AFS_TRACE_LEVEL_ERROR,
402 "AFSInitializeRedirector AFS_GENERIC_MEMORY_23_TAG allocation error\n");
404 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
407 RtlCopyMemory( AFSDumpFileLocation.Buffer,
411 AFSDumpFileLocation.Length = 4 * sizeof( WCHAR);
413 RtlCopyMemory( &AFSDumpFileLocation.Buffer[ AFSDumpFileLocation.Length/sizeof( WCHAR)],
414 (void *)((char *)RedirInitInfo + RedirInitInfo->DumpFileLocationOffset),
415 RedirInitInfo->DumpFileLocationLength);
417 AFSDumpFileLocation.Length += (USHORT)RedirInitInfo->DumpFileLocationLength;
420 // Be sure the shutdown flag is not set
423 ClearFlag( pDevExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN);
426 // Set up the Throttles.
428 // Max IO is 10% of the cache, or the value in the registry,
429 // with a minimum of 5Mb (and a maximum of 50% cache size)
434 // collect what the user
436 pDevExt->Specific.RDR.MaxIo.QuadPart = AFSMaxDirectIo;
437 pDevExt->Specific.RDR.MaxIo.QuadPart *= (1024 * 1024);
443 pDevExt->Specific.RDR.MaxIo.QuadPart = cacheSizeBytes.QuadPart / 2;
446 if (pDevExt->Specific.RDR.MaxIo.QuadPart < (5 * 1024 * 1204))
449 pDevExt->Specific.RDR.MaxIo.QuadPart = 5 * 1024 * 1204;
454 // For small cache configurations ...
457 if (pDevExt->Specific.RDR.MaxIo.QuadPart > cacheSizeBytes.QuadPart / 2)
460 pDevExt->Specific.RDR.MaxIo.QuadPart = cacheSizeBytes.QuadPart / 2;
464 // Maximum Dirty is 50% of the cache, or the value in the
465 // registry. No minimum, maximum of 90% of cache size.
470 pDevExt->Specific.RDR.MaxDirty.QuadPart = AFSMaxDirtyFile;
471 pDevExt->Specific.RDR.MaxDirty.QuadPart *= (1024 * 1024);
477 pDevExt->Specific.RDR.MaxDirty.QuadPart = cacheSizeBytes.QuadPart/2;
481 cacheSizeBytes.QuadPart *= 9;
482 cacheSizeBytes.QuadPart = cacheSizeBytes.QuadPart / 10;
484 if (pDevExt->Specific.RDR.MaxDirty.QuadPart > cacheSizeBytes.QuadPart)
486 pDevExt->Specific.RDR.MaxDirty.QuadPart = cacheSizeBytes.QuadPart;
490 // Store off any flags for the file system
493 if( BooleanFlagOn( RedirInitInfo->Flags, AFS_REDIR_INIT_FLAG_HIDE_DOT_FILES))
497 // Hide files which begin with .
500 SetFlag( pDevExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES);
503 if( BooleanFlagOn( RedirInitInfo->Flags, AFS_REDIR_INIT_FLAG_DISABLE_SHORTNAMES))
507 // Hide files which begin with .
510 SetFlag( pDevExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES);
514 // Are we performing direct to service IO?
517 if( BooleanFlagOn( RedirInitInfo->Flags, AFS_REDIR_INIT_PERFORM_SERVICE_IO))
521 // Send IO requests directly to service
524 SetFlag( pDevExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO);
529 if( RedirInitInfo->MemoryCacheOffset.QuadPart != 0 &&
530 RedirInitInfo->MemoryCacheLength.QuadPart != 0)
533 ntStatus = STATUS_INSUFFICIENT_RESOURCES;
536 pDevExt->Specific.RDR.CacheMdl = MmCreateMdl( NULL,
537 (void *)RedirInitInfo->MemoryCacheOffset.QuadPart,
538 RedirInitInfo->MemoryCacheLength.QuadPart);
540 pDevExt->Specific.RDR.CacheMdl = MmCreateMdl( NULL,
541 (void *)RedirInitInfo->MemoryCacheOffset.LowPart,
542 RedirInitInfo->MemoryCacheLength.LowPart);
545 if( pDevExt->Specific.RDR.CacheMdl != NULL)
551 MmProbeAndLockPages( pDevExt->Specific.RDR.CacheMdl,
555 pDevExt->Specific.RDR.CacheBaseAddress = MmGetSystemAddressForMdlSafe( pDevExt->Specific.RDR.CacheMdl,
558 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
561 AFSDumpTraceFilesFnc();
563 IoFreeMdl( pDevExt->Specific.RDR.CacheMdl);
564 pDevExt->Specific.RDR.CacheMdl = NULL;
567 if( pDevExt->Specific.RDR.CacheMdl != NULL)
569 pDevExt->Specific.RDR.CacheLength = RedirInitInfo->MemoryCacheLength;
570 ntStatus = STATUS_SUCCESS;
576 if( !NT_SUCCESS( ntStatus) &&
577 RedirInitInfo->CacheFileNameLength == 0)
580 AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING,
581 AFS_TRACE_LEVEL_ERROR,
582 "AFSInitializeRedirector Unable to initialize cache file %08lX\n",
585 try_return( ntStatus);
588 if( pDevExt->Specific.RDR.CacheMdl == NULL)
591 if( RedirInitInfo->CacheFileNameLength == 0)
594 AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING,
595 AFS_TRACE_LEVEL_ERROR,
596 "AFSInitializeRedirector CacheMdl == NULL\n");
598 try_return( ntStatus = STATUS_INVALID_PARAMETER);
602 // Go open the cache file
605 pDevExt->Specific.RDR.CacheFile.Length = 0;
606 pDevExt->Specific.RDR.CacheFile.MaximumLength = (USHORT)RedirInitInfo->CacheFileNameLength + (4 * sizeof( WCHAR));
608 pDevExt->Specific.RDR.CacheFile.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
609 pDevExt->Specific.RDR.CacheFile.MaximumLength,
610 AFS_GENERIC_MEMORY_24_TAG);
612 if( pDevExt->Specific.RDR.CacheFile.Buffer == NULL)
615 AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING,
616 AFS_TRACE_LEVEL_ERROR,
617 "AFSInitializeRedirector AFS_GENERIC_MEMORY_24_TAG allocation failure\n");
619 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
622 RtlCopyMemory( pDevExt->Specific.RDR.CacheFile.Buffer,
626 pDevExt->Specific.RDR.CacheFile.Length = 4 * sizeof( WCHAR);
628 RtlCopyMemory( &pDevExt->Specific.RDR.CacheFile.Buffer[ pDevExt->Specific.RDR.CacheFile.Length/sizeof( WCHAR)],
629 RedirInitInfo->CacheFileName,
630 RedirInitInfo->CacheFileNameLength);
632 pDevExt->Specific.RDR.CacheFile.Length += (USHORT)RedirInitInfo->CacheFileNameLength;
634 InitializeObjectAttributes( &stObjectAttribs,
635 &pDevExt->Specific.RDR.CacheFile,
636 OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
640 ntStatus = ZwOpenFile( &pDevExt->Specific.RDR.CacheFileHandle,
641 GENERIC_READ | GENERIC_WRITE,
644 FILE_SHARE_READ | FILE_SHARE_WRITE,
645 FILE_WRITE_THROUGH | FILE_RANDOM_ACCESS);
647 if( !NT_SUCCESS( ntStatus))
650 AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING,
651 AFS_TRACE_LEVEL_ERROR,
652 "AFSInitializeRedirector ZwOpenFile failure %08lX\n",
655 try_return( ntStatus);
659 // Map to the fileobject
662 ntStatus = ObReferenceObjectByHandle( pDevExt->Specific.RDR.CacheFileHandle,
666 (void **)&pDevExt->Specific.RDR.CacheFileObject,
669 if( !NT_SUCCESS( ntStatus))
672 AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING,
673 AFS_TRACE_LEVEL_ERROR,
674 "AFSInitializeRedirector ObReferenceObjectByHandle failure %08lX\n",
677 try_return( ntStatus);
682 pDevExt->Specific.RDR.MaxLinkCount = RedirInitInfo->MaxPathLinkCount;
684 pDevExt->Specific.RDR.NameArrayLength = RedirInitInfo->NameArrayLength;
687 // Intialize the library
690 ntStatus = AFSInitializeLibrary( &RedirInitInfo->GlobalFileId,
693 if ( !NT_SUCCESS( ntStatus))
695 AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING,
696 AFS_TRACE_LEVEL_ERROR,
697 "AFSInitializeRedirector AFSInitializeLibrary failure %08lX\n",
703 if( !NT_SUCCESS( ntStatus))
706 if( pDevExt->Specific.RDR.CacheMdl != NULL)
709 MmUnmapLockedPages( pDevExt->Specific.RDR.CacheBaseAddress,
710 pDevExt->Specific.RDR.CacheMdl);
712 MmUnlockPages( pDevExt->Specific.RDR.CacheMdl);
714 ExFreePool( pDevExt->Specific.RDR.CacheMdl);
716 pDevExt->Specific.RDR.CacheMdl = NULL;
717 pDevExt->Specific.RDR.CacheBaseAddress = NULL;
718 pDevExt->Specific.RDR.CacheLength.QuadPart = 0;
721 if( pDevExt->Specific.RDR.CacheFileHandle != NULL)
724 ZwClose( pDevExt->Specific.RDR.CacheFileHandle);
726 pDevExt->Specific.RDR.CacheFileHandle = NULL;
729 if( pDevExt->Specific.RDR.CacheFileObject != NULL)
732 ObDereferenceObject( pDevExt->Specific.RDR.CacheFileObject);
734 pDevExt->Specific.RDR.CacheFileObject = NULL;
737 if( pDevExt->Specific.RDR.CacheFile.Buffer != NULL)
740 ExFreePool( pDevExt->Specific.RDR.CacheFile.Buffer);
742 pDevExt->Specific.RDR.CacheFile.Buffer = NULL;
745 if( AFSDumpFileLocation.Buffer != NULL)
747 ExFreePool( AFSDumpFileLocation.Buffer);
749 AFSDumpFileLocation.Buffer = NULL;
752 if ( pDevExt->Fcb != NULL)
755 AFSRemoveRdrFcb( &pDevExt->Fcb);
760 AFSUnloadLibrary( TRUE);
771 NTSTATUS ntStatus = STATUS_SUCCESS;
772 AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
778 // Unload the library first so we close off any accesses to the cache or underlying
782 AFSUnloadLibrary( TRUE);
785 // Close off the cache file or mapping
788 if( pDevExt->Specific.RDR.CacheMdl != NULL)
791 MmUnmapLockedPages( pDevExt->Specific.RDR.CacheBaseAddress,
792 pDevExt->Specific.RDR.CacheMdl);
794 MmUnlockPages( pDevExt->Specific.RDR.CacheMdl);
796 ExFreePool( pDevExt->Specific.RDR.CacheMdl);
798 pDevExt->Specific.RDR.CacheMdl = NULL;
799 pDevExt->Specific.RDR.CacheBaseAddress = NULL;
800 pDevExt->Specific.RDR.CacheLength.QuadPart = 0;
803 if( pDevExt->Specific.RDR.CacheFileHandle != NULL)
806 ZwClose( pDevExt->Specific.RDR.CacheFileHandle);
808 pDevExt->Specific.RDR.CacheFileHandle = NULL;
811 if( pDevExt->Specific.RDR.CacheFileObject != NULL)
814 ObDereferenceObject( pDevExt->Specific.RDR.CacheFileObject);
816 pDevExt->Specific.RDR.CacheFileObject = NULL;
819 if( pDevExt->Specific.RDR.CacheFile.Buffer != NULL)
822 ExFreePool( pDevExt->Specific.RDR.CacheFile.Buffer);
824 pDevExt->Specific.RDR.CacheFile.Buffer = NULL;
827 if( AFSDumpFileLocation.Buffer != NULL)
829 ExFreePool( AFSDumpFileLocation.Buffer);
831 AFSDumpFileLocation.Buffer = NULL;
834 if ( pDevExt->Fcb != NULL)
837 AFSRemoveRdrFcb( &pDevExt->Fcb);
848 // Function: AFSInitRdrFcb
852 // This function performs Redirector Fcb initialization
856 // A status is returned for the function
860 AFSInitRdrFcb( OUT AFSFcb **RdrFcb)
863 NTSTATUS ntStatus = STATUS_SUCCESS;
865 AFSNonPagedFcb *pNPFcb = NULL;
871 // Initialize the root fcb
874 pFcb = (AFSFcb *)AFSExAllocatePoolWithTag( PagedPool,
876 AFS_FCB_ALLOCATION_TAG);
881 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
882 AFS_TRACE_LEVEL_ERROR,
883 "AFSInitRdrFcb Failed to allocate the root fcb\n");
885 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
891 pFcb->Header.NodeByteSize = sizeof( AFSFcb);
892 pFcb->Header.NodeTypeCode = AFS_REDIRECTOR_FCB;
894 pNPFcb = (AFSNonPagedFcb *)AFSExAllocatePoolWithTag( NonPagedPool,
895 sizeof( AFSNonPagedFcb),
896 AFS_FCB_NP_ALLOCATION_TAG);
901 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
902 AFS_TRACE_LEVEL_ERROR,
903 "AFSInitRdrFcb Failed to allocate the non-paged fcb\n");
905 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
908 RtlZeroMemory( pNPFcb,
909 sizeof( AFSNonPagedFcb));
911 pNPFcb->Size = sizeof( AFSNonPagedFcb);
913 pNPFcb->Type = AFS_NON_PAGED_FCB;
916 // OK, initialize the entry
919 ExInitializeFastMutex( &pNPFcb->AdvancedHdrMutex);
921 FsRtlSetupAdvancedHeader( &pFcb->Header, &pNPFcb->AdvancedHdrMutex);
923 ExInitializeResourceLite( &pNPFcb->Resource);
925 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
926 AFS_TRACE_LEVEL_VERBOSE,
927 "AFSInitRootFcb Acquiring Fcb lock %p EXCL %08lX\n",
929 PsGetCurrentThread());
931 ExInitializeResourceLite( &pNPFcb->PagingResource);
933 pFcb->Header.Resource = &pNPFcb->Resource;
935 pFcb->Header.PagingIoResource = &pNPFcb->PagingResource;
937 pFcb->NPFcb = pNPFcb;
939 if ( InterlockedCompareExchangePointer( (PVOID *)RdrFcb, pFcb, NULL) != NULL)
942 try_return( ntStatus = STATUS_REPARSE);
947 if( ntStatus != STATUS_SUCCESS)
953 AFSRemoveRdrFcb( &pFcb);
962 // Function: AFSRemoveRdrFcb
966 // This function performs Redirector Fcb removal/deallocation
974 AFSRemoveRdrFcb( IN OUT AFSFcb **RdrFcb)
978 pFcb = (AFSFcb *) InterlockedCompareExchangePointer( (PVOID *)RdrFcb, NULL, (PVOID)(*RdrFcb));
986 if( pFcb->NPFcb != NULL)
993 ExDeleteResourceLite( &pFcb->NPFcb->Resource);
995 ExDeleteResourceLite( &pFcb->NPFcb->PagingResource);
998 // The non paged region
1001 AFSExFreePoolWithTag( pFcb->NPFcb, AFS_FCB_NP_ALLOCATION_TAG);
1005 // And the Fcb itself
1008 AFSExFreePoolWithTag( pFcb, AFS_FCB_ALLOCATION_TAG);