NTSTATUS ntStatus = STATUS_SUCCESS;
UNICODE_STRING uniDeviceName;
- ULONG ulIndex = 0;
AFSDeviceExt *pDeviceExt = NULL;
- AFSFileID stRootFid;
UNICODE_STRING uniFsRtlRegisterUncProviderEx;
FsRtlRegisterUncProviderEx_t pFsRtlRegisterUncProviderEx = NULL;
+ RTL_OSVERSIONINFOW sysVersion;
+ ULONG ulDeviceCharacteristics = FILE_REMOTE_DEVICE;
__Enter
{
+ RtlZeroMemory( &sysVersion,
+ sizeof( RTL_OSVERSIONINFOW));
+
+ sysVersion.dwOSVersionInfoSize = sizeof( RTL_OSVERSIONINFOW);
+
+ RtlGetVersion( &sysVersion);
+
RtlInitUnicodeString( &uniDeviceName,
AFS_RDR_DEVICE_NAME);
pFsRtlRegisterUncProviderEx = (FsRtlRegisterUncProviderEx_t)MmGetSystemRoutineAddress(&uniFsRtlRegisterUncProviderEx);
+ //
+ // On 32-bit Windows XP, do not set FILE_DEVICE_SECURE_OPEN
+ // flag as it interferes with initial access to \\afs from
+ // limited user accounts.
+ //
+
+ if(!(sysVersion.dwMajorVersion == 5 &&
+ sysVersion.dwMinorVersion == 1))
+ {
+
+ ulDeviceCharacteristics |= FILE_DEVICE_SECURE_OPEN;
+ }
+
ntStatus = IoCreateDevice( AFSDriverObject,
sizeof( AFSDeviceExt),
pFsRtlRegisterUncProviderEx ? NULL : &uniDeviceName,
FILE_DEVICE_NETWORK_FILE_SYSTEM,
- FILE_REMOTE_DEVICE,
+ ulDeviceCharacteristics,
FALSE,
&AFSRDRDeviceObject);
if( !NT_SUCCESS( ntStatus))
{
- AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING,
+ AFSDbgTrace(( AFS_SUBSYSTEM_INIT_PROCESSING,
AFS_TRACE_LEVEL_ERROR,
"AFSInitRDRDevice IoCreateDevice failure %08lX\n",
- ntStatus);
+ ntStatus));
try_return( ntStatus);
}
ExInitializeResourceLite( &pDeviceExt->Specific.RDR.ProviderListLock);
+ ntStatus = AFSInitRdrFcb( &pDeviceExt->Fcb);
+
+ if ( !NT_SUCCESS(ntStatus))
+ {
+
+ AFSDbgTrace(( AFS_SUBSYSTEM_INIT_PROCESSING,
+ AFS_TRACE_LEVEL_ERROR,
+ "AFSInitRDRDevice AFSInitRdrFcb failure %08lX\n",
+ ntStatus));
+
+ try_return( ntStatus);
+ }
+
//
// Clear the initializing bit
//
AFSRDRDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
//
+ // Increase the StackSize to support the extra stack frame required
+ // for use of IoCompletion routines.
+ //
+
+ AFSRDRDeviceObject->StackSize++;
+
+ //
// Register this device with MUP with FilterMgr if Vista or above
//
0);
if ( !NT_SUCCESS( ntStatus))
{
- AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING,
+ AFSDbgTrace(( AFS_SUBSYSTEM_INIT_PROCESSING,
AFS_TRACE_LEVEL_ERROR,
"AFSInitRDRDevice FsRtlRegisterUncProvider failure %08lX\n",
- ntStatus);
+ ntStatus));
}
}
else
}
else
{
- AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING,
+ AFSDbgTrace(( AFS_SUBSYSTEM_INIT_PROCESSING,
AFS_TRACE_LEVEL_ERROR,
"AFSInitRDRDevice FsRtlRegisterUncProvider failure %08lX\n",
- ntStatus);
+ ntStatus));
}
}
+ //
+ // Good to go, all registered and ready to start receiving requests
+ //
+
+try_exit:
+
if( !NT_SUCCESS( ntStatus))
{
try_return( ntStatus);
}
-
- //
- // Good to go, all registered and ready to start receiving requests
- //
-
-try_exit:
-
- if( !NT_SUCCESS( ntStatus))
- {
-
- }
}
return ntStatus;
AFSRDRDeviceControl( IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
+ UNREFERENCED_PARAMETER(DeviceObject);
NTSTATUS ntStatus = STATUS_SUCCESS;
PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
- PFILE_OBJECT pFileObject = pIrpSp->FileObject;
BOOLEAN bCompleteIrp = TRUE;
__Enter
NTSTATUS ntStatus = STATUS_SUCCESS;
LARGE_INTEGER cacheSizeBytes;
AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
- AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
OBJECT_ATTRIBUTES stObjectAttribs;
IO_STATUS_BLOCK stIoStatus;
UNICODE_STRING uniServiceName;
if( !NT_SUCCESS( ntStatus))
{
- AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING,
+ AFSDbgTrace(( AFS_SUBSYSTEM_INIT_PROCESSING,
AFS_TRACE_LEVEL_ERROR,
"AFSInitializeRedirector AFSLoadLibrary failure %08lX\n",
- ntStatus);
+ ntStatus));
try_return( ntStatus);
}
if( AFSDumpFileLocation.Buffer == NULL)
{
- AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING,
+ AFSDbgTrace(( AFS_SUBSYSTEM_INIT_PROCESSING,
AFS_TRACE_LEVEL_ERROR,
- "AFSInitializeRedirector AFS_GENERIC_MEMORY_23_TAG allocation error\n");
+ "AFSInitializeRedirector AFS_GENERIC_MEMORY_23_TAG allocation error\n"));
try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
}
SetFlag( pDevExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES);
}
- if( RedirInitInfo->MemoryCacheOffset.QuadPart != 0 &&
- RedirInitInfo->MemoryCacheLength.QuadPart != 0)
+ if( BooleanFlagOn( RedirInitInfo->Flags, AFS_REDIR_INIT_FLAG_DISABLE_SHORTNAMES))
{
- ntStatus = STATUS_INSUFFICIENT_RESOURCES;
+ //
+ // Hide files which begin with .
+ //
-#ifdef AMD64
- pDevExt->Specific.RDR.CacheMdl = MmCreateMdl( NULL,
- (void *)RedirInitInfo->MemoryCacheOffset.QuadPart,
- RedirInitInfo->MemoryCacheLength.QuadPart);
-#else
- pDevExt->Specific.RDR.CacheMdl = MmCreateMdl( NULL,
- (void *)RedirInitInfo->MemoryCacheOffset.LowPart,
- RedirInitInfo->MemoryCacheLength.LowPart);
-#endif
+ SetFlag( pDevExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES);
+ }
- if( pDevExt->Specific.RDR.CacheMdl != NULL)
- {
+ //
+ // Global Reparse Point Policy
+ //
- __try
- {
+ pDevExt->Specific.RDR.ReparsePointPolicy = RedirInitInfo->GlobalReparsePointPolicy;
- MmProbeAndLockPages( pDevExt->Specific.RDR.CacheMdl,
- KernelMode,
- IoModifyAccess);
+ //
+ // Are we performing direct to service IO?
+ //
- pDevExt->Specific.RDR.CacheBaseAddress = MmGetSystemAddressForMdlSafe( pDevExt->Specific.RDR.CacheMdl,
- NormalPagePriority);
- }
- __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) )
- {
- IoFreeMdl( pDevExt->Specific.RDR.CacheMdl);
- pDevExt->Specific.RDR.CacheMdl = NULL;
- }
+ if( BooleanFlagOn( RedirInitInfo->Flags, AFS_REDIR_INIT_PERFORM_SERVICE_IO))
+ {
+
+ //
+ // Send IO requests directly to service
+ //
+
+ SetFlag( pDevExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO);
+ }
+ else
+ {
+
+ if( RedirInitInfo->MemoryCacheOffset.QuadPart != 0 &&
+ RedirInitInfo->MemoryCacheLength.QuadPart != 0)
+ {
+
+ ntStatus = STATUS_INSUFFICIENT_RESOURCES;
+
+#ifdef AMD64
+ pDevExt->Specific.RDR.CacheMdl = MmCreateMdl( NULL,
+ (void *)RedirInitInfo->MemoryCacheOffset.QuadPart,
+ RedirInitInfo->MemoryCacheLength.QuadPart);
+#else
+ pDevExt->Specific.RDR.CacheMdl = MmCreateMdl( NULL,
+ (void *)RedirInitInfo->MemoryCacheOffset.LowPart,
+ RedirInitInfo->MemoryCacheLength.LowPart);
+#endif
if( pDevExt->Specific.RDR.CacheMdl != NULL)
{
- pDevExt->Specific.RDR.CacheLength = RedirInitInfo->MemoryCacheLength;
- ntStatus = STATUS_SUCCESS;
- }
- }
- }
+ __try
+ {
- if( !NT_SUCCESS( ntStatus) &&
- RedirInitInfo->CacheFileNameLength == 0)
- {
+ MmProbeAndLockPages( pDevExt->Specific.RDR.CacheMdl,
+ KernelMode,
+ IoModifyAccess);
- AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING,
- AFS_TRACE_LEVEL_ERROR,
- "AFSInitializeRedirector Unable to initialize cache file %08lX\n",
- ntStatus);
+ pDevExt->Specific.RDR.CacheBaseAddress = MmGetSystemAddressForMdlSafe( pDevExt->Specific.RDR.CacheMdl,
+ NormalPagePriority);
+ }
+ __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
+ {
- try_return( ntStatus);
- }
+ AFSDumpTraceFilesFnc();
- if( pDevExt->Specific.RDR.CacheMdl == NULL)
- {
+ IoFreeMdl( pDevExt->Specific.RDR.CacheMdl);
+ pDevExt->Specific.RDR.CacheMdl = NULL;
+ }
- if( RedirInitInfo->CacheFileNameLength == 0)
+ if( pDevExt->Specific.RDR.CacheMdl != NULL)
+ {
+ pDevExt->Specific.RDR.CacheLength = RedirInitInfo->MemoryCacheLength;
+ ntStatus = STATUS_SUCCESS;
+ }
+
+ }
+ }
+
+ if( !NT_SUCCESS( ntStatus) &&
+ RedirInitInfo->CacheFileNameLength == 0)
{
- AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING,
+ AFSDbgTrace(( AFS_SUBSYSTEM_INIT_PROCESSING,
AFS_TRACE_LEVEL_ERROR,
- "AFSInitializeRedirector CacheMdl == NULL\n");
+ "AFSInitializeRedirector Unable to initialize cache file %08lX\n",
+ ntStatus));
- try_return( ntStatus = STATUS_INVALID_PARAMETER);
+ try_return( ntStatus);
}
- //
- // Go open the cache file
- //
+ if( pDevExt->Specific.RDR.CacheMdl == NULL)
+ {
- pDevExt->Specific.RDR.CacheFile.Length = 0;
- pDevExt->Specific.RDR.CacheFile.MaximumLength = (USHORT)RedirInitInfo->CacheFileNameLength + (4 * sizeof( WCHAR));
+ if( RedirInitInfo->CacheFileNameLength == 0)
+ {
- pDevExt->Specific.RDR.CacheFile.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
- pDevExt->Specific.RDR.CacheFile.MaximumLength,
- AFS_GENERIC_MEMORY_24_TAG);
+ AFSDbgTrace(( AFS_SUBSYSTEM_INIT_PROCESSING,
+ AFS_TRACE_LEVEL_ERROR,
+ "AFSInitializeRedirector CacheMdl == NULL\n"));
- if( pDevExt->Specific.RDR.CacheFile.Buffer == NULL)
- {
+ try_return( ntStatus = STATUS_INVALID_PARAMETER);
+ }
- AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING,
- AFS_TRACE_LEVEL_ERROR,
- "AFSInitializeRedirector AFS_GENERIC_MEMORY_24_TAG allocation failure\n");
+ //
+ // Go open the cache file
+ //
- try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
- }
+ pDevExt->Specific.RDR.CacheFile.Length = 0;
+ pDevExt->Specific.RDR.CacheFile.MaximumLength = (USHORT)RedirInitInfo->CacheFileNameLength + (4 * sizeof( WCHAR));
- RtlCopyMemory( pDevExt->Specific.RDR.CacheFile.Buffer,
- L"\\??\\",
- 4 * sizeof( WCHAR));
+ pDevExt->Specific.RDR.CacheFile.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
+ pDevExt->Specific.RDR.CacheFile.MaximumLength,
+ AFS_GENERIC_MEMORY_24_TAG);
- pDevExt->Specific.RDR.CacheFile.Length = 4 * sizeof( WCHAR);
+ if( pDevExt->Specific.RDR.CacheFile.Buffer == NULL)
+ {
- RtlCopyMemory( &pDevExt->Specific.RDR.CacheFile.Buffer[ pDevExt->Specific.RDR.CacheFile.Length/sizeof( WCHAR)],
- RedirInitInfo->CacheFileName,
- RedirInitInfo->CacheFileNameLength);
+ AFSDbgTrace(( AFS_SUBSYSTEM_INIT_PROCESSING,
+ AFS_TRACE_LEVEL_ERROR,
+ "AFSInitializeRedirector AFS_GENERIC_MEMORY_24_TAG allocation failure\n"));
- pDevExt->Specific.RDR.CacheFile.Length += (USHORT)RedirInitInfo->CacheFileNameLength;
+ try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
+ }
- InitializeObjectAttributes( &stObjectAttribs,
- &pDevExt->Specific.RDR.CacheFile,
- OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
- NULL,
- NULL);
+ RtlCopyMemory( pDevExt->Specific.RDR.CacheFile.Buffer,
+ L"\\??\\",
+ 4 * sizeof( WCHAR));
- ntStatus = ZwOpenFile( &pDevExt->Specific.RDR.CacheFileHandle,
- GENERIC_READ | GENERIC_WRITE,
- &stObjectAttribs,
- &stIoStatus,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- FILE_WRITE_THROUGH | FILE_RANDOM_ACCESS);
+ pDevExt->Specific.RDR.CacheFile.Length = 4 * sizeof( WCHAR);
- if( !NT_SUCCESS( ntStatus))
- {
+ RtlCopyMemory( &pDevExt->Specific.RDR.CacheFile.Buffer[ pDevExt->Specific.RDR.CacheFile.Length/sizeof( WCHAR)],
+ RedirInitInfo->CacheFileName,
+ RedirInitInfo->CacheFileNameLength);
- AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING,
- AFS_TRACE_LEVEL_ERROR,
- "AFSInitializeRedirector ZwOpenFile failure %08lX\n",
- ntStatus);
+ pDevExt->Specific.RDR.CacheFile.Length += (USHORT)RedirInitInfo->CacheFileNameLength;
- try_return( ntStatus);
- }
+ InitializeObjectAttributes( &stObjectAttribs,
+ &pDevExt->Specific.RDR.CacheFile,
+ OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
- //
- // Map to the fileobject
- //
+ ntStatus = ZwOpenFile( &pDevExt->Specific.RDR.CacheFileHandle,
+ GENERIC_READ | GENERIC_WRITE,
+ &stObjectAttribs,
+ &stIoStatus,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ FILE_WRITE_THROUGH | FILE_RANDOM_ACCESS);
- ntStatus = ObReferenceObjectByHandle( pDevExt->Specific.RDR.CacheFileHandle,
- SYNCHRONIZE,
- NULL,
- KernelMode,
- (void **)&pDevExt->Specific.RDR.CacheFileObject,
- NULL);
+ if( !NT_SUCCESS( ntStatus))
+ {
- if( !NT_SUCCESS( ntStatus))
- {
+ AFSDbgTrace(( AFS_SUBSYSTEM_INIT_PROCESSING,
+ AFS_TRACE_LEVEL_ERROR,
+ "AFSInitializeRedirector ZwOpenFile failure %08lX\n",
+ ntStatus));
- AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING,
- AFS_TRACE_LEVEL_ERROR,
- "AFSInitializeRedirector ObReferenceObjectByHandle failure %08lX\n",
- ntStatus);
+ try_return( ntStatus);
+ }
- try_return( ntStatus);
+ //
+ // Map to the fileobject
+ //
+
+ ntStatus = ObReferenceObjectByHandle( pDevExt->Specific.RDR.CacheFileHandle,
+ SYNCHRONIZE,
+ NULL,
+ KernelMode,
+ (void **)&pDevExt->Specific.RDR.CacheFileObject,
+ NULL);
+
+ if( !NT_SUCCESS( ntStatus))
+ {
+
+ AFSDbgTrace(( AFS_SUBSYSTEM_INIT_PROCESSING,
+ AFS_TRACE_LEVEL_ERROR,
+ "AFSInitializeRedirector ObReferenceObjectByHandle failure %08lX\n",
+ ntStatus));
+
+ try_return( ntStatus);
+ }
}
}
if ( !NT_SUCCESS( ntStatus))
{
- AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING,
+ AFSDbgTrace(( AFS_SUBSYSTEM_INIT_PROCESSING,
AFS_TRACE_LEVEL_ERROR,
"AFSInitializeRedirector AFSInitializeLibrary failure %08lX\n",
- ntStatus);
+ ntStatus));
}
try_exit:
AFSDumpFileLocation.Buffer = NULL;
}
+ if ( pDevExt->Fcb != NULL)
+ {
+
+ AFSRemoveRdrFcb( &pDevExt->Fcb);
+
+ pDevExt = NULL;
+ }
+
AFSUnloadLibrary( TRUE);
}
}
AFSDumpFileLocation.Buffer = NULL;
}
+
+ if ( pDevExt->Fcb != NULL)
+ {
+
+ AFSRemoveRdrFcb( &pDevExt->Fcb);
+
+ pDevExt->Fcb = NULL;
+ }
+
+ }
+
+ return ntStatus;
+}
+
+//
+// Function: AFSInitRdrFcb
+//
+// Description:
+//
+// This function performs Redirector Fcb initialization
+//
+// Return:
+//
+// A status is returned for the function
+//
+
+NTSTATUS
+AFSInitRdrFcb( OUT AFSFcb **RdrFcb)
+{
+
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+ AFSFcb *pFcb = NULL;
+ AFSNonPagedFcb *pNPFcb = NULL;
+
+ __Enter
+ {
+
+ //
+ // Initialize the root fcb
+ //
+
+ pFcb = (AFSFcb *)AFSExAllocatePoolWithTag( PagedPool,
+ sizeof( AFSFcb),
+ AFS_FCB_ALLOCATION_TAG);
+
+ if( pFcb == NULL)
+ {
+
+ AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_ERROR,
+ "AFSInitRdrFcb Failed to allocate the root fcb\n"));
+
+ try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
+ }
+
+ RtlZeroMemory( pFcb,
+ sizeof( AFSFcb));
+
+ pFcb->Header.NodeByteSize = sizeof( AFSFcb);
+ pFcb->Header.NodeTypeCode = AFS_REDIRECTOR_FCB;
+
+ pNPFcb = (AFSNonPagedFcb *)AFSExAllocatePoolWithTag( NonPagedPool,
+ sizeof( AFSNonPagedFcb),
+ AFS_FCB_NP_ALLOCATION_TAG);
+
+ if( pNPFcb == NULL)
+ {
+
+ AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_ERROR,
+ "AFSInitRdrFcb Failed to allocate the non-paged fcb\n"));
+
+ try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
+ }
+
+ RtlZeroMemory( pNPFcb,
+ sizeof( AFSNonPagedFcb));
+
+ pNPFcb->Size = sizeof( AFSNonPagedFcb);
+
+ pNPFcb->Type = AFS_NON_PAGED_FCB;
+
+ //
+ // OK, initialize the entry
+ //
+
+ ExInitializeFastMutex( &pNPFcb->AdvancedHdrMutex);
+
+ FsRtlSetupAdvancedHeader( &pFcb->Header, &pNPFcb->AdvancedHdrMutex);
+
+ ExInitializeResourceLite( &pNPFcb->Resource);
+
+ AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSInitRootFcb Acquiring Fcb lock %p EXCL %08lX\n",
+ &pNPFcb->Resource,
+ PsGetCurrentThread()));
+
+ ExInitializeResourceLite( &pNPFcb->PagingResource);
+
+ pFcb->Header.Resource = &pNPFcb->Resource;
+
+ pFcb->Header.PagingIoResource = &pNPFcb->PagingResource;
+
+ pFcb->NPFcb = pNPFcb;
+
+ if ( InterlockedCompareExchangePointer( (PVOID *)RdrFcb, pFcb, NULL) != NULL)
+ {
+
+ try_return( ntStatus = STATUS_REPARSE);
+ }
+
+try_exit:
+
+ if( ntStatus != STATUS_SUCCESS)
+ {
+
+ if( pFcb != NULL)
+ {
+
+ AFSRemoveRdrFcb( &pFcb);
+ }
+ }
}
return ntStatus;
}
+
+//
+// Function: AFSRemoveRdrFcb
+//
+// Description:
+//
+// This function performs Redirector Fcb removal/deallocation
+//
+// Return:
+//
+// void.
+//
+
+void
+AFSRemoveRdrFcb( IN OUT AFSFcb **RdrFcb)
+{
+ AFSFcb *pFcb = NULL;
+
+ pFcb = (AFSFcb *) InterlockedCompareExchangePointer( (PVOID *)RdrFcb, NULL, (PVOID)(*RdrFcb));
+
+ if ( pFcb == NULL)
+ {
+
+ return;
+ }
+
+ if( pFcb->NPFcb != NULL)
+ {
+
+ //
+ // Now the resource
+ //
+
+ ExDeleteResourceLite( &pFcb->NPFcb->Resource);
+
+ ExDeleteResourceLite( &pFcb->NPFcb->PagingResource);
+
+ //
+ // The non paged region
+ //
+
+ AFSExFreePoolWithTag( pFcb->NPFcb, AFS_FCB_NP_ALLOCATION_TAG);
+ }
+
+ //
+ // And the Fcb itself
+ //
+
+ AFSExFreePoolWithTag( pFcb, AFS_FCB_ALLOCATION_TAG);
+
+ return;
+}