OutputBufferLength в драйвере всегда 0

Тема в разделе "WASM.WIN32", создана пользователем Iceberg, 6 дек 2005.

  1. Iceberg

    Iceberg New Member

    Публикаций:
    0
    Регистрация:
    5 дек 2005
    Сообщения:
    54
    Адрес:
    Санкт-Петербург
    Всем привет! Простой вопрос: почему в драйвере длина выходного буфера всегда 0, т.е. pIrpStack->Parameters.DeviceIoControl.OutputBufferLength всегда равен нулю? Используется следующий CTL CODE:



    #define IOCTL_HDRIVER_SHARE \

    CTL_CODE(FILE_DEVICE_UNKNOWN, 0x807, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)



    из приложения запрос посылается так:



    DeviceIoControl(g_hDriver, IOCTL_HDRIVER_SHARE, NULL, 0, g_pSharedMemory, sizeof(PVOID), &nbytes, NULL);



    а описатель открывается так:



    g_hDriver = CreateFile("\\\\.\\HDetect", GENERIC_WRITE | GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
     
  2. Iceberg

    Iceberg New Member

    Публикаций:
    0
    Регистрация:
    5 дек 2005
    Сообщения:
    54
    Адрес:
    Санкт-Петербург
    Соответственно, если я что-нибудь из драйвера запишу по pIrp->AssociatedIrp.SystemBuffer = 0x12345678

    то в UserMode по g_pSharedMemory все равно будет ноль.
     
  3. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    Код (Text):
    1. DeviceIoControl(g_hDriver, IOCTL_HDRIVER_SHARE, NULL, 0, [b]&[/b]g_pSharedMemory, sizeof(PVOID), &nbytes, NULL);
     
  4. Iceberg

    Iceberg New Member

    Публикаций:
    0
    Регистрация:
    5 дек 2005
    Сообщения:
    54
    Адрес:
    Санкт-Петербург
    Four-F

    Ага, пробовал и так. В этом случае ловлю BSOD с кодом 0xc2 (BAD_POOL_CALLER). Смотрим расшифровку:

    starting address: 0x870000 - тот самый, который должно было получить приложение в g_pSharedMemory.

    start of system address space: 0x80000000.

    и описание: Attempt to free usermode address to kernel pool. Правда мне не понятно к чему это.

    Вот код из драйвера (Four-F, часть 9, кстати :):


    Код (Text):
    1.  
    2. case IOCTL_HDRIVER_SHARE:
    3. {
    4.     __try
    5.     {
    6.         DPRINT("InputLength=%d\n", InputLength);
    7.         DPRINT("OutputLength=%d\n", OutputLength);
    8.  
    9.         g_pSharedMemory = ExAllocatePool(NonPagedPool, PAGE_SIZE);
    10.  
    11.         DPRINT("SharingMemory: %X bytes of nonpaged memory allocated at address %08X\n",
    12.                                                                 PAGE_SIZE, g_pSharedMemory);
    13.  
    14.         g_pMdl = IoAllocateMdl(g_pSharedMemory, PAGE_SIZE, FALSE, FALSE, NULL);
    15.  
    16.         if(g_pMdl != NULL)
    17.         {
    18.             DPRINT("SharingMemory: MDL allocated at address %08X\n", g_pMdl);
    19.        
    20.             MmBuildMdlForNonPagedPool(g_pMdl);
    21.  
    22.             g_pUserAddress = MmMapLockedPagesSpecifyCache(
    23.                                     g_pMdl, UserMode, MmCached,
    24.                                     NULL, FALSE, NormalPagePriority);
    25.  
    26.             DPRINT("SharingMemory: Memory mapped into user space at address %08X\n",
    27.                                                                             g_pUserAddress);
    28.         }
    29.     }
    30.  
    31.     __except(EXCEPTION_EXECUTE_HANDLER)
    32.     {
    33.     }
    34.  
    35.     pIrp->AssociatedIrp.SystemBuffer = g_pUserAddress;
    36.  
    37.     DPRINT("g_pUserAddress=%p\n", g_pUserAddress);
    38.                
    39.     st = STATUS_SUCCESS;
    40.     pIrp->IoStatus.Information = sizeof(PVOID);
    41.  
    42.     break;
    43. }
    По шагам прошел по коду в Soft-Ice, все выделяется благополучно, далее отрабатывает IofCompleteRequest и возвращается управление.
     
  5. serious

    serious New Member

    Публикаций:
    0
    Регистрация:
    23 май 2005
    Сообщения:
    33
    Адрес:
    Russia
    Попробуй METHOD_NEITHER, ИМХО METHOD_BUFFERED просто динамически выделяет память размером sizeof(PVOID), возвращает туда данные, а затем копирует их а реальный буфер, когда ирп завершается. Кстати, а g_pSharedMemory - это память 3-го кольца?
     
  6. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    <font color="red]
    Код (Text):
    1. pIrp->AssociatedIrp.SystemBuffer = g_pUserAddress;
    </font><!--color-->Эта строка просто затирает адрес системного буфера, а должна поместить в этот буфер содержимое переменной g_pUserAddress. Должно быть как-то так:
    Код (Text):
    1. * ( (PVOID*) pIrp->AssociatedIrp.SystemBuffer ) = g_pUserAddress;
    ЗЫ: В __except неплохо бы порелизить всё назад, а то утечка будет. Оборачивать в SEH имеет смысл только MmMapLockedPagesSpecifyCache.
     
  7. Iceberg

    Iceberg New Member

    Публикаций:
    0
    Регистрация:
    5 дек 2005
    Сообщения:
    54
    Адрес:
    Санкт-Петербург
    serious

    g_pSharedMemory ет память нулевого кольца, доступная из третьего, для чтения и для записи.



    Four-F

    Точно! Проморгал, спасибо!