Delphi-PRAXiS
Seite 3 von 3     123   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Named Pipes zwischen Service und eingeschränktem Programm (https://www.delphipraxis.net/119717-named-pipes-zwischen-service-und-eingeschraenktem-programm.html)

Dezipaitor 30. Aug 2008 15:57

Re: Named Pipes zwischen Service und eingeschränktem Program
 
Sowas ?
http://jedi-apilib.svn.sourceforge.n...23&view=markup
Delphi-Quellcode:
program Server;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  Dialogs,
  jwaWindows,
  jwsclDescriptor,
  jwsclACL,
  JwsclSID,
  jwsclKnownSid,
  jwsclMapping,
  jwsclToken,
  jwsclStrings;

type TMessage = record
       Data : array[0..1023] of Char;
     end;

var PipeHandle : THandle;
    pSecAttr : TSecurityAttributes;
    SD : TJwSecurityDescriptor;
    i : Integer;
    lpData : TMessage;
    iWritten,
    iRead : DWORD;

    PipeToken : TJwSecurityToken;
    c : Char;
begin
  Writeln('Server Pipe');
  JwInitWellKnownSIDs; //for the JwXxxxSID variables

  SD := TJwSecurityDescriptor.Create;
  SD.DACL.Add(TJwDiscretionaryAccessControlEntryAllow.Create(nil,[],GENERIC_ALL,JwAdministratorsSID, false));
  SD.DACL.Add(TJwDiscretionaryAccessControlEntryAllow.Create(nil,[],GENERIC_ALL,JwLocalSystemSID, false));

  Writeln('Do you want to allow the actual logged on user to connect to the pipe? (y/n)');
  Writeln('If you say yes, your user will succed to connect to the pipe. However if you are using Vista, the user will get'+
   'the string ''denied'' from the server because he is deny only for admins. Is the process started elevated or on XP it should work fine.');
  Writeln('If you say no, the user will only allowed to be connected to the pipe, if he is an administrator or system ');
  Write('[Y/N]:');

  Read(c);
  if UpCase(c) = 'Y' then
    SD.DACL.Add(TJwDiscretionaryAccessControlEntryAllow.Create(nil,[],GENERIC_ALL,JwLocalGroupSID, false));


  //ShowMessage(SD.GetTextMap(TJwSecurityPipeMapping));

  //remove Everyone group if available
  i := SD.DACL.FindSID(JwWorldSID);
  if i > -1 then
  begin
    {If lpSecurityAttributes is NULL, the named pipe gets a default security descriptor
    and the handle cannot be inherited. The ACLs in the default security descriptor for
    a named pipe grant full control to the LocalSystem account, administrators, and the creator owner.
    They also grant read access to members of the Everyone group and the anonymous account.
    }
    SD.DACL.Delete(i); //remove Everyone group
  end;


  pSecAttr := SD.Create_SAEx(true);

  try
    PipeHandle := CreateNamedPipe(
      '\\.\pipe\JwsclPipeTest',//__in     LPCTSTR lpName,
      PIPE_ACCESS_DUPLEX or FILE_FLAG_FIRST_PIPE_INSTANCE,//__in     DWORD dwOpenMode,
      PIPE_TYPE_MESSAGE or      // message type pipe
        PIPE_WAIT,//__in     DWORD dwPipeMode,
      1,//__in     DWORD nMaxInstances,
      4096,//__in     DWORD nOutBufferSize,
      4096,//__in     DWORD nInBufferSize,
      0,//__in     DWORD nDefaultTimeOut,
      LPSECURITY_ATTRIBUTES(@pSecAttr)//__in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes
    );
    if PipeHandle = INVALID_HANDLE_VALUE then
      RaiseLastOSError;
  finally
    SD.Free_SAEx(pSecAttr);
    FreeAndNil(SD);
  end;

  try
    if not ConnectNamedPipe(PipeHandle,nil) then
      RaiseLastOSError;

    if not ReadFile(PipeHandle,@lpData,sizeof(lpData),@iRead, nil) then
      RaiseLastOSError;

    writeln('Data from other side: ',lpData.Data);

    try
      //throws exception if fails
      TJwSecurityToken.ImpersonateNamedPipeClient(PipeHandle);
      //we are in context of user now
     
      try
        if JwCheckAdministratorAccess then
        begin
          lpData.Data := 'Success'#0#0;
          Writeln('Client is approved.');
        end
        else
        begin
          lpData.Data := 'Denied.'#0#0;
          Writeln('Client is denied.');
        end;

        WriteFile(PipeHandle, @lpData,sizeof(lpData), @iWritten, nil);
       
      finally
        TJwSecurityToken.RevertToSelf;
      end;
    finally
    end;
  finally
    Sleep(2000); //or wait for more connections as shown above
    CloseHandle(PipeHandle);
  end;
  writeln('Hit enter...');
  readln;
end.

Fridolin Walther 30. Aug 2008 16:19

Re: Named Pipes zwischen Service und eingeschränktem Program
 
Zitat:

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 ;).

Dezipaitor 30. Aug 2008 16:27

Re: Named Pipes zwischen Service und eingeschränktem Program
 
Ich arbeite dran die Units bisschen kleiner zu machen. Besonders da JwaWindows und SysUtils drin sind, ist das alles etwas groß.
Dummerweise gibt es nur wenig Zeit und wenig Hilfe für die Aufgaben :wall:

Dezipaitor 30. Aug 2008 17:24

Re: Named Pipes zwischen Service und eingeschränktem Program
 
Ich habe auch grad erlebt,dass es garnicht möglich ist SysUtils zu ersetzen.
Zudem, wenn man die einzelnen Units JwaXXX der JwaWindows vorzieht, dann muss man damit leben, dass je nach Reihenfolge dieser Units in der Uses Klausel, man verschiedene Typen verwendet. Diese Typen können nämlich doppelt in verschiedenen JwaUnits definiert worden sein. Dann muss man explizit casten.

CodeX 30. Aug 2008 18:34

Re: Named Pipes zwischen Service und eingeschränktem Program
 
Ich denke, mein Problem ist so weit gelöst. Danke schön Euch allen!! :cheers:

quendolineDD 6. Nov 2008 09:54

Re: Named Pipes zwischen Service und eingeschränktem Program
 
Ich verfolge ja das ganze Thema und bin selber am Schreiben eines Dienstes, der eine NamedPipe zur Verfügung stellt und für eine definierte Benutzergruppe diese zur Verfügung stellen soll.
Jedoch möchte ich keine JEDI-Komponenten verwenden .... Probleme bekomme ich bei dem Code u.a. bei

[Fehler] uService.pas(89): Undefinierter Bezeichner: 'LPSECURITY_ATTRIBUTES'
[Fehler] uService.pas(90): Undefinierter Bezeichner: 'PSECURITY_ATTRIBUTES'
[Fehler] uService.pas(93): Undefinierter Bezeichner: 'ACL_SIZE_INFORMATION'
[Fehler] uService.pas(98): Undefinierter Bezeichner: 'MultipleTrusteeOperations'
[Fehler] uService.pas(100): Undefinierter Bezeichner: 'pstrName'
[...]
[Fehler] uService.pas(111): Inkompatible Typen: '_ACL' und 'PACL'

Derzeitiges uses

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, SvcMgr, Dialogs, accctrl, aclapi;

Dezipaitor 6. Nov 2008 10:09

Re: Named Pipes zwischen Service und eingeschränktem Program
 
Die musst du alle selbst übersetzen aus C nach Delphi.


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:38 Uhr.
Seite 3 von 3     123   

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz