--- /dev/null
+/*
+ * 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;
+}