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.

715 lines
15 KiB

  1. /*++
  2. Copyright (c) 1990-2003 Microsoft Corporation
  3. Module Name:
  4. regdata.c
  5. Abstract:
  6. This module contains all registry data save/retrieve function for the
  7. printer properties
  8. Author:
  9. 30-Nov-1993 Tue 00:17:47 created
  10. [Environment:]
  11. GDI Device Driver - Plotter.
  12. [Notes:]
  13. Revision History:
  14. --*/
  15. #include "precomp.h"
  16. #pragma hdrstop
  17. #define DBG_PLOTFILENAME DbgRegData
  18. #define DBG_GETREGDATA 0x00000001
  19. #define DBG_SETREGDATA 0x00000002
  20. DEFINE_DBGVAR(0);
  21. //
  22. // Local definition
  23. //
  24. typedef struct _PLOTREGKEY {
  25. LPWSTR pwKey;
  26. DWORD Size;
  27. } PLOTREGKEY, *PPLOTREGKEY;
  28. PLOTREGKEY PlotRegKey[] = {
  29. { L"ColorInfo", sizeof(COLORINFO) },
  30. { L"DevPelsDPI", sizeof(DWORD) },
  31. { L"HTPatternSize", sizeof(DWORD) },
  32. { L"InstalledForm", sizeof(PAPERINFO) },
  33. { L"PtrPropData", sizeof(PPDATA) },
  34. { L"IndexPenData", sizeof(BYTE) },
  35. { L"PenData", sizeof(PENDATA) }
  36. };
  37. #define MAX_PEN_DIGITS 6
  38. LPWSTR
  39. GetPenDataKey(
  40. LPWSTR pwBuf,
  41. size_t cchBuf,
  42. WORD PenNum
  43. )
  44. /*++
  45. Routine Description:
  46. This fucntion composed the PenData%ld string as wsprintf does
  47. Arguments:
  48. pwBuf - Where data to be stored
  49. PenNum - Pen number to be appended
  50. Return Value:
  51. VOID
  52. Author:
  53. 24-Oct-1995 Tue 15:06:17 created
  54. Revision History:
  55. --*/
  56. {
  57. LPWSTR pwSrc;
  58. LPWSTR pwDst;
  59. WCHAR wNumBuf[MAX_PEN_DIGITS + 1];
  60. size_t cchDst;
  61. //
  62. // Fristable copy the string
  63. //
  64. pwSrc = PlotRegKey[PRKI_PENDATA1].pwKey;
  65. pwDst = pwBuf;
  66. //while (*pwDst++ = *pwSrc++);
  67. if (SUCCEEDED(StringCchCopyW(pwDst, cchBuf, pwSrc)) &&
  68. SUCCEEDED(StringCchLengthW(pwDst, cchBuf, &cchDst)))
  69. {
  70. pwDst += cchDst;
  71. cchBuf -= cchDst;
  72. }
  73. else
  74. {
  75. return NULL;
  76. }
  77. //
  78. // We need to back one, since we also copy the NULL
  79. //
  80. --pwDst;
  81. ++cchBuf;
  82. //
  83. // conver the number to string, remember the 0 case and always end with
  84. // a NULL
  85. //
  86. pwSrc = &wNumBuf[MAX_PEN_DIGITS];
  87. *pwSrc = (WCHAR)0;
  88. do {
  89. *(--pwSrc) = (WCHAR)((PenNum % 10) + L'0');
  90. } while (PenNum /= 10);
  91. //
  92. // Copy the number string now
  93. //
  94. //while (*pwDst++ = *pwSrc++);
  95. if (!SUCCEEDED(StringCchCopyW(pwDst, cchBuf, pwSrc)))
  96. {
  97. return NULL;
  98. }
  99. return(pwBuf);
  100. }
  101. BOOL
  102. GetPlotRegData(
  103. HANDLE hPrinter,
  104. LPBYTE pData,
  105. DWORD RegIdx
  106. )
  107. /*++
  108. Routine Description:
  109. This function retrieve from registry to the pData
  110. Arguments:
  111. hPrinter - Handle to the printer interested
  112. pData - Pointer to the data area buffer, it must large enough
  113. RegIdx - One of the PRKI_xxxx in LOWORD(Index), HIWORD(Index)
  114. specified total count for the PENDATA set
  115. Return Value:
  116. TRUE if sucessful, FALSE if failed,
  117. Author:
  118. 06-Dec-1993 Mon 22:22:47 created
  119. 10-Dec-1993 Fri 01:13:14 updated
  120. Fixed nesty problem in spooler of GetPrinterData which if we passed
  121. a pbData and cb but if it cannot get any data then it will clear all
  122. our buffer, this is not we expected (we expected it just return error
  123. rather clear our buffer). Now we do extended test before we really
  124. go get the data. The other problem is, if we set pbData = NULL then
  125. spooler always have excption happened even we pass &cb as NULL also.
  126. Revision History:
  127. --*/
  128. {
  129. PPLOTREGKEY pPRK;
  130. LONG lRet;
  131. DWORD cb;
  132. DWORD Type;
  133. WCHAR wBuf[32];
  134. PLOTREGKEY PRK;
  135. UINT Index;
  136. Index = LOWORD(RegIdx);
  137. PLOTASSERT(0, "GetPlotRegData: Invalid PRKI_xxx Index %ld",
  138. Index <= PRKI_LAST, Index);
  139. if (Index >= PRKI_PENDATA1) {
  140. UINT cPenData;
  141. if ((cPenData = (UINT)HIWORD(RegIdx)) >= MAX_PENPLOTTER_PENS) {
  142. PLOTERR(("GetPlotRegData: cPenData too big %ld (Max=%ld)",
  143. cPenData, MAX_PENPLOTTER_PENS));
  144. cPenData = MAX_PENPLOTTER_PENS;
  145. }
  146. PRK.pwKey = GetPenDataKey(wBuf, CCHOF(wBuf), (WORD)(Index - PRKI_PENDATA1 + 1));
  147. PRK.Size = (DWORD)sizeof(PENDATA) * (DWORD)cPenData;
  148. pPRK = &PRK;
  149. } else {
  150. pPRK = (PPLOTREGKEY)&PlotRegKey[Index];
  151. }
  152. //
  153. // We must do following sequence or if an error occurred then the pData
  154. // will be filled with ZEROs
  155. //
  156. // 1. Set Type/cb to invalid value
  157. // 1. query the type/size of the keyword, (if more data available)
  158. // 2. and If size is exact as we want
  159. // 3. and if the type is as we want (REG_BINARY)
  160. // 4. assume data valid then query it
  161. //
  162. Type = 0xffffffff;
  163. cb = 0;
  164. if ((lRet = xGetPrinterData(hPrinter,
  165. pPRK->pwKey,
  166. &Type,
  167. (LPBYTE)pData,
  168. 0,
  169. &cb)) != ERROR_MORE_DATA) {
  170. if (lRet == ERROR_FILE_NOT_FOUND) {
  171. PLOTWARN(("GetPlotRegData: GetPrinterData(%ls) not found",
  172. pPRK->pwKey));
  173. } else {
  174. PLOTERR(("GetPlotRegData: 1st GetPrinterData(%ls) failed, Error=%ld",
  175. pPRK->pwKey, lRet));
  176. }
  177. } else if (cb != pPRK->Size) {
  178. PLOTERR(("GetPlotRegData: GetPrinterData(%ls) Size != %ld (%ld)",
  179. pPRK->pwKey, pPRK->Size, cb));
  180. } else if (Type != REG_BINARY) {
  181. PLOTERR(("GetPlotRegData: GetPrinterData(%ls) Type != REG_BINARY (%ld)",
  182. pPRK->pwKey, Type));
  183. } else if ((lRet = xGetPrinterData(hPrinter,
  184. pPRK->pwKey,
  185. &Type,
  186. (LPBYTE)pData,
  187. pPRK->Size,
  188. &cb)) == NO_ERROR) {
  189. PLOTDBG(DBG_GETREGDATA, ("READ '%ws' REG Data: Type=%ld, %ld bytes",
  190. pPRK->pwKey, Type, cb));
  191. return(TRUE);
  192. } else {
  193. PLOTERR(("GetPlotRegData: 2nd GetPrinterData(%ls) failed, Error=%ld",
  194. pPRK->pwKey, lRet));
  195. }
  196. return(FALSE);
  197. }
  198. BOOL
  199. UpdateFromRegistry(
  200. HANDLE hPrinter,
  201. PCOLORINFO pColorInfo,
  202. LPDWORD pDevPelsDPI,
  203. LPDWORD pHTPatSize,
  204. PPAPERINFO pCurPaper,
  205. PPPDATA pPPData,
  206. LPBYTE pIdxPlotData,
  207. DWORD cPenData,
  208. PPENDATA pPenData
  209. )
  210. /*++
  211. Routine Description:
  212. This function take hPrinter and read the printer properties from the
  213. registry, if sucessful then it update to the pointer supplied
  214. Arguments:
  215. hPrinter - The printer it interested
  216. pColorInfo - Pointer to the COLORINFO data structure
  217. pDevPelsDPI - Pointer to the DWORD for Device Pels per INCH
  218. pHTPatSize - Poineer to the DWORD for halftone patterns size
  219. pCurPaper - Pointer to the PAPERINFO data structure for update
  220. pPPData - Pointer to the PPDATA data structure
  221. pIdxPlotData - Pointer to the BYTE which have current PlotData index
  222. cPenData - count of PENDATA to be updated
  223. pPenData - Pointer to the PENDATA data structure
  224. Return Value:
  225. return TRUE if it read sucessful from the registry else FALSE, for each of
  226. the data pointer passed it will try to read from registry, if a NULL
  227. pointer is passed then that registry is skipped.
  228. if falied, the pCurPaper will be set to default
  229. Author:
  230. 30-Nov-1993 Tue 14:54:33 created
  231. 02-Feb-1994 Wed 01:40:07 updated
  232. Fixed &pDevPelsDPI, &pHTPatSize typo to pDevPelsDPI, pHTPatSize.
  233. 19-May-1994 Thu 18:09:06 updated
  234. Do not save back if something go wrong
  235. Revision History:
  236. --*/
  237. {
  238. BOOL Ok = TRUE;
  239. BYTE bData;
  240. //
  241. // In turn get each of the data from registry, the GetPlotRegData will
  242. // not update the data if read failed
  243. //
  244. if (pColorInfo) {
  245. if (!GetPlotRegData(hPrinter, (LPBYTE)pColorInfo, PRKI_CI)) {
  246. Ok = FALSE;
  247. }
  248. }
  249. if (pDevPelsDPI) {
  250. if (!GetPlotRegData(hPrinter, (LPBYTE)pDevPelsDPI, PRKI_DEVPELSDPI)) {
  251. Ok = FALSE;
  252. }
  253. }
  254. if (pHTPatSize) {
  255. if (!GetPlotRegData(hPrinter, (LPBYTE)pHTPatSize, PRKI_HTPATSIZE)) {
  256. Ok = FALSE;
  257. }
  258. }
  259. if (pCurPaper) {
  260. if (!GetPlotRegData(hPrinter, (LPBYTE)pCurPaper, PRKI_FORM)) {
  261. Ok = FALSE;
  262. }
  263. }
  264. if (pPPData) {
  265. if (!GetPlotRegData(hPrinter, (LPBYTE)pPPData, PRKI_PPDATA)) {
  266. Ok = FALSE;
  267. }
  268. pPPData->Flags &= PPF_ALL_BITS;
  269. }
  270. if (pIdxPlotData) {
  271. if ((!GetPlotRegData(hPrinter, &bData, PRKI_PENDATA_IDX)) ||
  272. (bData >= PRK_MAX_PENDATA_SET)) {
  273. bData = 0;
  274. Ok = FALSE;
  275. }
  276. *pIdxPlotData = bData;
  277. }
  278. if ((cPenData) && (pPenData)) {
  279. WORD IdxPen;
  280. //
  281. // First is get the current pendata selection index
  282. //
  283. if ((IdxPen = LOWORD(cPenData)) >= PRK_MAX_PENDATA_SET) {
  284. if (!pIdxPlotData) {
  285. if ((!GetPlotRegData(hPrinter, &bData, PRKI_PENDATA_IDX)) ||
  286. (bData >= PRK_MAX_PENDATA_SET)) {
  287. bData = 0;
  288. }
  289. }
  290. IdxPen = (WORD)bData;
  291. }
  292. cPenData = MAKELONG(IdxPen + PRKI_PENDATA1, HIWORD(cPenData));
  293. if (!GetPlotRegData(hPrinter, (LPBYTE)pPenData, cPenData)) {
  294. Ok = FALSE;
  295. }
  296. }
  297. return(Ok);
  298. }
  299. #ifdef UMODE
  300. BOOL
  301. SetPlotRegData(
  302. HANDLE hPrinter,
  303. LPBYTE pData,
  304. DWORD RegIdx
  305. )
  306. /*++
  307. Routine Description:
  308. This function save pData to to the registry
  309. Arguments:
  310. hPrinter - Handle to the printer interested
  311. pData - Pointer to the data area buffer, it must large enough
  312. RegIdx - One of the PRKI_xxxx in LOWORD(Index), HIWORD(Index)
  313. specified total count for the PENDATA set
  314. Return Value:
  315. TRUE if sucessful, FALSE if failed,
  316. Author:
  317. 06-Dec-1993 Mon 22:25:55 created
  318. Revision History:
  319. --*/
  320. {
  321. PPLOTREGKEY pPRK;
  322. WCHAR wBuf[32];
  323. PLOTREGKEY PRK;
  324. UINT Index;
  325. Index = (UINT)LOWORD(RegIdx);
  326. PLOTASSERT(0, "SetPlotRegData: Invalid PRKI_xxx Index %ld",
  327. Index <= PRKI_LAST, Index);
  328. if (Index >= PRKI_PENDATA1) {
  329. UINT cPenData;
  330. if ((cPenData = (UINT)HIWORD(RegIdx)) >= MAX_PENPLOTTER_PENS) {
  331. PLOTERR(("GetPlotRegData: cPenData too big %ld (Max=%ld)",
  332. cPenData, MAX_PENPLOTTER_PENS));
  333. cPenData = MAX_PENPLOTTER_PENS;
  334. }
  335. PRK.pwKey = GetPenDataKey(wBuf, CCHOF(wBuf), (WORD)(Index - PRKI_PENDATA1 + 1));
  336. PRK.Size = (DWORD)sizeof(PENDATA) * (DWORD)cPenData;
  337. pPRK = &PRK;
  338. } else {
  339. pPRK = (PPLOTREGKEY)&PlotRegKey[Index];
  340. }
  341. if (xSetPrinterData(hPrinter,
  342. pPRK->pwKey,
  343. REG_BINARY,
  344. pData,
  345. pPRK->Size) != NO_ERROR) {
  346. PLOTERR(("SetPlotRegData: SetPrinterData(%ls [%ld]) failed",
  347. pPRK->pwKey, pPRK->Size));
  348. return(FALSE);
  349. } else {
  350. PLOTDBG(DBG_SETREGDATA, ("SAVE '%ws' registry data", pPRK->pwKey));
  351. return(TRUE);
  352. }
  353. }
  354. BOOL
  355. SaveToRegistry(
  356. HANDLE hPrinter,
  357. PCOLORINFO pColorInfo,
  358. LPDWORD pDevPelsDPI,
  359. LPDWORD pHTPatSize,
  360. PPAPERINFO pCurPaper,
  361. PPPDATA pPPData,
  362. LPBYTE pIdxPlotData,
  363. DWORD cPenData,
  364. PPENDATA pPenData
  365. )
  366. /*++
  367. Routine Description:
  368. This function take hPrinter and read the printer properties from the
  369. registry, if sucessful then it update to the pointer supplied
  370. Arguments:
  371. hPrinter - The printer it interested
  372. pColorInfo - Pointer to the COLORINFO data structure
  373. pDevPelsDPI - Pointer to the DWORD for Device Pels per INCH
  374. pHTPatSize - Poineer to the DWORD for halftone patterns size
  375. pCurPaper - Pointer to the PAPERINFO data structure for update
  376. pPPData - Pointer to the PPDATA data structure
  377. pIdxPlotData - Pointer to the DWORD which have current PlotData index
  378. cPenData - count of PENDATA to be updated
  379. pPenData - Pointer to the PENDATA data structure
  380. Return Value:
  381. return TRUE if it read sucessful from the registry else FALSE, for each of
  382. the data pointer passed it will try to read from registry, if a NULL
  383. pointer is passed then that registry is skipped.
  384. if falied, the pCurPaper will be set to default
  385. Author:
  386. 30-Nov-1993 Tue 14:54:33 created
  387. Revision History:
  388. --*/
  389. {
  390. BOOL Ok = TRUE;
  391. //
  392. // In turn get each of the data from registry.
  393. //
  394. if (pColorInfo) {
  395. if (!SetPlotRegData(hPrinter, (LPBYTE)pColorInfo, PRKI_CI)) {
  396. Ok = FALSE;
  397. }
  398. }
  399. if (pDevPelsDPI) {
  400. if (!SetPlotRegData(hPrinter, (LPBYTE)pDevPelsDPI, PRKI_DEVPELSDPI)) {
  401. Ok = FALSE;
  402. }
  403. }
  404. if (pHTPatSize) {
  405. if (!SetPlotRegData(hPrinter, (LPBYTE)pHTPatSize, PRKI_HTPATSIZE)) {
  406. Ok = FALSE;
  407. }
  408. }
  409. if (pCurPaper) {
  410. if (!SetPlotRegData(hPrinter, (LPBYTE)pCurPaper, PRKI_FORM)) {
  411. Ok = FALSE;
  412. }
  413. }
  414. if (pPPData) {
  415. pPPData->NotUsed = 0;
  416. if (!SetPlotRegData(hPrinter, (LPBYTE)pPPData, PRKI_PPDATA)) {
  417. Ok = FALSE;
  418. }
  419. }
  420. if (pIdxPlotData) {
  421. if (*pIdxPlotData >= PRK_MAX_PENDATA_SET) {
  422. *pIdxPlotData = 0;
  423. Ok = FALSE;
  424. }
  425. if (!SetPlotRegData(hPrinter, pIdxPlotData, PRKI_PENDATA_IDX)) {
  426. Ok = FALSE;
  427. }
  428. }
  429. if ((cPenData) && (pPenData)) {
  430. WORD IdxPen;
  431. //
  432. // First is get the current pendata selection index
  433. //
  434. if ((IdxPen = LOWORD(cPenData)) >= PRK_MAX_PENDATA_SET) {
  435. IdxPen = (WORD)((pIdxPlotData) ? *pIdxPlotData : 0);
  436. }
  437. cPenData = MAKELONG(IdxPen + PRKI_PENDATA1, HIWORD(cPenData));
  438. if (!SetPlotRegData(hPrinter, (LPBYTE)pPenData, cPenData)) {
  439. Ok = FALSE;
  440. }
  441. }
  442. return(Ok);
  443. }
  444. #endif