Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Windows 10 WebUSB printing issues with Zebra LP2844 DOMException: Access denied

In a project I'm trying to use the WebUSB API available in Chrome to print using a Zebra LP2844 printer.

I succeeded on OSX without issues and eventually on Ubuntu and on ChromeOS thanks to this post that talked about unbinding the kernel driver so Chrome was able to access the device.

The page I'm using for this is served though https as the documentation requires it.

On Windows 10 however, I'm able to connect to the printer with navigator.usb.requestDevice as shown here

connected printer

but when I call open() on the connected printer during the print routine, I keep getting the next error

Error DOMException: Access denied.

Here is the print method code:

print : async function(printString) {
    let startTime = new Date().getTime();

    if (!this.pairedPrinter) {
      console.log("No printer connected");
      return;
    }

    try {
      if (!this.pairedPrinter.opened) {
        await this.pairedPrinter.open();
      }

      await this.pairedPrinter.claimInterface(0);

      let encoder = new TextEncoder();
      const printBuffer = encoder.encode(printString);

      let printResult = await this.pairedPrinter.transferOut(6, printBuffer);

      await this.pairedPrinter.releaseInterface(0);

      await this.pairedPrinter.close();

    } catch (err) {
      console.log("Error");
      console.log(err);
    } finally {
      let endTime = new Date().getTime();
      let printTime = endTime - startTime;
      console.log("Print time: " + printTime + " ms");
    }
}

I found a similar question here, that points to this other answer. It makes perfect sense that the default driver being installed by Windows when I plug the printer prevents Chrome from accessing it (just like Ubuntu does).

So, I implemented a custom .inf file as described here.

This is my inf file

;
;
; Installs WinUsb
;

; =================== Strings ===================

[Strings]
ManufacturerName = "Zebra"
ClassName = "Universal Serial Bus devices"
DeviceName = "Aeropost Zebra LP2844"
SourceName = "Aeropost Zebra LP2844 Install Disk"
DeviceID   = "VID_0A5F&PID_0009"
DeviceGUID = "{c3bd2e26-7e03-4189-8c9d-852faf628494}"
REG_MULTI_SZ = 0x00010000

[Version]
Signature = "$Windows NT$"
Class     = Printer
ClassGuid = {4d36e979-e325-11ce-bfc1-08002be10318}
Provider  = %ManufacturerName%
CatalogFile = zebrawinusb.cat
DriverVer = 03/02/2018,1.0.0.0

; ========== Class definition ===========

[ClassInstall32]
AddReg = ClassInstall_AddReg

[ClassInstall_AddReg]
HKR,,,0,"Universal Serial Bus devices"
HKR,,Icon,,-20

; ========== Manufacturer/Models sections ===========

[Manufacturer]
%ManufacturerName% = Standard,NTx86
%ManufacturerName% = Standard,NTamd64

[Standard.NTx86]
%DeviceName% = USB_Install, USB\%DeviceID%

[Standard.NTamd64]
%DeviceName% = USB_Install, USB\%DeviceID%

; =================== Installation ===================

[USB_Install]
Include = winusb.inf
Needs   = WINUSB.NT

[USB_Install.Services]
Include = winusb.inf
Needs   = WINUSB.NT.Services

[USB_Install.Wdf]
KmdfService = WINUSB, WinUsb_Install

[WinUSB_Install]
KmdfLibraryVersion = 1.11

[USB_Install.HW]
AddReg=Dev_AddReg

[Dev_AddReg]
HKR,,DeviceInterfaceGUIDs,0x10000,%DeviceGUID%

[USB_Install.CoInstallers]
AddReg = CoInstallers_AddReg
CopyFiles = CoInstallers_CopyFiles

[CoInstallers_AddReg]
HKR,,CoInstallers32,0x00010000,"WdfCoInstaller01011.dll,WdfCoInstaller","WinUsbCoInstaller2.dll"

[CoInstallers_CopyFiles]
WinUsbCoInstaller2.dll
WdfCoInstaller01011.dll

[DestinationDirs]
; If your INF needs to copy files, you must not use the DefaultDestDir directive here.  
CoInstallers_CopyFiles=11
; ================= Source Media Section =====================

