Obtaining a handle to a USB WebCam (Windows 10/CPP)

1

I'm trying to obtain a handle to my USB WebCam (Microsoft LifeCam HD-3000 ) device. I dont want to use it in a conventional way so usage of any multimedia framework are not considerable. I need to be able (if possible) to send to it IRP's via DeviceIoControl etc. Reversing its driver written in KMDF I found a call to WdfDeviceCreateDeviceInterface and GUID passed as an argument:

v1 = WdfDeviceCreateDeviceInterface(WdfDriverGlobals, device, &stru_FFFFF807650740C8, 0i64);

.rdata:FFFFF807650740C8 stru_FFFFF807650740C8 dd 0B94D388Ah           ; Data1
.rdata:FFFFF807650740C8                                         ; DATA XREF: internalEvtDeviceAdd+351↓o
.rdata:FFFFF807650740C8                 dw 7331h                ; Data2
.rdata:FFFFF807650740C8                 dw 4E5Eh                ; Data3
.rdata:FFFFF807650740C8                 db 8Bh, 0Fh, 8, 16h, 0Eh, 0A1h, 0F7h, 6; Data4

Python>getGUID(0xFFFFF807650740C8)
b94d388a-7331-4e5e-8b0f-08160ea1f706

Having an interface GUID I used the WinObjEx64 to find a symlink to created device:

Found symbolic link to usb webcam device

With symlink I attempted to open a handle:

int main()
{
    LPWSTR errormsg = NULL;
    DWORD errorCode;
    HANDLE h = CreateFile(L"\\\\.\\USB#VID_045E&PID_0779&MI_00#6&2bd7a9d&0&0000#{b94d388a-7331-4e5e-8b0f-08160ea1f706}",
                GENERIC_READ, // Only read access
                0,            // FILE_SHARE_READ | FILE_SHARE_WRITE
                NULL,         // no SECURITY_ATTRIBUTES structure
                OPEN_EXISTING,// No special create flags
                0,            // No special attributes
                NULL);        // No template file

    errorCode = GetLastError();
    printf("Error code: 0x%x\n", errorCode);
    if (h == INVALID_HANDLE_VALUE)
    {
        FormatMessageW(
            FORMAT_MESSAGE_ALLOCATE_BUFFER |
            FORMAT_MESSAGE_FROM_SYSTEM |
            FORMAT_MESSAGE_IGNORE_INSERTS,
            0,
            errorCode,
            MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
            (LPWSTR)&errormsg,
            0, NULL);

        wprintf(L"Error : %s\n", errormsg);
    }

    return 0;
}

Output:

Error code: 0x2
Error : The system cannot find the file specified.

With such result I decided to obtain a dev path using SetupDi* APIs


void GetInterfaceDevicePath(GUID* guid) {
    DWORD requiredSize;
    int MemberIdx = 0;
    HDEVINFO hDeviceInfoset = SetupDiGetClassDevs(guid, NULL, 0, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);
    if (hDeviceInfoset != INVALID_HANDLE_VALUE) {
        SP_DEVICE_INTERFACE_DATA DeviceInterfaceData = { 0 };
        DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
        while (SetupDiEnumDeviceInterfaces(hDeviceInfoset, NULL, guid, MemberIdx, &DeviceInterfaceData)) {
            MemberIdx++;
            SP_DEVINFO_DATA DeviceInfoData = { 0 };
            DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
            SetupDiGetDeviceInterfaceDetail(hDeviceInfoset, &DeviceInterfaceData, NULL, 0, &requiredSize, NULL);
            SP_DEVICE_INTERFACE_DETAIL_DATA* DevIntfDetailData = (SP_DEVICE_INTERFACE_DETAIL_DATA*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
                requiredSize);
            DevIntfDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
            if (SetupDiGetDeviceInterfaceDetail(hDeviceInfoset, &DeviceInterfaceData,
                DevIntfDetailData, requiredSize, &requiredSize, &DeviceInfoData)) {
                printf("DevicePath: %S\n", (TCHAR*)DevIntfDetailData->DevicePath);

                HANDLE h = CreateFileW(DevIntfDetailData->DevicePath,
                    0,
                    0,
                    NULL, 
                    OPEN_EXISTING,
                    0,
                    NULL);
                LPWSTR errormsg = NULL;
                DWORD error = GetLastError();
                printf("Error code: 0x%x\n", error);
                if (h == INVALID_HANDLE_VALUE)
                {
                    FormatMessageW(
                        FORMAT_MESSAGE_ALLOCATE_BUFFER |
                        FORMAT_MESSAGE_FROM_SYSTEM |
                        FORMAT_MESSAGE_IGNORE_INSERTS,
                        0,
                        error,
                        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                        (LPWSTR)&errormsg,
                        0, NULL);

                    wprintf(L"Error : %s\n", errormsg);
                }
            }
            HeapFree(GetProcessHeap(), 0, DevIntfDetailData);
        }
        SetupDiDestroyDeviceInfoList(hDeviceInfoset);
    }
}

