program pipeserver;
{$APPTYPE CONSOLE}
uses
jwawinbase, jwawintype, jwawinnt, jwaaccctrl, jwaaclapi, jwawinerror, sysutils;
function InstanceThread(PipeHandle : dword) : dword;
stdcall;
var
Value : dword;
tmp : dword;
begin
result := 0;
ReadFile(PipeHandle, @Value, 4, @tmp,
nil);
WriteFile(PipeHandle, @Value, 4, @tmp,
nil);
FlushFileBuffers(PipeHandle);
DisconnectNamedPipe(PipeHandle);
CloseHandle(PipeHandle);
end;
function ServerThread(unused : dword) : dword;
stdcall;
const
BUFSIZE = 4;
var
PipeHandle : dword;
Connected : boolean;
SA : LPSECURITY_ATTRIBUTES;
ACL : PACL;
Group : TRUSTEE;
EA : PEXPLICIT_ACCESS;
SD : PSECURITY_DESCRIPTOR;
ACL_SIZE : ACL_SIZE_INFORMATION;
WellKnownSID : PSID;
tmp : dword;
begin
tmp := SECURITY_MAX_SID_SIZE;
GetMem(WellKnownSID, tmp);
CreateWellKnownSid(WinWorldSid,
nil, WellKnownSID, tmp);
Group.MultipleTrusteeOperation := NO_MULTIPLE_TRUSTEE;
Group.pMultipleTrustee :=
nil;
Group.ptstrName := Pointer(WellKnownSID);
Group.TrusteeForm := TRUSTEE_IS_SID;
Group.TrusteeType := TRUSTEE_IS_WELL_KNOWN_GROUP;
new(EA);
EA^.grfAccessMode := GRANT_ACCESS;
EA^.grfAccessPermissions := GENERIC_READ
or GENERIC_WRITE;
EA^.grfInheritance := NO_INHERITANCE;
EA^.Trustee := group;
SetEntriesInAcl(1, EA,
nil,
ACL);
GetAclInformation(
ACL, @ACL_SIZE, sizeof(ACL_SIZE), AclSizeInformation);
getmem(SD, SECURITY_DESCRIPTOR_MIN_LENGTH + ACL_SIZE.AclBytesFree + ACL_SIZE.AclBytesInUse);
InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(sd, TRUE,
ACL, FALSE);
new(SA);
sa^.bInheritHandle := FALSE;
sa^.lpSecurityDescriptor := sd;
sa^.nLength := sizeof(sa);
while true
do
begin
PipeHandle := CreateNamedPipeW('
\\.\pipe\demopipe', PIPE_ACCESS_DUPLEX,
PIPE_TYPE_MESSAGE
or PIPE_READMODE_MESSAGE
or
PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, BUFSIZE,
BUFSIZE, INFINITE, SA);
if PipeHandle = INVALID_HANDLE_VALUE
then
begin
sleep(100);
continue;
end;
Connected := ConnectNamedPipe(PipeHandle,
nil)
or (GetLastError = ERROR_PIPE_CONNECTED);
if Connected
then
begin
tmp := CreateThread(
nil, 0, @InstanceThread,
Pointer(PipeHandle), 0,
nil);
if tmp = 0
then
begin
DisconnectNamedPipe(PipeHandle);
CloseHandle(PipeHandle);
continue;
end else
CloseHandle(tmp);
end else
CloseHandle(PipeHandle);
end;
LocalFree(cardinal(
ACL));
freemem(SD);
freemem(WellKnownSID);
dispose(EA);
end;
var
tmp : dword;
begin
write('
Starting ServerThread: ');
tmp := CreateThread(
nil, 0, @ServerThread,
nil, 0,
nil);
writeln(tmp <> 0);
CloseHandle(tmp);
readln;
end.