解决USB 打印机错误问题

    技术2022-05-13  20

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

     


    最新回复(0)