Ok, this is my current project:
I am working on a desktop manager using the WINAPI: CreateDesktop() and its counterparts.
The step I am at is fully closing a desktop, by the only means is to close all programs currently running in it.
To do this, I needed to find out what processes were running under what desktop.
I found out that using GetStartUpInfo API, I could determine this. The only problem I found that it is for a local process, not remote. So I decided to code a dll that I would inject and have it relay the information to the main application.
This is the code for the main application:
CODE
var
Form1 : TForm1;
Importing : String;
WM_DLLMESSAGE : DWord;
...
...
type
TWMDLLData = record
Msg: Cardinal;
Handle: HWND;
Info: Longint;
Result: Longint;
end;
...
...
procedure TForm1.ViewRunning1Click(Sender: TObject);
var
pID : Array[0..1023] Of DWORD;
Current : DWORD;
I : Integer;
ProcCount : Integer;
hProcess : THandle;
hMod : HMODULE;
ModuleName : Array[0..300] Of Char;
Debug : TStartupInfo;
_DesktopName : PChar;
DesktopName : String;
begin
EnumProcesses(@pID,SizeOf(pID),Current);
ProcCount := Current DIV SizeOf(DWORD);
GetStartupInfo(Debug);
_DesktopName := Debug.lpDesktop;
DesktopName := _DeskTopName;
For I := 0 To ProcCount - 1 Do
begin
hProcess := OpenProcess(Process_all_access,False,pID[I]);
If hProcess > 0 Then
begin
EnumProcessModules(hProcess,@hMod,SizeOf(hMod),Current);
GetModuleFileNameEx(hProcess,hMod,ModuleName,SizeOf(ModuleName));
Importing := '';
If InjectLibrary(hProcess,PChar(ExtractFilePath(ParamStr(0)) + 'DesktopAPI.dll')) Then
begin
While Importing = '' Do
begin
Application.ProcessMessages;
end;
UninjectLibrary(hProcess,PChar(ExtractFilePath(ParamStr(0)) + 'DesktopAPI.dll'));
If Importing = DesktopName Then
begin
Form4.ValueListEditor1.InsertRow(ExtractFileName(ModuleName),IntToStr(pID[I]),True);
end;
end;
end;
CloseHandle(hProcess);
end;
Form4.Show;
end;
procedure TForm1.WMDLLData(var Msg: TWMDLLData);
begin
Importing := String(Msg.Info);
end;
procedure TForm1.DefaultHandler(var Message);
var
ee: TWMDLLData;
begin
with TMessage(Message) do
begin
if (Msg = WM_DLLMESSAGE) then
begin
ee.Msg := Msg;
ee.Handle := wParam;
ee.Info := lParam;
if ee.Handle <> Handle then
WMDLLData(ee);
end
else
inherited DefaultHandler(Message);
end;
end;
Initialization
WM_DLLMESSAGE := RegisterWindowMessage('Sending Data');
The DLL source is as follows:
CODE
library DesktopAPI;
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;
{$R *.res}
var
WM_DLLMESSAGE : DWORD;
type
TWMDLLData = record
Msg: Cardinal;
Handle: HWND;
Info: Longint;
Result: Longint;
end;
procedure EntryPoint(Reason: LongWord);
var
Debug : TStartupInfo;
Data : TCopyDataStruct;
pDesktop : PChar;
Tmp2 : String;
begin
If Reason = 1 Then
begin
GetStartUpInfo(Debug);
pDesktop := Debug.lpDesktop;
Data.dwData := 0;
Data.cbData := 1 + Length(pDesktop);
Data.lpData := pDesktop;
Tmp2 := pDesktop;
SendMessage(HWND_Broadcast,WM_DLLMESSAGE,0,Integer(Tmp2));
end;
end;
begin
WM_DLLMESSAGE := RegisterWindowMessage('Sending Data');
DLLProc := @EntryPoint;
EntryPoint(1);
end.
The problem is that whenever I run the main procedure and start the process, the computer does a hard reboot.
I am not really sure where to go from this point, as trying anything new gets me another crash. So I thought eye's other than my own might catch something I did wrong.