Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Непонятности с GetWindowModuleFileName


Страницы:   1 2

Чапаев ©   (2005-11-14 11:56:00) 

По идее, функция должна записать в буфер имя и путь к исполняемому файлу, который создал окно.

Делаю EnumWindows(), в процедуре обратного вызова вызываю эту функцию. Если вызываю из хука на мышь, не возвращает ничего, если из обычной программы -- всегда возвращает имя этой самой программы. В чём глюк?


shadowonline   (2005-12-26 16:24:00) [1]

Странно, поставил Delphi 6, скомпилировал ошибка осталась. Только exe-к на 70Кб раздулся. Похоже руки у меня точно не стого места ростут(Но как этот же exe-к работает под Win 2000????).


shadowonline   (2005-12-26 16:23:00) [2]

Странно, поставил Delphi 6, скомпилировал ошибка осталась. Только exe-к на 70Кб раздулся. Похоже руки у меня точно не стого места ростут(Но как этот же exe-к работает под Win 2000????).


shadowonline   (2005-12-26 13:30:00) [3]

Может есть какой патчь для Delphi 5


Игорь Шевченко   (2005-12-26 12:35:00) [4]

Код в [6] проверялся именно на XP SP2


shadowonline   (2005-12-26 12:11:00) [5]

Предустановлен SP2. Может быть проблемма в винде?


Игорь Шевченко   (2005-12-26 11:18:00) [6]

Какой сервис-пак для XP установлен ?


shadowonline   (2005-12-24 10:44:00) [7]

Дополнительные тесты показали. Происходит ошибка в строке
if NOT ReadProcessMemory(AProcessHandle,
                           @PPEB(PEBAddress)^.ProcessParameters,
                           @ATargetProcessParametersPointer, SizeOf(Ptr32),
                           AReturned) then
      RaiseLastWin32Error();
Ошибка 299 Запрос ReadProcessMemory был выполнен только частично.
Это под ХР, а под 2000 работает.(по поводу 87 ошибки похоже я криво окно искал, извиняюсь)


shadowonline   (2005-12-24 10:18:00) [8]

Теперь понятно в чем фишка. Но что то руки у меня кривые.
Нашел и состряпал(перевод из С) следующий код, все равно не помогает.
Может какую ни будь другую привилегию нужно или что не так делаю.
Функция возвращает успех но ошибка "87. Параметр задан неверно." все равно вылетает.

If EnableDebugPrivilege('SEDEBUGPRIVILEGE') Then ShowMessage('Yes!!!')
Else ShowMessage('No!!!');

function EnableDebugPrivilege(seName:String):Boolean;
Var
 hToken, prevst: Cardinal;
 tp, tk: TOKEN_PRIVILEGES;
Begin
 Result:= True;
 If (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken)) Then Begin
   tp.PrivilegeCount:= 1;
   If LookupPrivilegeValue(nil, PChar(seName), tp.Privileges[0].Luid) Then Begin
     tp.Privileges[0].Attributes:= SE_PRIVILEGE_ENABLED;
     If not AdjustTokenPrivileges(hToken, False, tp, sizeof(tp), tk, prevst) Then Result:= False;
   End
   Else Result:= False;
   CloseHandle(hToken);
 End
 Else Result:= False;
End;


Игорь Шевченко   (2005-12-23 15:57:00) [9]


> if AProcessHandle = 0 then


Не смог открыть процесс.

С привилегиями все хорошо ?


shadowonline   (2005-12-23 15:36:00) [10]

?????????. Если отлажевать под Win 2000 то ошибок вообще нет(все работает). Как же тогда ее можно отладить? Или только у меня под XP не работает????


shadowonline   (2005-12-23 15:30:00) [11]

В первом
if AProcessHandle = 0 then
    RaiseLastWin32Error();//Здесь
PEBAddress := RtlGetPeb;


Игорь Шевченко   (2005-12-23 14:39:00) [12]

shadowonline ©   (23.12.05 13:45) [11]


> Отладка показала что ошибка происходит после вызова RaiseLastWin32Error();
> .


RaiseLastWin32Error в этом коде вызывается четыре раза. Мне за догадливость, в каком именно месте происходит ошибка, денег не платят.


shadowonline   (2005-12-23 13:45:00) [13]

Извиняюсь, ошибся!!! Отладка показала что ошибка происходит после вызова RaiseLastWin32Error();. Причем брекпоинт внутри RaiseLastWin32Error(); не отрабатывает(можно предположить что она и не вызывается). Нечего не понимаю. Может у меня руки кривые, но под Win 2000 работает однако.


Игорь Шевченко   (2005-12-23 11:23:00) [14]

shadowonline ©   (23.12.05 07:40) [9]

Бред. Пройди отладчиком.


