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.

562 lines
14 KiB

  1. /*++
  2. Copyright (c) 1996-1999 Microsoft Corporation
  3. Module Name:
  4. data.h
  5. Abstract:
  6. Interface to PPD/GPD parsers and deals with getting binary data.
  7. Environment:
  8. Windows NT Unidrv driver
  9. Revision History:
  10. 10/15/96 -amandan-
  11. Created
  12. --*/
  13. #include "unidrv.h"
  14. PGPDDRIVERINFO
  15. PGetDefaultDriverInfo(
  16. IN HANDLE hPrinter,
  17. IN PRAWBINARYDATA pRawData
  18. )
  19. /*++
  20. Routine Description:
  21. This function just need to get default driverinfo
  22. Arguments:
  23. hPrinter - Handle to printer.
  24. pRawData - Pointer to RAWBINARYDATA
  25. Return Value:
  26. Returns pUIInfo
  27. Note:
  28. --*/
  29. {
  30. PINFOHEADER pInfoHeader;
  31. //
  32. // Set the current driver version
  33. //
  34. pInfoHeader = InitBinaryData(pRawData, NULL, NULL);
  35. //
  36. // Get GPDDRIVERINFO
  37. //
  38. if (pInfoHeader == NULL)
  39. return NULL;
  40. else
  41. return(OFFSET_TO_POINTER(pInfoHeader, pInfoHeader->loDriverOffset));
  42. }
  43. PGPDDRIVERINFO
  44. PGetUpdateDriverInfo (
  45. IN PDEV * pPDev,
  46. IN HANDLE hPrinter,
  47. IN PINFOHEADER pInfoHeader,
  48. IN POPTSELECT pOptionsArray,
  49. IN PRAWBINARYDATA pRawData,
  50. IN WORD wMaxOptions,
  51. IN PDEVMODE pdmInput,
  52. IN PPRINTERDATA pPrinterData
  53. )
  54. /*++
  55. Routine Description:
  56. This function calls the parser to get the updated INFOHEADER
  57. for the binary data.
  58. Arguments:
  59. hPrinter Handle to printer
  60. pOptionsArray pointer to optionsarray
  61. pRawData Pointer to RAWBINARYDATA
  62. wMaxOptions max count for optionsarray
  63. pdmInput Pointer to input DEVMODE
  64. pPrinterData Pointer to PRINTERDATA
  65. Return Value:
  66. PINFOHEADER , NULL if failure.
  67. Note:
  68. At this point the input devmode have been validated. And its option
  69. array is either the default or its own valid array. Don't need to check
  70. again in this function.
  71. Once completed, this function should have filled out the pOptionsArray with
  72. 1. Combined array from PRINTERDATA and DEVMODE
  73. 2. Resolve UI Conflicts
  74. --*/
  75. {
  76. PUNIDRVEXTRA pdmPrivate;
  77. POPTSELECT pDocOptions, pPrinterOptions;
  78. RECTL rcFormImageArea;
  79. OPTSELECT DocOptions[MAX_PRINTER_OPTIONS];
  80. OPTSELECT PrinterOptions[MAX_PRINTER_OPTIONS];
  81. //
  82. // Check for PRINTERDATA.dwChecksum32, If matches with current binary data,
  83. // Use it to combine PRINTERDATA.aOptions to combined array
  84. //
  85. pPrinterOptions = pPrinterData->dwChecksum32 == pRawData->dwChecksum32 ?
  86. pPrinterData->aOptions : NULL;
  87. if (pdmInput)
  88. {
  89. pdmPrivate = (PUNIDRVEXTRA) GET_DRIVER_PRIVATE_DEVMODE(pdmInput);
  90. pDocOptions = pdmPrivate->aOptions;
  91. }
  92. else
  93. pDocOptions = NULL;
  94. //
  95. // Combine the option arrays to pOptionsArray
  96. // Note: pDocOptions and pPrinterOptions cannot be NULL when combining
  97. // options array to get snapshot.
  98. //
  99. if (pDocOptions == NULL)
  100. {
  101. if (! InitDefaultOptions(pRawData,
  102. DocOptions,
  103. MAX_PRINTER_OPTIONS,
  104. MODE_DOCUMENT_STICKY))
  105. {
  106. return FALSE;
  107. }
  108. pDocOptions = DocOptions;
  109. }
  110. if (pPrinterOptions == NULL)
  111. {
  112. if (! InitDefaultOptions(pRawData,
  113. PrinterOptions,
  114. MAX_PRINTER_OPTIONS,
  115. MODE_PRINTER_STICKY))
  116. {
  117. return FALSE;
  118. }
  119. pPrinterOptions = PrinterOptions;
  120. }
  121. CombineOptionArray(pRawData, pOptionsArray, wMaxOptions, pDocOptions, pPrinterOptions);
  122. if (! BMergeFormToTrayAssignments(pPDev))
  123. {
  124. ERR(("BMergeFormToTrayAssignments failed"));
  125. }
  126. //
  127. // Resolve any UI conflicts.
  128. //
  129. if (!ResolveUIConflicts( pRawData,
  130. pOptionsArray,
  131. MAX_PRINTER_OPTIONS,
  132. MODE_DOCANDPRINTER_STICKY))
  133. {
  134. VERBOSE(("Resolved conflicting printer feature selections.\n"));
  135. }
  136. //
  137. // We are here means pOptionsArray is valid. Call parser to UpdateBinaryData
  138. //
  139. pInfoHeader = InitBinaryData(pRawData,
  140. pInfoHeader,
  141. pOptionsArray);
  142. //
  143. // Get GPDDRIVERINFO
  144. //
  145. if (pInfoHeader == NULL)
  146. return NULL;
  147. else
  148. return(OFFSET_TO_POINTER(pInfoHeader, pInfoHeader->loDriverOffset));
  149. }
  150. VOID
  151. VFixOptionsArray(
  152. PDEV *pPDev,
  153. PRECTL prcFormImageArea
  154. )
  155. /*++
  156. Routine Description:
  157. This functions is called to propagate public devmode settings
  158. to the combined option array.
  159. Arguments:
  160. hPrinter Handle to printer
  161. pInfoHeader Pointer to INFOHEADER
  162. pOptionsArray Pointer to the options array
  163. pdmInput Pointer to input devmode
  164. bMetric Flag to indicate running in metric system
  165. prcImageArea Returns the logical imageable area associated with the requested form
  166. Return Value:
  167. None
  168. Note:
  169. --*/
  170. {
  171. WORD wGID, wOptID, wOption;
  172. HANDLE hPrinter = pPDev->devobj.hPrinter ;
  173. PINFOHEADER pInfoHeader = pPDev->pInfoHeader ;
  174. POPTSELECT pOptionsArray = pPDev->pOptionsArray ;
  175. PDEVMODE pdmInput = pPDev->pdm ;
  176. BOOL bMetric = pPDev->PrinterData.dwFlags & PFLAGS_METRIC ;
  177. //
  178. // Validate the form-related fields in the input devmode and
  179. // make sure they're consistent with each other.
  180. //
  181. if (BValidateDevmodeFormFields(hPrinter, pdmInput, prcFormImageArea, NULL, 0) == FALSE)
  182. {
  183. //
  184. // If failed to validate the form fields, ask parser to
  185. // use the default
  186. //
  187. VDefaultDevmodeFormFields(pPDev->pUIInfo, pdmInput, bMetric );
  188. prcFormImageArea->top = prcFormImageArea->left = 0;
  189. prcFormImageArea->right = pdmInput->dmPaperWidth * DEVMODE_PAPER_UNIT;
  190. prcFormImageArea->bottom = pdmInput->dmPaperLength * DEVMODE_PAPER_UNIT;
  191. }
  192. for (wOption = 0; wOption < MAX_GID; wOption++)
  193. {
  194. switch(wOption)
  195. {
  196. case 0:
  197. wGID = GID_PAGESIZE;
  198. VFixOptionsArrayWithPaperSizeID(pPDev) ;
  199. continue;
  200. break;
  201. case 1:
  202. wGID = GID_DUPLEX;
  203. break;
  204. case 2:
  205. wGID = GID_INPUTSLOT;
  206. break;
  207. case 3:
  208. wGID = GID_MEDIATYPE;
  209. break;
  210. case 4:
  211. wGID = GID_COLORMODE;
  212. break;
  213. case 5:
  214. wGID = GID_COLLATE;
  215. break;
  216. case 6:
  217. wGID = GID_RESOLUTION;
  218. break;
  219. case 7:
  220. wGID = GID_ORIENTATION;
  221. break;
  222. default:
  223. continue;
  224. }
  225. ChangeOptionsViaID(pInfoHeader, pOptionsArray, wGID, pdmInput);
  226. }
  227. }
  228. PWSTR
  229. PGetROnlyDisplayName(
  230. PDEV *pPDev,
  231. PTRREF loOffset,
  232. PWSTR wstrBuf,
  233. WORD wsize
  234. )
  235. /*++
  236. revised capabilities:
  237. caller must pass in a local buffer to
  238. hold the string, the local buffer
  239. shall be of fixed size say
  240. WCHAR wchbuf[MAX_DISPLAY_NAME];
  241. The return value shall be either the passed
  242. in ptr or a ptr pointing directly to the buds
  243. binary data.
  244. Routine Description:
  245. Get a read-only copy of a display name:
  246. 1) if the display name is in the binary printer description data,
  247. then we simply return a pointer to that data.
  248. 2) otherwise, the display name is in the resource DLL.
  249. we allocate memory out of the driver's heap and
  250. load the string.
  251. Caller should NOT attempt to free the returned pointer unless
  252. that pointer is one he allocated.
  253. Arguments:
  254. pci - Points to basic printer info
  255. loOffset - Display name string offset
  256. Return Value:
  257. Pointer to the requested display name string
  258. NULL if there is an error or string not found in resource.dll
  259. --*/
  260. {
  261. if (loOffset & GET_RESOURCE_FROM_DLL)
  262. {
  263. //
  264. // loOffset specifies a string resource ID
  265. // in the resource DLL
  266. //
  267. INT iLength;
  268. //
  269. // First ensure the resource DLL has been loaded
  270. // and a heap has already been created
  271. //
  272. // nah, just look here!
  273. // pPDev->WinResData.hModule ;
  274. //
  275. // Load string resource into a temporary buffer
  276. // and allocate enough memory to hold the string
  277. //
  278. // #ifdef RCSTRINGSUPPORT
  279. #if 0
  280. if(((loOffset & ~GET_RESOURCE_FROM_DLL) >= RESERVED_STRINGID_START)
  281. && ((loOffset & ~GET_RESOURCE_FROM_DLL) <= RESERVED_STRINGID_END))
  282. {
  283. iLength = ILoadStringW( &pPDev->localWinResData,
  284. (int)( loOffset & ~GET_RESOURCE_FROM_DLL),
  285. wstrBuf, wsize );
  286. }
  287. else
  288. #endif
  289. {
  290. iLength = ILoadStringW( &pPDev->WinResData,
  291. (int)( loOffset & ~GET_RESOURCE_FROM_DLL),
  292. wstrBuf, wsize );
  293. }
  294. if( iLength)
  295. return (wstrBuf); // debug check that buffer is null terminated.
  296. return(NULL); // no string was found!
  297. }
  298. else
  299. {
  300. //
  301. // loOffset is a byte offset from the beginning of
  302. // the resource data block
  303. //
  304. return OFFSET_TO_POINTER(pPDev->pUIInfo->pubResourceData, loOffset);
  305. // note wchbuf is ignored in this case.
  306. }
  307. }
  308. VOID
  309. VFixOptionsArrayWithPaperSizeID(
  310. PDEV *pPDev
  311. )
  312. /*++
  313. Routine Description:
  314. Fix up combined options array with paper size information from public devmode fields
  315. Arguments:
  316. pci - Points to basic printer info
  317. Return Value:
  318. NONE
  319. function uses:
  320. UImodule Render Module equiv
  321. pci->pUIInfo pPDev->pUIInfo
  322. pci->pInfoHeader pPDev->pInfoHeader
  323. pci->pdm pPDev->pdm
  324. pci->pRawData pPDev->pRawData
  325. pci->pCombinedOptions pPDev->pOptionsArray
  326. MapToDeviceOptIndex
  327. PGetIndexedOption
  328. PGetReadOnlyDisplayName
  329. ReconstructOptionArray
  330. --*/
  331. {
  332. PFEATURE pFeature = GET_PREDEFINED_FEATURE(pPDev->pUIInfo, GID_PAGESIZE);
  333. BOOL abEnabledOptions[MAX_PRINTER_OPTIONS];
  334. PDWORD pdwPaperIndex = (PDWORD)abEnabledOptions;
  335. DWORD dwCount, dwOptionIndex, i;
  336. if (pFeature == NULL)
  337. return;
  338. dwCount = MapToDeviceOptIndex(pPDev->pInfoHeader,
  339. GID_PAGESIZE,
  340. pPDev->pdm->dmPaperWidth * DEVMODE_PAPER_UNIT,
  341. pPDev->pdm->dmPaperLength * DEVMODE_PAPER_UNIT,
  342. pdwPaperIndex);
  343. if (dwCount == 0 )
  344. return;
  345. dwOptionIndex = pdwPaperIndex[0];
  346. if (dwCount > 1 )
  347. {
  348. POPTION pOption;
  349. PCWSTR pDisplayName;
  350. WCHAR wchBuf[MAX_DISPLAY_NAME];
  351. for (i = 0; i < dwCount; i++)
  352. {
  353. if (pOption = PGetIndexedOption(pPDev->pUIInfo, pFeature, pdwPaperIndex[i]))
  354. {
  355. if(pOption->loDisplayName == 0xffffffff) //use papername from EnumForms()
  356. {
  357. PFORM_INFO_1 pForms;
  358. DWORD dwFormIndex ;
  359. // temp hack!!! possibly needed for NT40 ?
  360. // dwOptionIndex = pdwPaperIndex[i];
  361. // break;
  362. // end hack.
  363. // ----- the fix ------ //
  364. if (pPDev->pSplForms == NULL)
  365. pPDev->pSplForms = MyEnumForms(pPDev->devobj.hPrinter, 1, &pPDev->dwSplForms);
  366. if (pPDev->pSplForms == NULL)
  367. {
  368. // ERR(("No spooler forms.\n")); just a heads up.
  369. // dwOptionIndex already set to safe default
  370. break;
  371. }
  372. pForms = pPDev->pSplForms ;
  373. dwFormIndex = ((PPAGESIZE)pOption)->dwPaperSizeID - 1 ;
  374. if ( (dwFormIndex < pPDev->dwSplForms) &&
  375. (pDisplayName = (pForms[dwFormIndex]).pName) &&
  376. (_wcsicmp(pPDev->pdm->dmFormName, pDisplayName) == EQUAL_STRING) )
  377. {
  378. dwOptionIndex = pdwPaperIndex[i];
  379. break;
  380. }
  381. }
  382. else if ( (pDisplayName = PGetROnlyDisplayName(pPDev, pOption->loDisplayName,
  383. wchBuf, MAX_DISPLAY_NAME )) &&
  384. (_wcsicmp(pPDev->pdm->dmFormName, pDisplayName) == EQUAL_STRING) )
  385. {
  386. dwOptionIndex = pdwPaperIndex[i];
  387. break;
  388. }
  389. }
  390. } // if name doesn't match we default to the first candidate.
  391. }
  392. ZeroMemory(abEnabledOptions, sizeof(abEnabledOptions));
  393. abEnabledOptions[dwOptionIndex] = TRUE;
  394. ReconstructOptionArray(pPDev->pRawData,
  395. pPDev->pOptionsArray,
  396. MAX_COMBINED_OPTIONS,
  397. GET_INDEX_FROM_FEATURE(pPDev->pUIInfo, pFeature),
  398. abEnabledOptions);
  399. }