用VC++实现USB接口读写数据的程序

使用一个GUIDguidHID_1查找并打开一个USB设备

extern "C" int PASCAL SearchUSBDevice()
{
	HANDLE hUsb;

	int nCount, i, j;//标记同一设备个数
	HDEVINFO hDevInfoSet;
	BOOL bResult;

	PSP_DEVICE_INTERFACE_DETAIL_DATA pDetail =NULL;

	memset(m_sysversion, 0, 20);
	GetSysVersion(m_sysversion);

	// 检索相关GUID的USB设备总设备个数
	if (!GetUSBList())
	{
		return 0;
	}
	// 取得一个该GUID相关的设备信息集句柄
	hDevInfoSet = ::SetupDiGetClassDevs((LPGUID)&guidHID_1,//GUID_CLASS_USB_DEVICE, // class GUID
		NULL, // 无关键字
		NULL, // 不指定父窗口句柄
		DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); // 目前存在的设备

	// 失败...
	if (hDevInfoSet == INVALID_HANDLE_VALUE)
	{
		return NULL;
	}

	// 申请设备接口数据空间

	nCount = 0;
	bResult = TRUE;
	for (i=0; i< 34; i++)
	{
		bDeviceOpen[i] = FALSE;
		memset(m_DeviceDesc[i], 0, 256);
	}

	SP_DEVICE_INTERFACE_DATA ifdata;
	// 设备序号=0,1,2... 逐一测试设备接口,到失败为止
	while (bResult)
	{

		ifdata.cbSize = sizeof(ifdata);
		// 枚举符合该GUID的设备接口
		bResult = ::SetupDiEnumDeviceInterfaces(
			hDevInfoSet, // 设备信息集句柄
			NULL, // 不需额外的设备描述
			(LPGUID)&guidHID_1,//GUID_CLASS_USB_DEVICE, // GUID
			(ULONG)nCount, // 设备信息集里的设备序号
			&ifdata); // 设备接口信息

		if (bResult)
		{
			ULONG predictedLength = 0;
			ULONG requiredLength = 0;
			// 取得该设备接口的细节(设备路径)
			bResult = SetupDiGetInterfaceDeviceDetail(
				hDevInfoSet, // 设备信息集句柄
				&ifdata, // 设备接口信息
				NULL, // 设备接口细节(设备路径)
				0, // 输出缓冲区大小
				&requiredLength, // 不需计算输出缓冲区大小(直接用设定值)
				NULL); // 不需额外的设备描述
			// 取得该设备接口的细节(设备路径)
			predictedLength=requiredLength;

			// if(pDetail)
			// {
			// pDetail =NULL;
			// }
			pDetail = (PSP_INTERFACE_DEVICE_DETAIL_DATA)::GlobalAlloc(LMEM_ZEROINIT, predictedLength);
			pDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
			bResult = SetupDiGetInterfaceDeviceDetail(
				hDevInfoSet, // 设备信息集句柄
				&ifdata, // 设备接口信息
				pDetail, // 设备接口细节(设备路径)
				predictedLength, // 输出缓冲区大小
				&requiredLength, // 不需计算输出缓冲区大小(直接用设定值)
				NULL); // 不需额外的设备描述

			if (bResult)
			{
				// 复制设备路径到输出缓冲区
				//::strcpy(pszDevicePath[nCount], pDetail->DevicePath);
				if (strcmp(m_sysversion, "winnt")==0)
				{
					char ch[18];
					for(i=0;i<17;i++){
						ch[i]=*(pDetail->DevicePath+8+i);
					}
					ch[17]='\0';
					if (strcmp(ch,"vid_0471&pid_0666")==0)//比较版本号,防止意外出错
					{

						memset( &READ_OS, 0, sizeof( OVERLAPPED ) ) ;
						memset( &WRITE_OS, 0, sizeof( OVERLAPPED ) ) ;

						READ_OS.hEvent = CreateEvent( NULL, // no security
							TRUE, // explicit reset req
							FALSE, // initial event reset
							NULL ) ; // no name
						if (READ_OS.hEvent == NULL)
						{
							break;
						}

						WRITE_OS.hEvent = CreateEvent( NULL, // no security
							TRUE, // explicit reset req
							FALSE, // initial event reset
							NULL ) ; // no name
						if (NULL == WRITE_OS.hEvent)
						{
							CloseHandle( READ_OS.hEvent );
							break;
						}

						hUsb=CreateFile(pDetail->DevicePath,//&guidHID_1,//
							GENERIC_READ|GENERIC_WRITE,
							FILE_SHARE_READ|FILE_SHARE_WRITE,
							NULL,
							OPEN_EXISTING,
							FILE_ATTRIBUTE_NORMAL/*|
												 FILE_FLAG_OVERLAPPED*/,
												 NULL);
						if (hUsb != NULL)
						{
							// 比较定位找到的USB在哪个USB PORT上
							char id[30];
							memset(id, 0, 30);
							i=0;
							do
							{
								id[i]=*(pDetail->DevicePath+26+i);
								i++;
							}
							while(id[i-1]!='#');
							id[i-1] = '\0';
							for (j=0; j<34; j++)
							{
								if(strcmp(id, m_USBList[j])==0)
								{
									sprintf(m_DeviceDesc[j+1], "%s", pDetail->DevicePath);
									m_USBPositionMap[nCount] = j+1;
									break;
								}
							}

							CloseHandle(hUsb);
							nCount++;
							// break;
						}
					}// 比较驱动版本
				}// 比较操作系统版本
				else
				{
					memset( &READ_OS, 0, sizeof( OVERLAPPED ) ) ;
					memset( &WRITE_OS, 0, sizeof( OVERLAPPED ) ) ;

					READ_OS.hEvent = CreateEvent( NULL, // no security
						TRUE, // explicit reset req
						FALSE, // initial event reset
						NULL ) ; // no name
					if (READ_OS.hEvent == NULL)
					{
						break;
					}

					WRITE_OS.hEvent = CreateEvent( NULL, // no security
						TRUE, // explicit reset req
						FALSE, // initial event reset
						NULL ) ; // no name
					if (NULL == WRITE_OS.hEvent)
					{
						CloseHandle( READ_OS.hEvent );
						break;
					}

					hUsb=CreateFile(pDetail->DevicePath,//&guidHID_1,//
						GENERIC_READ|GENERIC_WRITE,
						FILE_SHARE_READ|FILE_SHARE_WRITE,
						NULL,
						OPEN_EXISTING,
						FILE_ATTRIBUTE_NORMAL/*|
											 FILE_FLAG_OVERLAPPED*/,
											 NULL);
					if (hUsb != NULL)
					{
						if(strcmp(pDetail->DevicePath, m_USBList[j])==0)
						{
							sprintf(m_DeviceDesc[j+1], "%s", pDetail->DevicePath);
							m_USBPositionMap[nCount] = j+1;
							break;
						}
						CloseHandle(hUsb);
						nCount++;
						// break;
					}
				}
			}
		}
	}
	// 释放设备接口数据空间
	::GlobalFree(pDetail);

	// 关闭设备信息集句柄
	::SetupDiDestroyDeviceInfoList(hDevInfoSet);

	iDeviceCount = nCount;

	return nCount;
}
// 写
BOOL Writestr(char *buf,int buflen, int index)
{
	BOOL fWriteStat;
	DWORD dwErrorFlags;
	DWORD dwError;
	COMSTAT ComStat;
	char szError[ 10 ] ;
	DWORD ret;
	int len, i, j, packet;
	div_t div_result;
	BYTE sendpacket[65];
	BYTE xorcode="0x00";

	if (m_gphdCom[index] == NULL) // no usb device(jk100c)
	{
		return -1;
	}

	div_result = div(buflen, 58);
	if (div_result.rem == 0)
	{
		packet = div_result.quot;
	}
	else
	{
		packet = div_result.quot+1;
	}
	for (i=0; i<packet; i++)
	{
		memset(sendpacket, 0, 65);
		if(i==packet-1)
		{
			// end packet
			if (div_result.rem == 0)
			{
				len = 58;
			}
			else
			{
				len = div_result.rem;
			}
		}
		else
		{
			len = 58;
		}
		sendpacket[0] = 0x13;
		sendpacket[1] = 3+len;
		sendpacket[2] = 0x01;
		sendpacket[3] = packet*16+i+1;
		memcpy(sendpacket+4, buf+(i*58), len);
		for(j=0;j<len+3;j++)
		{
			xorcode^=sendpacket[j+1];
		}
		sendpacket[len+4] = (char)xorcode;
		sendpacket[len+5] = 0x23;
		PurgeComm(m_gphdCom[index],PURGE_RXCLEAR|PURGE_TXCLEAR);
		// Sleep(10);
		fWriteStat = WriteFile(m_gphdCom[index], sendpacket, len+6,&ret, NULL);
		if (!fWriteStat)
		{
			if(GetLastError() == ERROR_IO_PENDING)
			{
				dwError = GetLastError();
				// an error occurred, try to recover
				wsprintf( szError, "\n\r <CE-%u>", dwError ) ;
				OutputDebugString(szError);
				ClearCommError(m_gphdCom[index], &dwErrorFlags, &ComStat ) ;
				if (dwErrorFlags >0)
				{
					wsprintf( szError, "\n\r <CE-%u>", dwErrorFlags ) ;
					OutputDebugString(szError);
				}
			}
			else
			{
				// some other error occurred
				ClearCommError(m_gphdCom[index], &dwErrorFlags, &ComStat ) ;
				if (dwErrorFlags > 0)
				{
					wsprintf( szError, "\n\r <CE-%u>", dwErrorFlags ) ;
					OutputDebugString(szError);
				}
				return FALSE;
			}
		}
		if (i != packet-1)
		{
			// should be receive ack
			if (ReceivePacketAnswer(index) != 0)
			{
				return FALSE;
			}
		}
	}

	return TRUE;
}

