问题描述
我正在尝试从USB 2.0相机获取数据。我正在尝试使用IOCTL_CHANGER_GET_STATUS的DeviceIOControl,并且返回错误,表示句柄无效。然后我尝试使用GetCommState,它说错误1说它不是现有的函数(我的程序中包含winbase.h和windows.h)。当我使用CreateFile()时,它确实有效,并且不会返回INVALID_HANDLE_VALUE错误代码。一切正常,直到我进入DeviceIOControl和GetCommState方法,它确实到达最后。在这一点上我不知道这是一个小错误,错误类型的GUID,或者我需要完全不同的方向。
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.
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());
}
我的尝试:
我的设备是GUID_DEVINTERFACE_USB_DEVICE然后我将其更改为GUID_CLASS_USB_DEVICE。我还将createfile从非重叠更改为重叠并从文件中删除共享。当我打印出InterfaceDetailData - >我得到的Devicepath
\\?\\\ b#vid_1908& pid_2310#5& 25c44976& 0& 3#{a5dcbf10-6530-11d2-901f-00c04fb951ed }
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}
推荐答案
#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.
通信资源是提供的物理或逻辑设备单个双向异步数据流。串行端口,并行端口,传真机和调制解调器是通信资源的示例。
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.
您的设备是一个不属于通信设备类别的网络摄像头。
类似于 IOCTL_CHANGER_GET_STATUS
IOCTL功能:
网络摄像头的驱动程序不支持。您应该尝试获取驱动程序的文档(通常包含在设备制造商提供的SDK中)以检查支持哪些功能。如果驱动程序支持该功能,则无论如何都需要文档,因为它包含返回数据的描述。
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.
这篇关于我的设备句柄是无效的,还是与COM编程功能不兼容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!