Всем привет! Простой вопрос: почему в драйвере длина выходного буфера всегда 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);
Соответственно, если я что-нибудь из драйвера запишу по pIrp->AssociatedIrp.SystemBuffer = 0x12345678 то в UserMode по g_pSharedMemory все равно будет ноль.
Код (Text): DeviceIoControl(g_hDriver, IOCTL_HDRIVER_SHARE, NULL, 0, [b]&[/b]g_pSharedMemory, sizeof(PVOID), &nbytes, NULL);
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): case IOCTL_HDRIVER_SHARE: { __try { DPRINT("InputLength=%d\n", InputLength); DPRINT("OutputLength=%d\n", OutputLength); g_pSharedMemory = ExAllocatePool(NonPagedPool, PAGE_SIZE); DPRINT("SharingMemory: %X bytes of nonpaged memory allocated at address %08X\n", PAGE_SIZE, g_pSharedMemory); g_pMdl = IoAllocateMdl(g_pSharedMemory, PAGE_SIZE, FALSE, FALSE, NULL); if(g_pMdl != NULL) { DPRINT("SharingMemory: MDL allocated at address %08X\n", g_pMdl); MmBuildMdlForNonPagedPool(g_pMdl); g_pUserAddress = MmMapLockedPagesSpecifyCache( g_pMdl, UserMode, MmCached, NULL, FALSE, NormalPagePriority); DPRINT("SharingMemory: Memory mapped into user space at address %08X\n", g_pUserAddress); } } __except(EXCEPTION_EXECUTE_HANDLER) { } pIrp->AssociatedIrp.SystemBuffer = g_pUserAddress; DPRINT("g_pUserAddress=%p\n", g_pUserAddress); st = STATUS_SUCCESS; pIrp->IoStatus.Information = sizeof(PVOID); break; } По шагам прошел по коду в Soft-Ice, все выделяется благополучно, далее отрабатывает IofCompleteRequest и возвращается управление.
Попробуй METHOD_NEITHER, ИМХО METHOD_BUFFERED просто динамически выделяет память размером sizeof(PVOID), возвращает туда данные, а затем копирует их а реальный буфер, когда ирп завершается. Кстати, а g_pSharedMemory - это память 3-го кольца?
<font color="red] Код (Text): pIrp->AssociatedIrp.SystemBuffer = g_pUserAddress; </font><!--color-->Эта строка просто затирает адрес системного буфера, а должна поместить в этот буфер содержимое переменной g_pUserAddress. Должно быть как-то так: Код (Text): * ( (PVOID*) pIrp->AssociatedIrp.SystemBuffer ) = g_pUserAddress; ЗЫ: В __except неплохо бы порелизить всё назад, а то утечка будет. Оборачивать в SEH имеет смысл только MmMapLockedPagesSpecifyCache.
serious g_pSharedMemory ет память нулевого кольца, доступная из третьего, для чтения и для записи. Four-F Точно! Проморгал, спасибо!