Запускаю в цикле некоторое количество раз поток ThreadProc. С условием прекращения ожидания окончания работы потока по истечение некоторого времени. Код (Text): void ThreadProc( PVOID lParam){ ... ... PsTerminateSystemThread (STATUS_SUCCESS); } //--------------------------------------------------------- if (STATUS_SUCCESS == PsCreateSystemThread (&hThread, THREAD_ALL_ACCESS, &oAttr, NtCurrentProcess(), NULL, ThreadProc, &lParam)){ ObReferenceObjectByHandle (hThread, THREAD_ALL_ACCESS, NULL, KernelMode, &pkThread, NULL); ZwClose (hThread); Timeout.HighPart = -1; Timeout.LowPart = 100000; if (STATUS_SUCCESS == KeWaitForSingleObject (pkThread, Executive, KernelMode, FALSE, &Timeout)){ result = TRUE; DbgPrint("Success"); } } Собственно потоки стартуют, отрабатывают, но часть потоков не завершается, и программа, запустившая поток, зависает. Насколько правильно тут используется KeWaitForSingleObject? Или причина зависания не в KeWaitForSingleObject?
Как-то для меня немного странно инициализируется Timeout... Может, он на самом деле сильно большой получается при такой инициализации? Я обычно пишу LARGE_INTEGER TimeOut; TimeOut.QuadPart = -50; \\5 MicroSec
Инициализирую по аналогии с тем, как делается для таймера. Может надо другие величины? Сейчас попробую с QuardPart (надо перегрузиться, а то не отцепиться никак от драйвера
У меня такая же хрень бывала Хоть не БСОД Если я не ошибаюсь, такая херня(когда весится запускающее драйвер приложение, но не система) у меня получалась когда я пытался ждать в DispatchClose routine окончания потока. Кажется, если я писал типа while(!pDE->ThreadTerminated);, то висла вся система, а если использовал событие, то висла только вызывающая программа. Теперь я юзаю while(!pDE->ThreadTerminated); "текник" в DriverUnload routine и все нормально работает.
Частично проблема решается с QuadPart = -100000. Вызывающая прога перестает виснуть после DeviceIoControl, но драйвер остается в невменяемом состоянии - ни остановить, ни другие коды ему послать. Только перезагрузка Пробовал ZwTerminateThread для зависших потоков - тут другой капкан: необходимо линковать ntdll к драйверу во избежание unresolved external, а с прилинкованой ntdll драйвер не стартует вообще
...Если ты используешь PsTerminateSystemThread, то, как я понимаю, поток ядерный, следовательно, его никак нельзя насильно остановить. Вот фрагмент из w2kdriverbook по этому поводу: When a driver unloads, it must ensure that any system thread it may have created has terminated. System threads must terminate themselves, using PsTerminateSystemThread, described in Table 14.2. Unlike Win32 user-mode threads, there is no way to forcibly terminate a system thread. This means that some kind of signaling mechanism needs to be set up to let a thread know it should exit. As discussed later in this chapter, Event objects provide a convenient mechanism for this. Короче: так или иначе Ты должен дождаться когда все треды поконячат собой. И поэтому конечный таймаут тут никак не может решить проблему. По-моему, это в самих тредах дело...
В доке чётко написано, про то, что для относительного таймаута он должен быть отрицательным. В аттаче хидер, юзать примерно так: Код (Text): Timeout.QuadPart = -SECONDS_ONE; ZwTerminateThread не поможет, т.к. ядерные потоки сами себя завершают. В доке, кажется, чётко сказано. Линковаться с ntdll, как и с любой другой юзермодной библиотекой - забей! _684132569__TimeIntervals.rar
Вот те и на... Получается, если писАл Timeout.QuadPart = -50 - это не 5 микросекунд что ли??? А, не, гоню... Там значок *, а не какая-нибудь запятая, как мне показалось в DDK еще более просто написано: Timeout Pointer to a time-out value that specifies the absolute or relative time at which the wait is to be completed (optional). A negative value specifies an interval relative to the current time. The value should be expressed in units of 100 nanoseconds. Absolute expiration times track any changes in the system time; relative expiration times are not affected by system time changes.