Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Mailslots ? (https://www.delphipraxis.net/4670-mailslots.html)

Captnemo 8. Mai 2003 11:18


Mailslots ?
 
Hallo Leute :dancer2:

ich schreib grad ein Prog, welchse aus einem Dienst und einer Anwendung besteht. Da ich zwischen beiden Daten austauschen muß, will ich mit Mailslots die Daten in Form von Strings übergeben.

Gesagt - getan :firejump:

Nun bin aber auf ein Problem :coder: gestossen, welches ich mir nicht erklähren kann.

Wenn der Dienst und das Anwendungsprogramm (WinXP) unter dem gleichen Benutzerkonto laufen, klappt alles wie erwartet. :chat:

Wenn aber der Dienst unter dem Systemkonto läuft, und das Anwendungsprogramm unter einem Benutzerkonto, dan können zwar beide mit CreateMailSlot einen MailSlot eröffnen, aber mit CreateFile nicht auf den jeweils anderen zugreifen. :evil:
Ich vermute das Sie nicht das Recht haben, auf den jeweils anderen Mailslot zuzugreifen. Weiss ich aber nicht. :?:

Vielleicht befindet sich hier ja ein MailSlot-Guru, der mir weiter helfen kann. :D

bis denn
Captnemo

sakura 8. Mai 2003 11:49

Ich arbeite viel mit Pipes, welche sich an dieser Stelle genau gleich verhalten. Ja, Du musst ein wenig mit den Security Attributen "rumspielen". Dazu musst Du nur ein paar Zeilen am Server einfügen.

Delphi-Quellcode:
// der Server
var
  FSA: SECURITY_ATTRIBUTES;
  FSD: SECURITY_DESCRIPTOR;
...
  InitializeSecurityDescriptor(@FSD, SECURITY_DESCRIPTOR_REVISION);
  SetSecurityDescriptorDacl(@FSD, True, nil, False);
  FSA.lpSecurityDescriptor := @FSD;
  FSA.nLength := sizeof(SECURITY_ATTRIBUTES);
  FSA.bInheritHandle := True;
// gleiches halt nur mit der Server-Pipe, der letzte Parameter bestimmt das Security Level
  Pipe := CreateNamedPipe(
    PChar(FFullPipeName), PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE or
    PIPE_READMODE_MESSAGE or PIPE_WAIT or SECURITY_ANONYMOUS,
    PIPE_UNLIMITED_INSTANCES, cMaxMessageDataSize + 1024,
    cMaxMessageDataSize + 1024, NMPWAIT_USE_DEFAULT_WAIT, @FSA
  );
...:cat:...

Captnemo 8. Mai 2003 12:07

Prima :spin: Endlich mal eine brauchbar Antwort. Danke.

Ich werd mal ein bischen rumprobieren.

Ich würd ja gerne bei Mailslots bleiben, da ich mich mit den Pipes noch nie beschäftigt haben. Geht das mit den Security Attributes auch bei Mailslots ?

Oder kennst du ein gutes Tutorial oder ein kleinen Source der mit das mit den Pipes verständlich vermitteln kann?

:cheers:

sakura 8. Mai 2003 12:12

Mailslots und Pipes sind eigentlich identisch, von daher sollte es funktionieren. Der letzte Parameter nimmt den Pointer auf FSA.

Code:
HANDLE CreateMailslot(
  LPCTSTR lpName,
  DWORD nMaxMessageSize,
  DWORD lReadTimeout,
  [color=#ff0044]LPSECURITY_ATTRIBUTES lpSecurityAttributes[/color]
);
Gegenüber Mailslots kann man mit Named Pipes in beide Richtungen kommunizieren. Die Nutzung ist fast identisch. Ein weiterer Vorteil von Pipes ist, dass man sich sicher sein kann, das die Nachricht auch wirklich übermittelt wird, dafür ist der Overhead (CPU- und Netzwerkbelastung) etwas höher.

...:cat:...

Captnemo 8. Mai 2003 20:40

Habs jetzt probiert. Und es hat soweit geklappt.
Danke nochmal.

Jetzt wird bei CreateFile kein Fehler mehr produziert. Ich kann auch eine Nachricht von der Anwendung an den Dienst schicken, aber vom Dienst an die Anwendung klappt noch nicht, obwohl Windows beim CreateFile keinen Fehler meldet ? Weiß noch nicht warum.

Hast du dazu auch noch eine Idee?

sakura 8. Mai 2003 21:38

So auf Anhieb nicht. Wenn Du alles gleich machst, nur halt anders herum, dann sollte es eigentlich gehen. Du musst halt auch die Security Attribute runterschrauben. Ansonsten versuche es mal mit Pipes. Ist eigentlich vom Handling indentisch, dafür aber two-way. Erinnere mich mal morgen, dann sende ich meine Komponenten hier rein. Die sind aber im Büro und ich gerade nicht :lol:

...:cat:...

Captnemo 9. Mai 2003 07:40

Hallo Sakura :cat:

Ich sollte dich erinnern :chat: :chat: Gell

Captnemo 9. Mai 2003 07:56

Hi Sakura, ich bins nochmal,

ich hab jetzt mal ein bischen rumexperimentiert, und dabei folgendes Festgestellt:

Ich kann deinen Code zwar fehlerfrei abtippen, aber verstanden habe ich Ihn nicht :?
Wenn ich jetzt z.B. mit SetSecurityDesriptorSACL versucht die Sicherheitsattribute für das System zu setzen, kann der Mailslot nicht mehr erzeugt werden.
Wahrscheinlich habe ich dafür von der Geschichte zu wenig Ahnung. Die W32-Hilfe ist da aber auch nicht wirklich ein Hilfe, weil wenn man nicht den richtigen Einstig hat, dann ist das wenig verständlich geschrieben. Zumal auch die Auswirkungen, die einige Parameter haben, bzw. was wie kombiniert werden kann, in der W32-Hilfe meiner Meinung nach nicht ausreichend erläutert ist.

Gibts da nicht irgendwo was besserers? Wo hast du denn deine Kenntnisse her ?

Luckie 9. Mai 2003 08:01

www.msdn.microsoft.com oder das PSDK downloaden.

sakura 9. Mai 2003 10:36

Liste der Anhänge anzeigen (Anzahl: 1)
Hi Captnemo,

so tief stecke ich in der Materie auch nicht mehr drinne. Letztendlich habe ich das damals wohl aus dem MSDN (siehe Luckies Post) zusammengekratzt. Auf Anhieb kann ich es auch nicht erklären - die Materie ist einfach zu viel schichtig. Anbei die Komponenten. Sind nie ganz fertig geworden, funktionieren aber und haben eine rudimentäre Hilfe dabei.

...:cat:...

Captnemo 9. Mai 2003 10:46

@sakura

Danke. Mal sehen was ich draus machen kann.

Manchmal macht MS uns das Leben schwere als es sein sollte.
Wenn es das PDSK so gäbe wie die Hilfe von Delphi, dann wäre das alles wahrscheinlich schneller zu lösen :lol:

@luckie

Das PDSK hab ich mir schon runtergeladen. Ich darin genauso gelesen, wie auch in der Win32-Hilfe, die Delphi mitbringt.
Wenn man sich mit einer Materie auseinandersetzt, mit der man sich noch nie beschäftigt hat, dann kommt man um eine verständlichere Erklärung von anderen Personen kaum drumrum.
Ein Beispiel-Code sagt manchmal mehr wie tausend MS-Seiten :lol:

Noch dazu brauche Ich meistens länger, als früher, da meine Grauen Zellen sich langsam auf die Reise macht :spin:

Motzi 9. Mai 2003 13:59

Jedes Kernel-Objekt besitzt einen Security-Descriptor der die Zugriffsrechte für das Objekt bestimmt. Dieser Security-Descriptor besitzt unter anderem 2 ACLs (ACL = Access Control List). Und zwar die DACL (Discretionary ACL) und die SACL (System ACL). Die SACL brauchst du in diesem Fall überhaupt nicht, denn die Zugriffsrechte für Benutzer, Gruppen, Computer werden alle in der DACL festgelegt. Ein Dienst lauft in der System-LogonSession und besitzt das SeTCBPrivilege (TCB = Trusted Computer Base) und hat somit die höchsten Rechte. Der Dienst sollte also ohne Probleme den MailSlot des Progs öffnen können. Ein Problem ist es nur umgekehrt, da das Prog kein Recht hat auf den Mailslot des Services zuzugreifen. Um das zu erreichen muss ein neuer Eintrag im DACL des Service-Mailslot vorgenommen werden. In dem Code von Sakura wird einfach ein leerer DACL erzeugt, dh es sind keine expliziten Zugriffsrechte angegeben und daher kann jeder Benutzer/Gruppe/Computer ohne Einschränkungen auf den Mailslot zugreifen. Eine andre Möglichkeit wäre einen neuen ACE (Access Control Entry) zu der DACL hinzuzufügen, der nur den expliziten Zugriff für den einen Benutzer zulässt mit dessen Prog zu kommunizieren musst.

Captnemo 9. Mai 2003 15:44

Hi Sakura,

ich bin zu dämlich :cry: :cry: :cry:

Ich kriegs mit deinen Komponenten nicht hin.

Also kurz was ich gemacht habe:

Server:

gnsPipeServer auf die Form. Pipename=Test. Active=True;
ProcessMessage
..
var
Text: String;
begin
Text:=StrPas(aByteArray);
Memo1.Lines.Add(Text);
end;
..

Client:

gnsPipeClient auf die Form. Pipename=Test.

..
procedure TForm1.Button2Click(Sender: TObject);
var
lpBuffer: Pointer;
Buffersize: Integer;
InCount, OutCount: Cardinal;
begin
Buffersize:=255;
GetMem(lpBuffer,Buffersize);
lpBuffer:=PChar(Edit1.text);
gnsPipeClient1.SendAndReceive(lpBuffer,Buffersize, InCount,OutCount);
FreeMem(lpBuffer, Buffersize);
end;
..

--------------------------------------
Fehlermeldung: Ungültige Zeigeroperation.

Ich weiß das was ich da mache ist sicher falsch. Aber mit Pointern hab ich nicht so :cry:

Hast du nicht ein Beispielcode für micht :mrgreen:

sakura 9. Mai 2003 16:06

Mal schauen, irgendwo gibt es aber bestimmt noch ein Beispiel *grübel*

...:cat:...

sakura 9. Mai 2003 16:08

Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von leicht gefälscht
Luck is with you

Keine Ahnung, ob das was taugt, aber das lag hier gerade rum.

...:cat:...

Captnemo 10. Mai 2003 10:36

Liste der Anhänge anzeigen (Anzahl: 1)
Hat eine Zeit und Lust sich das Mal anzusehen? Vielleicht Du Sakura :mrgreen: ?

Den Dienst kann ich starten. Das prog auch. Wenn ich eine Nachricht an den Dienst sende, dann ist prog und Dienst voll ausgelastet.

sakura 10. Mai 2003 12:15

Zitat:

Zitat von Captnemo
Vielleicht Du Sakura :mrgreen: ?

Gerne doch. 8)

Im Service ist der kleine, aber alles entscheidene Fehler. Wie gesagt, dadurch, daß die Komponenten noch nicht ganz ausgereift sind, ist dieser Fehler wohl etwas fatal. :oops:

Die PChar-Variable des Servers, welche Du nutzt, um die Daten zu empfangen, ist nicht initialisiert. Die daraus entstehende Exception wird nicht abgefangen und verläuft sich in der CPU.

Korrektur sind die folgenden Zeilen. Anschließend läuft alles wie am Schnürchen.
Code:
procedure TService1.gnsPipeServer1ProcessMessage(Sender: TObject;
  aByteArray: Pointer; BufferSize, InCount: Cardinal;
  var OutCount: Cardinal; var DisconnectClient: Boolean);
var
   i: Cardinal;
   temp: PChar;
begin
  [color=#cc0000]Temp := GetMemory(Incount + 1);
  try[/color]
    for i:=0 to InCount do
      Temp[i]:=CHR(TByteArray(aByteArray^)[i]);
    Nachrichten.Add(StrPas(temp));
  [color=#cc0000]finally
    FreeMemory(Temp);
  end;[/color]
end;
...:cat:...

Captnemo 10. Mai 2003 12:41

Gelesen - in Prog übertragen - gestartet - läuft.

Auf die simple Idee für Temp erstmal Speicher zu reservieren, bin ich Trottel natürlich nicht gekommen. :oops:

Danke.

Jetzt muß ich das Ganze noch in mein Programm übertragen. Hoffentlich läuft jetzt alles :mrgreen: :mrgreen: :mrgreen:

bonnet 25. Apr 2005 11:26

Re: Mailslots ?
 
Hallo,
vielen Dank für diese tollen Thread, hab die Kompnenten von sakura ausprobiert und es läuft alles fantastisch.
Bis auf eine kleine Ausnahme:
Wenn ich erst eine lange Nachricht versende und anschließend wieder kurze werden an die kurze Nachrichten noch einige Zeichen angehängt.

Woran kann das liegen? Hat jemand eine Idee?

sakura 30. Mai 2005 09:10

Re: Mailslots ?
 
Hi, ich sehe das erst jetzt :oops: Die Komponenten, welche ich hier gepostet habe, arbeiten (zur Vereinfachung) mit einer festen Messagegröße (einstellbar in der Properties), wenn Du eine andere brauchst, dann musst Du diese neu definieren oder (leider) einen gänzlich anderen Ansatz nutzen.

...:cat:...

bonnet 30. Mai 2005 11:15

Re: Mailslots ?
 
vielen dank,
die antwort reicht mir, habe jetzt auch immer mit fester Messagegröße gearbeitet (ging ja nicht anders), dachte nur das ich etwas falsch gemacht hab'.

grüße
bonnet

madas 9. Aug 2007 10:27

Re: Mailslots ?
 
Hallo,

erstmal vielen dank für das tolle Beispiel.

Nun vielleicht auch eine dumme Frage:

Kann damit auch eine Art Kommunikation zwischen Client und Server auf bauen?

Sprich Client sender an Server
Server gibt eine Antowrt zurück
Client sendet je nach Antwort des Servers wieder was an den Server
usw.

Noch ne Frage: Kann ich damit auch Objekte von einem eigenen Datentyp an den Server senden?

torud 5. Sep 2007 13:46

Re: Mailslots ?
 
Also ich muss leider feststellen, dass die Beispieldatei bei mir nicht funktioniert. Ich habe die Komponenten installiert und anschliessend den Server und den Client kompiliert, alles ohne Änderungen!

Danach habe ich den Server gestartet und aktiviert.

Anschliessend habe ich den Client gestartet und die Checkbox RUN aktiviert. Das Programm steht eine Weile still, wohl weil es versucht sich zu connecten und dann schreibt der Client in seine Liste: Could not Create Pipe Instance 1 of 53...

UND NUN???

Helmi 30. Aug 2008 14:48

Re: Mailslots ?
 
Zitat:

Zitat von torud
Also ich muss leider feststellen, dass die Beispieldatei bei mir nicht funktioniert. Ich habe die Komponenten installiert und anschliessend den Server und den Client kompiliert, alles ohne Änderungen!

Danach habe ich den Server gestartet und aktiviert.

Anschliessend habe ich den Client gestartet und die Checkbox RUN aktiviert. Das Programm steht eine Weile still, wohl weil es versucht sich zu connecten und dann schreibt der Client in seine Liste: Could not Create Pipe Instance 1 of 53...

UND NUN???

Hallo,

da würd ich gerne mit einhaken!
Ich wollt das Beipiel auch testen, aber ich bekomme die selbe Fehlermeldung.

Kann sich das bitte kurz jemand anschauen, und vielleicht eine kurze Anleitung geben, wie man dieses Beispiel verwendet?

torud 30. Aug 2008 16:44

Re: Mailslots ?
 
Wie Du am Datum des letzten Postings sehen kannst, ist der Thread dem Tode nahe...

Helmi 30. Aug 2008 17:20

Re: Mailslots ?
 
Zitat:

Zitat von torud
Wie Du am Datum des letzten Postings sehen kannst, ist der Thread dem Tode nahe...

Was aber kein Hinderungsgrund zum Wiederbeleben ist...

steewan 22. Okt 2008 21:20

Re: Mailslots ?
 
Ihr müsst den Servernamen im Client "gate-two" entsprechend abändern. Wenn Ihr Client und Server auf einem Rechner laufen habt, dann reicht ein ".", ansonsten der Name des Rechners wo der Server läuft.

Helmi 22. Okt 2008 21:28

Re: Mailslots ?
 
Danke!!

Das hat geholfen

steewan 23. Okt 2008 22:08

Re: Mailslots ?
 
Leider bekomme ich eine Zugriffsverletzung im Beispiel und nachdem die erscheint, kann auch keine neue Verbindung aufgebaut werden. Schön wäre eine aktuelle Komponente oder vielleicht den Quellcode, um diesen zu korrigieren.

xZise 16. Sep 2009 13:03

Re: Mailslots ?
 
Hallo,
sorry das ich das hier nochmal wiederbelebe, allerdings funktionieren die Demos nicht so richtig.
Und zwar starte ich den Server und aktiviere diesen. Danach starte ich den Client und setze das "gate-two" auf "." und aktiviere auch dort das Kästchen. Mit dem Ergebnis ganz vieler Fehlermeldungen:
Zitat:

Could not create pipe instance 1 of 2.
Ich setze hier Windows Vista Business ein und habe die UAC aktiviert.

Und ich benutze Delphi 2009. Und ich fürchte da liegt der Hund begraben. Da wenn ich es mit Turbo Delhi kompiliere funktioniert es einwandfrei :)

MfG
xZise


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:05 Uhr.

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