Здравствуйте. У меня не совсем вопрос по Win32, но очень близок. Этот вопрос уже задавался на osronline.com, но MS не захотел отвечать. Может кто-нибудь знает ответ на него? A driver I am developing makes use of user APCs (yes, I know, undocumented and therefore bad, still, in this case, I'm fairly certain it is the best solution - at least for the time being) to callback into userland applications. This code works fine on both 64 bit and 32 bit versions of Windows. WOW64 however is a problem. In this case, the APC generates a callback as expected, however the callback is called with a 64 bit stack. I'm aware that Windows' own use of user apcs users helper functions with the wow64 dll to manage the thunking and stack manipulation problems, but I do not see a clear way I can use these to my advantage. С уважением, Виталий.
Мне не понятен ваш комментарий. Использования данного метода описано, например, здесь: http://www.ddj.com/dept/windows/184416590. Этот механизм нами используется для внедрения dll в процессы уже много лет. Он всегда работал, и сейчас при портировании продукта на Windows x64 возникла проблема для WOW64 процессов, при этом для настоящих 64-битных процессов такой проблемы нет. Весь вопрос в том, как из APC, который исполняется в WOW64 процессе, но в 64-битном режиме, исполнить 32-битный код.
b_vital Т.е. обработчик 32-битный, но стек 64-битный и обработчик не может вытащить из стека параметры? Может МС не ответило, т.к. не поняло вопроса?
Неверно. Обработчик 64-битный, работает в 64-битном режиме, но весь процесс 32-битный исполняемый в WOW64 подсистеме. А МС злорадно отказались отвечать.
Скорее всего туплю, но мне совершенно не понятна суть вопроса. В МС тоже не телепаты работают. В следующий раз, когда надумаете что-то у них спросить, имейте в виду, что такие длинные (и синтаксически сложные) предложения, как в вашем первом посте, американец не в состоянии восприять, а уж тем более осмыслить. В саппорт писать нужно коротко и ясно. Это всё имхо, конечно.
Суть вопроса в том, что на Windows x64 любая APC сгенерированная в ядре для исполнения в пользовательском режиме всегда исполняется в 64-битном режиме, даже для 32-битных процессов, так как они (процессы) на самом деле зарождаются как 64-битные и только затем переключаются в 32-битный режим. Американцы прекрасно поняли вопрос, но отказались на него отвечать, на том основании, что использовалось недокоментированное решение, а сответственно документированного решения для него нет.
b_vital Ну, это понятно было ещё из прошлого ответа. Потом Вы пишете . Поэтому мне не понятен вопрос. Где тут можно поставить вопросительный знак? Уже в этом форуме Вы объясняете, что , да и то не сразу. Если МСовцы всё это поняли, то я снимаю перед ними шляпу. Я бы на вашем месте адаптировал существующее решение под x64, т.е. переписал бы обработчик, раз МС отказывается его поддерживать. Странно что эти недокументированности вообще работают в WOW.
На самом деле обработчик невозможно переписать, нужно использовать или совсем другой метод, или разбираться как поступает сам Windows в таких случаях. Вот я и разбираюсь. Может кто-то уже решал эту проблему и сможет поделиться информацией.
[offtop]А можно узнать почему? Из-за размера? Из-за ограничений в режимах адресации?[/offtop] Не знаю как он поступает. Помню, что WOW позволяет 32-битным клиентам подключаться к 64-битным серверам OLE-COM и наоборот. Может сам Windows использует именно эту лазейку?
b_vital Может ответишь тогда мне на один вопрос связаный с APC (я так и не нашел подходящего решения). Как выполнить user mode APC в контексте произвольного потока, при следующих условиях: 1) Поток не находиться в alertable состоянии. 2) Поток в этот момент может находиться в состоянии ожидания. 3) APC обязательно должен быть выполнен безотлагательно, без ожидания перехода потока в другое состояние. 4) После выполнения APC поток должен вернуться в то состояние, в котором он до этого находился. Пока что на этот вопрос я ответа не нашел. Если поток находиться в состоянии ожидания, то можно перевести его в alertable состояние поправив поле в структуре ETHREAD, тогда поток выполняет APC при выходе из ожидания, но обратно в старое состояние не возвращается что приводит к вылетания процесса владеющего этим потоком. Существует ли вобще универсальное (для всех систем NT линейки) и стабильное решение этой проблемы?
Хотя, прошу прощения, по поводу 4) я не уверен, вернётся ли он в состояние ожидания? Хотя по тому, как всё устроено, думаю, что будет работать.
А я наоборот совсем уверен, что поток после выполнения APC просто вылетит, так как давно это пробовал. Естественно, вылетит не всякий поток, но если например назначить APC каждому потоку в winlogon.exe то бсод обеспечен.
Вот тебе на! Это ж асинхронный ввод-вывод с файлами может груз словить. APC один из великих механизмов, и это ж надо ж такое западло сделать! Им ещё повезло, что многие программеры (именно программеры, титула программист они недостойны) не знают о существовании APC. А то бы их перевешали всех. b_vital Но это и есть переход в alertable.
Ms Rem Я про ReadFileEx и WriteFileEx. BOOL ReadFileEx( HANDLE hFile, // handle of file to read LPVOID lpBuffer, // address of buffer DWORD nNumberOfBytesToRead, // number of bytes to read LPOVERLAPPED lpOverlapped, // address of offset LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine // address of completion routine ); lpCompletionRoutine Points to the completion routine to be called when the read operation is complete and the calling thread is in an alertable wait state . For more information about the completion routine, see FileIOCompletionRoutine. Так как процедура будет 32-разрядная, но помещена в 64-разрядную очередь APC,то можно сделать определённые выводы: слетит всё к прародителям дзэна. Это фактически тоже добавление в очередь APC, только функция получает управление лишь если чтение завершено. Но если там стоит 64-х разрядный переходник, то может ещё жить будет. Проверьте кто-нибудь.
Накнулся на сабжевую проблему - минут за 20 нашел решение. Библиотека wow64.dll экспортирует функцию Wow64ApcRoutine. Ее и нужно передать в качестве юзенрмодного колбэка в wow64. При этом параметры обрабатываются примерно так struct QUAD { LONG wowNormalContext; LONG wowNormalRoutine }, //NormalContext для Wow64ApcRoutine LONGLONG SystemArg1, LONGLONG SystemArg2.