Force "Print Document on" 11x17 Scaled

The Print Spooler API in Windows does not seem to have an option to force scaling to another paper size. Formerly, we would install the printer save the registry key in HKCU\Printers\DevModePerUser. Then, we could check the “Print Document On” option, apply the settings, and save the registry key again. Performing a diff of between the two sets of roughly 4000 hex values should give a subset of values that relate to “Print Document On.” Finally, on installation we could read in the registry key after everything else had been setup, cycle through it changing the appropriate values based on our diff and then save the registry key. This stopped working.

No new diffs could be collected that would update the scale to fit functionality that we needed. However, if the “Print Document On” option is manually set and the registry key is collected, that key can be used as the “diff” and the newly added printer would print scaled as desired. This has the unfortunate side effect of modifying all other settings on the printer including the name and color settings. As a work around, two different registry key “diffs” are used: one for color and one for black&white. Then, the first 30 hex characters can be chopped off in each key to make sure the printer name is not overwritten.

#include <windows.h>;

int stf[][2] = {
  {8, 0},
  {10, 0},
  // and more keys

int setPrintDocumentOn(char *printerName) {
  HKEY hkey;

  // find the tree where the key we need to change resides
  RegOpenKey(HKEY_CURRENT_USER, "Printers\\DevModePerUser", &hkey);

  DWORD requiredSize = 0;
  DWORD dataType;

  // read in the key
  RegQueryValueEx(hkey, printerName, 0, &dataType, NULL, &requiredSize);
  char *DevModePerUserData = malloc(requiredSize);
  RegQueryValueEx(hkey, printerName, 0, &dataType, (BYTE *)DevModePerUserData, &requiredSize);

  // update the key
  int i = 0;
  for(i = 0; i < sizeof(stf) / 8; i++) {
    DevModePerUserData[stf[i][0]] = stf[i][1];

  // and save our updates
  RegSetValueEx(hkey, printerName, 0, REG_BINARY, (BYTE *)DevModePerUserData, requiredSize);