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.

731 lines
23 KiB

  1. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  2. // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  3. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  4. // PARTICULAR PURPOSE.
  5. //
  6. // Copyright 1997 - 2003 Microsoft Corporation. All Rights Reserved.
  7. //
  8. // FILE: OEMUI.cpp
  9. //
  10. //
  11. // PURPOSE: Main file for OEM UI test module.
  12. //
  13. //
  14. // Functions:
  15. //
  16. //
  17. //
  18. //
  19. // PLATFORMS: Windows 2000, Windows XP, Windows Server 2003
  20. //
  21. //
  22. #include "precomp.h"
  23. #include "resource.h"
  24. #include "debug.h"
  25. #include "oemui.h"
  26. // StrSafe.h needs to be included last
  27. // to disallow bad string functions.
  28. #include <STRSAFE.H>
  29. ////////////////////////////////////////////////////////
  30. // INTERNAL MACROS and DEFINES
  31. ////////////////////////////////////////////////////////
  32. typedef struct _tagCBUserData
  33. {
  34. HANDLE hComPropSheet;
  35. HANDLE hPropPage;
  36. POEMUIPSPARAM pOEMUIParam;
  37. PFNCOMPROPSHEET pfnComPropSheet;
  38. } CBUSERDATA, *PCBUSERDATA;
  39. ////////////////////////////////////////////////////////
  40. // INTERNAL PROTOTYPES
  41. ////////////////////////////////////////////////////////
  42. static HRESULT hrDocumentPropertyPage(DWORD dwMode, POEMCUIPPARAM pOEMUIParam);
  43. static HRESULT hrPrinterPropertyPage(DWORD dwMode, POEMCUIPPARAM pOEMUIParam);
  44. LONG APIENTRY OEMPrinterUICallBack(PCPSUICBPARAM pCallbackParam, POEMCUIPPARAM pOEMUIParam);
  45. LONG APIENTRY OEMDocUICallBack(PCPSUICBPARAM pCallbackParam, POEMCUIPPARAM pOEMUIParam);
  46. LONG APIENTRY OEMDocUICallBack2(PCPSUICBPARAM pCallbackParam);
  47. INT_PTR CALLBACK DevicePropPageProc(HWND hDlg, UINT uiMsg, WPARAM wParam, LPARAM lParam);
  48. static POPTITEM CreateOptItems(HANDLE hHeap, DWORD dwOptItems);
  49. static void InitOptItems(POPTITEM pOptItems, DWORD dwOptItems);
  50. static POPTTYPE CreateOptType(HANDLE hHeap, WORD wOptParams);
  51. static PTSTR GetStringResource(HANDLE hHeap, HANDLE hModule, UINT uResource);
  52. ////////////////////////////////////////////////////////////////////////////////
  53. //
  54. // Initializes OptItems to display OEM device or document property UI.
  55. //
  56. HRESULT hrOEMPropertyPage(DWORD dwMode, POEMCUIPPARAM pOEMUIParam)
  57. {
  58. HRESULT hResult = S_OK;
  59. VERBOSE(DLLTEXT("hrOEMPropertyPage(%d) entry.\r\n"), dwMode);
  60. // Validate parameters.
  61. if( (OEMCUIP_DOCPROP != dwMode)
  62. &&
  63. (OEMCUIP_PRNPROP != dwMode)
  64. )
  65. {
  66. ERR(ERRORTEXT("hrOEMPropertyPage() ERROR_INVALID_PARAMETER.\r\n"));
  67. VERBOSE(DLLTEXT("\tdwMode = %d, pOEMUIParam = %#lx.\r\n"), dwMode, pOEMUIParam);
  68. // Return invalid parameter error.
  69. SetLastError(ERROR_INVALID_PARAMETER);
  70. return E_FAIL;
  71. }
  72. switch(dwMode)
  73. {
  74. case OEMCUIP_DOCPROP:
  75. hResult = hrDocumentPropertyPage(dwMode, pOEMUIParam);
  76. break;
  77. case OEMCUIP_PRNPROP:
  78. hResult = hrPrinterPropertyPage(dwMode, pOEMUIParam);
  79. break;
  80. default:
  81. // Should never reach this!
  82. ERR(ERRORTEXT("hrOEMPropertyPage() Invalid dwMode, %d"), dwMode);
  83. SetLastError(ERROR_INVALID_PARAMETER);
  84. hResult = E_FAIL;
  85. break;
  86. }
  87. return hResult;
  88. }
  89. ////////////////////////////////////////////////////////////////////////////////
  90. //
  91. // Initializes OptItems to display OEM document property UI.
  92. //
  93. static HRESULT hrDocumentPropertyPage(DWORD dwMode, POEMCUIPPARAM pOEMUIParam)
  94. {
  95. if(NULL == pOEMUIParam->pOEMOptItems)
  96. {
  97. // Fill in the number of OptItems to create for OEM document property UI.
  98. pOEMUIParam->cOEMOptItems = 1;
  99. VERBOSE(DLLTEXT("hrDocumentPropertyPage() requesting %d number of items.\r\n"), pOEMUIParam->cOEMOptItems);
  100. }
  101. else
  102. {
  103. POEMDEV pOEMDev = (POEMDEV) pOEMUIParam->pOEMDM;
  104. VERBOSE(DLLTEXT("hrDocumentPropertyPage() fill out %d items.\r\n"), pOEMUIParam->cOEMOptItems);
  105. // Init UI Callback reference.
  106. pOEMUIParam->OEMCUIPCallback = OEMDocUICallBack;
  107. // Init OEMOptItmes.
  108. InitOptItems(pOEMUIParam->pOEMOptItems, pOEMUIParam->cOEMOptItems);
  109. // Fill out tree view items.
  110. // New section.
  111. pOEMUIParam->pOEMOptItems[0].Level = 1;
  112. pOEMUIParam->pOEMOptItems[0].Flags = OPTIF_COLLAPSE;
  113. pOEMUIParam->pOEMOptItems[0].pName = GetStringResource(pOEMUIParam->hOEMHeap, pOEMUIParam->hModule, IDS_ADV_SECTION);
  114. pOEMUIParam->pOEMOptItems[0].Sel = pOEMDev->dwAdvancedData;
  115. pOEMUIParam->pOEMOptItems[0].pOptType = CreateOptType(pOEMUIParam->hOEMHeap, 2);
  116. pOEMUIParam->pOEMOptItems[0].pOptType->Type = TVOT_UDARROW;
  117. pOEMUIParam->pOEMOptItems[0].pOptType->pOptParam[1].IconID = 0;
  118. pOEMUIParam->pOEMOptItems[0].pOptType->pOptParam[1].lParam = 100;
  119. }
  120. return S_OK;
  121. }
  122. ////////////////////////////////////////////////////////////////////////////////
  123. //
  124. // Initializes OptItems to display OEM printer property UI.
  125. //
  126. static HRESULT hrPrinterPropertyPage(DWORD dwMode, POEMCUIPPARAM pOEMUIParam)
  127. {
  128. if(NULL == pOEMUIParam->pOEMOptItems)
  129. {
  130. // Fill in the number of OptItems to create for OEM printer property UI.
  131. pOEMUIParam->cOEMOptItems = 1;
  132. VERBOSE(DLLTEXT("hrPrinterPropertyPage() requesting %d number of items.\r\n"), pOEMUIParam->cOEMOptItems);
  133. }
  134. else
  135. {
  136. DWORD dwError;
  137. DWORD dwDeviceValue;
  138. DWORD dwType;
  139. DWORD dwNeeded;
  140. VERBOSE(DLLTEXT("hrPrinterPropertyPage() fill out %d items.\r\n"), pOEMUIParam->cOEMOptItems);
  141. // Get device settings value from printer.
  142. dwError = GetPrinterData(pOEMUIParam->hPrinter, OEMUI_VALUE, &dwType, (PBYTE) &dwDeviceValue,
  143. sizeof(dwDeviceValue), &dwNeeded);
  144. if( (ERROR_SUCCESS != dwError)
  145. ||
  146. (dwDeviceValue > 100)
  147. )
  148. {
  149. // Failed to get the device value or value is invalid, just use the default.
  150. dwDeviceValue = 0;
  151. }
  152. // Init UI Callback reference.
  153. pOEMUIParam->OEMCUIPCallback = OEMPrinterUICallBack;
  154. // Init OEMOptItmes.
  155. InitOptItems(pOEMUIParam->pOEMOptItems, pOEMUIParam->cOEMOptItems);
  156. // Fill out tree view items.
  157. // New section.
  158. pOEMUIParam->pOEMOptItems[0].Level = 1;
  159. pOEMUIParam->pOEMOptItems[0].Flags = OPTIF_COLLAPSE;
  160. pOEMUIParam->pOEMOptItems[0].pName = GetStringResource(pOEMUIParam->hOEMHeap, pOEMUIParam->hModule, IDS_DEV_SECTION);
  161. pOEMUIParam->pOEMOptItems[0].Sel = dwDeviceValue;
  162. pOEMUIParam->pOEMOptItems[0].pOptType = CreateOptType(pOEMUIParam->hOEMHeap, 2);
  163. pOEMUIParam->pOEMOptItems[0].pOptType->Type = TVOT_UDARROW;
  164. pOEMUIParam->pOEMOptItems[0].pOptType->pOptParam[1].IconID = 0;
  165. pOEMUIParam->pOEMOptItems[0].pOptType->pOptParam[1].lParam = 100;
  166. }
  167. return S_OK;
  168. }
  169. ////////////////////////////////////////////////////////////////////////////////
  170. //
  171. // Adds property page to Document property sheet.
  172. //
  173. HRESULT hrOEMDocumentPropertySheets(PPROPSHEETUI_INFO pPSUIInfo, LPARAM lParam,
  174. IPrintOemDriverUI* pOEMHelp)
  175. {
  176. LONG_PTR lResult;
  177. VERBOSE(DLLTEXT("OEMDocumentPropertySheets() entry.\r\n"));
  178. // Validate parameters.
  179. if( (NULL == pPSUIInfo)
  180. ||
  181. (PROPSHEETUI_INFO_VERSION != pPSUIInfo->Version)
  182. )
  183. {
  184. ERR(ERRORTEXT("OEMDocumentPropertySheets() ERROR_INVALID_PARAMETER.\r\n"));
  185. // Return invalid parameter error.
  186. SetLastError(ERROR_INVALID_PARAMETER);
  187. return E_FAIL;
  188. }
  189. // Do action.
  190. switch(pPSUIInfo->Reason)
  191. {
  192. case PROPSHEETUI_REASON_INIT:
  193. {
  194. DWORD dwSheets = 0;
  195. PCBUSERDATA pUserData = NULL;
  196. POEMUIPSPARAM pOEMUIParam = (POEMUIPSPARAM) pPSUIInfo->lParamInit;
  197. HANDLE hHeap = pOEMUIParam->hOEMHeap;
  198. POEMDEV pOEMDev = (POEMDEV) pOEMUIParam->pOEMDM;
  199. COMPROPSHEETUI Sheet;
  200. // Init property page.
  201. memset(&Sheet, 0, sizeof(COMPROPSHEETUI));
  202. Sheet.cbSize = sizeof(COMPROPSHEETUI);
  203. Sheet.Flags = CPSUIF_UPDATE_PERMISSION;
  204. Sheet.hInstCaller = ghInstance;
  205. Sheet.pCallerName = GetStringResource(hHeap, ghInstance, IDS_NAME);
  206. Sheet.pHelpFile = NULL;
  207. Sheet.pfnCallBack = OEMDocUICallBack2;
  208. Sheet.pDlgPage = CPSUI_PDLGPAGE_TREEVIEWONLY;
  209. Sheet.cOptItem = 1;
  210. Sheet.IconID = IDI_CPSUI_PRINTER;
  211. Sheet.pOptItemName = GetStringResource(hHeap, ghInstance, IDS_SECTION);
  212. Sheet.CallerVersion = 0x100;
  213. Sheet.OptItemVersion = 0x100;
  214. // Init user data.
  215. pUserData = (PCBUSERDATA) HeapAlloc(hHeap, HEAP_ZERO_MEMORY, sizeof(CBUSERDATA));
  216. pUserData->hComPropSheet = pPSUIInfo->hComPropSheet;
  217. pUserData->pfnComPropSheet = pPSUIInfo->pfnComPropSheet;
  218. pUserData->pOEMUIParam = pOEMUIParam;
  219. Sheet.UserData = (ULONG_PTR) pUserData;
  220. // Create OptItems for page.
  221. Sheet.pOptItem = CreateOptItems(hHeap, Sheet.cOptItem);
  222. // Initialize OptItems
  223. Sheet.pOptItem[0].Level = 1;
  224. Sheet.pOptItem[0].Flags = OPTIF_COLLAPSE;
  225. Sheet.pOptItem[0].pName = GetStringResource(hHeap, ghInstance, IDS_SECTION);
  226. Sheet.pOptItem[0].Sel = pOEMDev->dwDriverData;
  227. Sheet.pOptItem[0].pOptType = CreateOptType(hHeap, 2);
  228. Sheet.pOptItem[0].pOptType->Type = TVOT_UDARROW;
  229. Sheet.pOptItem[0].pOptType->pOptParam[1].IconID = 0;
  230. Sheet.pOptItem[0].pOptType->pOptParam[1].lParam = 100;
  231. // Add property sheets.
  232. lResult = pPSUIInfo->pfnComPropSheet(pPSUIInfo->hComPropSheet, CPSFUNC_ADD_PCOMPROPSHEETUI,
  233. (LPARAM)&Sheet, (LPARAM)&dwSheets);
  234. }
  235. break;
  236. case PROPSHEETUI_REASON_GET_INFO_HEADER:
  237. {
  238. PPROPSHEETUI_INFO_HEADER pHeader = (PPROPSHEETUI_INFO_HEADER) lParam;
  239. pHeader->pTitle = (LPTSTR)PROP_TITLE;
  240. lResult = TRUE;
  241. }
  242. break;
  243. case PROPSHEETUI_REASON_GET_ICON:
  244. // No icon
  245. lResult = 0;
  246. break;
  247. case PROPSHEETUI_REASON_SET_RESULT:
  248. {
  249. PSETRESULT_INFO pInfo = (PSETRESULT_INFO) lParam;
  250. lResult = pInfo->Result;
  251. }
  252. break;
  253. case PROPSHEETUI_REASON_DESTROY:
  254. lResult = TRUE;
  255. break;
  256. }
  257. pPSUIInfo->Result = lResult;
  258. return S_OK;
  259. }
  260. ////////////////////////////////////////////////////////////////////////////////
  261. //
  262. // Adds property page to printer property sheet.
  263. //
  264. HRESULT hrOEMDevicePropertySheets(PPROPSHEETUI_INFO pPSUIInfo, LPARAM lParam)
  265. {
  266. LONG_PTR lResult;
  267. VERBOSE(DLLTEXT("hrOEMDevicePropertySheets(%#x, %#x) entry\r\n"), pPSUIInfo, lParam);
  268. // Validate parameters.
  269. if( (NULL == pPSUIInfo)
  270. ||
  271. (PROPSHEETUI_INFO_VERSION != pPSUIInfo->Version)
  272. )
  273. {
  274. ERR(ERRORTEXT("hrOEMDevicePropertySheets() ERROR_INVALID_PARAMETER.\r\n"));
  275. // Return invalid parameter error.
  276. SetLastError(ERROR_INVALID_PARAMETER);
  277. return E_FAIL;
  278. }
  279. Dump(pPSUIInfo);
  280. // Do action.
  281. switch(pPSUIInfo->Reason)
  282. {
  283. case PROPSHEETUI_REASON_INIT:
  284. {
  285. PROPSHEETPAGE Page;
  286. // Init property page.
  287. memset(&Page, 0, sizeof(PROPSHEETPAGE));
  288. Page.dwSize = sizeof(PROPSHEETPAGE);
  289. Page.dwFlags = PSP_DEFAULT;
  290. Page.hInstance = ghInstance;
  291. Page.pszTemplate = MAKEINTRESOURCE(IDD_DEVICE_PROPPAGE);
  292. Page.pfnDlgProc = DevicePropPageProc;
  293. // Add property sheets.
  294. lResult = pPSUIInfo->pfnComPropSheet(pPSUIInfo->hComPropSheet, CPSFUNC_ADD_PROPSHEETPAGE, (LPARAM)&Page, 0);
  295. VERBOSE(DLLTEXT("hrOEMDevicePropertySheets() pfnComPropSheet returned %d.\r\n"), lResult);
  296. }
  297. break;
  298. case PROPSHEETUI_REASON_GET_INFO_HEADER:
  299. {
  300. PPROPSHEETUI_INFO_HEADER pHeader = (PPROPSHEETUI_INFO_HEADER) lParam;
  301. pHeader->pTitle = (LPTSTR)PROP_TITLE;
  302. lResult = TRUE;
  303. }
  304. break;
  305. case PROPSHEETUI_REASON_GET_ICON:
  306. // No icon
  307. lResult = 0;
  308. break;
  309. case PROPSHEETUI_REASON_SET_RESULT:
  310. {
  311. PSETRESULT_INFO pInfo = (PSETRESULT_INFO) lParam;
  312. lResult = pInfo->Result;
  313. }
  314. break;
  315. case PROPSHEETUI_REASON_DESTROY:
  316. lResult = TRUE;
  317. break;
  318. }
  319. pPSUIInfo->Result = lResult;
  320. return S_OK;
  321. }
  322. ////////////////////////////////////////////////////////////////////////////////
  323. //
  324. // OptItems call back for OEM printer property UI.
  325. //
  326. LONG APIENTRY OEMPrinterUICallBack(PCPSUICBPARAM pCallbackParam, POEMCUIPPARAM pOEMUIParam)
  327. {
  328. LONG lReturn = CPSUICB_ACTION_NONE;
  329. POEMDEV pOEMDev = (POEMDEV) pOEMUIParam->pOEMDM;
  330. VERBOSE(DLLTEXT("OEMPrinterUICallBack() entry, Reason is %d.\r\n"), pCallbackParam->Reason);
  331. switch(pCallbackParam->Reason)
  332. {
  333. case CPSUICB_REASON_APPLYNOW:
  334. {
  335. DWORD dwDriverValue = pOEMUIParam->pOEMOptItems[0].Sel;
  336. // Store OptItems state in printer data.
  337. SetPrinterData(pOEMUIParam->hPrinter, OEMUI_VALUE, REG_DWORD, (PBYTE) &dwDriverValue, sizeof(DWORD));
  338. }
  339. break;
  340. default:
  341. break;
  342. }
  343. return lReturn;
  344. }
  345. ////////////////////////////////////////////////////////////////////////////////
  346. //
  347. // Call back for OEM device property UI.
  348. //
  349. INT_PTR CALLBACK DevicePropPageProc(HWND hDlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
  350. {
  351. switch (uiMsg)
  352. {
  353. case WM_COMMAND:
  354. switch(HIWORD(wParam))
  355. {
  356. case BN_CLICKED:
  357. switch(LOWORD(wParam))
  358. {
  359. case IDC_CALIBRATE:
  360. // Just display a message that the printer is calibrated,
  361. // since we don't acutally calibrate anything.
  362. {
  363. TCHAR szName[MAX_PATH];
  364. TCHAR szCalibrated[MAX_PATH];
  365. LoadString(ghInstance, IDS_NAME, szName, sizeof(szName)/sizeof(szName[0]));
  366. LoadString(ghInstance, IDS_CALIBRATED, szCalibrated, sizeof(szCalibrated)/sizeof(szCalibrated[0]));
  367. MessageBox(hDlg, szCalibrated, szName, MB_OK);
  368. }
  369. break;
  370. }
  371. break;
  372. default:
  373. return FALSE;
  374. }
  375. return TRUE;
  376. case WM_NOTIFY:
  377. {
  378. switch (((LPNMHDR)lParam)->code) // type of notification message
  379. {
  380. case PSN_SETACTIVE:
  381. break;
  382. case PSN_KILLACTIVE:
  383. break;
  384. case PSN_APPLY:
  385. break;
  386. case PSN_RESET:
  387. break;
  388. }
  389. }
  390. break;
  391. }
  392. return FALSE;
  393. }
  394. ////////////////////////////////////////////////////////////////////////////////
  395. //
  396. // OptItems call back for OEM document property UI.
  397. //
  398. LONG APIENTRY OEMDocUICallBack(PCPSUICBPARAM pCallbackParam, POEMCUIPPARAM pOEMUIParam)
  399. {
  400. LONG lReturn = CPSUICB_ACTION_NONE;
  401. POEMDEV pOEMDev = (POEMDEV) pOEMUIParam->pOEMDM;
  402. VERBOSE(DLLTEXT("OEMDocUICallBack() entry, Reason is %d.\r\n"), pCallbackParam->Reason);
  403. switch(pCallbackParam->Reason)
  404. {
  405. case CPSUICB_REASON_APPLYNOW:
  406. // Update UI item data.
  407. pOEMDev->dwAdvancedData = pOEMUIParam->pOEMOptItems[0].Sel;
  408. break;
  409. case CPSUICB_REASON_KILLACTIVE:
  410. // Update devmode if settings have changed.
  411. if(pOEMDev->dwAdvancedData != pOEMUIParam->pOEMOptItems[0].Sel)
  412. {
  413. // Update OEM Devmode driver data.
  414. pOEMDev->dwAdvancedData = pOEMUIParam->pOEMOptItems[0].Sel;
  415. }
  416. break;
  417. case CPSUICB_REASON_SETACTIVE:
  418. if(pOEMUIParam->pOEMOptItems[0].Sel != pOEMDev->dwAdvancedData)
  419. {
  420. pOEMUIParam->pOEMOptItems[0].Sel = pOEMDev->dwAdvancedData;
  421. pOEMUIParam->pOEMOptItems[0].Flags |= OPTIF_CHANGED;
  422. lReturn = CPSUICB_ACTION_OPTIF_CHANGED;
  423. }
  424. break;
  425. default:
  426. break;
  427. }
  428. return lReturn;
  429. }
  430. LONG APIENTRY OEMDocUICallBack2(PCPSUICBPARAM pCallbackParam)
  431. {
  432. LONG lReturn = CPSUICB_ACTION_NONE;
  433. PCBUSERDATA pUserData = (PCBUSERDATA) pCallbackParam->UserData;
  434. POEMDEV pOEMDev = (POEMDEV) pUserData->pOEMUIParam->pOEMDM;
  435. VERBOSE(DLLTEXT("OEMDocUICallBack2() entry, Reason is %d.\r\n"), pCallbackParam->Reason);
  436. switch(pCallbackParam->Reason)
  437. {
  438. case CPSUICB_REASON_APPLYNOW:
  439. // Update OEM devmode driver data.
  440. pOEMDev->dwDriverData = pCallbackParam->pOptItem[0].Sel;
  441. pUserData->pfnComPropSheet(pUserData->hComPropSheet, CPSFUNC_SET_RESULT,
  442. (LPARAM)pUserData->hPropPage,
  443. (LPARAM)CPSUI_OK);
  444. break;
  445. case CPSUICB_REASON_KILLACTIVE:
  446. if(pOEMDev->dwDriverData != pCallbackParam->pOptItem[0].Sel)
  447. {
  448. // Update OEM devmode driver data.
  449. pOEMDev->dwDriverData = pCallbackParam->pOptItem[0].Sel;
  450. }
  451. break;
  452. case CPSUICB_REASON_SETACTIVE:
  453. if(pCallbackParam->pOptItem[0].Sel != pOEMDev->dwDriverData)
  454. {
  455. pCallbackParam->pOptItem[0].Sel = pOEMDev->dwDriverData;
  456. pCallbackParam->pOptItem[0].Flags |= OPTIF_CHANGED;
  457. lReturn = CPSUICB_ACTION_OPTIF_CHANGED;
  458. }
  459. break;
  460. default:
  461. break;
  462. }
  463. return lReturn;
  464. }
  465. ////////////////////////////////////////////////////////////////////////////////
  466. //
  467. // Creates and Initializes OptItems.
  468. //
  469. static POPTITEM CreateOptItems(HANDLE hHeap, DWORD dwOptItems)
  470. {
  471. POPTITEM pOptItems = NULL;
  472. // Allocate memory for OptItems;
  473. pOptItems = (POPTITEM) HeapAlloc(hHeap, HEAP_ZERO_MEMORY, sizeof(OPTITEM) * dwOptItems);
  474. if(NULL != pOptItems)
  475. {
  476. InitOptItems(pOptItems, dwOptItems);
  477. }
  478. else
  479. {
  480. ERR(ERRORTEXT("CreateOptItems() failed to allocate memory for OPTITEMs!\r\n"));
  481. }
  482. return pOptItems;
  483. }
  484. ////////////////////////////////////////////////////////////////////////////////
  485. //
  486. // Initializes OptItems.
  487. //
  488. static void InitOptItems(POPTITEM pOptItems, DWORD dwOptItems)
  489. {
  490. VERBOSE(DLLTEXT("InitOptItems() entry.\r\n"));
  491. // Zero out memory.
  492. memset(pOptItems, 0, sizeof(OPTITEM) * dwOptItems);
  493. // Set each OptItem's size, and Public DM ID.
  494. for(DWORD dwCount = 0; dwCount < dwOptItems; dwCount++)
  495. {
  496. pOptItems[dwCount].cbSize = sizeof(OPTITEM);
  497. pOptItems[dwCount].DMPubID = DMPUB_NONE;
  498. }
  499. }
  500. ////////////////////////////////////////////////////////////////////////////////
  501. //
  502. // Allocates and initializes OptType for OptItem.
  503. //
  504. static POPTTYPE CreateOptType(HANDLE hHeap, WORD wOptParams)
  505. {
  506. POPTTYPE pOptType = NULL;
  507. VERBOSE(DLLTEXT("CreateOptType() entry.\r\n"));
  508. // Allocate memory from the heap for the OPTTYPE; the driver will take care of clean up.
  509. pOptType = (POPTTYPE) HeapAlloc(hHeap, HEAP_ZERO_MEMORY, sizeof(OPTTYPE));
  510. if(NULL != pOptType)
  511. {
  512. // Initialize OPTTYPE.
  513. pOptType->cbSize = sizeof(OPTTYPE);
  514. pOptType->Count = wOptParams;
  515. // Allocate memory from the heap for the OPTPARAMs for the OPTTYPE.
  516. pOptType->pOptParam = (POPTPARAM) HeapAlloc(hHeap, HEAP_ZERO_MEMORY, wOptParams * sizeof(OPTPARAM));
  517. if(NULL != pOptType->pOptParam)
  518. {
  519. // Initialize the OPTPARAMs.
  520. for(WORD wCount = 0; wCount < wOptParams; wCount++)
  521. {
  522. pOptType->pOptParam[wCount].cbSize = sizeof(OPTPARAM);
  523. }
  524. }
  525. else
  526. {
  527. ERR(ERRORTEXT("CreateOptType() failed to allocated memory for OPTPARAMs!\r\n"));
  528. // Free allocated memory and return NULL.
  529. HeapFree(hHeap, 0, pOptType);
  530. pOptType = NULL;
  531. }
  532. }
  533. else
  534. {
  535. ERR(ERRORTEXT("CreateOptType() failed to allocated memory for OPTTYPE!\r\n"));
  536. }
  537. return pOptType;
  538. }
  539. ////////////////////////////////////////////////////////////////////////////////////
  540. //
  541. // Retrieves pointer to a String resource.
  542. //
  543. static PTSTR GetStringResource(HANDLE hHeap, HANDLE hModule, UINT uResource)
  544. {
  545. int nResult;
  546. DWORD dwSize = MAX_PATH;
  547. PTSTR pszString = NULL;
  548. VERBOSE(DLLTEXT("GetStringResource(%#x, %#x, %d) entered.\r\n"), hHeap, hModule, uResource);
  549. // Allocate buffer for string resource from heap; let the driver clean it up.
  550. pszString = (PTSTR) HeapAlloc(hHeap, HEAP_ZERO_MEMORY, dwSize * sizeof(TCHAR));
  551. if(NULL != pszString)
  552. {
  553. // Load string resource; resize after loading so as not to waste memory.
  554. nResult = LoadString((HMODULE)hModule, uResource, pszString, dwSize);
  555. if(nResult > 0)
  556. {
  557. PTSTR pszTemp;
  558. VERBOSE(DLLTEXT("LoadString() returned %d!\r\n"), nResult);
  559. VERBOSE(DLLTEXT("String load was \"%s\".\r\n"), pszString);
  560. pszTemp = (PTSTR) HeapReAlloc(hHeap, HEAP_ZERO_MEMORY, pszString, (nResult + 1) * sizeof(TCHAR));
  561. if(NULL != pszTemp)
  562. {
  563. pszString = pszTemp;
  564. }
  565. else
  566. {
  567. ERR(ERRORTEXT("GetStringResource() HeapReAlloc() of string retrieved failed! (Last Error was %d)\r\n"), GetLastError());
  568. }
  569. }
  570. else
  571. {
  572. ERR(ERRORTEXT("LoadString() returned %d! (Last Error was %d)\r\n"), nResult, GetLastError());
  573. ERR(ERRORTEXT("GetStringResource() failed to load string resource %d!\r\n"), uResource);
  574. pszString = NULL;
  575. }
  576. }
  577. else
  578. {
  579. ERR(ERRORTEXT("GetStringResource() failed to allocate string buffer!\r\n"));
  580. }
  581. return pszString;
  582. }