From this answer
CoInternetIsFeatureEnabled in Delphi2010
Does anyone know how to stop the clicking sound. That doesn't appear to work in Delphi XE when I drop it into a separate pas file. There is some missing . and other reasons why it wont compile so im a bit stuck.
Here's what I did.
unit untUrlMon;
interface
uses
Windows;
const
GET_FEATURE_FROM_THREAD = $00000001;
GET_FEATURE_FROM_PROCESS = $00000002;
GET_FEATURE_FROM_REGISTRY = $00000004;
GET_FEATURE_FROM_THREAD_LOCALMACHINE = $00000008;
GET_FEATURE_FROM_THREAD_INTRANET = $00000010;
GET_FEATURE_FROM_THREAD_TRUSTED = $00000020;
GET_FEATURE_FROM_THREAD_INTERNET = $00000040;
GET_FEATURE_FROM_THREAD_RESTRICTED = $00000080;
SET_FEATURE_ON_THREAD = $00000001;
SET_FEATURE_ON_PROCESS = $00000002;
SET_FEATURE_IN_REGISTRY = $00000004;
SET_FEATURE_ON_THREAD_LOCALMACHINE = $00000008;
SET_FEATURE_ON_THREAD_INTRANET = $00000010;
SET_FEATURE_ON_THREAD_TRUSTED = $00000020;
SET_FEATURE_ON_THREAD_INTERNET = $00000040;
SET_FEATURE_ON_THREAD_RESTRICTED = $00000080;
type
INTERNETFEATURELIST = (
FEATURE_OBJECT_CACHING,
FEATURE_ZONE_ELEVATION,
FEATURE_MIME_HANDLING,
FEATURE_MIME_SNIFFING,
FEATURE_WINDOW_RESTRICTIONS,
FEATURE_WEBOC_POPUPMANAGEMENT,
FEATURE_BEHAVIORS,
FEATURE_DISABLE_MK_PROTOCOL,
FEATURE_LOCALMACHINE_LOCKDOWN,
FEATURE_SECURITYBAND,
FEATURE_RESTRICT_ACTIVEXINSTALL,
FEATURE_VALIDATE_NAVIGATE_URL,
FEATURE_RESTRICT_FILEDOWNLOAD,
FEATURE_ADDON_MANAGEMENT,
FEATURE_PROTOCOL_LOCKDOWN,
FEATURE_HTTP_USERNAME_PASSWORD_DISABLE,
FEATURE_SAFE_BINDTOOBJECT,
FEATURE_UNC_SAVEDFILECHECK,
FEATURE_GET_URL_DOM_FILEPATH_UNENCODED,
FEATURE_TABBED_BROWSING,
FEATURE_SSLUX,
FEATURE_DISABLE_NAVIGATION_SOUNDS,
FEATURE_DISABLE_LEGACY_COMPRESSION,
FEATURE_FORCE_ADDR_AND_STATUS,
FEATURE_XMLHTTP,
FEATURE_DISABLE_TELNET_PROTOCOL,
FEATURE_FEEDS,
FEATURE_BLOCK_INPUT_PROMPTS,
FEATURE_ENTRY_COUNT
);
function CoInternetIsFeatureEnabled(FeatureEntry: INTERNETFEATURELIST; dwFlags: DWORD): HRESULT; stdcall; external 'urlmon.dll'
implementation
function CoInternetSetFeatureEnabled(FeatureEntry: INTERNETFEATURELIST; dwFlags: DWORD; fEnable: BOOL): HRESULT; stdcall; external 'urlmon.dll'
begin
if CoInternetIsFeatureEnabled(FEATURE_DISABLE_NAVIGATION_SOUNDS, GET_FEATURE_FROM_PROCESS) = S_FALSE then
CoInternetSetFeatureEnabled(FEATURE_DISABLE_NAVIGATION_SOUNDS, SET_FEATURE_ON_PROCESS, True);
end;
I'd imagine you need something like this:
unit untUrlMon;
implementation
uses
Windows;
const
SET_FEATURE_ON_PROCESS = $00000002;
FEATURE_DISABLE_NAVIGATION_SOUNDS = 21;
function CoInternetSetFeatureEnabled(FeatureEntry: DWORD; dwFlags: DWORD; fEnable: BOOL): HRESULT; stdcall; external 'urlmon.dll';
initialization
CoInternetSetFeatureEnabled(FEATURE_DISABLE_NAVIGATION_SOUNDS, SET_FEATURE_ON_PROCESS, True);
end.
If you replace the final "end;" with "end." it should compile.
I believe you also need ";" after the two function declarations (after the "external 'urlmon.dll'" part).
The final "begin/end" is then run automatically in every program you include this unit in.
Related
I want to call windows API: GetNativeSystemInfo at Inno Setup iss file, so I do not have to call an external DLL to detect ARM processor architecture.
But I don't know how to add it...
Could someone show me how to import and use that functionality in an Inno script???
Thank you!
The API declaration:
type
TSystemInfo = record
wProcessorArchitecture: Word;
wReserved: Word;
dwPageSize: DWORD;
lpMinimumApplicationAddress: Cardinal;
lpMaximumApplicationAddress: Cardinal;
dwActiveProcessorMask: DWORD_PTR;
dwNumberOfProcessors: DWORD;
dwProcessorType: DWORD;
dwAllocationGranularity: DWORD;
wProcessorLevel: Word;
wProcessorRevision: Word;
end;
const
PROCESSOR_ARCHITECTURE_INTEL = 0;
PROCESSOR_ARCHITECTURE_MIPS = 1;
PROCESSOR_ARCHITECTURE_ALPHA = 2;
PROCESSOR_ARCHITECTURE_PPC = 3;
PROCESSOR_ARCHITECTURE_SHX = 4;
PROCESSOR_ARCHITECTURE_ARM = 5;
PROCESSOR_ARCHITECTURE_IA64 = 6;
PROCESSOR_ARCHITECTURE_ALPHA64 = 7;
PROCESSOR_ARCHITECTURE_MSIL = 8;
PROCESSOR_ARCHITECTURE_AMD64 = 9;
PROCESSOR_ARCHITECTURE_IA32_ON_WIN64 = 10;
procedure GetNativeSystemInfo(var lpSystemInformation: TSystemInfo);
external 'GetNativeSystemInfo#Kernel32.dll stdcall';
And use:
var
SystemInfo: TSystemInfo;
begin
GetNativeSystemInfo(SystemInfo);
if SystemInfo.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_ARM then
begin
{ ... }
end;
end;
I'd like to be able to use the UrlCreateFromPathW function from Shlwapi.dll in my installer script, but I haven't been able to get it to work.
HRESULT UrlCreateFromPath(
_In_ PCTSTR pszPath,
_Out_ PTSTR pszUrl,
_Inout_ DWORD *pcchUrl,
DWORD dwFlags
);
I've cobbled together the following from other "Inno Setup" tagged questions here, and from glancing at the JEDI translation for the DLL. TryUrlCreateFromPath always returns false. Any assistance would be much appreciated.
[Code]
const
INTERNET_MAX_URL_LENGTH = 2048 + 32 + 3;
S_OK = $00000000;
function UrlCreateFromPathW(pszPath, pszUrl: string; var pcchUrl: DWORD; dwFlags: DWORD): HResult; external 'UrlCreateFromPathW#Shlwapi.dll stdcall';
function TryUrlCreateFromPath(const path: string; var url: string): Boolean;
var
charcount: dword;
flags: dword;
begin
SetLength(url, INTERNET_MAX_URL_LENGTH);
flags := 0;
Result := UrlCreateFromPathW(path, url, charcount, flags) = S_OK;
if Result then
SetLength(url, charcount);
end;
function InitializeSetup: Boolean;
var
URL: string;
ErrorCode: Integer;
begin
Result := True;
if TryUrlCreateFromPath('c:\temp', URL) then
MsgBox('URL: ' + URL, mbConfirmation, MB_OK)
else
MsgBox('ERROR', mbError, MB_OK);
end;
The pcchUrl is an in/out argument. On input, it must contain a number of characters allocated in the pszUrl.
You do not initialize it. It most likely defaults to 0, hence the UrlCreateFromPath returns E_INVALIDARG.
Initialize it like:
charcount := INTERNET_MAX_URL_LENGTH;
I was looking for a solution to prevent a laptop with win7 from hibernate because any operation is done every some hours and I have no admin rights to change the energy saver menu. Anyway, I tried it with free pascal (Lazarus) like this:
procedure TForm1.Timer2StartTimer(Sender: TObject);
var MousePos: TPoint;
begin
begin
getCursorPos(MousePos);
MousePos.x > 800 then Windows.SetCursorPos(10, 10); ;
MousePos.X := (Mouse.CursorPos.x)+1 ;
MousePos.Y := (Mouse.CursorPos.y)+1 ;
Mouse.CursorPos := MousePos;
end;
end;
It makes the mouse move as expected and wanted, but the laptop still falls asleep. So I googled and found http://www.script-example.com/themen/Bildschirmschoner-verhindern.php. I used the application presented there and it worked. The laptop doesnt go to sleep although the application isnt doing anything else then me.
could anybody tell me how to manage that with free pascal? thanks a lot.
You can use the Windows API function "SetThreadExecutionState" to reset the idle timer that Windows uses to decide when to show a screen saver or put the computer to sleep.
Use the following declarations to use the API:
const
ES_SYSTEM_REQUIRED = DWORD($00000001);
{$EXTERNALSYM ES_SYSTEM_REQUIRED}
ES_DISPLAY_REQUIRED = DWORD($00000002);
{$EXTERNALSYM ES_DISPLAY_REQUIRED}
ES_USER_PRESENT = DWORD($00000004);
{$EXTERNALSYM ES_USER_PRESENT}
ES_CONTINUOUS = DWORD($80000000);
{$EXTERNALSYM ES_CONTINUOUS}
ES_AWAYMODE_REQUIRED = DWORD($00000040);
{$EXTERNALSYM ES_AWAYMODE_REQUIRED}
type
EXECUTION_STATE = DWORD;
function SetThreadExecutionState(esFlags: EXECUTION_STATE): EXECUTION_STATE; stdcall; external 'kernel32.dll';
Then use a TTimer set to an appropriate Interval value and in the OnTimer event, call
SetThreadExecutionState(ES_SYSTEM_REQUIRED);
For details on the background, see this documentation on MSDN: https://msdn.microsoft.com/en-us/library/windows/desktop/aa373233%28v=vs.85%29.aspx
This works on Lazarus 1.4.4 with FPC 2.6.4:
[...]
implementation
{$R *.lfm}
const
ES_SYSTEM_REQUIRED = DWORD($00000001);
{$EXTERNALSYM ES_SYSTEM_REQUIRED}
ES_DISPLAY_REQUIRED = DWORD($00000002);
{$EXTERNALSYM ES_DISPLAY_REQUIRED}
ES_USER_PRESENT = DWORD($00000004);
{$EXTERNALSYM ES_USER_PRESENT}
ES_CONTINUOUS = DWORD($80000000);
{$EXTERNALSYM ES_CONTINUOUS}
ES_AWAYMODE_REQUIRED = DWORD($00000040);
{$EXTERNALSYM ES_AWAYMODE_REQUIRED}
type
EXECUTION_STATE = DWORD;
function SetThreadExecutionState(esFlags: EXECUTION_STATE): EXECUTION_STATE; stdcall; external 'kernel32.dll';
{ TForm1 }
procedure TForm1.Timer1Timer(Sender: TObject);
begin
// Prevent Screensaver
SetThreadExecutionState(ES_DISPLAY_REQUIRED);
// Prevent Standby or Hibernate
SetThreadExecutionState(ES_SYSTEM_REQUIRED);
end;
I need to get a fully qualified domain name for a Windows machine on a domain in Delphi.
I've tried to use LookupAccountSid but it gives me only the netbios domain name,
in my case it is "intranet" but I need the full "intranet.companyname.com"
Any Ideas?
Try the GetUserNameEx Windows API function.
const
NameUnknown = 0;
NameFullyQualifiedDN = 1;
NameSamCompatible = 2;
NameDisplay = 3;
NameUniqueId = 6;
NameCanonical = 7;
NameUserPrincipal = 8;
NameCanonicalEx = 9;
NameServicePrincipal = 10;
NameDnsDomain = 12;
function GetUserNameExString(ANameFormat: DWORD): string;
var
Buf: array[0..256] of Char;
BufSize: DWORD;
GetUserNameEx: function (NameFormat: DWORD; lpNameBuffer: LPSTR;
var nSize: ULONG): BOOL; stdcall;
begin
Result := '';
BufSize := SizeOf(Buf) div SizeOf(Buf[0]);
GetUserNameEx := GetProcAddress(GetModuleHandle('secur32.dll'), 'GetUserNameExA');
if Assigned(GetUserNameEx) then
if GetUserNameEx(ANameFormat, Buf, BufSize) then
Result := Buf;
end;
using the NameDnsDomain format for example, will result www.mydomain.com\user_name if you are logged into "www.mydomain.com" domain.
Since I now implemented this for my own needs in our application, #iPath's comment was quit right. better use GetComputerNameEx, and specify one of the COMPUTER_NAME_FORMAT for your own needs.
A Delphi implementation would look like this (Unicode version):
interface
...
type
COMPUTER_NAME_FORMAT = (
ComputerNameNetBIOS,
ComputerNameDnsHostname,
ComputerNameDnsDomain,
ComputerNameDnsFullyQualified,
ComputerNamePhysicalNetBIOS,
ComputerNamePhysicalDnsHostname,
ComputerNamePhysicalDnsDomain,
ComputerNamePhysicalDnsFullyQualified,
ComputerNameMax);
function GetComputerNameExString(ANameFormat: COMPUTER_NAME_FORMAT): WideString;
implementation
...
function GetComputerNameExW(NameType: COMPUTER_NAME_FORMAT; lpBuffer: LPWSTR;
var nSize: DWORD): BOOL; stdcall; external kernel32 name 'GetComputerNameExW';
function GetComputerNameExString(ANameFormat: COMPUTER_NAME_FORMAT): WideString;
var
nSize: DWORD;
begin
nSize := 1024;
SetLength(Result, nSize);
if GetComputerNameExW(ANameFormat, PWideChar(Result), nSize) then
SetLength(Result, nSize)
else
Result := '';
end;
NetGetJoinInformation should work fine.
MSDN:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa370423(v=vs.85).aspx
Example:
type
PWKSTA_INFO_100 = ^WKSTA_INFO_100;
WKSTA_INFO_100 = packed record
wki100_platform_id: DWord;
wki100_computername: PWChar;
wki100_langroup: PWChar;
wki100_ver_major: DWord;
wki100_ver_minor: DWord;
end;
TNetSetupJoinStatus =
(
NetSetupUnknownStatus,
NetSetupUnjoined,
NetSetupWorkgroupName,
NetSetupDomainName
);
TNetApiBufferFreeFunction = function(ABuffer: Pointer): DWORD; stdcall;
TNetWkstaGetInfoFunction = function(const AServername: PWChar; const ALevel: DWord; const ABufptr: Pointer): DWORD; stdcall;
TNetGetJoinInformationFunction = function(const AServerName: PWChar; out ANameBuffer: PWChar; out ABufferType: TNetSetupJoinStatus): DWORD; stdcall;
const
NERR_SUCCESS = 0;
function GetLocalComputerDomainName: string;
var
NetApiBuffer: Pointer;
NetApi: THandle;
NetApiBufferFree: TNetApiBufferFreeFunction;
NetWkstaGetInfo: TNetWkstaGetInfoFunction;
NetGetJoinInformation: TNetGetJoinInformationFunction;
NetSetupJoinStatus: TNetSetupJoinStatus;
NameBuffer: PWideChar;
begin
Result := '';
NetApi := LoadLibrary('netapi32.dll');
if NetApi <> 0 then
begin
NetApiBufferFree := TNetApiBufferFreeFunction( GetProcAddress(NetApi, 'NetApiBufferFree'));
NetGetJoinInformation := TNetGetJoinInformationFunction(GetProcAddress(NetApi, 'NetGetJoinInformation'));
NetWkstaGetInfo := TNetWkstaGetInfoFunction( GetProcAddress(NetApi, 'NetWkstaGetInfo'));
if #NetApiBufferFree <> nil then
begin
if #NetSetupJoinStatus <> nil then
begin
if NetGetJoinInformation(nil, NameBuffer, NetSetupJoinStatus) = NERR_SUCCESS then
begin
if NetSetupJoinStatus = NetSetupDomainName then
begin
Result := NameBuffer;
end;
NetApiBufferFree(NameBuffer);
end;
end;
end;
FreeLibrary(NetApi);
end;
end;
I tried all of the above, but without success. In the end, I settled for simply grabbing the environment variable.
uses jclSysInfo;
function GetDomain:string;
begin
result:=GetEnvironmentVariable('USERDNSDOMAIN');
end;
Tested on Server 2008 R2 - works fine. Returns "server.home.lan".
Results in an empty string on a Windows 7 non-domain connected PC.
The only correct api to use is DsGetDcName.
Because NetGetJoinInformation is still from the 'lanmanager age' so, the domain is LM compliant.
The code here is C, but you are smart enough to do the same in Delphi :)
PDOMAIN_CONTROLLER_INFOW pdomInfo ;
auto result1 = ::DsGetDcNameW(nullptr, nullptr, nullptr, nullptr, DS_DIRECTORY_SERVICE_PREFERRED | DS_RETURN_DNS_NAME, &pdomInfo);
if (result1 == ERROR_SUCCESS) {
auto retVal = SysAllocString(pdomInfo->DomainName);
::NetApiBufferFree(pdomInfo);
}
Using the standard win32 api, what's the best way to detect more than one user is logged on? I have an upgrade to our software product that can't be run when more than one user is logged in. (I know this is something to be avoided because of its annoyance factor, but the product is very complicated. You'll have to trust me when I say there really is no other solution.) Thanks.
In order to have more than one user logged in at once, Terminal Services or Fast User Switching must be enabled. Since Fast User Switching is implemented using Terminal Services, you first need to find out if the OS has it enabled. You can use GetVersionEx with an OSVERSIONINFOEX. Check for the VER_SUITE_SINGLEUSERTS and VER_SUITE_TERMINAL flags.
If TS is enabled, you can use WTSEnumerateSessions to find out how many users are logged on. This only works if the "Terminal Services" service is started.
If the machine doesn't support Terminal Services (or if the service isn't started), then you can only have one user logged on.
Here's a solution that works on XP, Server 2003, Vista, and Server 2008. Note, this won't work on Windows 2000, because "LsaEnumerateLogonSessions" is not available on Windows 2000. This code is modified from a Delphi-PRAXIS post.
To compile this, create a new VCL application with a TButton and a TMemo on the form. Then copy and paste this code and it should compile. I tested on XP and Vista and it works well. It will return interactive and remote users.
unit main;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
const
WTS_CURRENT_SERVER_HANDLE = 0;
type
PTOKEN_USER = ^TOKEN_USER;
_TOKEN_USER = record
User: TSidAndAttributes;
end;
TOKEN_USER = _TOKEN_USER;
USHORT = word;
_LSA_UNICODE_STRING = record
Length: USHORT;
MaximumLength: USHORT;
Buffer: LPWSTR;
end;
LSA_UNICODE_STRING = _LSA_UNICODE_STRING;
PLuid = ^LUID;
_LUID = record
LowPart: DWORD;
HighPart: LongInt;
end;
LUID = _LUID;
_SECURITY_LOGON_TYPE = (
seltFiller0, seltFiller1,
Interactive,
Network,
Batch,
Service,
Proxy,
Unlock,
NetworkCleartext,
NewCredentials,
RemoteInteractive,
CachedInteractive,
CachedRemoteInteractive);
SECURITY_LOGON_TYPE = _SECURITY_LOGON_TYPE;
PSECURITY_LOGON_SESSION_DATA = ^SECURITY_LOGON_SESSION_DATA;
_SECURITY_LOGON_SESSION_DATA = record
Size: ULONG;
LogonId: LUID;
UserName: LSA_UNICODE_STRING;
LogonDomain: LSA_UNICODE_STRING;
AuthenticationPackage: LSA_UNICODE_STRING;
LogonType: SECURITY_LOGON_TYPE;
Session: ULONG;
Sid: PSID;
LogonTime: LARGE_INTEGER;
LogonServer: LSA_UNICODE_STRING;
DnsDomainName: LSA_UNICODE_STRING;
Upn: LSA_UNICODE_STRING;
end;
SECURITY_LOGON_SESSION_DATA = _SECURITY_LOGON_SESSION_DATA;
_WTS_INFO_CLASS = (
WTSInitialProgram,
WTSApplicationName,
WTSWorkingDirectory,
WTSOEMId,
WTSSessionId,
WTSUserName,
WTSWinStationName,
WTSDomainName,
WTSConnectState,
WTSClientBuildNumber,
WTSClientName,
WTSClientDirectory,
WTSClientProductId,
WTSClientHardwareId,
WTSClientAddress,
WTSClientDisplay,
WTSClientProtocolType);
WTS_INFO_CLASS = _WTS_INFO_CLASS;
_WTS_CONNECTSTATE_CLASS = (
WTSActive, // User logged on to WinStation
WTSConnected, // WinStation connected to client
WTSConnectQuery, // In the process of connecting to client
WTSShadow, // Shadowing another WinStation
WTSDisconnected, // WinStation logged on without client
WTSIdle, // Waiting for client to connect
WTSListen, // WinStation is listening for connection
WTSReset, // WinStation is being reset
WTSDown, // WinStation is down due to error
WTSInit); // WinStation in initialization
WTS_CONNECTSTATE_CLASS = _WTS_CONNECTSTATE_CLASS;
function LsaFreeReturnBuffer(Buffer: pointer): Integer; stdcall;
function WTSGetActiveConsoleSessionId: DWORD; external 'Kernel32.dll';
function LsaGetLogonSessionData(LogonId: PLUID;
var ppLogonSessionData: PSECURITY_LOGON_SESSION_DATA): LongInt; stdcall;
external 'Secur32.dll';
function LsaNtStatusToWinError(Status: cardinal): ULONG; stdcall;
external 'Advapi32.dll';
function LsaEnumerateLogonSessions(Count: PULONG; List: PLUID): LongInt;
stdcall; external 'Secur32.dll';
function WTSQuerySessionInformationA(hServer: THandle; SessionId: DWORD;
WTSInfoClass: WTS_INFO_CLASS; var pBuffer: Pointer;
var pBytesReturned: DWORD): BOOL; stdcall; external 'Wtsapi32.dll';
type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
function LsaFreeReturnBuffer; external 'secur32.dll' name 'LsaFreeReturnBuffer';
procedure GetActiveUserNames(var slUserList : TStringList);
var
Count: cardinal;
List: PLUID;
sessionData: PSECURITY_LOGON_SESSION_DATA;
i1: integer;
SizeNeeded, SizeNeeded2: DWORD;
OwnerName, DomainName: PChar;
OwnerType: SID_NAME_USE;
pBuffer: Pointer;
pBytesreturned: DWord;
sUser : string;
begin
//result:= '';
//Listing LogOnSessions
i1:= lsaNtStatusToWinError(LsaEnumerateLogonSessions(#Count, #List));
try
if i1 = 0 then
begin
i1:= -1;
if Count > 0 then
begin
repeat
inc(i1);
LsaGetLogonSessionData(List, sessionData);
//Checks if it is an interactive session
sUser := sessionData.UserName.Buffer;
if (sessionData.LogonType = Interactive)
or (sessionData.LogonType = RemoteInteractive)
or (sessionData.LogonType = CachedInteractive)
or (sessionData.LogonType = CachedRemoteInteractive) then
begin
//
SizeNeeded := MAX_PATH;
SizeNeeded2:= MAX_PATH;
GetMem(OwnerName, MAX_PATH);
GetMem(DomainName, MAX_PATH);
try
if LookupAccountSID(nil, sessionData.SID, OwnerName,
SizeNeeded, DomainName,SizeNeeded2,
OwnerType) then
begin
if OwnerType = 1 then //This is a USER account SID (SidTypeUser=1)
begin
sUser := AnsiUpperCase(sessionData.LogonDomain.Buffer);
sUser := sUser + '\';
sUser := sUser + AnsiUpperCase(sessionData.UserName.Buffer);
slUserList.Add(sUser);
// if sessionData.Session = WTSGetActiveConsoleSessionId then
// begin
// //Wenn Benutzer aktiv
// try
// if WTSQuerySessionInformationA
// (WTS_CURRENT_SERVER_HANDLE,
// sessionData.Session, WTSConnectState,
// pBuffer,
// pBytesreturned) then
// begin
// if WTS_CONNECTSTATE_CLASS(pBuffer^) = WTSActive then
// begin
// //result:= sessionData.UserName.Buffer;
// slUserList.Add(sessionData.UserName.Buffer);
// end;
// end;
// finally
// LSAFreeReturnBuffer(pBuffer);
// end;
//end;
end;
end;
finally
FreeMem(OwnerName);
FreeMem(DomainName);
end;
end;
inc(List);
try
LSAFreeReturnBuffer(sessionData);
except
end;
until (i1 = Count-1);// or (result <> '');
end;
end;
finally
LSAFreeReturnBuffer(List);
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
slUsers : TStringList;
begin
slUsers := TStringList.Create;
slUsers.Duplicates := dupIgnore;
slUsers.Sorted := True;
try
GetActiveUserNames(slUsers);
Memo1.Lines.AddStrings(slUsers);
finally
FreeAndNil(slUsers)
end;
end;
end.
This might be a roundabout way, but run down the process list and see who the process owners are.