Помогите решить проблему: Надо использовать функцию ядра KeDelayExecutionThread в самом обычном пользовательском режиме. При иполнении кода typedef enum _MODE { KernelMode, UserMode, MaximumMode } KPROCESSOR_MODE; typedef dword (__stdcall * _KeDelayExecutionThread) ( KPROCESSOR_MODE WaitMode, BOOLEAN Alertable, PLARGE_INTEGER Interval ); _KeDelayExecutionThread KeDelayExecutionThread; GetModuleHandle( "kernel32.dll" ); printf("hk=%08X\n",(dword)kernel); KeDelayExecutionThread = (_KeDelayExecutionThread) GetProcAddress(kernel, "_KeDelayExecutionThread@12"); printf("kdet=%08X\n",(dword)KeDelayExecutionThread); if(KeDelayExecutionThread) KeDelayExecutionThread(UserMode, 0, (PLARGE_INTEGER)50000000); в потоке вывода получаю hk=(не ноль), kdet=ноль. PS: Это - если динамически. Статически же заголовок <ntddk> не подключить - слишком много переопределений, конфликтных с <windows.h>; Я выписал аккуратно из <ntddk> объяву - ругается линкер (нету функции), хотя я написал ему #pragma comment (lib, "ntoskrnl.lib")
Flames47 Разве KeDelayExecutionThread экспортируется из kernel32.dll? Под wxpsp2 такой код: Код (Text): HMODULE h = LoadLibrary("ntoskrnl.exe"); if (NULL != h) { PFN_KED ked = (PFN_KED) GetProcAddress(h,"KeDelayExecutionThread"); if (NULL != f) printf("ok\n"); } выдает ok.
Если из 3 кольца, нужно использовать ntdll.dll и экспорт NtDelayExecution http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/ NT%20Objects/Thread/NtDelayExecution.html Или просто - SleepEx Вызвать функцию ядра на 3 кольце - не реально....
q_q Это я попробовал - вместо kernel32.dll получать хандл ntoskrnl.exe. Получается другая фигня - ошибка доступа к памяти (The instruction at "0x008554ce" referenced memory at "0x0000005a". The memory could not be "read"). TarasCo SleepEx не пойдет - плохая точность и неприемлимо большой интервал. (это я только для наглядной проверки работоспособности функции KeDelayExecutionThread 5 секунд написал, - речь идёт о интервалах <= 1 мс) За ссылку на NtDelayExecution спасибо, все теперь ok. А как же насчёт KeDelayExecutionThread? Значит её нельзя юзать? Или можно, но третьим параметром передавать адрес, выделенный GlobalAlloc'ом с флагом GMEM_SHARE?
На самом деле если Вам нужна хорошая разрешающая способность, Вы идете неверным путем. Вызвав в ядре ли KeDelayExecutionThread, в 3 ли кольце NtDelayExecution - одночуйственно спровоцируете переключение контекста и , как следствие, возможную задержку в несколько мс. Для получение микросекундных задержек Вам нужно крутиться в цикле проверяя значение счетчика ( QueryPerformanceCounter ) примерно так: http://junglewin.narod.ru/time.html#Estimate При этом дабы избежать переключения контекста желательно перед входом в цикл вызвать Sleep(0). Тогда цикл будет выполнен в начале слайса и не будет прерван переключением контекста.
TarasCo, на самом деле мне требуется очень точная эмуляция действий пользователя. Надо, чтоб клавные и мышиные события генерировались в точно заданное время.
Ну тогда не очень понятно требование < 1мс.... Врядли существуют такие заапгрейченные пользователи Возможно, Вам пригодятся ожидаемые таймеры (CreateWaitableTimer)... Но опять же повторюсь, использование любых функций, переводящих поток в состояние ожидания, снижает точность любых методов привязки ко временной шкале как минимум до величины слайса. Т.е речь идет о миллисекундах (и даже десятках; держите в уме, что на серверных платформах слайс гороздо длинее, чем на десктопах ). С другой стороны, никто не заставляет Вас засыпать, ожидая тот же ожидаемый таймер. Можно просто проверять его состояние с помощтю WaitForSingleObject, задавая интервал ожидания = 0.