SERVICE_CONTROL_DEVICEEVENT



  • Hallo,

    ich bekomme in meinem Service in der HandlerEx Funktion niemals das SERVICE_CONTROL_DEVICEEVENT.

    Ich weiß das ich zuerst RegisterDeviceNotification ausführen muss.

    Allerdings WILL DAS EINFACH NICHT KLAPPEN. Seit 2 Wochen versuche ich alles um das hinzukriegen. Aber er klappt nicht.

    Ich habe ausgegeben... Ich finde keine guten Beispiele. Wenn dann nur Beispiele die bei mir nicht funktionieren oder so.
    Und hier im Forum kann mir dazu anscheinend keiner helfen.

    Kennt einer von euch sonst noch ne Möglichkeit irgendwie mitzubekommen, wenn ein USB-Stick angeschlossen wird??
    MFG
    Ace

    PS: Nochmal mein aktueller Code:

    #include <iostream>
    #include <fstream>
    
    #include <Windows.h>
    #include <winuser.h>
    #include <lm.h>
    #include <dbt.h>
    #include <vcl.h>
    #include <Tlhelp32.h>
    #include <stdio.h>
    #include <cstdio.h>
    
    #define DEVICE_NOTIFY_ALL_INTERFACE_CLASSES  0x00000004
    
    using namespace std;
    
    SERVICE_STATUS Service_status;
    SERVICE_STATUS_HANDLE hService_status;
    
    DWORD WINAPI HandlerEx(DWORD dwControl,DWORD dwEventType,LPVOID lpEventData,LPVOID lpContex)
    {
       DWORD status;
    
       switch(dwControl)
       {
          case SERVICE_CONTROL_DEVICEEVENT:
             Beep( 750, 3000 );
             if(dwEventType == DBT_DEVICEARRIVAL)
             {
                    Beep(500,3000);
             }
             break;
          case SERVICE_CONTROL_PAUSE:
          // Do whatever it takes to pause here.
             Service_status.dwCurrentState = SERVICE_PAUSED;
             break;
    
          case SERVICE_CONTROL_CONTINUE:
          // Do whatever it takes to continue here.
             Service_status.dwCurrentState = SERVICE_RUNNING;
             break;
    
          case SERVICE_CONTROL_STOP:
          // Do whatever it takes to stop here.
             Service_status.dwWin32ExitCode = 0;
             Service_status.dwCurrentState  = SERVICE_STOPPED;
             Service_status.dwCheckPoint    = 0;
             Service_status.dwWaitHint      = 0;
             SetServiceStatus (hService_status, &Service_status);
             return 1;
    
          case SERVICE_CONTROL_INTERROGATE:
          // Fall through to send current status.
             break;
       }
       SetServiceStatus (hService_status, &Service_status);
    
       // Send current status.
    
       return 1;
    }
    
    void WINAPI MyServiceStart (DWORD argc, LPTSTR *argv)
    {
        DWORD status;
        DWORD specificError;
    
        Service_status.dwServiceType        = SERVICE_WIN32;
        Service_status.dwCurrentState       = SERVICE_START_PENDING;
        Service_status.dwControlsAccepted   = 0;
        Service_status.dwWin32ExitCode      = 0;
        Service_status.dwServiceSpecificExitCode = 0;
        Service_status.dwCheckPoint         = 0;
        Service_status.dwWaitHint           = 10000;
    
        hService_status = RegisterServiceCtrlHandlerEx(
            "MyService",
            (LPHANDLER_FUNCTION_EX)HandlerEx,
            0);
    
        SetServiceStatus(hService_status, &Service_status);
    
        // Handle error condition 
        if (status != NO_ERROR)
        {
            Service_status.dwCurrentState       = SERVICE_STOPPED; 
            Service_status.dwCheckPoint         = 0;
            Service_status.dwWaitHint           = 0; 
            Service_status.dwWin32ExitCode      = status;
            Service_status.dwServiceSpecificExitCode = specificError; 
    
            SetServiceStatus (hService_status, &Service_status); 
            return; 
        } 
    
        // Initialization complete - report running status. 
        Service_status.dwCurrentState       = SERVICE_RUNNING; 
        Service_status.dwCheckPoint         = 0; 
        Service_status.dwWaitHint           = 0;
        Service_status.dwControlsAccepted   = SERVICE_ACCEPT_STOP |
            SERVICE_ACCEPT_PAUSE_CONTINUE;
    
        SetServiceStatus (hService_status, &Service_status);
        DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;
        ZeroMemory( &NotificationFilter, sizeof(NotificationFilter) );
        NotificationFilter.dbcc_size = sizeof(NotificationFilter);
        NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
        memcpy(
            &(NotificationFilter.dbcc_classguid),
            &(GUID_DEVINTERFACE_CDROM),
            sizeof(GUID_DEVINTERFACE_CDROM)
        );
        HANDLE hRegister = RegisterDeviceNotification(
            &Service_status,
            &NotificationFilter,
            DEVICE_NOTIFY_SERVICE_HANDLE|
            DEVICE_NOTIFY_ALL_INTERFACE_CLASSES
        );
        if(hRegister==NULL)
        {
            Beep(1000,100);
            Sleep(100);
            int error = GetLastError();
            if(error==13)
            {
              Beep(1500,1000);
              Sleep(100);
              Beep(1500,1000);
            }else{
            FILE* file;
            file = fopen("C:\\mytxt.txt","w");
            fprintf(file,"%d",error);
            fclose(file);
    
            }
        }
        return;
    }
    
    int main(int argc, char *argv[])
    {
        SERVICE_TABLE_ENTRY serv_dispatchtable[]=
        {
                            {TEXT("MyService"),(LPSERVICE_MAIN_FUNCTION)MyServiceStart},
                            {NULL,NULL}
        };
        StartServiceCtrlDispatcher(serv_dispatchtable);
        system("PAUSE");
        return EXIT_SUCCESS;
    }
    


  • Leider krieg ich das nicht kompiliert,

    aber

    im MSDN steht zu lesen

    HDEVNOTIFY RegisterDeviceNotification(
    HANDLE hRecipient,
    LPVOID NotificationFilter,
    DWORD Flags
    );

    Parameters
    hRecipient
    [in] Handle to the window or service that will receive device events for the devices specified in the NotificationFilter parameter. The same window handle can be used in multiple calls to RegisterDeviceNotification.
    Services can specify either a window handle or service status handle.

    In Deinem Code aber

    SERVICE_STATUS Service_status;
    SERVICE_STATUS_HANDLE hService_status;
    
    //...
    
        HANDLE hRegister = RegisterDeviceNotification(
            &Service_status,
            &NotificationFilter,
            DEVICE_NOTIFY_SERVICE_HANDLE|
            DEVICE_NOTIFY_ALL_INTERFACE_CLASSES
        );
    

    Übergib dem Systemruf vielleicht mal hService_status.

    Ansonsten könnten Testausschiften mittels

    OutputDebugString()
    

    in HandlerEx(...) helfen.

    Oder halt mal via Taskmanager in den laufenden Dienst "reindebuggen".

    Grüsse

    Gast++

    P.S.:Btw. mir fällt auf dass fast alle gespostetn Codebeispiele, also auch die in anderen Threads) nicht mit UNICODE laufen. Bei mir ( VC Express ) musste ich extra MBCS auswählen; bei Dir nicht?



  • Erst mal vieeeeeeleeeeen Dank.
    Bin echt nicht mehr weitergekommen. Obwohl das nur so kleiner dummer Fehler war.

    Jetzt bekomme ich immerhin keine Fehlermeldung for RegisterDeviceNotification.

    Im Moment funzt. das mit der GUID noch nicht aber da werd ich nochma gucken.

    MFG
    Ace

    PS:Benutze den BCB und ich hab da nix mit MBCS ausgewählt weiß auch gar nicht wie ich das da mache.



  • Gast++ schrieb:

    P.S.:Btw. mir fällt auf dass fast alle gespostetn Codebeispiele, also auch die in anderen Threads) nicht mit UNICODE laufen. Bei mir ( VC Express ) musste ich extra MBCS auswählen; bei Dir nicht?

    Jops, das ist leider bei fast allen so...liegt daran, dass die wenigsten hier auf Zeichensatz-unabhängige Typen achten (TCHAR, TEXT-Makro, ...).
    Bei dem obrigen Code ist es das Gleiche 🤡 .



  • AceKiller73 schrieb:

    Erst mal vieeeeeeleeeeen Dank.

    You're welcome! 😉

    AceKiller73 schrieb:

    Im Moment funzt. das mit der GUID noch nicht aber da werd ich nochma gucken.

    Welche GUID ?
    GUID_DEVINTERFACE_CDROM?
    Mit dem Ding wär ich vorsichtig; das schein ein Makro zu sein.

    Vielleicht &GUID_DEVINTERFACE_CDROM statt &(GUID_DEVINTERFACE_CDROM)?
    ( Schuss ins Blaue auf bewusst unsicherer Grundlage 😉 )

    Das wäre auch von MS gar nicht nett...

    AceKiller73 schrieb:

    PS:Benutze den BCB und ich hab da nix mit MBCS ausgewählt weiß auch gar nicht wie ich das da mache.

    Den Compiler kenn ich nicht aber ein

    #undef _MBCS
    #undef MBCS
    #define _UNICODE 1
    #define UNICODE 1
    #include <tchar.h>
    

    vor dem ersten #include sollte den Zweck erfüllen.
    Gibt wahrschinelich ein paar Fehlermeldungen weil irgendwo "const char*" statt TEXT(const char*) oder _T(const char*) verwandt wird.
    Kannst ja mal testen

    _tprintf(_T("sizeof TCHAR ist: %i\n"),sizeof(TCHAR));

    und zur Not wieder auskommentieren
    (2 sollte herauskommen)

    Aber hier könnte es wirklich wchtig sein, da der NT-Kernel sonst bei Systemrufen afaik immer implzit konvertieren muss.
    So täts der Compiler _vor_ der Laufzeit des Prog.

    Grüsse

    *this


Anmelden zum Antworten