Einzelnen Beitrag anzeigen

Fridolin Walther

Registriert seit: 11. Mai 2008
Ort: Kühlungsborn
446 Beiträge
 
Delphi 2009 Professional
 
#22

Re: Named Pipes zwischen Service und eingeschränktem Program

  Alt 30. Aug 2008, 16:19
Zitat von Apollonius:
@0xF30FC7: Ich finde einfach, dass man den Memory Manager nicht bemühen sollte, wenn der Stack es genauso tut, denn er ist in jedem Fall langsamer und hat einen nicht zu vernachlässigenden Speicher-Overhead.
Das gleiche gilt für EA. Bei SD würde ich allerdings auch den MM nehmen, da du die Größe nicht im Voraus weißt.
Nunja, würde das ganze tausendfach in einer Schleife ablaufen, würd ich Dir recht geben. Aber der Performanceunterschied ist wahrscheinlich nicht mal ohne weiteres Messbar und geht in der Messungenauigkeit unter.

@CodeX:
Dezipaitor hat ja bereits den Beispiel Quelltext aus der JWSCL gepostet. Mein Beispiel würde so aussehen:

Delphi-Quellcode:
program pipeserver;

{$APPTYPE CONSOLE}

uses
  SysUtils, jwaWindows, jwsclDescriptor, jwsclACL, JwsclSID, jwsclKnownSid;

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;
  tmp : dword;
  SD : TJwSecurityDescriptor;
  SA : TSecurityAttributes;
begin
  JwInitWellKnownSIDs;

  SD := TJwSecurityDescriptor.Create;
  SD.DACL.Add(TJwDiscretionaryAccessControlEntryAllow.Create(nil, [], GENERIC_ALL, JwLocalGroupSID, false));
  SA := SD.Create_SAEx(true, false);

  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;

  SD.Free_SAEx(SA);
  SD.Free;
end;

var
  tmp : dword;
begin
  write('Starting ServerThread: ');
  tmp := CreateThread(nil, 0, @ServerThread, nil, 0, nil);
  writeln(tmp <> 0);
  CloseHandle(tmp);
  readln;
end.
Das PipeServer Executable ist übrigens dadurch von 58kb auf 610kb angewachsen .
Fridolin Walther
  Mit Zitat antworten Zitat