[SourceDisksNames]
1 = %SourceName%

[SourceDisksFiles.x86]
WinUSBCoInstaller2.dll = 1,x86
WdfCoInstaller01011.dll = 1,x86

[SourceDisksFiles.x64]
WinUSBCoInstaller2.dll = 1,x64
WdfCoInstaller01011.dll = 1,x64

Built the driver using inf2cat, test-signed it and when I try to update the printer driver to use it, it fails with error "the file specified could not be found (0x00000002)".

setupapi.dev.log file provides no info whatsoever about which file is not being found though.

Here's the log file for the driver update process:

>>>  [Device Install (DiShowUpdateDevice) - USBPRINT\ZEBRA_LP2844_\6&3295E28F&3&USB001]
>>>  Section start 2018/03/02 16:14:00.023
      cmd: "C:\WINDOWS\system32\mmc.exe" C:\WINDOWS\system32\devmgmt.msc
     dvi: {DIF_UPDATEDRIVER_UI} 16:14:00.023
     dvi:      Class installer: Enter 16:14:00.023
     dvi:      Class installer: Exit
     dvi:      Default installer: Enter 16:14:00.039
     dvi:      Default installer: Exit
     dvi: {DIF_UPDATEDRIVER_UI - exit(0xe000020e)} 16:14:00.054
     ndv: {Update Driver Software Wizard - USBPRINT\ZEBRA_LP2844_\6&3295E28F&3&USB001}
     dvi:      {DIF_SELECTDEVICE} 16:14:05.662
     dvi:           Class installer: Enter 16:14:05.678
     dvi:           Class installer: Exit
     dvi:      {DIF_SELECTDEVICE - exit(0xe000020e)} 16:14:05.678
     dvi:      {DIF_SELECTDEVICE} 16:14:12.148
     dvi:           Class installer: Enter 16:14:12.148
     dvi:           Class installer: Exit
     dvi:      {DIF_SELECTDEVICE - exit(0xe000020e)} 16:14:12.163
     ndv:      Driver package 'C:\WINDOWS\System32\DriverStore\FileRepository\zebrawinusb.inf_amd64_ddcc3ed00fd3e8a8\zebrawinusb.inf' is already imported.
     sto:      {Setup Import Driver Package: c:\zebrawinusbdriver\zebrawinusb.inf} 16:14:16.158
     sto:           Driver package already imported as 'oem20.inf'.
     sto:      {Setup Import Driver Package - exit (0x00000000)} 16:14:16.180
     dvi:      Searching for hardware ID(s):
     dvi:           usbprint\zebra_lp2844_5bc4
     dvi:           zebra_lp2844_5bc4
     dvi:      Class GUID of device remains: {4d36e979-e325-11ce-bfc1-08002be10318}.
     dvi:      {Plug and Play Service: Device Install for USBPRINT\ZEBRA_LP2844_\6&3295E28F&3&USB001}
     dvi:           Driver INF Path: C:\WINDOWS\INF\oem20.inf
     dvi:           Driver Node Name: zebrawinusb.inf:c14ce8840c48fa1f:USB_Install:1.0.0.0:usb\vid_0a5f&pid_0009,
     dvi:           Driver Store Path: C:\WINDOWS\System32\DriverStore\FileRepository\zebrawinusb.inf_amd64_ddcc3ed00fd3e8a8\zebrawinusb.inf
     dvi:           Searching for hardware ID(s):
     dvi:                usbprint\zebra_lp2844_5bc4
     dvi:                zebra_lp2844_5bc4
     dvi:           Class GUID of device changed to: {4d36e979-e325-11ce-bfc1-08002be10318}.
     dvi:           {Core Device Install} 16:14:16.313
!    pol:                Selected driver node does not match this device (force-install)
     dvi:                {Install Device - USBPRINT\ZEBRA_LP2844_\6&3295E28F&3&USB001} 16:14:16.316
     dvi:                     Device Status: 0x0180200a, Problem: 0x0 (0x00000000)
     dvi:                     Parent device: USB\VID_0A5F&PID_0009\42J113802152
