Windows: Redirector interface for afsd_service.exe
[openafs.git] / src / WINNT / afsrdr / user / RDRInit.cpp
diff --git a/src/WINNT/afsrdr/user/RDRInit.cpp b/src/WINNT/afsrdr/user/RDRInit.cpp
new file mode 100644 (file)
index 0000000..7d123e2
--- /dev/null
@@ -0,0 +1,2033 @@
+/*
+ * Copyright (c) 2008 Secure Endpoints, Inc.
+ * Copyright (c) 2009-2011 Your File System, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * - Neither the name of Secure Endpoints Inc. nor the names of its contributors
+ *   may be used to endorse or promote products derived from this software without
+ *   specific prior written permission from Secure Endpoints, Inc. and
+ *   Your File System, Inc.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _WIN32_WINNT
+#define _WIN32_WINNT 0x0500
+#endif
+#define _CRT_SECURE_NO_DEPRECATE
+#define _CRT_NON_CONFORMING_SWPRINTFS
+#define UNICODE 1
+#define STRSAFE_NO_DEPRECATE
+
+#include <ntstatus.h>
+#define WIN32_NO_STATUS
+#include <windows.h>
+typedef LONG NTSTATUS, *PNTSTATUS;      // not declared in ntstatus.h
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <errno.h>
+
+#include <devioctl.h>
+
+#include <tchar.h>
+#include <winbase.h>
+#include <winreg.h>
+#include <strsafe.h>
+
+#include "..\\Common\\AFSUserDefines.h"
+#include "..\\Common\\AFSUserIoctl.h"
+#include "..\\Common\\AFSUserStructs.h"
+
+extern "C" {
+#include <osilog.h>
+extern osi_log_t *afsd_logp;
+
+#include <WINNT/afsreg.h>
+#include <afs/cm_config.h>
+#include <afs/cm_error.h>
+}
+#include <RDRPrototypes.h>
+
+#ifndef FlagOn
+#define FlagOn(_F,_SF)        ((_F) & (_SF))
+#endif
+
+#ifndef BooleanFlagOn
+#define BooleanFlagOn(F,SF)   ((BOOLEAN)(((F) & (SF)) != 0))
+#endif
+
+#ifndef SetFlag
+#define SetFlag(_F,_SF)       ((_F) |= (_SF))
+#endif
+
+#ifndef ClearFlag
+#define ClearFlag(_F,_SF)     ((_F) &= ~(_SF))
+#endif
+
+#define QuadAlign(Ptr) (                \
+    ((((ULONG)(Ptr)) + 7) & 0xfffffff8) \
+    )
+
+#define MIN_WORKER_THREADS 5
+#define MAX_WORKER_THREADS 512
+
+typedef struct _worker_thread_info {
+
+    HANDLE hThread;
+
+    ULONG  Flags;
+
+    HANDLE hEvent;
+
+} WorkerThreadInfo;
+
+WorkerThreadInfo glWorkerThreadInfo[ MAX_WORKER_THREADS];
+
+UINT   glThreadHandleIndex = 0;
+
+HANDLE glDevHandle = INVALID_HANDLE_VALUE;
+
+static DWORD Exit = false;
+
+static DWORD ExitPending = false;
+
+DWORD  dwOvEvIdx = 0;
+
+extern "C" wchar_t RDR_UNCName[64]=L"AFS";
+
+/* returns 0 on success */
+extern "C" DWORD
+RDR_Initialize(void)
+{
+
+    DWORD dwRet = 0;
+    HKEY parmKey;
+    DWORD dummyLen;
+    DWORD numSvThreads = CM_CONFIGDEFAULT_SVTHREADS;
+
+    dwRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
+                         0, KEY_QUERY_VALUE, &parmKey);
+    if (dwRet == ERROR_SUCCESS) {
+        dummyLen = sizeof(numSvThreads);
+        dwRet = RegQueryValueEx(parmKey, TEXT("ServerThreads"), NULL, NULL,
+                                (BYTE *) &numSvThreads, &dummyLen);
+
+        dummyLen = sizeof(RDR_UNCName);
+        dwRet = RegQueryValueExW(parmKey, L"NetbiosName", NULL, NULL,
+                                 (BYTE *) RDR_UNCName, &dummyLen);
+
+        RegCloseKey (parmKey);
+    }
+
+    // Initialize the Thread local storage index for the overlapped i/o
+    // Event Handle
+    dwOvEvIdx = TlsAlloc();
+
+    Exit = false;
+
+    //
+    // Launch our workers down to the
+    // filters control device for processing requests
+    //
+
+    dwRet = RDR_ProcessWorkerThreads(numSvThreads);
+
+    if (dwRet == ERROR_SUCCESS) {
+
+        RDR_InitIoctl();
+    }
+
+    return dwRet;
+}
+
+BOOL RDR_DeviceIoControl( HANDLE hDevice,
+                          DWORD dwIoControlCode,
+                          LPVOID lpInBuffer,
+                          DWORD nInBufferSize,
+                          LPVOID lpOutBuffer,
+                          DWORD nOutBufferSize,
+                          LPDWORD lpBytesReturned )
+{
+    OVERLAPPED ov;
+    HANDLE hEvent;
+    BOOL rc = FALSE;
+    DWORD gle;
+
+    ZeroMemory(&ov, sizeof(OVERLAPPED));
+
+    hEvent = (HANDLE)TlsGetValue(dwOvEvIdx);
+    if (hEvent == NULL) {
+        hEvent = CreateEvent( NULL, TRUE, TRUE, NULL );
+        if (hEvent == INVALID_HANDLE_VALUE || hEvent == NULL)
+            return FALSE;
+        TlsSetValue( dwOvEvIdx, (LPVOID) hEvent );
+    }
+
+    ResetEvent( hEvent);
+    ov.hEvent = hEvent;
+    *lpBytesReturned = 0;
+
+    rc = DeviceIoControl( hDevice,
+                          dwIoControlCode,
+                          lpInBuffer,
+                          nInBufferSize,
+                          lpOutBuffer,
+                          nOutBufferSize,
+                          lpBytesReturned,
+                          &ov );
+    if ( !rc ) {
+        gle = GetLastError();
+
+        if ( gle == ERROR_IO_PENDING )
+            rc = GetOverlappedResult( hDevice, &ov, lpBytesReturned, TRUE );
+    }
+
+    return rc;
+}
+
+extern "C" DWORD
+RDR_ShutdownFinal(void)
+{
+
+    DWORD dwIndex = 0;
+
+    Exit = true;
+
+    //
+    // Close all the worker thread handles
+    //
+
+    while( dwIndex < glThreadHandleIndex)
+    {
+
+        CloseHandle( glWorkerThreadInfo[ dwIndex].hThread);
+
+        dwIndex++;
+    }
+
+    if( glDevHandle != INVALID_HANDLE_VALUE)
+    {
+
+        CloseHandle( glDevHandle);
+    }
+
+    return 0;
+}
+
+extern "C" DWORD
+RDR_ShutdownNotify(void)
+{
+
+    HANDLE hDevHandle = NULL;
+    DWORD bytesReturned;
+
+    //
+    // We use the global handle to the control device instance
+    //
+
+    hDevHandle = glDevHandle;
+
+
+    //
+    // First, notify the file system driver that
+    // we are shutting down.
+    //
+
+    ExitPending = true;
+
+    if( !RDR_DeviceIoControl( hDevHandle,
+                              IOCTL_AFS_SHUTDOWN,
+                              NULL,
+                              0,
+                              NULL,
+                              0,
+                              &bytesReturned ))
+    {
+        // log the error, nothing to do
+    }
+
+    return 0;
+}
+
+//
+// Here we launch the worker threads for the given volume
+//
+
+DWORD
+RDR_ProcessWorkerThreads(DWORD numThreads)
+{
+    DWORD WorkerID;
+    HANDLE hEvent;
+    DWORD index = 0;
+    DWORD bytesReturned = 0;
+    DWORD dwRedirInitInfo;
+    AFSRedirectorInitInfo * redirInitInfo = NULL;
+    DWORD dwErr;
+
+    if (dwErr = RDR_SetInitParams(&redirInitInfo, &dwRedirInitInfo))
+        return dwErr;
+
+    glDevHandle = CreateFile( AFS_SYMLINK_W,
+                             GENERIC_READ | GENERIC_WRITE,
+                             FILE_SHARE_READ | FILE_SHARE_WRITE,
+                             NULL,
+                             OPEN_EXISTING,
+                             FILE_FLAG_OVERLAPPED,
+                             NULL);
+
+    if( glDevHandle == INVALID_HANDLE_VALUE)
+    {
+        free(redirInitInfo);
+        return GetLastError();
+    }
+
+    //
+    // Now call down to initialize the pool.
+    //
+
+    if( !RDR_DeviceIoControl( glDevHandle,
+                              IOCTL_AFS_INITIALIZE_CONTROL_DEVICE,
+                              NULL,
+                              0,
+                              NULL,
+                              0,
+                              &bytesReturned ))
+    {
+
+        CloseHandle( glDevHandle);
+
+        glDevHandle = NULL;
+
+        free(redirInitInfo);
+
+        return GetLastError();
+    }
+
+    //
+    // OK, now launch the workers
+    //
+
+    hEvent = CreateEvent( NULL,
+                         TRUE,
+                         FALSE,
+                         NULL);
+
+    //
+    // Here we create a pool of worker threads but you can create the pool with as many requests
+    // as you want
+    //
+
+    if (numThreads < MIN_WORKER_THREADS)
+        numThreads = MIN_WORKER_THREADS;
+    else if (numThreads > MAX_WORKER_THREADS)
+        numThreads = MAX_WORKER_THREADS;
+
+    for (index = 0; index < numThreads; index++)
+    {
+        //
+        // 20% of worker threads should be reserved for release extent
+        // event processing
+        //
+        glWorkerThreadInfo[ glThreadHandleIndex].Flags =
+            (glThreadHandleIndex % 5) ? 0 : AFS_REQUEST_RELEASE_THREAD;
+        glWorkerThreadInfo[ glThreadHandleIndex].hEvent = hEvent;
+        glWorkerThreadInfo[ glThreadHandleIndex].hThread =
+            CreateThread( NULL,
+                          0,
+                          RDR_RequestWorkerThread,
+                          (void *)&glWorkerThreadInfo[ glThreadHandleIndex],
+                          0,
+                          &WorkerID);
+
+        if( glWorkerThreadInfo[ glThreadHandleIndex].hThread != NULL)
+        {
+
+            //
+            // Wait for the thread to signal it is ready for processing
+            //
+
+            WaitForSingleObject( hEvent,
+                                INFINITE);
+
+            glThreadHandleIndex++;
+
+            ResetEvent( hEvent);
+        }
+        else
+        {
+
+            //
+            // Perform cleanup specific to your application
+            //
+
+        }
+    }
+
+    if( !RDR_DeviceIoControl( glDevHandle,
+                              IOCTL_AFS_INITIALIZE_REDIRECTOR_DEVICE,
+                              redirInitInfo,
+                              dwRedirInitInfo,
+                              NULL,
+                              0,
+                              &bytesReturned ))
+    {
+
+        CloseHandle( glDevHandle);
+
+        glDevHandle = NULL;
+
+        free(redirInitInfo);
+
+        return GetLastError();
+    }
+
+    free(redirInitInfo);
+
+    return 0;
+}
+
+//
+// Entry point for the worker thread
+//
+
+DWORD
+WINAPI
+RDR_RequestWorkerThread( LPVOID lpParameter)
+{
+
+    HANDLE hDevHandle = NULL;
+    DWORD bytesReturned;
+    AFSCommRequest *requestBuffer;
+    bool bError = false;
+    WorkerThreadInfo * pInfo = (WorkerThreadInfo *)lpParameter;
+
+    //
+    // We use the global handle to the control device instance
+    //
+
+    hDevHandle = glDevHandle;
+
+    //
+    // Allocate a request buffer.
+    //
+
+    requestBuffer = (AFSCommRequest *)malloc( sizeof( AFSCommRequest) + AFS_PAYLOAD_BUFFER_SIZE);
+
+    if( requestBuffer)
+    {
+
+        //
+        // Here we simply signal back to the main thread that we ahve started
+        //
+
+        SetEvent( pInfo->hEvent);
+
+        //
+        // Process requests until we are told to stop
+        //
+
+        while( !Exit)
+       {
+
+            memset( requestBuffer, '\0', sizeof( AFSCommRequest) + AFS_PAYLOAD_BUFFER_SIZE);
+
+            requestBuffer->RequestFlags = pInfo->Flags;
+
+            if( !RDR_DeviceIoControl( hDevHandle,
+                                      IOCTL_AFS_PROCESS_IRP_REQUEST,
+                                      (void *)requestBuffer,
+                                      sizeof( AFSCommRequest),
+                                      (void *)requestBuffer,
+                                      sizeof( AFSCommRequest) + AFS_PAYLOAD_BUFFER_SIZE,
+                                      &bytesReturned ))
+            {
+
+                //
+                // Error condition back from driver
+                //
+
+                break;
+            }
+
+            //
+            // Go process the request
+            //
+
+            if (!Exit)
+                RDR_ProcessRequest( requestBuffer);
+        }
+
+       free( requestBuffer);
+    }
+
+    ExitThread( 0);
+
+    return 0;
+}
+
+//
+// This is the entry point for the worker threads to process the request from the TC Filter driver
+//
+
+void
+RDR_ProcessRequest( AFSCommRequest *RequestBuffer)
+{
+
+    DWORD              bytesReturned;
+    DWORD              result = 0;
+    ULONG              ulIndex = 0;
+    ULONG              ulCreateFlags = 0;
+    AFSCommResult *     pResultCB = NULL;
+    AFSCommResult      stResultCB;
+    DWORD              dwResultBufferLength = 0;
+    AFSSetFileExtentsCB * SetFileExtentsResultCB = NULL;
+    AFSSetByteRangeLockResultCB *SetByteRangeLockResultCB = NULL;
+    WCHAR              wchBuffer[1024];
+    char *pBuffer = (char *)wchBuffer;
+    DWORD gle;
+    cm_user_t *         userp = NULL;
+    BOOL                bWow64 = (RequestBuffer->RequestFlags & AFS_REQUEST_FLAG_WOW64) ? TRUE : FALSE;
+    BOOL                bFast  = (RequestBuffer->RequestFlags & AFS_REQUEST_FLAG_FAST_REQUEST) ? TRUE : FALSE;
+    BOOL                bHoldFid = (RequestBuffer->RequestFlags & AFS_REQUEST_FLAG_HOLD_FID) ? TRUE : FALSE;
+    BOOL                bFlushFile = (RequestBuffer->RequestFlags & AFS_REQUEST_FLAG_FLUSH_FILE) ? TRUE : FALSE;
+    BOOL                bDeleteFile = (RequestBuffer->RequestFlags & AFS_REQUEST_FLAG_FILE_DELETED) ? TRUE : FALSE;
+    BOOL                bUnlockFile = (RequestBuffer->RequestFlags & AFS_REQUEST_FLAG_BYTE_RANGE_UNLOCK_ALL) ? TRUE : FALSE;
+    BOOL                bCheckOnly = (RequestBuffer->RequestFlags & AFS_REQUEST_FLAG_CHECK_ONLY) ? TRUE : FALSE;
+    BOOL                bRetry = FALSE;
+    BOOL                bUnsupported = FALSE;
+    BOOL                bIsLocalSystem = (RequestBuffer->RequestFlags & AFS_REQUEST_LOCAL_SYSTEM_PAG) ? TRUE : FALSE;
+
+    userp = RDR_UserFromCommRequest(RequestBuffer);
+
+  retry:
+    //
+    // Build up the string to display based on the request type.
+    //
+
+    switch( RequestBuffer->RequestType)
+    {
+
+        case AFS_REQUEST_TYPE_DIR_ENUM:
+        {
+
+            AFSDirQueryCB *pQueryCB = (AFSDirQueryCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
+
+            if (afsd_logp->enabled) {
+                swprintf( wchBuffer,
+                          L"ProcessRequest Processing AFS_REQUEST_TYPE_DIR_ENUM Index %08lX",
+                          RequestBuffer->RequestIndex);
+
+                osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
+            }
+
+            //
+            // Here is where the content of the specific directory is enumerated.
+            //
+
+            RDR_EnumerateDirectory( userp, RequestBuffer->FileId,
+                                   pQueryCB, bWow64, bFast,
+                                   RequestBuffer->ResultBufferLength,
+                                   &pResultCB);
+            break;
+        }
+
+        case AFS_REQUEST_TYPE_EVAL_TARGET_BY_ID:
+        {
+            AFSEvalTargetCB *pEvalTargetCB = (AFSEvalTargetCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
+
+            if (afsd_logp->enabled) {
+                swprintf( wchBuffer,
+                          L"ProcessRequest Processing AFS_REQUEST_TYPE_EVAL_TARGET_BY_ID Index %08lX",
+                          RequestBuffer->RequestIndex);
+
+                osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
+            }
+            //
+            // Here is where the specified node is evaluated.
+            //
+
+            RDR_EvaluateNodeByID( userp, pEvalTargetCB->ParentId,
+                                  RequestBuffer->FileId,
+                                  bWow64, bFast, bHoldFid,
+                                  RequestBuffer->ResultBufferLength,
+                                  &pResultCB);
+            break;
+        }
+
+        case AFS_REQUEST_TYPE_EVAL_TARGET_BY_NAME:
+        {
+            AFSEvalTargetCB *pEvalTargetCB = (AFSEvalTargetCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
+
+            if (afsd_logp->enabled) {
+                swprintf( wchBuffer,
+                          L"ProcessRequest Processing AFS_REQUEST_TYPE_EVAL_TARGET_BY_NAME Index %08lX",
+                          RequestBuffer->RequestIndex);
+
+                osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
+            }
+            //
+            // Here is where the specified node is evaluated.
+            //
+
+            RDR_EvaluateNodeByName( userp, pEvalTargetCB->ParentId,
+                                    RequestBuffer->Name,
+                                    RequestBuffer->NameLength,
+                                    RequestBuffer->RequestFlags & AFS_REQUEST_FLAG_CASE_SENSITIVE ? TRUE : FALSE,
+                                    bWow64, bFast, bHoldFid,
+                                    RequestBuffer->ResultBufferLength,
+                                    &pResultCB);
+            break;
+        }
+
+        case AFS_REQUEST_TYPE_CREATE_FILE:
+        {
+
+            AFSFileCreateCB *pCreateCB = (AFSFileCreateCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
+
+            WCHAR wchFileName[ 256];
+
+            if (afsd_logp->enabled) {
+                memset( wchFileName, '\0', 256 * sizeof( WCHAR));
+
+                memcpy( wchFileName,
+                        RequestBuffer->Name,
+                        RequestBuffer->NameLength);
+
+                swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_CREATE_FILE Index %08lX File %S",
+                          RequestBuffer->RequestIndex, wchFileName);
+
+                osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
+            }
+
+            RDR_CreateFileEntry( userp,
+                                 RequestBuffer->Name,
+                                RequestBuffer->NameLength,
+                                pCreateCB,
+                                 bWow64,
+                                 bHoldFid,
+                                RequestBuffer->ResultBufferLength,
+                                &pResultCB);
+
+            break;
+        }
+
+        case AFS_REQUEST_TYPE_UPDATE_FILE:
+        {
+
+            AFSFileUpdateCB *pUpdateCB = (AFSFileUpdateCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
+
+            if (afsd_logp->enabled) {
+                swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_UPDATE_FILE Index %08lX File %08lX.%08lX.%08lX.%08lX",
+                          RequestBuffer->RequestIndex,
+                          RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
+                          RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique);
+
+                osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
+            }
+
+            RDR_UpdateFileEntry( userp, RequestBuffer->FileId,
+                                pUpdateCB,
+                                 bWow64,
+                                RequestBuffer->ResultBufferLength,
+                                &pResultCB);
+
+            break;
+        }
+
+        case AFS_REQUEST_TYPE_DELETE_FILE:
+        {
+
+            AFSFileDeleteCB *pDeleteCB = (AFSFileDeleteCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
+
+            if (afsd_logp->enabled) {
+                swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_DELETE_FILE Index %08lX %08lX.%08lX.%08lX.%08lX CheckOnly %X",
+                          RequestBuffer->RequestIndex,
+                          RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
+                          RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique,
+                          bCheckOnly);
+
+                osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
+            }
+
+            RDR_DeleteFileEntry( userp,
+                                 pDeleteCB->ParentId,
+                                 pDeleteCB->ProcessId,
+                                 RequestBuffer->Name,
+                                RequestBuffer->NameLength,
+                                 bWow64,
+                                 bCheckOnly,
+                                RequestBuffer->ResultBufferLength,
+                                &pResultCB);
+
+            break;
+        }
+
+        case AFS_REQUEST_TYPE_RENAME_FILE:
+        {
+
+            AFSFileRenameCB *pFileRenameCB = (AFSFileRenameCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
+
+            if (afsd_logp->enabled) {
+                swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_RENAME_FILE Index %08lX File %08lX.%08lX.%08lX.%08lX NameLength %08lX Name %*S",
+                          RequestBuffer->RequestIndex,
+                          RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
+                          RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique,
+                          RequestBuffer->NameLength, (int)RequestBuffer->NameLength, RequestBuffer->Name);
+
+                osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
+            }
+
+            RDR_RenameFileEntry( userp,
+                                 RequestBuffer->Name,
+                                RequestBuffer->NameLength,
+                                 RequestBuffer->FileId,
+                                pFileRenameCB,
+                                 bWow64,
+                                RequestBuffer->ResultBufferLength,
+                                &pResultCB);
+
+            break;
+        }
+
+        case AFS_REQUEST_TYPE_REQUEST_FILE_EXTENTS:
+        {
+
+            AFSRequestExtentsCB *pFileRequestExtentsCB = (AFSRequestExtentsCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
+
+            if (afsd_logp->enabled) {
+                swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_REQUEST_FILE_EXTENTS Index %08lX File %08lX.%08lX.%08lX.%08lX %S",
+                          RequestBuffer->RequestIndex,
+                          RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
+                          RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique,
+                          BooleanFlagOn( RequestBuffer->RequestFlags, AFS_REQUEST_FLAG_SYNCHRONOUS) ? L"Sync" : L"Async");
+
+                osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
+            }
+
+            if (BooleanFlagOn( RequestBuffer->RequestFlags, AFS_REQUEST_FLAG_SYNCHRONOUS))
+                osi_panic("SYNCHRONOUS AFS_REQUEST_TYPE_REQUEST_FILE_EXTENTS not supported",
+                          __FILE__, __LINE__);
+            else
+                bRetry = RDR_RequestFileExtentsAsync( userp, RequestBuffer->FileId,
+                                                      pFileRequestExtentsCB,
+                                                      bWow64,
+                                                      &dwResultBufferLength,
+                                                      &SetFileExtentsResultCB );
+            break;
+        }
+
+        case AFS_REQUEST_TYPE_RELEASE_FILE_EXTENTS:
+        {
+
+            AFSReleaseExtentsCB *pFileReleaseExtentsCB = (AFSReleaseExtentsCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
+
+            if (afsd_logp->enabled) {
+                swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_RELEASE_FILE_EXTENTS Index %08lX File %08lX.%08lX.%08lX.%08lX",
+                          RequestBuffer->RequestIndex,
+                          RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
+                          RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique);
+
+                osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
+            }
+
+            RDR_ReleaseFileExtents( userp, RequestBuffer->FileId,
+                                   pFileReleaseExtentsCB,
+                                    bWow64,
+                                   RequestBuffer->ResultBufferLength,
+                                   &pResultCB);
+
+            break;
+        }
+
+        case AFS_REQUEST_TYPE_FLUSH_FILE:
+        {
+            if (afsd_logp->enabled) {
+                swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_FLUSH_FILE Index %08lX File %08lX.%08lX.%08lX.%08lX",
+                          RequestBuffer->RequestIndex,
+                          RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
+                          RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique);
+
+                osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
+            }
+
+            RDR_FlushFileEntry( userp, RequestBuffer->FileId,
+                                bWow64,
+                                RequestBuffer->ResultBufferLength,
+                                &pResultCB);
+            break;
+        }
+
+        case AFS_REQUEST_TYPE_OPEN_FILE:
+        {
+            AFSFileOpenCB *pFileOpenCB = (AFSFileOpenCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
+
+            if (afsd_logp->enabled) {
+                swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_OPEN_FILE Index %08lX File %08lX.%08lX.%08lX.%08lX",
+                          RequestBuffer->RequestIndex,
+                          RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
+                          RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique);
+
+                osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
+            }
+
+            RDR_OpenFileEntry( userp, RequestBuffer->FileId,
+                               pFileOpenCB,
+                               bWow64,
+                               bHoldFid,
+                               RequestBuffer->ResultBufferLength,
+                               &pResultCB);
+
+            break;
+        }
+
+        case AFS_REQUEST_TYPE_PIOCTL_OPEN:
+        {
+            AFSPIOCtlOpenCloseRequestCB *pPioctlCB = (AFSPIOCtlOpenCloseRequestCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
+
+            if (afsd_logp->enabled) {
+                swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_PIOCTL_OPEN Index %08lX Parent %08lX.%08lX.%08lX.%08lX",
+                          RequestBuffer->RequestIndex,
+                          RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
+                          RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique);
+
+                osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
+            }
+
+            RDR_PioctlOpen( userp,
+                            RequestBuffer->FileId,
+                            pPioctlCB,
+                            bWow64,
+                            RequestBuffer->ResultBufferLength,
+                            &pResultCB);
+            break;
+        }
+
+        case AFS_REQUEST_TYPE_PIOCTL_WRITE:
+        {
+            AFSPIOCtlIORequestCB *pPioctlCB = (AFSPIOCtlIORequestCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
+
+            if (afsd_logp->enabled) {
+                swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_PIOCTL_WRITE Index %08lX Parent %08lX.%08lX.%08lX.%08lX",
+                          RequestBuffer->RequestIndex,
+                          RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
+                          RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique);
+
+                osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
+            }
+
+            RDR_PioctlWrite( userp,
+                             RequestBuffer->FileId,
+                             pPioctlCB,
+                             bWow64,
+                             RequestBuffer->ResultBufferLength,
+                             &pResultCB);
+            break;
+        }
+
+    case AFS_REQUEST_TYPE_PIOCTL_READ:
+            {
+                AFSPIOCtlIORequestCB *pPioctlCB = (AFSPIOCtlIORequestCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
+
+                if (afsd_logp->enabled) {
+                    swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_PIOCTL_READ Index %08lX Parent %08lX.%08lX.%08lX.%08lX",
+                              RequestBuffer->RequestIndex,
+                              RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
+                              RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique);
+
+                    osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
+                }
+
+                RDR_PioctlRead( userp,
+                                RequestBuffer->FileId,
+                                pPioctlCB,
+                                bWow64,
+                                bIsLocalSystem,
+                                RequestBuffer->ResultBufferLength,
+                                &pResultCB);
+                break;
+            }
+
+    case AFS_REQUEST_TYPE_PIOCTL_CLOSE:
+            {
+                AFSPIOCtlOpenCloseRequestCB *pPioctlCB = (AFSPIOCtlOpenCloseRequestCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
+
+                if (afsd_logp->enabled) {
+                    swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_PIOCTL_CLOSE Index %08lX Parent %08lX.%08lX.%08lX.%08lX",
+                              RequestBuffer->RequestIndex,
+                              RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
+                              RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique);
+
+                    osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
+                }
+
+                RDR_PioctlClose( userp,
+                                RequestBuffer->FileId,
+                                pPioctlCB,
+                                bWow64,
+                                RequestBuffer->ResultBufferLength,
+                                &pResultCB);
+                break;
+            }
+
+
+    case AFS_REQUEST_TYPE_BYTE_RANGE_LOCK:
+            {
+                if (afsd_logp->enabled) {
+                    swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_BYTE_RANGE_LOCK Index %08lX File %08lX.%08lX.%08lX.%08lX %S",
+                              RequestBuffer->RequestIndex,
+                              RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
+                              RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique,
+                              BooleanFlagOn( RequestBuffer->RequestFlags, AFS_REQUEST_FLAG_SYNCHRONOUS) ? L"Sync" : L"Async");
+
+                    osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
+                }
+
+                AFSByteRangeLockRequestCB *pBRLRequestCB = (AFSByteRangeLockRequestCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
+
+                RDR_ByteRangeLockSync( userp,
+                                       RequestBuffer->FileId,
+                                       pBRLRequestCB,
+                                       bWow64,
+                                       RequestBuffer->ResultBufferLength,
+                                       &pResultCB);
+
+                break;
+            }
+
+    case AFS_REQUEST_TYPE_BYTE_RANGE_UNLOCK:
+            {
+                AFSByteRangeUnlockRequestCB *pBRURequestCB = (AFSByteRangeUnlockRequestCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
+
+                if (afsd_logp->enabled) {
+                    swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_BYTE_RANGE_UNLOCK Index %08lX File %08lX.%08lX.%08lX.%08lX",
+                              RequestBuffer->RequestIndex,
+                              RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
+                              RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique);
+
+                    osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
+                }
+
+                RDR_ByteRangeUnlock( userp,
+                                     RequestBuffer->FileId,
+                                     pBRURequestCB,
+                                     bWow64,
+                                     RequestBuffer->ResultBufferLength,
+                                     &pResultCB);
+                break;
+            }
+
+    case AFS_REQUEST_TYPE_BYTE_RANGE_UNLOCK_ALL:
+            {
+                AFSByteRangeUnlockRequestCB *pBRURequestCB = (AFSByteRangeUnlockRequestCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
+
+                if (afsd_logp->enabled) {
+                    swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_BYTE_RANGE_UNLOCK_ALL Index %08lX File %08lX.%08lX.%08lX.%08lX",
+                              RequestBuffer->RequestIndex,
+                              RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
+                              RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique);
+
+                    osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
+                }
+
+                RDR_ByteRangeUnlockAll( userp,
+                                        RequestBuffer->FileId,
+                                        pBRURequestCB,
+                                        bWow64,
+                                        RequestBuffer->ResultBufferLength,
+                                        &pResultCB);
+                break;
+            }
+
+    case AFS_REQUEST_TYPE_GET_VOLUME_INFO:
+            {
+                if (afsd_logp->enabled) {
+                    swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_GET_VOLUME_INFO Index %08lX File %08lX.%08lX.%08lX.%08lX",
+                              RequestBuffer->RequestIndex,
+                              RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
+                              RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique);
+
+                    osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
+                }
+
+                RDR_GetVolumeInfo( userp,
+                                   RequestBuffer->FileId,
+                                   bWow64,
+                                   RequestBuffer->ResultBufferLength,
+                                   &pResultCB);
+                break;
+            }
+
+    case AFS_REQUEST_TYPE_HOLD_FID:
+            {
+
+                AFSHoldFidRequestCB *pHoldFidCB = (AFSHoldFidRequestCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
+
+                if (afsd_logp->enabled) {
+                    swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_HOLD_FID Index %08lX",
+                              RequestBuffer->RequestIndex);
+
+                    osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
+                }
+
+                RDR_HoldFid( userp,
+                             pHoldFidCB,
+                             bFast,
+                             RequestBuffer->ResultBufferLength,
+                             &pResultCB);
+
+                break;
+            }
+
+    case AFS_REQUEST_TYPE_RELEASE_FID:
+            {
+
+                AFSReleaseFidRequestCB *pReleaseFidCB = (AFSReleaseFidRequestCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
+
+                if (afsd_logp->enabled) {
+                    swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_RELEASE_FID Index %08lX",
+                              RequestBuffer->RequestIndex);
+
+                    osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
+                }
+
+                RDR_ReleaseFid( userp,
+                                pReleaseFidCB,
+                                bFast,
+                                RequestBuffer->ResultBufferLength,
+                                &pResultCB);
+
+                break;
+            }
+
+    case AFS_REQUEST_TYPE_CLEANUP_PROCESSING:
+            {
+
+                AFSFileCleanupCB *pCleanupCB = (AFSFileCleanupCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
+
+                if (afsd_logp->enabled) {
+                    swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_CLEANUP_FILE Index %08lX File %08lX.%08lX.%08lX.%08lX",
+                              RequestBuffer->RequestIndex,
+                              RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
+                              RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique);
+
+                    osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
+                }
+
+                RDR_CleanupFileEntry( userp,
+                                      RequestBuffer->FileId,
+                                      RequestBuffer->Name,
+                                      RequestBuffer->NameLength,
+                                      pCleanupCB,
+                                      bWow64,
+                                      bFlushFile,
+                                      bDeleteFile,
+                                      bUnlockFile,
+                                      RequestBuffer->ResultBufferLength,
+                                      &pResultCB);
+
+                break;
+            }
+
+    case AFS_REQUEST_TYPE_PIPE_OPEN:
+            {
+                AFSPipeOpenCloseRequestCB *pPipeCB = (AFSPipeOpenCloseRequestCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
+
+                if (afsd_logp->enabled) {
+                    swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_PIPE_OPEN Index %08lX Parent %08lX.%08lX.%08lX.%08lX",
+                              RequestBuffer->RequestIndex,
+                              RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
+                              RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique);
+
+                    osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
+                }
+
+                RDR_PipeOpen( userp,
+                              RequestBuffer->FileId,
+                              RequestBuffer->Name,
+                              RequestBuffer->NameLength,
+                              pPipeCB,
+                              bWow64,
+                              RequestBuffer->ResultBufferLength,
+                              &pResultCB);
+                break;
+            }
+
+    case AFS_REQUEST_TYPE_PIPE_WRITE:
+            {
+                AFSPipeIORequestCB *pPipeCB = (AFSPipeIORequestCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
+                BYTE *pPipeData = ((BYTE *)RequestBuffer->Name + RequestBuffer->DataOffset + sizeof(AFSPipeIORequestCB));
+
+                if (afsd_logp->enabled) {
+                    swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_PIPE_WRITE Index %08lX Parent %08lX.%08lX.%08lX.%08lX",
+                              RequestBuffer->RequestIndex,
+                              RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
+                              RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique);
+
+                    osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
+                }
+
+                RDR_PipeWrite( userp,
+                               RequestBuffer->FileId,
+                               pPipeCB,
+                               pPipeData,
+                               bWow64,
+                               RequestBuffer->ResultBufferLength,
+                               &pResultCB);
+                break;
+            }
+
+    case AFS_REQUEST_TYPE_PIPE_READ:
+            {
+                AFSPipeIORequestCB *pPipeCB = (AFSPipeIORequestCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
+
+                if (afsd_logp->enabled) {
+                    swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_PIPE_READ Index %08lX Parent %08lX.%08lX.%08lX.%08lX",
+                              RequestBuffer->RequestIndex,
+                              RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
+                              RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique);
+
+                    osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
+                }
+
+                RDR_PipeRead( userp,
+                              RequestBuffer->FileId,
+                              pPipeCB,
+                              bWow64,
+                              RequestBuffer->ResultBufferLength,
+                              &pResultCB);
+                break;
+            }
+
+    case AFS_REQUEST_TYPE_PIPE_CLOSE:
+            {
+                AFSPipeOpenCloseRequestCB *pPipeCB = (AFSPipeOpenCloseRequestCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
+
+                if (afsd_logp->enabled) {
+                    swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_PIPE_CLOSE Index %08lX Parent %08lX.%08lX.%08lX.%08lX",
+                              RequestBuffer->RequestIndex,
+                              RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
+                              RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique);
+
+                    osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
+                }
+
+                RDR_PipeClose( userp,
+                                RequestBuffer->FileId,
+                                pPipeCB,
+                                bWow64,
+                                RequestBuffer->ResultBufferLength,
+                                &pResultCB);
+                break;
+            }
+
+
+    case AFS_REQUEST_TYPE_PIPE_TRANSCEIVE:
+            {
+                AFSPipeIORequestCB *pPipeCB = (AFSPipeIORequestCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
+                BYTE *pPipeData = ((BYTE *)RequestBuffer->Name + RequestBuffer->DataOffset + sizeof(AFSPipeIORequestCB));
+
+                if (afsd_logp->enabled) {
+                    swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_PIPE_TRANSCEIVE Index %08lX",
+                              RequestBuffer->RequestIndex);
+
+                    osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
+                }
+
+                RDR_PipeTransceive( userp,
+                                    RequestBuffer->FileId,
+                                    pPipeCB,
+                                    pPipeData,
+                                    bWow64,
+                                    RequestBuffer->ResultBufferLength,
+                                    &pResultCB);
+                break;
+            }
+
+    case AFS_REQUEST_TYPE_PIPE_QUERY_INFO:
+            {
+                AFSPipeInfoRequestCB *pPipeInfoCB = (AFSPipeInfoRequestCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
+
+                if (afsd_logp->enabled) {
+                    swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_PIPE_QUERY_INFO Index %08lX",
+                              RequestBuffer->RequestIndex);
+
+                    osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
+                }
+
+                RDR_PipeQueryInfo( userp,
+                                   RequestBuffer->FileId,
+                                   pPipeInfoCB,
+                                   bWow64,
+                                   RequestBuffer->ResultBufferLength,
+                                   &pResultCB);
+                break;
+            }
+
+    case AFS_REQUEST_TYPE_PIPE_SET_INFO:
+            {
+                AFSPipeInfoRequestCB *pPipeInfoCB = (AFSPipeInfoRequestCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
+                BYTE *pPipeData = ((BYTE *)RequestBuffer->Name + RequestBuffer->DataOffset + sizeof(AFSPipeInfoRequestCB));
+
+                if (afsd_logp->enabled) {
+                    swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_PIPE_SET_INFO Index %08lX",
+                              RequestBuffer->RequestIndex);
+
+                    osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
+                }
+
+                RDR_PipeSetInfo( userp,
+                                 RequestBuffer->FileId,
+                                 pPipeInfoCB,
+                                 pPipeData,
+                                 bWow64,
+                                 RequestBuffer->ResultBufferLength,
+                                 &pResultCB);
+
+                break;
+            }
+
+    default:
+            bUnsupported = TRUE;
+
+            if (afsd_logp->enabled) {
+                swprintf( wchBuffer, L"ProcessRequest Received unknown request type %08lX Index %08lX",
+                          RequestBuffer->RequestType,
+                          RequestBuffer->RequestIndex);
+
+                osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
+            }
+
+            break;
+    }
+
+    if( BooleanFlagOn( RequestBuffer->RequestFlags, AFS_REQUEST_FLAG_SYNCHRONOUS))
+    {
+       if (pResultCB == NULL) {
+           // We failed probably due to a memory allocation error
+            // unless the unsupported flag was set.
+           pResultCB = &stResultCB;
+            memset(&stResultCB, 0, sizeof(stResultCB));
+            if ( bUnsupported )
+                pResultCB->ResultStatus = STATUS_NOT_IMPLEMENTED;
+            else
+                pResultCB->ResultStatus = STATUS_NO_MEMORY;
+       }
+
+        //
+        // This is how the filter associates the response information passed in the IOCtl below to the
+        // original call. This request index is setup by the filter and should not be modified, otherwise the
+        // filter will not be able to locate the request in its internal queue and the blocking thread will
+        // not be awakened
+        //
+
+        pResultCB->RequestIndex = RequestBuffer->RequestIndex;
+
+        if (afsd_logp->enabled) {
+            swprintf( wchBuffer,
+                      L"ProcessRequest Responding to Index %08lX Length %08lX",
+                      pResultCB->RequestIndex,
+                      pResultCB->ResultBufferLength);
+
+            osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
+        }
+
+        //
+        // Now post the result back to the driver.
+        //
+
+        if( !RDR_DeviceIoControl( glDevHandle,
+                                  IOCTL_AFS_PROCESS_IRP_RESULT,
+                                  (void *)pResultCB,
+                                  sizeof( AFSCommResult) + pResultCB->ResultBufferLength,
+                                  (void *)NULL,
+                                  0,
+                                  &bytesReturned ))
+        {
+            char *pBuffer = (char *)wchBuffer;
+            gle = GetLastError();
+            if (afsd_logp->enabled) {
+                swprintf( wchBuffer,
+                          L"Failed to post IOCTL_AFS_PROCESS_IRP_RESULT gle %X", gle);
+                osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
+            }
+
+            sprintf( pBuffer,
+                     "Failed to post IOCTL_AFS_PROCESS_IRP_RESULT gle %X",
+                     GetLastError());
+            osi_panic(pBuffer, __FILE__, __LINE__);
+        }
+
+    }
+    else if (RequestBuffer->RequestType == AFS_REQUEST_TYPE_REQUEST_FILE_EXTENTS) {
+
+        if (SetFileExtentsResultCB) {
+
+            if (1 || afsd_logp->enabled) {
+                if (SetFileExtentsResultCB->ResultStatus != 0)
+                    swprintf( wchBuffer,
+                          L"ProcessRequest Responding Asynchronously with FAILURE to REQUEST_FILE_EXTENTS Index %08lX Count %08lX Status %08lX",
+                          RequestBuffer->RequestIndex, SetFileExtentsResultCB->ExtentCount, SetFileExtentsResultCB->ResultStatus);
+                else
+                    swprintf( wchBuffer,
+                          L"ProcessRequest Responding Asynchronously with SUCCESS to REQUEST_FILE_EXTENTS Index %08lX Count %08lX",
+                          RequestBuffer->RequestIndex, SetFileExtentsResultCB->ExtentCount);
+
+                osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
+            }
+
+            if( (SetFileExtentsResultCB->ExtentCount != 0 ||
+                 SetFileExtentsResultCB->ResultStatus != 0) &&
+                !RDR_DeviceIoControl( glDevHandle,
+                                       IOCTL_AFS_SET_FILE_EXTENTS,
+                                      (void *)SetFileExtentsResultCB,
+                                      dwResultBufferLength,
+                                      (void *)NULL,
+                                      0,
+                                      &bytesReturned ))
+            {
+                gle = GetLastError();
+                if (afsd_logp->enabled) {
+                    swprintf( wchBuffer,
+                              L"Failed to post IOCTL_AFS_SET_FILE_EXTENTS gle %X",
+                              gle);
+                    osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
+                }
+
+                // The file system returns an error when it can't find the FID
+                // This is a bug in the file system but we should try to avoid
+                // the crash and clean up our own memory space.
+                //
+                // Since we couldn't deliver the extents to the file system
+                // we should release them.
+                if ( SetFileExtentsResultCB->ExtentCount != 0)
+                {
+                    RDR_ReleaseFailedSetFileExtents( userp,
+                                                 SetFileExtentsResultCB,
+                                                 dwResultBufferLength);
+                }
+
+                if (gle != ERROR_GEN_FAILURE) {
+                    sprintf( pBuffer,
+                             "Failed to post IOCTL_AFS_SET_FILE_EXTENTS gle %X",
+                             gle);
+                    osi_panic(pBuffer, __FILE__, __LINE__);
+                }
+            }
+
+            free(SetFileExtentsResultCB);
+
+      } else {
+          /* Must be out of memory */
+          if (afsd_logp->enabled) {
+              swprintf( wchBuffer,
+                        L"ProcessRequest Responding Asynchronously STATUS_NO_MEMORY to REQUEST_FILE_EXTENTS Index %08lX",
+                        RequestBuffer->RequestIndex);
+
+              osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
+          }
+
+          RDR_SetFileStatus( (cm_fid_t *)&RequestBuffer->FileId, STATUS_NO_MEMORY);
+       }
+    }
+    else if (RequestBuffer->RequestType == AFS_REQUEST_TYPE_BYTE_RANGE_LOCK) {
+
+        if (afsd_logp->enabled) {
+            swprintf( wchBuffer,
+                      L"ProcessRequest Responding Asynchronously to REQUEST_TYPE_BYTE_RANGELOCK Index %08lX",
+                      RequestBuffer->RequestIndex);
+
+            osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
+        }
+
+
+        if (SetByteRangeLockResultCB) {
+
+            if( !RDR_DeviceIoControl( glDevHandle,
+                                  IOCTL_AFS_SET_BYTE_RANGE_LOCKS,
+                                  (void *)SetByteRangeLockResultCB,
+                                  dwResultBufferLength,
+                                  (void *)NULL,
+                                  0,
+                                  &bytesReturned ))
+            {
+                gle = GetLastError();
+
+                if (afsd_logp->enabled) {
+                    swprintf( wchBuffer,
+                              L"Failed to post IOCTL_AFS_SET_BYTE_RANGE_LOCKS gle 0x%x", gle);
+                    osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
+                }
+
+
+                // TODO - instead of a panic we should release the locks
+                sprintf( pBuffer,
+                         "Failed to post IOCTL_AFS_SET_BYTE_RANGE_LOCKS gle %X", gle);
+                osi_panic(pBuffer, __FILE__, __LINE__);
+            }
+
+            free(SetByteRangeLockResultCB);
+        } else {
+            /* Must be out of memory */
+            AFSSetByteRangeLockResultCB SetByteRangeLockResultCB;
+
+            dwResultBufferLength = sizeof(AFSSetByteRangeLockResultCB);
+            memset( &SetByteRangeLockResultCB, '\0', dwResultBufferLength );
+            SetByteRangeLockResultCB.FileId = RequestBuffer->FileId;
+            SetByteRangeLockResultCB.Result[0].Status = STATUS_NO_MEMORY;
+
+            if( !RDR_DeviceIoControl( glDevHandle,
+                                      IOCTL_AFS_SET_BYTE_RANGE_LOCKS,
+                                      (void *)&SetByteRangeLockResultCB,
+                                      dwResultBufferLength,
+                                      (void *)NULL,
+                                      0,
+                                      &bytesReturned ))
+            {
+                gle = GetLastError();
+
+                if (afsd_logp->enabled) {
+                    swprintf( wchBuffer,
+                              L"Failed to post IOCTL_AFS_SET_BYTE_RANGE_LOCKS gle 0x%x", gle);
+                    osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
+                }
+
+                /* We were out of memory - nothing to do */
+            }
+        }
+    }
+    else {
+
+        if (afsd_logp->enabled) {
+            swprintf( wchBuffer,
+                      L"ProcessRequest Not responding to async Index %08lX",
+                      RequestBuffer->RequestIndex);
+
+            osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
+        }
+    }
+
+    if (bRetry)
+        goto retry;
+
+    if (userp)
+        RDR_ReleaseUser(userp);
+
+
+    if( pResultCB && pResultCB != &stResultCB)
+    {
+
+       free( pResultCB);
+    }
+    return;
+}
+
+
+extern "C" DWORD
+RDR_SetFileExtents( AFSSetFileExtentsCB *pSetFileExtentsResultCB,
+                    DWORD dwResultBufferLength)
+{
+    WCHAR wchBuffer[1024];
+    DWORD bytesReturned;
+    DWORD gle;
+
+    if (1 || afsd_logp->enabled) {
+        if (pSetFileExtentsResultCB->ResultStatus != 0)
+            swprintf( wchBuffer,
+               L"RDR_SetFileExtents IOCTL_AFS_SET_FILE_EXTENTS FAILURE Count %08lX Status %08lX",
+               pSetFileExtentsResultCB->ExtentCount, pSetFileExtentsResultCB->ResultStatus);
+        else
+            swprintf( wchBuffer,
+               L"RDR_SetFileExtents IOCTL_AFS_SET_FILE_EXTENTS SUCCESS Count %08lX",
+               pSetFileExtentsResultCB->ExtentCount);
+
+        osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
+    }
+
+    if( !RDR_DeviceIoControl( glDevHandle,
+                              IOCTL_AFS_SET_FILE_EXTENTS,
+                              (void *)pSetFileExtentsResultCB,
+                              dwResultBufferLength,
+                              (void *)NULL,
+                              0,
+                              &bytesReturned ))
+    {
+        gle = GetLastError();
+        return gle;
+    }
+
+    return 0;
+}
+
+
+extern "C" DWORD
+RDR_SetFileStatus( cm_fid_t *fidp,
+                   DWORD dwStatus)
+{
+    WCHAR               wchBuffer[1024];
+    AFSExtentFailureCB  SetFileStatusCB;
+    DWORD               bytesReturned;
+    DWORD               gle;
+    AFSFileID          *pFileId = (AFSFileID *)fidp;
+
+    SetFileStatusCB.FileId = *pFileId;
+    SetFileStatusCB.FailureStatus = dwStatus;
+
+    if (afsd_logp->enabled) {
+        swprintf( wchBuffer, L"RDR_SetFileStatus IOCTL_AFS_EXTENT_FAILURE_CB Fid %08lX.%08lX.%08lX.%08lX Status 0x%lX",
+                  pFileId->Cell, pFileId->Volume,
+                  pFileId->Vnode, pFileId->Unique,
+                  dwStatus);
+
+        osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
+    }
+
+    if( !RDR_DeviceIoControl( glDevHandle,
+                              IOCTL_AFS_SET_FILE_EXTENT_FAILURE,
+                              (void *)&SetFileStatusCB,
+                              sizeof(AFSExtentFailureCB),
+                              (void *)NULL,
+                              0,
+                              &bytesReturned ))
+    {
+        gle = GetLastError();
+        return gle;
+    }
+
+    return 0;
+}
+
+
+extern "C" DWORD
+RDR_RequestExtentRelease(cm_fid_t *fidp, LARGE_INTEGER numOfHeldExtents, DWORD numOfExtents, AFSFileExtentCB *extentList)
+{
+
+    HANDLE hDevHandle = NULL;
+    DWORD bytesReturned;
+    AFSReleaseFileExtentsCB *requestBuffer = NULL;
+    AFSReleaseFileExtentsResultCB *responseBuffer = NULL;
+    DWORD requestBufferLen, responseBufferLen;
+    bool bError = false;
+    DWORD rc = 0;
+    WCHAR wchBuffer[256];
+    DWORD gle;
+
+    if (ExitPending) {
+        if (afsd_logp->enabled) {
+            swprintf( wchBuffer,
+                      L"IOCTL_AFS_RELEASE_FILE_EXTENTS request ignored due to shutdown pending");
+
+            osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
+        }
+
+        OutputDebugString(L"RDR_RequestExtentRequest ignored - shutdown pending\n");
+        return CM_ERROR_WOULDBLOCK;
+    }
+
+    if (afsd_logp->enabled) {
+        swprintf( wchBuffer,
+                  L"IOCTL_AFS_RELEASE_FILE_EXTENTS request - number %08lX",
+                  numOfExtents);
+
+        osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
+    }
+
+    //
+    // We use the global handle to the control device instance
+    //
+
+    hDevHandle = glDevHandle;
+
+    //
+    // Allocate a request buffer.
+    //
+
+    requestBufferLen = sizeof( AFSReleaseFileExtentsCB) + sizeof(AFSFileExtentCB) * numOfExtents;
+    requestBuffer = (AFSReleaseFileExtentsCB *)malloc( requestBufferLen);
+    responseBufferLen = (sizeof( AFSReleaseFileExtentsResultCB) + sizeof( AFSReleaseFileExtentsResultFileCB)) * numOfExtents;
+    responseBuffer = (AFSReleaseFileExtentsResultCB *)malloc( responseBufferLen);
+
+
+    if( requestBuffer && responseBuffer)
+    {
+
+       memset( requestBuffer, '\0', sizeof( AFSReleaseFileExtentsCB));
+       memset( responseBuffer, '\0', responseBufferLen);
+
+        // If there is a FID provided, use it
+        if (fidp && extentList)
+        {
+            RDR_fid2FID( fidp, &requestBuffer->FileId);
+
+            memcpy(&requestBuffer->FileExtents, extentList, numOfExtents * sizeof(AFSFileExtentCB));
+
+            requestBuffer->Flags = 0;
+        } else {
+
+            requestBuffer->Flags = AFS_RELEASE_EXTENTS_FLAGS_RELEASE_ALL;
+        }
+
+        // Set the number of extents to be freed
+        // Leave the rest of the structure as zeros to indicate free anything
+        requestBuffer->ExtentCount = numOfExtents;
+
+        requestBuffer->HeldExtentCount = numOfHeldExtents;
+
+        if( !RDR_DeviceIoControl( hDevHandle,
+                                  IOCTL_AFS_RELEASE_FILE_EXTENTS,
+                                  (void *)requestBuffer,
+                                  requestBufferLen,
+                                  (void *)responseBuffer,
+                                  responseBufferLen,
+                                  &bytesReturned ))
+        {
+            //
+            // Error condition back from driver
+            //
+            if (afsd_logp->enabled) {
+                gle = GetLastError();
+                swprintf( wchBuffer,
+                          L"Failed to post IOCTL_AFS_RELEASE_FILE_EXTENTS - gle 0x%x", gle);
+                osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
+            }
+            rc = -1;
+            goto cleanup;
+        }
+
+        //
+        // Go process the request
+        //
+
+        if (afsd_logp->enabled) {
+            swprintf( wchBuffer,
+                      L"IOCTL_AFS_RELEASE_FILE_EXTENTS returns - serial number %08lX flags %lX FileCount %lX",
+                      responseBuffer->SerialNumber, responseBuffer->Flags, responseBuffer->FileCount);
+            osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
+        }
+
+        rc = RDR_ProcessReleaseFileExtentsResult( responseBuffer, bytesReturned);
+    } else {
+
+        rc = ENOMEM;
+    }
+
+  cleanup:
+    if (requestBuffer)
+        free( requestBuffer);
+    if (responseBuffer)
+        free( responseBuffer);
+
+    return rc;
+}
+
+
+extern "C" DWORD
+RDR_NetworkStatus(BOOLEAN status)
+{
+
+    HANDLE hDevHandle = NULL;
+    DWORD bytesReturned;
+    AFSNetworkStatusCB *requestBuffer = NULL;
+    DWORD rc = 0;
+    WCHAR wchBuffer[256];
+    DWORD gle;
+
+    if (afsd_logp->enabled) {
+        swprintf( wchBuffer,
+                  L"IOCTL_AFS_NETWORK_STATUS request - status %d",
+                  status);
+
+        osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
+    }
+
+    //
+    // We use the global handle to the control device instance
+    //
+
+    hDevHandle = glDevHandle;
+
+    //
+    // Allocate a request buffer.
+    //
+
+    requestBuffer = (AFSNetworkStatusCB *)malloc( sizeof( AFSNetworkStatusCB));
+
+
+    if( requestBuffer)
+    {
+
+       memset( requestBuffer, '\0', sizeof( AFSNetworkStatusCB));
+
+        // Set the number of extents to be freed
+        // Leave the rest of the structure as zeros to indicate free anything
+        requestBuffer->Online = status;
+
+        if( !RDR_DeviceIoControl( hDevHandle,
+                                  IOCTL_AFS_NETWORK_STATUS,
+                                  (void *)requestBuffer,
+                                  sizeof( AFSNetworkStatusCB),
+                                  NULL,
+                                  0,
+                                  &bytesReturned ))
+        {
+            //
+            // Error condition back from driver
+            //
+            if (afsd_logp->enabled) {
+                gle = GetLastError();
+                swprintf( wchBuffer,
+                          L"Failed to post IOCTL_AFS_NETWORK_STATUS gle 0x%x",
+                          gle);
+                osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
+            }
+
+            rc = -1;
+            goto cleanup;
+        }
+    } else
+        rc = ENOMEM;
+
+  cleanup:
+    if (requestBuffer)
+        free( requestBuffer);
+
+    return rc;
+}
+
+
+
+extern "C" DWORD
+RDR_VolumeStatus(ULONG cellID, ULONG volID, BOOLEAN online)
+{
+
+    HANDLE hDevHandle = NULL;
+    DWORD bytesReturned;
+    AFSVolumeStatusCB *requestBuffer = NULL;
+    DWORD rc = 0;
+    WCHAR wchBuffer[256];
+    DWORD gle;
+
+    if (afsd_logp->enabled) {
+        swprintf( wchBuffer,
+                  L"IOCTL_AFS_VOLUME_STATUS request - cell 0x%x vol 0x%x online %d",
+                  cellID, volID, online);
+
+        osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
+    }
+
+    //
+    // We use the global handle to the control device instance
+    //
+
+    hDevHandle = glDevHandle;
+
+    //
+    // Allocate a request buffer.
+    //
+
+    requestBuffer = (AFSVolumeStatusCB *)malloc( sizeof( AFSVolumeStatusCB));
+
+
+    if( requestBuffer)
+    {
+
+       memset( requestBuffer, '\0', sizeof( AFSVolumeStatusCB));
+
+        requestBuffer->FileID.Cell = cellID;
+        requestBuffer->FileID.Volume = volID;
+        requestBuffer->Online = online;
+
+        if( !RDR_DeviceIoControl( hDevHandle,
+                                  IOCTL_AFS_VOLUME_STATUS,
+                                  (void *)requestBuffer,
+                                  sizeof( AFSVolumeStatusCB),
+                                  NULL,
+                                  0,
+                                  &bytesReturned ))
+        {
+            //
+            // Error condition back from driver
+            //
+
+            if (afsd_logp->enabled) {
+                gle = GetLastError();
+                swprintf( wchBuffer,
+                          L"Failed to post IOCTL_AFS_VOLUME_STATUS gle 0x%x", gle);
+                osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
+            }
+
+            rc = -1;
+            goto cleanup;
+        }
+    } else
+        rc = ENOMEM;
+
+  cleanup:
+    if (requestBuffer)
+        free( requestBuffer);
+
+    return rc;
+}
+
+extern "C" DWORD
+RDR_NetworkAddrChange(void)
+{
+    return 0;
+}
+
+
+extern "C" DWORD
+RDR_InvalidateVolume(ULONG cellID, ULONG volID, ULONG reason)
+{
+
+    HANDLE hDevHandle = NULL;
+    DWORD bytesReturned;
+    AFSInvalidateCacheCB *requestBuffer = NULL;
+    DWORD rc = 0;
+    WCHAR wchBuffer[256];
+    DWORD gle;
+
+    if (afsd_logp->enabled) {
+        swprintf( wchBuffer,
+                  L"IOCTL_AFS_INVALIDATE_CACHE (vol) request - cell 0x%x vol 0x%x reason %d",
+                  cellID, volID, reason);
+
+        osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
+    }
+
+    //
+    // We use the global handle to the control device instance
+    //
+
+    hDevHandle = glDevHandle;
+
+    //
+    // Allocate a request buffer.
+    //
+
+    requestBuffer = (AFSInvalidateCacheCB *)malloc( sizeof( AFSInvalidateCacheCB));
+
+
+    if( requestBuffer)
+    {
+
+       memset( requestBuffer, '\0', sizeof( AFSInvalidateCacheCB));
+
+        requestBuffer->FileID.Cell = cellID;
+        requestBuffer->FileID.Volume = volID;
+        requestBuffer->WholeVolume = TRUE;
+        requestBuffer->Reason = reason;
+
+        if( !RDR_DeviceIoControl( hDevHandle,
+                                  IOCTL_AFS_INVALIDATE_CACHE,
+                                  (void *)requestBuffer,
+                                  sizeof( AFSInvalidateCacheCB),
+                                  NULL,
+                                  0,
+                                  &bytesReturned ))
+        {
+            //
+            // Error condition back from driver
+            //
+
+            if (afsd_logp->enabled) {
+                gle = GetLastError();
+                swprintf( wchBuffer,
+                          L"Failed to post IOCTL_AFS_INVALIDATE_VOLUME gle 0x%x", gle);
+                osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
+            }
+
+            rc = -1;
+            goto cleanup;
+        }
+    } else
+        rc = ENOMEM;
+
+  cleanup:
+    if (requestBuffer)
+        free( requestBuffer);
+
+    return rc;
+}
+
+
+extern "C" DWORD
+RDR_InvalidateObject(ULONG cellID, ULONG volID, ULONG vnode, ULONG uniq, ULONG hash, ULONG fileType, ULONG reason)
+{
+
+    HANDLE hDevHandle = NULL;
+    DWORD bytesReturned;
+    AFSInvalidateCacheCB *requestBuffer = NULL;
+    DWORD rc = 0;
+    WCHAR wchBuffer[256];
+    DWORD gle;
+
+    if (afsd_logp->enabled) {
+        swprintf( wchBuffer,
+                  L"IOCTL_AFS_INVALIDATE_CACHE (obj) request - cell 0x%x vol 0x%x vn 0x%x uniq 0x%x hash 0x%x type 0x%x reason %d",
+                  cellID, volID, vnode, uniq, hash, fileType, reason);
+
+        osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
+    }
+
+    //
+    // We use the global handle to the control device instance
+    //
+
+    hDevHandle = glDevHandle;
+
+    //
+    // Allocate a request buffer.
+    //
+
+    requestBuffer = (AFSInvalidateCacheCB *)malloc( sizeof( AFSInvalidateCacheCB));
+
+
+    if( requestBuffer)
+    {
+
+       memset( requestBuffer, '\0', sizeof( AFSInvalidateCacheCB));
+
+        requestBuffer->FileID.Cell = cellID;
+        requestBuffer->FileID.Volume = volID;
+        requestBuffer->FileID.Vnode = vnode;
+        requestBuffer->FileID.Unique = uniq;
+        requestBuffer->FileID.Hash = hash;
+        requestBuffer->FileType = fileType;
+        requestBuffer->WholeVolume = FALSE;
+        requestBuffer->Reason = reason;
+
+        if( !RDR_DeviceIoControl( hDevHandle,
+                                  IOCTL_AFS_INVALIDATE_CACHE,
+                                  (void *)requestBuffer,
+                                  sizeof( AFSInvalidateCacheCB),
+                                  NULL,
+                                  0,
+                                  &bytesReturned ))
+        {
+            //
+            // Error condition back from driver
+            //
+            if (afsd_logp->enabled) {
+                gle = GetLastError();
+                swprintf( wchBuffer,
+                          L"Failed to post IOCTL_AFS_INVALIDATE_CACHE gle 0x%x", gle);
+                osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
+            }
+
+            rc = -1;
+            goto cleanup;
+        }
+    } else
+        rc = ENOMEM;
+
+  cleanup:
+    if (requestBuffer)
+        free( requestBuffer);
+
+    return rc;
+}
+
+
+
+extern "C" DWORD
+RDR_SysName(ULONG Architecture, ULONG Count, WCHAR **NameList)
+{
+
+    HANDLE hDevHandle = NULL;
+    DWORD bytesReturned;
+    AFSSysNameNotificationCB *requestBuffer = NULL;
+    DWORD rc = 0;
+    WCHAR wchBuffer[256];
+    DWORD Length;
+    DWORD gle;
+
+    if (afsd_logp->enabled) {
+        swprintf( wchBuffer,
+                  L"IOCTL_AFS_SYSNAME_NOTIFICATION request - Arch %d Count %d",
+                  Architecture, Count);
+
+        osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
+    }
+
+    if (Count <= 0 || NameList == NULL)
+        return -1;
+
+    //
+    // We use the global handle to the control device instance
+    //
+
+    hDevHandle = glDevHandle;
+
+    //
+    // Allocate a request buffer.
+    //
+
+    Length = sizeof (AFSSysNameNotificationCB) + (Count - 1) * sizeof (AFSSysName);
+    requestBuffer = (AFSSysNameNotificationCB *)malloc( Length );
+
+
+    if( requestBuffer)
+    {
+        unsigned int i;
+
+       memset( requestBuffer, '\0', Length);
+
+        requestBuffer->Architecture = Architecture;
+        requestBuffer->NumberOfNames = Count;
+        for ( i=0 ; i<Count; i++) {
+            size_t len = wcslen(NameList[i]);
+            requestBuffer->SysNames[i].Length = (ULONG) (len * sizeof(WCHAR));
+            StringCchCopyNW(requestBuffer->SysNames[i].String, AFS_MAX_SYSNAME_LENGTH,
+                            NameList[i], len);
+        }
+
+        if( !RDR_DeviceIoControl( hDevHandle,
+                                  IOCTL_AFS_SYSNAME_NOTIFICATION,
+                                  (void *)requestBuffer,
+                                  Length,
+                                  NULL,
+                                  0,
+                                  &bytesReturned ))
+        {
+            //
+            // Error condition back from driver
+            //
+            if (afsd_logp->enabled) {
+                gle = GetLastError();
+                swprintf( wchBuffer,
+                          L"Failed to post IOCTL_AFS_SYSNAME_NOTIFICATION gle 0x%x", gle);
+                osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
+            }
+
+            rc = -1;
+            goto cleanup;
+        }
+    } else
+        rc = ENOMEM;
+
+  cleanup:
+    if (requestBuffer)
+        free( requestBuffer);
+
+    return rc;
+}