// 读
int Readstr(char *buf,int nMaxLength, int index)
{
	BOOL fReadStat ;
	COMSTAT ComStat;
	DWORD dwErrorFlags;
	DWORD dwLength;
	DWORD dwError;
	char szError[ 10 ];

	if (fCOMMOpened==0)
	{
		return FALSE; //串口未打开
	}

	// only try to read number of bytes in queue
	ClearCommError(m_gphdCom[index], &dwErrorFlags, &ComStat) ;
	//dwLength = min( (DWORD) nMaxLength, ComStat.cbInQue ) ;

	dwLength=nMaxLength;
	if (dwLength > 0)
	{
		if (olap==TRUE)
		{
			fReadStat = ReadFile(m_gphdCom[index],buf, dwLength, &dwLength,&READ_OS) ;
			if (!fReadStat)
			{
				if (GetLastError() == ERROR_IO_PENDING)
				{
					OutputDebugString("\n\rIO Pending");
					while(!GetOverlappedResult(m_gphdCom[index], &READ_OS,
						&dwLength, TRUE ))
					{
						dwError = GetLastError();
						if(dwError == ERROR_IO_INCOMPLETE) continue;
						else
						{
							// an error occurred, try to recover
							ClearCommError(m_gphdCom[index],&dwErrorFlags, &ComStat ) ;
							break;
						}
					}
				}
				else // end-----if (GetLastError() == ERROR_IO_PENDING)
				{
					// some other error occurred
					dwLength = 0 ;
					ClearCommError(m_gphdCom[index], &dwErrorFlags, &ComStat ) ;
					if (dwErrorFlags >0)
					{
						wsprintf( szError, "\n\r <CE-%u>", dwErrorFlags ) ;
						OutputDebugString(szError);
					}
				}
			} // end-----if (!fReadStat)
		} // end-----if (olap==TRUE)
		else
		{
			fReadStat = ReadFile( m_gphdCom[index],buf, dwLength, &dwLength, NULL ) ;
			if (!fReadStat)
			{
				dwError = GetLastError();
				ClearCommError(m_gphdCom[index],&dwErrorFlags, &ComStat ) ;

				if (dwErrorFlags >0)
				{
					wsprintf( szError, "\n\r <CE-%u>", dwErrorFlags ) ;
					OutputDebugString(szError);
				}
			}
			PurgeComm(m_gphdCom[index],PURGE_RXCLEAR|PURGE_TXCLEAR);
		}
	}

	return dwLength;
}

(本文来自:http://bbs.ednchina.com/BLOG_ARTICLE_14969.HTML)

申明:未加转载说明即为原创文章,转载请注明:

转自Roboby's Home 链接:用VC++实现USB接口读写数据的程序


  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值