Вопросик по DeviceIoControl из R3-> R0

Тема в разделе "WASM.NT.KERNEL", создана пользователем test555, 25 ноя 2008.

  1. test555

    test555 New Member

    Публикаций:
    0
    Регистрация:
    7 дек 2007
    Сообщения:
    241
    Руководствуясь статьей
    http://www.wasm.ru/article.php?article=drvw2k14
    и примером из WDK \general\event)
    Я начал писать синхронизацию драйвера и юзермода.

    1. В юзермод делаю так:

    Код (Text):
    1. var hEvent, hDriver:DWORD;
    2.  
    3. begin
    4.  hDriver := CreateFile('\\.\MyDev1', GENERIC_READ or GENERIC_WRITE, 0, nil, OPEN_EXISTING, 0, 0);
    5. if hDriver<>INVALID_HANDLE_VALUE then begin
    6.  
    7.  hEvent:= CreateEvent( nil, FALSE, FALSE, nil);
    8.  
    9.  Memo1.Lines.Add('h_Event = '+inttostr(hEvent));
    10.  DeviceIoControl(hDriver,
    11.                   IOCTL_SET_NOTIFY,
    12.                   @hEvent,
    13.                   sizeof(hEvent),
    14.                   nil,
    15.                   0,
    16.                   returned,
    17.                   nil
    18.                   );
    Далее в драйвере у меня обработчик
    Код (Text):
    1. DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DriverDispatcher;
    Начало этого обработчика
    Код (Text):
    1. NTSTATUS DriverDispatcher(
    2.     IN PDEVICE_OBJECT DeviceObject,
    3.     IN PIRP Irp)
    4. {
    5.     PIO_STACK_LOCATION irpStack;
    6.     ULONG ioControlCode;
    7.     NTSTATUS            status ;
    8.     LARGE_INTEGER       liDelayTime;
    9.     HANDLE               h_Event;
    10.    
    11.    
    12.     irpStack = IoGetCurrentIrpStackLocation (Irp);
    13.    
    14.     ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;
    15.         switch( irpStack->Parameters.DeviceIoControl.IoControlCode )
    16.     {
    17.             case IOCTL_SET_NOTIFY:
    18.                 DPRINT("IOCTL_SET_NOTIFY");
    19.                 if (irpStack->Parameters.DeviceIoControl.InputBufferLength >= sizeof(HANDLE))
    20.                 { // СИГНАЛ НА УВЕДОМЛЕНИЕ
    21.                     if (g_fbNotifyRoutineSet == FALSE)
    22.                     {DPRINT("TRY TO --->>> _SET_NOTIFY");
    23.                    
    24.                     h_Event = (HANDLE)Irp->AssociatedIrp.SystemBuffer;
    25.                    
    26.                     DPRINT("h_Event = %ld (%X)", h_Event, h_Event);
    27.  
    28.                     status = ObReferenceObjectByHandle(h_Event,
    29.                                        EVENT_MODIFY_STATE,
    30.                                        *ExEventObjectType,
    31.                                        UserMode,
    32.                                        &g_pkEventObject,
    33.                                        NULL
    34.                                        );
    35.                     DPRINT("status = %X", status);
    36.                    
    37.                     }
    Все хорошо, дебугпринт выводит что до этого куска кода мы дошли.
    Получаю что хендл в юзермоде создается, а тут мне выводится значение:
    h_event = -1982210680 (89D9DD88)
    Ну и соответсвтенно ObReferenceObjectByHandle мне дает ошибку С0000008, что означает что отсуствует хендл. Все логично. Но что я сделал ни так?

    Вот кусок кода из статьи
    ДРАВЙЕР:
    Код (Text):
    1.                  mov edx, [esi].AssociatedIrp.SystemBuffer
    2.                  mov edx, [edx]
    3.  
    4.                  mov ecx, ExEventObjectType
    5.                  mov ecx, [ecx]
    6.                  mov ecx, [ecx]
    7.  
    8.                  invoke ObReferenceObjectByHandle, edx, EVENT_MODIFY_STATE, ecx, \
    9.                                          UserMode, addr g_pkEventObject, NULL
    Тамошний Юзермод:

    Код (Text):
    1.                  invoke CreateFile, $CTA0("\\\\.\\ProcessMon"), \
    2.                          GENERIC_READ + GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL
    3.  
    4.                  .if eax != INVALID_HANDLE_VALUE
    5.                      mov g_hDevice, eax
    6.  
    7.                      invoke DeleteService, g_hService
    8.  
    9.                      invoke CreateEvent, NULL, FALSE, FALSE, NULL
    10.                      mov g_hEvent, eax
    11.  
    12.                      and g_fbExitNow, FALSE
    13.  
    14.                      push eax
    15.                        invoke CreateThread, NULL, 0, offset WaitForProcessData, g_hEvent, 0, esp
    16.                      pop ecx
    17.                      .if eax != NULL
    18.                      
    19.                          invoke CloseHandle, eax                            
    20.  
    21.                          ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    22.  
    23.                          invoke DeviceIoControl, g_hDevice, IOCTL_SET_NOTIFY, \
    24.                                  addr g_hEvent, sizeof g_hEvent, NULL, 0, addr dwBytesReturned, NULL
    25.  
    26.                          .if eax != 0
    27. ....
    Вот. Вроде у меня аналогично переписано в С
    Только в драйвентри у меня deviceObject->Flags |= DO_BUFFERED_IO;
    Чтобы можно было общаться через WriteFile/ReadFile
    Однако если закомментировать, то тоже самое получается..

    Вот меня эти строки смущают, что у меня в коде они не так работают..
    Код (Text):
    1.                  mov edx, [esi].AssociatedIrp.SystemBuffer
    2.                  mov edx, [edx]
    3.  
    4.                  mov ecx, ExEventObjectType
    5.                  mov ecx, [ecx]
    6.                  mov ecx, [ecx]
    Первые 2 строки значат (в АСМЕ не оч. хорошо понимаю, могу ошибаться)
    1. Записываем значение в регистр едх,
    2. а потом в него же записывается значение по тому адресу?

    Вот в другом примере выглядит так:
    Код (Text):
    1.    registerEvent = (PREGISTER_EVENT)Irp->AssociatedIrp.SystemBuffer;
    2. ..
    3.  
    4.     status = ObReferenceObjectByHandle(registerEvent->hEvent,
    5.                                        SYNCHRONIZE,
    6.                                        *ExEventObjectType,
    7.                                        Irp->RequestorMode,
    8.                                        &notifyRecord->Event,
    9.                                        NULL
    10.                                        );
    11. ..
    12. typedef struct _REGISTER_EVENT
    13. {
    14.     NOTIFY_TYPE Type;
    15.     HANDLE  hEvent;
    16.     LARGE_INTEGER DueTime; // requested DueTime in 100-nanosecond units
    17.  
    18. } REGISTER_EVENT , *PREGISTER_EVENT ;
    Запутался я с указателями, значениями на указатели и тд..
    Помогите пожалуйста разобраться..
    Я уже по всякому перепробовал...


    Спасибо.
     
  2. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    SystemBuffer - указатель на буфер в котором лежит хендл. Д.б. так:
    Код (Text):
    1. h_Event = *(HANDLE*)Irp->AssociatedIrp.SystemBuffer;
    PS: Остальное не смотрел.
     
  3. test555

    test555 New Member

    Публикаций:
    0
    Регистрация:
    7 дек 2007
    Сообщения:
    241
    Four-F, я Ваш поклонник!!!