Click here to Skip to main content
15,881,852 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I am trying to get data from a USB 2.0 camera. I am trying DeviceIOControl with IOCTL_CHANGER_GET_STATUS and I get a return of error saying that the handle is invalid. Then I tried using GetCommState and it says error 1 saying that it is not an existing function(I do have winbase.h and windows.h included in my program). When I use CreateFile() it does work and doesn't return an INVALID_HANDLE_VALUE error code. Everything works properly up until I get to the DeviceIOControl and GetCommState methods, it does reach to the end too. at this point I do not know if it is a small error, wrong type of GUID, or an entirely different direction I need to go with this.

C++
if((webdevices = SetupDiGetClassDevs(&GUID_DEVINTERFACE_USB_DEVICE,NULL,NULL,(DIGCF_PRESENT|DIGCF_DEVICEINTERFACE))) != NULL){
            printf("SetupDiGetClassDevs Worked!!\n");
    }else{
        printf("SetupDiGetClassDevs didn't work error %d\n",GetLastError());
    }

    webDevInfoDat->cbSize = sizeof(SP_DEVINFO_DATA);
    webInterDat->cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
    SetupDiEnumDeviceInfo(webdevices,i,webDevInfoDat);
    while(sdei = SetupDiEnumDeviceInterfaces(webdevices,NULL,&GUID_DEVINTERFACE_USB_DEVICE,i,webInterDat)){

        if(SetupDiGetDeviceInterfaceDetail(webdevices,webInterDat,webInterDetDat,interDetSiz,&reqInterDetSiz,webDevInfoDat)){

            printf("Interface Detail Data\nDevicePath: %s\nRequired Size: %d\n",webInterDetDat->DevicePath,reqInterDetSiz);
            
        }else{
            printf("Getting SetupDiGetDeviceDetail error %d RequiredSize %d\n",GetLastError(),reqInterDetSiz);
        }

            webcam = CreateFile(webInterDetDat->DevicePath,(GENERIC_READ|GENERIC_WRITE),0,NULL,OPEN_EXISTING,0,NULL);
            if(webcam == INVALID_HANDLE_VALUE){
            printf("Creating File didn't work %d\n",GetLastError());
            }else{
                printf("Creating File did work\n");
                if(webInterDetDat->DevicePath[13] != '9'){//to make sure it is the camera
                    CloseHandle(webcam);
                }else{
                    printf("save this file\n");
                    break;
                }
            }

        printf("\n");
        i++;
        webInterDat->cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
    }

/*********************************************
get device media information with IO control
*************************************************/

    if(DeviceIoControl(webcam,IOCTL_CHANGER_GET_STATUS,NULL,0,NULL,0,&sizeOfgCP,&oLap) != 0){
        printf("Getting CHANGER_GET_STATUS worked %d\n",sizeOfgCP);
    }else{
        printf("Getting CHANGER_GET_STATUS failed. error %d\nRequired Size %d\n",GetLastError(),sizeOfgCP);
    }
    if(GetCommState(webcam,&webcamDCB) != 0){
      printf("Getting GetCommState worked! baud rate is %d\n",webcamDCB.BaudRate);
    }else{
        printf("Getting GetCommState failed %d\n",GetLastError());
    }


What I have tried:

My device is a GUID_DEVINTERFACE_USB_DEVICE then I changed it to GUID_CLASS_USB_DEVICE. I have also changed the createfile from non-overlapped to overlapped and removed sharing from the file. When I print out the InterfaceDetailData -> Devicepath I get

\\?\usb#vid_1908&pid_2310#5&25c44976&0&3#{a5dcbf10-6530-11d2-901f-00c04fb951ed}
Posted
Updated 21-May-17 23:19pm
v2
Comments
KarstenK 21-May-17 4:25am    
Read the documentation of these function carefully. Some handles arent only valid for some function. Check all rights and flags.

Good luck.

Your code seems to be confused and lacking initialization.
This one, fast & dirty fixing, work compiled as plain C:
C++
#include <windows.h>
#include <SetupAPI.h>
#include <stdio.h>
#include <stddef.h>

GUID GUID_DEVINTERFACE_USB_DEVICE = {0xA5DCBF10, 0x6530, 0x11D2, {0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED}};

HANDLE webcam = NULL;

/*
 *	get device media information with IO control
 */
void UseDeviceIoControl(HANDLE hwebcam)
{
	DWORD sizeOfgCP = 0;
	OVERLAPPED oLap = {0};
	if (DeviceIoControl(hwebcam, IOCTL_CHANGER_GET_STATUS, NULL, 0, NULL, 0, &sizeOfgCP, &oLap) != 0)
	{
		printf("Getting CHANGER_GET_STATUS worked %d\n", sizeOfgCP);
	}
	else
	{
		printf("Getting CHANGER_GET_STATUS failed. error %d\nRequired Size %d\n", GetLastError(), sizeOfgCP);
	}
	DCB webcamDCB;
	if (GetCommState(webcam, &webcamDCB) != 0)
	{
		printf("Getting GetCommState worked! baud rate is %d\n", webcamDCB.BaudRate);
	}
	else
	{
		printf("Getting GetCommState failed %d\n", GetLastError());
	}
}

