You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
555 lines
15 KiB
555 lines
15 KiB
//-----------------------------------------------------------------------------
|
|
// This files contains the module name for this mini driver. Each mini driver
|
|
// must have a unique module name. The module name is used to obtain the
|
|
// module handle of this Mini Driver. The module handle is used by the
|
|
// generic library to load in tables from the Mini Driver.
|
|
// It also contains Install() for upgrading 3.0 driver to 3.1.
|
|
//
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#include "strings.h"
|
|
|
|
|
|
// #define CONVERT_FROM_WIN30
|
|
|
|
char *rgchModuleName = "PCL4MSJ";
|
|
char szSoftFonts[] = "SoftFonts";
|
|
|
|
#ifdef CONVERT_FROM_WIN30
|
|
char szPrtIndex[] = "prtindex";
|
|
char szWinVer[] = "winver";
|
|
char sz310[] = "310";
|
|
char sz150[] = "150";
|
|
char sz75[] = "75";
|
|
char szNull[] = "";
|
|
char szOrient[] = "orient";
|
|
char szOrientation[] = "Orientation";
|
|
char szPaper[] = "paper";
|
|
char szPaperSize[] = "Paper Size";
|
|
char szPrtResFac[] = "prtresfac";
|
|
char szPrintQuality[] = "Print Quality";
|
|
char szTray[] = "tray";
|
|
char szDefaultSource[] = "Default Source";
|
|
char szNumCart[] = "numcart";
|
|
char szCartIndex[] = "cartindex";
|
|
char szCartridge[] = "Cartridge ";
|
|
char szNumberCart[] = "Number of Cartridges";
|
|
char szFsVers[] = "fsvers";
|
|
char szFontSummary[] = "Font Summary";
|
|
|
|
// map old HPPCL's cartindex to unidrv's FONTCART index for newer cartridges.
|
|
// This mapping table is created based on the old HPPCL .rc file.
|
|
int rgNewCartMap[9] = {8, 7, 2, 3, 5, 6, 1, 4, 0};
|
|
|
|
#endif
|
|
|
|
|
|
#define PRINTDRIVER
|
|
#include "print.h"
|
|
#include "gdidefs.inc"
|
|
#include "mdevice.h"
|
|
|
|
|
|
|
|
#define DELETE_OLD
|
|
|
|
#ifndef WINNT
|
|
HDC FAR PASCAL CreateIC(LPCSTR, LPCSTR, LPCSTR, const VOID FAR*);
|
|
BOOL FAR PASCAL DeleteDC(HDC);
|
|
#endif // !WINNT
|
|
|
|
#include "unidrv.h"
|
|
|
|
|
|
#ifndef WINNT
|
|
extern char *rgchModuleName; // global module name
|
|
|
|
// typedef for soft font installer
|
|
typedef int (FAR PASCAL *SFPROC)(HWND,LPSTR,LPSTR,BOOL,int,int);
|
|
|
|
short NEAR PASCAL MakeAppName(LPSTR,LPCSTR,short);
|
|
|
|
#define SOFT_FONT_THRES 25 // build font summary, if over this limit
|
|
#define MAX_CART_INDEX 33
|
|
#define MAX_OLD_CART 24
|
|
#define TMPSIZE 256
|
|
|
|
HINSTANCE hInst;
|
|
|
|
#ifdef PRTCAPSTUFF
|
|
|
|
char szPrtCaps[] = "prtcaps";
|
|
|
|
#define MAX_NUM_MODELS 24
|
|
#define MAX_MODEL_NAME 29
|
|
typedef struct
|
|
{
|
|
char szModel[MAX_MODEL_NAME];
|
|
int rgIndexLimit[2];
|
|
char szPrtCaps[7]; // keep as a string instead of integer to avoid
|
|
// conversion because itoa doesn't work here.
|
|
} MODELMAP, FAR * LPMODELMAP;
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------
|
|
// Function: DoPrtCapsStuff(lpDevName,lpPort)
|
|
//
|
|
// Action: Write out PRTCAPS under [<model>,<port>] section
|
|
// in order to be backward-compatible with existing font
|
|
// packages. Note that this code can fail
|
|
// under extremely low memory conditions, so be sure and check
|
|
// the return values from the resource calls.
|
|
//-------------------------------------------------------------------
|
|
void NEAR PASCAL DoPrtCapsStuff(LPSTR lpDevName,
|
|
LPSTR lpPort)
|
|
{
|
|
char szOldSec[64];
|
|
int i;
|
|
HANDLE hMd;
|
|
HANDLE hResMap;
|
|
LPMODELMAP lpModelMap;
|
|
|
|
|
|
lstrcpy(szOldSec,lpDevName);
|
|
MakeAppName((LPSTR)szOldSec,lpPort,sizeof(szOldSec));
|
|
|
|
hMd=GetModuleHandle((LPSTR)rgchModuleName);
|
|
hResMap=LoadResource(hMd,FindResource(hMd,MAKEINTRESOURCE(1),RT_RCDATA));
|
|
if(hResMap)
|
|
{
|
|
if(lpModelMap=(LPMODELMAP)LockResource(hResMap))
|
|
{
|
|
for (i=0;i<MAX_NUM_MODELS;i++)
|
|
{
|
|
if (!lstrcmp(lpDevName,(LPSTR)(lpModelMap[i].szModel)))
|
|
{
|
|
WriteProfileString((LPSTR)szOldSec,szPrtCaps,
|
|
(LPSTR)lpModelMap[i].szPrtCaps);
|
|
break;
|
|
}
|
|
}
|
|
UnlockResource(hResMap);
|
|
}
|
|
FreeResource(hResMap);
|
|
}
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
//------------------------------------------------------------------------
|
|
// Function: LibMain(hInstance,wDataSeg,cbHeapSize,lpszCmdLine)
|
|
//
|
|
// Action: Save the hInstance for this DLL
|
|
//
|
|
// Return: 1
|
|
//------------------------------------------------------------------------
|
|
int WINAPI LibMain (HANDLE hInstance,
|
|
WORD wDataSeg,
|
|
WORD cbHeapSize,
|
|
LPSTR lpszCmdLine)
|
|
{
|
|
hInst=hInstance;
|
|
|
|
return 1;
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------*MakeAppName*---------------------------------------
|
|
// Action: compose the <printer,port> name for reading the profile data
|
|
// Return the length of the actual application name. Return -1 if fails.
|
|
//
|
|
//------------------------------------------------------------------------------
|
|
short NEAR PASCAL MakeAppName(LPSTR lpAppName,
|
|
LPCSTR lpPortName,
|
|
short max)
|
|
{
|
|
short length, count;
|
|
LPCSTR lpTmp;
|
|
LPCSTR lpLastColon = NULL;
|
|
|
|
length = lstrlen(lpAppName);
|
|
|
|
if (!lpPortName)
|
|
return length;
|
|
|
|
if (length == 0 || length > max - lstrlen(lpPortName))
|
|
return -1;
|
|
|
|
// insert the comma
|
|
lpAppName[length++] = ',';
|
|
|
|
// append the port name but do not want the last ':', if any.
|
|
for (lpTmp = lpPortName ; *lpTmp; lpTmp++)
|
|
if (*lpTmp == ':')
|
|
lpLastColon = lpTmp;
|
|
if (lpLastColon && lpLastColon == lpTmp - 1)
|
|
count = lpLastColon - lpPortName;
|
|
else
|
|
count = lpTmp - lpPortName;
|
|
|
|
lstrcpy((LPSTR)&lpAppName[length], lpPortName);
|
|
|
|
length += count;
|
|
lpAppName[length]='\0';
|
|
|
|
return length;
|
|
}
|
|
|
|
#ifdef CONVERT_FROM_WIN30
|
|
|
|
//------------------------------------------------------------------------------
|
|
// Function: itoa
|
|
//
|
|
// Action: This function converts the given integer into an ASCII string.
|
|
//
|
|
// return: The length of the string.
|
|
//-----------------------------------------------------------------------------
|
|
|
|
short NEAR PASCAL itoa(buf, n)
|
|
LPSTR buf;
|
|
short n;
|
|
{
|
|
short fNeg;
|
|
short i, j;
|
|
|
|
if (fNeg = (n < 0))
|
|
n = -n;
|
|
|
|
for (i = 0; n; i++)
|
|
{
|
|
buf[i] = (char)(n % 10 + '0');
|
|
n /= 10;
|
|
}
|
|
|
|
// n was zero
|
|
if (i == 0)
|
|
buf[i++] = '0';
|
|
|
|
if (fNeg)
|
|
buf[i++] = '-';
|
|
|
|
for (j = 0; j < i / 2; j++)
|
|
{
|
|
short tmp;
|
|
|
|
tmp = buf[j];
|
|
buf[j] = buf[i - j - 1];
|
|
buf[i - j - 1] = (char)tmp;
|
|
}
|
|
|
|
buf[i] = 0;
|
|
|
|
return i;
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
//-------------------------*DevInstall*---------------------------------------
|
|
// Action: De-install, upgrade or install a device.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
int FAR PASCAL DevInstall(hWnd, lpDevName, lpOldPort, lpNewPort)
|
|
HWND hWnd;
|
|
LPSTR lpDevName;
|
|
LPSTR lpOldPort, lpNewPort;
|
|
{
|
|
char szOldSec[64];
|
|
int nReturn=1;
|
|
|
|
if (!lpDevName)
|
|
return -1;
|
|
|
|
if (!lpOldPort)
|
|
{
|
|
#ifdef CONVERT_FROM_WIN30
|
|
char szNewSec[64];
|
|
char szBuf[32];
|
|
int tmp;
|
|
int i, index;
|
|
HANDLE hMd;
|
|
HANDLE hResMap;
|
|
LPMODELMAP lpModelMap;
|
|
#endif
|
|
|
|
if (!lpNewPort)
|
|
return 0;
|
|
|
|
#ifdef CONVERT_FROM_WIN30
|
|
// install a device for the first time. Convert old HPPCL settings,
|
|
// which are still under [<driver>,<port>], into equivalent new
|
|
// UNIDRV settings under [<device>,<port>], if applicable.
|
|
// All soft fonts are left under the section [<driver>,<port>].
|
|
lstrcpy(szOldSec,rgchModuleName);
|
|
MakeAppName((LPSTR)szOldSec, lpNewPort, sizeof(szOldSec));
|
|
|
|
// if old section exists at all
|
|
if (!GetProfileString(szOldSec, NULL, NULL, szBuf, sizeof(szBuf)))
|
|
goto DI_exit;
|
|
|
|
// make sure the old device settings are for this device.
|
|
// If not, there is nothing to do here. Simply return 1.
|
|
tmp = GetProfileInt(szOldSec, szPrtIndex, 0);
|
|
hMd = GetModuleHandle((LPSTR)rgchModuleName);
|
|
hResMap = LoadResource(hMd,
|
|
FindResource(hMd, MAKEINTRESOURCE(1), RT_RCDATA));
|
|
lpModelMap = (LPMODELMAP)LockResource(hResMap);
|
|
for (i = 0; i < MAX_NUM_MODELS; i++)
|
|
{
|
|
if (!lstrcmp(lpDevName, (LPSTR)lpModelMap[i].szModel))
|
|
{
|
|
if ((tmp < lpModelMap[i].rgIndexLimit[0]) ||
|
|
(tmp > lpModelMap[i].rgIndexLimit[1]) )
|
|
i = MAX_NUM_MODELS; // not this model. No conversion.
|
|
break;
|
|
}
|
|
}
|
|
|
|
UnlockResource(hResMap);
|
|
FreeResource(hResMap);
|
|
|
|
if (i >= MAX_NUM_MODELS)
|
|
// this model is not even listed in the old HPPCL driver.
|
|
goto DI_exit;
|
|
|
|
if (GetProfileInt(szOldSec, szWinVer, 0) == 310)
|
|
goto DI_exit;
|
|
|
|
WriteProfileString(szOldSec, szWinVer, sz310);
|
|
#ifdef DELETE_OLD
|
|
WriteProfileString(szOldSec, szPrtIndex, NULL);
|
|
#endif
|
|
|
|
lstrcpy(szNewSec, lpDevName);
|
|
MakeAppName((LPSTR)szNewSec, lpNewPort, sizeof(szNewSec));
|
|
|
|
// convertable device settings include: copies, duplex, orient,
|
|
// paper, prtresfac, tray, and cartidges.
|
|
|
|
if (GetProfileString(szOldSec, szOrient, szNull, szBuf, sizeof(szBuf)) > 0)
|
|
{
|
|
WriteProfileString(szNewSec, szOrientation, szBuf);
|
|
#ifdef DELETE_OLD
|
|
WriteProfileString(szOldSec, szOrient, NULL);
|
|
#endif
|
|
}
|
|
if (GetProfileString(szOldSec, szPaper, szNull, szBuf, sizeof(szBuf)) > 0)
|
|
{
|
|
WriteProfileString(szNewSec, szPaperSize, szBuf);
|
|
#ifdef DELETE_OLD
|
|
WriteProfileString(szOldSec, szPaper, NULL);
|
|
#endif
|
|
}
|
|
|
|
// default to 2 if cannot find it
|
|
tmp = GetProfileInt(szOldSec, szPrtResFac, 2);
|
|
|
|
if (tmp == 1)
|
|
WriteProfileString(szNewSec, szPrintQuality, sz150);
|
|
else if (tmp == 2)
|
|
WriteProfileString(szNewSec, szPrintQuality, sz75);
|
|
|
|
#ifdef DELETE_OLD
|
|
WriteProfileString(szOldSec, szPrtResFac, NULL);
|
|
#endif
|
|
|
|
if (GetProfileString(szOldSec, szTray, szNull, szBuf, sizeof(szBuf)) > 0)
|
|
{
|
|
WriteProfileString(szNewSec, szDefaultSource, szBuf);
|
|
#ifdef DELETE_OLD
|
|
WriteProfileString(szOldSec, szTray, NULL);
|
|
#endif
|
|
}
|
|
|
|
// try to convert the cartridge information.
|
|
|
|
if ((tmp = GetProfileInt(szOldSec, szNumCart, 0)) == 0)
|
|
tmp = 1;
|
|
|
|
// this is executed at least once
|
|
{
|
|
char szOldCartKey[16];
|
|
char szNewCartKey[16];
|
|
char nCart = 0;
|
|
|
|
lstrcpy(szOldCartKey, szCartIndex);
|
|
|
|
for (i = 0; i < tmp; i++)
|
|
{
|
|
if (i > 0)
|
|
itoa((LPSTR)&szOldCartKey[9], i);
|
|
// compose cartridge keyname under UNIDRV.
|
|
lstrcpy(szNewCartKey, szCartridge);
|
|
itoa((LPSTR)&szNewCartKey[10], i + 1);
|
|
|
|
if ((index = GetProfileInt(szOldSec, szOldCartKey, 0)) > 0)
|
|
{
|
|
WriteProfileString(szOldSec, szOldCartKey, NULL);
|
|
nCart++;
|
|
if (index <= MAX_OLD_CART)
|
|
{
|
|
itoa((LPSTR)szBuf, index + 8);
|
|
WriteProfileString(szNewSec, szNewCartKey, szBuf);
|
|
}
|
|
else if (index <= MAX_CART_INDEX)
|
|
{
|
|
itoa((LPSTR)szBuf, rgNewCartMap[index - MAX_OLD_CART - 1]);
|
|
WriteProfileString(szNewSec, szNewCartKey, szBuf);
|
|
}
|
|
else
|
|
{
|
|
// external cartridges. Simply copy the id over.
|
|
itoa((LPSTR)szBuf, index);
|
|
WriteProfileString(szNewSec, szNewCartKey, szBuf);
|
|
}
|
|
}
|
|
}
|
|
|
|
// integer to ASCII string conversion.
|
|
itoa((LPSTR)szBuf, nCart);
|
|
WriteProfileString(szNewSec, szNumberCart, szBuf);
|
|
}
|
|
|
|
// delete the old font summary file
|
|
WriteProfileString(szOldSec, szFsVers, NULL);
|
|
if (GetProfileString(szOldSec, szFontSummary, szNull, szBuf, sizeof(szBuf)) > 0)
|
|
{
|
|
int hFS;
|
|
|
|
// truncate the old font summary file to zero size.
|
|
if ((hFS = _lcreat(szBuf, 0)) >= 0)
|
|
_lclose(hFS);
|
|
WriteProfileString(szOldSec, szFontSummary, NULL);
|
|
}
|
|
|
|
// create UNIDRV's font summary file, if there are many soft fonts.
|
|
if (GetProfileInt(szOldSec, szSoftFonts, 0) > SOFT_FONT_THRES)
|
|
{
|
|
HDC hIC;
|
|
|
|
if (hIC = CreateIC("PCL4MSJ", lpDevName, lpNewPort, NULL))
|
|
DeleteDC(hIC);
|
|
}
|
|
#endif
|
|
}
|
|
else
|
|
|
|
{
|
|
|
|
// move device settings from the old port to the new port, or
|
|
// de-install a device, i.e. remove its device setttings in order
|
|
// to compress the profile.
|
|
|
|
// First, check if there is any soft font installed under the
|
|
// old port. If so, warn the user to copy them over.
|
|
|
|
lstrcpy(szOldSec, rgchModuleName);
|
|
MakeAppName((LPSTR)szOldSec, lpOldPort, sizeof(szOldSec));
|
|
if (GetProfileInt(szOldSec, szSoftFonts, 0) > 0 && lpNewPort)
|
|
{
|
|
LPBYTE lpTemp;
|
|
|
|
if(lpTemp=GlobalAllocPtr(GMEM_MOVEABLE,TMPSIZE))
|
|
{
|
|
if(LoadString(hInst,IDS_SOFTFONTWARNING,lpTemp,TMPSIZE))
|
|
{
|
|
// Use this API so that the M Box is set to the Foreground
|
|
MSGBOXPARAMS mbp;
|
|
|
|
mbp.cbSize = sizeof(mbp);
|
|
mbp.hwndOwner = hWnd;
|
|
mbp.hInstance = hInst;
|
|
mbp.lpszText = lpTemp;
|
|
mbp.lpszCaption = lpOldPort;
|
|
mbp.dwStyle = MB_SETFOREGROUND | MB_OK | MB_ICONEXCLAMATION;
|
|
mbp.lpszIcon = NULL;
|
|
mbp.dwContextHelpId = 0L;
|
|
mbp.lpfnMsgBoxCallback = NULL;
|
|
MessageBoxIndirect(&mbp);
|
|
}
|
|
GlobalFreePtr (lpTemp);
|
|
}
|
|
}
|
|
nReturn=UniDevInstall(hWnd, lpDevName, lpOldPort, lpNewPort);
|
|
}
|
|
|
|
|
|
#ifdef CONVERT_FROM_WIN30
|
|
DI_exit:
|
|
#endif
|
|
|
|
#ifdef PRTCAPSTUFF
|
|
|
|
DoPrtCapsStuff(lpDevName,lpNewPort);
|
|
|
|
#endif
|
|
|
|
return nReturn;
|
|
}
|
|
|
|
|
|
// the following 3 definitions MUST be compatible with the
|
|
// HPPCL font installer
|
|
#define CLASS_LASERJET 0
|
|
#define CLASS_DESKJET 1
|
|
#define CLASS_DESKJET_PLUS 2
|
|
|
|
//---------------------------*InstallExtFonts*---------------------------------
|
|
// Action: call the specific font installer to add/delete/modify soft fonts
|
|
// and/or external cartridges.
|
|
//
|
|
// Parameters:
|
|
// HWND hWnd; handle to the parent windows.
|
|
// LPSTR lpDeviceName; long pointer to the printer name.
|
|
// LPSTR lpPortName; long pointer to the associated port name.
|
|
// BOOL bSoftFonts; flag if supporting soft fonts or not.
|
|
//
|
|
// Return Value:
|
|
// > 0 : if the font information has changed;
|
|
// == 0 : if nothing has changed;
|
|
// == -1 : if intending to use the universal font installer
|
|
// (not available now).
|
|
//-------------------------------------------------------------------------
|
|
|
|
int FAR PASCAL InstallExtFonts(hWnd, lpDeviceName, lpPortName, bSoftFonts)
|
|
HWND hWnd;
|
|
LPSTR lpDeviceName;
|
|
LPSTR lpPortName;
|
|
BOOL bSoftFonts;
|
|
{
|
|
int fsVers;
|
|
HANDLE hFIlib;
|
|
SFPROC lpFIns;
|
|
|
|
if ((hFIlib = LoadLibrary((LPSTR)"FINSTALL.DLL")) < 32 ||
|
|
!(lpFIns = (SFPROC)GetProcAddress(hFIlib,"InstallSoftFont")))
|
|
{
|
|
if (hFIlib >= 32)
|
|
FreeLibrary(hFIlib);
|
|
#ifdef DEBUG
|
|
MessageBox(0,
|
|
"Can't load FINSTALL.DLL or can't get InstallSoftFont",
|
|
NULL, MB_OK);
|
|
#endif
|
|
return TRUE;
|
|
}
|
|
|
|
// FINSTALL.DLL was loaded properly. Now call InstallSoftFont().
|
|
// We choose to ignore the returned fvers. No use of it.
|
|
fsVers = (*lpFIns)(hWnd, rgchModuleName, lpPortName,
|
|
(GetKeyState(VK_SHIFT) < 0 && GetKeyState(VK_CONTROL) < 0),
|
|
1, // dummy value for fvers.
|
|
bSoftFonts ? CLASS_LASERJET : 256
|
|
);
|
|
FreeLibrary(hFIlib);
|
|
return fsVers;
|
|
}
|
|
|
|
|
|
#endif // !WINNT
|