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;
49 AFSDeviceExt *pDeviceExt = NULL;
51 UNICODE_STRING uniFsRtlRegisterUncProviderEx;
52 FsRtlRegisterUncProviderEx_t pFsRtlRegisterUncProviderEx = NULL;
57 RtlInitUnicodeString( &uniDeviceName,
60 RtlInitUnicodeString( &uniFsRtlRegisterUncProviderEx,
61 L"FsRtlRegisterUncProviderEx");
63 pFsRtlRegisterUncProviderEx = (FsRtlRegisterUncProviderEx_t)MmGetSystemRoutineAddress(&uniFsRtlRegisterUncProviderEx);
65 ntStatus = IoCreateDevice( AFSDriverObject,
66 sizeof( AFSDeviceExt),
67 pFsRtlRegisterUncProviderEx ? NULL : &uniDeviceName,
68 FILE_DEVICE_NETWORK_FILE_SYSTEM,
73 if( !NT_SUCCESS( ntStatus))
76 AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING,
77 AFS_TRACE_LEVEL_ERROR,
78 "AFSInitRDRDevice IoCreateDevice failure %08lX\n",
81 try_return( ntStatus);
84 pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
86 RtlZeroMemory( pDeviceExt,
87 sizeof( AFSDeviceExt));
90 // Initialize resources
93 pDeviceExt->Specific.RDR.VolumeTree.TreeLock = &pDeviceExt->Specific.RDR.VolumeTreeLock;
95 ExInitializeResourceLite( pDeviceExt->Specific.RDR.VolumeTree.TreeLock);
97 pDeviceExt->Specific.RDR.VolumeTree.TreeHead = NULL;
99 ExInitializeResourceLite( &pDeviceExt->Specific.RDR.VolumeListLock);
101 pDeviceExt->Specific.RDR.VolumeListHead = NULL;
103 pDeviceExt->Specific.RDR.VolumeListTail = NULL;
105 KeInitializeEvent( &pDeviceExt->Specific.RDR.QueuedReleaseExtentEvent,
109 ExInitializeResourceLite( &pDeviceExt->Specific.RDR.RootCellTreeLock);
111 pDeviceExt->Specific.RDR.RootCellTree.TreeLock = &pDeviceExt->Specific.RDR.RootCellTreeLock;
113 pDeviceExt->Specific.RDR.RootCellTree.TreeHead = NULL;
115 ExInitializeResourceLite( &pDeviceExt->Specific.RDR.ProviderListLock);
117 ntStatus = AFSInitRdrFcb( &pDeviceExt->Fcb);
119 if ( !NT_SUCCESS(ntStatus))
122 AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING,
123 AFS_TRACE_LEVEL_ERROR,
124 "AFSInitRDRDevice AFSInitRdrFcb failure %08lX\n",
127 try_return( ntStatus);
131 // Clear the initializing bit
134 AFSRDRDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
137 // Register this device with MUP with FilterMgr if Vista or above
140 if( pFsRtlRegisterUncProviderEx)
143 ntStatus = pFsRtlRegisterUncProviderEx( &AFSMUPHandle,
147 if ( !NT_SUCCESS( ntStatus))
149 AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING,
150 AFS_TRACE_LEVEL_ERROR,
151 "AFSInitRDRDevice FsRtlRegisterUncProvider failure %08lX\n",
158 ntStatus = FsRtlRegisterUncProvider( &AFSMUPHandle,
162 if ( NT_SUCCESS( ntStatus))
165 IoRegisterFileSystem( AFSRDRDeviceObject);
169 AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING,
170 AFS_TRACE_LEVEL_ERROR,
171 "AFSInitRDRDevice FsRtlRegisterUncProvider failure %08lX\n",
177 // Good to go, all registered and ready to start receiving requests
182 if( !NT_SUCCESS( ntStatus))
186 // Delete our device and bail
189 ExDeleteResourceLite( pDeviceExt->Specific.RDR.VolumeTree.TreeLock);
191 ExDeleteResourceLite( &pDeviceExt->Specific.RDR.VolumeListLock);
193 ExDeleteResourceLite( &pDeviceExt->Specific.RDR.RootCellTreeLock);
195 ExDeleteResourceLite( &pDeviceExt->Specific.RDR.ProviderListLock);
197 IoDeleteDevice( AFSRDRDeviceObject);
199 AFSRDRDeviceObject = NULL;
201 try_return( ntStatus);
209 AFSRDRDeviceControl( IN PDEVICE_OBJECT DeviceObject,
213 NTSTATUS ntStatus = STATUS_SUCCESS;
214 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
215 PFILE_OBJECT pFileObject = pIrpSp->FileObject;
216 BOOLEAN bCompleteIrp = TRUE;
221 switch( pIrpSp->Parameters.DeviceIoControl.IoControlCode)
224 case IOCTL_REDIR_QUERY_PATH:
227 QUERY_PATH_REQUEST *pPathRequest = (QUERY_PATH_REQUEST *)pIrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
228 QUERY_PATH_RESPONSE *pPathResponse = (QUERY_PATH_RESPONSE *)Irp->UserBuffer;
229 UNICODE_STRING uniPathName;
231 ntStatus = STATUS_BAD_NETWORK_PATH;
233 uniPathName.Length = (USHORT)pPathRequest->PathNameLength;
234 uniPathName.MaximumLength = uniPathName.Length;
236 uniPathName.Buffer = pPathRequest->FilePathName;
238 if( uniPathName.Length >= AFSServerName.Length + sizeof( WCHAR))
241 USHORT usLength = uniPathName.Length;
243 uniPathName.Length = AFSServerName.Length;
246 // Skip over the first slash in the name
249 uniPathName.Buffer = &uniPathName.Buffer[ 1];
253 // Check to see if the first (or only) component
254 // of the path matches the server name
257 if( RtlCompareUnicodeString( &AFSServerName,
260 ( usLength == AFSServerName.Length + sizeof( WCHAR) ||
261 uniPathName.Buffer[ AFSServerName.Length / sizeof( WCHAR)] == '\\'))
264 ntStatus = STATUS_SUCCESS;
266 pPathResponse->LengthAccepted = AFSServerName.Length + sizeof( WCHAR);
273 case IOCTL_REDIR_QUERY_PATH_EX:
276 QUERY_PATH_REQUEST_EX *pPathRequest = (QUERY_PATH_REQUEST_EX *)pIrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
277 QUERY_PATH_RESPONSE *pPathResponse = (QUERY_PATH_RESPONSE *)Irp->UserBuffer;
278 UNICODE_STRING uniPathName;
280 ntStatus = STATUS_BAD_NETWORK_PATH;
282 uniPathName.Length = pPathRequest->PathName.Length;
283 uniPathName.MaximumLength = uniPathName.Length;
285 uniPathName.Buffer = pPathRequest->PathName.Buffer;
287 if( uniPathName.Length >= AFSServerName.Length + sizeof( WCHAR))
290 USHORT usLength = uniPathName.Length;
292 uniPathName.Length = AFSServerName.Length;
295 // Skip over the first slash in the name
298 uniPathName.Buffer = &uniPathName.Buffer[ 1];
302 // Check to see if the first (or only) component
303 // of the path matches the server name
306 if( RtlCompareUnicodeString( &AFSServerName,
309 ( usLength == AFSServerName.Length + sizeof( WCHAR) ||
310 uniPathName.Buffer[ AFSServerName.Length / sizeof( WCHAR)] == '\\'))
313 ntStatus = STATUS_SUCCESS;
315 pPathResponse->LengthAccepted = AFSServerName.Length + sizeof( WCHAR);
324 ntStatus = STATUS_INVALID_DEVICE_REQUEST;
332 // Complete the request
335 AFSCompleteRequest( Irp,
344 AFSInitializeRedirector( IN AFSRedirectorInitInfo *RedirInitInfo)
347 NTSTATUS ntStatus = STATUS_SUCCESS;
348 LARGE_INTEGER cacheSizeBytes;
349 AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
350 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
351 OBJECT_ATTRIBUTES stObjectAttribs;
352 IO_STATUS_BLOCK stIoStatus;
353 UNICODE_STRING uniServiceName;
359 // First this is to load the library
362 RtlInitUnicodeString( &uniServiceName,
363 AFS_REDIR_LIBRARY_SERVICE_ENTRY);
365 ntStatus = AFSLoadLibrary( 0,
368 if( !NT_SUCCESS( ntStatus))
371 AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING,
372 AFS_TRACE_LEVEL_ERROR,
373 "AFSInitializeRedirector AFSLoadLibrary failure %08lX\n",
376 try_return( ntStatus);
380 // Save off the cache file information
383 pDevExt->Specific.RDR.CacheBlockSize = RedirInitInfo->CacheBlockSize;
385 pDevExt->Specific.RDR.CacheBlockCount = RedirInitInfo->ExtentCount;
387 pDevExt->Specific.RDR.MaximumRPCLength = RedirInitInfo->MaximumChunkLength;
389 cacheSizeBytes = RedirInitInfo->ExtentCount;
390 cacheSizeBytes.QuadPart *= RedirInitInfo->CacheBlockSize;
392 AFSDumpFileLocation.Length = 0;
394 AFSDumpFileLocation.MaximumLength = (USHORT)RedirInitInfo->DumpFileLocationLength + (4 * sizeof( WCHAR));
396 AFSDumpFileLocation.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
397 AFSDumpFileLocation.MaximumLength,
398 AFS_GENERIC_MEMORY_23_TAG);
400 if( AFSDumpFileLocation.Buffer == NULL)
403 AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING,
404 AFS_TRACE_LEVEL_ERROR,
405 "AFSInitializeRedirector AFS_GENERIC_MEMORY_23_TAG allocation error\n");
407 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
410 RtlCopyMemory( AFSDumpFileLocation.Buffer,
414 AFSDumpFileLocation.Length = 4 * sizeof( WCHAR);
416 RtlCopyMemory( &AFSDumpFileLocation.Buffer[ AFSDumpFileLocation.Length/sizeof( WCHAR)],
417 (void *)((char *)RedirInitInfo + RedirInitInfo->DumpFileLocationOffset),
418 RedirInitInfo->DumpFileLocationLength);
420 AFSDumpFileLocation.Length += (USHORT)RedirInitInfo->DumpFileLocationLength;
423 // Be sure the shutdown flag is not set
426 ClearFlag( pDevExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN);
429 // Set up the Throttles.
431 // Max IO is 10% of the cache, or the value in the registry,
432 // with a minimum of 5Mb (and a maximum of 50% cache size)
437 // collect what the user
439 pDevExt->Specific.RDR.MaxIo.QuadPart = AFSMaxDirectIo;
440 pDevExt->Specific.RDR.MaxIo.QuadPart *= (1024 * 1024);
446 pDevExt->Specific.RDR.MaxIo.QuadPart = cacheSizeBytes.QuadPart / 2;
449 if (pDevExt->Specific.RDR.MaxIo.QuadPart < (5 * 1024 * 1204))
452 pDevExt->Specific.RDR.MaxIo.QuadPart = 5 * 1024 * 1204;
457 // For small cache configurations ...
460 if (pDevExt->Specific.RDR.MaxIo.QuadPart > cacheSizeBytes.QuadPart / 2)
463 pDevExt->Specific.RDR.MaxIo.QuadPart = cacheSizeBytes.QuadPart / 2;
467 // Maximum Dirty is 50% of the cache, or the value in the
468 // registry. No minimum, maximum of 90% of cache size.
473 pDevExt->Specific.RDR.MaxDirty.QuadPart = AFSMaxDirtyFile;
474 pDevExt->Specific.RDR.MaxDirty.QuadPart *= (1024 * 1024);
480 pDevExt->Specific.RDR.MaxDirty.QuadPart = cacheSizeBytes.QuadPart/2;
484 cacheSizeBytes.QuadPart *= 9;
485 cacheSizeBytes.QuadPart = cacheSizeBytes.QuadPart / 10;
487 if (pDevExt->Specific.RDR.MaxDirty.QuadPart > cacheSizeBytes.QuadPart)
489 pDevExt->Specific.RDR.MaxDirty.QuadPart = cacheSizeBytes.QuadPart;
493 // Store off any flags for the file system
496 if( BooleanFlagOn( RedirInitInfo->Flags, AFS_REDIR_INIT_FLAG_HIDE_DOT_FILES))
500 // Hide files which begin with .
503 SetFlag( pDevExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES);
506 if( BooleanFlagOn( RedirInitInfo->Flags, AFS_REDIR_INIT_FLAG_DISABLE_SHORTNAMES))
510 // Hide files which begin with .
513 SetFlag( pDevExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES);
516 if( RedirInitInfo->MemoryCacheOffset.QuadPart != 0 &&
517 RedirInitInfo->MemoryCacheLength.QuadPart != 0)
520 ntStatus = STATUS_INSUFFICIENT_RESOURCES;
523 pDevExt->Specific.RDR.CacheMdl = MmCreateMdl( NULL,
524 (void *)RedirInitInfo->MemoryCacheOffset.QuadPart,
525 RedirInitInfo->MemoryCacheLength.QuadPart);
527 pDevExt->Specific.RDR.CacheMdl = MmCreateMdl( NULL,
528 (void *)RedirInitInfo->MemoryCacheOffset.LowPart,
529 RedirInitInfo->MemoryCacheLength.LowPart);
532 if( pDevExt->Specific.RDR.CacheMdl != NULL)
538 MmProbeAndLockPages( pDevExt->Specific.RDR.CacheMdl,
542 pDevExt->Specific.RDR.CacheBaseAddress = MmGetSystemAddressForMdlSafe( pDevExt->Specific.RDR.CacheMdl,
545 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
548 AFSDumpTraceFilesFnc();
550 IoFreeMdl( pDevExt->Specific.RDR.CacheMdl);
551 pDevExt->Specific.RDR.CacheMdl = NULL;
554 if( pDevExt->Specific.RDR.CacheMdl != NULL)
556 pDevExt->Specific.RDR.CacheLength = RedirInitInfo->MemoryCacheLength;
557 ntStatus = STATUS_SUCCESS;
563 if( !NT_SUCCESS( ntStatus) &&
564 RedirInitInfo->CacheFileNameLength == 0)
567 AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING,
568 AFS_TRACE_LEVEL_ERROR,
569 "AFSInitializeRedirector Unable to initialize cache file %08lX\n",
572 try_return( ntStatus);
575 if( pDevExt->Specific.RDR.CacheMdl == NULL)
578 if( RedirInitInfo->CacheFileNameLength == 0)
581 AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING,
582 AFS_TRACE_LEVEL_ERROR,
583 "AFSInitializeRedirector CacheMdl == NULL\n");
585 try_return( ntStatus = STATUS_INVALID_PARAMETER);
589 // Go open the cache file
592 pDevExt->Specific.RDR.CacheFile.Length = 0;
593 pDevExt->Specific.RDR.CacheFile.MaximumLength = (USHORT)RedirInitInfo->CacheFileNameLength + (4 * sizeof( WCHAR));
595 pDevExt->Specific.RDR.CacheFile.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
596 pDevExt->Specific.RDR.CacheFile.MaximumLength,
597 AFS_GENERIC_MEMORY_24_TAG);
599 if( pDevExt->Specific.RDR.CacheFile.Buffer == NULL)
602 AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING,
603 AFS_TRACE_LEVEL_ERROR,
604 "AFSInitializeRedirector AFS_GENERIC_MEMORY_24_TAG allocation failure\n");
606 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
609 RtlCopyMemory( pDevExt->Specific.RDR.CacheFile.Buffer,
613 pDevExt->Specific.RDR.CacheFile.Length = 4 * sizeof( WCHAR);
615 RtlCopyMemory( &pDevExt->Specific.RDR.CacheFile.Buffer[ pDevExt->Specific.RDR.CacheFile.Length/sizeof( WCHAR)],
616 RedirInitInfo->CacheFileName,
617 RedirInitInfo->CacheFileNameLength);
619 pDevExt->Specific.RDR.CacheFile.Length += (USHORT)RedirInitInfo->CacheFileNameLength;
621 InitializeObjectAttributes( &stObjectAttribs,
622 &pDevExt->Specific.RDR.CacheFile,
623 OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
627 ntStatus = ZwOpenFile( &pDevExt->Specific.RDR.CacheFileHandle,
628 GENERIC_READ | GENERIC_WRITE,
631 FILE_SHARE_READ | FILE_SHARE_WRITE,
632 FILE_WRITE_THROUGH | FILE_RANDOM_ACCESS);
634 if( !NT_SUCCESS( ntStatus))
637 AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING,
638 AFS_TRACE_LEVEL_ERROR,
639 "AFSInitializeRedirector ZwOpenFile failure %08lX\n",
642 try_return( ntStatus);
646 // Map to the fileobject
649 ntStatus = ObReferenceObjectByHandle( pDevExt->Specific.RDR.CacheFileHandle,
653 (void **)&pDevExt->Specific.RDR.CacheFileObject,
656 if( !NT_SUCCESS( ntStatus))
659 AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING,
660 AFS_TRACE_LEVEL_ERROR,
661 "AFSInitializeRedirector ObReferenceObjectByHandle failure %08lX\n",
664 try_return( ntStatus);
668 pDevExt->Specific.RDR.MaxLinkCount = RedirInitInfo->MaxPathLinkCount;
670 pDevExt->Specific.RDR.NameArrayLength = RedirInitInfo->NameArrayLength;
673 // Intialize the library
676 ntStatus = AFSInitializeLibrary( &RedirInitInfo->GlobalFileId,
679 if ( !NT_SUCCESS( ntStatus))
681 AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING,
682 AFS_TRACE_LEVEL_ERROR,
683 "AFSInitializeRedirector AFSInitializeLibrary failure %08lX\n",
689 if( !NT_SUCCESS( ntStatus))
692 if( pDevExt->Specific.RDR.CacheMdl != NULL)
695 MmUnmapLockedPages( pDevExt->Specific.RDR.CacheBaseAddress,
696 pDevExt->Specific.RDR.CacheMdl);
698 MmUnlockPages( pDevExt->Specific.RDR.CacheMdl);
700 ExFreePool( pDevExt->Specific.RDR.CacheMdl);
702 pDevExt->Specific.RDR.CacheMdl = NULL;
703 pDevExt->Specific.RDR.CacheBaseAddress = NULL;
704 pDevExt->Specific.RDR.CacheLength.QuadPart = 0;
707 if( pDevExt->Specific.RDR.CacheFileHandle != NULL)
710 ZwClose( pDevExt->Specific.RDR.CacheFileHandle);
712 pDevExt->Specific.RDR.CacheFileHandle = NULL;
715 if( pDevExt->Specific.RDR.CacheFileObject != NULL)
718 ObDereferenceObject( pDevExt->Specific.RDR.CacheFileObject);
720 pDevExt->Specific.RDR.CacheFileObject = NULL;
723 if( pDevExt->Specific.RDR.CacheFile.Buffer != NULL)
726 ExFreePool( pDevExt->Specific.RDR.CacheFile.Buffer);
728 pDevExt->Specific.RDR.CacheFile.Buffer = NULL;
731 if( AFSDumpFileLocation.Buffer != NULL)
733 ExFreePool( AFSDumpFileLocation.Buffer);
735 AFSDumpFileLocation.Buffer = NULL;
738 if ( pDevExt->Fcb != NULL)
741 AFSRemoveRdrFcb( &pDevExt->Fcb);
746 AFSUnloadLibrary( TRUE);
757 NTSTATUS ntStatus = STATUS_SUCCESS;
758 AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
764 // Unload the library first so we close off any accesses to the cache or underlying
768 AFSUnloadLibrary( TRUE);
771 // Close off the cache file or mapping
774 if( pDevExt->Specific.RDR.CacheMdl != NULL)
777 MmUnmapLockedPages( pDevExt->Specific.RDR.CacheBaseAddress,
778 pDevExt->Specific.RDR.CacheMdl);
780 MmUnlockPages( pDevExt->Specific.RDR.CacheMdl);
782 ExFreePool( pDevExt->Specific.RDR.CacheMdl);
784 pDevExt->Specific.RDR.CacheMdl = NULL;
785 pDevExt->Specific.RDR.CacheBaseAddress = NULL;
786 pDevExt->Specific.RDR.CacheLength.QuadPart = 0;
789 if( pDevExt->Specific.RDR.CacheFileHandle != NULL)
792 ZwClose( pDevExt->Specific.RDR.CacheFileHandle);
794 pDevExt->Specific.RDR.CacheFileHandle = NULL;
797 if( pDevExt->Specific.RDR.CacheFileObject != NULL)
800 ObDereferenceObject( pDevExt->Specific.RDR.CacheFileObject);
802 pDevExt->Specific.RDR.CacheFileObject = NULL;
805 if( pDevExt->Specific.RDR.CacheFile.Buffer != NULL)
808 ExFreePool( pDevExt->Specific.RDR.CacheFile.Buffer);
810 pDevExt->Specific.RDR.CacheFile.Buffer = NULL;
813 if( AFSDumpFileLocation.Buffer != NULL)
815 ExFreePool( AFSDumpFileLocation.Buffer);
817 AFSDumpFileLocation.Buffer = NULL;
820 if ( pDevExt->Fcb != NULL)
823 AFSRemoveRdrFcb( &pDevExt->Fcb);
834 // Function: AFSInitRdrFcb
838 // This function performs Redirector Fcb initialization
842 // A status is returned for the function
846 AFSInitRdrFcb( OUT AFSFcb **RdrFcb)
849 NTSTATUS ntStatus = STATUS_SUCCESS;
851 AFSNonPagedFcb *pNPFcb = NULL;
852 IO_STATUS_BLOCK stIoStatus = {0,0};
853 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
859 // Initialize the root fcb
862 pFcb = (AFSFcb *)AFSExAllocatePoolWithTag( PagedPool,
864 AFS_FCB_ALLOCATION_TAG);
869 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
870 AFS_TRACE_LEVEL_ERROR,
871 "AFSInitRdrFcb Failed to allocate the root fcb\n");
873 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
879 pFcb->Header.NodeByteSize = sizeof( AFSFcb);
880 pFcb->Header.NodeTypeCode = AFS_REDIRECTOR_FCB;
882 pNPFcb = (AFSNonPagedFcb *)AFSExAllocatePoolWithTag( NonPagedPool,
883 sizeof( AFSNonPagedFcb),
884 AFS_FCB_NP_ALLOCATION_TAG);
889 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
890 AFS_TRACE_LEVEL_ERROR,
891 "AFSInitRdrFcb Failed to allocate the non-paged fcb\n");
893 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
896 RtlZeroMemory( pNPFcb,
897 sizeof( AFSNonPagedFcb));
899 pNPFcb->Size = sizeof( AFSNonPagedFcb);
901 pNPFcb->Type = AFS_NON_PAGED_FCB;
904 // OK, initialize the entry
907 ExInitializeFastMutex( &pNPFcb->AdvancedHdrMutex);
909 FsRtlSetupAdvancedHeader( &pFcb->Header, &pNPFcb->AdvancedHdrMutex);
911 ExInitializeResourceLite( &pNPFcb->Resource);
913 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
914 AFS_TRACE_LEVEL_VERBOSE,
915 "AFSInitRootFcb Acquiring Fcb lock %08lX EXCL %08lX\n",
917 PsGetCurrentThread());
919 ExInitializeResourceLite( &pNPFcb->PagingResource);
921 pFcb->Header.Resource = &pNPFcb->Resource;
923 pFcb->Header.PagingIoResource = &pNPFcb->PagingResource;
925 pFcb->NPFcb = pNPFcb;
927 if ( InterlockedCompareExchangePointer( (PVOID *)RdrFcb, pFcb, NULL) != NULL)
930 try_return( ntStatus = STATUS_REPARSE);
935 if( ntStatus != STATUS_SUCCESS)
941 AFSRemoveRdrFcb( &pFcb);
950 // Function: AFSRemoveRdrFcb
954 // This function performs Redirector Fcb removal/deallocation
962 AFSRemoveRdrFcb( IN OUT AFSFcb **RdrFcb)
966 pFcb = (AFSFcb *) InterlockedCompareExchangePointer( (PVOID *)RdrFcb, NULL, (PVOID)(*RdrFcb));
974 if( pFcb->NPFcb != NULL)
981 ExDeleteResourceLite( &pFcb->NPFcb->Resource);
983 ExDeleteResourceLite( &pFcb->NPFcb->PagingResource);
986 // The non paged region
989 AFSExFreePoolWithTag( pFcb->NPFcb, AFS_FCB_NP_ALLOCATION_TAG);
993 // And the Fcb itself
996 AFSExFreePoolWithTag( pFcb, AFS_FCB_ALLOCATION_TAG);