shadowonline   (2005-12-23 07:40:00) [15]

Ругается на строку "PEBAddress:= RtlGetPeb;" вызов асемблера.
Говорит ошибка 87. Параметр задан неверно.


Игорь Шевченко   (2005-12-22 17:47:00) [16]


> опять не работает.


Как именно не работает ?


shadowonline   (2005-12-22 17:17:00) [17]

Спасибо за код. Работает!
Вот только возникла проблема при переходе на Win XP, опять не работает.
Может там опять поменяли адрес блока PEB.
Помогите опять найти PEB блок в XP!!!


Игорь Шевченко   (2005-11-18 21:40:00) [18]

Чапаев ©   (18.11.05 18:14) [5]

Спасибо. В этих системах поменялся адрес блока PEB.

Вот такой код работает:

function RtlGetPeb: Cardinal; assembler;
asm
 mov eax,fs:[24]
 mov eax,[eax+48]
end;

{ Получение командной строки для процесса выбранного окна }
function HSGetWindowCommandLine (AWindowHandle : HWND) : String;
var
 PEBAddress: Cardinal{ = $7FFDF000};
var
 AProcessID : DWORD;
 AProcessHandle : THandle;
 ATargetProcessParametersPointer : Ptr32;
 ATargetProcessParameters : TRTL_USER_PROCESS_PARAMETERS;
 ATargetCommandLine : array[0..MAX_PATH] of WideChar;
 AReturned : DWORD;
 APathBytes : WORD;
begin
 Result := '';
 { Алгоритм пригоден только для NT-платформ }
 if HSQuerySystemInfo(hsiNTPlatform) then begin
   { PID для процесса, создавшего окно }
{$IFDEF VER140}
   GetWindowThreadProcessID(AWindowHandle, AProcessID);
{$ELSE}
   GetWindowThreadProcessID(AWindowHandle, @AProcessID);
{$ENDIF}
   { handle этого процесса }
   AProcessHandle := OpenProcess(PROCESS_VM_READ or PROCESS_VM_OPERATION,
     false, AProcessID);
   if AProcessHandle = 0 then
     RaiseLastWin32Error();
   PEBAddress := RtlGetPeb;
   try
     { Получение адреса структуры параметров процесса }
     if NOT ReadProcessMemory(AProcessHandle,
                            { Этот оператор нужен для подсчета смещения в блоке
                              PEB на указатель на параметры процесса }
                            @PPEB(PEBAddress)^.ProcessParameters,
                            @ATargetProcessParametersPointer, SizeOf(Ptr32),
                            AReturned) then
       RaiseLastWin32Error();
     { Проверка избыточна, но вставлена для пущей надежности. }
     if AReturned <> SizeOf(Pointer) then
       raise Exception.CreateFmt(
         'ReadProcessMemory прочитала неверное количество данных, ожидалось %d, получено %d',
         [SizeOf(Ptr32), AReturned]);
     { Получение структуры параметров процесса }
     if NOT ReadProcessMemory(AProcessHandle, ATargetProcessParametersPointer,
                              @ATargetProcessParameters,
                              SizeOf(ATargetProcessParameters),
                              AReturned) then
       RaiseLastWin32Error();
     { Проверка избыточна, но вставлена для пущей надежности. }
     if AReturned <> SizeOf(ATargetProcessParameters) then
       raise Exception.CreateFmt(
         'ReadProcessMemory прочитала неверное количество данных, ожидалось %d, получено %d',
         [SizeOf(ATargetProcessParameters), AReturned]);
     { размер командной строки в байтах }
     APathBytes := ATargetProcessParameters.CommandLine.Length;
     if APathBytes > MAX_PATH * SizeOf(WideChar) then
       APathBytes := MAX_PATH * SizeOf(WideChar);
     { Получение командной строки для указанного процесса }
     if not ReadProcessMemory(AProcessHandle,
                              ATargetProcessParameters.CommandLine.Buffer,
                              @ATargetCommandLine,
                              APathBytes,
                              AReturned) then
       RaiseLastWin32Error();
     { Для преобразования в Ansi подсчитывается число символов Unicode без
       завершающего нуля. lstrlenW почему-то дала неверный результат. Странно.}
     Result := WideCharLenToString(ATargetCommandLine,
               Pred(AReturned DIV SizeOf(WideChar)));
   finally
     CloseHandle(AProcessHandle);
   end;
 end;
end;


Чапаев   (2005-11-18 18:14:00) [19]


> Привилегиев видать нету.

На домашнем компе? Под администраторским аккаунтом? Да должно бы хватить... ;-)


Игорь Шевченко   (2005-11-17 12:27:00) [20]

Чапаев ©   (17.11.05 11:28) [2]

Привилегиев видать нету.


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо