Click here to Skip to main content
15,887,313 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
I'm writing a program which needs to read data from usb device. I looked up msdn, that i know Readfile function can do this,so I used this, but it never works. The program can write data to USB device but can't read and when I add parameter 'GENERIC_READ' in the function createfile ,the program can detect the USB device. As I debug I found that the errorcode is 5. Please help. This is 911. Thanks a lot.
bool CUSB::InitUSB()
{
          
	VendorID=0X040B;  
	ProductID=0X6515;
	
	GUID guidHID;
	HidD_GetHidGuid(&guidHID);   
	HDEVINFO hDevInfo;
	hDevInfo = SetupDiGetClassDevs(&guidHID,
		NULL,
		0,   
		DIGCF_PRESENT|DIGCF_INTERFACEDEVICE);
	if(hDevInfo == INVALID_HANDLE_VALUE) 
	{
		return false;
	}
	SP_DEVICE_INTERFACE_DATA strtInterfaceData;
	strtInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
	
	DWORD index = 0;
	CString temp;
	BOOL findFlag = false;
	int i = 0;
	while(1)
	{
		if(!SetupDiEnumDeviceInterfaces(hDevInfo, 
			NULL, 
			&guidHID, 
			i,
			&strtInterfaceData))   
		{
			break;
		}
		i++;
		if(strtInterfaceData.Flags == SPINT_ACTIVE )
		{
	
			DWORD strSize = 0, requiesize = 0;
			SetupDiGetDeviceInterfaceDetail(hDevInfo, 
				&strtInterfaceData, 
				NULL, 
				0, 
				&strSize, 
				NULL);
			requiesize = strSize;  
			PSP_DEVICE_INTERFACE_DETAIL_DATA strtDetailData;
			strtDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(requiesize);
			strtDetailData -> cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
			SP_DEVINFO_DATA infodata;
			infodata.cbSize = sizeof(SP_DEVINFO_DATA);
			if(!SetupDiGetDeviceInterfaceDetail(hDevInfo, 
				&strtInterfaceData,
				strtDetailData, 
				strSize, 
				&requiesize, 
				NULL))
			{
				free(strtDetailData);
				break;
			}
			CString str = strtDetailData -> DevicePath;
		
			hDevice = CreateFile(strtDetailData->DevicePath,
			    GENERIC_WRITE|GENERIC_READ,
				FILE_SHARE_READ|FILE_SHARE_WRITE,
				NULL, 
				OPEN_EXISTING, 
				0, 
				NULL); 
			 DWORD dwError = GetLastError(); 
             CString str1; 
             str1.Format(_T("Error Code :[%d]"), dwError); 
             AfxMessageBox(str1);
			if(hDevice == INVALID_HANDLE_VALUE)
			{
				
				free(strtDetailData);
				break;
			}
			
			HIDD_ATTRIBUTES strtAttrib;
			strtAttrib.Size = sizeof(HIDD_ATTRIBUTES);
		
			if(!HidD_GetAttributes(hDevice, &strtAttrib))  
			{
				free(strtDetailData);
				break;
			}
		 
			if(strtAttrib.VendorID == VendorID)
			{
				if(strtAttrib.ProductID ==ProductID)  
				{
			
					PHIDP_PREPARSED_DATA preparsedData;
					HidD_GetPreparsedData(hDevice, &preparsedData);
					HIDP_CAPS capabilities;
					HidP_GetCaps(preparsedData, &capabilities);
					if(capabilities.OutputReportByteLength == 9) 
					{
						
						findFlag = true;   
						free(strtDetailData);
						break;
					}
				}
			}
			free(strtDetailData);
		}
	}
	
	SetupDiDestroyDeviceInfoList(hDevInfo);   
	
	if(findFlag == false) 
	{
		return false;
	}
	else 
	{
		return true;
	}  
}

bool CUSB::WriteUSB(char *Data)
{
	if(hDevice==INVALID_HANDLE_VALUE)
		return false;

	PHIDP_PREPARSED_DATA preparsedData;
	HidD_GetPreparsedData(hDevice, &preparsedData);
 
	HIDP_CAPS capabilities;
	HidP_GetCaps(preparsedData, &capabilities);
	memset(SendDataBuffer, 0, 9);
	SendDataBuffer[4]=*Data; 
	bool succ =false;
	unsigned long nWriteBytes;

     succ = WriteFile(hDevice,
                     SendDataBuffer, 
                     capabilities.OutputReportByteLength,
                     &nWriteBytes,
					 NULL);
	return succ;
    
}
bool CUSB::ReadUSB(char RecieveDataBuffer[])
{
	unsigned long length;
	if(hDevice==INVALID_HANDLE_VALUE)
		return false;
	char readBuffer[32];
	length = 32;
	memset(&readBuffer,0,32);
	memset(&RecieveDataBuffer,0,32);
    PHIDP_PREPARSED_DATA preparsedData;
	HidD_GetPreparsedData(hDevice,&preparsedData);
	HIDP_CAPS capabilities;
	HidP_GetCaps(preparsedData,&capabilities);
	memset(RecieveDataBuffer, 0, 9);
	bool succ = false;
	unsigned long nWriteBytes;
	succ = ReadFile(hDevice,RecieveDataBuffer,capabilities.OutputReportByteLength,&nWriteBytes,NULL);
	DWORD dwError = GetLastError(); 
             CString str1; 
             str1.Format(_T("Error Code :[%d]"), dwError); 
             AfxMessageBox(str1);
	memcpy(&RecieveDataBuffer,&readBuffer,32);
return succ;
}
Posted
Updated 15-Mar-11 15:35pm
v3
Comments
JF2015 14-Mar-11 2:40am    
Modified to add code formatting.
markfilan 14-Mar-11 2:49am    
sorry, it's a little mess, but do u know how to solve this ?thanks!
markfilan 14-Mar-11 2:51am    
and the below is the descriptor of the device:
Device Descriptor:
bcdUSB: 0x0110
bDeviceClass: 0x00
bDeviceSubClass: 0x00
bDeviceProtocol: 0x00
bMaxPacketSize0: 0x08 (8)
idVendor: 0x040B (Weltrend Semiconductor)
idProduct: 0x6515
bcdDevice: 0x0102
iManufacturer: 0x01
iProduct: 0x02
iSerialNumber: 0x00
bNumConfigurations: 0x01

