Maveric Только PASSIVE_LEVEL и лучше юзать ZwSetSystemTime - она экспортируется, а вызывает ту же NtSetSystemTime. Точно не помню, но кажется в конечном итоге всё сводится к изменению нескольких полей в структуре KI_USER_SHARED_DATA. Она мапится одновременно в ядро и юзер, причём по фиксированному адресу.
Four-F, спасибо за ответ. Значит чтобы модифицировать системное время на IRQL > PASSIVE_LEVEL придётся править эту самую KI_USER_SHARED_DATA ? И почему только на PASSIVE_LEVEL можно вызывать ZwSetSystemTime ?
в KI_USER_SHARED_DATA системное время хранится в структуре KSYSTEM_TIME, которая состоит из 3-х двордов. Что за формат такой ?
Maveric Не советую. Намного проще заставить системный рабочий поток вызвать ZwSetSystemTime на PASSIVE_LEVEL. См. "System Worker Threads" в DDK. Maveric А все Zw на пассив зовутся. Это шлюз из юзер-моды в ядро. Вся юзер-мода всегда на пассиве работает и при шлюзовании ядро должно проверить все передаваемые из юзера параметры на валидность, например, буферы и т.п. К тому же юзерные буферы и стек могут быть сброшены в подкачку, а подкачать их можно опять же только на пассив. Проверку юзерных параметров можно сделать только под SEH, а SEH нельзя юзать на повышенных IRQL. См., код NtSetSystemTime - первым делом ставится SEH. Возможно обработчикам int2E/sysenter тоже нужет пассив. Я уже всех деталей не помню, но по-любому все Zw только на PASSIVE_LEVEL зовутся... ну может какие-то можно и на APC_LEVEL, но только не выше.
С системными потоками мысль хорошая, но только "Callers of IoQueueWorkItem must be running at IRQL <= DISPATCH_LEVEL." А мне это не особо подходит. Задача вообще такая стоит: сажусь на прерывание от com-порта и если оно приходит нужно установить время в системе.
Тут пришёл в голову вариант: организовать DPC, который ставится в очередь из обработчика прерывания. В DPC уже вызывается IoQueueWorkItem По-моему как-то это всё долго Неужели нельзя короче ?
И ещё вопросик. Если я подключу обработчик прерывания раньше системного, то на каком IRQL он будет выполняться ?
Maveric DPC - это нормальный способ опуститься до DISPATCH_LEVEL. А то, что ты WorkItem ещё будешь в очередь ставить... ну... как короче, я не знаю, но руками в KI_USER_SHARED_DATA полез бы в самом последнем случае, если вообще полез бы. Maveric Очевидно на DIRQL, который система назначила для данного вектора, если ты имеешь ввиду IoConnectInterrupt. Если ты хучишь, но наверное, на IRQL, текущим в момент прерывания. А вообще я с аппаратными прерываниями плохо знаком. ЗЫ: Какая-то шибко мудрёная задачка.
Придётся заменить обработчик в IDT. Насколько я понимаю, IoConnectInterrupt добавляет обработчик в конец списка.