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.

746 lines
17 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. docprop.c
  5. Abstract:
  6. Implemetation of DDI entry points:
  7. DrvDocumentPropertySheets
  8. DrvDocumentProperties
  9. DrvAdvancedDocumentProperties
  10. DrvConvertDevMode
  11. Environment:
  12. Fax driver user interface
  13. Revision History:
  14. 01/09/96 -davidx-
  15. Created it.
  16. mm/dd/yy -author-
  17. description
  18. --*/
  19. #include "faxui.h"
  20. #include "forms.h"
  21. #include "libproto.h"
  22. #include "faxhelp.h"
  23. INT_PTR FaxOptionsProc(HWND, UINT, WPARAM, LPARAM);
  24. LONG SimpleDocumentProperties(PDOCUMENTPROPERTYHEADER);
  25. BOOL GenerateFormsList(PUIDATA);
  26. BOOL AddDocPropPages(PUIDATA, LPTSTR);
  27. LPTSTR GetHelpFilename(PUIDATA);
  28. BOOL SaveUserInfo(PDRVDEVMODE);
  29. BOOL
  30. SaveUserInfo(PDRVDEVMODE pDM) {
  31. HKEY hKey;
  32. if ((hKey = GetUserInfoRegKey(REGKEY_FAX_USERINFO,FALSE))) {
  33. SetRegistryString( hKey, REGVAL_BILLING_CODE, pDM->dmPrivate.billingCode );
  34. SetRegistryString( hKey, REGVAL_MAILBOX , pDM->dmPrivate.emailAddress );
  35. RegCloseKey(hKey);
  36. return TRUE;
  37. }
  38. return FALSE;
  39. }
  40. LONG
  41. DrvDocumentPropertySheets(
  42. PPROPSHEETUI_INFO pPSUIInfo,
  43. LPARAM lParam
  44. )
  45. /*++
  46. Routine Description:
  47. Display "Document Properties" property sheets
  48. Arguments:
  49. pPSUIInfo - Pointer to a PROPSHEETUI_INFO structure
  50. lParam - Pointer to a DOCUMENTPROPERTYHEADER structure
  51. Return Value:
  52. > 0 if successful, <= 0 if failed
  53. [Note:]
  54. Please refer to WinNT DDK/SDK documentation for more details.
  55. --*/
  56. {
  57. PDOCUMENTPROPERTYHEADER pDPHdr;
  58. PUIDATA pUiData;
  59. int iRet = -1;
  60. //
  61. // Do not execute any code before this initialization
  62. //
  63. if(!InitializeDll())
  64. {
  65. return iRet;
  66. }
  67. //
  68. // Validate input parameters
  69. // pPSUIInfo = NULL is a special case: don't need to display the dialog
  70. //
  71. if (! (pDPHdr = (PDOCUMENTPROPERTYHEADER) (pPSUIInfo ? pPSUIInfo->lParamInit : lParam))) {
  72. Assert(FALSE);
  73. return -1;
  74. }
  75. if (pPSUIInfo == NULL)
  76. {
  77. return SimpleDocumentProperties(pDPHdr);
  78. }
  79. Verbose(("DrvDocumentPropertySheets: %d\n", pPSUIInfo->Reason));
  80. //
  81. // Create a UIDATA structure if necessary
  82. //
  83. pUiData = (pPSUIInfo->Reason == PROPSHEETUI_REASON_INIT) ?
  84. FillUiData(pDPHdr->hPrinter, pDPHdr->pdmIn) :
  85. (PUIDATA) pPSUIInfo->UserData;
  86. if (!ValidUiData(pUiData))
  87. {
  88. goto exit;
  89. }
  90. //
  91. // Handle various cases for which this function might be called
  92. //
  93. switch (pPSUIInfo->Reason)
  94. {
  95. case PROPSHEETUI_REASON_INIT:
  96. pUiData->hasPermission = ((pDPHdr->fMode & DM_NOPERMISSION) == 0);
  97. pUiData->pfnComPropSheet = pPSUIInfo->pfnComPropSheet;
  98. pUiData->hComPropSheet = pPSUIInfo->hComPropSheet;
  99. if (pDPHdr->fMode & DM_USER_DEFAULT)
  100. {
  101. pUiData->configDefault = TRUE;
  102. }
  103. //
  104. // Find online help filename
  105. //
  106. GetHelpFilename(pUiData);
  107. //
  108. // Add our pages to the property sheet
  109. //
  110. if (GenerateFormsList(pUiData) && AddDocPropPages(pUiData, pDPHdr->pszPrinterName))
  111. {
  112. pPSUIInfo->UserData = (DWORD_PTR) pUiData;
  113. pPSUIInfo->Result = CPSUI_CANCEL;
  114. iRet = 1;
  115. goto exit;
  116. }
  117. //
  118. // Clean up properly in case of an error
  119. //
  120. HeapDestroy(pUiData->hheap);
  121. break;
  122. case PROPSHEETUI_REASON_GET_INFO_HEADER:
  123. {
  124. PPROPSHEETUI_INFO_HEADER pPSUIHdr;
  125. pPSUIHdr = (PPROPSHEETUI_INFO_HEADER) lParam;
  126. pPSUIHdr->Flags = PSUIHDRF_PROPTITLE | PSUIHDRF_NOAPPLYNOW;
  127. pPSUIHdr->pTitle = pDPHdr->pszPrinterName;
  128. pPSUIHdr->hInst = g_hResource;
  129. pPSUIHdr->IconID = IDI_CPSUI_PRINTER2;
  130. }
  131. iRet = 1;
  132. goto exit;
  133. case PROPSHEETUI_REASON_SET_RESULT:
  134. //
  135. // Copy the new devmode back into the output buffer provided by the caller
  136. // Always return the smaller of current and input devmode
  137. //
  138. {
  139. PSETRESULT_INFO pSRInfo = (PSETRESULT_INFO) lParam;
  140. Verbose(("Set result: %d\n", pSRInfo->Result));
  141. if (pSRInfo->Result == CPSUI_OK && (pDPHdr->fMode & (DM_COPY|DM_UPDATE)))
  142. {
  143. if (!ConvertDevmodeOut(
  144. (PDEVMODE) &pUiData->devmode,
  145. pDPHdr->pdmIn,
  146. pDPHdr->pdmOut,
  147. pDPHdr->cbOut))
  148. {
  149. goto exit;
  150. }
  151. SaveUserInfo(&pUiData->devmode);
  152. }
  153. pPSUIInfo->Result = pSRInfo->Result;
  154. }
  155. iRet = 1;
  156. goto exit;
  157. case PROPSHEETUI_REASON_DESTROY:
  158. //
  159. // Cleanup properly before exiting
  160. //
  161. HeapDestroy(pUiData->hheap);
  162. iRet = 1;
  163. goto exit;
  164. }
  165. exit:
  166. return iRet;
  167. } // DrvDocumentPropertySheets
  168. LONG
  169. DoDocumentProperties(
  170. HWND hwnd,
  171. HANDLE hPrinter,
  172. LPTSTR pPrinterName,
  173. PDEVMODE pdmOutput,
  174. PDEVMODE pdmInput,
  175. DWORD fMode
  176. )
  177. /*++
  178. Arguments:
  179. hwnd - Handle to the parent window of the document properties dialog box.
  180. hPrinter - Handle to a printer object.
  181. pPrinterName - Points to a null-terminated string that specifies
  182. the name of the device for which the document properties dialog
  183. box should be displayed.
  184. pdmOutput - Points to a DEVMODE structure that receives the document
  185. properties data specified by the user.
  186. pdmInput - Points to a DEVMODE structure that initializes the dialog
  187. box controls. This parameter can be NULL.
  188. fmode - Specifies a mask of flags that determine which operations
  189. the function performs.
  190. Return Value:
  191. > 0 if successful
  192. = 0 if canceled
  193. < 0 if error
  194. --*/
  195. {
  196. DOCUMENTPROPERTYHEADER docPropHdr;
  197. DWORD result;
  198. //
  199. // Initialize a DOCUMENTPROPERTYHEADER structure
  200. //
  201. memset(&docPropHdr, 0, sizeof(docPropHdr));
  202. docPropHdr.cbSize = sizeof(docPropHdr);
  203. docPropHdr.hPrinter = hPrinter;
  204. docPropHdr.pszPrinterName = pPrinterName;
  205. docPropHdr.pdmIn = pdmInput;
  206. docPropHdr.pdmOut = pdmOutput;
  207. docPropHdr.fMode = fMode;
  208. //
  209. // Don't need to get compstui involved when the dialog is not displayed
  210. //
  211. if ((fMode & DM_PROMPT) == 0)
  212. return SimpleDocumentProperties(&docPropHdr);
  213. CallCompstui(hwnd, DrvDocumentPropertySheets, (LPARAM) &docPropHdr, &result);
  214. return result;
  215. }
  216. LONG
  217. DrvDocumentProperties(
  218. HWND hwnd,
  219. HANDLE hPrinter,
  220. LPTSTR pPrinterName,
  221. PDEVMODE pdmOutput,
  222. PDEVMODE pdmInput,
  223. DWORD fMode
  224. )
  225. /*++
  226. Routine Description:
  227. Set the public members of a DEVMODE structure for a print document
  228. [Note:]
  229. Please refer to WinNT DDK/SDK documentation for more details.
  230. This is the old entry point for the spooler. Even though
  231. no one should be using this, do it for compatibility.
  232. --*/
  233. {
  234. LONG result;
  235. Verbose(("Entering DrvDocumentProperties: fMode = %x...\n", fMode));
  236. //
  237. // Do not execute any code before this initialization
  238. //
  239. if(!InitializeDll())
  240. {
  241. return IDCANCEL;
  242. }
  243. //
  244. // Check if caller is asking querying for size
  245. //
  246. if (fMode == 0 || pdmOutput == NULL)
  247. return sizeof(DRVDEVMODE);
  248. //
  249. // Call the common routine shared with DrvAdvancedDocumentProperties
  250. //
  251. result = DoDocumentProperties(hwnd, hPrinter, pPrinterName, pdmOutput, pdmInput, fMode);
  252. return (result > 0) ? IDOK : (result == 0) ? IDCANCEL : result;
  253. }
  254. LONG
  255. DrvAdvancedDocumentProperties(
  256. HWND hwnd,
  257. HANDLE hPrinter,
  258. LPTSTR pPrinterName,
  259. PDEVMODE pdmOutput,
  260. PDEVMODE pdmInput
  261. )
  262. /*++
  263. Routine Description:
  264. Set the private members of a DEVMODE structure.
  265. In this release, this function is almost identical to
  266. DrvDocumentProperties above with a few minor exceptions
  267. [Note:]
  268. Please refer to WinNT DDK/SDK documentation for more details.
  269. This is the old entry point for the spooler. Even though
  270. no one should be using this, do it for compatibility.
  271. --*/
  272. {
  273. Verbose(("Entering DrvAdvancedDocumentProperties...\n"));
  274. //
  275. // Do not execute any code before this initialization
  276. //
  277. if(!InitializeDll())
  278. {
  279. return -1;
  280. }
  281. //
  282. // Return the number of bytes required if pdmOutput is NULL
  283. //
  284. if (pdmOutput == NULL)
  285. return sizeof(DRVDEVMODE);
  286. //
  287. // Otherwise, call the common routine shared with DrvDocumentProperties
  288. //
  289. return DoDocumentProperties(hwnd,
  290. hPrinter,
  291. pPrinterName,
  292. pdmOutput,
  293. pdmInput,
  294. DM_COPY|DM_PROMPT|DM_ADVANCED) > 0;
  295. }
  296. BOOL
  297. DrvConvertDevMode(
  298. LPTSTR pPrinterName,
  299. PDEVMODE pdmIn,
  300. PDEVMODE pdmOut,
  301. PLONG pcbNeeded,
  302. DWORD fMode
  303. )
  304. /*++
  305. Routine Description:
  306. Use by SetPrinter and GetPrinter to convert devmodes
  307. Arguments:
  308. pPrinterName - Points to printer name string
  309. pdmIn - Points to the input devmode
  310. pdmOut - Points to the output devmode buffer
  311. pcbNeeded - Specifies the size of output buffer on input
  312. On output, this is the size of output devmode
  313. fMode - Specifies what function to perform
  314. Return Value:
  315. TRUE if successful
  316. FALSE otherwise and an error code is logged
  317. --*/
  318. {
  319. static DRIVER_VERSION_INFO versionInfo = {
  320. // Current driver version number and private devmode size
  321. DRIVER_VERSION, sizeof(DMPRIVATE),
  322. // 3.51 driver version number and private devmode size
  323. // NOTE: We don't have a 3.51 driver - use current version number and devmode size.
  324. DRIVER_VERSION, sizeof(DMPRIVATE)
  325. };
  326. INT result;
  327. HANDLE hPrinter;
  328. Verbose(("Entering DrvConvertDevMode: %x...\n", fMode));
  329. //
  330. // Do not execute any code before this initialization
  331. //
  332. if(!InitializeDll())
  333. {
  334. return FALSE;
  335. }
  336. //
  337. // Call a library routine to handle the common cases
  338. //
  339. result = CommonDrvConvertDevmode(pPrinterName, pdmIn, pdmOut, pcbNeeded, fMode, &versionInfo);
  340. //
  341. // If not handled by the library routine, we only need to worry
  342. // about the case when fMode is CDM_DRIVER_DEFAULT
  343. //
  344. if (result == CDM_RESULT_NOT_HANDLED && fMode == CDM_DRIVER_DEFAULT) {
  345. //
  346. // Return driver default devmode
  347. //
  348. if (OpenPrinter(pPrinterName, &hPrinter, NULL)) {
  349. PDRVDEVMODE pdmDefault = (PDRVDEVMODE) pdmOut;
  350. DriverDefaultDevmode(pdmDefault, pPrinterName, hPrinter);
  351. pdmDefault->dmPrivate.flags |= FAXDM_DRIVER_DEFAULT;
  352. result = CDM_RESULT_TRUE;
  353. ClosePrinter(hPrinter);
  354. } else
  355. Error(("OpenPrinter failed: %d\n", GetLastError()));
  356. }
  357. return (result == CDM_RESULT_TRUE);
  358. }
  359. LONG
  360. SimpleDocumentProperties(
  361. PDOCUMENTPROPERTYHEADER pDPHdr
  362. )
  363. /*++
  364. Routine Description:
  365. Handle simple "Document Properties" where we don't need to display
  366. a dialog and therefore don't have to have common UI library involved
  367. Arguments:
  368. pDPHdr - Points to a DOCUMENTPROPERTYHEADER structure
  369. Return Value:
  370. > 0 if successful, <= 0 otherwise
  371. --*/
  372. {
  373. PUIDATA pUiData;
  374. int iRet = -1;
  375. //
  376. // Check if the caller is interested in the size only
  377. //
  378. pDPHdr->cbOut = sizeof(DRVDEVMODE);
  379. if (pDPHdr->fMode == 0 || pDPHdr->pdmOut == NULL)
  380. {
  381. return pDPHdr->cbOut;
  382. }
  383. //
  384. // Create a UIDATA structure
  385. //
  386. if (! (pUiData = FillUiData(pDPHdr->hPrinter, pDPHdr->pdmIn)))
  387. {
  388. return iRet;
  389. }
  390. //
  391. // Copy the devmode back into the output buffer provided by the caller
  392. // Always return the smaller of current and input devmode
  393. //
  394. if (pDPHdr->fMode & (DM_COPY | DM_UPDATE))
  395. {
  396. if (ConvertDevmodeOut((PDEVMODE) &pUiData->devmode, pDPHdr->pdmIn, pDPHdr->pdmOut, pDPHdr->cbOut))
  397. {
  398. iRet = 1;
  399. }
  400. }
  401. HeapDestroy(pUiData->hheap);
  402. return iRet;
  403. }
  404. BOOL
  405. AddDocPropPages(
  406. PUIDATA pUiData,
  407. LPTSTR pPrinterName
  408. )
  409. /*++
  410. Routine Description:
  411. Add our "Document Properties" pages to the property sheet
  412. Arguments:
  413. pUiData - Points to our UIDATA structure
  414. pPrinterName - Specifies the printer name
  415. Return Value:
  416. TRUE if successful, FALSE otherwise
  417. --*/
  418. {
  419. PROPSHEETPAGE psp = {0};
  420. HANDLE hActCtx;
  421. //
  422. // "Document Properties" dialog only has one tab - "Fax Options"
  423. //
  424. psp.dwSize = sizeof(PROPSHEETPAGE);
  425. psp.dwFlags = 0;
  426. psp.hInstance = g_hResource;
  427. psp.lParam = (LPARAM) pUiData;
  428. psp.pszTemplate = MAKEINTRESOURCE(IDD_DOCPROP);
  429. psp.pfnDlgProc = FaxOptionsProc;
  430. //
  431. // Need to add a Activation Context so that Compstui will create the property page using
  432. // ComCtl v6 (i.e. so it will / can be Themed).
  433. //
  434. hActCtx = GetFaxActivationContext();
  435. if (INVALID_HANDLE_VALUE != hActCtx)
  436. {
  437. pUiData->pfnComPropSheet(pUiData->hComPropSheet,
  438. CPSFUNC_SET_FUSION_CONTEXT,
  439. (LPARAM)hActCtx,
  440. 0);
  441. }
  442. pUiData->hFaxOptsPage = (HANDLE)
  443. pUiData->pfnComPropSheet(pUiData->hComPropSheet,
  444. CPSFUNC_ADD_PROPSHEETPAGE,
  445. (LPARAM) &psp,
  446. 0);
  447. return (pUiData->hFaxOptsPage != NULL);
  448. }
  449. BOOL
  450. GenerateFormsList(
  451. PUIDATA pUiData
  452. )
  453. /*++
  454. Routine Description:
  455. Generate the list of forms supported by the fax driver
  456. Arguments:
  457. pUiData - Points to our UIDATA structure
  458. Return Value:
  459. TRUE if successful, FALSE if there is an error
  460. --*/
  461. {
  462. PFORM_INFO_1 pFormsDB;
  463. DWORD cForms, count;
  464. //
  465. // Get a list of forms in the forms database
  466. //
  467. pFormsDB = GetFormsDatabase(pUiData->hPrinter, &cForms);
  468. if (pFormsDB == NULL || cForms == 0) {
  469. Error(("Couldn't get system forms\n"));
  470. return FALSE;
  471. }
  472. //
  473. // Enumerate the list of supported forms
  474. //
  475. pUiData->cForms = count = EnumPaperSizes(NULL, pFormsDB, cForms, DC_PAPERS);
  476. Assert(count != GDI_ERROR);
  477. pUiData->pFormNames = HeapAlloc(pUiData->hheap, 0, sizeof(TCHAR) * count * CCHPAPERNAME);
  478. pUiData->pPapers = HeapAlloc(pUiData->hheap, 0, sizeof(WORD) * count);
  479. if (!pUiData->pFormNames || !pUiData->pPapers)
  480. {
  481. if(pUiData->pFormNames)
  482. {
  483. HeapFree(pUiData->hheap, 0, pUiData->pFormNames);
  484. }
  485. if(pUiData->pPapers)
  486. {
  487. HeapFree(pUiData->hheap, 0, pUiData->pPapers);
  488. }
  489. MemFree(pFormsDB);
  490. return FALSE;
  491. }
  492. EnumPaperSizes(pUiData->pFormNames, pFormsDB, cForms, DC_PAPERNAMES);
  493. EnumPaperSizes(pUiData->pPapers, pFormsDB, cForms, DC_PAPERS);
  494. MemFree(pFormsDB);
  495. return TRUE;
  496. }
  497. LPTSTR
  498. GetHelpFilename(
  499. PUIDATA pUiData
  500. )
  501. /*++
  502. Routine Description:
  503. Return the driver's help filename string
  504. Arguments:
  505. pUiData - Points to our UIDATA structure
  506. Return Value:
  507. Pointer to the driver help filename, NULL if error
  508. --*/
  509. {
  510. PDRIVER_INFO_3 pDriverInfo3 = NULL;
  511. PVOID pHelpFile = NULL;
  512. //
  513. // Attempt to get help file name using the new DRIVER_INFO_3
  514. //
  515. if (pDriverInfo3 = MyGetPrinterDriver(pUiData->hPrinter, 3)) {
  516. if ((pDriverInfo3->pHelpFile != NULL) &&
  517. (pHelpFile = HeapAlloc(pUiData->hheap, 0, SizeOfString(pDriverInfo3->pHelpFile))))
  518. {
  519. _tcscpy(pHelpFile, pDriverInfo3->pHelpFile);
  520. }
  521. MemFree(pDriverInfo3);
  522. }
  523. //
  524. // If DRIVER_INFO_3 isn't supported, get help file name the old fashion way
  525. //
  526. if (pHelpFile == NULL) {
  527. if (!(pHelpFile = HeapAlloc(pUiData->hheap, 0, SizeOfString(FAXCFG_HELP_FILENAME))) )
  528. {
  529. pHelpFile = NULL;
  530. } else {
  531. _tcscpy(pHelpFile, FAXCFG_HELP_FILENAME);
  532. }
  533. }
  534. Verbose(("Driver help filename: %ws\n", pHelpFile));
  535. return (pUiData->pHelpFile = pHelpFile);
  536. }