My test system is AMD X64 X2 Dual, 1GB RAM, Windows 2003 Server SP1.
Just for the sake of troubleshooting, I've been using the MSPLOT printer
driver that comes with full source code with the Windows 2003 DDK.
Everything I say equally applies to MSPLOT and my own printer driver.
The way I normally install the printer driver on Win32 is using
GetPrinterDriverDirectory, CopyFile, AddPortEx, AddPrinterDriverEx, and
AddPrinter. The AddPrinter call fails on x64 with error 1003 "Cannot
complete this function".
I know that the printer driver is valid, because it happens with MSPLOT,
one of the DDK samples (c:\WINDDK\3790.1830\src\print\msplot\), and
that's x64-compatible. It installs fine manually, using the INF file.
And yes, it's compiled for amd64.
Here's some more specific information of what I'm trying to do:
GetPrinterDriverDirectory(...)
// returns C:\WINDOWS\system32\spool\drivers\x64
CopyFile("driver.dll",
"C:\\WINDOWS\\system32\\spool\\drivers\\x64\\driver.dll", FALSE);
CopyFile("driver.dat",
"C:\\WINDOWS\\system32\\spool\\drivers\\x64\\driver.dat", FALSE);
CopyFile("driverui.dll",
"C:\\WINDOWS\\system32\\spool\\drivers\\x64\\driverui.dll", FALSE);
DRIVER_INFO_3 driverInfo3;
memset(&driverInfo3, 0, sizeof(driverInfo3));
driverInfo3.cVersion = 3;
driverInfo3.pName = "MyPrinterName";
driverInfo3.pEnvironment = "Windows x64";
driverInfo3.pDriverPath =
"C:\\WINDOWS\\system32\spool\\drivers\\x64\\driver.dll";
driverInfo3.pDataFile =
"C:\\WINDOWS\\system32\\spool\\drivers\\x64\\driver.dat";
driverInfo3.pConfigFile =
"C:\\WINDOWS\\system32\\spool\\drivers\\x64\\driverui.dll";
driverInfo3.pHelpFile = "";
driverInfo3.pDependentFiles = "\0";
driverInfo3.pMonitorName = NULL;
driverInfo3.pDefaultDataType = "RAW";
AddPrinterDriverEx(NULL, 6, &driverInfo3, APD_COPY_NEW_FILES);
// returns TRUE, GetLastError() 0
PRINTER_INFO_2 pi;
memset(&pi, 0, sizeof(pi));
pi.pServerName = NULL;
pi.pPrinterName = "MyPrinterName";
pi.pShareName = NULL;
pi.pPortName = "My Port:";
pi.pDriverName = "MyPrinterName";
pi.pComment = "";
pi.pLocation = "";
pi.pDevMode.dmDeviceName="MyPrinterName";
pi.pDevMode.dmSpecVersion = 1025;
pi.pDevMode.dmDriverVersion = 1024;
pi.pDevMode.dmSize = 156;
pi.pDevMode.dmDriverExtra = 0;
pi.pDevMode.dmFields = 93715;
// DM_ORIENTATION | DM_PAPERSIZE | DM_SCALE |
// DM_DEFAULTSOURCE | DM_PRINTQUALITY | DM_COLOR |
// DM_YRESOLUTION | DM_TTOPTION | DM_FORMNAME
pi.pDevMode.fmOrientation = 1; // DMORIENT_PORTRAIT
pi.pDevMode.dmPaperSize = 1; // DMPAPER_LETTER
pi.pDevMode.dmPaperLength = 2794;
pi.pDevMode.dmPaperWidth = 2159;
pi.pDevMode.dmScale = 100; // 100% (1:1)
pi.pDevMode.dmCopies = 1;
pi.pDevMode.dmDefaultSource = 15; // DMBIN_FORMSOURCE
pi.pDevMode.dmPrintQuality = 600;
pi.pDevMode.dmColor = 2; // DMCOLOR_COLOR
pi.pDevMode.dmDuplex = 0;
pi.pDevMode.dmYResolution = 600;
pi.pDevMode.dmTTOption = 3; // DMTT_SUBDEV
pi.pDevMode.dmCollate = 0;
pi.pDevMode.dmFormName = "Letter";
pi.pSepFile = "";
pi.pPrintProcessor = "WinPrint";
pi.pDatatype = "RAW";
pi.pParameters = "";
pi.pSecurityDescriptor = NULL;
pi.Attributes = PRINTER_ATTRIBUTE_DO_COMPLETE_FIRST |
PRINTER_ATTRIBUTE_LOCAL;
AddPrinter(NULL, 2, &pi); // returns 0
GetLastError(); // returns 1003 "Cannot complete this function"
The only difference I noticed between Win32 and x64 is the driver path
(C:\WINDOWS\system32\spool\drivers\x64) and the environment string
("Windows x64" vs "Windows NT x86"). Other than those, my installer
works perfectly on Win32, but never on x64.
I've spent several days researching it, but was unable to figure it out.
AddPrinterDriverEx always suceeds, but AddPrinter fails with error 1003.
There must be something that causes this problem on the x64 platform.
This code has been working for years on Win32 with hundreds of different
machines.
I was wondering if anyone can spot something obvious, or point me to the
right direction please.
As I mentioned, installing via the INF file works fine. However, I
prefer automatic installation, because it's part of a bigger system.
Obviously, eventually I want to install my own printer driver, not
MSPLOT. I'm only using MSPLOT to make sure the problem is not with my
driver.
The Microsoft-provided INF file contains the following information:
[HP]
"Hewlett-Packard HP-GL/2 Plotter" = HPGL2PEN.PCD,
HPHewlett-Packard_HP7319,Hewlett-Packard_HP-GL/2_Plotter
[HP.NTamd64]
"Hewlett-Packard HP-GL/2 Plotter" = HPGL2PEN.PCD,
HPHewlett-Packard_HP7319,Hewlett-Packard_HP-GL/2_Plotter
When I rename these strings to my own company and product information,
it no longer works. That's probably because of the 16-bit CRC code
(7319) in the hardware ID, which I don't know how to generate for my own
product name. I've tried to recreate that CRC based on the manufacturer
and product name without success. It doesn't seem to be documented
anywhere. Anyway, the INF file is not my preferred installation method,
I would really like to get it to work with the AddPrinter call.
Thanks,
Tamas
C:\WINDOWS\system32\spool\drivers\x64\3
CopyFile("driver.dll",
"C:\\WINDOWS\\system32\\spool\\drivers\\x64\\driver.dll", FALSE);
CopyFile("driver.dat",
"C:\\WINDOWS\\system32\\spool\\drivers\\x64\\driver.dat", FALSE);
CopyFile("driverui.dll",
"C:\\WINDOWS\\system32\\spool\\drivers\\x64\\driverui.dll", FALSE);
--
Alan Morris
Windows Printing Team
Search the Microsoft Knowledge Base here:
http://support.microsoft.com/default.aspx?scid=fh;[ln];kbhowto
This posting is provided "AS IS" with no warranties, and confers no rights.
"Tamas Demjen" <tde...@yahoo.com> wrote in message
news:%23YW92sD...@TK2MSFTNGP02.phx.gbl...
I don't suspect that the printer driver itself is wrong, because it's
Microsoft's HPGL Plotter driver, and it installs via the INF file. I
wish I had some working sample code that properly installs a printer
dirver on x64.
In my previous message I sent pseudo code that didn't really compile.
Here's the actual source code that I'm using (now modified to use the
"3" directory). This is the simplest way of reproducing the problem:
#include "stdafx.h"
#include <windows.h>
#if defined(_UNICODE) || defined(UNICODE)
#define _FN(___FUNCTION_NAME___) ___FUNCTION_NAME___##"W"
#else
#define _FN(___FUNCTION_NAME___) ___FUNCTION_NAME___##"A"
#endif // defined(_UNICODE) || defined(UNICODE)
int _tmain(int argc, _TCHAR* argv[])
{
CopyFile(_T("c:\\Driver3\\plotter.dll"),
_T("C:\\WINDOWS\\system32\\spool\\drivers\\x64\\3\\plotter.dll"),
FALSE);
CopyFile(_T("c:\\Driver3\\hpgl2pen.pcd"),
_T("C:\\WINDOWS\\system32\\spool\\drivers\\x64\\3\\hpgl2pen.pcd"),
FALSE);
CopyFile(_T("c:\\Driver3\\plotui.dll"),
_T("C:\\WINDOWS\\system32\\spool\\drivers\\3\\x64\\plotui.dll"),
FALSE);
typedef BOOL (WINAPI *type_AddPortEx)(LPCTSTR szName, DWORD dwLevel,
LPBYTE pInfo, LPCTSTR szMonitor);
HMODULE hWinspool = LoadLibrary(_T("WINSPOOL.DRV"));
type_AddPortEx AddPortEx = (type_AddPortEx)GetProcAddress(hWinspool,
_FN("AddPortEx"));
PORT_INFO_1 portInfo;
memset(&portInfo, 0, sizeof(PORT_INFO_1));
portInfo.pName = _T("MyPrinter Port");
BOOL res0 = AddPortEx(NULL, 1, (LPBYTE)&portInfo, _T("Local Port"));
// returns TRUE
FreeLibrary(hWinspool);
DRIVER_INFO_3 driverInfo3;
memset(&driverInfo3, 0, sizeof(driverInfo3));
driverInfo3.cVersion = 3;
driverInfo3.pName = _T("MyPrinterName");
driverInfo3.pEnvironment = _T("Windows x64");
driverInfo3.pDriverPath =
_T("C:\\WINDOWS\\system32\\spool\\drivers\\x64\\3\\plotter.dll");
driverInfo3.pDataFile =
_T("C:\\WINDOWS\\system32\\spool\\drivers\\x64\\3\\hpgl2pen.pcd");
driverInfo3.pConfigFile =
_T("C:\\WINDOWS\\system32\\spool\\drivers\\x64\\3\\plotui.dll");
driverInfo3.pHelpFile = _T("");
driverInfo3.pDependentFiles = _T("\0");
driverInfo3.pMonitorName = NULL;
driverInfo3.pDefaultDataType = _T("RAW");
BOOL res1 = AddPrinterDriverEx(NULL, 3, (LPBYTE)&driverInfo3,
APD_COPY_NEW_FILES);
// returns TRUE, GetLastError() 0
PRINTER_INFO_2 pi;
memset(&pi, 0, sizeof(pi));
DEVMODE dm;
memset(&dm, 0, sizeof(dm));
pi.pDevMode = &dm;
pi.pServerName = NULL;
pi.pPrinterName = _T("MyPrinterName");
pi.pShareName = NULL;
pi.pPortName = _T("MyPrinter Port:");
pi.pDriverName = _T("MyPrinterName");
pi.pComment = _T("");
pi.pLocation = _T("");
_tcscpy(pi.pDevMode->dmDeviceName, _T("MyPrinterName"));
pi.pDevMode->dmSpecVersion = 1025;
pi.pDevMode->dmDriverVersion = 1024;
pi.pDevMode->dmSize = 156;
pi.pDevMode->dmDriverExtra = 0;
pi.pDevMode->dmFields =
DM_ORIENTATION | DM_PAPERSIZE | DM_SCALE |
DM_DEFAULTSOURCE | DM_PRINTQUALITY | DM_COLOR |
DM_YRESOLUTION | DM_TTOPTION | DM_FORMNAME;
pi.pDevMode->dmOrientation = 1; // DMORIENT_PORTRAIT
pi.pDevMode->dmPaperSize = 1; // DMPAPER_LETTER
pi.pDevMode->dmPaperLength = 2794;
pi.pDevMode->dmPaperWidth = 2159;
pi.pDevMode->dmScale = 100; // 100% (1:1)
pi.pDevMode->dmCopies = 1;
pi.pDevMode->dmDefaultSource = 15; // DMBIN_FORMSOURCE
pi.pDevMode->dmPrintQuality = 600;
pi.pDevMode->dmColor = 2; // DMCOLOR_COLOR
pi.pDevMode->dmDuplex = 0;
pi.pDevMode->dmYResolution = 600;
pi.pDevMode->dmTTOption = 3; // DMTT_SUBDEV
pi.pDevMode->dmCollate = 0;
_tcscpy(pi.pDevMode->dmFormName, _T("Letter"));
pi.pSepFile = _T("");
pi.pPrintProcessor = _T("WinPrint");
pi.pDatatype = _T("RAW");
pi.pParameters = _T("");
pi.pSecurityDescriptor = NULL;
pi.Attributes = PRINTER_ATTRIBUTE_DO_COMPLETE_FIRST |
PRINTER_ATTRIBUTE_LOCAL;
HANDLE hprinter = AddPrinter(NULL, 2, (LPBYTE)&pi); // returns 0
DWORD dw = GetLastError();
// returns 1003 "Cannot complete this function"
return 0;
}
Thanks,
Tamas
Regardless, AddPrinter always fails with 1003. There might be something
very wrong here.
Thanks,
Tamas
I'm porting an existing printer driver to x64. Installation works fine
on Win32 with AddPort, AddPrinterDriver and AddPrinter. On Win64 (2008
in my case) AddPrinter fails with 1003 - Cannot complete this function.
I feel desperate.
Did you find a solution?
regards,
Marcus
--
Marcus Schaub
------------------------------------------------------------------------
Marcus Schaub's Profile: http://forums.techarena.in/members/marcus-schaub.htm
View this thread: http://forums.techarena.in/xp-print-fax/866576.htm