How to install pscript/unidrv rendering plugins? DDK/WDK print/oemdll samples are acting strange

StackOverflow https://stackoverflow.com/questions/15130332

  •  16-03-2022
  •  | 
  •  

Question

I'm trying to get something of pscript/unidrv rendering plugins, but the provided DDK samples just can't be installed on any possible combination of DDK/build/target system I ever have.

The message reported is 'The specified port is unknown' for WinXP x64 and 'Element not found' for Win7,Win8 (part of Win7 setupapi log with remarkable "dvi: A NULL driver installation is not allowed for this type of device!" error can be found here).

So far, I've tried to:

  • change .rc file to match FILESUBTYPE (VFT2_DRV_VERSIONED_PRINTER) and FILETYPE (VFT_DRV)
  • sign using test certificate, turn debug mode on
  • add empty hw-id followed by normal compatible-id to product names in .inf ("product 1" = product_target,,product_1)
  • checked that all files referenced in .inf (.ini, .gpd, .dll) are in place
  • remove all additional references to any files excluding my desired oemps target
  • run chkinf tests and fix all the warnings
  • mess with UAC, file locations, do other Inca dance.

What else should be done to get a pscript rendering plugin installed into the system?

Are they ever meant to be installed as a normal device, outside of printer drivers? MSDN is really unclear on that, but, guessing from the presence of .inf's inside DDK sources, I guess there's a way to install them 'as is', I just don't found that.. yet.


UPD: found the description for these samples in WDK8 ("http://code.msdn.microsoft.com/windowshardware/OEMDLL-Samples-71364d95"), which mentions something that isn't found at main article ("Customizing Microsoft's Printer Drivers") - "The BITMAP, OEMPS, OEMUI, OEMUNI, OEMPREAN, CUSTHLP, SyncSet, ThemeUI, PSUIRep, and Watermark samples do not affect the printer output".

Was it helpful?

Solution

The quote you cite regarding the BITMAP, OEMPS, etc. simply means that those samples only show the structure of a driver plugin and don't produce any output. But that doesn't mean they can't. If you want to build a driver plugin, I would recommend you begin with one of those samples and add code to it that does what you want.

Installing print drivers can be tricky because the Add Printer Wizard provides very poor error reporting. All it gives you is a Win32 error code. For example, if any required files are missing, it will just show you error code 0x2, which means missing file. However, it won't tell you which file is missing, which can be very frustrating. But rest assured, those samples can be installed. In general, you need to have all the files listed in the .inf file present in the same directory with the .inf file. In most cases, that would be one or two DLLs, plus an .ini and a .gpd or .ppd file. I just built and installed the generic text driver, for example. I also found a good tutorial on installing that driver here.

So I would recommend you begin with the generic text sample. Once you've got it to build and install, tackle the pscript driver. Don't change the .inf file they provide, and don't fiddle with the .rc file or certificates; you don't need a certificate.

An alternative to using the Add Printer Wizard is to install the driver directly using the AddPrinterDriver and AddPrinter functions. This is more complex, but I prefer it because it gives you more control and you can see exactly what errors are happening and why. No .inf file is needed. The following is a snippit of working code that installs a driver and creates a printer using that driver. Error checking and copying of files has been removed for clarity....

char driverPath[MAX_PATH];
DWORD needed;
GetPrinterDriverDirectory(0, 0, 1, (UCHAR *)driverPath, sizeof(driverPath), &needed);

// **copy all necessary files to driverPath here**

// format all file names with full paths
char driverSrc[MAX_PATH];
sprintf_s(driverSrc, "%s\\%s", driverPath, psDriverFile);
char driverUISrc[MAX_PATH];
sprintf_s(driverUISrc, "%s\\%s", driverPath, psUIFile);
char driverPPDSrc[MAX_PATH];
sprintf_s(driverPPDSrc, "%s\\%s", driverPath, psPPDFile);
char helpFileSrc[MAX_PATH];
sprintf_s(helpFileSrc, "%s\\%s", driverPath, psHelpFile);

// initialize the DRIVER_INFO struct
DRIVER_INFO_3 di;
memset(&di, 0, sizeof(di));
di.cVersion = 3;
di.pEnvironment = "Windows x64";
di.pDriverPath = driverPath;
di.pName = "MyDriver";
di.pDefaultDataType = "RAW";
di.pDataFile = driverPPDSrc;
di.pConfigFile = driverUISrc;
di.pHelpFile = helpFileSrc;
di.pDependentFiles = pszDependentFiles;

// add the driver
AddPrinterDriver(0, 3, (LPBYTE)&di);

// create the printer
PRINTER_INFO_2 pi;
memset(&pi, 0, sizeof(pi));
pi.pPrinterName = (LPSTR)pPrinterNames->at(i);
pi.pDriverName = "MyDriver";
pi.pPrintProcessor = "winprint";
pi.Attributes = PRINTER_ATTRIBUTE_LOCAL;
pi.pDatatype = "RAW";
pi.pPortName = "LPT1:";
HANDLE hPrinter = AddPrinter(0, 2, (LPBYTE)&pi);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top