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.

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