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.

329 lines
9.5 KiB

  1. /*++
  2. Copyright (c) 1996-1998 Microsoft Corporation
  3. Module Name:
  4. gpc2gpd.c
  5. Abstract:
  6. GPC-to-GPD conversion program
  7. Environment:
  8. User-mode, stand-alone utility tool
  9. Revision History:
  10. 10/16/96 -zhanw-
  11. Created it.
  12. --*/
  13. #include "gpc2gpd.h"
  14. #if !defined(DEVSTUDIO) // MDT only uses onre routine
  15. VOID
  16. VUsage(
  17. PSTR pstrProgName
  18. )
  19. {
  20. printf("usage: gpc2gpd -I<GPC file>\r\n");
  21. printf(" -M<model index>\r\n");
  22. printf(" -R<resource DLL>\r\n");
  23. printf(" -O<GPD file>\r\n");
  24. printf(" -N<Model Name>\r\n");
  25. printf(" -S<0> -- output display strings directly \r\n");
  26. printf(" <1> -- output display strings as value macros\r\n");
  27. printf(" (see stdnames.gpd) \r\n");
  28. printf(" <2> -- output display strings as RC id's (see common.rc)\r\n");
  29. printf(" -P -- if present, use spooler names for standard papersizes\r\n");
  30. }
  31. #endif //!defined(DEVSTUDIO)
  32. void
  33. VOutputGlobalEntries(
  34. IN OUT PCONVINFO pci,
  35. IN PSTR pstrModelName,
  36. IN PSTR pstrResourceDLLName,
  37. IN PSTR pstrGPDFileName)
  38. {
  39. VOut(pci, "*GPDSpecVersion: \"1.0\"\r\n");
  40. //
  41. // *CodePage should be defined in the included GPD file
  42. //
  43. if (pci->dwStrType == STR_MACRO)
  44. VOut(pci, "*Include: \"StdNames.gpd\"\r\n");
  45. else
  46. VOut(pci, "*CodePage: 1252\r\n");
  47. VOut(pci, "*GPDFileVersion: \"1.0\"\r\n");
  48. VOut(pci, "*GPDFileName: \"%s\"\r\n", pstrGPDFileName);
  49. VOut(pci, "*ModelName: \"%s\"\r\n", pstrModelName);
  50. VOut(pci, "*MasterUnits: PAIR(%d, %d)\r\n", pci->pdh->ptMaster.x, pci->pdh->ptMaster.y);
  51. VOut(pci, "*ResourceDLL: \"%s\"\r\n", pstrResourceDLLName);
  52. if (pci->pdh->fTechnology == GPC_TECH_TTY)
  53. VOut(pci, "*PrinterType: TTY\r\n");
  54. else if (pci->pmd->fGeneral & MD_SERIAL)
  55. VOut(pci, "*PrinterType: SERIAL\r\n");
  56. else
  57. VOut(pci, "*PrinterType: PAGE\r\n");
  58. if ((pci->pmd->fGeneral & MD_COPIES) && pci->ppc->sMaxCopyCount > 1)
  59. VOut(pci, "*MaxCopies: %d\r\n", pci->ppc->sMaxCopyCount);
  60. if (pci->pmd->sCartSlots > 0)
  61. VOut(pci, "*FontCartSlots: %d\r\n", pci->pmd->sCartSlots);
  62. if (pci->pmd->fGeneral & MD_CMD_CALLBACK)
  63. pci->dwErrorCode |= ERR_MD_CMD_CALLBACK;
  64. }
  65. #if !defined(DEVSTUDIO) // MDT only uses the above code
  66. void
  67. VPrintErrors(
  68. IN HANDLE hLogFile,
  69. IN DWORD dwError)
  70. {
  71. DWORD dwNumBytesWritten;
  72. DWORD i, len;
  73. for (i = 0; i < NUM_ERRS; i++)
  74. {
  75. if (dwError & gdwErrFlag[i])
  76. {
  77. len = strlen(gpstrErrMsg[i]);
  78. if (!WriteFile(hLogFile, gpstrErrMsg[i], len, &dwNumBytesWritten, NULL) ||
  79. dwNumBytesWritten != len)
  80. return; // abort
  81. }
  82. }
  83. }
  84. INT _cdecl
  85. main(
  86. INT argc,
  87. CHAR **argv
  88. )
  89. /*++
  90. Routine Desscription:
  91. This routine parses the command line parameters, maps the GPC file into memory
  92. and creates the output GPD file. It then starts converting GPC data by calling
  93. various sub-routines. If any error occurs, it reports errors and tries to
  94. continue if possible.
  95. The following command line parameters are supported:
  96. -I<GPC_file> : the file name does not need double quotes. Ex. -Icanon330.gpc
  97. -M<model_id>: an integer, such as 1, which is the string resource id of the
  98. the model name in the .rc file that comes with the given GPC
  99. file.
  100. -N<model_name>: a string, such as "HP LaserJet 4L".
  101. -R<resource_dll>: the resource dll to be associated with the generated GPD
  102. file. Ex. -Rcanon330.dll
  103. -O<GPD_file>: the output GPD file name. Ex. -Ohplj4l.gpd
  104. -S<style>: the string style used in generating the GPD file for standard names.
  105. -S0 means using the direct strings for *Name entries.
  106. -S1 means using string value macros for *Name entries. This is
  107. mainly used for on-the-fly conversion. The value macros are
  108. defined in printer5\inc\stdnames.gpd.
  109. -S2 means using RC string id's. These strings are defined in
  110. printer5\inc\common.rc.
  111. -P rcNameID: 0x7fffffff for standard papersizes.
  112. Arguments:
  113. argc - number of arguments
  114. **argv - pointer to an array of strings
  115. Return value:
  116. 0
  117. --*/
  118. {
  119. PSTR pstrProgName;
  120. PSTR pstrGPCFileName = NULL;
  121. WCHAR wstrGPCFile[MAX_PATH];
  122. PSTR pstrGPDFileName = NULL;
  123. WCHAR wstrGPDFile[MAX_PATH];
  124. PSTR pstrResourceDLLName = NULL;
  125. PSTR pstrModelName = NULL;
  126. HFILEMAP hGPCFileMap;
  127. CONVINFO ci; // structure to keep track conversion information
  128. DWORD dwStrType = STR_MACRO; // default
  129. WORD wModelIndex;
  130. BOOL bUseSystemPaperNames = FALSE;
  131. //
  132. // Go through the command line arguments
  133. //
  134. pstrProgName = *argv++;
  135. argc--;
  136. if (argc == 0)
  137. goto error_exit;
  138. for ( ; argc--; argv++)
  139. {
  140. PSTR pArg = *argv;
  141. if (*pArg == '-' || *pArg == '/')
  142. {
  143. switch (*++pArg)
  144. {
  145. case 'I':
  146. pstrGPCFileName = ++pArg;
  147. break;
  148. case 'M':
  149. wModelIndex = (WORD)atoi(++pArg);
  150. break;
  151. case 'R':
  152. pstrResourceDLLName = ++pArg;
  153. break;
  154. case 'O':
  155. pstrGPDFileName = ++pArg;
  156. break;
  157. case 'N':
  158. pstrModelName = ++pArg;
  159. break;
  160. case 'S':
  161. dwStrType = atoi(++pArg);
  162. break;
  163. case 'P':
  164. bUseSystemPaperNames = TRUE;
  165. break;
  166. default:
  167. goto error_exit;
  168. }
  169. }
  170. else
  171. goto error_exit;
  172. }
  173. //
  174. // check if we have all the arguments needed
  175. //
  176. if (!pstrGPCFileName || !pstrGPDFileName || !pstrResourceDLLName ||
  177. !wModelIndex || !pstrModelName)
  178. goto error_exit;
  179. ZeroMemory((PVOID)&ci, sizeof(CONVINFO));
  180. //
  181. // Open the GPC file and map it into memory.
  182. //
  183. MultiByteToWideChar(CP_ACP, 0, pstrGPCFileName, -1, wstrGPCFile, MAX_PATH);
  184. hGPCFileMap = MapFileIntoMemory((LPCTSTR)wstrGPCFile, (PVOID *)&(ci.pdh), NULL);
  185. if (!hGPCFileMap)
  186. {
  187. ERR(("Couldn't open file: %ws\r\n", pstrGPCFileName));
  188. return (-1);
  189. }
  190. //
  191. // create the output GPD file. If the given file already exists,
  192. // overwrite it.
  193. //
  194. MultiByteToWideChar(CP_ACP, 0, pstrGPDFileName, -1, wstrGPDFile, MAX_PATH);
  195. ci.hGPDFile = CreateFile((PCTSTR)wstrGPDFile, GENERIC_WRITE, 0, NULL,
  196. CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  197. if (ci.hGPDFile == INVALID_HANDLE_VALUE)
  198. {
  199. ERR(("Couldn't create file: %ws\r\n", pstrGPDFileName));
  200. UnmapFileFromMemory(hGPCFileMap);
  201. return (-1);
  202. }
  203. //
  204. // GPC file sanity check
  205. //
  206. if (ci.pdh->sMagic != 0x7F00 ||
  207. !(ci.pmd = (PMODELDATA)GetTableInfo(ci.pdh, HE_MODELDATA, wModelIndex-1)) ||
  208. !(ci.ppc = (PPAGECONTROL)GetTableInfo(ci.pdh, HE_PAGECONTROL,
  209. ci.pmd->rgi[MD_I_PAGECONTROL])))
  210. {
  211. ci.dwErrorCode |= ERR_BAD_GPCDATA;
  212. goto exit;
  213. }
  214. //
  215. // allocate dynamic buffers needed for conversion
  216. //
  217. if (!(ci.ppiSize=(PPAPERINFO)MemAllocZ(ci.pdh->rghe[HE_PAPERSIZE].sCount*sizeof(PAPERINFO))) ||
  218. !(ci.ppiSrc=(PPAPERINFO)MemAllocZ(ci.pdh->rghe[HE_PAPERSOURCE].sCount*sizeof(PAPERINFO))) ||
  219. !(ci.presinfo=(PRESINFO)MemAllocZ(ci.pdh->rghe[HE_RESOLUTION].sCount*sizeof(RESINFO))))
  220. {
  221. ci.dwErrorCode |= ERR_OUT_OF_MEMORY;
  222. goto exit;
  223. }
  224. ci.dwStrType = dwStrType;
  225. ci.bUseSystemPaperNames = bUseSystemPaperNames ;
  226. //
  227. // generate GPD data
  228. //
  229. VOutputGlobalEntries(&ci, pstrModelName, pstrResourceDLLName, pstrGPDFileName);
  230. VOutputUIEntries(&ci);
  231. VOutputPrintingEntries(&ci);
  232. exit:
  233. UnmapFileFromMemory(hGPCFileMap);
  234. CloseHandle(ci.hGPDFile);
  235. if (ci.ppiSize)
  236. MemFree(ci.ppiSize);
  237. if (ci.ppiSrc)
  238. MemFree(ci.ppiSrc);
  239. if (ci.presinfo)
  240. MemFree(ci.presinfo);
  241. if (ci.dwErrorCode)
  242. {
  243. PWSTR pwstrLogFileName;
  244. INT i;
  245. HANDLE hLogFile;
  246. //
  247. // Open the log file and print out errors/warnings.
  248. // Borrow the GPD file name buffer.
  249. //
  250. pwstrLogFileName = wstrGPDFile;
  251. i = _tcslen((PTSTR)pwstrLogFileName);
  252. if (_tcsrchr((PTSTR)pwstrLogFileName, TEXT('.')) != NULL)
  253. i = i - 4; // there is a .GPD extension
  254. StringCchCopyW((PTSTR)pwstrLogFileName + i, CCHOF(wstrGPDFile) - i, TEXT(".log"));
  255. hLogFile = CreateFile((PCTSTR)pwstrLogFileName, GENERIC_WRITE, 0, NULL,
  256. CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  257. if (hLogFile == INVALID_HANDLE_VALUE)
  258. {
  259. ERR(("Couldn't create the log file\r\n"));
  260. return (-1);
  261. }
  262. VPrintErrors(hLogFile, ci.dwErrorCode);
  263. CloseHandle(hLogFile);
  264. }
  265. return 0;
  266. error_exit:
  267. VUsage(pstrProgName);
  268. return (-1);
  269. }
  270. #endif // !defined(DEVSTUDIO)