KeDelayExecutionThread - как получить?

Тема в разделе "WASM.WIN32", создана пользователем Flames47, 4 мар 2005.

  1. Flames47

    Flames47 New Member

    Публикаций:
    0
    Регистрация:
    4 мар 2005
    Сообщения:
    4
    Помогите решить проблему: Надо использовать функцию ядра 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")
     
  2. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    Flames47

    Разве KeDelayExecutionThread экспортируется из kernel32.dll?

    Под wxpsp2 такой код:
    Код (Text):
    1.  
    2.   HMODULE h = LoadLibrary("ntoskrnl.exe");
    3.   if (NULL != h)
    4.   {
    5.     PFN_KED ked = (PFN_KED) GetProcAddress(h,"KeDelayExecutionThread");
    6.     if (NULL != f)
    7.       printf("ok\n");
    8.   }
    выдает ok.
     
  3. TarasCo

    TarasCo New Member

    Публикаций:
    0
    Регистрация:
    2 фев 2005
    Сообщения:
    106
  4. Flames47

    Flames47 New Member

    Публикаций:
    0
    Регистрация:
    4 мар 2005
    Сообщения:
    4
    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?
     
  5. TarasCo

    TarasCo New Member

    Публикаций:
    0
    Регистрация:
    2 фев 2005
    Сообщения:
    106
    На самом деле если Вам нужна хорошая разрешающая способность, Вы идете неверным путем. Вызвав в ядре ли KeDelayExecutionThread, в 3 ли кольце NtDelayExecution - одночуйственно спровоцируете переключение контекста и , как следствие, возможную задержку в несколько мс. Для получение микросекундных задержек Вам нужно крутиться в цикле проверяя значение счетчика ( QueryPerformanceCounter )

    примерно так: http://junglewin.narod.ru/time.html#Estimate

    При этом дабы избежать переключения контекста желательно перед входом в цикл вызвать Sleep(0). Тогда цикл будет выполнен в начале слайса и не будет прерван переключением контекста.
     
  6. Flames47

    Flames47 New Member

    Публикаций:
    0
    Регистрация:
    4 мар 2005
    Сообщения:
    4
    TarasCo, на самом деле мне требуется очень точная эмуляция действий пользователя. Надо, чтоб клавные и мышиные события генерировались в точно заданное время.
     
  7. TarasCo

    TarasCo New Member

    Публикаций:
    0
    Регистрация:
    2 фев 2005
    Сообщения:
    106
    Ну тогда не очень понятно требование < 1мс.... Врядли существуют такие заапгрейченные пользователи :)

    Возможно, Вам пригодятся ожидаемые таймеры (CreateWaitableTimer)... Но опять же повторюсь, использование любых функций, переводящих поток в состояние ожидания, снижает точность любых методов привязки ко временной шкале как минимум до величины слайса. Т.е речь идет о миллисекундах (и даже десятках; держите в уме, что на серверных платформах слайс гороздо длинее, чем на десктопах ). С другой стороны, никто не заставляет Вас засыпать, ожидая тот же ожидаемый таймер. Можно просто проверять его состояние с помощтю WaitForSingleObject, задавая интервал ожидания = 0.