Announcement

Collapse
No announcement yet.

Mailslot von Service > Zugriff verweigert bei Zugriff aus Programm

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Mailslot von Service > Zugriff verweigert bei Zugriff aus Programm

    Hallo zusammen,
    um unter W2K ein Programm mit einem Service kommunizieren zu lassen habe ich in beiden jeweils einen Mailslot eingerichtet (natürlich unterschiedliche namen) was auch funktioniert. Der Service kann problemlos Nachrichten an das Programm senden. Versuche ich jedoch aus dem Programm eine Nachricht an den Service zu senden bekomme ich bereits bei CreateFile INVALID_HANDLE_VALUE zurück und lastWin32Error sagt Fehler 5, zugriff verweigert! Unterliegen Mailslots von Services irgendwelchen beschränkungen?

  • #2
    Hi,
    die Namen der Mailslots müssen gleich sein, sonst geht es nicht! Der Service macht z.b: das Create für den Mailslot und die App das Open. Zugriff verweigert, weil warscheinlich der MS nicht vorhanden ist.

    Gruss Fran

    Comment


    • #3
      Doch, der Mailsot wurde definitiv erzeugt, die namen für die zwei
      Mailslots (in jede Richtung einer) wurden in einer gemeinsam benutzten Unit definiert, beide wurden richtig erzeugt und wie gesagt funktioniert auch das senden vom Programm an den Service nur andersherum nicht, beim erzeugen kann man aber ja Prüfen ob invalidhandlevalue und das ist bei beiden Slots nicht der Fall..

      Comment


      • #4
        Ja stimmt. Da hab ich es wohl falsch verstanden. Sollte dann aber trotzdem funktionieren... Leider kann ich mit den vorhandenen Infos keine weitere Diagnose stellen.

        MfG Fran

        Comment


        • #5
          Wurde der MailSlot vom Service und dem Client auf dem gleichen Rechner gestartet ? Ein Mailslot kann im schreibmodus nur einmal per Rechner geöffnet werden.

          Gruß Hage

          Comment


          • #6
            Ja, auf dem gleichen Rechner, aber es sind ja zwei Mailslots, ich habe jetzt die namen nicht imn Kopf, aber folgendes Beispiel soll es klarer machen, der Service richtet beim starten den mailslot 'tapiServiceSlot' ein und prüft regelmäßig, ob dort vom Programm zum Beispiel die Nachricht 'Settings' angekommen ist, er also die Einstellungen neu lesen soll. Kommt zum Beispiel ein Anruf oder wurde ein Gespräch aufgezeichnet versucht der Service wiederum den Mailslot 'TapiAnwendung' zum schreiben zu öffnen, gelingt dies kann er eine Nachricht senden, die das Programm veranlasst, die Anrufliste neu einzulesen, läuft das Programm nicht, weil z.B. keiner angemeldet ist, passiert eben nichts. Der zweite Teil funktioniert, das Programm kann beim Start den Mailsot 'TapiAnwendung' erstellen und Nachrichten kommen an. Der erste teil funktioniert nur in so fern, das der Service es definitiv schafft, den Mailslot 'tapiServiceSlot' zu erstellen, das Programm kann diesen aber merkwürdigerweise grundsächtlich nicht zum schreiben öffnen (gleiche Routine, die der Service beim schreiben zur Anwendung nutzt, nur eben der andere Mailsotname! Der ganze Umstand hat zwei Hintergründe, erstens soll das ganze später auch über Netzwerk funktionieren, zweitens kann ja jeder Fritz-Anwender mal einen Filemonitor mitlaufen lassen um zu sehen, was ich vermeiden will..

            Comment


            • #7
              Konkret heist das der Service den "tapiMailSlot" auf Computer "XYZ" anlegt, da ja dort der Service läuft. In Deiner Test Anwendung wird nun versucht diesen "tapiMailSlot" zum schreiben zu öffnen, und die test-Anwendung läuft auf dem geleichen Computer "XYZ" ?? Nun, lies mal über MailSlots nach:
              1.) per Computer kann es nur einen MailSlot mit gleichem Namen geben<br>
              2.) heist nur einer kann den mailSlot erstellen, z.B. der Service, alle anderen müssen dann OpenFile() benutzen.<br>
              3.) BEIDE Server und Client müssen den Security Descriptor ausfüllen.<br>
              4.) der nMaxMessageSize Parameter sollte bei weitem kleiner < 400 Bytes sein. Es zeigte sich nämlich das das Limit von 400 Bytes falsch ist. Als Konsequenz davon sollte jede "Message", bzw. Write, in den MailSlot nicht größer als <400 Bytes sein. ich persönlich nutze 256 Bytes Messages.<br>

              Gruß Hage

              Comment


              • #8
                Mit zum schreiben öffnen meine ich natürlich Openfile bzw. CreateFile. Das ich es prinzipiell richtig mache sieht man aber auch daran, das es andersherum funktioniert, aber wenn Du es ganau wissen willst, hier der Teil im Service:<pre>
                mailSlot2 := CreateMailSlot(PChar(msMailSlot2Name),0,0,nil);
                if mailSlot2 = INVALID_HANDLE_VALUE then
                debugP('Mailslot2 konnte nicht erstellt werden')
                else begin
                settingsTimer.Enabled := true;
                debugP('Mailslot2 erstellt!')
                end;
                </pre> und in der Anwendung gibts die Routine:<pre>
                procedure Tmain.kickMessage(msg:String);
                var bytes : Dword;
                mailSlot2 : THandle;
                t : String;
                begin
                t := msMailSlot2Name;
                try
                mailSlot2 := CreateFile(PChar(t),Generic_Write, FILE_SHARE_READ,nil,Open_Existing,File_Attribute_N ormal,0);
                if mailSlot2 <> INVALID_HANDLE_VALUE then begin
                win32Check(WriteFile(mailSlot2,msg[1],length(msg),bytes,nil));
                closeHandle(mailSlot2);
                end else
                RaiseLastWin32Error;
                except
                hist.lines.add('Fehler bei Nachricht an den Server');
                end;
                end;
                </pre>
                Und das CreateFile erntet dann INVALID_HANDLE_VALUE, testweise habe ich dann RaiseLastWin32Error eingebaut und erfahren(Fehlercode 5, Zugriff verweigert). Der Eintrag t := msMailSlot2Name ist eigentlich unerheblich und diente mir nur beim Debuggen, weil Delphi mir den Inhalt dieses Ressourcenstrings aus einer (der einzigen) gemeinsamen unit von Server und Anwendung nicht anzeigen konnte.<p>
                Wie gesagt, gibt es das gleiche Pärchen nochmal andersherum, also Erstellung von der Anwendung und Beschreiben duch den Service, exakt die gleichen Routinen (von denen habe ich kopiert), nur anderer Name und diese kopien (also senden von Service an Prog) funktionieren (auch ohne Security Descriptor)! Die größe der Nachricht liegt um die 10 Zeichen!
                &#10

                Comment


                • #9
                  Richtig <b>auch ohne Security Descriptor</b>. Da liegt aber wahrscheinlich auch das Problem. Ein Service läuft in einer besonders geschützten/priveligierten Station. D.h. ein Service kann ohne weiteres per default auf die durch andere APP-Stations alllozierten Resourcen zugreifen. D.h. der Service "sieht" den durch die Application erzeugten MailSlot. Umgehkehrt, hat aber der Service seinen MailSlot NICHT EXPLIZIT mit Rechte für andere Stations versehen. Dadurch bekommt der Server MailSlot eben höhere Sicherheitsschranken, so daß Deine Application nicht auf den Server MailSlot zugreifen kann.<br>
                  Du siehst das Dein Argument, <b>wenn's so rum läuft, müsste es auch anders rum laufen</b> und das offensichtliche NICHT Funktionieren, eher den Gebrauch des SecurityDescriptors und der Stations sugeriert.

                  Gruß Hage

                  Comment


                  • #10
                    Ich hatte eigentlich einfach nur die Hoffnung, das es ohne geht, da mich dessen Beschreibung im SDK abgeschreckt hat. Nachdem dann die eine Version funktionierte hab ich mich eben dann gewundert, das es andersrum nicht genauso geht. Aber dann werde ich mir das wohl doch nochmal in Ruhe zu gemüte führen müssen, danke erstmal

                    Comment


                    • #11
                      Jetzt weiss ich, warum ichs ohne versuchen wollte, ich nutze jetzt folgende funktion:
                      <pre>
                      function CreateSDiscriptor:Boolean;
                      const SECURITY_DESCRIPTOR_REVISION = 1;
                      var
                      SecurityDescriptor:TSecurityDescriptor;
                      begin
                      result := false;
                      try
                      SecurityAttr.nLength:=SizeOf(SECURITY_ATTRIBUTES);
                      SecurityAttr.bInheritHandle:=TRUE;
                      SecurityAttr.lpSecurityDescriptor:=@SecurityDescri ptor;
                      if not InitializeSecurityDescriptor(@SecurityDescriptor,S ECURITY_DESCRIPTOR_REVISION) then
                      exit;
                      if not SetSecurityDescriptorDacl(@SecurityDescriptor,TRUE ,NIL,FALSE) then
                      exit;
                      if not SetKernelObjectSecurity(GetCurrentProcess,DACL_SEC URITY_INFORMATION,@SecurityDescriptor) then
                      exit;
                      except on e:exception do exit;
                      end;
                      result := true;
                      end;
                      </pre> wobei SecurityAttr global als TSecurityAttributes definiert ist und der Service im CreateEreignis folgendes versucht:<pre>
                      if CreateSDiscriptor then begin
                      mailSlot2 := CreateMailSlot(PChar(msMailSlot2Name), 0, 0, @SecurityAttr);
                      if mailSlot2 = INVALID_HANDLE_VALUE then begin
                      debugP('Mailslot2 konnte nicht erstellt werden');
                      debugP(GetLastWin32Error);
                      end else begin
                      settingsTimer.Enabled := true;
                      debugP('Mailslot2 erstellt!')
                      end;
                      end else debugP('Fehler beim Erstellen des Security Descriptors: '+GetLastWin32Error);
                      </pre> Das merkwürdige ist, das das erzeugen des Descriptors fehlerfrei durchläuft, aber das erzeugen des Mailslots mit der Fehlermeldung "Win32-Fehler. Code: 183. Eine Datei kann nicht erstellt werden, wenn sie bereits vorhanden ist" abbricht. Da komme ich jetzt nicht mit, den ohne diesen Descriptor wird der Mailslot fehlerfrei erstellt, also wird der Fehler wohl eher dort liegen oder

                      Comment


                      • #12
                        Bevor mir wieder jemand erzählt, das der Name eindeutig sein muss, er ist es!!

                        Comment


                        • #13
                          Keiner eine Ahnung davon

                          Comment


                          • #14
                            ich habe mal ein komplettes Beispiel zum Zusammenstellen eines Sicherheitsdeskriptors (im Zusammenhang mit einem Registry-Zugriff aus einem Service) gepostet, vielleicht finde ich den Post ja noch...

                            ...gefunden... "http://www.entwickler-forum.de/webx?13@ @.ee7127e.ee704fa/30"

                            Vielleicht auch ganz gut, um sich in's Thema einzulesen (war ein langer Thread =)

                            Gruß Nico

                            PS: Leerzeichen zwischen den beiden @ bei der URL rausnehmen =

                            Comment


                            • #15
                              Hm, ist ja völlig anders, als das was ich gefunden hatte (s.o.) muss ich mir wohl nochmal in ruhe zerflücken, danke erstmal

                              Comment

                              Working...
                              X