!    dvi:                     Unable to determine matching device ID for oem20.inf. Error = 0xE0000228
!    dvi:                     Unable to configure device, falling back to standard device installation.
     dvi:                     {DIF_ALLOW_INSTALL} 16:14:16.324
     dvi:                          Using exported function 'ClassInstall32' in module 'C:\WINDOWS\system32\ntprint.dll'.
     dvi:                          Class installer == ntprint.dll,ClassInstall32
     dvi:                          Class installer: Enter 16:14:16.336
     dvi:                          Class installer: Exit
     dvi:                          Default installer: Enter 16:14:16.340
     dvi:                          Default installer: Exit
     dvi:                     {DIF_ALLOW_INSTALL - exit(0xe000020e)} 16:14:16.342
     dvi:                     {DIF_INSTALLDEVICEFILES} 16:14:16.343
     dvi:                          Class installer: Enter 16:14:16.344
!!!  dvi:                          Class installer: failed(0x00000002)!
     dvi:                     {DIF_INSTALLDEVICEFILES - exit(0x00000002)} 16:14:16.383
!    dvi:                     Queueing up error report for device install failure.
     dvi:                {Install Device - exit(0x00000002)} 16:14:16.383
     dvi:           {Core Device Install - exit(0x00000002)} 16:14:16.383
     dvi:           {DIF_DESTROYPRIVATEDATA} 16:14:16.383
     dvi:                Class installer: Enter 16:14:16.383
     dvi:                Class installer: Exit
     dvi:                Default installer: Enter 16:14:16.399
     dvi:                Default installer: Exit
     dvi:           {DIF_DESTROYPRIVATEDATA - exit(0xe000020e)} 16:14:16.399
     ump:      {Plug and Play Service: Device Install exit(00000002)}
!!!  ndv:      Device install failed for device.
     ndv: {Update Driver Software Wizard exit(00000002)}
<<<  Section end 2018/03/02 16:15:14.498
<<<  [Exit status: FAILURE(0x00000002)]

I even tried replacing the printer driver using zadig, with the same results (Access denied error).

At this point, any assistance is highly appreciated.

UPDATE 03/05/2018

Today I managed to make my custom inf installer finish successfully, by following the next steps:

  • prevent windows 10 from searching the web for drivers and installing them when I plug in the printer (view details here)
  • update my custom inf installer to use the USBDevice class and the {88bae032-5a81-49f0-bc3d-a4ff138216d6} ClassGuid values
  • built the driver cat file and signed it
  • uninstall all drivers for the device and unplug the printer
  • restart the computer
  • plug the printer again. At this point, in the Device Manager, the device is detected as a Universal Serial Bus device as shown here
  • finally, followed followed this instructions to update the device drivers using the one created before.

Driver installation succeeded and regedit reflects the device is now using WinUSB driver updated

