Jump to content

  • Log In with Google      Sign In   
  • Create Account


Accessing a Devices Interface/Class GUID always causes an error


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
5 replies to this topic

#1 gretty   Members   -  Reputation: 208

Like
0Likes
Like

Posted 04 January 2013 - 11:45 PM

Hello

 

Using C++ and native Win32 functions, I am attempting to get the class/interface GUID of a connected device such as a TV or projector. I am using the function RegisterDeviceNotification() to give me the GUID when a TV is connected.

My Problem: When the TV is connected I can successfully be notified but when I go to access the GUID of the device(by inspecting the lParam structure) I get an access violation or error.

I cant figure out whats going wrong? Whenever I go to access or use the GUID my program fails, note my program doesn't crash but the output window writes something like First-chance exception at 0x001c1a9d in myProgram.exe... and I cant figure out whats going wrong?

   

 

HDEVNOTIFY *hDeviceNotify;
    GUID interfaceClassGuid = { 0x25dbce51, 0x6c8f, 0x4a72, 0x8a,0x6d,0xb5,0x4c,0x2b,0x4f,0xc8,0x35 };
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        int wmId, wmEvent;
        PAINTSTRUCT ps;
        HDC hdc;
    
        switch (message)
        {
            case WM_CREATE:
            {                  
                 openConsoleWindow();
    
                 DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;
                 ZeroMemory( &NotificationFilter, sizeof(NotificationFilter) );
                 NotificationFilter.dbcc_size       = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
                 NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
                 NotificationFilter.dbcc_classguid  = interfaceClassGuid;
             
                 *hDeviceNotify = RegisterDeviceNotification( hWnd, &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE );
             
                 if (*hDeviceNotify == NULL)
                     printf("hDeviceNotify = NULL \n");
            }    
            break;
            case WM_DEVICECHANGE:
            {
                PDEV_BROADCAST_DEVICEINTERFACE b = (PDEV_BROADCAST_DEVICEINTERFACE) lParam;
                    
                // The following printf NEVER prints out.
                // When accessing the below GUID I get an error:
                // "First-chance exception at 0x001c1a9d in myProgram.exe: 0xC0000005: Access violation writing location 0x00000000."
                printf("GUID: Data1: %x, Data2: %x, Data3: %x, Data4: %s \n", b->dbcc_classguid.Data1,
                    b->dbcc_classguid.Data2, b->dbcc_classguid.Data3, (char*)b->dbcc_classguid.Data4);
                        
                // The following function ALWAYS fails.
                // GetLastError() gives the error "The parameter is incorrect"
                HDEVINFO hDevInfo = SetupDiGetClassDevs(&b->dbcc_classguid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
                if (hDevInfo == INVALID_HANDLE_VALUE) {
                     //printf("hDevInfo == INVALID_HANDLE_VALUE \n");
                   outputLastError(_T("hDevInfo == INVALID_HANDLE_VALUE \n"));
                }
    
            }
            break;
            ...

 



Sponsor:

#2 e‍dd   Members   -  Reputation: 2105

Like
1Likes
Like

Posted 05 January 2013 - 12:17 AM

Have you checked wparam? If it's something like DBT_DEVICEREMOVECOMPLETE, you're probably casting lParam to the wrong type in the first place.

 

In general, it's my understanding that you should always first cast lparam to a DEV_BROADCAST_HDR* and only cast to something further once you have confirmed the value of its dbch_devicetype.



#3 gretty   Members   -  Reputation: 208

Like
0Likes
Like

Posted 05 January 2013 - 01:49 AM

Thanks for the reply

 

For my TV, the wParam value is always DBT_DEVNODES_CHANGED, even when I connect and remove the device(instead of having DBT_DEVICEARRIVAL/DBT_DEVICEREMOVE sent).

 

The following code takes your advice into account but it reproduces the same errors(exception and same GetLastError() value):

 

 

        case WM_DEVICECHANGE:
        {
            if (wParam != DBT_DEVNODES_CHANGED) {
                printf("1: \n");
                break;
            }

            PDEV_BROADCAST_HDR h = (PDEV_BROADCAST_HDR) lParam;
            if (h->dbch_devicetype != DBT_DEVTYP_DEVICEINTERFACE) {
                printf("2\n");
                break;
            }

            PDEV_BROADCAST_DEVICEINTERFACE b = (PDEV_BROADCAST_DEVICEINTERFACE) h;
                
            // When accessing the below GUID I get an error:
            // "First-chance exception at 0x001c1a9d in TEST GUID Error.exe: 0xC0000005: Access violation writing location 0x00000000."
            printf("GUID: Data1: %x, Data2: %x, Data3: %x, Data4: %s \n", b->dbcc_classguid.Data1,
                b->dbcc_classguid.Data2, b->dbcc_classguid.Data3, b->dbcc_classguid.Data4);
                    
            // The following function ALWAYS fails.
            // GetLastError() gives the error "The parameter is incorrect"
            HDEVINFO hDevInfo = SetupDiGetClassDevs(&b->dbcc_classguid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
            if (hDevInfo == INVALID_HANDLE_VALUE) {
                 //printf("hDevInfo == INVALID_HANDLE_VALUE \n");
               outputLastError(_T("hDevInfo == INVALID_HANDLE_VALUE \n"));
            }

        }
        break;


#4 e‍dd   Members   -  Reputation: 2105

Like
0Likes
Like

Posted 05 January 2013 - 07:56 AM

MSDN says that lParam is 0 when wParam is DBT_DEVNODES_CHANGED (which IMHO, you should really assert on anyway). So your code behaves as expected -- undefined behaviour.

 

It appears you have copied the GUID passed to RegisterDeviceNotification from the MSDN example code. I don't know much about Windows' device handling but I have a strong suspicion that this GUID is not the one you should be using.

 

Have you tried adding DEVICE_NOTIFY_ALL_INTERFACE_CLASSES to the flags in your call to RegisterDeviceNotification()? In this case the GUID is ignored and you get messages for all devices. This may give you a better indication of what's really happening and help you detect your TV.

 

Just out of curiosity, are you attempting to detect your telly to automatically enable some kind of out-of-band debug console for a game? That would be cool :)



#5 gretty   Members   -  Reputation: 208

Like
0Likes
Like

Posted 05 January 2013 - 06:13 PM

I'll try adding DEVICE_NOTIFY_ALL_INTERFACE_CLASSES and see what messages I receive.

 

 

Just out of curiosity, are you attempting to detect your telly to automatically enable some kind of out-of-band debug console for a game? That would be cool smile.png

 

Nah, the ultimate goal is so when I connect my laptop to the TV it will open my folder that contains all my TV shows and start playing the video file I was playing when I last disconnected from the TV(maybe even at the same position/time in the file). I'm moving into a new unit and I'm too cheap to pay for Foxtel(cable TV) :P so I want this application to let me play tv shows off my laptop :)

 

The code above is the first step:

 - Detect a device arrival - get the class/interface GUID of the device

 - Determine if the connect device is a TV (I have no idea how I'll do this but I suspect using a SetupDi..() function which is why I need the GUID)

 - If the device is a TV:

    - Open the tv show folder

    - Start playing the video file I was playing when I last disconnected from the TV



#6 gretty   Members   -  Reputation: 208

Like
0Likes
Like

Posted 06 January 2013 - 02:11 AM

Thanks Edd :)

 

Adding that flag worked. Now I receive DBT_DEVICEARRIVAL message upon connection and the GUID is inside the structure also.






Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS