Информация об изменениях

Сообщение [UPD] Re: NtDeviceIoControlFile : в IoStatusBlock.Informatio от 16.08.2018 19:22

Изменено 17.08.2018 10:32 ononim

Re: NtDeviceIoControlFile : в IoStatusBlock.Information мусо
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] Re: NtDeviceIoControlFile : в IoStatusBlock.Informatio
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: _проверяете_ свой ивент ожиданием с нулевым таймаутом, если он просигнален — сигнальте паровозиком юзерский ивент.

Я тут еще подумал, и пришел к выводу что стабильно рабочего решения для сценария с IOCP у вас таким путем не получится Потому что параллельно работающий юзерский поток может получить через GetQueuedCompletionStatus уведомление о завершении _до_ того как раздуплится ваш код, ждущий на event'е. Получив его, он в свою очередь может уничтожить/резюзать текущую IoStatusBlock.