Event unter anderem Benutzer aufrufen



  • Hallo zusammen
    ich hoffe das gehört hier rein. soweit ich weiss, gehört das zur API, also bitte nicht hauen, wenns hier falsch ist 😉

    ich muss in einem programm ein event basteln, dass ich unter einem anderen benutzer (mit anderem Programm, das durch runas gestartet wird) brauchen kann.. eigentlich wollte ich das so machen:

    programm 1:

    HANDLE event = CreateEvent(0, FALSE, FALSE, "MeinEvent");
    [...]
    WaitForSingleObject(event, INFINITE);
    

    programm 2 (unter anderem benutzer gestartet)

    HANDLE event = OpenEvent(EVENT_MODIFY_STATE, FALSE, "MeinEvent");
    PulseEvent(event);
    

    (ich muss in programm 1 warten, bis programm 2 durchgelaufen ist)

    blöderweise funktioniert OpenEvent nicht. durch einiges ausprobieren und nachforschen habe ich rausgefunden, dass das default-SECURITY_ATTRIBUTE anderen benutzern nur lese-zugriff auf events gibt, OpenEvent also nur mit "SYNCHRONIZE" anstatt "EVENT_MODIFY_STATE" funzen würde, was mir nichts bringt (SYNCHRONIZE erlaubt das pulsen oder das normale losschicken eines events nicht)
    um das zu ändern, müsste ich den ersten parameter von CreateEvent (das Security-Attribute, 0 = default) ändern. ein solches sieht so aus:

    typedef struct _SECURITY_ATTRIBUTES { // sa 
        DWORD  nLength; 
        LPVOID lpSecurityDescriptor; 
        BOOL   bInheritHandle; 
    } SECURITY_ATTRIBUTES;
    

    nLength und bInheritHandle sind mir klar, aber um dem anderen user zugriff zu gewähren, muss ich lpSecurityDescriptor ändern.. der ist auch ein struct, dessen parameter man laut MSDN nur per funktionen setzen soll.. die, die ich wohl benötige, ist InitializeSecurityDescriptor()

    die sieht ihrerseits so aus:

    BOOL InitializeSecurityDescriptor(
      PSECURITY_DESCRIPTOR pSecurityDescriptor,
      DWORD dwRevision
    );
    

    dwRevision ist "[in] The revision level to assign to the security descriptor. This parameter must be SECURITY_DESCRIPTOR_REVISION. "
    nur wird mir leider nirgends gesagt, was eine SECURITY_DESCRIPTOR_REVISION ist..

    ausserdem wäre da noch die funktion "SetSecurityDescriptorGroup".
    diese will einen pointer zu einer SID.
    um eine solche zu basteln, bräuchte ich wohl die funktion "AllocateAndIntializeSid"

    BOOL AllocateAndInitializeSid(
      PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
      BYTE nSubAuthorityCount,
      DWORD dwSubAuthority0,
      DWORD dwSubAuthority1,
      DWORD dwSubAuthority2,
      DWORD dwSubAuthority3,
      DWORD dwSubAuthority4,
      DWORD dwSubAuthority5,
      DWORD dwSubAuthority6,
      DWORD dwSubAuthority7,
      PSID* pSid
    );
    

    pIdentifierAuthority
    [in] Pointer to a SID_IDENTIFIER_AUTHORITY structure. This structure provides the top-level identifier authority value to set in the SID.
    nSubAuthorityCount
    [in] Specifies the number of subauthorities to place in the SID. This parameter also identifies how many of the subauthority parameters have meaningful values. This parameter must contain a value from 1 to 8.
    For example, a value of 3 indicates that the subauthority values specified by the dwSubAuthority0, dwSubAuthority1, and dwSubAuthority2 parameters have meaningful values and to ignore the remainder.

    dwSubAuthority0
    [in] Subauthority value to place in the SID.
    [...]
    dwSubAuthority7
    [in] Subauthority value to place in the SID.
    pSid
    [out] Pointer to a variable that receives the pointer to the allocated and initialized SID structure.

    nun gibts aber keinen link auf der msdn-seite, der mir sagen würde, wie ich diese subauthorities mache..

    ich hätte auch noch ein beispiel gefunden (weiter unten bei "To retreive the SID for a user account") , werd aber daraus nicht wirklich schlau.

    kann mir jemand da aushelfen? (eventuell sogar mit einem code, wie man ein event bastelt, das man von anderen usern aus auch benutzen kann? :D)



  • danke für die rege beteiligung 😛

    ich hab's nun gelöst (für's archiv, falls irgendwann mal jemand ein ähnliches problem haben sollte)
    erst hatte ich sowas (in Programm 1):

    SECURITY_ATTRIBUTES* secAttr = new SECURITY_ATTRIBUTES;
    secAttr->bInheritHandle = FALSE; // keine vererbung
    SECURITY_DESCRIPTOR *pSecDesc = new SECURITY_DESCRIPTOR;
    PSID sid= NULL; // plöde securityid
    
    // Retrieve the SID of the Everyone group.
    SID_IDENTIFIER_AUTHORITY WorldAuth = SECURITY_WORLD_SID_AUTHORITY;
    if (AllocateAndInitializeSid(&WorldAuth, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &sid) == FALSE) {
    	ErrorHandler("AllocateAndInitializeSid failed", GetLastError());
    }
    
    if (InitializeSecurityDescriptor(pSecDesc, SECURITY_DESCRIPTOR_REVISION) == FALSE) {
    	ErrorHandler("InitializeSecurityDescriptor failed", GetLastError());
    }
    
    //SetSecurityDescriptorGroup(pSecDesc, sid, FALSE);
    secAttr->lpSecurityDescriptor = pSecDesc; // da mussich machen
    secAttr->nLength = sizeof(*secAttr); // die grösse in bytes
    
    HANDLE event = CreateEvent(secAttr, FALSE, FALSE, "TTPRIETEVENT");
    

    (ErrorHandler ist ne eigene funktion, die den Fehler ins logfile schreibt und das programm falls nötig beendet)

    durch ein usenetposting von Rob Beckers in borland.public.cppbuilder.vcl.components.using ("How to intercept another running instance of the same program?") hatte ich eine funktionierende lösung, die, wie könnte es auch anders sein, um einiges einfacher war. danke, rob

    SECURITY_ATTRIBUTES SecAttr; 
    SECURITY_DESCRIPTOR SecDesc; 
    
    InitializeSecurityDescriptor(&SecDesc,SECURITY_DESCRIPTOR_REVISION); 
    SetSecurityDescriptorDacl(&SecDesc,TRUE,NULL,FALSE); 
    SecAttr.nLength=sizeof(SECURITY_ATTRIBUTES); 
    SecAttr.bInheritHandle=FALSE;
    
    //descriptor for event so all processes have full access 
    SecAttr.lpSecurityDescriptor=&SecDesc; 
    HANDLE event = CreateEvent(&SecAttr, TRUE, FALSE, "TTPRIETEVENT");
    if (event == NULL) ErrorHandler("Fehler bei CreateEvent", GetLastError(), true);
    


  • hi,
    du kannst auch 'nen security descriptor mit 'ner NULL DACL nehmen. da kann dann jeder beliebig drauf zugreifen:

    SECURITY_DESCRIPTOR SD;
    InitializeSecurityDescriptor (&SD, SECURITY_DESCRIPTOR_REVISION);
    SetSecurityDescriptorDacl (&SD TRUE, (PACL)NULL, FALSE);
    

    ...und wenn du mit mehreren benutzern hantierst, dann ist es besser den event im globalen session namespace anzulegen:

    HANDLE event = CreateEvent(secAttr, FALSE, FALSE, "Global\\TTPRIETEVENT");
    

    dann isser z.b. auch in allen terminal sessions sichtbar...



  • hi,
    du kannst auch 'nen security descriptor mit 'ner NULL DACL nehmen. da kann dann jeder beliebig drauf zugreifen:

    SECURITY_DESCRIPTOR SD;
    InitializeSecurityDescriptor (&SD, SECURITY_DESCRIPTOR_REVISION);
    SetSecurityDescriptorDacl (&SD TRUE, (PACL)NULL, FALSE);
    

    hab ich ja nun auch gemacht:

    SECURITY_DESCRIPTOR SecDesc; 
    
    InitializeSecurityDescriptor(&SecDesc,SECURITY_DESCRIPTOR_REVISION); 
    SetSecurityDescriptorDacl(&SecDesc,TRUE,NULL,FALSE);
    

    ...und wenn du mit mehreren benutzern hantierst, dann ist es besser den event im globalen session namespace anzulegen:

    HANDLE event = CreateEvent(secAttr, FALSE, FALSE, "Global\\TTPRIETEVENT");
    

    dann isser z.b. auch in allen terminal sessions sichtbar...

    mach ich eventuell noch, aber ist bei meinem fall eher unnötig

    danke trotzdem 😉


Anmelden zum Antworten