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.

612 lines
16 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. All rights reserved
  4. Module Name:
  5. Prop.c
  6. Abstract:
  7. Handles new entry points to document and device properties.
  8. Public Entrypoints:
  9. DocumentPropertySheets
  10. DevicePropertySheets
  11. Author:
  12. Albert Ting (AlbertT) 25-Sept-1995
  13. Steve Kiraly (SteveKi) 02-Feb-1996
  14. Environment:
  15. User Mode -Win32
  16. Revision History:
  17. --*/
  18. #include "precomp.h"
  19. #pragma hdrstop
  20. #include "client.h"
  21. #include "winddiui.h"
  22. //
  23. // UI user data structure definition.
  24. //
  25. typedef struct _UIUserData
  26. {
  27. HANDLE hModule;
  28. LPWSTR pszTitle;
  29. } UIUserData;
  30. BOOL
  31. CreateUIUserData(
  32. IN OUT UIUserData **pData,
  33. IN HANDLE hPrinter
  34. )
  35. /*++
  36. Routine Description:
  37. This function creates the UI user data and loads the printer
  38. driver UI module.
  39. Arguments:
  40. pData pointer to where to return the pointer to the UI user data
  41. hPrinter handle to the open printer
  42. Return Value:
  43. TRUE the UI user data was alloceted, FALSE error occurred.
  44. --*/
  45. {
  46. SPLASSERT( pData );
  47. //
  48. // Allocate the UI user data.
  49. //
  50. *pData = AllocSplMem( sizeof( UIUserData ) );
  51. if( *pData )
  52. {
  53. //
  54. // The title is not allocated initaly.
  55. //
  56. (*pData)->pszTitle = NULL;
  57. //
  58. // Load the printer driver UI module.
  59. //
  60. (*pData)->hModule = LoadPrinterDriver( hPrinter );
  61. if( !(*pData)->hModule )
  62. {
  63. FreeSplMem( *pData );
  64. *pData = NULL;
  65. }
  66. }
  67. return !!*pData;
  68. }
  69. VOID
  70. DestroyUIUserData(
  71. IN UIUserData **pData
  72. )
  73. /*++
  74. Routine Description:
  75. This function destroys the UI user data and unloads the printer
  76. driver UI module.
  77. Arguments:
  78. pData pointer to the UI user data
  79. Return Value:
  80. Nothing.
  81. --*/
  82. {
  83. if( pData && *pData )
  84. {
  85. if( (*pData)->hModule )
  86. {
  87. RefCntUnloadDriver( (*pData)->hModule, TRUE );
  88. (*pData)->hModule = NULL;
  89. }
  90. if( (*pData)->pszTitle )
  91. {
  92. FreeSplMem( (*pData)->pszTitle );
  93. (*pData)->pszTitle = NULL;
  94. }
  95. FreeSplMem( *pData );
  96. *pData = NULL;
  97. }
  98. }
  99. VOID
  100. CreatePrinterFriendlyName(
  101. IN UIUserData *pData,
  102. IN LPCWSTR pszName
  103. )
  104. /*++
  105. Routine Description:
  106. This function creates the printer friendly name and stores
  107. the new name in the UIUserData.
  108. Arguments:
  109. pData pointer to the UI user data
  110. pszName pointer to the unfriendly printer name
  111. Return Value:
  112. Nothing. If the operation fails the unfriendly name is used.
  113. --*/
  114. {
  115. UINT nSize = 0;
  116. HINSTANCE hModule = NULL;
  117. BOOL bStatus = FALSE;
  118. //
  119. // Load printui, which knows how to format the friendly name.
  120. //
  121. hModule = LoadLibrary( szPrintUIDll );
  122. if( hModule )
  123. {
  124. typedef BOOL (*pfConstructPrinterFriendlyName)( LPCWSTR, LPWSTR, UINT * );
  125. pfConstructPrinterFriendlyName pfn;
  126. pfn = (pfConstructPrinterFriendlyName)GetProcAddress( hModule, szConstructPrinterFriendlyName );
  127. if( pfn )
  128. {
  129. //
  130. // Query for the friendly name size.
  131. //
  132. if( !pfn( pszName, NULL, &nSize ) && GetLastError() == ERROR_INSUFFICIENT_BUFFER )
  133. {
  134. //
  135. // Allocate the friendly name buffer.
  136. //
  137. pData->pszTitle = AllocSplMem( (nSize+1) * sizeof(WCHAR) );
  138. if( pData->pszTitle )
  139. {
  140. //
  141. // Get the printer friendly name.
  142. //
  143. bStatus = pfn( pszName, pData->pszTitle, &nSize );
  144. }
  145. }
  146. }
  147. //
  148. // Release the library.
  149. //
  150. FreeLibrary( hModule );
  151. }
  152. //
  153. // Something failed use the unfriendly name.
  154. //
  155. if( !bStatus )
  156. {
  157. FreeSplMem( pData->pszTitle );
  158. pData->pszTitle = AllocSplStr( pszName );
  159. }
  160. }
  161. BOOL
  162. FixUpDEVMODEName(
  163. PDOCUMENTPROPERTYHEADER pDPHdr
  164. )
  165. /*++
  166. Routine Description:
  167. This function fixed up the returned DEVMODE with friendly printer name
  168. in the dmDeviceName field (cut off at 31 character as CCHDEVICENAME)
  169. Arguments:
  170. pDPHdr - Pointer to the DOCUMENTPROPERTYHEADER structure
  171. Return Value:
  172. TRUE if frendly name is copied, FALSE otherwise
  173. Author:
  174. 08-Jul-1996 Mon 13:36:09 created -by- Daniel Chou (danielc)
  175. Revision History:
  176. --*/
  177. {
  178. PPRINTER_INFO_2 pPI2 = NULL;
  179. DWORD cbNeed = 0;
  180. DWORD cbRet = 0;
  181. BOOL bCopy = FALSE;
  182. if ((pDPHdr->fMode & (DM_COPY | DM_UPDATE)) &&
  183. (!(pDPHdr->fMode & DM_NOPERMISSION)) &&
  184. (pDPHdr->pdmOut) &&
  185. (!GetPrinter(pDPHdr->hPrinter, 2, NULL, 0, &cbNeed)) &&
  186. (GetLastError() == ERROR_INSUFFICIENT_BUFFER) &&
  187. (pPI2 = AllocSplMem(cbNeed)) &&
  188. (GetPrinter(pDPHdr->hPrinter, 2, (LPBYTE)pPI2, cbNeed, &cbRet)) &&
  189. (cbNeed == cbRet)) {
  190. StringCchCopy(pDPHdr->pdmOut->dmDeviceName,
  191. CCHDEVICENAME - 1,
  192. pPI2->pPrinterName);
  193. bCopy = TRUE;
  194. }
  195. if (pPI2) {
  196. FreeSplMem(pPI2);
  197. }
  198. return(bCopy);
  199. }
  200. LONG_PTR
  201. DevicePropertySheets(
  202. PPROPSHEETUI_INFO pCPSUIInfo,
  203. LPARAM lParam
  204. )
  205. /*++
  206. Routine Description:
  207. Adds the device specific printer pages. This replaces
  208. PrinterProperties.
  209. Arguments:
  210. pCPSUIInfo - pointer to common ui info header.
  211. lParam - user defined lparam, see compstui for details.
  212. \nt\public\oak\inc\compstui.h
  213. Return Value:
  214. Returns > 0 if success
  215. Returns <= 0 if failure
  216. --*/
  217. {
  218. PDEVICEPROPERTYHEADER pDevPropHdr = NULL;
  219. PPROPSHEETUI_INFO_HEADER pCPSUIInfoHdr = NULL;
  220. PSETRESULT_INFO pSetResultInfo = NULL;
  221. LONG_PTR lResult = FALSE;
  222. HANDLE hModule = NULL;
  223. INT_FARPROC pfn = NULL;
  224. extern HANDLE hInst;
  225. DBGMSG( DBG_TRACE, ("DrvDevicePropertySheets\n") );
  226. //
  227. // Ony compstui requests, are acknowledged.
  228. //
  229. if (pCPSUIInfo) {
  230. if ((!(pDevPropHdr = (PDEVICEPROPERTYHEADER)pCPSUIInfo->lParamInit)) ||
  231. (pDevPropHdr->cbSize < sizeof(DEVICEPROPERTYHEADER))) {
  232. SetLastError(ERROR_INVALID_PARAMETER);
  233. return 0;
  234. }
  235. switch (pCPSUIInfo->Reason) {
  236. case PROPSHEETUI_REASON_INIT:
  237. DBGMSG( DBG_TRACE, ( "DrvDevicePropertySheets PROPSHEETUI_REASON_INIT\n") );
  238. //
  239. // Create the UI User data.
  240. //
  241. if( CreateUIUserData( &(UIUserData *)(pCPSUIInfo->UserData), pDevPropHdr->hPrinter ) ){
  242. if( ((UIUserData *)(pCPSUIInfo->UserData))->hModule ){
  243. //
  244. // Get the driver property sheet entry.
  245. //
  246. if ((pfn = (INT_FARPROC)GetProcAddress( ((UIUserData *)(pCPSUIInfo->UserData))->hModule, szDrvDevPropSheets))) {
  247. //
  248. // Before calling into the driver to add pages make sure the proper
  249. // fusion activation context is set.
  250. //
  251. lResult = pCPSUIInfo->pfnComPropSheet( pCPSUIInfo->hComPropSheet,
  252. CPSFUNC_SET_FUSION_CONTEXT,
  253. (LPARAM)ACTCTX_EMPTY,
  254. (LPARAM)0);
  255. //
  256. // Common ui will call the driver to add it's sheets.
  257. //
  258. lResult = pCPSUIInfo->pfnComPropSheet( pCPSUIInfo->hComPropSheet,
  259. CPSFUNC_ADD_PFNPROPSHEETUI,
  260. (LPARAM)pfn,
  261. pCPSUIInfo->lParamInit );
  262. }
  263. }
  264. }
  265. //
  266. // If something failed ensure we free the library
  267. // if it was loaded.
  268. //
  269. if( lResult <= 0 ){
  270. DBGMSG( DBG_TRACE, ( "DrvDevicePropertySheets PROPSHEETUI_REASON_INIT failed with %d\n", lResult ) );
  271. DestroyUIUserData( &(UIUserData *)(pCPSUIInfo->UserData) );
  272. }
  273. break;
  274. case PROPSHEETUI_REASON_GET_INFO_HEADER:
  275. DBGMSG( DBG_TRACE, ( "DrvDevicePropertySheets PROPSHEETUI_REASON_GET_INFO_HEADER\n") );
  276. pCPSUIInfoHdr = (PPROPSHEETUI_INFO_HEADER)lParam;
  277. CreatePrinterFriendlyName( (UIUserData *)(pCPSUIInfo->UserData), pDevPropHdr->pszPrinterName );
  278. pCPSUIInfoHdr->pTitle = ((UIUserData *)(pCPSUIInfo->UserData))->pszTitle;
  279. pCPSUIInfoHdr->Flags = PSUIHDRF_PROPTITLE | PSUIHDRF_NOAPPLYNOW;
  280. pCPSUIInfoHdr->hInst = hInst;
  281. pCPSUIInfoHdr->IconID = IDI_CPSUI_PRINTER;
  282. lResult = TRUE;
  283. break;
  284. case PROPSHEETUI_REASON_SET_RESULT:
  285. DBGMSG( DBG_TRACE, ( "DrvDevicePropertySheets PROPSHEETUI_REASON_SET_RESULT\n") );
  286. pSetResultInfo = (PSETRESULT_INFO)lParam;
  287. pCPSUIInfo->Result = pSetResultInfo->Result;
  288. lResult = TRUE;
  289. break;
  290. case PROPSHEETUI_REASON_DESTROY:
  291. DBGMSG( DBG_TRACE, ( "DrvDevicePropertySheets PROPSHEETUI_REASON_DESTROY\n") );
  292. DestroyUIUserData( &(UIUserData *)(pCPSUIInfo->UserData) );
  293. lResult = TRUE;
  294. break;
  295. }
  296. }
  297. return lResult;
  298. }
  299. LONG_PTR
  300. DocumentPropertySheets(
  301. PPROPSHEETUI_INFO pCPSUIInfo,
  302. LPARAM lParam
  303. )
  304. /*++
  305. Routine Description:
  306. Adds the document property pages. This replaces DocumentProperties
  307. and Advanced DocumentProperties.
  308. Arguments:
  309. pCPSUIInfo - pointer to common ui info header.
  310. lParam - user defined lparam, see compstui for details.
  311. \nt\public\oak\inc\compstui.h
  312. Return Value:
  313. Returns > 0 if success
  314. Returns <= 0 if failure
  315. --*/
  316. {
  317. PDOCUMENTPROPERTYHEADER pDocPropHdr = NULL;
  318. PPROPSHEETUI_INFO_HEADER pCPSUIInfoHdr = NULL;
  319. PSETRESULT_INFO pSetResultInfo = NULL;
  320. LONG_PTR lResult = FALSE;
  321. HANDLE hModule = NULL;
  322. INT_FARPROC pfn = NULL;
  323. extern HANDLE hInst;
  324. DBGMSG( DBG_TRACE, ("DrvDocumentPropertySheets\n") );
  325. //
  326. // Ony compstui requests, are acknowledged.
  327. //
  328. if (pCPSUIInfo) {
  329. if ((!(pDocPropHdr = (PDOCUMENTPROPERTYHEADER)pCPSUIInfo->lParamInit)) ||
  330. (pDocPropHdr->cbSize < sizeof(PDOCUMENTPROPERTYHEADER))) {
  331. SetLastError(ERROR_INVALID_PARAMETER);
  332. return 0;
  333. }
  334. switch (pCPSUIInfo->Reason) {
  335. case PROPSHEETUI_REASON_INIT:
  336. DBGMSG( DBG_TRACE, ( "DrvDocumentPropertySheets PROPSHEETUI_REASON_INIT\n") );
  337. if (!(pDocPropHdr->fMode & DM_PROMPT)) {
  338. SetLastError(ERROR_INVALID_PARAMETER);
  339. return 0;
  340. }
  341. //
  342. // Create the UI User data.
  343. //
  344. if( CreateUIUserData( &(UIUserData *)(pCPSUIInfo->UserData), pDocPropHdr->hPrinter ) ){
  345. if( ((UIUserData *)(pCPSUIInfo->UserData))->hModule ){
  346. if (pfn = (INT_FARPROC)GetProcAddress( ((UIUserData *)(pCPSUIInfo->UserData))->hModule, szDrvDocPropSheets)) {
  347. //
  348. // Before calling into the driver to add pages make sure the proper
  349. // fusion activation context is set.
  350. //
  351. lResult = pCPSUIInfo->pfnComPropSheet( pCPSUIInfo->hComPropSheet,
  352. CPSFUNC_SET_FUSION_CONTEXT,
  353. (LPARAM)ACTCTX_EMPTY,
  354. (LPARAM)0);
  355. //
  356. // Common ui will call the driver to add it's sheets.
  357. //
  358. lResult = pCPSUIInfo->pfnComPropSheet( pCPSUIInfo->hComPropSheet,
  359. CPSFUNC_ADD_PFNPROPSHEETUI,
  360. (LPARAM)pfn,
  361. pCPSUIInfo->lParamInit );
  362. }
  363. }
  364. }
  365. //
  366. // If something failed ensure we free the library
  367. // if it was loaded.
  368. //
  369. if( lResult <= 0 ){
  370. DBGMSG( DBG_TRACE, ( "DrvDocumentPropertySheets PROPSHEETUI_REASON_INIT failed with %d\n", lResult ) );
  371. DestroyUIUserData( &(UIUserData *)(pCPSUIInfo->UserData) );
  372. }
  373. break;
  374. case PROPSHEETUI_REASON_GET_INFO_HEADER:
  375. DBGMSG( DBG_TRACE, ( "DrvDocumentPropertySheets PROPSHEETUI_REASON_GET_INFO_HEADER\n") );
  376. pCPSUIInfoHdr = (PPROPSHEETUI_INFO_HEADER)lParam;
  377. CreatePrinterFriendlyName( (UIUserData *)(pCPSUIInfo->UserData), pDocPropHdr->pszPrinterName );
  378. pCPSUIInfoHdr->pTitle = ((UIUserData *)(pCPSUIInfo->UserData))->pszTitle;
  379. pCPSUIInfoHdr->Flags = PSUIHDRF_PROPTITLE | PSUIHDRF_NOAPPLYNOW;
  380. pCPSUIInfoHdr->hInst = hInst;
  381. pCPSUIInfoHdr->IconID = IDI_CPSUI_PRINTER;
  382. lResult = TRUE;
  383. break;
  384. case PROPSHEETUI_REASON_SET_RESULT:
  385. DBGMSG( DBG_TRACE, ( "DrvDocumentPropertySheets PROPSHEETUI_REASON_SET_RESULT\n") );
  386. pSetResultInfo = (PSETRESULT_INFO)lParam;
  387. if ((pCPSUIInfo->Result = pSetResultInfo->Result) > 0) {
  388. FixUpDEVMODEName(pDocPropHdr);
  389. }
  390. lResult = TRUE;
  391. break;
  392. case PROPSHEETUI_REASON_DESTROY:
  393. DBGMSG( DBG_TRACE, ( "DrvDocumentPropertySheets PROPSHEETUI_REASON_DESTROY\n") );
  394. DestroyUIUserData( &(UIUserData*)(pCPSUIInfo->UserData) );
  395. lResult = TRUE;
  396. break;
  397. }
  398. //
  399. // If a null pointer to common ui info header then
  400. // call the driver directly.
  401. //
  402. } else {
  403. lResult = -1;
  404. if ((!(pDocPropHdr = (PDOCUMENTPROPERTYHEADER)lParam)) ||
  405. (pDocPropHdr->cbSize < sizeof(PDOCUMENTPROPERTYHEADER))) {
  406. SetLastError(ERROR_INVALID_PARAMETER);
  407. return lResult;
  408. }
  409. if (pDocPropHdr->fMode & DM_PROMPT) {
  410. SetLastError(ERROR_INVALID_PARAMETER);
  411. } else if ((hModule = LoadPrinterDriver(pDocPropHdr->hPrinter)) &&
  412. (pfn = (INT_FARPROC)GetProcAddress(hModule, szDrvDocPropSheets))) {
  413. if ((lResult = (*pfn)(NULL, pDocPropHdr)) > 0) {
  414. FixUpDEVMODEName(pDocPropHdr);
  415. }
  416. } else {
  417. SetLastError(ERROR_INVALID_HANDLE);
  418. }
  419. if (hModule) {
  420. RefCntUnloadDriver(hModule, TRUE);
  421. }
  422. }
  423. return lResult;
  424. }