views:

30

answers:

1

Hi,

I've written an printer driver which works under x86 and x64 MS Windows systems. I also have written an setup which installs the printer driver via AddPrinterDriver and AddPrinter functions.

So far, so good. The thing is, if I want to share this printer from an x64 system to an x86 system, the x64 print server needs to have the additional drivers for x86 systems installed.

Now I could just install the additional drivers via "Printer Properties" -> "Sharing" -> "Additional Drivers" and select the proper .inf file, but I want to do it via my setup program.

Does anybody know how to accomplish this?

Thanks for the help!

+1  A: 

So I found an solution myself. There must be a better and simpler way, but well it works.

When installing the driver, also copy the right architecture files to the other architectures. x86 driver to x86 spooler driver dir, x64 to x64 spooler driver dir etc.

Then before calling AddPrinterDriver and AddPrinter you must add a few registry values for each other architectures you want to support. Then call AddPrinterDriver and AddPrinter only for the base architecture of the os you install your driver on.

The registry values must be added to

SYSTEM\CurrentControlSet\Control\Print\Environments\{TARGET_ENVIROMENT}\Drivers\Version-3\{NAME_OF_YOUR_DRIVER}

whereby {TARGET_ENVIROMENT} is the other enviroment you want to support, e.g. "Windows NT x86"; "Windows x64"; "Windows IA64" and {NAME_OF_YOUR_DRIVER} must match the drivername you are using for AddPrinterDriver. The values you have to add there are a copy of the ones AddPrinterDriver will add to your systems enviroment. You can see them in detail in the code example below. After that just call AddPrinterDriver and AddPrinter for the system architecture and the additional drivers will also be present.

