Source code of Windows XP (NT5)
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.

535 lines
14 KiB

  1. /*++
  2. Copyright (C) 2000 Microsoft Corporation
  3. Module Name:
  4. gdipconv.cpp
  5. Abstract:
  6. Helper functions for using GDI+ to convert image formats
  7. Author:
  8. DavePar
  9. Revision History:
  10. --*/
  11. #include "pch.h"
  12. /**************************************************************************\
  13. * wiauGetDrvItemContext
  14. \**************************************************************************/
  15. HRESULT wiauGetDrvItemContext(BYTE *pWiasContext, VOID **ppItemCtx, IWiaDrvItem **ppDrvItem)
  16. {
  17. HRESULT hr = S_OK;
  18. //
  19. // Locals
  20. //
  21. IWiaDrvItem *pWiaDrvItem = NULL;
  22. REQUIRE_ARGS(!pWiasContext || !ppItemCtx, hr, "wiauGetDrvItemContext");
  23. *ppItemCtx = NULL;
  24. if (ppDrvItem)
  25. *ppDrvItem = NULL;
  26. hr = wiasGetDrvItem(pWiasContext, &pWiaDrvItem);
  27. REQUIRE_SUCCESS(hr, "wiauGetDrvItemContext", "wiasGetDrvItem failed");
  28. hr = pWiaDrvItem->GetDeviceSpecContext((BYTE **) ppItemCtx);
  29. REQUIRE_SUCCESS(hr, "wiauGetDrvItemContext", "GetDeviceSpecContext failed");
  30. if (!*ppItemCtx)
  31. {
  32. wiauDbgError("wiauGetDrvItemContext", "Item context is null");
  33. hr = E_FAIL;
  34. goto Cleanup;
  35. }
  36. if (ppDrvItem)
  37. {
  38. *ppDrvItem = pWiaDrvItem;
  39. }
  40. Cleanup:
  41. return hr;
  42. }
  43. /**************************************************************************\
  44. * wiauSetImageItemSize
  45. \**************************************************************************/
  46. HRESULT wiauSetImageItemSize(BYTE *pWiasContext, LONG lWidth, LONG lHeight,
  47. LONG lDepth, LONG lSize, PWSTR pwszExt)
  48. {
  49. HRESULT hr = S_OK;
  50. LONG lNewSize = 0;
  51. LONG lWidthInBytes = 0;
  52. GUID guidFormatID = GUID_NULL;
  53. BSTR bstrExt = NULL;
  54. LONG lNumProperties = 2;
  55. PROPVARIANT pv[3];
  56. PROPSPEC ps[3] = {{PRSPEC_PROPID, WIA_IPA_ITEM_SIZE},
  57. {PRSPEC_PROPID, WIA_IPA_BYTES_PER_LINE},
  58. {PRSPEC_PROPID, WIA_IPA_FILENAME_EXTENSION}};
  59. //
  60. // Read the current format GUID
  61. //
  62. hr = wiasReadPropGuid(pWiasContext, WIA_IPA_FORMAT, &guidFormatID, NULL, TRUE);
  63. REQUIRE_SUCCESS(hr, "wiauSetImageItemSize", "wiasReadPropGuid failed");
  64. if (IsEqualCLSID(guidFormatID, WiaImgFmt_BMP) ||
  65. IsEqualCLSID(guidFormatID, WiaImgFmt_MEMORYBMP))
  66. {
  67. lNewSize = sizeof(BITMAPINFOHEADER);
  68. //
  69. // if this is a file, add file header to size
  70. //
  71. if (IsEqualCLSID(guidFormatID, WiaImgFmt_BMP))
  72. {
  73. lNewSize += sizeof(BITMAPFILEHEADER);
  74. }
  75. //
  76. // Calculate number of bytes per line, width must be
  77. // aligned to 4 byte boundary.
  78. //
  79. lWidthInBytes = ((lWidth * lDepth + 31) & ~31) / 8;
  80. //
  81. // Calculate image size
  82. //
  83. lNewSize += lWidthInBytes * lHeight;
  84. //
  85. // Set the extension property
  86. //
  87. if (pwszExt) {
  88. bstrExt = SysAllocString(L"BMP");
  89. REQUIRE_ALLOC(bstrExt, hr, "wiauSetImageItemSize");
  90. }
  91. }
  92. else
  93. {
  94. lNewSize = lSize;
  95. lWidthInBytes = 0;
  96. //
  97. // Set the extension property
  98. //
  99. if (pwszExt) {
  100. bstrExt = SysAllocString(pwszExt);
  101. REQUIRE_ALLOC(bstrExt, hr, "wiauSetImageItemSize");
  102. }
  103. }
  104. //
  105. // Initialize propvar's. Then write the values. Don't need to call
  106. // PropVariantClear when done, since no memory was allocated.
  107. //
  108. if (bstrExt)
  109. lNumProperties++;
  110. for (int i = 0; i < lNumProperties; i++) {
  111. PropVariantInit(&pv[i]);
  112. }
  113. pv[0].vt = VT_I4;
  114. pv[0].lVal = lNewSize;
  115. pv[1].vt = VT_I4;
  116. pv[1].lVal = lWidthInBytes;
  117. pv[2].vt = VT_BSTR;
  118. pv[2].bstrVal = bstrExt;
  119. //
  120. // Write WIA_IPA_ITEM_SIZE and WIA_IPA_BYTES_PER_LINE property values
  121. //
  122. hr = wiasWriteMultiple(pWiasContext, lNumProperties, ps, pv);
  123. REQUIRE_SUCCESS(hr, "wiauSetImageItemSize", "wiasWriteMultiple failed");
  124. Cleanup:
  125. if (bstrExt)
  126. SysFreeString(bstrExt);
  127. return hr;
  128. }
  129. /**************************************************************************\
  130. * wiauPropsInPropSpec
  131. \**************************************************************************/
  132. BOOL wiauPropsInPropSpec(LONG NumPropSpecs, const PROPSPEC *pPropSpecs,
  133. int NumProps, PROPID *pProps)
  134. {
  135. for (int count = 0; count < NumProps; count++)
  136. if (wiauPropInPropSpec(NumPropSpecs, pPropSpecs, pProps[count]))
  137. return TRUE;
  138. return FALSE;
  139. }
  140. /**************************************************************************\
  141. * wiauPropInPropSpec
  142. \**************************************************************************/
  143. BOOL wiauPropInPropSpec(LONG NumPropSpecs, const PROPSPEC *pPropSpecs,
  144. PROPID PropId, int *pIdx)
  145. {
  146. for (int count = 0; count < NumPropSpecs; count++)
  147. if (pPropSpecs[count].propid == PropId)
  148. {
  149. if (pIdx)
  150. *pIdx = count;
  151. return TRUE;
  152. }
  153. return FALSE;
  154. }
  155. /**************************************************************************\
  156. * wiauGetValidFormats
  157. \**************************************************************************/
  158. HRESULT wiauGetValidFormats(IWiaMiniDrv *pDrv, BYTE *pWiasContext, LONG TymedValue,
  159. int *pNumFormats, GUID **ppFormatArray)
  160. {
  161. HRESULT hr = S_OK;
  162. LONG NumFi = 0;
  163. WIA_FORMAT_INFO *pFiArray = NULL;
  164. LONG lErrVal = 0;
  165. GUID *pFA = NULL;
  166. REQUIRE_ARGS(!ppFormatArray || !pNumFormats, hr, "wiauGetValidFormats");
  167. *ppFormatArray = NULL;
  168. *pNumFormats = 0;
  169. hr = pDrv->drvGetWiaFormatInfo(pWiasContext, 0, &NumFi, &pFiArray, &lErrVal);
  170. REQUIRE_SUCCESS(hr, "wiauGetValidFormats", "drvGetWiaFormatInfo failed");
  171. //
  172. // This will allocate more spots than necessary, but pNumFormats will be set correctly
  173. //
  174. pFA = new GUID[NumFi];
  175. REQUIRE_ALLOC(pFA, hr, "wiauGetValidFormats");
  176. for (int count = 0; count < NumFi; count++)
  177. {
  178. if (pFiArray[count].lTymed == TymedValue)
  179. {
  180. pFA[*pNumFormats] = pFiArray[count].guidFormatID;
  181. (*pNumFormats)++;
  182. }
  183. }
  184. *ppFormatArray = pFA;
  185. Cleanup:
  186. return hr;
  187. }
  188. /**************************************************************************\
  189. * wiauGetResourceString
  190. \**************************************************************************/
  191. HRESULT wiauGetResourceString(HINSTANCE hInst, LONG lResourceID, BSTR *pbstrStr)
  192. {
  193. DBG_FN("GetResourceString");
  194. HRESULT hr = S_OK;
  195. //
  196. // Locals
  197. //
  198. INT iLen = 0;
  199. TCHAR tszTempStr[MAX_PATH] = TEXT("");
  200. WCHAR wszTempStr[MAX_PATH] = L"";
  201. REQUIRE_ARGS(!pbstrStr, hr, "GetResourceString");
  202. *pbstrStr = NULL;
  203. //
  204. // Get the string from the resource
  205. //
  206. iLen = LoadString(hInst, lResourceID, tszTempStr, MAX_PATH);
  207. REQUIRE_FILEIO(iLen, hr, "GetResourceString", "LoadString failed");
  208. hr = wiauStrT2W(tszTempStr, wszTempStr, sizeof(wszTempStr));
  209. REQUIRE_SUCCESS(hr, "GetResourceString", "wiauStrT2W failed");
  210. //
  211. // Caller must free this allocated BSTR
  212. //
  213. *pbstrStr = SysAllocString(wszTempStr);
  214. REQUIRE_ALLOC(*pbstrStr, hr, "GetResourceString");
  215. Cleanup:
  216. return hr;
  217. }
  218. /**************************************************************************\
  219. * wiauRegOpenDataW
  220. \**************************************************************************/
  221. HRESULT wiauRegOpenDataW(HKEY hkeyAncestor, HKEY *phkeyDeviceData)
  222. {
  223. DBG_FN("wiauRegOpenDataW");
  224. HRESULT hr = S_OK;
  225. //
  226. // Locals
  227. //
  228. LONG lReturn = 0;
  229. REQUIRE_ARGS(!hkeyAncestor || !phkeyDeviceData, hr, "wiauRegOpenDataW");
  230. lReturn = ::RegOpenKeyExW(hkeyAncestor, L"DeviceData", 0, KEY_READ, phkeyDeviceData);
  231. REQUIRE_WIN32(lReturn, hr, "wiauRegOpenDataW", "RegOpenKeyExW failed");
  232. Cleanup:
  233. return hr;
  234. }
  235. /**************************************************************************\
  236. * wiauRegOpenDataA
  237. \**************************************************************************/
  238. HRESULT wiauRegOpenDataA(HKEY hkeyAncestor, HKEY *phkeyDeviceData)
  239. {
  240. DBG_FN("wiauRegOpenDataA");
  241. HRESULT hr = S_OK;
  242. //
  243. // Locals
  244. //
  245. LONG lReturn = 0;
  246. REQUIRE_ARGS(!hkeyAncestor || !phkeyDeviceData, hr, "wiauRegOpenDataA");
  247. lReturn = ::RegOpenKeyExA(hkeyAncestor, "DeviceData", 0, KEY_READ, phkeyDeviceData);
  248. REQUIRE_WIN32(lReturn, hr, "wiauRegOpenDataA", "RegOpenKeyExA failed");
  249. Cleanup:
  250. return hr;
  251. }
  252. /**************************************************************************\
  253. * wiauRegGetStrW
  254. \**************************************************************************/
  255. HRESULT wiauRegGetStrW(HKEY hkKey, PCWSTR pwszValueName, PWSTR pwszValue, DWORD *pdwLength)
  256. {
  257. DBG_FN("wiauRegGetStrW");
  258. HRESULT hr = S_OK;
  259. //
  260. // Locals
  261. //
  262. LONG lReturn = 0;
  263. DWORD dwType = 0;
  264. REQUIRE_ARGS(!hkKey || !pwszValueName || !pwszValue || !pdwLength, hr, "wiauRegGetStrW");
  265. lReturn = ::RegQueryValueExW(hkKey, pwszValueName, NULL, &dwType, (BYTE *) pwszValue, pdwLength);
  266. REQUIRE_WIN32(lReturn, hr, "wiauRegGetStrW", "RegQueryValueExW failed");
  267. if ((dwType != REG_SZ) &&
  268. (dwType != REG_EXPAND_SZ) &&
  269. (dwType != REG_MULTI_SZ)) {
  270. wiauDbgError("wiauRegGetStrW", "ReqQueryValueEx returned wrong type for key, %d", dwType);
  271. hr = E_FAIL;
  272. goto Cleanup;
  273. }
  274. Cleanup:
  275. return hr;
  276. }
  277. /**************************************************************************\
  278. * wiauRegGetStrA
  279. \**************************************************************************/
  280. HRESULT wiauRegGetStrA(HKEY hkKey, PCSTR pszValueName, PSTR pszValue, DWORD *pdwLength)
  281. {
  282. DBG_FN("wiauRegGetStrA");
  283. HRESULT hr = S_OK;
  284. //
  285. // Locals
  286. //
  287. LONG lReturn = 0;
  288. DWORD dwType = 0;
  289. REQUIRE_ARGS(!hkKey || !pszValueName || !pszValue || !pdwLength, hr, "wiauRegGetStrA");
  290. lReturn = ::RegQueryValueExA(hkKey, pszValueName, NULL, &dwType, (BYTE *) pszValue, pdwLength);
  291. REQUIRE_WIN32(lReturn, hr, "wiauRegGetStrA", "RegQueryValueExA failed");
  292. if ((dwType != REG_SZ) &&
  293. (dwType != REG_EXPAND_SZ) &&
  294. (dwType != REG_MULTI_SZ)) {
  295. wiauDbgError("wiauRegGetStrA", "ReqQueryValueEx returned wrong type for key, %d", dwType);
  296. hr = E_FAIL;
  297. goto Cleanup;
  298. }
  299. Cleanup:
  300. return hr;
  301. }
  302. /**************************************************************************\
  303. * wiauRegGetDwordW
  304. \**************************************************************************/
  305. HRESULT wiauRegGetDwordW(HKEY hkKey, PCTSTR pwszValueName, DWORD *pdwValue)
  306. {
  307. DBG_FN("wiauRegGetDwordW");
  308. HRESULT hr = S_OK;
  309. //
  310. // Locals
  311. //
  312. LONG lReturn = 0;
  313. DWORD dwType = 0;
  314. DWORD dwLength = sizeof(*pdwValue);
  315. REQUIRE_ARGS(!hkKey || !pwszValueName || !pdwValue, hr, "wiauRegGetDwordW");
  316. lReturn = ::RegQueryValueExW(hkKey, pwszValueName, NULL, &dwType, (BYTE *) pdwValue, &dwLength);
  317. REQUIRE_WIN32(lReturn, hr, "wiauRegGetDwordW", "RegQueryValueExW failed");
  318. if (dwType != REG_DWORD) {
  319. wiauDbgError("wiauRegGetDwordW", "ReqQueryValueEx returned wrong type for key, %d", dwType);
  320. hr = E_FAIL;
  321. goto Cleanup;
  322. }
  323. Cleanup:
  324. return hr;
  325. }
  326. /**************************************************************************\
  327. * wiauRegGetDwordA
  328. \**************************************************************************/
  329. HRESULT wiauRegGetDwordA(HKEY hkKey, PCSTR pszValueName, DWORD *pdwValue)
  330. {
  331. DBG_FN("wiauRegGetDwordA");
  332. HRESULT hr = S_OK;
  333. //
  334. // Locals
  335. //
  336. LONG lReturn = 0;
  337. DWORD dwType = 0;
  338. DWORD dwLength = sizeof(*pdwValue);
  339. REQUIRE_ARGS(!hkKey || !pszValueName || !pdwValue, hr, "wiauRegGetDword");
  340. lReturn = ::RegQueryValueExA(hkKey, pszValueName, NULL, &dwType, (BYTE *) pdwValue, &dwLength);
  341. REQUIRE_WIN32(lReturn, hr, "wiauRegGetDwordA", "RegQueryValueExA failed");
  342. if (dwType != REG_DWORD) {
  343. wiauDbgError("wiauRegGetDwordA", "ReqQueryValueExA returned wrong type for key, %d", dwType);
  344. hr = E_FAIL;
  345. goto Cleanup;
  346. }
  347. Cleanup:
  348. return hr;
  349. }
  350. /**************************************************************************\
  351. * wiauStrW2C
  352. \**************************************************************************/
  353. HRESULT wiauStrW2C(WCHAR *pwszSrc, CHAR *pszDst, INT iSize)
  354. {
  355. HRESULT hr = S_OK;
  356. INT iWritten = 0;
  357. REQUIRE_ARGS(!pwszSrc || !pszDst || iSize < 1, hr, "wiauStrW2C");
  358. iWritten = WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, pszDst, iSize, NULL, NULL);
  359. REQUIRE_FILEIO(iWritten != 0, hr, "wiauStrW2C", "WideCharToMultiByte failed");
  360. Cleanup:
  361. return hr;
  362. }
  363. /**************************************************************************\
  364. * wiauStrC2W
  365. \**************************************************************************/
  366. HRESULT wiauStrC2W(CHAR *pszSrc, WCHAR *pwszDst, INT iSize)
  367. {
  368. HRESULT hr = S_OK;
  369. INT iWritten = 0;
  370. REQUIRE_ARGS(!pszSrc || !pwszDst || iSize < 1, hr, "wiauStrC2W");
  371. iWritten = MultiByteToWideChar(CP_ACP, 0, pszSrc, -1, pwszDst, iSize / sizeof(*pwszDst));
  372. REQUIRE_FILEIO(iWritten != 0, hr, "wiauStrC2W", "MultiByteToWideChar failed");
  373. Cleanup:
  374. return hr;
  375. }
  376. /**************************************************************************\
  377. * wiauStrW2W
  378. \**************************************************************************/
  379. HRESULT wiauStrW2W(WCHAR *pwszSrc, WCHAR *pwszDst, INT iSize)
  380. {
  381. HRESULT hr = S_OK;
  382. REQUIRE_ARGS(!pwszSrc || !pwszDst || iSize < 1, hr, "wiauStrW2W");
  383. if ((lstrlenW(pwszSrc) + 1) > (iSize / (INT) sizeof(*pwszDst))) {
  384. hr = ERROR_INSUFFICIENT_BUFFER;
  385. goto Cleanup;
  386. }
  387. lstrcpyW(pwszDst, pwszSrc);
  388. Cleanup:
  389. return hr;
  390. }
  391. /**************************************************************************\
  392. * wiauStrC2C
  393. \**************************************************************************/
  394. HRESULT wiauStrC2C(CHAR *pszSrc, CHAR *pszDst, INT iSize)
  395. {
  396. HRESULT hr = S_OK;
  397. REQUIRE_ARGS(!pszSrc || !pszDst || iSize < 1, hr, "wiauStrC2C");
  398. if ((lstrlenA(pszSrc) + 1) > iSize) {
  399. hr = ERROR_INSUFFICIENT_BUFFER;
  400. goto Cleanup;
  401. }
  402. lstrcpyA(pszDst, pszSrc);
  403. Cleanup:
  404. return hr;
  405. }