原创文章,转载请与作者联系,谢谢。
最近为公司开发POS机用的热敏打印机驱动,USB接口,当USB printer一插上, WinCE总提示"Unidentified USB device"对话框,
而插入HP和EPSON的打印机就能正确认识,问题很奇怪,没有道理不支持公司的USB Printer啊,没办法,只好查看PB的源代码,
路径为:C:/WINCE420/PUBLIC/COMMON/OAK/DRIVERS/USB/CLASS/PRINTER(注: 根椐所安装PB的路径不同而不同).
问题在 lpc.c文件里的RegisterPrinterSettings(.....)函数中,
原码如下:
//#pragma warning( push )
//#pragma warning( disable : 4706 )
// assignment within conditional expression
/*++ Populates the Registry with our Printer Driver Settings [HKEY_LOCAL_MACHINE/Printers/ "Driver"="pcl.dll"
// names the DLL that contains the printer driver "High Quality"="300"
// the resolution of high-quality mode "Draft Quality"="150?
// the resolution of draft-quality mode (optional) "Color"="Monochrome"
// literal string 揅olor" -or- "Monochrome" --*/
BOOL RegisterPrinterSettings( PUSBPRN_CONTEXT pUsbPrn )
{
#define MAX_LEN 1024
char *p;
int i;
BOOL bRc = TRUE;
BYTE buf[MAX_LEN];
TCHAR tBuffer[MAX_LEN];
BYTE cDesc[MAX_LEN] = "Printers//";
DWORD dwIdLen,dwIndex;
REG_VALUE_DESCR keyValues[] = { (TEXT("Driver")), REG_SZ, 0, (PBYTE)(TEXT("pcl.dll")),
// 0 default: WCE currently does not support others, e.g. PostScript (TEXT("High Quality")), REG_SZ, 0, (PBYTE)(TEXT("300")),
// 1 default (TEXT("Draft Quality")), REG_SZ, 0, (PBYTE)(TEXT("150")),
// 2 default (TEXT("Color")), REG_SZ, 0, (PBYTE)(TEXT("Monochrome")),
// 3 default NULL, 0, 0, NULL // 4
};
DEBUGMSG(ZONE_LPT_INIT, (TEXT(">RegisterPrinterSettings/n")));
if (!pUsbPrn)
{
DEBUGMSG(ZONE_ERR, (TEXT("Invalid parameter/n")));
return FALSE;
}
// // read the ID string from the printer
// dwIdLen = GetDeviceId( pUsbPrn, buf, MAX_LEN);
if (dwIdLen)
{
// // parse for CMD //
// ...TBD //
// parse for Color support //
p = buf;
while( (p = strchr(p, '$'))!=NULL )
{
if (p[2] == 'C')
{
keyValues[3].Data = (PBYTE)(TEXT("Color"));
break;
}
p++;
}
// // parse for a Description string //
if ((p = strstr(buf, "DESCRIPTION:"))!=NULL)
p += sizeof("DESCRIPTION:") - 1;
else if ((p = strstr(buf, "DES:"))!=NULL)
p += sizeof("DES:") - 1;
else if ((p = strstr(buf, "MDL:"))!=NULL)
p += sizeof("MDL:") - 1;
else if ((p = strstr(buf, "MODEL:"))!=NULL)
p += sizeof("MODEL:") - 1;
if (p)
{
if (strchr(p, ';'))
{
i = strchr(p, ';') - p;
p[i] = 0;
}
else
{
i = strlen(p);
} // concat string to /Printers/
strncat( cDesc, p, MAX_LEN-1-strlen(cDesc));
for (dwIndex =0 ; dwIndex< MAX_LEN-1 && cDesc[dwIndex]!=0 ;dwIndex++)
tBuffer[dwIndex]=cDesc[dwIndex];
tBuffer[dwIndex]=0; // Terminated. DEBUGMSG(ZONE_LPT_INIT, (TEXT("DESCRIPTION: %s/n"), tBuffer ));
// // finally, add it to HKEY_LOCAL_MACHINE/Printers/ if it does not already exist. // bRc = GetSetKeyValues(tBuffer, &keyValues[0], SET, FALSE );
if ( !bRc )
{
DEBUGMSG( ZONE_ERR, (TEXT("GetSetKeyValues failed!/n")));
} }
else
{
DEBUGMSG(ZONE_ERR, (TEXT("Failed to find DES!/n"))); bRc = FALSE; } }
else
{
bRc = FALSE;
}
DEBUGMSG(ZONE_LPT_INIT, (TEXT("<RegisterPrinterSettings:%d/n"), bRc));
return bRc;
} //#pragma warning( pop )
在
// // parse for a Description string //
if ((p = strstr(buf, "DESCRIPTION:"))!=NULL)
p += sizeof("DESCRIPTION:") - 1;
else if ((p = strstr(buf, "DES:"))!=NULL) p += sizeof("DES:") - 1;
else if ((p = strstr(buf, "MODEL:"))!=NULL) p += sizeof("MODEL:") - 1;
加入:
else if ((p = strstr(buf, "MDL:"))!=NULL) p += sizeof("MDL:") -
1; 解决问题。
问题分析: 从国外网站的消息来看,应该是Microsoft公司WinCE的一个bug, Microsoft在GetDeviceID()后,开始对Device ID String 进行解析,
而在解析Device id string 时,并没有对MDL分段做提取.
因为按照IEEE-2xxx来说,USB configuration是支持MDL field的,所以应该是USB Printer Class Driver的问题。
此文并没有具体的分析问题如何一步一步怎么解决的,因为写得太麻烦了,
不过一篇文章对很多在写WinCE下的USB驱动开发的XDJM来说,应该有帮助。发现网上有很多人问这个问题,但没有google到答案。