In Win32 you could use the following to install the drivers for x86 and x64 on an x64 system (this example does no error checks):

    DWORD uSize;
    BYTE driver_dir_x86[MAX_PATH];
    BYTE driver_dir_x64[MAX_PATH];

    GetPrinterDriverDirectory(NULL,"Windows NT x86",1,driver_dir_x86,MAX_PATH,&uSize);
    GetPrinterDriverDirectory(NULL,"Windows x64",1,driver_dir_x64,MAX_PATH,&uSize);


    CopyFile(".\x86\printer_driver.dll",driver_dir_x86);
    CopyFile(".\x86\PRINTER.PPD",driver_dir_x86);
    CopyFile(".\x86\PRINTERUI.DLL",driver_dir_x86);
    CopyFile(".\x86\PRINTER.HLP",driver_dir_x86);

    CopyFile(".\x64\printer_driver.dll",driver_dir_x64);
    CopyFile(".\x86\PRINTER.PPD",driver_dir_x64);
    CopyFile(".\x86\PRINTERUI.DLL",driver_dir_x64);
    CopyFile(".\x86\PRINTER.HLP",driver_dir_x64);

    //Insert x86 additional drivers to registry
   RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Print\\Environments\\Windows NT x86\\Drivers\\Version-3\\", 0, KEY_ALL_ACCESS, &hkey);
   RegCreateKey(hkey, "My_Printer_Drivername", &hsubkey);       {
   RegSetValueEx(hsubkey, "Dependent Files", 0, REG_MULTI_SZ, (BYTE*)"", lstrlen("")+1);
   RegSetValueEx(hsubkey, "Previous Names", 0, REG_MULTI_SZ, (BYTE*)"", lstrlen("")+1);
   RegSetValueEx(hsubkey, "ColorProfiles", 0, REG_MULTI_SZ, (BYTE*)"", lstrlen("")+1);
   RegSetValueEx(hsubkey, "CoreDependencies", 0, REG_MULTI_SZ, (BYTE*)"", lstrlen("")+1);
   DWORD Val = 3;
   RegSetValueEx(hsubkey, "Version", 0, REG_DWORD, (BYTE*)&Val, sizeof(DWORD));
   Val = 0;
   RegSetValueEx(hsubkey, "TempDir", 0, REG_DWORD, (BYTE*)&Val, sizeof(DWORD));
   Val = 2;
   RegSetValueEx(hsubkey, "Attributes", 0, REG_DWORD, (BYTE*)&Val, sizeof(DWORD));
   Val = 0;
   RegSetValueEx(hsubkey, "PrinterDriverAttributes", 0, REG_DWORD, (BYTE*)&Val, sizeof(DWORD));
   RegSetValueEx(hsubkey, "Configuration File", 0, REG_SZ, (BYTE*)"PRINTERUI.DLL", lstrlen("PRINTERUI.DLL")+1);
   RegSetValueEx(hsubkey, "Data File", 0, REG_SZ, (BYTE*)"PRINTER.PPD", lstrlen("PRINTER.PPD")+1);
   RegSetValueEx(hsubkey, "Driver", 0, REG_SZ, (BYTE*)"printer_driver.dll", lstrlen("printer_driver.dll")+1);
   RegSetValueEx(hsubkey, "Help File", 0, REG_SZ, (BYTE*)"PRINTER.HLP", lstrlen("PRINTER.HLP")+1);
   RegSetValueEx(hsubkey, "Monitor", 0, REG_SZ, (BYTE*)"", lstrlen("")+1);
   RegSetValueEx(hsubkey, "Datatype", 0, REG_SZ, (BYTE*)"RAW", lstrlen("RAW")+1);
   RegSetValueEx(hsubkey, "Manufacturer", 0, REG_SZ, (BYTE*)"", lstrlen("")+1);
   RegSetValueEx(hsubkey, "OEM URL", 0, REG_SZ, (BYTE*)"", lstrlen("")+1);
   RegSetValueEx(hsubkey, "HardwareID", 0, REG_SZ, (BYTE*)"", lstrlen("")+1);
   RegSetValueEx(hsubkey, "Provider", 0, REG_SZ, (BYTE*)"", lstrlen("")+1);
   RegSetValueEx(hsubkey, "Print Processor", 0, REG_SZ, (BYTE*)"", lstrlen("")+1);
   RegSetValueEx(hsubkey, "VendorSetup", 0, REG_SZ, (BYTE*)"", lstrlen("")+1);
   RegSetValueEx(hsubkey, "InfPath", 0, REG_SZ, (BYTE*)"", lstrlen("")+1);
   RegSetValueEx(hsubkey, "DriverDate", 0, REG_SZ, (BYTE*)"01/01/2010", lstrlen("01/01/2010")+1);
   RegSetValueEx(hsubkey, "DriverVersion", 0, REG_SZ, (BYTE*)"1.0.0.0", lstrlen("1.0.0.0")+1);
   RegSetValueEx(hsubkey, "MinInboxDriverVerDate", 0, REG_SZ, (BYTE*)"01/01/2010", lstrlen("01/01/2010")+1);
   RegSetValueEx(hsubkey, "MinInboxDriverVerVersion", 0, REG_SZ, (BYTE*)"1.0.0.0", lstrlen("1.0.0.0")+1);
   RegCloseKey(hsubkey);
   RegCloseKey(hkey);

   //Add x64 printer driver
   DRIVER_INFO_3 di3;
   ZeroMemory(&di3, sizeof(DRIVER_INFO_3)); 
   di3.cVersion = 0x03; 
   di3.pConfigFile = "PRINTERUI.DLL"; 
   di3.pDataFile = "PRINTER.PPD";       
   di3.pDependentFiles = "";
   di3.pDriverPath = "printer_driver.dll"; 
   di3.pEnvironment = "Windows x64";
   di3.pHelpFile = "PRINTER.HLP";
   di3.pMonitorName = NULL; 
   di3.pName = "My_Printer_Drivername";
   di3.pDefaultDataType = TEXT("RAW");
   AddPrinterDriver(NULL, 3, (LPBYTE)&di3);
Thomas Woischnig