В паскале разберёшься? Кину тебе пример кода, который запускает Regedit и переводит его на нужную ветку в его TreeView.07.12.06 06:37 Число просмотров: 4074 Автор: HandleX <Александр М.> Статус: The Elderman
Procedure ShowServiceRegKey(aServiceName: String; FormWnd: HWND);
Type
TRemoteBuff = Record
Item: TTVITEM;
aStr: Packed Array[0..820] Of Char;
End;
pRemoteBuff = ^TRemoteBuff;
Function GetSFieldCount(aStr: String; Delimiter: Char = #9): DWORD;
Var TempP: PChar;
Begin
TempP := PChar(aStr);
If aStr = '' Then Result := 0
Else Result := 1;
While TempP^ <> #0 Do
Begin
If TempP^ = Delimiter Then
Inc(Result);
Inc(TempP);
End;
End;
Function GetSField(aStr: String; anIndex: DWord; Delimiter: Char = #9): String;
Var
TempP: PChar;
Counter: DWORD;
Ind1, Ind2: Integer;
Begin
Counter := 0;
Result := '';
TempP := PChar(aStr);
Ind1 := -1; Ind2 := -1;
While TempP^ <> #0 Do
Begin
If TempP^ = Delimiter Then Inc(Counter);
If Counter = anIndex Then
If Ind1 = -1 Then
Ind1 := TempP - PChar(aStr);
If Counter > anIndex Then
Begin
Ind2 := TempP - PChar(aStr);
Break;
End;
Inc(TempP);
End;
If TempP^ = #0 Then
Ind2 := StrEnd(PChar(aStr)) - PChar(aStr);
If Ind1 <> 0 Then Inc(Ind1);
Result := Copy(aStr, Ind1 + 1, Ind2 - Ind1)
End;
Procedure ConnectHostToRegedit(aRegMainWnd: HWND; aHostName: String);
Function GetChildEditControl(aParent: HWND): HWND;
Function EnumProc(aHwnd: HWND; RetValue: PDWORD): BOOL; StdCall;
Var aBuff: String[255];
Begin
SetLength(aBuff, GetClassName(aHwnd, @aBuff[1], 254));
If (OSVersion.dwMajorVersion >= 5) And (OSVersion.dwMinorVersion >= 1) Then Result := Not (aBuff = 'RichEdit20W')
Else Result := Not (aBuff = 'Edit');
If Not Result Then
RetValue^ := aHwnd;
End;
Begin
EnumChildWindows(aParent, @EnumProc, DWORD(@Result));
End;
Function GetWindowClass(aWnd: HWND): String;
Begin
SetLength(Result, 255);
SetLength(Result, GetClassName(aWnd, PChar(Result), Length(Result)));
End;
Var
fWnd, eWnd: HWND;
mHndl, subMenu: HMENU;
mID: Integer;
begin
If aRegMainWnd = 0 Then Exit;
mHndl := GetMenu(aRegMainWnd);
Win32Check(mHndl <> 0);
subMenu := GetSubMenu(mHndl, 0);
Win32Check(SubMenu <> 0);
If (OSVersion.dwMajorVersion >= 5) And (OSVersion.dwMinorVersion >= 1) Then mID := GetMenuItemID(SubMenu, 6)
Else mID := GetMenuItemID(SubMenu, 3);
Win32Check(mID > 0);
Win32Check(PostMessage(aRegMainWnd, WM_COMMAND, mID, 0));
Repeat
fWnd := GetForegroundWindow;
Sleep(50);
Until Pos('#', GetWIndowClass(fWnd)) <> 0;
Win32Check(fWnd <> 0);
eWnd := GetChildEditControl(fWnd);
Win32Check(eWnd <> 0);
Win32Check(SendMessage(eWnd, WM_SETTEXT, 0, DWORD(PChar(aHostName))) <> 0);
SendMessage(fWnd, WM_KEYDOWN, 13, 0);
SendMessage(fWnd, WM_KEYUP, 13, 0);
End;
Function MakeFintInAnotherProcess(aProcess: THandle; aRemBuff: PRemoteBuff; aHwnd: HWND; aKey: String): Boolean;
Procedure WriteStrToBuff(aStr: String);
Var
aSrc: Pointer;
aSize, Written: DWORD;
Begin
aSrc := PChar(aStr);
aSize := Length(aStr) + 1;
If aSize > High(aRemBuff.aStr) Then
Raise Exception.Create('String is too long!');
Win32Check(WriteProcessMemory(aProcess, @aRemBuff^.aStr, aSrc, aSize, Written));
Win32Check(Written = aSize);
End;
Function ReadStrFromBuff: String;
Var Readed: DWORD;
Begin
SetLength(Result, High(aRemBuff.aStr));
Win32Check(ReadProcessMemory(aProcess, @aRemBuff.aStr, PChar(Result), High(aRemBuff.aStr), Readed));
Win32Check(Readed = High(aRemBuff.aStr));
SetLength(Result, StrLen(PChar(Result)));
End;
Function ReadStrFromAddr(anAddr: Pointer): String;
Var
Readed: DWORD;
Buff: Char;
pTemp: Pointer;
Begin
pTemp := anAddr;
Result := '';
Repeat
Win32Check(ReadProcessMemory(aProcess, pTemp, @Buff, 1, Readed));
Win32Check(Readed = 1);
If Buff <> #0 Then
Result := Result + Buff;
Inc(DWORD(pTemp));
Until Buff = #0;
End;
Procedure WriteItemToBuff(Const Item: TTVITEM);
Var Written: DWORD;
Begin
Win32Check(WriteProcessMemory(aProcess, aRemBuff, @Item, SizeOf(Item), Written));
Win32Check(Written = SizeOf(Item));
End;
Procedure ReadItemFromBuff(Var Item: TTVITEM);
Var Readed: DWORD;
Begin
Win32Check(ReadProcessMemory(aProcess, aRemBuff, @Item, SizeOf(Item), Readed));
Win32Check(Readed = SizeOf(Item));
End;
Function GetItemText(anItem: THandle): String;
Var ItemParams: TTVITEM;
Begin
ZeroMemory(@ItemParams, SizeOf(ItemParams));
ItemParams.mask := TVIF_TEXT;
ItemParams.hItem := HTREEITEM(anItem);
ItemParams.pszText := @aRemBuff.aStr;
ItemParams.cchTextMax := 400;
WriteItemToBuff(ItemParams);
Win32Check(TreeView_GetItem(aHwnd, aRemBuff.Item));
ReadItemFromBuff(ItemParams);
If ItemParams.pszText = Nil Then Result := ''
Else
If ItemParams.pszText = @aRemBuff.aStr Then Result := ReadStrFromBuff
Else Result := ReadStrFromAddr(ItemParams.pszText);
End;
Function FindChild(aParent: THandle; aText: String): THandle;
Var
anItem: THandle;
Compares: Integer;
TempStr: String;
Begin
Result := 0;
anItem := DWORD(TreeView_GetNextItem(aHwnd, HTREEITEM(aParent), TVGN_CHILD));
If anItem = 0 Then Exit;
Repeat
TempStr := GetItemText(anItem);
Compares := AnsiCompareStr(aText, TempStr);
If Compares = 0 Then Break;
anItem := DWORD(TreeView_GetNextSibling(aHwnd, HTREEITEM(anItem)));
Until anItem = 0;
If Compares = 0 Then Result := anItem;
End;
Function FindNextItem(fromItem: THandle; aText: String): THandle;
Var
anItem: THandle;
Compares: Integer;
TempStr: String;
Begin
Result := 0;
anItem := fromItem;
If anItem = 0 Then Exit;
Compares := -1;
Repeat
anItem := SendMessage(aHwnd, TVM_GETNEXTITEM, TVGN_NEXT, anItem);
If anItem = 0 Then Break;
TempStr := GetItemText(anItem);
Compares := AnsiCompareText(aText, TempStr);
Until Compares = 0;
If Compares = 0 Then Result := anItem;
End;
Var
anItem, TempItem: THandle;
J, Max: Integer;
TempStr: String;
Begin
Max := GetSFieldCount(aKey, '\') - 1;
Result := Max >= 0;
If Not Result Then Exit;
anItem := DWORD(TreeView_GetRoot(aHwnd));
Result := anItem <> 0;
If Not Result Then Exit;
If (MainForm.HostName <> '') AND (UpperCase(MainForm.HostName) <> UpperCase(LocalHostName)) Then
Begin
ConnectHostToRegedit(GetParent(aHwnd), MainForm.HostName);
Repeat
Sleep(100);
TempItem := FindNextItem(DWORD(TreeView_GetRoot(aHwnd)), MainForm.HostName);
Until TempItem <> 0;
anItem := TempItem;
Result := anItem <> 0;
If Not Result Then Exit;
End;
Result := TreeView_Expand(aHwnd, HTREEITEM(anItem), TVE_EXPAND);
If Not Result Then Exit;
For J := 0 To Max Do
Begin
TempStr := GetSField(aKey, J, '\');
anItem := FindChild(anItem, TempStr);
Result := anItem <> 0;
If Not Result Then Exit;
TreeView_Expand(aHwnd, HTREEITEM(anItem), TVE_EXPAND);
If J = Max Then
Result := TreeView_SelectItem(aHwnd, HTREEITEM(anItem)) <> HTREEITEM(0);
End;
End;
Function GetWindowProcessIDByTopmostWindowClass(aClass: String; Var aWnd: HWND): DWORD;
begin
Result := 0;
aWnd := FindWindow(PChar(aClass), Nil);
If aWnd = 0 Then Exit;
GetWindowThreadProcessID(aWnd, @Result);
End;
Function GetChildTreeView(aParent: HWND): HWND;
Function EnumProc(aHwnd: HWND; RetValue: PDWORD): BOOL; StdCall;
Var aBuff: String[255];
Begin
SetLength(aBuff, GetClassName(aHwnd, @aBuff[1], 254));
Result := Not (aBuff = 'SysTreeView32');
If Not Result Then
RetValue^ := aHwnd;
End;
Begin
EnumChildWindows(aParent, @EnumProc, DWORD(@Result));
End;
Function ShellExecuteAndWaitForIdle(ExePath: String): THandle;
Var anInfo: TShellExecuteInfo;
Begin
ZeroMemory(@anInfo, SizeOf(anInfo));
anInfo.cbSize := SizeOf(anInfo);
anInfo.fMask := SEE_MASK_NOCLOSEPROCESS;
anInfo.Wnd := FormWnd;
anInfo.lpVerb := 'Open';
anInfo.lpFile := PChar(ExePath);
anInfo.nShow := SW_SHOWNORMAL;
If Not ShellExecuteEx(@anInfo) Then Abort;
Result := anInfo.hProcess;
Win32Check(WaitForInputIdle(Result, INFINITE) <> $FFFFFFFF);
End;
Var
pID, pHndl: THandle;
rBuff: PRemoteBuff;
aHwnd: HWND;
Begin
pHndl := 0;
pID := GetWindowProcessIDByTopmostWindowClass('RegEdit_RegEdit', aHwnd);
If pId = 0 Then
If GetLastError = ERROR_FILE_NOT_FOUND Then
Begin
pHndl := ShellExecuteAndWaitForIdle('regedit.exe');
pID := GetWindowProcessIDByTopmostWindowClass('RegEdit_RegEdit', aHwnd);
Win32Check(pID <> 0);
End Else RaiseLastWin32Error
Else pHndl := OpenProcess(PROCESS_ALL_ACCESS, False, pID);
Win32Check(pHndl <> 0);
Try
If IsIconic(aHwnd) Then ShowWindow(aHwnd, SW_Restore);
SetForegroundWindow(aHwnd);
aHwnd := GetChildTreeView(aHwnd);
Win32Check(aHwnd <> 0);
rBuff := VirtualAllocEx(pHndl, Nil, SizeOf(rBuff), MEM_COMMIT, PAGE_READWRITE);
Win32Check(rBuff <> Nil);
Try
If Not MakeFintInAnotherProcess(pHndl, rBuff, aHwnd, 'HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\' + aServiceName) Then
Raise Exception.Create('Error dialing with Regedit ;-)');
Finally
Win32Check(VirtualFreeEx(pHndl, rBuff, 0, MEM_RELEASE) <> Nil);
End;
Finally
CloseHandle(pHndl);
End;
End;
Такая проблема. Нужно определить текущий элемент в контроле SysListTreeView32 в чужом окне (хэндл контрола получаю через Windows Hooks и EnumChildWindows). Попробовал через TVM_GETITEM (он же TreeView_GetItem), но это сообщение возвращает ошибку. Такое подозрение, что это сообщение нельзя использовать с чужими окнами. Вот как я делал:
На что указатель? Верно, на память. В адресном пространстве какого процесса? Как ты думаешь, вот если ты бы писал венды, стал бы ты парить моск, копируя букаффки из адресного пространства одного процеса в адресное пространство другого (насколько я понимаю, у тебя хендл окна ДРУГОГО процесса)? Вот я бы не стал. Поскольку 99,9999 использования этого сообщения наблюдается в своём процессе со своими контролами -)) И программеры M$ тоже себя этим не стали утруждать. Поэтому берём VirtualAllocEx (аллоцируем память под букаффки в читаемом процессе), шлём соответств. мессидж в чужое окно с соотв. указателем на память, валидном в ТОМ процессе, а потом читаем чужое адресное пространство с помощью ReadProcessMemory(). И не забываем, что в 9x-ME виндах этих функций нет.
Удачи.
Вот пробую сделать то же самое, но уже в своём процессе и законном обработчике окна. Тоже названия веток не определяются. Хэндл проверял - не ноль. Где я опять туплю?07.12.06 03:36 Автор: Vedrus <Serokhvostov Anton> Статус: Member Отредактировано 07.12.06 03:54 Количество правок: 2
В паскале разберёшься? Кину тебе пример кода, который запускает Regedit и переводит его на нужную ветку в его TreeView.07.12.06 06:37 Автор: HandleX <Александр М.> Статус: The Elderman
Procedure ShowServiceRegKey(aServiceName: String; FormWnd: HWND);
Type
TRemoteBuff = Record
Item: TTVITEM;
aStr: Packed Array[0..820] Of Char;
End;
pRemoteBuff = ^TRemoteBuff;
Function GetSFieldCount(aStr: String; Delimiter: Char = #9): DWORD;
Var TempP: PChar;
Begin
TempP := PChar(aStr);
If aStr = '' Then Result := 0
Else Result := 1;
While TempP^ <> #0 Do
Begin
If TempP^ = Delimiter Then
Inc(Result);
Inc(TempP);
End;
End;
Function GetSField(aStr: String; anIndex: DWord; Delimiter: Char = #9): String;
Var
TempP: PChar;
Counter: DWORD;
Ind1, Ind2: Integer;
Begin
Counter := 0;
Result := '';
TempP := PChar(aStr);
Ind1 := -1; Ind2 := -1;
While TempP^ <> #0 Do
Begin
If TempP^ = Delimiter Then Inc(Counter);
If Counter = anIndex Then
If Ind1 = -1 Then
Ind1 := TempP - PChar(aStr);
If Counter > anIndex Then
Begin
Ind2 := TempP - PChar(aStr);
Break;
End;
Inc(TempP);
End;
If TempP^ = #0 Then
Ind2 := StrEnd(PChar(aStr)) - PChar(aStr);
If Ind1 <> 0 Then Inc(Ind1);
Result := Copy(aStr, Ind1 + 1, Ind2 - Ind1)
End;
Procedure ConnectHostToRegedit(aRegMainWnd: HWND; aHostName: String);
Function GetChildEditControl(aParent: HWND): HWND;
Function EnumProc(aHwnd: HWND; RetValue: PDWORD): BOOL; StdCall;
Var aBuff: String[255];
Begin
SetLength(aBuff, GetClassName(aHwnd, @aBuff[1], 254));
If (OSVersion.dwMajorVersion >= 5) And (OSVersion.dwMinorVersion >= 1) Then Result := Not (aBuff = 'RichEdit20W')
Else Result := Not (aBuff = 'Edit');
If Not Result Then
RetValue^ := aHwnd;
End;
Begin
EnumChildWindows(aParent, @EnumProc, DWORD(@Result));
End;
Function GetWindowClass(aWnd: HWND): String;
Begin
SetLength(Result, 255);
SetLength(Result, GetClassName(aWnd, PChar(Result), Length(Result)));
End;
Var
fWnd, eWnd: HWND;
mHndl, subMenu: HMENU;
mID: Integer;
begin
If aRegMainWnd = 0 Then Exit;
mHndl := GetMenu(aRegMainWnd);
Win32Check(mHndl <> 0);
subMenu := GetSubMenu(mHndl, 0);
Win32Check(SubMenu <> 0);
If (OSVersion.dwMajorVersion >= 5) And (OSVersion.dwMinorVersion >= 1) Then mID := GetMenuItemID(SubMenu, 6)
Else mID := GetMenuItemID(SubMenu, 3);
Win32Check(mID > 0);
Win32Check(PostMessage(aRegMainWnd, WM_COMMAND, mID, 0));
Repeat
fWnd := GetForegroundWindow;
Sleep(50);
Until Pos('#', GetWIndowClass(fWnd)) <> 0;
Win32Check(fWnd <> 0);
eWnd := GetChildEditControl(fWnd);
Win32Check(eWnd <> 0);
Win32Check(SendMessage(eWnd, WM_SETTEXT, 0, DWORD(PChar(aHostName))) <> 0);
SendMessage(fWnd, WM_KEYDOWN, 13, 0);
SendMessage(fWnd, WM_KEYUP, 13, 0);
End;
Function MakeFintInAnotherProcess(aProcess: THandle; aRemBuff: PRemoteBuff; aHwnd: HWND; aKey: String): Boolean;
Procedure WriteStrToBuff(aStr: String);
Var
aSrc: Pointer;
aSize, Written: DWORD;
Begin
aSrc := PChar(aStr);
aSize := Length(aStr) + 1;
If aSize > High(aRemBuff.aStr) Then
Raise Exception.Create('String is too long!');
Win32Check(WriteProcessMemory(aProcess, @aRemBuff^.aStr, aSrc, aSize, Written));
Win32Check(Written = aSize);
End;
Function ReadStrFromBuff: String;
Var Readed: DWORD;
Begin
SetLength(Result, High(aRemBuff.aStr));
Win32Check(ReadProcessMemory(aProcess, @aRemBuff.aStr, PChar(Result), High(aRemBuff.aStr), Readed));
Win32Check(Readed = High(aRemBuff.aStr));
SetLength(Result, StrLen(PChar(Result)));
End;
Function ReadStrFromAddr(anAddr: Pointer): String;
Var
Readed: DWORD;
Buff: Char;
pTemp: Pointer;
Begin
pTemp := anAddr;
Result := '';
Repeat
Win32Check(ReadProcessMemory(aProcess, pTemp, @Buff, 1, Readed));
Win32Check(Readed = 1);
If Buff <> #0 Then
Result := Result + Buff;
Inc(DWORD(pTemp));
Until Buff = #0;
End;
Procedure WriteItemToBuff(Const Item: TTVITEM);
Var Written: DWORD;
Begin
Win32Check(WriteProcessMemory(aProcess, aRemBuff, @Item, SizeOf(Item), Written));
Win32Check(Written = SizeOf(Item));
End;
Procedure ReadItemFromBuff(Var Item: TTVITEM);
Var Readed: DWORD;
Begin
Win32Check(ReadProcessMemory(aProcess, aRemBuff, @Item, SizeOf(Item), Readed));
Win32Check(Readed = SizeOf(Item));
End;
Function GetItemText(anItem: THandle): String;
Var ItemParams: TTVITEM;
Begin
ZeroMemory(@ItemParams, SizeOf(ItemParams));
ItemParams.mask := TVIF_TEXT;
ItemParams.hItem := HTREEITEM(anItem);
ItemParams.pszText := @aRemBuff.aStr;
ItemParams.cchTextMax := 400;
WriteItemToBuff(ItemParams);
Win32Check(TreeView_GetItem(aHwnd, aRemBuff.Item));
ReadItemFromBuff(ItemParams);
If ItemParams.pszText = Nil Then Result := ''
Else
If ItemParams.pszText = @aRemBuff.aStr Then Result := ReadStrFromBuff
Else Result := ReadStrFromAddr(ItemParams.pszText);
End;
Function FindChild(aParent: THandle; aText: String): THandle;
Var
anItem: THandle;
Compares: Integer;
TempStr: String;
Begin
Result := 0;
anItem := DWORD(TreeView_GetNextItem(aHwnd, HTREEITEM(aParent), TVGN_CHILD));
If anItem = 0 Then Exit;
Repeat
TempStr := GetItemText(anItem);
Compares := AnsiCompareStr(aText, TempStr);
If Compares = 0 Then Break;
anItem := DWORD(TreeView_GetNextSibling(aHwnd, HTREEITEM(anItem)));
Until anItem = 0;
If Compares = 0 Then Result := anItem;
End;
Function FindNextItem(fromItem: THandle; aText: String): THandle;
Var
anItem: THandle;
Compares: Integer;
TempStr: String;
Begin
Result := 0;
anItem := fromItem;
If anItem = 0 Then Exit;
Compares := -1;
Repeat
anItem := SendMessage(aHwnd, TVM_GETNEXTITEM, TVGN_NEXT, anItem);
If anItem = 0 Then Break;
TempStr := GetItemText(anItem);
Compares := AnsiCompareText(aText, TempStr);
Until Compares = 0;
If Compares = 0 Then Result := anItem;
End;
Var
anItem, TempItem: THandle;
J, Max: Integer;
TempStr: String;
Begin
Max := GetSFieldCount(aKey, '\') - 1;
Result := Max >= 0;
If Not Result Then Exit;
anItem := DWORD(TreeView_GetRoot(aHwnd));
Result := anItem <> 0;
If Not Result Then Exit;
If (MainForm.HostName <> '') AND (UpperCase(MainForm.HostName) <> UpperCase(LocalHostName)) Then
Begin
ConnectHostToRegedit(GetParent(aHwnd), MainForm.HostName);
Repeat
Sleep(100);
TempItem := FindNextItem(DWORD(TreeView_GetRoot(aHwnd)), MainForm.HostName);
Until TempItem <> 0;
anItem := TempItem;
Result := anItem <> 0;
If Not Result Then Exit;
End;
Result := TreeView_Expand(aHwnd, HTREEITEM(anItem), TVE_EXPAND);
If Not Result Then Exit;
For J := 0 To Max Do
Begin
TempStr := GetSField(aKey, J, '\');
anItem := FindChild(anItem, TempStr);
Result := anItem <> 0;
If Not Result Then Exit;
TreeView_Expand(aHwnd, HTREEITEM(anItem), TVE_EXPAND);
If J = Max Then
Result := TreeView_SelectItem(aHwnd, HTREEITEM(anItem)) <> HTREEITEM(0);
End;
End;
Function GetWindowProcessIDByTopmostWindowClass(aClass: String; Var aWnd: HWND): DWORD;
begin
Result := 0;
aWnd := FindWindow(PChar(aClass), Nil);
If aWnd = 0 Then Exit;
GetWindowThreadProcessID(aWnd, @Result);
End;
Function GetChildTreeView(aParent: HWND): HWND;
Function EnumProc(aHwnd: HWND; RetValue: PDWORD): BOOL; StdCall;
Var aBuff: String[255];
Begin
SetLength(aBuff, GetClassName(aHwnd, @aBuff[1], 254));
Result := Not (aBuff = 'SysTreeView32');
If Not Result Then
RetValue^ := aHwnd;
End;
Begin
EnumChildWindows(aParent, @EnumProc, DWORD(@Result));
End;
Function ShellExecuteAndWaitForIdle(ExePath: String): THandle;
Var anInfo: TShellExecuteInfo;
Begin
ZeroMemory(@anInfo, SizeOf(anInfo));
anInfo.cbSize := SizeOf(anInfo);
anInfo.fMask := SEE_MASK_NOCLOSEPROCESS;
anInfo.Wnd := FormWnd;
anInfo.lpVerb := 'Open';
anInfo.lpFile := PChar(ExePath);
anInfo.nShow := SW_SHOWNORMAL;
If Not ShellExecuteEx(@anInfo) Then Abort;
Result := anInfo.hProcess;
Win32Check(WaitForInputIdle(Result, INFINITE) <> $FFFFFFFF);
End;
Var
pID, pHndl: THandle;
rBuff: PRemoteBuff;
aHwnd: HWND;
Begin
pHndl := 0;
pID := GetWindowProcessIDByTopmostWindowClass('RegEdit_RegEdit', aHwnd);
If pId = 0 Then
If GetLastError = ERROR_FILE_NOT_FOUND Then
Begin
pHndl := ShellExecuteAndWaitForIdle('regedit.exe');
pID := GetWindowProcessIDByTopmostWindowClass('RegEdit_RegEdit', aHwnd);
Win32Check(pID <> 0);
End Else RaiseLastWin32Error
Else pHndl := OpenProcess(PROCESS_ALL_ACCESS, False, pID);
Win32Check(pHndl <> 0);
Try
If IsIconic(aHwnd) Then ShowWindow(aHwnd, SW_Restore);
SetForegroundWindow(aHwnd);
aHwnd := GetChildTreeView(aHwnd);
Win32Check(aHwnd <> 0);
rBuff := VirtualAllocEx(pHndl, Nil, SizeOf(rBuff), MEM_COMMIT, PAGE_READWRITE);
Win32Check(rBuff <> Nil);
Try
If Not MakeFintInAnotherProcess(pHndl, rBuff, aHwnd, 'HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\' + aServiceName) Then
Raise Exception.Create('Error dialing with Regedit ;-)');
Finally
Win32Check(VirtualFreeEx(pHndl, rBuff, 0, MEM_RELEASE) <> Nil);
End;
Finally
CloseHandle(pHndl);
End;
End;
---
В задаче обошлось текущим процессом. Был ещё один касяк у...26.12.06 17:55 Автор: Vedrus <Serokhvostov Anton> Статус: Member
> стали утруждать. Поэтому берём VirtualAllocEx (аллоцируем > память под букаффки в читаемом процессе), шлём соответств. > мессидж в чужое окно с соотв. указателем на память, > валидном в ТОМ процессе, а потом читаем чужое адресное > пространство с помощью ReadProcessMemory(). И не забываем,
Как минимум WM_GETTEXT (скорее всего и common control-ы тоже) смотрит чтобы окно принадлежало тому же процессу, что и поток, пославший оный gettext. Если процессы разные - текст не копируется вообще. Единственный реальный способ - CreateRemoteThread-выделение памяти-получение строки-копирование через WriteProcessMemory в родительский процесс
В своё время писал софтину, которая открывает regedit на нужном ключе реестра. Там нет RemoteThread, есть только то, о чём я говорил выше.06.12.06 08:13 Автор: HandleX <Александр М.> Статус: The Elderman
Ну значит Common Control-ы не проверяют процесс. А зря. Если любой процесс может выставить буфером-приемником любой адрес в адресном пространстве жертвы, то завалить такую апликуху - раз плюнуть06.12.06 15:04 Автор: amirul <Serge> Статус: The Elderman