Windows: RDR DeviceObject Characteristics
[openafs.git] / src / WINNT / afsrdr / kernel / fs / AFSRDRSupport.cpp
index 93354a8..295a60b 100644 (file)
@@ -45,9 +45,7 @@ AFSInitRDRDevice()
 
     NTSTATUS       ntStatus = STATUS_SUCCESS;
     UNICODE_STRING uniDeviceName;
-    ULONG          ulIndex = 0;
     AFSDeviceExt  *pDeviceExt = NULL;
-    AFSFileID      stRootFid;
     UNICODE_STRING uniFsRtlRegisterUncProviderEx;
     FsRtlRegisterUncProviderEx_t pFsRtlRegisterUncProviderEx = NULL;
 
@@ -66,17 +64,17 @@ AFSInitRDRDevice()
                                    sizeof( AFSDeviceExt),
                                    pFsRtlRegisterUncProviderEx ? NULL : &uniDeviceName,
                                    FILE_DEVICE_NETWORK_FILE_SYSTEM,
-                                   FILE_REMOTE_DEVICE,
+                                   FILE_DEVICE_SECURE_OPEN | FILE_REMOTE_DEVICE,
                                    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);
         }
@@ -114,6 +112,19 @@ AFSInitRDRDevice()
 
         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
         //
@@ -121,6 +132,13 @@ AFSInitRDRDevice()
         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
         //
 
@@ -133,10 +151,10 @@ AFSInitRDRDevice()
                                                     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
@@ -153,13 +171,19 @@ AFSInitRDRDevice()
             }
             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))
         {
 
@@ -181,17 +205,6 @@ AFSInitRDRDevice()
 
             try_return( ntStatus);
         }
-
-        //
-        // Good to go, all registered and ready to start receiving requests
-        //
-
-try_exit:
-
-        if( !NT_SUCCESS( ntStatus))
-        {
-
-        }
     }
 
     return ntStatus;
@@ -201,10 +214,10 @@ 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
@@ -339,7 +352,6 @@ AFSInitializeRedirector( IN AFSRedirectorInitInfo *RedirInitInfo)
     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;
@@ -360,10 +372,10 @@ AFSInitializeRedirector( IN AFSRedirectorInitInfo *RedirInitInfo)
         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);
         }
@@ -392,9 +404,9 @@ AFSInitializeRedirector( IN AFSRedirectorInitInfo *RedirInitInfo)
         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);
         }
@@ -495,152 +507,182 @@ AFSInitializeRedirector( IN AFSRedirectorInitInfo *RedirInitInfo)
             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)
-            {
+        //
+        // Are we performing direct to service IO?
+        //
 
-                __try
-                {
+        if( BooleanFlagOn( RedirInitInfo->Flags, AFS_REDIR_INIT_PERFORM_SERVICE_IO))
+        {
 
-                    MmProbeAndLockPages( pDevExt->Specific.RDR.CacheMdl,
-                                         KernelMode,
-                                         IoModifyAccess);
+            //
+            // Send IO requests directly to service
+            //
 
-                    pDevExt->Specific.RDR.CacheBaseAddress = MmGetSystemAddressForMdlSafe( pDevExt->Specific.RDR.CacheMdl,
-                                                                                           NormalPagePriority);
-                }
-                __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) )
-                {
-                    IoFreeMdl( pDevExt->Specific.RDR.CacheMdl);
-                    pDevExt->Specific.RDR.CacheMdl = NULL;
-                }
+            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);
+                }
             }
         }
 
@@ -657,10 +699,10 @@ AFSInitializeRedirector( IN AFSRedirectorInitInfo *RedirInitInfo)
 
         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:
@@ -714,6 +756,14 @@ try_exit:
                 AFSDumpFileLocation.Buffer = NULL;
             }
 
+            if ( pDevExt->Fcb != NULL)
+            {
+
+                AFSRemoveRdrFcb( &pDevExt->Fcb);
+
+                pDevExt = NULL;
+            }
+
             AFSUnloadLibrary( TRUE);
         }
     }
@@ -787,7 +837,182 @@ AFSCloseRedirector()
 
             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;
+}