ConnectionStatus: DeviceConnected
Current Config Value: 0x01
Device Bus Speed: Low
Device Address: 0x01
Open Pipes: 2

Endpoint Descriptor:
bEndpointAddress: 0x81
Transfer Type: Interrupt
wMaxPacketSize: 0x0008 (8)
bInterval: 0x0A

Endpoint Descriptor:
bEndpointAddress: 0x02
Transfer Type: Interrupt
wMaxPacketSize: 0x0008 (8)
bInterval: 0x0A

An error code of 5 means 'Access denied'. This is strange, if you are able to write a file. Can you show the code where you call ReadUSB()? Have you verified that a file was actually written?
 
Share this answer
 
Comments
markfilan 14-Mar-11 21:01pm    
i can write data to the usb device.here are the code where call ReadUSB:
m_USB.ReadUSB(RecieveDataBuffer);
DWORD dwError = GetLastError();
CString str;
str.Format(_T("Error Code :[%d]"), dwError);
AfxMessageBox(str);
m_Gridctrl.SetItemText(row,4,RecieveDataBuffer);
markfilan 14-Mar-11 21:02pm    
i thought is that pssible beacause the USB is described as a keyboard that made me can not read data from it .
It has maybe nothing to do with your problem but be careful with your memset and memcpy functions. In your ReadUSB function, your are passing the buffer address instead of the buffer itself.

Replace these lines:
C++
...
memset(&readBuffer, 0, 32);
...
memset(&RecieveDataBuffer, 0, 32);
...
memcpy(&RecieveDataBuffer, &readBuffer, 32);

By these ones:
XML
...
memset(readBuffer, 0, 32);
...
memset(RecieveDataBuffer, 0, 32);
...
memcpy(RecieveDataBuffer, readBuffer, 32);
 
Share this answer
 
Comments
markfilan 14-Mar-11 21:03pm    
i will try ,thanks .but do u know why createfile can not complete successfully?
Olivier Levrey 15-Mar-11 5:18am    
I have little knowledge in device drivers but I think it depends on the driver implementation. If you want to use GENERIC_READ or GENERIC_WRITE flags, the driver should implement theses functions. Maybe the driver you are using doesn't support ReadFile and you need to use DeviceIoControl instead. But once again, I don't much about drivers.
Kurt Degiorgio 16-Mar-11 4:04am    
yes it is possible that the driver has not implemented READ and WRITE IOCTLS, but if it is a USB device it normally uses the generic USB Driver provided by Microsoft, also in order to use DeviceIoControl you need to have access to the IOCTL codes.
I had a similar problem with the COM port, perhaps this may help you. Use the functions:
* _open
* _write
* _read
* _close

#include <io.h>
#include <fcntl.h>

int main(int argc,char* argv[])
{
  int      file = _open("COM3",_O_RDWR | _O_BINARY);
  char    a[1]={0};
  int      err;

  if(file)
  {
    #define  LED_OFF    "\x5A\x10\x0E\x00"
    #define VENDOR_ID  "\x5A\x01\x00\x00"

    err = _write(file,VENDOR_ID,4);
    err = _read(file,a,1);
    err = _write(file,LED_OFF,4);

    _close(file);
  }

  return 1;
}
 
Share this answer
 
v3
Comments
markfilan 15-Mar-11 21:30pm    
I GOOGLED this function,but i did not understand it well,I can use this function to open the USB device without enumeration?
mbue 16-Mar-11 7:12am    
1. Your original question was about ReadFile problem, right?
2. I told you to use these functions to use instead CreateFile, ReadFile, WriteFile and so on.
3. You can use the functions to open, read and write named devices too.
4. This is code from my problem (only as example for you), that solved my problem to read/write a named device.
Regards.
markfilan 20-Mar-11 20:49pm    
so, the first parameter I should use the name of the device?
pls,everybody help me ~ I'm doing this 4 a couple of days.but still can not find a way 2 solve this .
 
Share this answer
 
Comments
Kurt Degiorgio 16-Mar-11 5:54am    
Can you please provide more information on the USB device you are copying the information to? (i.e are you able to manually copy a file or read to it through windows explorer)
markfilan 16-Mar-11 20:45pm    
it can't read by winodws explorer or manullly copy a file .what i provided above is all i no about the device .

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