unit enumStuff;<br><br>// Delphi 4,5 enumeration implementation of several win32 APIs<br>// Dragon PC <br><br>interface<br><br>uses windows;<br><br>type TACardinal = array [0..maxInt shr 2-1] of cardinal;<br> TPACardinal = ^TACardinal;<br> TDACardinal = array of cardinal;<br><br>type TOperatingSystem = (osUnknown, osWin311, osWin95, osWin95osr2, osWin98, osWinNT3, osWinNT4, osWinNT4SP4, osWinNT5);<br>function GetOperatingSystem : TOperatingSystem;<br>// Tests which system is running...<br><br>type TExeType = (etUnknown, etDos, etWin16, etConsole, etWin32);<br>function GetExeType(exefile: string) : TExeType;<br>// Determines the type of the executable.<br><br>type TWindowList = array of record<br> pid : cardinal;<br> tid : cardinal;<br> window : cardinal;<br> parent : cardinal;<br> owner : cardinal;<br> visible : boolean;<br> enabled : boolean;<br> inTaskbar : boolean;<br> rect : TRect;<br> title : string;<br> className : string;<br> end;<br> TThreadList = array of record<br> pid : cardinal;<br> tid : cardinal;<br> windows : TWindowList;<br> end;<br> TProcessList = array of record<br> pid : cardinal;<br> name : string;<br> exeType : TExeType;<br> threads : TThreadList;<br> end;<br> TDesktopList = array of record<br> name : string;<br> windows : TWindowList;<br> end;<br> TWindowStationList = array of record<br> name : string;<br> desktops : TDesktopList;<br> end;<br> TCachedPasswordList = array of record<br> resource : string;<br> password : string;<br> resType : byte;<br> end;<br><br>function GetProcessList (threadsToo: boolean = false; windowsToo: boolean = false) : TProcessList;<br>// Lists the currently running processes.<br><br>function GetThreadList (pid: cardinal = 0; windowsToo: boolean = false) : TThreadList;<br>// Lists the currently running threads of the process "pid" or of all processes.<br><br>function GetWindowList (pid: cardinal = 0; tid: cardinal = 0; onlyThoseInTaskbar: boolean = false) : TWindowList;<br>// Lists the currently existing top level windows of the process "pid" or of all<br>// processes and of the thread "tid" or of all threads.<br><br>function GetChildWindowList (window: cardinal) : TWindowList;<br>// Lists the the child windows of "window".<br><br>function GetWindowStationList (desktopsToo: boolean = false; windowsToo: boolean = false) : TWindowStationList;<br>// Lists the currently existing window stations. (works only under winNT)<br><br>function GetDesktopList (ws: cardinal = 0; windowsToo: boolean = false) : TDesktopList;<br>// Lists the currently existing desktops. (works only under winNT)<br><br>function GetDesktopWindowList (dt: cardinal = 0) : TWindowList;<br>// Lists the currently existing windows of the current desktop. (works only under winNT)<br><br>function GetCachedPasswords : TCachedPasswordList;<br>// Lists all cached passwords of the currently logged in user. (works only under win95/98)<br><br>implementation<br><br>uses ShellAPI, sysUtils;<br><br>type TPThreadList = ^TThreadList;<br> TPProcessList = ^TProcessList;<br><br>var OS : TOperatingSystem;<br> OSReady : boolean = false;<br>function GetOperatingSystem : TOperatingSystem;<br>var os1 : TOSVersionInfo;<br>begin<br> if not OSReady then begin<br> OSReady:=true;<br> os1.dwOSVersionInfoSize:=sizeOf(os1); GetVersionEx(os1);<br> case os1.dwPlatformID of<br> VER_PLATFORM_WIN32s : OS:=osWin311;<br> VER_PLATFORM_WIN32_WINDOWS : if (os1.dwMajorVersion=4) and (os1.dwMinorVersion=0) then begin<br> if os1.dwBuildNumber>1000 then OS:=osWin95osr2 else OS:=osWin95;<br> end else if (os1.dwMajorVersion=4) and (os1.dwMinorVersion=10) then<br> OS:=osWin98<br> else OS:=osUnknown;<br> VER_PLATFORM_WIN32_NT : case os1.dwMajorVersion of<br> 0..3 : OS:=osWinNT3;<br> 4 : if string(os1.szCSDVersion)='Service Pack 4' then OS:=osWinNT4SP4<br> else OS:=osWinNT4;<br> 5 : OS:=osWinNT5;<br> end;<br> else OS:=osUnknown;<br> end;<br> end;<br> result:=OS;<br>end;<br><br>const MAX_MODULE_NAME32 = 255;<br>type<br> TProcessEntry32 = record<br> dwSize : DWORD;<br> cntUsage : DWORD;<br> th32ProcessID : DWORD; // this process<br> th32DefaultHeapID : DWORD;<br> th32ModuleID : DWORD; // associated exe<br> cntThreads : DWORD;<br> th32ParentProcessID : DWORD; // this process's parent process<br> pcPriClassBase : integer; // Base priority of process's threads<br> dwFlags : DWORD;<br> szExeFile : array [0..MAX_PATH-1] of char; // Path<br> end;<br> TThreadEntry32 = record<br> dwSize : DWORD;<br> cntUsage : DWORD;<br> th32ThreadID : DWORD; // this thread<br> th32OwnerProcessID : DWORD; // Process this thread is associated with<br> tpBasePri : integer;<br> tpDeltaPri : integer;<br> dwFlags : DWORD;<br> end;<br> TModuleEntry32 = record<br> dwSize : DWORD;<br> th32ModuleID : DWORD; // This module<br> th32ProcessID : DWORD; // owning process<br> GlblcntUsage : DWORD; // Global usage count on the module<br> ProccntUsage : DWORD; // Module usage count in th32ProcessID's context<br> modBaseAddr : pointer; // Base address of module in th32ProcessID's context<br> modBaseSize : DWORD; // Size in bytes of module starting at modBaseAddr<br> hModule : HMODULE; // The hModule of this module in th32ProcessID's context<br> szModule : array [0..MAX_MODULE_NAME32] of char;<br> szExePath : array [0..MAX_PATH-1] of char;<br> end;<br>const TH32CS_SnapProcess = 2;<br> TH32CS_SnapThread = 4;<br> TH32CS_SnapModule = 8;<br>var //PsApiHandle : cardinal = 0;<br> CreateToolhelp32Snapshot :<br> function (dwFlags,th32ProcessID: cardinal) : cardinal; stdcall<br> = nil;<br> Process32First :<br> function (hSnapshot: cardinal; var lppe: TProcessEntry32) : bool; stdcall<br> = nil;<br> Process32Next :<br> function (hSnapshot: cardinal; var lppe: TProcessEntry32) : bool; stdcall<br> = nil;<br> Thread32First :<br> function (hSnapshot: cardinal; var lpte: TThreadEntry32) : bool; stdcall<br> = nil;<br> Thread32Next :<br> function (hSnapshot: cardinal; var lpte: TThreadEntry32) : bool; stdcall<br> = nil;<br> Module32First :<br> function (hSnapshot: cardinal; var lpme: TModuleEntry32) : bool; stdcall<br> = nil;<br> Module32Next :<br> function (hSnapshot: cardinal; var lpme: TModuleEntry32) : bool; stdcall<br> = nil;<br> EnumProcesses :<br> function (idProcess: TPACardinal; cb: cardinal; var cbNeeded: cardinal) : bool; stdcall<br> = nil;<br> EnumProcessModules :<br> function (hProcess: cardinal; var hModule: cardinal; cb: cardinal; var cbNeeded: cardinal) : bool; stdcall<br> = nil;<br> GetModuleFileNameEx :<br> function (hProcess,hModule: cardinal; fileName: PChar; nSize: cardinal) : cardinal; stdcall<br> = nil;<br><br>function TestToolhelpFunctions : boolean;<br>var c1 : cardinal;<br>begin<br> c1:=GetModuleHandle('kernel32');<br> @CreateToolhelp32Snapshot:=GetProcAddress(c1,'CreateToolhelp32Snapshot');<br> @Process32First :=GetProcAddress(c1,'Process32First'  
;<br> @Process32Next :=GetProcAddress(c1,'Process32Next' );<br> @Thread32First :=GetProcAddress(c1,'Thread32First' );<br> @Thread32Next :=GetProcAddress(c1,'Thread32Next'  
;<br> @Module32First :=GetProcAddress(c1,'Module32First' );<br> @Module32Next :=GetProcAddress(c1,'Module32Next'  
;<br> result:=(@CreateToolhelp32Snapshot<>nil) and<br> (@Process32First<>nil) and (@Process32Next<>nil) and<br> (@Thread32First<>nil) and (@Thread32Next<>nil) and<br> (@Module32First<>nil) and (@Module32Next<>nil);<br>end;<br><br>{function TestPsApi : boolean;<br>begin<br> if PsApiHandle=0 then begin<br> PsApiHandle:=LoadLibrary('psapi');<br> result:=PsApiHandle<>0;<br> if result then begin<br> @EnumProcesses :=GetProcAddress(PsApiHandle,'EnumProcesses' );<br> @EnumProcessModules :=GetProcAddress(PsApiHandle,'EnumProcessModules'  
;<br> @GetModuleFileNameEx:=GetProcAddress(PsApiHandle,'GetModuleFileNameExA');<br> result:=(@EnumProcesses<>nil) and (@EnumProcessModules<>nil) and (@GetModuleFileNameEx<>nil);<br> end;<br> end else result:=true;<br>end;}<br><br>function GetExeType(exefile: string) : TExeType;<br>var c1 : cardinal;<br> sfi : TSHFileInfo;<br> s1 : string;<br>begin<br> c1:=SHGetFileInfo(pchar(exefile),0,sfi,SizeOf(sfi),SHGFI_EXETYPE);<br> s1:=chr(c1 and $ff)+chr((c1 and $ff00) shr 8);<br> if s1='MZ' then result:=etDos<br> else if s1='NE' then result:=etWin16<br> else if (s1='PE') and (hiWord(c1)=0) then result:=etConsole<br> else if (s1='PE') and (hiWord(c1)>0) then result:=etWin32<br> else if CompareText(AnsiUpperCase(ExtractFileName(exefile)),AnsiUpperCase('winoa386.mod'))=0 then result:=etDos<br> else result:=etUnknown;<br>end;<br><br>function NT4_EnumProcessesAndThreads(pl: TPProcessList; tl: TPThreadList; windowsToo: boolean) : boolean;<br>type TPerfDataBlock = packed record<br> signature : array [0..3] of wchar;<br> littleEndian : cardinal;<br> version : cardinal;<br> revision : cardinal;<br> totalByteLength : cardinal;<br> headerLength : cardinal;<br> numObjectTypes : cardinal;<br> defaultObject : cardinal;<br> systemTime : TSystemTime;<br> perfTime : comp;<br> perfFreq : comp;<br> perfTime100nSec : comp;<br> systemNameLength : cardinal;<br> systemnameOffset : cardinal;<br> end;<br> TPPerfDataBlock = ^TPerfDataBlock;<br><br> TPerfObjectType = packed record<br> totalByteLength : cardinal;<br> definitionLength : cardinal;<br> headerLength : cardinal;<br> objectNameTitleIndex : cardinal;<br> objectNameTitle : PWideChar;<br> objectHelpTitleIndex : cardinal;<br> objectHelpTitle : PWideChar;<br> detailLevel : cardinal;<br> numCounters : cardinal;<br> defaultCounter : integer;<br> numInstances : integer;<br> codePage : cardinal;<br> perfTime : comp;<br> perfFreq : comp;<br> end;<br> TPPerfObjectType = ^TPerfObjectType;<br><br> TPerfCounterDefinition = packed record<br> byteLength : cardinal;<br> counterNameTitleIndex : cardinal;<br> counterNameTitle : PWideChar;<br> counterHelpTitleIndex : cardinal;<br> counterHelpTitle : PWideChar;<br> defaultScale : integer;<br> defaultLevel : cardinal;<br> counterType : cardinal;<br> counterSize : cardinal;<br> counterOffset : cardinal;<br> end;<br> TPPerfCounterDefinition = ^TPerfCounterDefinition;<br><br> TPerfInstanceDefinition = packed record<br> byteLength : cardinal;<br> parentObjectTitleIndex : cardinal;<br> parentObjectInstance : cardinal;<br> uniqueID : integer;<br> nameOffset : cardinal;<br> nameLength : cardinal;<br> end;<br> TPPerfInstanceDefinition = ^TPerfInstanceDefinition;<br> TAPChar = array [0..maxInt div 4-1] of pchar;<br> TPCardinal = ^cardinal;<br>var i1,i2,i3,i4 : integer;<br> b1,b2,b3,b4 : boolean;<br> bt,bp : boolean;<br> c1 : cardinal;<br> pCard : TPCardinal;<br> perfDataBlock : TPPerfDataBlock;<br> perfObjectType : TPPerfObjectType;<br> perfCounterDef : TPPerfCounterDefinition;<br> perfInstanceDef : TPPerfInstanceDefinition;<br>begin<br> result:=false;<br> bt:=tl=nil; if not bt then tl^:=nil; bp:=pl=nil; if not bp then pl^:=nil;<br> if bt and bp then exit;<br> perfDataBlock:=nil;<br> try<br> i1:=$10000;<br> repeat<br> ReallocMem(perfDataBlock,i1); i2:=i1;<br> i4:=RegQueryValueEx(HKEY_PERFORMANCE_DATA,'230 232',nil,@i3,pointer(perfDataBlock),@i2);<br> if i4=ERROR_MORE_DATA then i1:=i1*2;<br> until (i4<>ERROR_MORE_DATA);<br> if i4<>ERROR_SUCCESS then exit;<br> perfObjectType:=pointer(cardinal(perfDataBlock)+perfDataBlock^.headerLength);<br> for i1:=0 to integer(perfDataBlock^.numObjectTypes)-1 do begin<br> b1:= (pl<>nil) and (perfObjectType^.objectNameTitleIndex=230); // 230 -> "Process"<br> b2:=(not b1) and (tl<>nil) and (perfObjectType^.objectNameTitleIndex=232); // 232 -> "Thread"<br> if b1 or b2 then begin<br> perfCounterDef:=pointer(cardinal(perfObjectType)+perfObjectType^.headerLength);<br> for i2:=0 to perfObjectType^.numCounters-1 do begin<br> b3:= perfCounterDef^.counterNameTitleIndex=784; // 784 -> "ID Process"<br> b4:=(not b3) and (perfCounterDef^.counterNameTitleIndex=804); // 804 -> "ID Thread"<br> if b3 or b4 then begin<br> perfInstanceDef:=pointer(cardinal(perfObjectType)+perfObjectType^.definitionLength);<br> if b1 then SetLength(pl^,perfObjectType^.numInstances-1)<br> else SetLength(tl^,perfObjectType^.numInstances-1);<br> for i3:=0 to perfObjectType^.numInstances-2 do begin<br> c1:=TPCardinal(cardinal(perfInstanceDef)+perfInstanceDef^.byteLength+perfCounterDef^.counterOffset)^;<br> if b1 then begin<br> pl^[i3].pid:=c1;<br> if c1<>0 then begin<br> pl^[i3].name:=wideString(PWideChar(cardinal(perfInstanceDef)+perfInstanceDef.nameOffset));<br> if pl^[i3].name<>'System' then pl^[i3].name:=pl^[i3].name+'.exe';<br> end else pl^[i3].name:='[System Process]';<br> end else if b3 then tl^[i3].pid:=c1 else tl^[i3].tid:=c1;<br> pCard:=pointer(cardinal(perfInstanceDef)+perfInstanceDef^.byteLength);<br> perfInstanceDef:=pointer(cardinal(pCard)+pCard^);<br> end;<br> end;<br> inc(perfCounterDef);<br> end;<br> bt:=bt or b2; bp:=bp or b1; if bt and bp then break;<br> end;<br> perfObjectType:=pointer(cardinal(perfObjectType)+perfObjectType^.totalByteLength);<br> end;<br> result:=((pl<>nil) and (pl^<>nil)) or ((tl<>nil) and (tl^<>nil));<br> if (tl<>nil) and windowsToo then<br> if windowsToo then<br> for i1:=0 to high(tl^) do<br> if (tl^[i1].pid<>0) then<br> tl^[i1].windows:=GetWindowList(tl^[i1].pid,tl^[i1].tid);<br> finally FreeMem(perfDataBlock) end;<br>end;<br><br>function GetProcessList(threadsToo: boolean = false; windowsToo: boolean = false) : TProcessList;<br>var c1 : cardinal;<br> i1,i2,i3,i4 : integer;<br> tl : TThreadList;<br> pe : TProcessEntry32;<br>begin<br> result:=nil;<br> if GetOperatingSystem in [osWin95,osWin95osr2,osWin98,osWinNT5] then begin<br> if not TestToolhelpFunctions then begin<br> MessageBox(0,'Toolhelp functions not available.','Error...',0);<br> exit;<br> end;<br> c1:=CreateToolHelp32Snapshot(TH32CS_SnapProcess,0);<br> try<br> i1:=0;<br> pe.dwSize:=sizeOf(pe);<br> if Process32First(c1,pe) then<br> repeat<br> SetLength(result,i1+1);<br> result[i1].pid:=pe.th32ProcessID; result[i1].name:=pe.szExeFile;<br> result[i1].exeType:=GetExeType(result[i1].name);<br> inc(i1);<br> until not Process32Next(c1,pe);<br> finally CloseHandle(c1) end;<br> if threadsToo then tl:=GetThreadList(0,windowsToo);<br> end else if GetOperatingSystem in [osWinNT3,osWinNT4,osWinNT4SP4] then<br> if ( threadsToo and (not NT4_EnumProcessesAndThreads(@result,@tl,windowsToo))) or <br> ((not threadsToo) and (not NT4_EnumProcessesAndThreads(@result,nil,false ))) then<br> MessageBox(0,'Error reading Performace Data.','Error...',0);<br>{ if not TestPsApi then begin<br> MessageBox(0,'"PsApi.dll" not found.','Error...',0);<br> exit;<br> end;<br> SetLength(s1,MAX_PATH+1);<br> SetLength(s1,GetModuleFileName(psApiHandle,pchar(s1),MAX_PATH));<br> c1:=100; SetLength(ac,c1);<br> if EnumProcesses(pointer(ac),4*c1,c2) then begin<br> while 4*c1=c2 do begin<br> inc(c1,100); SetLength(ac,c1); EnumProcesses(pointer(ac),4*c1,c2);<br> end;<br> SetLength(result,c2 div 4);<br> end;<br> for i1:=0 to high(result) do begin<br> result[i1].pid:=ac[i1];<br> c1:=OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ,false,ac[i1]);<br> if c1<>0 then<br> try<br><br> if EnumProcessModules(c1,c2,4,c3) then begin<br> SetLength(result[i1].name,MAX_PATH+1);<br> if GetModuleFileNameEx(c1,c2,PChar(result[i1].name),length(result[i1].name))<>0 then begin<br> result[i1].name:=string(PChar(result[i1].name));<br> result[i1].exeType:=GetExeType(result[i1].name);<br> end else begin result[i1].name:=''; result[i1].exeType:=etUnknown end;<br> end;<br> finally CloseHandle(c1) end;<br> end;<br> end; }<br> i4:=high(tl);<br> if i4>0 then<br> for i1:=0 to i4 do<br> for i2:=high(result) downto 0 do<br> if tl[i1].pid=result[i2].pid then begin<br> i3:=length(result[i2].threads); setLength(result[i2].threads,i3+1); result[i2].threads[i3]:=tl[i1];<br> end;<br>end;<br><br>function GetThreadList(pid: cardinal = 0; windowsToo: boolean = false) : TThreadList;<br>var c1 : cardinal;<br> i1 : integer;<br> te : TThreadEntry32;<br>begin<br> result:=nil;<br> if GetOperatingSystem in [osWin95,osWin95osr2,osWin98,osWinNT5] then begin<br> if not TestToolhelpFunctions then begin<br> MessageBox(0,'Toolhelp functions not available.','Error...',0);<br> exit;<br> end;<br> c1:=CreateToolHelp32Snapshot(TH32CS_SnapThread,0);<br> try<br> i1:=0;<br> te.dwSize:=sizeOf(te);<br> if Thread32First(c1,te) then<br> repeat<br> if (pid=0) or (pid=te.th32OwnerProcessID) then begin<br> SetLength(result,i1+1);<br> result[i1].tid:=te.th32ThreadID; result[i1].pid:=te.th32OwnerProcessID;<br> inc(i1);<br> end;<br> until not Thread32Next(c1,te);<br> finally CloseHandle(c1) end;<br> if windowsToo then<br> for i1:=0 to high(result) do<br> if (result[i1].pid<>0) then<br> result[i1].windows:=GetWindowList(result[i1].pid,result[i1].tid);<br> end else if GetOperatingSystem in [osWinNT3,osWinNT4,osWinNT4SP4] then<br> if not NT4_EnumProcessesAndThreads(nil,@result,windowsToo) then<br> MessageBox(0,'Error reading Performace Data.','Error...',0);<br>end;<br><br>var ew_pid, ew_tid : cardinal;<br> ew_onlyThoseInTaskbar : boolean;<br>function EnumWindowsProc(hwnd: cardinal; lParam: integer) : LongBool; stdcall;<br>var pwl : ^TWindowList;<br> i1 : integer;<br> cpid,ctid : cardinal;<br> cpar,cown : cardinal;<br> bvis,btsk : boolean;<br>begin<br> result:=true;<br> ctid:=GetWindowThreadProcessID(hwnd,@cpid);<br> if ((ew_pid=0) or (ew_pid=cpid)) and ((ew_tid=0) or (ew_tid=ctid)) then begin<br> bvis:=IsWindowVisible(hwnd);<br> cown:=GetWindow(hwnd,GW_OWNER); cpar:=GetParent(hwnd);<br> btsk:=(cown=0) and (cpar=0) and bvis and (GetWindowLong(hwnd,GWL_EXSTYLE) and WS_EX_TOOLWINDOW=0);<br> if (not ew_onlyThoseInTaskbar) or btsk then begin<br> pwl:=pointer(lParam);<br> i1:=length(pwl^);<br> SetLength(pwl^,i1+1);<br> with pwl^[i1] do begin<br> window:=hwnd;<br> parent:=cpar; owner:=cown;<br> visible:=bvis; enabled:=IsWindowEnabled(hwnd);<br> inTaskbar:=btsk;<br> GetWindowRect(hwnd,rect);<br> SetLength(title,MAX_PATH);<br> SetLength(title,GetWindowText(hwnd,pchar(title),MAX_PATH));<br> SetLength(className,MAX_PATH);<br> SetLength(className,GetClassName(hwnd,pchar(className),MAX_PATH));<br> pid:=cpid; tid:=ctid;<br> end;<br> end;<br> end;<br>end;<br><br>function GetWindowList(pid: cardinal = 0; tid: cardinal = 0; onlyThoseInTaskbar: boolean = false) : TWindowList;<br>begin<br> result:=nil;<br> ew_pid:=pid; ew_tid:=tid; ew_onlyThoseInTaskbar:=onlyThoseInTaskbar;<br> if ew_tid=0 then EnumWindows ( @EnumWindowsProc,integer(@result))<br> else EnumThreadWindows(ew_tid,@EnumWindowsProc,integer(@result));<br>end;<br><br>function GetChildWindowList(window: cardinal) : TWindowList;<br>begin<br> result:=nil;<br> ew_pid:=0; ew_tid:=0; ew_onlyThoseInTaskbar:=false;<br> EnumChildWindows(window,@EnumWindowsProc,integer(@result));<br>end;<br><br>function EnumWindowStationsProc(windowStationName: pchar; lParam: integer) : LongBool; stdcall;<br>var i1 : integer;<br> pwsl : ^TWindowStationList;<br>begin<br> result:=true;<br> pwsl:=pointer(lParam);<br> i1:=length(pwsl^);<br> SetLength(pwsl^,i1+1);<br> pwsl^[i1].name:=windowStationName;<br>end;<br><br>function GetWindowStationList(desktopsToo: boolean = false; windowsToo: boolean = false) : TWindowStationList;<br>var c1 : cardinal;<br> i1 : integer;<br>begin<br> result:=nil;<br> EnumWindowStations(@EnumWindowStationsProc,integer(@result));<br> if desktopsToo then<br> for i1:=0 to high(result) do begin<br> c1:=OpenWindowStation(pchar(result[i1].name),false,WINSTA_ENUMDESKTOPS);<br> if c1>0 then<br> try<br> result[i1].desktops:=GetDesktopList(c1,windowsToo);<br> finally CloseWindowStation(c1) end;<br> end;<br>end;<br><br>function EnumDesktopsProc(desktopName: pchar; lParam: integer) : LongBool; stdcall;<br>var i1 : integer;<br> pdl : ^TDesktopList;<br>begin<br> result:=true;<br> pdl:=pointer(lParam);<br> i1:=length(pdl^);<br> SetLength(pdl^,i1+1);<br> pdl^[i1].name:=desktopName;<br>end;<br><br>function GetDesktopList(ws: cardinal = 0; windowsToo: boolean = false) : TDesktopList;<br>var c1 : cardinal;<br> i1 : integer;<br>begin<br> result:=nil;<br> if ws=0 then ws:=GetProcessWindowStation;<br> EnumDesktops(ws,@EnumDesktopsProc,integer(@result));<br> if windowsToo then <br> for i1:=0 to high(result) do begin<br> c1:=OpenDesktop(pchar(result[i1].name),0,false,DESKTOP_READOBJECTS);<br> if c1>0 then<br> try<br> result[i1].windows:=GetDesktopWindowList(c1);<br> finally CloseDesktop(c1) end;<br> end;<br>end;<br><br>function GetDesktopWindowList(dt: cardinal = 0) : TWindowList;<br>begin<br> result:=nil;<br> if dt=0 then dt:=GetThreadDesktop(GetCurrentThreadID);<br> ew_pid:=0; ew_tid:=0; ew_onlyThoseInTaskbar:=false;<br> EnumDesktopWindows(dt,@EnumWindowsProc,integer(@result));<br>end;<br><br>{Button The class for a button.<br>ComboBox The class for a combo box.<br>Edit The class for an edit control.<br>ListBox The class for a list box.<br>MDIClient The class for an MDI client window.<br>ScrollBar The class for a scroll bar.<br>Static The class for a static control.<br><br><br>The following table describes the system classes that are available only for use by the system. They are listed here for completeness sake.<br><br>Class Description<br>ComboLBox The class for the list box contained in a combo box.<br>DDEMLEvent Windows NT: The class for DDEML events.<br>Message Windows NT 5.0 and later: The class for a message-only window.<br>#32768 The class for a menu.<br>#32769 The class for the desktop window.<br>#32770 The class for a dialog box.<br>#32771 The class for the task switch window.<br>#32772 Windows NT: The class for icon titles. }<br><br>type TPasswordCacheEntry = packed record<br> entry : word; // size of this entry, in bytes<br> resourceLen : word; // size of resource name, in bytes<br> passwordLen : word; // size of password, in bytes<br> entryIndex : byte; // entry index<br> entryType : byte; // type of entry<br> resource : array [0..$FFFFFFF] of char;<br> // start of resource name<br> // password immediately follows resource name<br> end;<br> TPPasswordCacheEntry = ^TPasswordCacheEntry;<br><br>function EnumPasswordCallbackProc(pce: TPPasswordCacheEntry; lParam: cardinal) : LongBool; stdcall;<br>var i1 : integer;<br> ppcl : ^TCachedPasswordList;<br>begin<br> result:=true;<br> ppcl:=pointer(lParam);<br> i1:=length(ppcl^);<br> SetLength(ppcl^,i1+1);<br> SetLength(ppcl^[i1].resource,pce^.resourceLen);<br> Move(pce^.resource[0],pointer(ppcl^[i1].resource)^,pce^.resourceLen);<br> ppcl^[i1].resource:=pchar(ppcl^[i1].resource);<br> SetLength(ppcl^[i1].password,pce^.passwordLen);<br> Move(pce^.resource[pce^.resourceLen],pointer(ppcl^[i1].password)^,pce^.passwordLen);<br> ppcl^[i1].password:=pchar(ppcl^[i1].password);<br> ppcl^[i1].resType:=pce^.entryType;<br>end;<br><br>var WNetEnumCachedPasswords : function (ps: pchar; pw: word; pb: byte; proc: pointer; lParam: cardinal) : word; stdcall<br> = nil;<br> mpr : cardinal = 0;<br><br>function GetCachedPasswords : TCachedPasswordList;<br>begin<br> result:=nil;<br> if mpr=0 then begin<br> mpr:=LoadLibrary('mpr');<br> if mpr=0 then exit;<br> end;<br> if @WNetEnumCachedPasswords=nil then begin<br> WNetEnumCachedPasswords:=GetProcAddress(mpr,'WNetEnumCachedPasswords');<br> if @WNetEnumCachedPasswords=nil then exit;<br> end;<br> WNetEnumCachedPasswords(nil,0,$FF,@EnumPasswordCallbackProc,cardinal(@result));<br>end;<br><br>initialization<br>finalization<br> if mpr <>0 then FreeLibrary(mpr  
;<br>// if psApiHandle<>0 then FreeLibrary(psApiHandle);<br>end.<br><br>