1) Je gaat toch de code moeten herschrijven, en dat lijkt me een stuk makkelijker en aangenamer als je de in het .NET framework aanwezige klassen gebruikt (die doen namelijk al wat jij probeert
2) Zou zoiets moeten zijn (ServiceInfo record is hier de managed versie van het record of de klasse die overeenstemt met jouw TQueryServiceConfig).
Code:
implementation
uses System.Runtime.InteropServices;
{$AUTOBOX ON}
const
GENERIC_ALL: integer = $10000000;
QUERY_CONFIG: integer = $1;
CHANGE_CONFIG:integer = $2;
type
// wat we meegeven
[StructLayout(LayoutKind.Sequential)]
QueryServiceConfigStruct = packed record
public
serviceType: Integer;
startType: Integer;
errorControl: Integer;
binaryPathName: IntPtr;
loadOrderGroup: IntPtr;
tagID: Integer;
dependencies: IntPtr;
startName: IntPtr;
displayName: IntPtr;
end;
//wat we opvullen
ServiceInfo = record
public
serviceType: Integer;
startType: Integer;
errorControl: Integer;
binaryPathName: string;
loadOrderGroup: string;
tagID: Integer;
dependencies: string;
startName: string;
displayName: string;
end;
[DllImport('advapi32.dll', SetLastError=True, CharSet=CharSet.Auto)]
class function QueryServiceConfig(
service: IntPtr; queryServiceConfig: IntPtr;
bufferSize: Integer; var bytesNeeded: Integer): Integer;external;
[DllImport('advapi32.dll', SetLastError=True, CharSet=CharSet.Auto)]
class function OpenSCManager(machineName: string; databaseName: string;
desiredAccess: Integer): IntPtr;external;
[DllImport('advapi32.dll', SetLastError=True, CharSet=CharSet.Auto)]
class function OpenService(scManager: IntPtr; serviceName: string;
desiredAccess: Integer): IntPtr;external;
class function GetServiceInfo(ServiceName: string): ServiceInfo;
var
retCode: Integer;
qscPtr: IntPtr;
qscs: QueryServiceConfigStruct;
bytesNeeded: Integer;
service: IntPtr;
scManager: IntPtr;
begin
scManager := OpenSCManager('.', nil, GENERIC_ALL);
if (scManager.ToInt32 <= 0) then
raise Win32Exception.Create;
service := OpenService(scManager, ServiceName, QUERY_CONFIG);
if (service.ToInt32 <= 0) then
raise NullReferenceException.Create;
bytesNeeded := 5;
qscPtr := Marshal.AllocCoTaskMem(0);
retCode := QueryServiceConfig(service, qscPtr, 0, bytesNeeded);
if ((retCode = 0) and (bytesNeeded = 0)) then
raise Win32Exception.Create
else
begin
qscPtr := Marshal.AllocCoTaskMem(bytesNeeded);
retCode := QueryServiceConfig(service, qscPtr, bytesNeeded, bytesNeeded);
if (retCode = 0) then
raise Win32Exception.Create;
qscs.binaryPathName := IntPtr.Zero;
qscs.dependencies := IntPtr.Zero;
qscs.displayName := IntPtr.Zero;
qscs.loadOrderGroup := IntPtr.Zero;
qscs.startName := IntPtr.Zero;
qscs := QueryServiceConfigStruct(
Marshal.PtrToStructure(
qscPtr, TypeOf(QueryServiceConfigStruct)));
end;
Result.binaryPathName := Marshal.PtrToStringAuto(qscs.binaryPathName);
Result.dependencies := Marshal.PtrToStringAuto(qscs.dependencies);
Result.displayName := Marshal.PtrToStringAuto(qscs.displayName);
Result.loadOrderGroup := Marshal.PtrToStringAuto(qscs.loadOrderGroup);
Result.startName := Marshal.PtrToStringAuto(qscs.startName);
Result.errorControl := qscs.errorControl;
Result.serviceType := qscs.serviceType;
Result.startType := qscs.startType;
Result.tagID := qscs.tagID;
Marshal.FreeCoTaskMem(qscPtr);
end;
Bookmarks