int main()
{
    GUID deviceGUID;
    CLSIDFromString(L"{b94d388a-7331-4e5e-8b0f-08160ea1f706}", (LPCLSID)&deviceGUID);
    GetInterfaceDevicePath(&deviceGUID);
    return 0;
}

Unfortunately that also failed:

DevicePath: \\?\usb#vid_045e&pid_0779&mi_00#6&2bd7a9d&0&0000#{b94d388a-7331-4e5e-8b0f-08160ea1f706}
Error code: 0x2
Error : The system cannot find the file specified.

Output from livekd about how this driver is attached to the driver/device stack:

||1:lkd> !drvobj \Driver\LifeCamTrueColor
Driver object (ffffc60eba506750) is for:
 \Driver\LifeCamTrueColor

Driver Extension List: (id , addr)
(fffff80684f87330 ffffc60eb19f75f0)  
Device Object list:
ffffc60eb82f54e0  
||1:lkd> !devobj ffffc60eb82f54e0
Device object (ffffc60eb82f54e0) is for:
  \Driver\LifeCamTrueColor DriverObject ffffc60eba506750
Current Irp 00000000 RefCount 0 Type 0000002f Flags 00002000
SecurityDescriptor ffffdb888d07e660 DevExt ffffc60ec0deffb0 DevObjExt ffffc60eb82f5658 
ExtensionFlags (0000000000)  
Characteristics (0x00000100)  FILE_DEVICE_SECURE_OPEN
AttachedDevice (Upper) ffffc60eaba48b40 \Driver\ksthunk
AttachedTo (Lower) ffffc60ec2cdadf0 \Driver\usbvideo
Device queue is not busy.
||1:lkd> !drvobj \Driver\usbvideo
Driver object (ffffc60ebfde7e30) is for:
 \Driver\usbvideo

Driver Extension List: (id , addr)
(fffff8069aa2d130 ffffc60eb19f7560)  
Device Object list:
ffffc60ec2cdadf0  
||1:lkd> !devobj ffffc60ec2cdadf0
Device object (ffffc60ec2cdadf0) is for:
  \Driver\usbvideo DriverObject ffffc60ebfde7e30
Current Irp 00000000 RefCount 0 Type 0000002f Flags 00002000
SecurityDescriptor ffffdb888d07e660 DevExt ffffc60ec2cdaf60 DevObjExt ffffc60ec2cdaf68 
ExtensionFlags (0000000000)  
Characteristics (0x00000100)  FILE_DEVICE_SECURE_OPEN
AttachedDevice (Upper) ffffc60eb82f54e0 \Driver\LifeCamTrueColor
AttachedTo (Lower) ffffc60eb60e60a0 \Driver\usbccgp
Device queue is not busy.
||1:lkd> !drvobj \Driver\ksthunk
Driver object (ffffc60ea7777df0) is for:
 \Driver\ksthunk

Driver Extension List: (id , addr)
(fffff806993f80a0 ffffc60ea772e580)  
Device Object list:
ffffc60eaf67c7b0  ffffc60eaba48b40  ffffc60ea7bc4e10  ffffc60ea79a8e00
ffffc60ea7a15de0  ffffc60ea771bdf0  

||1:lkd> !devobj ffffc60eaba48b40
Device object (ffffc60eaba48b40) is for:
 000000d4 \Driver\ksthunk DriverObject ffffc60ea7777df0
Current Irp 00000000 RefCount 0 Type 0000002f Flags 00002040
SecurityDescriptor ffffdb888d07e660 DevExt ffffc60eaba48c90 DevObjExt ffffc60eaba48c98 
ExtensionFlags (0000000000)  
Characteristics (0x00000100)  FILE_DEVICE_SECURE_OPEN
AttachedTo (Lower) ffffc60eb82f54e0 \Driver\LifeCamTrueColor
Device queue is not busy.

Also a screens from DeviceTree

enter image description here enter image description here

Thanks!

driver
reverse-engineering
webcam
kmdf
wdf
asked on Stack Overflow Apr 21, 2020 by user3305379

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0