3d Printer Interface
Platform: Windows macOS Linux. Plus Point: Has a super quick learning curve. Access and control your 3D printers via web interface from everywhere. If you want to connect from outside your home network (intranet) you need a vpn tunnel to your network (secure solution) or add port forwarding to make the printer available from the internet.
-->The Microsoft Standard Driver for 3D Printers allows developers to easily make their printer compatible with Windows 10. Any printer that uses Microsoft OS descriptors can be recognized as a compatible 3D printer. Using a concrete example, this article will show how to create a firmware that allows a device to be recognized as a 3D printer by Windows 10 and communicate its print capabilities.
Introduction
The Microsoft Standard Driver relieves the burden of writing their own driver from independent hardware vendors (IHVs) who want their 3D printers to be compatible with Windows 10. Versions of Windows that are aware of Microsoft OS descriptors use control requests to retrieve the information and use it to install and configure the device without requiring any user interaction.
The general process to get a 3D printer working on Windows 10 includes the following steps:
Compatible ID. The independent hardware vendor (IHV) has to include the '3D Print' compatible ID in the firmware of the printer. This allows the device to be recognized as a 3D printer.
Standard Driver. Once the device is plugged in, Windows Update will download the 3D print standard driver and detect the current device as a 3D printer that uses a default configuration.
Extended properties descriptor. Several base configurations for 3D printers are made available as part of the standard driver. A developer can therefore choose a base configuration that matches their 3D printer. On top of choosing a base configuration, a developer can override some of the properties to better match their 3D printer and include them in the new firmware.
Plug and play. Once the firmware is burned in the flash memory of the 3D printer, whenever a user plugs it into a Windows 10 machine, the standard driver will automatically be downloaded and will use the custom print capabilities that the developer has chosen.
In the following sections, we will illustrate each of these steps using a concrete example.
For more information, see Microsoft OS Descriptors.
Compatible ID
To specify to the Windows operating system that we are currently using a 3D printer, we have to use the right compatible ID. The list of Microsoft Compatible ID are available at Microsoft OS Descriptors.
The compatible ID for a 3D printer is shown in the following table:
Compatible ID | Sub-compatible ID | Description |
---|---|---|
'3DPRINT' (0x33 0x44 0x50 0x52 0x49 0x4E 0x54 0x00) | Varies | MS3DPRINT G-Code Printer |
In the header file that is included in the 3D printer firmware, the IHV must specify the Compatible ID as shown here:
This line in the code above is the compatible ID of a 3D Printer:
'3', 'D', 'P', 'R', 'I', 'N', 'T', 0x00, // compatibleID ('3DPRINT')
With this specific configuration, IHVs can compile their firmware and flash the device. Then when the device is plugged in, the 3D Print Standard Driver will automatically get downloaded from Windows Update.
At this stage the printer is using the standard driver default configuration, the parameters used by the default configuration are accessible in the folder %SYSTEMROOT%System32MS3DPrint in the file StandardGCode.xml. Additionally, a developer can chose to use a different base configuration, a list of base configurations are available in the same folder %SYSTEMROOT%System32MS3DPrint. This list is regularly populated with new configuration as new 3D printers emerge on the market.
Extended Properties OS Feature Descriptor
As stated in the above section, IHVs have access to several base configurations. This has the advantage of minimizing the amount of information that has to be stored in the printer’s flash memory. Developers can inspect the base configurations made available and choose the one that is the closest to their printers. In this example we are going to choose the SD card base configuration and override some of the properties with the parameters below:
Parameters | Value |
---|---|
Job3DOutputAreaWidth | 250000 |
Job3DOutputAreaDepth | 260000 |
Job3DOutputAreaHeight | 270000 |
Filamentdiameter | 2850 |
For more information about these parameters, please refer to the MS3DPrint Standard G-Code Driver.docx document in the 3D Printing SDK (MSI download) documentation.
To specify which base configuration to use and which parameters to override, the developer has to specify it through the Extended Properties OS Feature Descriptor as shown here:
Information regarding the extended properties OS feature descriptor are in the OS_Desc_Ext_Prop.doc file. See Microsoft OS Descriptors for more information.
Verifying the print capabilities
Once the device has the firmware burned in flash memory , the device will automatically be detected by Windows 10 and the print capabilities will be stored in registry.
It is very important that the IHV changes the VID/PID of the device to their own. You should never use the Vendor ID (VID) or Product ID (PID) of another existing device as the operating system will not be able to detect the device properly as the VID and PID take priority over the OS descriptor.
If the device has been properly installed, the device should be listed in Devices and Printers.
In the Device Manager, the matching device id and the compatible id can be verified.
The USB driver properties can be obtained by visiting the registry at HKEY_LOCAL_MACHINESYSTEMCurrentControlSetEnumUSB.
The 3D Print driver properties can be obtained by visiting the registry at HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlPrintPrinters.
Additional resources
For more information, see the following documents and resources:
You can also contact the Microsoft 3D Printing team at Ask 3D Printing Questions (ask3dprint@microsoft.com).
-->The architecture described in this topic enables support for custom USB interface 3D printers in the v3 and v4 print ecosystems. A standard port monitor, 3dmon.dll, forwards 3D print job commands to a Windows 3DPrintService running with local service credentials. The service loads and communicates with a partner DLL to execute the custom commands needed for a 3D print job. The partner DLL, as well as the 3dmon.dll and 3dprintservice.exe redistributables, are installed by the device's USB driver package. The partner DLL must implement and export a set of functions to communicate with the 3DPrintService. The rest of the required functionality to interact with the print spooler service is implemented in 3dmon.dll.
Note
This architecture requires the partner DLL to multi-instance, thread safe.
Architecture Decisions
The 3DPrintService windows service is used to load and invoke specific defined APIs in partner-provided DLLs during a print workflow. These APIs will allow for communication with the printer.
The KMDF USB Filter driver packages are published on Windows Update for installing via PnP for a supported 3D printer. The KMDF driver installs partner software and creates a 3D printer device node. The 3D printer device node is installed using a partner-published v4 print driver from Windows Update.
Packaging Decisions
Binaries and Binary Dependencies
The architectue uses a driver published by the hardware manufacturer on Windows Update. This driver includes the following Microsoft-provided redistributable binaries and their dependencies:
- 3dmon.dll
- 3dprintservice.exe
- ms3dprintusb.sys
Kernel mode USB filter driver
The KMDF driver is published by the partner and consists of components shown in the diagram below. This matches the device with a hardware ID (typically, a VID & PID). The driver creates a 3D printer device node on installation which triggers installation of the print queue and the slicer drivers. The partner provids v4 printer drivers for the 3D printer device node that is created.
MS3DPrintUSB.sys
The kernel mode device driver that creates the 3D printer dev node under Enum3DPrint. It is invoked by the PnP subsystem via a direct match of the VID & PID based on the device node created by Winusb.sys. The driver .inf file sets up the custom DLL used to set the 3DPrintService (if not already installed on the system).
3dmon.dll
3DMon.dll is a Microsoft-published port monitor redistributable binary invoked by the spooler to communicate with the 3D printer.
3dprintservice.exe
3DPrintService.exe is a Microsoft-published binary installed as a Windows service during driver setup. 3DMon communicates with this service to perform operations like printing, bidi, and so on with the 3D printer.
Partnerimpl.dll
Partnerimp.dll is partner's implementation of the published Microsoft interface. The DLL communicates with the partner's device using their protocols. 3DPrintService.exe loads this DLL at runtime to drive the operations of the 3D printer device.
Printer usage sequence
- The spooler communicates with 3dmon.dll which sends commands to the 3DPrintService windows service
- The 3DPrintService.exe runs with the account credentials of NetworkService
- The spooler, via 3dmon.dll, sends commands to 3DPrintService anytime the 3D printer is used
- The 3DPrintService processes commands and invokes APIs at runtime on partner-provided implementation DLLs
- The 3DPrintService hands off the responses from partner-provided DLLs back to the spooler
Interfaces and Interactions
The partner DLL must export the following API functions:
HRESULT Install([in] LPCWSTR args)
This API is optional and can be used by the manufacturer to install custom software or registration for their device. For example, installation of modelling included with the driver package for the device. This API is invoked with SYSTEM credentials to enable installation.
DWORD PrintApiSupported()
This API is used by the third-party manufacturers to indicate the version of the 3D print service API supported. The APIs below are compatible with version 1 of the 3DPrintService.
HRESULT InitializePrint(LPCWSTR pPrinterName, LPCWSTR pPortName, DWORD dwJobId, LPVOID* ppPartnerData)
This API is invoked prior to a print event starting to initialize the printer. The printer can save job specific state in the ppPartnerData parameter. This call is analogous to a StartDocPort invocation.
- jobId - job id used to track the job
- portName - portname for the 3D printer
- printerName - name of the printer this print job is being sent to
- ppPartnerData - pointer to pointer that can be used to store any job specific data
HRESULT PrintFile([in] DWORD jobId, [in] LPWSTR portName, [in] LPWSTR printerName, [in] LPWSTR pathToRenderedFile,[in]LPVOID* ppPartnerData)
This API is used by third-party manufacturers to print the document on their printer.
jobId - job id used to track the job
portName - portname for the 3D printer
printerName - name of the printer the print job is being sent to
pathToRenderedFile - UNC path to the location of the spooled file after rendering has been performed. The third-party manufacturer processes the file from this location and print the document on their device
ppPartnerData - pointer to pointer that isused to store partner specific data setup during the InitializePrint API call.
printerName can be obtained from the registry using the port name. Third-party manufacturers maynot be able to use the port name to communicate with their device. The printer name is unique on a Windows machine and their software will be capable of identifying which printer to print the job on. All printers active on a machine can be found at the following registry key:
HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlPrintPrinters
HRESULT Query(_In_ LPCWSTR command, _In_ LPCWSTR commandData, _Out_ LPWSTR resultBuffer, _Out_ resultBufferSize, , _In_ LPVOID* ppPartnerData)
3d Printer Service
- command - string command sent as a query
- commandData - command arguments (optional)
- resultBuffer - result of invocation of query arguments>
- resultBufferSize - size of the result buffer string
- ppPartnerData - pointer to pointer for the current partner DLL instance
The 3Dprint service invokes the partner DLL to get the size of the buffer to allocate for the command.
After allocating memory to hold the response string, the DLL will be invoked again to get the actual result.
The DLL can use the instance data from a previous IntializePrint() call to communicate with the device without opening a new communication channel each time the Query() function is called.
This API is used to communicate with the printer to obtain information on the device configuration, print progress, or to notify the partner DLL of device unplug events.
The commands below must be supported by the manufacturer:
Command | CommandData | Output | Comments |
---|---|---|---|
Printer.3DPrint:JobStatus | Job Commenced = {'Status': 'ok'} Status to be used on Completion {'Status': 'Completed'} | The spooler will display any returned value in the print queue UI. This lets the device display relevant information during a print on the print queue UI. The device can return an arbitrary string here (for example 'Busy' or '33% complete') and this will be displayed verbatim in the print queue job status. | |
Printer.3DPrint:JobCancel | {'Status': 'Completed'} | The spooler will invoke this command when a user cancels a print. The partner DLL returns this value when the cancellation was successful and the handles and threads have been closed. | |
Printer.Capabilities:Data | XML string conforming to the PrintDeviceCapabilites (PDC) schema. | The PDC query is invoked by apps that wish to obtain more information about the printer. The data is used to describe the capabilities of the device and can include the slicer settings if the driver relies on the Microsoft slicer. See below for a sample PDC. | |
Printer.3DPrint:Disconnect | {'Status': 'OK'} | This query is triggered whenever there is a PnP disconnection of the printer device. Partners can undertake any required actions, for example close any open handles to allow proper reconnect. | |
Printer.3DPrint:Connect | {'Status':'OK'} | This query is triggered whenever there is a PnP connection of the printer device. Partners can undertake any required actions. |
Print Device Capabilities XML
The following print device capabilities XML can be used as an example:
For 3D printers that do not have on-board display and buttons to allow the user to interact with the device at the beginning of the print, we advocate returning a PDC xml with a suitable user prompt message set as shown above in psdk3dx:userPrompt. This is to prevent starting a new print on top of an existing one. The custom status message <psk3dx:customStatus> is used to display any message during slicing.
HRESULT Cleanup(LPCWSTR pPrinterName, LPCWSTR pPortName, DWORD dwJobId, LPVOID* ppPartnerData)
- dwJobId - job id used to track the job in the spooler
- pPortName - portname for the 3D printer
- pPrinterName - name of the printer this print job is being sent to
- ppPartnerData - pointer to pointer that holds the job specific data setup during an InitializePrint API invocation
Cleanup is invoked on successful completion of a print job, or on completion of a cancel query on a print job. It provides an opportunity for the partner DLL to cleanup resources that were initialized for this print.
HRESULT UnInstall([in]LPCWSTR args)
3d Printer Interface
This API is called when uninstaling the 3D printer device and provides a mechanism for manufacturer to uninstall software they might have installed.