/*++ Copyright (c) 1999 Microsoft Corporation Module Name: ntumrefl.h Abstract: This module defines the types and functions which make up the reflector library. These functions are used by the miniredirs to reflect calls upto the user mode. Author: Andy Herron (andyhe) --*/ #ifndef _NTUMREFL_H #define _NTUMREFL_H // // These two structures are opaque to callers of the reflector library but // we'll define them here to make the compiler validate the types sent in. // typedef struct _UMRX_USERMODE_REFLECT_BLOCK *PUMRX_USERMODE_REFLECT_BLOCK; typedef struct _UMRX_USERMODE_WORKER_INSTANCE *PUMRX_USERMODE_WORKER_INSTANCE; // // These structures and function prototypes are for the user mode reflector. // #define UMREFLECTOR_CURRENT_VERSION 1 // // This structure will be exposed to both user and kernel mode components. // #define UMRX_WORKITEM_IMPERSONATING 0X00000001 typedef struct _UMRX_USERMODE_WORKITEM_HEADER { // // The kernel mode component stores the context in here. // PVOID Context; // // The kernel mode context uses the serial number to keep track of the // number of requests. // ULONG SerialNumber; // // This allows the kernel mode component of the reflector library to track // request to response. If this is zero, then no response is present in the // workitem. // USHORT WorkItemMID; // // Length of the workitem. // ULONG WorkItemLength; // // Flags describing the state of the request. // ULONG Flags; BOOL callWorkItemCleanup; union { IO_STATUS_BLOCK IoStatus; IO_STATUS_BLOCK; }; } UMRX_USERMODE_WORKITEM_HEADER, *PUMRX_USERMODE_WORKITEM_HEADER; // // The structure that is sent down to the usermode when starting the // DAV MiniRedir. // typedef struct _DAV_USERMODE_DATA { // // The ProcessId of the svchost.exe process that is loading the webclnt.dll // ULONG ProcessId; // // The WinInet's Cache Path. // WCHAR WinInetCachePath[MAX_PATH]; } DAV_USERMODE_DATA, *PDAV_USERMODE_DATA; // // This routine registers the user mode process with the kernel mode component. // The DriverDeviceName must be a valid name of the form L"\\Device\\foobar" // where foobar is the device name registered with RxRegisterMinirdr. The // Reflector is returned by the call and points to an opaque structure that // should be passed to subsequent calls. This structure gets initialized during // this call. The return value is a Win32 error code. STATUS_SUCCESS is // returned on success. // ULONG UMReflectorRegister ( PWCHAR DriverDeviceName, ULONG ReflectorVersion, PUMRX_USERMODE_REFLECT_BLOCK *Reflector ); // // This will close down the associated user mode reflector instance. If any user // mode threads are waiting for requests, they'll return immediately. This call // will not return until all threads are closed down and all associated // structures are freed. A user application should not use the Reflector after // this call has been started except to complete work on a request that is // pending. // ULONG UMReflectorUnregister( PUMRX_USERMODE_REFLECT_BLOCK Reflector ); // // We have instance handles for those apps with multiple threads pending in // the library at once. You should open an instance thread for each worker // thread you'll have sending down an IOCTL waiting for work. // ULONG UMReflectorOpenWorker( PUMRX_USERMODE_REFLECT_BLOCK ReflectorHandle, PUMRX_USERMODE_WORKER_INSTANCE *WorkerHandle ); // // Even after calling UMReflectorUnregister, you should still call // UMReflectorCloseWorker on each worker handle instance you have open. // VOID UMReflectorCloseWorker( PUMRX_USERMODE_WORKER_INSTANCE WorkerHandle ); // // This starts the Mini-Redir. // ULONG UMReflectorStart( ULONG ReflectorVersion, PUMRX_USERMODE_REFLECT_BLOCK ReflectorHandle ); // // This stops the Mini-Redir. // ULONG UMReflectorStop( PUMRX_USERMODE_REFLECT_BLOCK ReflectorHandle ); // // If any user mode threads are waiting for requests, they'll return // immediately. // ULONG UMReflectorReleaseThreads( PUMRX_USERMODE_REFLECT_BLOCK ReflectorHandle ); // // This allocates a work item that may have additional space below it for // Mini-Redir specific information. It should be freed using // ReflectorCompleteWorkItem below. // PUMRX_USERMODE_WORKITEM_HEADER UMReflectorAllocateWorkItem( PUMRX_USERMODE_WORKER_INSTANCE WorkerHandle, ULONG AdditionalBytes ); // // This may free the work item. It may unmap and possibly free both the user // and kernel mode associated buffers. If a kernel mode associated buffer is // stored in this WorkItem, the WorkItem will be posted back to the kernel mode // process for freeing. Once the call to ReflectorCompleteWorkItem is called, // the WorkItem should not be touched by the calling application. // ULONG UMReflectorCompleteWorkItem( PUMRX_USERMODE_WORKER_INSTANCE WorkerHandle, PUMRX_USERMODE_WORKITEM_HEADER WorkItem ); // // This user mode thread is requesting a client request to work on. It will not // return until the kernel portion of the library has a request to send up to // user mode. If the PreviousWorkItem is not NULL, then this work item contains // a response that will be sent down to the kernel. This eliminates a transition // for the typical case of a worker thread returning a result and then asking // for another work item. // ULONG UMReflectorGetRequest ( PUMRX_USERMODE_WORKER_INSTANCE WorkerHandle, PUMRX_USERMODE_WORKITEM_HEADER ResponseWorkItem OPTIONAL, PUMRX_USERMODE_WORKITEM_HEADER ReceiveWorkItem, BOOL revertAlreadyDone ); // // A response is sent down to kernel mode due to an action in user mode being // completed. The kernel mode library does not get another request for this // thread. Both the request and response buffers associated with the WorkItem // will be unmapped/unlocked/freed (when the library has done the // allocating/locking/mapping). // ULONG UMReflectorSendResponse( PUMRX_USERMODE_WORKER_INSTANCE WorkerHandle, PUMRX_USERMODE_WORKITEM_HEADER WorkItem ); ULONG UMReflectorImpersonate( PUMRX_USERMODE_WORKITEM_HEADER IncomingWorkItem, HANDLE ImpersonationToken ); ULONG UMReflectorRevert ( PUMRX_USERMODE_WORKITEM_HEADER IncomingWorkItem ); // // If the user mode side needs to allocate memory in the shared memory // area, it can do so using these calls. Note that if the memory isn't // freed up by the caller, it will be freed when the kernel mode async work // context is freed. // ULONG UMReflectorAllocateSharedMemory( PUMRX_USERMODE_WORKER_INSTANCE WorkerHandle, PUMRX_USERMODE_WORKITEM_HEADER WorkItem, SIZE_T SizeRequired, PVOID *SharedBuffer ); ULONG UMReflectorFreeSharedMemory( PUMRX_USERMODE_WORKER_INSTANCE WorkerHandle, PUMRX_USERMODE_WORKITEM_HEADER WorkItem, PVOID SharedBuffer ); VOID UMReflectorCompleteRequest( PUMRX_USERMODE_REFLECT_BLOCK ReflectorHandle, PUMRX_USERMODE_WORKITEM_HEADER WorkItemHeader ); VOID DavCleanupWorkItem( PUMRX_USERMODE_WORKITEM_HEADER UserWorkItem ); // // The control codes specific to the reflector library. // #define IOCTL_UMRX_RELEASE_THREADS \ _RDR_CONTROL_CODE(222, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_UMRX_GET_REQUEST \ _RDR_CONTROL_CODE(223, METHOD_OUT_DIRECT, FILE_ANY_ACCESS) #define IOCTL_UMRX_RESPONSE_AND_REQUEST \ _RDR_CONTROL_CODE(224, METHOD_OUT_DIRECT, FILE_ANY_ACCESS) #define IOCTL_UMRX_RESPONSE \ _RDR_CONTROL_CODE(225, METHOD_OUT_DIRECT, FILE_ANY_ACCESS) #define IOCTL_UMRX_GET_LOCK_OWNER \ _RDR_CONTROL_CODE(226, METHOD_BUFFERED, FILE_ANY_ACCESS) #define FSCTL_UMRX_START \ _RDR_CONTROL_CODE(227, METHOD_BUFFERED, FILE_ANY_ACCESS) #define FSCTL_UMRX_STOP \ _RDR_CONTROL_CODE(228, METHOD_BUFFERED, FILE_ANY_ACCESS) #endif // _NTUMREFL_H