Sadly, I continue getting the "DOMException: Access denied." error when I try to print from the web page... so I still need help :(

ps: this is probably the longest post on stackoverflow I know (or top 10 at least).

UPDATE 03/06/2018

As per Reilly Grant's request, I'm including the output of USBView (lsusb equivalent for windows)

[Port1]  :  Aeropost Zebra LP2844


Is Port User Connectable:         yes
Is Port Debug Capable:            no
Companion Port Number:            10
Companion Hub Symbolic Link Name: USB#ROOT_HUB30#4&4f0abe8&0&0#{f18a0e88-c30c-11d0-8815-00a0c906bed8}
Protocols Supported:
 USB 1.1:                         yes
 USB 2.0:                         yes
 USB 3.0:                         no

Device Power State:               PowerDeviceD0

       ---===>Device Information<===---
*!*ERROR:  No String Descriptor for index 4!

ConnectionStatus:                  
Current Config Value:              0x01  -> Device Bus Speed: Full (is not SuperSpeed or higher capable)
Device Address:                    0x01
Open Pipes:                           2

          ===>Device Descriptor<===
bLength:                           0x12
bDescriptorType:                   0x01
bcdUSB:                          0x0100
bDeviceClass:                      0x07
*!*ERROR:  unknown bDeviceClass 7
bDeviceSubClass:                   0x01
*!*ERROR:  bDeviceSubClass of 1 is invalid
bDeviceProtocol:                   0x02
*!*ERROR:  bDeviceProtocol of 2 is invalid
bMaxPacketSize0:                   0x08 = (8) Bytes
idVendor:                        0x0A5F = Zebra Technologies
idProduct:                       0x0009
bcdDevice:                       0x0001
iManufacturer:                     0x02
*!*ERROR:  No String Descriptor for index 2!
iProduct:                          0x04
*!*ERROR:  No String Descriptor for index 4!
iSerialNumber:                     0x06
*!*ERROR:  No String Descriptor for index 6!
bNumConfigurations:                0x01

          ---===>Open Pipes<===---

          ===>Endpoint Descriptor<===
bLength:                           0x07
bDescriptorType:                   0x05
bEndpointAddress:                  0x85  -> Direction: IN - EndpointID: 5
bmAttributes:                      0x02  -> Bulk Transfer Type
wMaxPacketSize:                  0x0040 = 0x40 bytes
bInterval:                         0x00

          ===>Endpoint Descriptor<===
bLength:                           0x07
bDescriptorType:                   0x05
bEndpointAddress:                  0x06  -> Direction: OUT - EndpointID: 6
bmAttributes:                      0x02  -> Bulk Transfer Type
wMaxPacketSize:                  0x0040 = 0x40 bytes
bInterval:                         0x00

       ---===>Full Configuration Descriptor<===---

          ===>Configuration Descriptor<===
bLength:                           0x09
bDescriptorType:                   0x02
wTotalLength:                    0x0020  -> Validated
bNumInterfaces:                    0x01
bConfigurationValue:               0x01
iConfiguration:                    0x00
bmAttributes:                      0xC0  -> Self Powered
  -> Bus Powered
MaxPower:                          0x00 =   0 mA

          ===>Interface Descriptor<===
bLength:                           0x09
bDescriptorType:                   0x04
bInterfaceNumber:                  0x00
bAlternateSetting:                 0x00
bNumEndpoints:                     0x02
bInterfaceClass:                   0x07  -> This is a Printer USB Device Interface Class
bInterfaceSubClass:                0x01
bInterfaceProtocol:                0x02
iInterface:                        0x00

          ===>Endpoint Descriptor<===
bLength:                           0x07
bDescriptorType:                   0x05
bEndpointAddress:                  0x85  -> Direction: IN - EndpointID: 5
bmAttributes:                      0x02  -> Bulk Transfer Type
wMaxPacketSize:                  0x0040 = 0x40 bytes
bInterval:                         0x00

          ===>Endpoint Descriptor<===
bLength:                           0x07
bDescriptorType:                   0x05
bEndpointAddress:                  0x06  -> Direction: OUT - EndpointID: 6
bmAttributes:                      0x02  -> Bulk Transfer Type
wMaxPacketSize:                  0x0040 = 0x40 bytes
bInterval:                         0x00

Interestingly (bizarrely actually) enough, while trying to get this new information, my Google Chrome started throwing

TypeError: Cannot read property 'getDevices' of undefined

error in the console, and typing navigator.usb in the console returned undefined.

Since that didn't make any sense, I reinstalled Chrome, but the error continued

Because of that I installed Chrome Canary (where navigator.usb existed) and turns out that THE PRINTER STARTED PRINTING and the Access Denied error was gone.

I uninstalled Chrome Canary and somehow GA Chrome also worked. That was until I closed Chrome and opened it again. Then I got the "Cannot read property 'getDevices' of undefined" error again.

I noticed that deleting Chrome's User Data folder in AppData/Local/Google (the entire profile folder) makes Chrome work again, until I close it and open it again.

Perhaps something in my printing code is leaving something "held" despite I'm calling releaseInterface and close?

Any ideas now that the problem seem to have changed a bit?

like image 925
jmrodriguez Avatar asked Mar 02 '18 23:03

jmrodriguez


1 Answers

After a few tests on other windows machines, I managed to make everything work using Zadig software to replace the windows installed driver with WinUSB.

The key was restarting the computer after replacing the drivers.

The custom driver I developed also works, but Zadig's program makes things much easier ;)

like image 98
jmrodriguez Avatar answered Oct 06 '22 11:10

jmrodriguez