Leaked source code of windows server 2003
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

  1. //-----------------------------------------------------------------------------
  2. // This files contains the module name for this mini driver. Each mini driver
  3. // must have a unique module name. The module name is used to obtain the
  4. // module handle of this Mini Driver. The module handle is used by the
  5. // generic library to load in tables from the Mini Driver.
  6. // It also contains Install() for upgrading 3.0 driver to 3.1.
  7. //
  8. //
  9. //-----------------------------------------------------------------------------
  10. #include "strings.h"
  11. // #define CONVERT_FROM_WIN30
  12. char *rgchModuleName = "PCL4MSJ";
  13. char szSoftFonts[] = "SoftFonts";
  14. #ifdef CONVERT_FROM_WIN30
  15. char szPrtIndex[] = "prtindex";
  16. char szWinVer[] = "winver";
  17. char sz310[] = "310";
  18. char sz150[] = "150";
  19. char sz75[] = "75";
  20. char szNull[] = "";
  21. char szOrient[] = "orient";
  22. char szOrientation[] = "Orientation";
  23. char szPaper[] = "paper";
  24. char szPaperSize[] = "Paper Size";
  25. char szPrtResFac[] = "prtresfac";
  26. char szPrintQuality[] = "Print Quality";
  27. char szTray[] = "tray";
  28. char szDefaultSource[] = "Default Source";
  29. char szNumCart[] = "numcart";
  30. char szCartIndex[] = "cartindex";
  31. char szCartridge[] = "Cartridge ";
  32. char szNumberCart[] = "Number of Cartridges";
  33. char szFsVers[] = "fsvers";
  34. char szFontSummary[] = "Font Summary";
  35. // map old HPPCL's cartindex to unidrv's FONTCART index for newer cartridges.
  36. // This mapping table is created based on the old HPPCL .rc file.
  37. int rgNewCartMap[9] = {8, 7, 2, 3, 5, 6, 1, 4, 0};
  38. #endif
  39. #define PRINTDRIVER
  40. #include "print.h"
  41. #include "gdidefs.inc"
  42. #include "mdevice.h"
  43. #define DELETE_OLD
  44. #ifndef WINNT
  45. HDC FAR PASCAL CreateIC(LPCSTR, LPCSTR, LPCSTR, const VOID FAR*);
  46. BOOL FAR PASCAL DeleteDC(HDC);
  47. #endif // !WINNT
  48. #include "unidrv.h"
  49. #ifndef WINNT
  50. extern char *rgchModuleName; // global module name
  51. // typedef for soft font installer
  52. typedef int (FAR PASCAL *SFPROC)(HWND,LPSTR,LPSTR,BOOL,int,int);
  53. short NEAR PASCAL MakeAppName(LPSTR,LPCSTR,short);
  54. #define SOFT_FONT_THRES 25 // build font summary, if over this limit
  55. #define MAX_CART_INDEX 33
  56. #define MAX_OLD_CART 24
  57. #define TMPSIZE 256
  58. HINSTANCE hInst;
  59. #ifdef PRTCAPSTUFF
  60. char szPrtCaps[] = "prtcaps";
  61. #define MAX_NUM_MODELS 24
  62. #define MAX_MODEL_NAME 29
  63. typedef struct
  64. {
  65. char szModel[MAX_MODEL_NAME];
  66. int rgIndexLimit[2];
  67. char szPrtCaps[7]; // keep as a string instead of integer to avoid
  68. // conversion because itoa doesn't work here.
  69. } MODELMAP, FAR * LPMODELMAP;
  70. //-------------------------------------------------------------------
  71. // Function: DoPrtCapsStuff(lpDevName,lpPort)
  72. //
  73. // Action: Write out PRTCAPS under [<model>,<port>] section
  74. // in order to be backward-compatible with existing font
  75. // packages. Note that this code can fail
  76. // under extremely low memory conditions, so be sure and check
  77. // the return values from the resource calls.
  78. //-------------------------------------------------------------------
  79. void NEAR PASCAL DoPrtCapsStuff(LPSTR lpDevName,
  80. LPSTR lpPort)
  81. {
  82. char szOldSec[64];
  83. int i;
  84. HANDLE hMd;
  85. HANDLE hResMap;
  86. LPMODELMAP lpModelMap;
  87. lstrcpy(szOldSec,lpDevName);
  88. MakeAppName((LPSTR)szOldSec,lpPort,sizeof(szOldSec));
  89. hMd=GetModuleHandle((LPSTR)rgchModuleName);
  90. hResMap=LoadResource(hMd,FindResource(hMd,MAKEINTRESOURCE(1),RT_RCDATA));
  91. if(hResMap)
  92. {
  93. if(lpModelMap=(LPMODELMAP)LockResource(hResMap))
  94. {
  95. for (i=0;i<MAX_NUM_MODELS;i++)
  96. {
  97. if (!lstrcmp(lpDevName,(LPSTR)(lpModelMap[i].szModel)))
  98. {
  99. WriteProfileString((LPSTR)szOldSec,szPrtCaps,
  100. (LPSTR)lpModelMap[i].szPrtCaps);
  101. break;
  102. }
  103. }
  104. UnlockResource(hResMap);
  105. }
  106. FreeResource(hResMap);
  107. }
  108. }
  109. #endif
  110. //------------------------------------------------------------------------
  111. // Function: LibMain(hInstance,wDataSeg,cbHeapSize,lpszCmdLine)
  112. //
  113. // Action: Save the hInstance for this DLL
  114. //
  115. // Return: 1
  116. //------------------------------------------------------------------------
  117. int WINAPI LibMain (HANDLE hInstance,
  118. WORD wDataSeg,
  119. WORD cbHeapSize,
  120. LPSTR lpszCmdLine)
  121. {
  122. hInst=hInstance;
  123. return 1;
  124. }
  125. //--------------------------*MakeAppName*---------------------------------------
  126. // Action: compose the <printer,port> name for reading the profile data
  127. // Return the length of the actual application name. Return -1 if fails.
  128. //
  129. //------------------------------------------------------------------------------
  130. short NEAR PASCAL MakeAppName(LPSTR lpAppName,
  131. LPCSTR lpPortName,
  132. short max)
  133. {
  134. short length, count;
  135. LPCSTR lpTmp;
  136. LPCSTR lpLastColon = NULL;
  137. length = lstrlen(lpAppName);
  138. if (!lpPortName)
  139. return length;
  140. if (length == 0 || length > max - lstrlen(lpPortName))
  141. return -1;
  142. // insert the comma
  143. lpAppName[length++] = ',';
  144. // append the port name but do not want the last ':', if any.
  145. for (lpTmp = lpPortName ; *lpTmp; lpTmp++)
  146. if (*lpTmp == ':')
  147. lpLastColon = lpTmp;
  148. if (lpLastColon && lpLastColon == lpTmp - 1)
  149. count = lpLastColon - lpPortName;
  150. else
  151. count = lpTmp - lpPortName;
  152. lstrcpy((LPSTR)&lpAppName[length], lpPortName);
  153. length += count;
  154. lpAppName[length]='\0';
  155. return length;
  156. }
  157. #ifdef CONVERT_FROM_WIN30
  158. //------------------------------------------------------------------------------
  159. // Function: itoa
  160. //
  161. // Action: This function converts the given integer into an ASCII string.
  162. //
  163. // return: The length of the string.
  164. //-----------------------------------------------------------------------------
  165. short NEAR PASCAL itoa(buf, n)
  166. LPSTR buf;
  167. short n;
  168. {
  169. short fNeg;
  170. short i, j;
  171. if (fNeg = (n < 0))
  172. n = -n;
  173. for (i = 0; n; i++)
  174. {
  175. buf[i] = (char)(n % 10 + '0');
  176. n /= 10;
  177. }
  178. // n was zero
  179. if (i == 0)
  180. buf[i++] = '0';
  181. if (fNeg)
  182. buf[i++] = '-';
  183. for (j = 0; j < i / 2; j++)
  184. {
  185. short tmp;
  186. tmp = buf[j];
  187. buf[j] = buf[i - j - 1];
  188. buf[i - j - 1] = (char)tmp;
  189. }
  190. buf[i] = 0;
  191. return i;
  192. }
  193. #endif
  194. //-------------------------*DevInstall*---------------------------------------
  195. // Action: De-install, upgrade or install a device.
  196. //
  197. //----------------------------------------------------------------------------
  198. int FAR PASCAL DevInstall(hWnd, lpDevName, lpOldPort, lpNewPort)
  199. HWND hWnd;
  200. LPSTR lpDevName;
  201. LPSTR lpOldPort, lpNewPort;
  202. {
  203. char szOldSec[64];
  204. int nReturn=1;
  205. if (!lpDevName)
  206. return -1;
  207. if (!lpOldPort)
  208. {
  209. #ifdef CONVERT_FROM_WIN30
  210. char szNewSec[64];
  211. char szBuf[32];
  212. int tmp;
  213. int i, index;
  214. HANDLE hMd;
  215. HANDLE hResMap;
  216. LPMODELMAP lpModelMap;
  217. #endif
  218. if (!lpNewPort)
  219. return 0;
  220. #ifdef CONVERT_FROM_WIN30
  221. // install a device for the first time. Convert old HPPCL settings,
  222. // which are still under [<driver>,<port>], into equivalent new
  223. // UNIDRV settings under [<device>,<port>], if applicable.
  224. // All soft fonts are left under the section [<driver>,<port>].
  225. lstrcpy(szOldSec,rgchModuleName);
  226. MakeAppName((LPSTR)szOldSec, lpNewPort, sizeof(szOldSec));
  227. // if old section exists at all
  228. if (!GetProfileString(szOldSec, NULL, NULL, szBuf, sizeof(szBuf)))
  229. goto DI_exit;
  230. // make sure the old device settings are for this device.
  231. // If not, there is nothing to do here. Simply return 1.
  232. tmp = GetProfileInt(szOldSec, szPrtIndex, 0);
  233. hMd = GetModuleHandle((LPSTR)rgchModuleName);
  234. hResMap = LoadResource(hMd,
  235. FindResource(hMd, MAKEINTRESOURCE(1), RT_RCDATA));
  236. lpModelMap = (LPMODELMAP)LockResource(hResMap);
  237. for (i = 0; i < MAX_NUM_MODELS; i++)
  238. {
  239. if (!lstrcmp(lpDevName, (LPSTR)lpModelMap[i].szModel))
  240. {
  241. if ((tmp < lpModelMap[i].rgIndexLimit[0]) ||
  242. (tmp > lpModelMap[i].rgIndexLimit[1]) )
  243. i = MAX_NUM_MODELS; // not this model. No conversion.
  244. break;
  245. }
  246. }
  247. UnlockResource(hResMap);
  248. FreeResource(hResMap);
  249. if (i >= MAX_NUM_MODELS)
  250. // this model is not even listed in the old HPPCL driver.
  251. goto DI_exit;
  252. if (GetProfileInt(szOldSec, szWinVer, 0) == 310)
  253. goto DI_exit;
  254. WriteProfileString(szOldSec, szWinVer, sz310);
  255. #ifdef DELETE_OLD
  256. WriteProfileString(szOldSec, szPrtIndex, NULL);
  257. #endif
  258. lstrcpy(szNewSec, lpDevName);
  259. MakeAppName((LPSTR)szNewSec, lpNewPort, sizeof(szNewSec));
  260. // convertable device settings include: copies, duplex, orient,
  261. // paper, prtresfac, tray, and cartidges.
  262. if (GetProfileString(szOldSec, szOrient, szNull, szBuf, sizeof(szBuf)) > 0)
  263. {
  264. WriteProfileString(szNewSec, szOrientation, szBuf);
  265. #ifdef DELETE_OLD
  266. WriteProfileString(szOldSec, szOrient, NULL);
  267. #endif
  268. }
  269. if (GetProfileString(szOldSec, szPaper, szNull, szBuf, sizeof(szBuf)) > 0)
  270. {
  271. WriteProfileString(szNewSec, szPaperSize, szBuf);
  272. #ifdef DELETE_OLD
  273. WriteProfileString(szOldSec, szPaper, NULL);
  274. #endif
  275. }
  276. // default to 2 if cannot find it
  277. tmp = GetProfileInt(szOldSec, szPrtResFac, 2);
  278. if (tmp == 1)
  279. WriteProfileString(szNewSec, szPrintQuality, sz150);
  280. else if (tmp == 2)
  281. WriteProfileString(szNewSec, szPrintQuality, sz75);
  282. #ifdef DELETE_OLD
  283. WriteProfileString(szOldSec, szPrtResFac, NULL);
  284. #endif
  285. if (GetProfileString(szOldSec, szTray, szNull, szBuf, sizeof(szBuf)) > 0)
  286. {
  287. WriteProfileString(szNewSec, szDefaultSource, szBuf);
  288. #ifdef DELETE_OLD
  289. WriteProfileString(szOldSec, szTray, NULL);
  290. #endif
  291. }
  292. // try to convert the cartridge information.
  293. if ((tmp = GetProfileInt(szOldSec, szNumCart, 0)) == 0)
  294. tmp = 1;
  295. // this is executed at least once
  296. {
  297. char szOldCartKey[16];
  298. char szNewCartKey[16];
  299. char nCart = 0;
  300. lstrcpy(szOldCartKey, szCartIndex);
  301. for (i = 0; i < tmp; i++)
  302. {
  303. if (i > 0)
  304. itoa((LPSTR)&szOldCartKey[9], i);
  305. // compose cartridge keyname under UNIDRV.
  306. lstrcpy(szNewCartKey, szCartridge);
  307. itoa((LPSTR)&szNewCartKey[10], i + 1);
  308. if ((index = GetProfileInt(szOldSec, szOldCartKey, 0)) > 0)
  309. {
  310. WriteProfileString(szOldSec, szOldCartKey, NULL);
  311. nCart++;
  312. if (index <= MAX_OLD_CART)
  313. {
  314. itoa((LPSTR)szBuf, index + 8);
  315. WriteProfileString(szNewSec, szNewCartKey, szBuf);
  316. }
  317. else if (index <= MAX_CART_INDEX)
  318. {
  319. itoa((LPSTR)szBuf, rgNewCartMap[index - MAX_OLD_CART - 1]);
  320. WriteProfileString(szNewSec, szNewCartKey, szBuf);
  321. }
  322. else
  323. {
  324. // external cartridges. Simply copy the id over.
  325. itoa((LPSTR)szBuf, index);
  326. WriteProfileString(szNewSec, szNewCartKey, szBuf);
  327. }
  328. }
  329. }
  330. // integer to ASCII string conversion.
  331. itoa((LPSTR)szBuf, nCart);
  332. WriteProfileString(szNewSec, szNumberCart, szBuf);
  333. }
  334. // delete the old font summary file
  335. WriteProfileString(szOldSec, szFsVers, NULL);
  336. if (GetProfileString(szOldSec, szFontSummary, szNull, szBuf, sizeof(szBuf)) > 0)
  337. {
  338. int hFS;
  339. // truncate the old font summary file to zero size.
  340. if ((hFS = _lcreat(szBuf, 0)) >= 0)
  341. _lclose(hFS);
  342. WriteProfileString(szOldSec, szFontSummary, NULL);
  343. }
  344. // create UNIDRV's font summary file, if there are many soft fonts.
  345. if (GetProfileInt(szOldSec, szSoftFonts, 0) > SOFT_FONT_THRES)
  346. {
  347. HDC hIC;
  348. if (hIC = CreateIC("PCL4MSJ", lpDevName, lpNewPort, NULL))
  349. DeleteDC(hIC);
  350. }
  351. #endif
  352. }
  353. else
  354. {
  355. // move device settings from the old port to the new port, or
  356. // de-install a device, i.e. remove its device setttings in order
  357. // to compress the profile.
  358. // First, check if there is any soft font installed under the
  359. // old port. If so, warn the user to copy them over.
  360. lstrcpy(szOldSec, rgchModuleName);
  361. MakeAppName((LPSTR)szOldSec, lpOldPort, sizeof(szOldSec));
  362. if (GetProfileInt(szOldSec, szSoftFonts, 0) > 0 && lpNewPort)
  363. {
  364. LPBYTE lpTemp;
  365. if(lpTemp=GlobalAllocPtr(GMEM_MOVEABLE,TMPSIZE))
  366. {
  367. if(LoadString(hInst,IDS_SOFTFONTWARNING,lpTemp,TMPSIZE))
  368. {
  369. // Use this API so that the M Box is set to the Foreground
  370. MSGBOXPARAMS mbp;
  371. mbp.cbSize = sizeof(mbp);
  372. mbp.hwndOwner = hWnd;
  373. mbp.hInstance = hInst;
  374. mbp.lpszText = lpTemp;
  375. mbp.lpszCaption = lpOldPort;
  376. mbp.dwStyle = MB_SETFOREGROUND | MB_OK | MB_ICONEXCLAMATION;
  377. mbp.lpszIcon = NULL;
  378. mbp.dwContextHelpId = 0L;
  379. mbp.lpfnMsgBoxCallback = NULL;
  380. MessageBoxIndirect(&mbp);
  381. }
  382. GlobalFreePtr (lpTemp);
  383. }
  384. }
  385. nReturn=UniDevInstall(hWnd, lpDevName, lpOldPort, lpNewPort);
  386. }
  387. #ifdef CONVERT_FROM_WIN30
  388. DI_exit:
  389. #endif
  390. #ifdef PRTCAPSTUFF
  391. DoPrtCapsStuff(lpDevName,lpNewPort);
  392. #endif
  393. return nReturn;
  394. }
  395. // the following 3 definitions MUST be compatible with the
  396. // HPPCL font installer
  397. #define CLASS_LASERJET 0
  398. #define CLASS_DESKJET 1
  399. #define CLASS_DESKJET_PLUS 2
  400. //---------------------------*InstallExtFonts*---------------------------------
  401. // Action: call the specific font installer to add/delete/modify soft fonts
  402. // and/or external cartridges.
  403. //
  404. // Parameters:
  405. // HWND hWnd; handle to the parent windows.
  406. // LPSTR lpDeviceName; long pointer to the printer name.
  407. // LPSTR lpPortName; long pointer to the associated port name.
  408. // BOOL bSoftFonts; flag if supporting soft fonts or not.
  409. //
  410. // Return Value:
  411. // > 0 : if the font information has changed;
  412. // == 0 : if nothing has changed;
  413. // == -1 : if intending to use the universal font installer
  414. // (not available now).
  415. //-------------------------------------------------------------------------
  416. int FAR PASCAL InstallExtFonts(hWnd, lpDeviceName, lpPortName, bSoftFonts)
  417. HWND hWnd;
  418. LPSTR lpDeviceName;
  419. LPSTR lpPortName;
  420. BOOL bSoftFonts;
  421. {
  422. int fsVers;
  423. HANDLE hFIlib;
  424. SFPROC lpFIns;
  425. if ((hFIlib = LoadLibrary((LPSTR)"FINSTALL.DLL")) < 32 ||
  426. !(lpFIns = (SFPROC)GetProcAddress(hFIlib,"InstallSoftFont")))
  427. {
  428. if (hFIlib >= 32)
  429. FreeLibrary(hFIlib);
  430. #ifdef DEBUG
  431. MessageBox(0,
  432. "Can't load FINSTALL.DLL or can't get InstallSoftFont",
  433. NULL, MB_OK);
  434. #endif
  435. return TRUE;
  436. }
  437. // FINSTALL.DLL was loaded properly. Now call InstallSoftFont().
  438. // We choose to ignore the returned fvers. No use of it.
  439. fsVers = (*lpFIns)(hWnd, rgchModuleName, lpPortName,
  440. (GetKeyState(VK_SHIFT) < 0 && GetKeyState(VK_CONTROL) < 0),
  441. 1, // dummy value for fvers.
  442. bSoftFonts ? CLASS_LASERJET : 256
  443. );
  444. FreeLibrary(hFIlib);
  445. return fsVers;
  446. }
  447. #endif // !WINNT