The DataSnap SocketServer service starts normally on an English version of Windows but not on a Non-English version. The reason for this is a hardwired username that is used if the service is started under the “LocalSystem” account. To resolve the issue, the locale specific LocalSystem username needs to be retrieved.
These are the modification that need to the done to the “ScktSrvr.dpr” which is in the ($Delphi) \Source\Vcl directory for Delphi 7 or in the $(BDS)\ source\Win32\db for the later versions. Once the service is re-built it will work as normal.
function LocalSystemUserName : string;
const
SECURITY_LOCAL_SYSTEM_RID :DWORD = $00000012;
SECURITY_NT_AUTHORITY : SID_IDENTIFIER_AUTHORITY = (Value:(0,0,0,0,0,5));
var
sia : SID_IDENTIFIER_AUTHORITY;
NameSize,
DomainSize: DWORD;
pAccountSid : PSID;
UsrName,DomainName : string;
SidNameUse : SID_NAME_USE;
begin
Result := 'SYSTEM';
sia := SECURITY_NT_AUTHORITY;
Win32Check(AllocateAndInitializeSid(sia,1,SECURITY_LOCAL_SYSTEM_RID,
0, 0, 0, 0, 0, 0, 0, pAccountSid));
if pAccountSid <> nil then
try
NameSize := 0;
DomainSize := 0;
LookupAccountSID(nil, pAccountSid, nil, NameSize, nil, DomainSize, SidNameUse);
if (GetLastError = $7A) and ((NameSize > 0) and (DomainSize > 0)) then
begin
SetLength(UsrName,NameSize);
SetLength(DomainName,DomainSize);
Win32Check(LookupAccountSID(nil, pAccountSid,PChar(UsrName), NameSize,
PChar(DomainName), DomainSize, SidNameUse));
SetLength(UsrName,NameSize);
Result := UsrName;
end;
finally
FreeSid(pAccountSid);
end;
end;
function StartService: Boolean;
var
Mgr, Svc: Integer;
UserName, ServiceStartName: string;
Config: Pointer;
Size: DWord;
begin
Result := False;
Mgr := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
if Mgr <> 0 then
begin
Svc := OpenService(Mgr, PChar(SServiceName), SERVICE_ALL_ACCESS);
Result := Svc <> 0;
if Result then
begin
QueryServiceConfig(Svc, nil, 0, Size);
Config := AllocMem(Size);
try
QueryServiceConfig(Svc, Config, Size, Size);
ServiceStartName := PQueryServiceConfig(Config)^.lpServiceStartName;
if CompareText(ServiceStartName, 'LocalSystem') = 0 then
ServiceStartName := LocalSystemUserName;
Size := 256;
SetLength(UserName, Size);
GetUserName(PChar(UserName), Size);
SetLength(UserName, StrLen(PChar(UserName)));
Result := CompareText(UserName, ServiceStartName) = 0;
finally
Dispose(Config);
end;
CloseServiceHandle(Svc);
end;
CloseServiceHandle(Mgr);
end;
end;
Author: Roy Nelson