原创文章,转载请与作者联系,谢谢。 最近为公司开发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到答案。