討論區快速選單
知識庫快速選單
網路投保旅行平安險 傑米的攝影旅遊筆記 政府補助!學嵌入式+物聯網
[ 回上頁 ] [ 討論區發言規則 ]
建立MDL讓AP跟Driver使用共同的memory buffer來交換資料
更改我的閱讀文章字型大小
作者 : shihchin(shihchin)
[ 貼文 58 | 人氣 3119 | 評價 0 | 評價/貼文 0 | 送出評價 0 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2012/1/24 下午 11:21:42
如標題,目前我已經可以讓單一AP跟driver可以共同使用同一個memory buffer,中間透過SEMAPHORE的方式去做lock跟unlock的動作,driver有用timer去固定一段時間也存取memory buffer,可是當第二個AP開啟使用同一個memory buffer時,幾乎都會lock住,造成第一個AP也會處於WAIT狀態,可是只有開啟1個AP時都OK,SEMAPHORE的個數我只給1,兩個AP跟driver都可以使用同一個SEMAPHORE的handle,請問我這樣子做是否有哪邊出問題?
作者 : shihchin(shihchin)
[ 貼文 58 | 人氣 3119 | 評價 0 | 評價/貼文 0 | 送出評價 0 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2012/1/30 上午 11:22:30
moufiltr.c

#include <ntddk.h>
#include <kbdmou.h>
#include <ntddmou.h>
#include <ntdd8042.h>
#include <wdf.h>
#include <wdmsec.h> /* for SDDLs */
#include "moufiltr.h"


#ifdef ALLOC_PRAGMA
#pragma alloc_text (PAGE, DriverEntry)
#pragma alloc_text (PAGE, MouFilter_EvtDeviceAdd)
#pragma alloc_text (PAGE, MouFilter_EvtIoInternalDeviceControl)
#endif

#pragma warning(push)
#pragma warning(disable:4055) // type case from PVOID to PSERVICE_CALLBACK_ROUTINE
#pragma warning(disable:4152) // function/data pointer conversion in expression


NTSTATUS
CreateControlDevice(IN WDFDRIVER driver, IN WDFDEVICE fdev, OUT WDFDEVICE *dev)
{
    PWDFDEVICE_INIT devInit;
    WDFDEVICE cdev = NULL;
    WDFQUEUE q = NULL;
    WDF_OBJECT_ATTRIBUTES ctrlAttr;
    WDF_IO_QUEUE_CONFIG ioQueueConfig;
    NTSTATUS status;
    DECLARE_CONST_UNICODE_STRING(ntDeviceName, FSPAD_NT_NAME);
    DECLARE_CONST_UNICODE_STRING(symLinkName, FSPAD_SYMBOL_NAME);

    devInit = WdfControlDeviceInitAllocate(driver, &SDDL_DEVOBJ_SYS_ALL_ADM_RWX_WORLD_RW_RES_R);
    if (devInit == NULL) {
     DbgPrint("WdfControlDeviceInitAllocate failed");
     return (STATUS_INSUFFICIENT_RESOURCES);
    }
    WdfDeviceInitSetExclusive(devInit, FALSE);
    status = WdfDeviceInitAssignName(devInit,&ntDeviceName);
    if (!NT_SUCCESS(status)) {
     DbgPrint("failed to assign name(0x%x)", status);
     goto create_ctl_dev_err;
    }
    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&ctrlAttr,CTRL_DEV_EXT);
    status = WdfDeviceCreate(&devInit, &ctrlAttr, &cdev);
    if (!NT_SUCCESS(status)) {
     DbgPrint("failed to create ctrlDev(0x%x)", status);
     goto create_ctl_dev_err;
    }
    IoDeleteSymbolicLink((PUNICODE_STRING)&symLinkName);
    status = WdfDeviceCreateSymbolicLink(cdev, &symLinkName);
    if (!NT_SUCCESS(status)) {
     DbgPrint("failed to create symlink(0x%x)", status);
     goto create_ctl_dev_err;
    }
    WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&ioQueueConfig,WdfIoQueueDispatchParallel);
作者 : shihchin(shihchin)
[ 貼文 58 | 人氣 3119 | 評價 0 | 評價/貼文 0 | 送出評價 0 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2012/1/30 上午 11:23:23
ioQueueConfig.EvtIoDeviceControl = FspadIoctl;

    status = WdfIoQueueCreate(cdev, &ioQueueConfig,
     WDF_NO_OBJECT_ATTRIBUTES, &q);
    if (!NT_SUCCESS(status)) {
     DbgPrint("failed to create ctrlDev queue(0x%x)", status);
     goto create_ctl_dev_err;
    }

    CtrlDevGetExt(cdev)->fdev = fdev;
    CtrlDevGetExt(cdev)->q = q;

    WdfControlFinishInitializing(cdev);

    *dev = cdev;

    return (STATUS_SUCCESS);

    create_ctl_dev_err:
     if (devInit != NULL)
     WdfDeviceInitFree(devInit);
     if (cdev != NULL)
     WdfObjectDelete(cdev);
     return (status);
}

VOID
MyWorkItemCallback (
    IN WDFWORKITEM hWorkItem
    )
{
    //UNREFERENCED_PARAMETER(hWorkItem);
    WDFDEVICE hDevice=NULL;
    PDEVICE_EXTENSION devExt;
    BYTE temp;
    LONG result;
    NTSTATUS status;

    hDevice = WdfWorkItemGetParentObject(hWorkItem);
    devExt = FilterGetData(hDevice);
    temp=0;

    if (devExt->Semaphore!=NULL)
    {
     status = KeWaitForSingleObject(devExt->Semaphore, UserRequest, UserMode,
     FALSE, NULL);
     if (!NT_SUCCESS(status)) {
     DebugPrint( ("KeWaitForSingleObject fail: 0x%x!\n", status));
     }
     if (devExt->MDLLock==1)
     {
     temp=((BYTE *)devExt->CommonBufferBaseVA)[0];
     RtlFillMemory(devExt->CommonBufferBaseVA,0x2000,devExt->tempdata);
     }
     if (devExt->MDLLock2==1)
     {
     RtlFillMemory(devExt->CommonBufferBaseVA2,0x2000,temp);
     }
     if (devExt->tempdata==99)
     devExt->tempdata=0;
     else
     devExt->tempdata++;
     result = KeReleaseSemaphore(devExt->Semaphore, 0, 1, FALSE);
     if (result)
     DbgPrint(("KeReleaseSemaphore fail.\n"));
    }
    return;
}
作者 : shihchin(shihchin)
[ 貼文 58 | 人氣 3119 | 評價 0 | 評價/貼文 0 | 送出評價 0 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2012/1/30 上午 11:28:53

VOID
MyEvtTimerFunc (
    IN WDFTIMER Timer
    )
{
    WDFDEVICE hDevice=NULL;
    PDEVICE_EXTENSION devExt;

    hDevice = WdfTimerGetParentObject(Timer);
    devExt = FilterGetData(hDevice);
    WdfWorkItemEnqueue(devExt->hWorkItem);
}


NTSTATUS
DriverEntry (
    IN PDRIVER_OBJECT DriverObject,
    IN PUNICODE_STRING RegistryPath
    )
{
    WDF_DRIVER_CONFIG config;
    NTSTATUS status;


    PAGED_CODE();

    DebugPrint(("Mouse Filter Driver Sample - Driver Framework Edition.\n"));
    DebugPrint(("Built %s %s\n", __DATE__, __TIME__));
    
    WDF_DRIVER_CONFIG_INIT(
     &config,
     MouFilter_EvtDeviceAdd
    );

    status = WdfDriverCreate(DriverObject,
     RegistryPath,
     WDF_NO_OBJECT_ATTRIBUTES,
     &config,
     WDF_NO_HANDLE); // hDriver optional
    if (!NT_SUCCESS(status)) {
     DebugPrint( ("WdfDriverCreate failed with status 0x%x\n", status));
    }

    return status;
}


NTSTATUS
MouFilter_EvtDeviceAdd(
    IN WDFDRIVER Driver,
    IN PWDFDEVICE_INIT DeviceInit
    )
{
    WDF_OBJECT_ATTRIBUTES deviceAttributes;
    WDF_OBJECT_ATTRIBUTES deviceAttributes2;
    NTSTATUS status;
    WDFDEVICE hDevice = NULL;
    WDF_IO_QUEUE_CONFIG ioQueueConfig;
    WDF_OBJECT_ATTRIBUTES attributes;
    WDF_OBJECT_ATTRIBUTES workitemattributes;
    PDEVICE_EXTENSION devExt;
    WDFDEVICE cdev;
    WDF_DMA_ENABLER_CONFIG dmaConfig;
    WDFMEMORY writeBufferMemHandle;
    PVOID writeBufferPointer;
    WDFMEMORY writeBufferMemHandle2;
    PVOID writeBufferPointer2;
    WDF_DMA_ENABLER_CONFIG dmaConfig2;
    WDF_TIMER_CONFIG timerConfig;
    WDFTIMER timerHandle;
    WDF_WORKITEM_CONFIG workitemConfig;
#define BUF_SIZE 0x2000
作者 : shihchin(shihchin)
[ 貼文 58 | 人氣 3119 | 評價 0 | 評價/貼文 0 | 送出評價 0 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2012/1/30 上午 11:31:30
UNREFERENCED_PARAMETER(Driver);

    PAGED_CODE();

    DebugPrint(("Enter FilterEvtDeviceAdd \n"));

    WdfFdoInitSetFilter(DeviceInit);

    WdfDeviceInitSetDeviceType(DeviceInit, FILE_DEVICE_MOUSE);

    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&deviceAttributes,
     DEVICE_EXTENSION);
    
    status = WdfDeviceCreate(&DeviceInit, &deviceAttributes, &hDevice);
    if (!NT_SUCCESS(status)) {
     DebugPrint(("WdfDeviceCreate failed with status code 0x%x\n", status));
     return status;
    }


    WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&ioQueueConfig,
     WdfIoQueueDispatchParallel);

    ioQueueConfig.EvtIoInternalDeviceControl = MouFilter_EvtIoInternalDeviceControl;

    status = WdfIoQueueCreate(hDevice,
     &ioQueueConfig,
     WDF_NO_OBJECT_ATTRIBUTES,
     WDF_NO_HANDLE // pointer to default queue
     );
    if (!NT_SUCCESS(status)) {
     DebugPrint( ("WdfIoQueueCreate failed 0x%x\n", status));
     return status;
    }

    devExt = FilterGetData(hDevice);
    RtlZeroMemory(devExt, sizeof(DEVICE_EXTENSION));

    status = CreateControlDevice(Driver, hDevice, &cdev);
    if (!NT_SUCCESS(status)) {
     DbgPrint("failed to create control device(0x%x)", status);
     if (hDevice != NULL)
     WdfObjectDelete(hDevice);
    }

    
    devExt->filterDevice = WdfDeviceWdmGetDeviceObject(hDevice);
    devExt->controlDevice = cdev;
    WdfDeviceSetAlignmentRequirement(hDevice, FILE_OCTA_ALIGNMENT);
    WDF_DMA_ENABLER_CONFIG_INIT(&dmaConfig, WdfDmaProfileScatterGather, BUF_SIZE);
    WDF_DMA_ENABLER_CONFIG_INIT(&dmaConfig2, WdfDmaProfileScatterGather, BUF_SIZE);

    WDF_OBJECT_ATTRIBUTES_INIT(&deviceAttributes);
    deviceAttributes.ParentObject = hDevice;
    status = WdfMemoryCreate(&deviceAttributes, PagedPool, 'eumP', BUF_SIZE, &writeBufferMemHandle, &writeBufferPointer);
作者 : shihchin(shihchin)
[ 貼文 58 | 人氣 3119 | 評價 0 | 評價/貼文 0 | 送出評價 0 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2012/1/30 上午 11:34:12
if (!NT_SUCCESS(status)) {
     DbgPrint("WdfMemoryCreate failed(0x%x)", status);
     return status;
    }
    WDF_OBJECT_ATTRIBUTES_INIT(&deviceAttributes2);
    deviceAttributes2.ParentObject = hDevice;
    status = WdfMemoryCreate(&deviceAttributes2, PagedPool, 'eumP', BUF_SIZE, &writeBufferMemHandle2, &writeBufferPointer2);
    if (!NT_SUCCESS(status)) {
     DbgPrint("WdfMemoryCreate failed(0x%x)", status);
     return status;
    }

    IoInitializeRemoveLock(&devExt->rptSyncLock,'KCOL',0,0);
    ExInitializeFastMutex(&devExt->MemUserListMutex);

    WDF_OBJECT_ATTRIBUTES_INIT(&workitemattributes);

    workitemattributes.ParentObject = hDevice;

    WDF_WORKITEM_CONFIG_INIT(
     &workitemConfig,
     MyWorkItemCallback
     );

    status = WdfWorkItemCreate(
     &workitemConfig,
     &workitemattributes,
     &devExt->hWorkItem
     );
    if (!NT_SUCCESS(status)) {
     DebugPrint( ("WdfWorkItemCreate failed 0x%08X\n", status));
     return status;
    }

    devExt->CommonBufferSize = BUF_SIZE;
    status = WdfDmaEnablerCreate(hDevice, &dmaConfig, WDF_NO_OBJECT_ATTRIBUTES,&devExt->DmaEnabler);
    if (!NT_SUCCESS(status)) {
     DebugPrint( ("WdfDmaEnablerCreate2 failed 0x%08X\n", status));
     return status;
    }
    status = WdfDmaEnablerCreate(hDevice, &dmaConfig2, WDF_NO_OBJECT_ATTRIBUTES,&devExt->DmaEnabler2);
    if (!NT_SUCCESS(status)) {
     DebugPrint( ("WdfDmaEnablerCreate2 failed 0x%08X\n", status));
     return status;
    }
    status = WdfCommonBufferCreate(devExt->DmaEnabler,devExt->CommonBufferSize,WDF_NO_OBJECT_ATTRIBUTES,
     &devExt->CommonBuffer);
    if (!NT_SUCCESS(status)) {
     DebugPrint( ("WdfCommonBufferCreate failed 0x%08X\n", status));
     return status;
    }
作者 : shihchin(shihchin)
[ 貼文 58 | 人氣 3119 | 評價 0 | 評價/貼文 0 | 送出評價 0 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2012/1/30 上午 11:39:28
status = WdfCommonBufferCreate(devExt->DmaEnabler2,devExt->CommonBufferSize,
     WDF_NO_OBJECT_ATTRIBUTES,&devExt->CommonBuffer2);

    if (!NT_SUCCESS(status)) {
     DebugPrint( ("WdfCommonBufferCreate2 failed 0x%08X\n", status));
     return status;
    }

    devExt->CommonBufferBaseVA = WdfCommonBufferGetAlignedVirtualAddress(devExt->CommonBuffer);
    devExt->CommonBufferBaseLA = WdfCommonBufferGetAlignedLogicalAddress(devExt->CommonBuffer);
    RtlZeroMemory(devExt->CommonBufferBaseVA, devExt->CommonBufferSize);
    devExt->CommonBufferBaseVA2 = WdfCommonBufferGetAlignedVirtualAddress(devExt->CommonBuffer2);
    devExt->CommonBufferBaseLA2 = WdfCommonBufferGetAlignedLogicalAddress(devExt->CommonBuffer2);

    RtlZeroMemory(devExt->CommonBufferBaseVA2, devExt->CommonBufferSize);
    devExt->lockflag=0;
    devExt->BufferMdl=IoAllocateMdl(devExt->CommonBufferBaseVA, 0x2000, FALSE, FALSE, NULL);
    if(!devExt->BufferMdl) {
     DebugPrint( ("IoAllocateMdl failed 0x%08X\n",STATUS_INSUFFICIENT_RESOURCES));
    }
    MmBuildMdlForNonPagedPool(devExt->BufferMdl);
    devExt->BufferMdl2=IoAllocateMdl(devExt->CommonBufferBaseVA2,0x2000,FALSE,FALSE,NULL);
    if(!devExt->BufferMdl2) {
     DebugPrint( ("IoAllocateMdl failed 0x%08X\n", STATUS_INSUFFICIENT_RESOURCES));
    }
    MmBuildMdlForNonPagedPool(devExt->BufferMdl2);
    devExt->MDLLock=0;
    devExt->MDLLock2=0;
    devExt->tempdata=0;
    WDF_TIMER_CONFIG_INIT_PERIODIC(&timerConfig,MyEvtTimerFunc,5);
    timerConfig.AutomaticSerialization=TRUE;
    WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
    attributes.ParentObject=hDevice;
    status = WdfTimerCreate(&timerConfig,&attributes,&timerHandle);
    if (!NT_SUCCESS(status)) {
     DebugPrint(("WdfTimerCreate failed status:0x%08X\n",status));
     return status;
    }
    devExt->timerHandle = timerHandle;
    WdfTimerStart(timerHandle,WDF_REL_TIMEOUT_IN_SEC(1));
    devExt->Semaphore = NULL;
    return status;
}
作者 : shihchin(shihchin)
[ 貼文 58 | 人氣 3119 | 評價 0 | 評價/貼文 0 | 送出評價 0 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2012/1/30 上午 11:41:52

VOID
MouFilter_DispatchPassThrough(
    __in WDFREQUEST Request,
    __in WDFIOTARGET Target
    )
{
    WDF_REQUEST_SEND_OPTIONS options;
    BOOLEAN ret;
    NTSTATUS status = STATUS_SUCCESS;

    WDF_REQUEST_SEND_OPTIONS_INIT(&options,
     WDF_REQUEST_SEND_OPTION_SEND_AND_FORGET);

    ret = WdfRequestSend(Request, Target, &options);

    if (ret == FALSE) {
     status = WdfRequestGetStatus (Request);
     DebugPrint( ("WdfRequestSend failed: 0x%x\n", status));
     WdfRequestComplete(Request, status);
    }

    return;
}

VOID
MouFilter_EvtIoInternalDeviceControl(
    IN WDFQUEUE Queue,
    IN WDFREQUEST Request,
    IN size_t OutputBufferLength,
    IN size_t InputBufferLength,
    IN ULONG IoControlCode
    )
{
    PDEVICE_EXTENSION devExt;
    PCONNECT_DATA connectData;
    PINTERNAL_I8042_HOOK_MOUSE hookMouse;
    NTSTATUS status = STATUS_SUCCESS;
    WDFDEVICE hDevice;
    size_t length;

    UNREFERENCED_PARAMETER(OutputBufferLength);
    UNREFERENCED_PARAMETER(InputBufferLength);

    PAGED_CODE();

    hDevice = WdfIoQueueGetDevice(Queue);
    devExt = FilterGetData(hDevice);

    switch (IoControlCode) {
    case IOCTL_INTERNAL_MOUSE_CONNECT:
     if (devExt->UpperConnectData.ClassService != NULL) {
     status = STATUS_SHARING_VIOLATION;
     break;
     }
    
     status = WdfRequestRetrieveInputBuffer(Request,
     sizeof(CONNECT_DATA),
     &connectData,
     &length);
     if(!NT_SUCCESS(status)){
     DebugPrint(("WdfRequestRetrieveInputBuffer failed %x\n", status));
     break;
     }

     devExt->UpperConnectData = *connectData;

     connectData->ClassDeviceObject = WdfDeviceWdmGetDeviceObject(hDevice);
     connectData->ClassService = MouFilter_ServiceCallback;
     break;
作者 : shihchin(shihchin)
[ 貼文 58 | 人氣 3119 | 評價 0 | 評價/貼文 0 | 送出評價 0 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2012/1/30 上午 11:45:24
case IOCTL_INTERNAL_MOUSE_DISCONNECT:
     status = STATUS_NOT_IMPLEMENTED;
     break;

    case IOCTL_INTERNAL_I8042_HOOK_MOUSE:
     DebugPrint(("hook mouse received!\n"));
     status = WdfRequestRetrieveInputBuffer(Request,sizeof(INTERNAL_I8042_HOOK_MOUSE),
     &hookMouse,&length);
     if(!NT_SUCCESS(status)){
     DebugPrint(("WdfRequestRetrieveInputBuffer failed %x\n", status));
     break;
     }

     devExt->UpperContext = hookMouse->Context;
     hookMouse->Context = (PVOID) devExt;

     if (hookMouse->IsrRoutine) {
     devExt->UpperIsrHook = hookMouse->IsrRoutine;
     }
     hookMouse->IsrRoutine = (PI8042_MOUSE_ISR) MouFilter_IsrHook;

     devExt->IsrWritePort = hookMouse->IsrWritePort;
     devExt->CallContext = hookMouse->CallContext;
     devExt->QueueMousePacket = hookMouse->QueueMousePacket;

     status = STATUS_SUCCESS;
     break;

    case IOCTL_MOUSE_QUERY_ATTRIBUTES:
    default:
     break;
    }

    if (!NT_SUCCESS(status)) {
     WdfRequestComplete(Request, status);
     return ;
    }

    MouFilter_DispatchPassThrough(Request,WdfDeviceGetIoTarget(hDevice));
}

BOOLEAN
MouFilter_IsrHook (
    PVOID DeviceExtension,
    PMOUSE_INPUT_DATA CurrentInput,
    POUTPUT_PACKET CurrentOutput,
    UCHAR StatusByte,
    PUCHAR DataByte,
    PBOOLEAN ContinueProcessing,
    PMOUSE_STATE MouseState,
    PMOUSE_RESET_SUBSTATE ResetSubState
)
{
    PDEVICE_EXTENSION devExt;
    BOOLEAN retVal = TRUE;

    devExt = DeviceExtension;
    
    if (devExt->UpperIsrHook) {
     retVal = (*devExt->UpperIsrHook) (devExt->UpperContext,CurrentInput,CurrentOutput,StatusByte,
     DataByte,ContinueProcessing,MouseState,ResetSubState);

     if (!retVal || !(*ContinueProcessing)) {
     return retVal;
     }
    }

    *ContinueProcessing = TRUE;
    return retVal;
}
作者 : shihchin(shihchin)
[ 貼文 58 | 人氣 3119 | 評價 0 | 評價/貼文 0 | 送出評價 0 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2012/1/30 上午 11:47:48
VOID
MouFilter_ServiceCallback(
    IN PDEVICE_OBJECT DeviceObject,
    IN PMOUSE_INPUT_DATA InputDataStart,
    IN PMOUSE_INPUT_DATA InputDataEnd,
    IN OUT PULONG InputDataConsumed
    )
{
    PDEVICE_EXTENSION devExt;
    WDFDEVICE hDevice;

    hDevice = WdfWdmDeviceGetWdfDeviceHandle(DeviceObject);

    devExt = FilterGetData(hDevice);
    (*(PSERVICE_CALLBACK_ROUTINE) devExt->UpperConnectData.ClassService)(
     devExt->UpperConnectData.ClassDeviceObject,
     InputDataStart,
     InputDataEnd,
     InputDataConsumed
     );
}

void
FspadIoctl(IN WDFQUEUE q, IN WDFREQUEST req, IN size_t oLen, IN size_t iLen,
    IN ULONG ioCode)
{
    PDEVICE_EXTENSION devExt;
    WDFDEVICE dev;
    NTSTATUS status;
    PVOID buffer;
    size_t bufSize;
    BYTE temp;
    HANDLE SemaphoreHandle;
    KPROCESSOR_MODE PreviousMode;

    UNREFERENCED_PARAMETER(oLen);
    UNREFERENCED_PARAMETER(iLen);

    dev = WdfIoQueueGetDevice(q);

    if (dev != CtrlDevGetExt(dev)->fdev) {
     dev = CtrlDevGetExt(dev)->fdev;
    }
    devExt = FilterGetData(dev);

    status = IoAcquireRemoveLock(&(devExt->rptSyncLock),
     (void *)RPT_SYNC_LK_TAG);
    if (!NT_SUCCESS(status)) {
     DbgPrint("failed to acquire removal lock: 0x%x", status);
     WdfRequestComplete(req, status);
     return;
    }

    switch (ioCode)
    {
    case IOCTL_OSR_SETSHAREMEM:
     DbgPrint("IOCTL_OSR_SETSHAREMEM\n");
     RtlCopyMemory(devExt->CommonBufferBaseVA2,devExt->CommonBufferBaseVA,0x2000);
     temp=((BYTE *)devExt->CommonBufferBaseVA2)[0];
     WdfRequestCompleteWithInformation(req, STATUS_SUCCESS, temp);
     break;
作者 : shihchin(shihchin)
[ 貼文 58 | 人氣 3119 | 評價 0 | 評價/貼文 0 | 送出評價 0 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2012/1/30 上午 11:48:51
case IOCTL_OSR_GETMEM:
     DbgPrint("IOCTL_OSR_GETMEM\n");
     if (devExt->MDLLock==0)
     {
     MmProbeAndLockPages(devExt->BufferMdl, KernelMode, (LOCK_OPERATION)(IoWriteAccess | IoReadAccess | IoModifyAccess));
     devExt->UserModeVirtualAddess = MmMapLockedPagesSpecifyCache(devExt->BufferMdl, UserMode, MmCached, NULL, FALSE, NormalPagePriority);
     if(!devExt->UserModeVirtualAddess)
     {
     MmFreePagesFromMdl(devExt->BufferMdl);
     IoFreeMdl(devExt->BufferMdl);
     DebugPrint( ("MmMapLockedPagesSpecifyCache failed 0x%08X\n", STATUS_INSUFFICIENT_RESOURCES));
     WdfRequestComplete(req, STATUS_NOT_IMPLEMENTED);
     break;
     }
     devExt->MDLLock=1;
     }
     status = WdfRequestRetrieveOutputBuffer(req,2,(PVOID *)&buffer,&bufSize);
     if (!NT_SUCCESS(status))
     {
     DbgPrint("failed to get memory address: 0x%x\n", status);
     }
     memcpy(buffer,&devExt->UserModeVirtualAddess,sizeof(PVOID));
     WdfRequestCompleteWithInformation(req, STATUS_SUCCESS, sizeof(PVOID));
     break;
    case IOCTL_OSR_GETMEM2:
     DbgPrint("IOCTL_OSR_GETMEM2\n");
     if (devExt->MDLLock2==0)
     {
     MmProbeAndLockPages(devExt->BufferMdl2, KernelMode, (LOCK_OPERATION)(IoWriteAccess | IoReadAccess | IoModifyAccess));
     devExt->UserModeVirtualAddess2 = MmMapLockedPagesSpecifyCache(devExt->BufferMdl2, UserMode, MmCached, NULL, FALSE, NormalPagePriority);
     if(!devExt->UserModeVirtualAddess2)
     {
     MmFreePagesFromMdl(devExt->BufferMdl2);
     IoFreeMdl(devExt->BufferMdl2);
     DebugPrint( ("MmMapLockedPagesSpecifyCache failed 0x%08X\n", STATUS_INSUFFICIENT_RESOURCES));
     WdfRequestComplete(req, STATUS_NOT_IMPLEMENTED);
     break;
     }
     devExt->MDLLock2=1;
     }
作者 : shihchin(shihchin)
[ 貼文 58 | 人氣 3119 | 評價 0 | 評價/貼文 0 | 送出評價 0 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2012/1/30 上午 11:51:09
status = WdfRequestRetrieveOutputBuffer(req,2,(PVOID *)&buffer,&bufSize);
     if (!NT_SUCCESS(status))
     {
     DbgPrint("failed to get memory address2: 0x%x\n", status);
     }
     memcpy(buffer,&devExt->UserModeVirtualAddess2,sizeof(PVOID));
     WdfRequestCompleteWithInformation(req, STATUS_SUCCESS, sizeof(PVOID));
     break;
    case IOCTL_OSR_CLOSE:
     DbgPrint("IOCTL_OSR_CLOSE\n");
     if (devExt->MDLLock==1)
     {
     MmUnmapLockedPages(devExt->UserModeVirtualAddess,devExt->BufferMdl);
     devExt->MDLLock=0;
     }
     if (devExt->MDLLock2==1)
     {
     MmUnmapLockedPages(devExt->UserModeVirtualAddess2,devExt->BufferMdl2);
     devExt->MDLLock2=0;
     }
     WdfRequestCompleteWithInformation(req, STATUS_SUCCESS, STATUS_SUCCESS);
     break;
    case IOCTL_OSR_SETSEMAPHOREHANDLE:
     DbgPrint("IOCTL_OSR_SETSEMAPHOREHANDLE\n");
     SemaphoreHandle=NULL;
     status = WdfRequestRetrieveInputBuffer(req,sizeof(HANDLE),(PVOID *)&buffer,NULL);
     if (!NT_SUCCESS(status))
     {
     DbgPrint("WdfRequestRetrieveInputBuffer fail!\n");
     WdfRequestCompleteWithInformation(req, STATUS_SUCCESS, 0);
     }
     else
     {
     SemaphoreHandle = (HANDLE *)(*(int *)buffer);
     if (devExt->Semaphore==NULL)
     {
     PreviousMode = ExGetPreviousMode();
     status=ObReferenceObjectByHandle(SemaphoreHandle,
     SYNCHRONIZE | SEMAPHORE_ALL_ACCESS | SEMAPHORE_QUERY_STATE,
     *ExSemaphoreObjectType,PreviousMode,(PVOID*)&devExt->Semaphore,NULL);
     if (!NT_SUCCESS(status))
     {
     DbgPrint("ObReferenceObjectByHandle fail: 0x%x\n", status);
     }
     }
     WdfRequestCompleteWithInformation(req, STATUS_SUCCESS, STATUS_SUCCESS);
     }
     break;
作者 : shihchin(shihchin)
[ 貼文 58 | 人氣 3119 | 評價 0 | 評價/貼文 0 | 送出評價 0 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2012/1/30 上午 11:52:45
default:
     WdfRequestComplete(req, STATUS_NOT_IMPLEMENTED);
     break;
    }

    IoReleaseRemoveLock(&(devExt->rptSyncLock), (void *)RPT_SYNC_LK_TAG);
}

#pragma warning(pop)


moufiltr.h

#ifndef MOUFILTER_H
#define MOUFILTER_H
#include "IOCTL.h"

#if DBG

#define TRAP() DbgBreakPoint()

#define DebugPrint(_x_) DbgPrint _x_

#else // DBG

#define TRAP()

#define DebugPrint(_x_)

#endif

#define FSPAD_NT_NAME L"\\Device\\OsrMemDrv" //L"\\Device\\8042PADMICE"
#define FSPAD_SYMBOL_NAME L"\\??\\OsrMemDrv" //L"\\DosDevices\\PADMICE"


typedef struct _MEM_USER_ENTRY
{
    LIST_ENTRY ListEntry;
    PFILE_OBJECT FileObject; // File Object of queuer
    PVOID UserVaToReturn; // Mapped VA for the process
    PMDL PMdl; // MDL used to map memory
    PIRP Irp; // If a hanging IRP was used.

} MEM_USER_ENTRY, *PMEM_USER_ENTRY;


 
typedef struct _DEVICE_EXTENSION
{
    WDFDEVICE controlDevice;

    PDEVICE_OBJECT filterDevice;

    PVOID UpperContext;
    
    PI8042_MOUSE_ISR UpperIsrHook;

    IN PI8042_ISR_WRITE_PORT IsrWritePort;

    IN PVOID CallContext;

    IN PI8042_QUEUE_PACKET QueueMousePacket;

    CONNECT_DATA UpperConnectData;

    IO_REMOVE_LOCK rptSyncLock;

#define RPT_SYNC_LK_TAG (0x5250544c)
size_t CommonBufferSize;
WDFDMAENABLER DmaEnabler;
WDFCOMMONBUFFER CommonBuffer;
PVOID CommonBufferBaseVA;
PHYSICAL_ADDRESS CommonBufferBaseLA;
FAST_MUTEX MemUserListMutex;
PVOID UserModeVirtualAddess;
PMDL BufferMdl;
WDFDMAENABLER DmaEnabler2;
WDFCOMMONBUFFER CommonBuffer2;
PVOID CommonBufferBaseVA2;
PHYSICAL_ADDRESS CommonBufferBaseLA2;
PVOID UserModeVirtualAddess2;
PMDL BufferMdl2;
ULONG MDLLock,MDLLock2;
WDFTIMER timerHandle;
WDFWORKITEM hWorkItem;
ULONG lockflag;
PKSEMAPHORE Semaphore;
BYTE tempdata;
 
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
作者 : shihchin(shihchin)
[ 貼文 58 | 人氣 3119 | 評價 0 | 評價/貼文 0 | 送出評價 0 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2012/1/30 上午 11:53:30

WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(DEVICE_EXTENSION,
     FilterGetData)


typedef struct _CTRL_DEVICE_EXTENSION {
WDFDEVICE fdev;
WDFQUEUE q;
} CTRL_DEV_EXT, *PCTRL_DEV_EXT;

typedef struct _WORKITEM_CONTEXT {
WDFDEVICE Device;
LONG Diff;
BOOLEAN bStatUpdate;
} WORKITEM_CONTEXT, *PWORKITEM_CONTEXT;

WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(CTRL_DEV_EXT, CtrlDevGetExt)

DRIVER_INITIALIZE DriverEntry;

EVT_WDF_DRIVER_DEVICE_ADD MouFilter_EvtDeviceAdd;
EVT_WDF_IO_QUEUE_IO_INTERNAL_DEVICE_CONTROL MouFilter_EvtIoInternalDeviceControl;
EVT_WDF_IO_QUEUE_IO_DEVICE_CONTROL FspadIoctl;
EVT_WDF_TIMER MyEvtTimerFunc;

VOID
MouFilter_DispatchPassThrough(
     __in WDFREQUEST Request,
    __in WDFIOTARGET Target
    );

BOOLEAN
MouFilter_IsrHook (
    PVOID DeviceExtension,
    PMOUSE_INPUT_DATA CurrentInput,
    POUTPUT_PACKET CurrentOutput,
    UCHAR StatusByte,
    PUCHAR DataByte,
    PBOOLEAN ContinueProcessing,
    PMOUSE_STATE MouseState,
    PMOUSE_RESET_SUBSTATE ResetSubState
);

VOID
MouFilter_ServiceCallback(
    IN PDEVICE_OBJECT DeviceObject,
    IN PMOUSE_INPUT_DATA InputDataStart,
    IN PMOUSE_INPUT_DATA InputDataEnd,
    IN OUT PULONG InputDataConsumed
    );

#endif // MOUFILTER_H
作者 : shihchin(shihchin)
[ 貼文 58 | 人氣 3119 | 評價 0 | 評價/貼文 0 | 送出評價 0 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2012/1/30 上午 11:54:18
ioctl.h


#ifndef __NOTHING_IOCTL_H__
#define __NOTHING_IOCTL_H__ (1)


#define FILE_DEVICE_OSRMEMDRV 0xCF53


#define OSR_MEMORY_SIZE 4096*2


#define IOCTL_OSR_SETSHAREMEM CTL_CODE(FILE_DEVICE_OSRMEMDRV, 2049, METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
#define IOCTL_OSR_GETMEM CTL_CODE(FILE_DEVICE_OSRMEMDRV, 2050, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_OSR_GETMEM2 CTL_CODE(FILE_DEVICE_OSRMEMDRV, 2051, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_OSR_CLOSE CTL_CODE(FILE_DEVICE_OSRMEMDRV, 2052, METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
#define IOCTL_OSR_SETSEMAPHOREHANDLE CTL_CODE(FILE_DEVICE_OSRMEMDRV, 2053, METHOD_BUFFERED, FILE_ANY_ACCESS)


typedef struct _USER_MEMORY_ADDRESS
{
    PVOID UserMemoryAddress;
} USER_MEMORY_ADDRESS,*PUSER_MEMORY_ADDRESS;

#endif /* __NOTHING_IOCTL_H__ */

作者 : doraemon(人稱阿牛)
[ 貼文 74 | 人氣 5056 | 評價 220 | 評價/貼文 2.97 | 送出評價 3 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2012/1/31 上午 12:47:36
老實說程式太長而且排版混亂沒有看

但好奇你這麼做的用途是什麼?

一般來說把kernel mode的記憶體export給user mode存取不是該考慮的設計方式

應該使用os提供的ReadFile & WriteFile來做會比較洽當
作者 : josjos(布魯托)
[ 貼文 4 | 人氣 0 | 評價 40 | 評價/貼文 10 | 送出評價 0 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2012/2/3 下午 12:31:46
不了解 WDF,不過在應該跟 WDM 一樣可以用 DeviceIoControl 的方式傳送資料。在 AP 中 CreateFile 時使用 exclusive 的方式存取即可同步了(尤其是你的 semaphore 是設1之下),這樣不是比較簡單嗎?

 板主 : 徵求中
 > 驅動程式 - 討論區
 - 最近熱門問答精華集
 - 全部歷史問答精華集
 - 驅動程式 - 知識庫
  ■ 全站最新Post列表
  ■ 我的文章收藏
  ■ 我最愛的作者
  ■ 全站文章收藏排行榜
  ■ 全站最愛作者排行榜
  ■  月熱門主題
  ■  季熱門主題
  ■  熱門主題Top 20
  ■  本區Post排行榜
  ■  本區評價排行榜
  ■  全站專家名人榜
  ■  全站Post排行榜
  ■  全站評價排行榜
  ■  全站人氣排行榜
 請輸入關鍵字 
  開始搜尋
 
Top 10
評價排行
驅動程式
1 新兵衛 1240 
2 eBoy 980 
3 牧童哥 780 
4 北極熊 580 
5 天行者 580 
6 燒酒仙 440 
7 weber 380 
8 KEN 350 
9 jonay 180 
10 掌握文武半邊天 180 
驅動程式
  專家等級 評價  
  一代宗師 10000  
  曠世奇才 5000  
  頂尖高手 3000  
  卓越專家 1500  
  優秀好手 750  
Microsoft Internet Explorer 6.0. Screen 1024x768 pixel. High Color (16 bit).
2000-2019 程式設計俱樂部 http://www.programmer-club.com.tw/
0.078125