NtDeviceIoControlFile : в IoStatusBlock.Information мусор
От: smbdnew  
Дата: 16.08.18 17:38
Оценка:
Вообщем то хукаю запросы в ядре к \device\afd (не спрашивайте зачем D).
Что то типа
    if (IoControlCode == 0x12017 /*recv*/) {
        st = Original_NtDeviceIoControlFile(
            FileHandle, Event, ApcRoutine, ApcContext, IoStatusBlock, IoControlCode,
            InputBuffer, InputBufferLength, OutputBuffer, OutputBufferLength
        );

        if (st == STATUS_PENDING && Event != NULL) {
            ZwWaitForSingleObject(Event, FALSE, NULL);
            st = IoStatusBlock->Status;
        }

        if (NT_SUCCESS(st)) {
            Trace("%p", IoStatusBlock->Information);
        }
    }


Собственно, в IoStatusBlock->Information мусор. Однако, в юзер приложении (сразу же после вызова) всё нормально, количество принятых байт. Что я делаю не так ?
[UPD] Re: NtDeviceIoControlFile : в IoStatusBlock.Informatio
От: ononim  
Дата: 16.08.18 19:22
Оценка:
S> if (st == STATUS_PENDING && Event != NULL) {
S> ZwWaitForSingleObject(Event, FALSE, NULL);
S> st = IoStatusBlock->Status;
S> }
А шо делать будем если st == STATUS_PENDING && Event == NULL ? А это может быть — completion ports, apc..

Кстати то, что вы вытворяете с event'ом, который передал вам юзер — тоже печалька. Ведь он может быть autoreset, и вы завесите приложение, поломав ему логику. Либо этот autoreset event может ожидать юзер в соседнем потоке. В результате он его дождется, а вы — нет. Результат — зависон.

Совет: ZwQueryInformationFile(...FileModeInformation..) и если там не фигурирует FILE_SYNCHRONOUS_IO_NONALERT|FILE_SYNCHRONOUS_IO_ALERT, то создаете свой event, суете его вместо юзерского.
Если функа вернула STATUS_PENDING — ждете свой ивент, когда дожидаете — сигналите юзерский ивент, если он не нулл. При этом вот этого вот тоже делать не стоит: st = IoStatusBlock->Status;
Если функа вернула чтото другое, и юзерский ивент не NULL: _проверяете_ свой ивент ожиданием с нулевым таймаутом, если он просигнален — сигнальте паровозиком юзерский ивент.

[UPD]
Я тут еще подумал, и пришел к выводу что стабильно рабочего решения для сценария с IOCP у вас таким путем не получится Потому что параллельно работающий юзерский поток может получить через GetQueuedCompletionStatus уведомление о завершении _до_ того как раздуплится ваш код, ждущий на event'е. Получив его, он в свою очередь может уничтожить/резюзать текущую IoStatusBlock.
Я уж не говорю о таких "мелочах", как факт того что вы эффективно превращаете асинхронный вызов в синхронный, что поломает логику приложения которает даже юзает простые event'ы, а не IOCP, но которое делает wait на несколько событий (а вы — нет).
Как много веселых ребят, и все делают велосипед...
Отредактировано 17.08.2018 11:30 ononim . Предыдущая версия . Еще …
Отредактировано 17.08.2018 10:36 ononim . Предыдущая версия .
Отредактировано 17.08.2018 10:32 ononim . Предыдущая версия .
Отредактировано 17.08.2018 10:32 ononim . Предыдущая версия .
Отредактировано 16.08.2018 19:44 ononim . Предыдущая версия .
Отредактировано 16.08.2018 19:39 ononim . Предыдущая версия .
Отредактировано 16.08.2018 19:37 ononim . Предыдущая версия .
Отредактировано 16.08.2018 19:31 ononim . Предыдущая версия .
Re: NtDeviceIoControlFile : в IoStatusBlock.Information мусор
От: mike_rs Россия  
Дата: 17.08.18 07:01
Оценка:
Здравствуйте, smbdnew, Вы писали:

S>Собственно, в IoStatusBlock->Information мусор.

ок, а статус какой в этом случае? NT_SUCCESS — это слишком расплывчато.
Re[2]: NtDeviceIoControlFile : в IoStatusBlock.Information мусор
От: smbdnew  
Дата: 18.08.18 02:56
Оценка:
Здравствуйте, mike_rs, Вы писали:

_>Здравствуйте, smbdnew, Вы писали:


S>>Собственно, в IoStatusBlock->Information мусор.

_>ок, а статус какой в этом случае? NT_SUCCESS — это слишком расплывчато.

статус всегда STATUS_SUCCESS, по этой же причине я не заморачивался с евентом.
Re[3]: NtDeviceIoControlFile : в IoStatusBlock.Information мусор
От: mike_rs Россия  
Дата: 20.08.18 13:41
Оценка:
Здравствуйте, smbdnew, Вы писали:

S>Здравствуйте, mike_rs, Вы писали:


_>>Здравствуйте, smbdnew, Вы писали:


S>>>Собственно, в IoStatusBlock->Information мусор.

_>>ок, а статус какой в этом случае? NT_SUCCESS — это слишком расплывчато.

S>статус всегда STATUS_SUCCESS, по этой же причине я не заморачивался с евентом.


исходя из этого кода
if (NT_SUCCESS(st)) {
Trace("%p", IoStatusBlock->Information);
}
это неочевидно.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.