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.

1495 lines
35 KiB

  1. /*++
  2. Copyright (c) 1996-1997 Microsoft Corporation
  3. Module Name:
  4. regdata.c
  5. Abstract:
  6. Functions for dealing with registry data
  7. [Environment:]
  8. Windows NT printer drivers
  9. Revision History:
  10. 02/04/97 -davidx-
  11. Use REG_MULTI_SZ type where appropriate.
  12. 01/21/97 -davidx-
  13. Add functions to manipulate MultiSZ strings.
  14. 09/25/96 -davidx-
  15. Convert to Hungarian notation.
  16. 08/18/96 -davidx-
  17. Implement GetPrinterProperties.
  18. 08/13/96 -davidx-
  19. Created it.
  20. --*/
  21. #include "lib.h"
  22. BOOL
  23. BGetPrinterDataDWord(
  24. IN HANDLE hPrinter,
  25. IN LPCTSTR ptstrRegKey,
  26. OUT PDWORD pdwValue
  27. )
  28. /*++
  29. Routine Description:
  30. Get a DWORD value from the registry under PrinerDriverData key
  31. Arguments:
  32. hPrinter - Specifies the printer object
  33. ptstrRegKey - Specifies the name of registry value
  34. pdwValue - Returns the requested DWORD value in the registry
  35. Return Value:
  36. TRUE if successful, FALSE if there is an error
  37. --*/
  38. {
  39. DWORD dwType, dwByteCount, dwStatus;
  40. dwStatus = GetPrinterData(hPrinter,
  41. (PTSTR) ptstrRegKey,
  42. &dwType,
  43. (PBYTE) pdwValue,
  44. sizeof(DWORD),
  45. &dwByteCount);
  46. if (dwStatus != ERROR_SUCCESS)
  47. VERBOSE(("GetPrinterData failed: %d\n", dwStatus));
  48. return (dwStatus == ERROR_SUCCESS);
  49. }
  50. PVOID
  51. PvGetPrinterDataBinary(
  52. IN HANDLE hPrinter,
  53. IN LPCTSTR ptstrSizeKey,
  54. IN LPCTSTR ptstrDataKey,
  55. OUT PDWORD pdwSize
  56. )
  57. /*++
  58. Routine Description:
  59. Get binary data from the registry under PrinterDriverData key
  60. Arguments:
  61. hPrinter - Handle to the printer object
  62. ptstrSizeKey - Name of the registry value which contains the binary data size
  63. ptstrDataKey - Name of the registry value which contains the binary data itself
  64. pdwSize - Points to a variable for receiving the binary data size
  65. Return Value:
  66. Pointer to the binary printer data read from the registry
  67. NULL if there is an error
  68. --*/
  69. {
  70. DWORD dwType, dwSize, dwByteCount;
  71. PVOID pvData = NULL;
  72. if (GetPrinterData(hPrinter,
  73. (PTSTR) ptstrSizeKey,
  74. &dwType,
  75. (PBYTE) &dwSize,
  76. sizeof(dwSize),
  77. &dwByteCount) == ERROR_SUCCESS &&
  78. dwSize > 0 &&
  79. (pvData = MemAlloc(dwSize)) &&
  80. GetPrinterData(hPrinter,
  81. (PTSTR) ptstrDataKey,
  82. &dwType,
  83. pvData,
  84. dwSize,
  85. &dwByteCount) == ERROR_SUCCESS &&
  86. dwSize == dwByteCount)
  87. {
  88. if (pdwSize)
  89. *pdwSize = dwSize;
  90. return pvData;
  91. }
  92. VERBOSE(("GetPrinterData failed: %ws/%ws\n", ptstrSizeKey, ptstrDataKey));
  93. MemFree(pvData);
  94. return NULL;
  95. }
  96. PTSTR
  97. PtstrGetPrinterDataString(
  98. IN HANDLE hPrinter,
  99. IN LPCTSTR ptstrRegKey,
  100. OUT LPDWORD pdwSize
  101. )
  102. /*++
  103. Routine Description:
  104. Get a string value from PrinerDriverData registry key
  105. Arguments:
  106. hPrinter - Specifies the printer object
  107. ptstrRegKey - Specifies the name of registry value
  108. pdwSize - Specifies the size
  109. Return Value:
  110. Pointer to the string value read from the registry
  111. NULL if there is an error
  112. --*/
  113. {
  114. DWORD dwType, dwSize, dwStatus;
  115. PVOID pvData = NULL;
  116. dwStatus = GetPrinterData(hPrinter, (PTSTR) ptstrRegKey, &dwType, NULL, 0, &dwSize);
  117. if ((dwStatus == ERROR_MORE_DATA || dwStatus == ERROR_SUCCESS) &&
  118. (dwSize > 0) &&
  119. (dwType == REG_SZ || dwType == REG_MULTI_SZ) &&
  120. (pvData = MemAlloc(dwSize)) != NULL &&
  121. (dwStatus = GetPrinterData(hPrinter,
  122. (PTSTR) ptstrRegKey,
  123. &dwType,
  124. pvData,
  125. dwSize,
  126. &dwSize)) == ERROR_SUCCESS)
  127. {
  128. if (pdwSize)
  129. *pdwSize = dwSize;
  130. return pvData;
  131. }
  132. VERBOSE(("GetPrinterData '%ws' failed: %d\n", ptstrRegKey, dwStatus));
  133. MemFree(pvData);
  134. return NULL;
  135. }
  136. PTSTR
  137. PtstrGetPrinterDataMultiSZPair(
  138. IN HANDLE hPrinter,
  139. IN LPCTSTR ptstrRegKey,
  140. OUT PDWORD pdwSize
  141. )
  142. /*++
  143. Routine Description:
  144. Get a MULTI_SZ value from PrinerDriverData registry key
  145. Arguments:
  146. hPrinter - Specifies the printer object
  147. ptstrRegKey - Specifies the name of registry value
  148. pdwSize - Return the size of MULTI_SZ value in bytes
  149. Return Value:
  150. Pointer to the MULTI_SZ value read from the registry
  151. NULL if there is an error
  152. --*/
  153. {
  154. DWORD dwType, dwSize, dwStatus;
  155. PVOID pvData = NULL;
  156. dwStatus = GetPrinterData(hPrinter, (PTSTR) ptstrRegKey, &dwType, NULL, 0, &dwSize);
  157. if ((dwStatus == ERROR_MORE_DATA || dwStatus == ERROR_SUCCESS) &&
  158. (dwSize > 0) &&
  159. (pvData = MemAlloc(dwSize)) != NULL &&
  160. (dwStatus = GetPrinterData(hPrinter,
  161. (PTSTR) ptstrRegKey,
  162. &dwType,
  163. pvData,
  164. dwSize,
  165. &dwSize)) == ERROR_SUCCESS &&
  166. BVerifyMultiSZPair(pvData, dwSize))
  167. {
  168. if (pdwSize)
  169. *pdwSize = dwSize;
  170. return pvData;
  171. }
  172. VERBOSE(("GetPrinterData '%ws' failed: %d\n", ptstrRegKey, dwStatus));
  173. MemFree(pvData);
  174. return NULL;
  175. }
  176. BOOL
  177. BGetDeviceHalftoneSetup(
  178. HANDLE hPrinter,
  179. DEVHTINFO *pDevHTInfo
  180. )
  181. /*++
  182. Routine Description:
  183. Retrieve device halftone setup information from registry
  184. Arguments:
  185. hprinter - Handle to the printer
  186. pDevHTInfo - Pointer to a DEVHTINFO buffer
  187. Return Value:
  188. TRUE if successful, FALSE otherwise
  189. --*/
  190. {
  191. DWORD dwType, dwNeeded;
  192. return GetPrinterData(hPrinter,
  193. REGVAL_CURRENT_DEVHTINFO,
  194. &dwType,
  195. (PBYTE) pDevHTInfo,
  196. sizeof(DEVHTINFO),
  197. &dwNeeded) == ERROR_SUCCESS &&
  198. dwNeeded == sizeof(DEVHTINFO);
  199. }
  200. #ifndef KERNEL_MODE
  201. BOOL
  202. BSavePrinterProperties(
  203. IN HANDLE hPrinter,
  204. IN PRAWBINARYDATA pRawData,
  205. IN PPRINTERDATA pPrinterData,
  206. IN DWORD dwSize
  207. )
  208. /*++
  209. Routine Description:
  210. Save Printer Properites to registry
  211. Arguments:
  212. hPrinter - Specifies a handle to the current printer
  213. pRawData - Points to raw binary printer description data
  214. pPrinterData - Points to PRINTERDATA
  215. dwSize - Specifies the size of PRINTERDATA
  216. Return Value:
  217. TRUE if successful, FALSE if there is an error
  218. --*/
  219. {
  220. BOOL bResult = FALSE;
  221. DWORD dwKeywordSize, dwFeatureCount = 0;
  222. PSTR pstrKeyword;
  223. POPTSELECT pCombineOptions;
  224. PUIINFO pUIInfo;
  225. PARSERINFO ParserInfo;
  226. ParserInfo.pRawData = NULL;
  227. ParserInfo.pInfoHeader = NULL;
  228. if (((pCombineOptions = MemAllocZ(MAX_COMBINED_OPTIONS * sizeof(OPTSELECT))) == NULL) ||
  229. ((pUIInfo = PGetUIInfo(hPrinter,
  230. pRawData,
  231. pCombineOptions,
  232. pPrinterData->aOptions,
  233. &ParserInfo,
  234. &dwFeatureCount)) == NULL))
  235. {
  236. //
  237. // We have to fail the function if out of memory, or PGetUIInfo returns NULL (in which
  238. // case pCombinOptions won't have valid option indices).
  239. //
  240. // Make sure free any allocated memory.
  241. //
  242. ERR(("pCombinOptions or pUIInfo is NULL\n"));
  243. if (pCombineOptions)
  244. MemFree(pCombineOptions);
  245. return FALSE;
  246. }
  247. pstrKeyword = PstrConvertIndexToKeyword(hPrinter,
  248. pPrinterData->aOptions,
  249. &dwKeywordSize,
  250. pUIInfo,
  251. pCombineOptions,
  252. dwFeatureCount);
  253. VUpdatePrivatePrinterData(hPrinter,
  254. pPrinterData,
  255. MODE_WRITE,
  256. pUIInfo,
  257. pCombineOptions
  258. );
  259. if (pstrKeyword)
  260. {
  261. bResult = BSetPrinterDataBinary(hPrinter,
  262. REGVAL_PRINTER_DATA_SIZE,
  263. REGVAL_PRINTER_DATA,
  264. pPrinterData,
  265. dwSize) &&
  266. BSetPrinterDataBinary(hPrinter,
  267. REGVAL_KEYWORD_SIZE,
  268. REGVAL_KEYWORD_NAME,
  269. pstrKeyword,
  270. dwKeywordSize);
  271. }
  272. if (pstrKeyword)
  273. MemFree(pstrKeyword);
  274. VFreeParserInfo(&ParserInfo);
  275. if (pCombineOptions)
  276. MemFree(pCombineOptions);
  277. return bResult;
  278. }
  279. BOOL
  280. BSetPrinterDataDWord(
  281. IN HANDLE hPrinter,
  282. IN LPCTSTR ptstrRegKey,
  283. IN DWORD dwValue
  284. )
  285. /*++
  286. Routine Description:
  287. Save a DWORD value to the registry under PrinerDriverData key
  288. Arguments:
  289. hPrinter - Specifies the printer object
  290. ptstrRegKey - Specifies the name of registry value
  291. dwValue - Specifies the value to be saved
  292. Return Value:
  293. TRUE if successful, FALSE otherwise
  294. --*/
  295. {
  296. DWORD dwStatus;
  297. dwStatus = SetPrinterData(hPrinter,
  298. (PTSTR) ptstrRegKey,
  299. REG_DWORD,
  300. (PBYTE) &dwValue,
  301. sizeof(dwValue));
  302. if (dwStatus != ERROR_SUCCESS)
  303. ERR(("Couldn't save printer data '%ws': %d\n", ptstrRegKey, dwStatus));
  304. return (dwStatus == ERROR_SUCCESS);
  305. }
  306. BOOL
  307. BSetPrinterDataBinary(
  308. IN HANDLE hPrinter,
  309. IN LPCTSTR ptstrSizeKey,
  310. IN LPCTSTR ptstrDataKey,
  311. IN PVOID pvData,
  312. IN DWORD dwSize
  313. )
  314. /*++
  315. Routine Description:
  316. Save binary data to the registry under PrinterDriverData key
  317. Arguments:
  318. hPrinter - Handle to the printer object
  319. ptstrSizeKey - Name of the registry value which contains the binary data size
  320. ptstrDataKey - Name of the registry value which contains the binary data itself
  321. pvData - Points to the binary data to be saved
  322. dwSize - Specifies the binary data size in bytes
  323. Return Value:
  324. TRUE if successful, FALSE if there is an error
  325. --*/
  326. {
  327. if (SetPrinterData(hPrinter,
  328. (PTSTR) ptstrSizeKey,
  329. REG_DWORD,
  330. (PBYTE) &dwSize,
  331. sizeof(dwSize)) != ERROR_SUCCESS ||
  332. SetPrinterData(hPrinter,
  333. (PTSTR) ptstrDataKey,
  334. REG_BINARY,
  335. pvData,
  336. dwSize) != ERROR_SUCCESS)
  337. {
  338. ERR(("Couldn't save printer data '%ws'/'%ws'\n", ptstrSizeKey, ptstrDataKey));
  339. return FALSE;
  340. }
  341. return TRUE;
  342. }
  343. BOOL
  344. BSetPrinterDataString(
  345. IN HANDLE hPrinter,
  346. IN LPCTSTR ptstrRegKey,
  347. IN LPCTSTR ptstrValue,
  348. IN DWORD dwType
  349. )
  350. /*++
  351. Routine Description:
  352. Save a string value under PrinerDriverData registry key
  353. Arguments:
  354. hPrinter - Specifies the printer object
  355. ptstrRegKey - Specifies the name of registry value
  356. ptstrValue - Points to string value to be saved
  357. dwType - Specifies string type: REG_SZ or REG_MULTI_SZ
  358. Return Value:
  359. TRUE if successful, FALSE if there is an error
  360. Note:
  361. If ptstrValue parameter is NULL, the specified registry value is deleted.
  362. --*/
  363. {
  364. DWORD dwStatus, dwSize;
  365. if (ptstrValue != NULL)
  366. {
  367. if (dwType == REG_SZ)
  368. dwSize = SIZE_OF_STRING(ptstrValue);
  369. else
  370. {
  371. LPCTSTR p = ptstrValue;
  372. while (*p)
  373. p += _tcslen(p) + 1;
  374. dwSize = ((DWORD)(p - ptstrValue) + 1) * sizeof(TCHAR);
  375. }
  376. dwStatus = SetPrinterData(hPrinter,
  377. (PTSTR) ptstrRegKey,
  378. dwType,
  379. (PBYTE) ptstrValue,
  380. dwSize);
  381. if (dwStatus != ERROR_SUCCESS)
  382. ERR(("Couldn't save printer data '%ws': %d\n", ptstrRegKey, dwStatus));
  383. }
  384. else
  385. {
  386. dwStatus = DeletePrinterData(hPrinter, (PTSTR) ptstrRegKey);
  387. if (dwStatus == ERROR_FILE_NOT_FOUND)
  388. dwStatus = ERROR_SUCCESS;
  389. if (dwStatus != ERROR_SUCCESS)
  390. ERR(("Couldn't delete printer data '%ws': %d\n", ptstrRegKey, dwStatus));
  391. }
  392. return (dwStatus == ERROR_SUCCESS);
  393. }
  394. BOOL
  395. BSetPrinterDataMultiSZPair(
  396. IN HANDLE hPrinter,
  397. IN LPCTSTR ptstrRegKey,
  398. IN LPCTSTR ptstrValue,
  399. IN DWORD dwSize
  400. )
  401. /*++
  402. Routine Description:
  403. Save a MULTI_SZ value under PrinerDriverData registry key
  404. Arguments:
  405. hPrinter - Specifies the printer object
  406. ptstrRegKey - Specifies the name of registry value
  407. ptstrValue - Points to MULTI_SZ value to be saved
  408. dwSize - Specifies the size of the MULTI_SZ value in bytes
  409. Return Value:
  410. TRUE if successful, FALSE if there is an error
  411. --*/
  412. {
  413. DWORD dwStatus;
  414. ASSERT(BVerifyMultiSZPair(ptstrValue, dwSize));
  415. dwStatus = SetPrinterData(hPrinter,
  416. (PTSTR) ptstrRegKey,
  417. REG_MULTI_SZ,
  418. (PBYTE) ptstrValue,
  419. dwSize);
  420. if (dwStatus != ERROR_SUCCESS)
  421. ERR(("Couldn't save printer data '%ws': %d\n", ptstrRegKey, dwStatus));
  422. return (dwStatus == ERROR_SUCCESS);
  423. }
  424. BOOL
  425. BSaveDeviceHalftoneSetup(
  426. HANDLE hPrinter,
  427. DEVHTINFO *pDevHTInfo
  428. )
  429. /*++
  430. Routine Description:
  431. Save device halftone setup information to registry
  432. Arguments:
  433. hPrinter - Handle to the printer
  434. pDevHTInfo - Pointer to device halftone setup information
  435. Return Value:
  436. TRUE if successful, FALSE otherwise
  437. --*/
  438. {
  439. return SetPrinterData(hPrinter,
  440. REGVAL_CURRENT_DEVHTINFO,
  441. REG_BINARY,
  442. (PBYTE) pDevHTInfo,
  443. sizeof(DEVHTINFO)) == ERROR_SUCCESS;
  444. }
  445. BOOL
  446. BSaveTTSubstTable(
  447. IN HANDLE hPrinter,
  448. IN TTSUBST_TABLE pTTSubstTable,
  449. IN DWORD dwSize
  450. )
  451. /*++
  452. Routine Description:
  453. Save TrueType font substitution table in registry
  454. Arguments:
  455. hPrinter - Handle to the current printer
  456. pTTSubstTable - Pointer to font substitution table to be saved
  457. dwSize - Size of font substitution table, in bytes
  458. Return Value:
  459. TRUE if successful, FALSE if there is an error
  460. Note:
  461. Previous version pscript driver used to save font substitution table
  462. as two separate keys: one for size and the other for actual data.
  463. We only need the data key now. But we should save the size as well
  464. to be compatible with old drivers.
  465. --*/
  466. {
  467. return
  468. BSetPrinterDataMultiSZPair(hPrinter, REGVAL_FONT_SUBST_TABLE, pTTSubstTable, dwSize) &&
  469. BSetPrinterDataDWord(hPrinter, REGVAL_FONT_SUBST_SIZE_PS40, dwSize);
  470. }
  471. BOOL
  472. BSaveFormTrayTable(
  473. IN HANDLE hPrinter,
  474. IN FORM_TRAY_TABLE pFormTrayTable,
  475. IN DWORD dwSize
  476. )
  477. /*++
  478. Routine Description:
  479. Save form-to-tray assignment table in registry
  480. Arguments:
  481. hPrinter - Handle to the current printer
  482. pFormTrayTable - Pointer to the form-to-tray assignment table to be saved
  483. dwSize - Size of the form-to-tray assignment table, in bytes
  484. Return Value:
  485. TRUE if successful, FALSE if there is an error
  486. --*/
  487. {
  488. //
  489. // Save the table in current format and then call driver-specific
  490. // functions to save the information in NT 4.0 format.
  491. //
  492. return
  493. (BSaveAsOldVersionFormTrayTable(hPrinter, pFormTrayTable, dwSize));
  494. }
  495. #endif // !KERNEL_MODE
  496. FORM_TRAY_TABLE
  497. PGetFormTrayTable(
  498. IN HANDLE hPrinter,
  499. OUT PDWORD pdwSize
  500. )
  501. /*++
  502. Routine Description:
  503. Retrieve form-to-tray assignment table from registry
  504. Arguments:
  505. hPrinter - Handle to the printer object
  506. pdwSize - Returns the form-to-tray assignment table size
  507. Return Value:
  508. Pointer to form-to-tray assignment table read from the registry
  509. NULL if there is an error
  510. --*/
  511. {
  512. FORM_TRAY_TABLE pFormTrayTable;
  513. DWORD dwSize;
  514. //
  515. // Call either PSGetFormTrayTable or UniGetFormTrayTable
  516. //
  517. pFormTrayTable = PGetAndConvertOldVersionFormTrayTable(hPrinter, &dwSize);
  518. if (pFormTrayTable != NULL && pdwSize != NULL)
  519. *pdwSize = dwSize;
  520. return pFormTrayTable;
  521. }
  522. BOOL
  523. BSearchFormTrayTable(
  524. IN FORM_TRAY_TABLE pFormTrayTable,
  525. IN PTSTR ptstrTrayName,
  526. IN PTSTR ptstrFormName,
  527. IN OUT PFINDFORMTRAY pFindData
  528. )
  529. /*++
  530. Routine Description:
  531. Find the specified tray-form pair in a form-to-tray assignment table
  532. Arguments:
  533. pFormTrayTable - Specifies a form-to-tray assignment table to be searched
  534. ptstrTrayName - Specifies the interested tray name
  535. ptstrFormName - Specifies the interested form name
  536. pFindData - Data structure used to keep information from one call to the next
  537. Return Value:
  538. TRUE if the specified tray-form pair is found in the table
  539. FALSE otherwise
  540. NOTE:
  541. If either ptstrTrayName or ptstrFormName is NULL, they'll act as wildcard and
  542. match any tray name or form name.
  543. The caller must call ResetFindFormTray(pFormTrayTable, pFindData) before
  544. calling this function for the very first time.
  545. --*/
  546. {
  547. PTSTR ptstrNextEntry;
  548. BOOL bFound = FALSE;
  549. //
  550. // Make sure pFindData is properly initialized
  551. //
  552. ASSERT(pFindData->pvSignature == pFindData);
  553. ptstrNextEntry = pFindData->ptstrNextEntry;
  554. while (*ptstrNextEntry)
  555. {
  556. PTSTR ptstrTrayField, ptstrFormField, ptstrPrinterFormField;
  557. //
  558. // Extract information from the current table entry
  559. //
  560. ptstrTrayField = ptstrNextEntry;
  561. ptstrNextEntry += _tcslen(ptstrNextEntry) + 1;
  562. ptstrFormField = ptstrNextEntry;
  563. ptstrNextEntry += _tcslen(ptstrNextEntry) + 1;
  564. //
  565. // Check if we found a matching entry
  566. //
  567. if ((ptstrTrayName == NULL || _tcscmp(ptstrTrayName, ptstrTrayField) == EQUAL_STRING) &&
  568. (ptstrFormName == NULL || _tcscmp(ptstrFormName, ptstrFormField) == EQUAL_STRING))
  569. {
  570. pFindData->ptstrTrayName = ptstrTrayField;
  571. pFindData->ptstrFormName = ptstrFormField;
  572. bFound = TRUE;
  573. break;
  574. }
  575. }
  576. pFindData->ptstrNextEntry = ptstrNextEntry;
  577. return bFound;
  578. }
  579. BOOL
  580. BGetPrinterProperties(
  581. IN HANDLE hPrinter,
  582. IN PRAWBINARYDATA pRawData,
  583. OUT PPRINTERDATA pPrinterData
  584. )
  585. /*++
  586. Routine Description:
  587. Return the current printer-sticky property data
  588. Arguments:
  589. hPrinter - Specifies a handle to the current printer
  590. pRawData - Points to raw binary printer description data
  591. pPrinterData - Buffer for storing the retrieved printer property info
  592. Return Value:
  593. TRUE if successful, FALSE if there is an error
  594. --*/
  595. {
  596. PVOID pvRegData;
  597. PSTR pstrKeyword;
  598. DWORD dwRegDataSize, dwKeywordSize, dwFeatureCount, dwVersion;
  599. POPTSELECT pCombineOptions;
  600. PUIINFO pUIInfo;
  601. PARSERINFO ParserInfo;
  602. //
  603. // Allocate a buffer to hold printer property data and
  604. // read the property property data from the registry.
  605. //
  606. if (pvRegData = PvGetPrinterDataBinary(hPrinter,
  607. REGVAL_PRINTER_DATA_SIZE,
  608. REGVAL_PRINTER_DATA,
  609. &dwRegDataSize))
  610. {
  611. //
  612. // Convert the printer property data from the registry to current version
  613. //
  614. ZeroMemory(pPrinterData, sizeof(PRINTERDATA));
  615. CopyMemory(pPrinterData, pvRegData, min(sizeof(PRINTERDATA), dwRegDataSize));
  616. pPrinterData->wDriverVersion = gwDriverVersion;
  617. pPrinterData->wSize = sizeof(PRINTERDATA);
  618. if (pPrinterData->wReserved2 != 0 ||
  619. pPrinterData->dwChecksum32 != pRawData->dwChecksum32)
  620. {
  621. InitDefaultOptions(pRawData,
  622. pPrinterData->aOptions,
  623. MAX_PRINTER_OPTIONS,
  624. MODE_PRINTER_STICKY);
  625. pPrinterData->wReserved2 = 0;
  626. pPrinterData->dwChecksum32 = pRawData->dwChecksum32;
  627. pPrinterData->dwOptions = pRawData->dwPrinterFeatures;
  628. pPrinterData->wProtocol = PROTOCOL_ASCII;
  629. pPrinterData->dwFlags |= PFLAGS_CTRLD_AFTER;
  630. pPrinterData->wMinoutlinePPEM = DEFAULT_MINOUTLINEPPEM;
  631. pPrinterData->wMaxbitmapPPEM = DEFAULT_MAXBITMAPPPEM;
  632. }
  633. //
  634. // Call driver-specific conversion to give them a chance to touch up
  635. //
  636. (VOID) BConvertPrinterPropertiesData(hPrinter,
  637. pRawData,
  638. pPrinterData,
  639. pvRegData,
  640. dwRegDataSize);
  641. }
  642. else
  643. {
  644. if (!BGetDefaultPrinterProperties(hPrinter, pRawData, pPrinterData))
  645. return FALSE;
  646. }
  647. //
  648. // At this point we should get a valid PrinterData or a
  649. // default PrinterData. Propagate Feature.Options to
  650. // PrinterData options array if possible
  651. //
  652. ParserInfo.pRawData = NULL;
  653. ParserInfo.pInfoHeader = NULL;
  654. if (((pCombineOptions = MemAllocZ(MAX_COMBINED_OPTIONS * sizeof(OPTSELECT))) == NULL) ||
  655. ((pUIInfo = PGetUIInfo(hPrinter,
  656. pRawData,
  657. pCombineOptions,
  658. pPrinterData->aOptions,
  659. &ParserInfo,
  660. &dwFeatureCount)) == NULL))
  661. {
  662. //
  663. // We have to fail the function if out of memory, or PGetUIInfo returns NULL (in which
  664. // case pCombinOptions won't have valid option indices).
  665. //
  666. // Make sure free any allocated memory.
  667. //
  668. ERR(("pCombinOptions or pUIInfo is NULL\n"));
  669. if (pvRegData)
  670. MemFree(pvRegData);
  671. if (pCombineOptions)
  672. MemFree(pCombineOptions);
  673. return FALSE;
  674. }
  675. //
  676. // set the ADD_EURO flag if it has not intentionally been set to FALSE
  677. //
  678. if (pUIInfo)
  679. {
  680. if (!(pPrinterData->dwFlags & PFLAGS_EURO_SET))
  681. {
  682. if (pUIInfo->dwFlags & FLAG_ADD_EURO)
  683. pPrinterData->dwFlags |= PFLAGS_ADD_EURO;
  684. pPrinterData->dwFlags |= PFLAGS_EURO_SET;
  685. }
  686. }
  687. VUpdatePrivatePrinterData(hPrinter,
  688. pPrinterData,
  689. MODE_READ,
  690. pUIInfo,
  691. pCombineOptions);
  692. if ((pstrKeyword = PvGetPrinterDataBinary(hPrinter,
  693. REGVAL_KEYWORD_SIZE,
  694. REGVAL_KEYWORD_NAME,
  695. &dwKeywordSize)) &&
  696. dwKeywordSize)
  697. {
  698. //
  699. // Skip merging in the keyword feature.option if the driver version
  700. // is less than version 3. This is so point and print to OS version less
  701. // than NT5 will work. REGVAL_PRINTER_INITED exists only for version 3
  702. // or greater driver
  703. //
  704. if (!BGetPrinterDataDWord(hPrinter, REGVAL_PRINTER_INITED, &dwVersion))
  705. *pstrKeyword = NUL;
  706. //
  707. // Convert feature.option keyword names to option indices
  708. //
  709. VConvertKeywordToIndex(hPrinter,
  710. pstrKeyword,
  711. dwKeywordSize,
  712. pPrinterData->aOptions,
  713. pRawData,
  714. pUIInfo,
  715. pCombineOptions,
  716. dwFeatureCount);
  717. MemFree(pstrKeyword);
  718. }
  719. else
  720. {
  721. SeparateOptionArray(pRawData,
  722. pCombineOptions,
  723. pPrinterData->aOptions,
  724. MAX_PRINTER_OPTIONS,
  725. MODE_PRINTER_STICKY);
  726. }
  727. VFreeParserInfo(&ParserInfo);
  728. if (pCombineOptions)
  729. MemFree(pCombineOptions);
  730. if (pvRegData)
  731. MemFree(pvRegData);
  732. return TRUE;
  733. }
  734. BOOL
  735. BGetDefaultPrinterProperties(
  736. IN HANDLE hPrinter,
  737. IN PRAWBINARYDATA pRawData,
  738. OUT PPRINTERDATA pPrinterData
  739. )
  740. /*++
  741. Routine Description:
  742. Return the default printer-sticky property data
  743. Arguments:
  744. hPrinter - Specifies a handle to the current printer
  745. pRawData - Points to raw binary printer description data
  746. pPrinterData - Buffer for storing the default printer property info
  747. Return Value:
  748. TRUE if successful, FALSE if there is an error
  749. --*/
  750. {
  751. PINFOHEADER pInfoHdr;
  752. PUIINFO pUIInfo;
  753. //
  754. // Allocate memory to hold the default printer property data
  755. //
  756. ASSERT(pPrinterData && pRawData);
  757. ZeroMemory(pPrinterData, sizeof(PRINTERDATA));
  758. pPrinterData->wDriverVersion = gwDriverVersion;
  759. pPrinterData->wSize = sizeof(PRINTERDATA);
  760. //
  761. // Get default printer-sticky option values
  762. //
  763. InitDefaultOptions(pRawData,
  764. pPrinterData->aOptions,
  765. MAX_PRINTER_OPTIONS,
  766. MODE_PRINTER_STICKY);
  767. pPrinterData->dwChecksum32 = pRawData->dwChecksum32;
  768. pPrinterData->dwOptions = pRawData->dwPrinterFeatures;
  769. //
  770. // Ask the parser for a new binary data instance and
  771. // use it to initialize the remaining fields of PRINTERDATA.
  772. //
  773. if (pInfoHdr = InitBinaryData(pRawData, NULL, NULL))
  774. {
  775. pUIInfo = GET_UIINFO_FROM_INFOHEADER(pInfoHdr);
  776. ASSERT(pUIInfo != NULL);
  777. pPrinterData->dwFreeMem = pUIInfo->dwFreeMem;
  778. pPrinterData->dwWaitTimeout = pUIInfo->dwWaitTimeout;
  779. pPrinterData->dwJobTimeout = pUIInfo->dwJobTimeout;
  780. if (pUIInfo->dwFlags & FLAG_TRUE_GRAY) // transfer the default into printer-sticky data
  781. pPrinterData->dwFlags |= (PFLAGS_TRUE_GRAY_TEXT | PFLAGS_TRUE_GRAY_GRAPH);
  782. FreeBinaryData(pInfoHdr);
  783. }
  784. //
  785. // Initialize any remaining fields
  786. //
  787. pPrinterData->wProtocol = PROTOCOL_ASCII;
  788. pPrinterData->dwFlags |= PFLAGS_CTRLD_AFTER;
  789. pPrinterData->wMinoutlinePPEM = DEFAULT_MINOUTLINEPPEM;
  790. pPrinterData->wMaxbitmapPPEM = DEFAULT_MAXBITMAPPPEM;
  791. #ifndef KERNEL_MODE
  792. //
  793. // Determine whether the system is running in a metric country.
  794. //
  795. if (IsMetricCountry())
  796. pPrinterData->dwFlags |= PFLAGS_METRIC;
  797. //
  798. // Ignore device fonts on non-1252 code page systems.
  799. //
  800. // NOTE: Adobe wants this to be turned off for NT4 driver.
  801. // For NT5 driver, we need to investigate and make sure
  802. // this doesn't break anything before turning this off.
  803. // Specifically, watch out for NT4-client to NT5 server
  804. // connection case.
  805. //
  806. // Fix MS bug #121883, Adobe bug #235417
  807. //
  808. #if 0
  809. #ifndef WINNT_40
  810. if (GetACP() != 1252)
  811. pPrinterData->dwFlags |= PFLAGS_IGNORE_DEVFONT;
  812. #endif // !WINNT_40
  813. #endif
  814. #endif // !KERNEL_MODE
  815. return TRUE;
  816. }
  817. LPCTSTR
  818. PtstrSearchDependentFileWithExtension(
  819. LPCTSTR ptstrDependentFiles,
  820. LPCTSTR ptstrExtension
  821. )
  822. /*++
  823. Routine Description:
  824. Search the list of dependent files (in REG_MULTI_SZ format)
  825. for a file with the specified extension
  826. Arguments:
  827. ptstrDependentFiles - Points to the list of dependent files
  828. ptstrExtension - Specifies the interested filename extension
  829. Return Value:
  830. Points to the first filename in the dependent file list
  831. with the specified extension
  832. --*/
  833. {
  834. if (ptstrDependentFiles == NULL)
  835. {
  836. WARNING(("Driver dependent file list is NULL\n"));
  837. return NULL;
  838. }
  839. while (*ptstrDependentFiles != NUL)
  840. {
  841. LPCTSTR ptstr, ptstrNext;
  842. //
  843. // Go the end of current string
  844. //
  845. ptstr = ptstrDependentFiles + _tcslen(ptstrDependentFiles);
  846. ptstrNext = ptstr + 1;
  847. //
  848. // Search backward for '.' character
  849. //
  850. while (--ptstr >= ptstrDependentFiles)
  851. {
  852. if (*ptstr == TEXT('.'))
  853. {
  854. //
  855. // If the extension matches, return a pointer to
  856. // the current string
  857. //
  858. if (_tcsicmp(ptstr, ptstrExtension) == EQUAL_STRING)
  859. return ptstrDependentFiles;
  860. break;
  861. }
  862. }
  863. ptstrDependentFiles = ptstrNext;
  864. }
  865. return NULL;
  866. }
  867. PTSTR
  868. PtstrGetDriverDirectory(
  869. LPCTSTR ptstrDriverDllPath
  870. )
  871. /*++
  872. Routine Description:
  873. Figure out printer driver directory from the driver DLL's full pathname
  874. Arguments:
  875. ptstrDriverDllPath - Driver DLL's full pathname
  876. Return Value:
  877. Pointer to the printer driver directory string
  878. NULL if there is an error
  879. The returned directory contains a trailing backslash.
  880. Caller is responsible for freeing the returned string.
  881. --*/
  882. {
  883. PTSTR ptstr;
  884. INT iLength;
  885. ASSERT(ptstrDriverDllPath != NULL);
  886. if ((ptstr = _tcsrchr(ptstrDriverDllPath, TEXT(PATH_SEPARATOR))) != NULL)
  887. iLength = (INT)(ptstr - ptstrDriverDllPath) + 1;
  888. else
  889. {
  890. WARNING(("Driver DLL path is not fully qualified: %ws\n", ptstrDriverDllPath));
  891. iLength = 0;
  892. }
  893. if ((ptstr = MemAlloc((iLength + 1) * sizeof(TCHAR))) != NULL)
  894. {
  895. CopyMemory(ptstr, ptstrDriverDllPath, iLength * sizeof(TCHAR));
  896. ptstr[iLength] = NUL;
  897. }
  898. else
  899. ERR(("Memory allocation failed\n"));
  900. return ptstr;
  901. }
  902. LPCTSTR
  903. PtstrSearchStringInMultiSZPair(
  904. LPCTSTR ptstrMultiSZ,
  905. LPCTSTR ptstrKey
  906. )
  907. /*++
  908. Routine Description:
  909. Search for the specified key in MultiSZ key-value string pairs
  910. Arguments:
  911. ptstrMultiSZ - Points to the data to be searched
  912. ptstrKey - Specifies the key string
  913. Return Value:
  914. Pointer to the value string corresponding to the specified
  915. key string; NULL if the specified key string is not found
  916. --*/
  917. {
  918. ASSERT(ptstrMultiSZ != NULL);
  919. while (*ptstrMultiSZ != NUL)
  920. {
  921. //
  922. // If the current string matches the specified key string,
  923. // then return the corresponding value string
  924. //
  925. if (_tcsicmp(ptstrMultiSZ, ptstrKey) == EQUAL_STRING)
  926. return ptstrMultiSZ + _tcslen(ptstrMultiSZ) + 1;
  927. //
  928. // Otherwise, advance to the next string pair
  929. //
  930. ptstrMultiSZ += _tcslen(ptstrMultiSZ) + 1;
  931. ptstrMultiSZ += _tcslen(ptstrMultiSZ) + 1;
  932. }
  933. return NULL;
  934. }
  935. BOOL
  936. BVerifyMultiSZPair(
  937. LPCTSTR ptstrData,
  938. DWORD dwSize
  939. )
  940. /*++
  941. Routine Description:
  942. Verify the input data block is in REG_MULTI_SZ format and
  943. it consists of multiple string pairs
  944. Arguments:
  945. ptstrData - Points to the data to be verified
  946. dwSize - Size of the data block in bytes
  947. Return Value:
  948. NONE
  949. --*/
  950. {
  951. LPCTSTR ptstrEnd;
  952. //
  953. // Size must be even
  954. //
  955. ASSERTMSG(dwSize % sizeof(TCHAR) == 0, ("Size is not even: %d\n", dwSize));
  956. dwSize /= sizeof(TCHAR);
  957. //
  958. // Go through one string pair during each iteration
  959. //
  960. ptstrEnd = ptstrData + dwSize;
  961. while (ptstrData < ptstrEnd && *ptstrData != NUL)
  962. {
  963. while (ptstrData < ptstrEnd && *ptstrData++ != NUL)
  964. NULL;
  965. if (ptstrData >= ptstrEnd)
  966. {
  967. ERR(("Corrupted MultiSZ pair\n"));
  968. return FALSE;
  969. }
  970. while (ptstrData < ptstrEnd && *ptstrData++ != NUL)
  971. NULL;
  972. if (ptstrData >= ptstrEnd)
  973. {
  974. ERR(("Corrupted MultiSZ pair\n"));
  975. return FALSE;
  976. }
  977. }
  978. //
  979. // Look for the last terminating NUL character
  980. //
  981. if (ptstrData++ >= ptstrEnd)
  982. {
  983. ERR(("Missing the last NUL terminator\n"));
  984. return FALSE;
  985. }
  986. if (ptstrData < ptstrEnd)
  987. {
  988. ERR(("Redundant data after the last NUL terminator\n"));
  989. }
  990. return TRUE;
  991. }
  992. BOOL
  993. BVerifyMultiSZ(
  994. LPCTSTR ptstrData,
  995. DWORD dwSize
  996. )
  997. /*++
  998. Routine Description:
  999. Verify the input data block is in REG_MULTI_SZ format
  1000. Arguments:
  1001. ptstrData - Points to the data to be verified
  1002. dwSize - Size of the data block in bytes
  1003. Return Value:
  1004. NONE
  1005. --*/
  1006. {
  1007. LPCTSTR ptstrEnd;
  1008. //
  1009. // Size must be even
  1010. //
  1011. ASSERTMSG(dwSize % sizeof(TCHAR) == 0, ("Size is not even: %d\n", dwSize));
  1012. dwSize /= sizeof(TCHAR);
  1013. ptstrEnd = ptstrData + dwSize;
  1014. while (ptstrData < ptstrEnd && *ptstrData != NUL)
  1015. {
  1016. while (ptstrData < ptstrEnd && *ptstrData++ != NUL)
  1017. NULL;
  1018. if (ptstrData >= ptstrEnd)
  1019. {
  1020. ERR(("Corrupted MultiSZ pair\n"));
  1021. return FALSE;
  1022. }
  1023. }
  1024. //
  1025. // Look for the last terminating NUL character
  1026. //
  1027. if (ptstrData++ >= ptstrEnd)
  1028. {
  1029. ERR(("Missing the last NUL terminator\n"));
  1030. return FALSE;
  1031. }
  1032. if (ptstrData < ptstrEnd)
  1033. {
  1034. ERR(("Redundant data after the last NUL terminator\n"));
  1035. }
  1036. return TRUE;
  1037. }
  1038. DWORD
  1039. DwCountStringsInMultiSZ(
  1040. IN LPCTSTR ptstrData
  1041. )
  1042. {
  1043. DWORD dwCount = 0;
  1044. if (ptstrData)
  1045. {
  1046. while (*ptstrData)
  1047. {
  1048. dwCount++;
  1049. ptstrData += wcslen(ptstrData);
  1050. ptstrData++;
  1051. }
  1052. }
  1053. return dwCount;
  1054. }