int main(void)
{
	HDEVINFO webdevices;

	if ((webdevices = SetupDiGetClassDevs(&GUID_DEVINTERFACE_USB_DEVICE, NULL, NULL, (DIGCF_PRESENT | DIGCF_DEVICEINTERFACE))) != NULL)
	{
		printf("SetupDiGetClassDevs Worked!!\n");
	}
	else
	{
		printf("SetupDiGetClassDevs didn't work error %d\n", GetLastError());
	}
	SP_DEVINFO_DATA webDevInfoDat;
	webDevInfoDat.cbSize = sizeof(SP_DEVINFO_DATA);
	SP_DEVICE_INTERFACE_DATA webInterDat;
	webInterDat.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);

	int i=0;
	SetupDiEnumDeviceInfo(webdevices, i, &webDevInfoDat);

	BOOL sdei;
	while (TRUE == (sdei = SetupDiEnumDeviceInterfaces(webdevices, NULL, &GUID_DEVINTERFACE_USB_DEVICE, i, &webInterDat)))
	{
		printf ("Device%d) ", i);
		PSP_DEVICE_INTERFACE_DETAIL_DATA_A pwebInterDetDat = NULL;
		DWORD interDetSiz = 0;
		DWORD reqInterDetSiz = 0;
		DWORD err = SetupDiGetDeviceInterfaceDetail(webdevices, &webInterDat, pwebInterDetDat, interDetSiz, &reqInterDetSiz, &webDevInfoDat);
		if (ERROR_INSUFFICIENT_BUFFER != GetLastError())
		{
			printf("SetupDiGetDeviceInterfaceDetail failed!\n");
			ExitProcess(1);
		}
		pwebInterDetDat = malloc(reqInterDetSiz);
		pwebInterDetDat->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);
		interDetSiz = reqInterDetSiz;
		if (SetupDiGetDeviceInterfaceDetail(webdevices, &webInterDat, pwebInterDetDat, interDetSiz, &reqInterDetSiz, &webDevInfoDat))
		{
			printf("Interface Detail Data\nDevicePath: %s\nRequired Size: %d\n", pwebInterDetDat->DevicePath, reqInterDetSiz);

		}
		else
		{
			printf("Getting SetupDiGetDeviceDetail error %d RequiredSize %d\n", GetLastError(), reqInterDetSiz);
		}
		webcam = CreateFile(pwebInterDetDat->DevicePath, (GENERIC_READ | GENERIC_WRITE), 0, NULL, OPEN_EXISTING, 0, NULL);
		if (webcam == INVALID_HANDLE_VALUE)
		{
			printf("Creating File didn't work %d\n", GetLastError());
		}
		else
		{
			printf("Creating File did work\n");
			if (pwebInterDetDat->DevicePath[13] != '9')
			{	//to make sure it is the camera
				CloseHandle(webcam);
			}
			else
			{
				printf("save this file\n");
				UseDeviceIoControl(webcam);
				break;
			}
		}
		printf("\n");
		i++;
		webInterDat.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
		free(pwebInterDetDat);
	}
}

Note the dynamic allocation of buffers as required by system.
Of course the code lacks of extended error checks.
 
Share this answer
 
v2
Comments
Member 12701845 22-May-17 0:01am    
I tried your solution and it is still not working for me. I now get error 1 for both of the functions still. Did you get the functions to work properly without when you ran it?
The INVALID_HANDLE_VALUE error is solved by solution 1.

The GetCommState function (Windows)[^] functions returns ERROR_INVALID_FUNCTION because that function is not supported by the device driver. The reason for not being supported is obvious:
A communications resource is a physical or logical device that provides a single bidirectional, asynchronous data stream. Serial ports, parallel ports, fax machines, and modems are examples of communications resources.
Your device is a web cam which does not belong to the class of communications devices.

Similar for the IOCTL_CHANGER_GET_STATUS IOCTL function:
It is not supported by the driver of your web cam. You should try to get the documentation for the driver (often included with the SDK provided by the device manufacturer) to check which functions are supported. If a driver supports that function you need the documentation anyway because it contains the description of the returned data.
 
Share this answer
 
Comments
Member 12701845 23-May-17 20:43pm    
I have tried doing different methods with GUID_DEVINTERFACE_USB_DEVICE but none of them seem to work. It looks like only DeviceIOControl has public methods for GUID_DEVINTERFACE_USB_HUB, GUID_DEVINTERFACE_USB_HOST_CONTROLLER. I learned what codes worked with them by looking at the header file they're declared in and them from the microsoft website to get more detail on that.

https://msdn.microsoft.com/en-us/library/windows/hardware/ff537236%28v=vs.85%29.aspx

I'll just have to work on it from there at this point. thank you for the help

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900