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.

540 lines
15 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. if (pPropSpecs)
  147. {
  148. for (int count = 0; count < NumPropSpecs; count++)
  149. if (pPropSpecs[count].propid == PropId)
  150. {
  151. if (pIdx)
  152. *pIdx = count;
  153. return TRUE;
  154. }
  155. }
  156. return FALSE;
  157. }
  158. /**************************************************************************\
  159. * wiauGetValidFormats
  160. \**************************************************************************/
  161. HRESULT wiauGetValidFormats(IWiaMiniDrv *pDrv, BYTE *pWiasContext, LONG TymedValue,
  162. int *pNumFormats, GUID **ppFormatArray)
  163. {
  164. HRESULT hr = S_OK;
  165. LONG NumFi = 0;
  166. WIA_FORMAT_INFO *pFiArray = NULL;
  167. LONG lErrVal = 0;
  168. GUID *pFA = NULL;
  169. REQUIRE_ARGS(!pDrv || !ppFormatArray || !pNumFormats, hr, "wiauGetValidFormats");
  170. *ppFormatArray = NULL;
  171. *pNumFormats = 0;
  172. hr = pDrv->drvGetWiaFormatInfo(pWiasContext, 0, &NumFi, &pFiArray, &lErrVal);
  173. REQUIRE_SUCCESS(hr, "wiauGetValidFormats", "drvGetWiaFormatInfo failed");
  174. //
  175. // This will allocate more spots than necessary, but pNumFormats will be set correctly
  176. //
  177. pFA = new GUID[NumFi];
  178. REQUIRE_ALLOC(pFA, hr, "wiauGetValidFormats");
  179. for (int count = 0; count < NumFi; count++)
  180. {
  181. if (pFiArray[count].lTymed == TymedValue)
  182. {
  183. pFA[*pNumFormats] = pFiArray[count].guidFormatID;
  184. (*pNumFormats)++;
  185. }
  186. }
  187. *ppFormatArray = pFA;
  188. Cleanup:
  189. return hr;
  190. }
  191. /**************************************************************************\
  192. * wiauGetResourceString
  193. \**************************************************************************/
  194. HRESULT wiauGetResourceString(HINSTANCE hInst, LONG lResourceID, BSTR *pbstrStr)
  195. {
  196. DBG_FN("GetResourceString");
  197. HRESULT hr = S_OK;
  198. //
  199. // Locals
  200. //
  201. INT iLen = 0;
  202. TCHAR tszTempStr[MAX_PATH] = TEXT("");
  203. WCHAR wszTempStr[MAX_PATH] = L"";
  204. REQUIRE_ARGS(!pbstrStr, hr, "GetResourceString");
  205. *pbstrStr = NULL;
  206. //
  207. // Get the string from the resource
  208. //
  209. iLen = LoadString(hInst, lResourceID, tszTempStr, MAX_PATH);
  210. REQUIRE_FILEIO(iLen, hr, "GetResourceString", "LoadString failed");
  211. hr = wiauStrT2W(tszTempStr, wszTempStr, sizeof(wszTempStr));
  212. REQUIRE_SUCCESS(hr, "GetResourceString", "wiauStrT2W failed");
  213. //
  214. // Caller must free this allocated BSTR
  215. //
  216. *pbstrStr = SysAllocString(wszTempStr);
  217. REQUIRE_ALLOC(*pbstrStr, hr, "GetResourceString");
  218. Cleanup:
  219. return hr;
  220. }
  221. /**************************************************************************\
  222. * wiauRegOpenDataW
  223. \**************************************************************************/
  224. HRESULT wiauRegOpenDataW(HKEY hkeyAncestor, HKEY *phkeyDeviceData)
  225. {
  226. DBG_FN("wiauRegOpenDataW");
  227. HRESULT hr = S_OK;
  228. //
  229. // Locals
  230. //
  231. LONG lReturn = 0;
  232. REQUIRE_ARGS(!hkeyAncestor || !phkeyDeviceData, hr, "wiauRegOpenDataW");
  233. lReturn = ::RegOpenKeyExW(hkeyAncestor, L"DeviceData", 0, KEY_READ, phkeyDeviceData);
  234. REQUIRE_WIN32(lReturn, hr, "wiauRegOpenDataW", "RegOpenKeyExW failed");
  235. Cleanup:
  236. return hr;
  237. }
  238. /**************************************************************************\
  239. * wiauRegOpenDataA
  240. \**************************************************************************/
  241. HRESULT wiauRegOpenDataA(HKEY hkeyAncestor, HKEY *phkeyDeviceData)
  242. {
  243. DBG_FN("wiauRegOpenDataA");
  244. HRESULT hr = S_OK;
  245. //
  246. // Locals
  247. //
  248. LONG lReturn = 0;
  249. REQUIRE_ARGS(!hkeyAncestor || !phkeyDeviceData, hr, "wiauRegOpenDataA");
  250. lReturn = ::RegOpenKeyExA(hkeyAncestor, "DeviceData", 0, KEY_READ, phkeyDeviceData);
  251. REQUIRE_WIN32(lReturn, hr, "wiauRegOpenDataA", "RegOpenKeyExA failed");
  252. Cleanup:
  253. return hr;
  254. }
  255. /**************************************************************************\
  256. * wiauRegGetStrW
  257. \**************************************************************************/
  258. HRESULT wiauRegGetStrW(HKEY hkKey, PCWSTR pwszValueName, PWSTR pwszValue, DWORD *pdwLength)
  259. {
  260. DBG_FN("wiauRegGetStrW");
  261. HRESULT hr = S_OK;
  262. //
  263. // Locals
  264. //
  265. LONG lReturn = 0;
  266. DWORD dwType = 0;
  267. REQUIRE_ARGS(!hkKey || !pwszValueName || !pwszValue || !pdwLength, hr, "wiauRegGetStrW");
  268. lReturn = ::RegQueryValueExW(hkKey, pwszValueName, NULL, &dwType, (BYTE *) pwszValue, pdwLength);
  269. REQUIRE_WIN32(lReturn, hr, "wiauRegGetStrW", "RegQueryValueExW failed");
  270. if ((dwType != REG_SZ) &&
  271. (dwType != REG_EXPAND_SZ) &&
  272. (dwType != REG_MULTI_SZ)) {
  273. wiauDbgError("wiauRegGetStrW", "ReqQueryValueEx returned wrong type for key, %d", dwType);
  274. hr = E_FAIL;
  275. goto Cleanup;
  276. }
  277. Cleanup:
  278. return hr;
  279. }
  280. /**************************************************************************\
  281. * wiauRegGetStrA
  282. \**************************************************************************/
  283. HRESULT wiauRegGetStrA(HKEY hkKey, PCSTR pszValueName, PSTR pszValue, DWORD *pdwLength)
  284. {
  285. DBG_FN("wiauRegGetStrA");
  286. HRESULT hr = S_OK;
  287. //
  288. // Locals
  289. //
  290. LONG lReturn = 0;
  291. DWORD dwType = 0;
  292. REQUIRE_ARGS(!hkKey || !pszValueName || !pszValue || !pdwLength, hr, "wiauRegGetStrA");
  293. lReturn = ::RegQueryValueExA(hkKey, pszValueName, NULL, &dwType, (BYTE *) pszValue, pdwLength);
  294. REQUIRE_WIN32(lReturn, hr, "wiauRegGetStrA", "RegQueryValueExA failed");
  295. if ((dwType != REG_SZ) &&
  296. (dwType != REG_EXPAND_SZ) &&
  297. (dwType != REG_MULTI_SZ)) {
  298. wiauDbgError("wiauRegGetStrA", "ReqQueryValueEx returned wrong type for key, %d", dwType);
  299. hr = E_FAIL;
  300. goto Cleanup;
  301. }
  302. Cleanup:
  303. return hr;
  304. }
  305. /**************************************************************************\
  306. * wiauRegGetDwordW
  307. \**************************************************************************/
  308. HRESULT wiauRegGetDwordW(HKEY hkKey, PCTSTR pwszValueName, DWORD *pdwValue)
  309. {
  310. DBG_FN("wiauRegGetDwordW");
  311. HRESULT hr = S_OK;
  312. REQUIRE_ARGS(!hkKey || !pwszValueName || !pdwValue, hr, "wiauRegGetDwordW");
  313. //
  314. // Locals
  315. //
  316. LONG lReturn = 0;
  317. DWORD dwType = 0;
  318. DWORD dwLength = sizeof(*pdwValue);
  319. lReturn = ::RegQueryValueExW(hkKey, pwszValueName, NULL, &dwType, (BYTE *) pdwValue, &dwLength);
  320. REQUIRE_WIN32(lReturn, hr, "wiauRegGetDwordW", "RegQueryValueExW failed");
  321. if (dwType != REG_DWORD) {
  322. wiauDbgError("wiauRegGetDwordW", "ReqQueryValueEx returned wrong type for key, %d", dwType);
  323. hr = E_FAIL;
  324. goto Cleanup;
  325. }
  326. Cleanup:
  327. return hr;
  328. }
  329. /**************************************************************************\
  330. * wiauRegGetDwordA
  331. \**************************************************************************/
  332. HRESULT wiauRegGetDwordA(HKEY hkKey, PCSTR pszValueName, DWORD *pdwValue)
  333. {
  334. DBG_FN("wiauRegGetDwordA");
  335. HRESULT hr = S_OK;
  336. REQUIRE_ARGS(!hkKey || !pszValueName || !pdwValue, hr, "wiauRegGetDword");
  337. //
  338. // Locals
  339. //
  340. LONG lReturn = 0;
  341. DWORD dwType = 0;
  342. DWORD dwLength = sizeof(*pdwValue);
  343. lReturn = ::RegQueryValueExA(hkKey, pszValueName, NULL, &dwType, (BYTE *) pdwValue, &dwLength);
  344. REQUIRE_WIN32(lReturn, hr, "wiauRegGetDwordA", "RegQueryValueExA failed");
  345. if (dwType != REG_DWORD) {
  346. wiauDbgError("wiauRegGetDwordA", "ReqQueryValueExA returned wrong type for key, %d", dwType);
  347. hr = E_FAIL;
  348. goto Cleanup;
  349. }
  350. Cleanup:
  351. return hr;
  352. }
  353. /**************************************************************************\
  354. * wiauStrW2C
  355. \**************************************************************************/
  356. HRESULT wiauStrW2C(WCHAR *pwszSrc, CHAR *pszDst, INT iSize)
  357. {
  358. HRESULT hr = S_OK;
  359. INT iWritten = 0;
  360. REQUIRE_ARGS(!pwszSrc || !pszDst || iSize < 1, hr, "wiauStrW2C");
  361. iWritten = WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, pszDst, iSize, NULL, NULL);
  362. REQUIRE_FILEIO(iWritten != 0, hr, "wiauStrW2C", "WideCharToMultiByte failed");
  363. Cleanup:
  364. return hr;
  365. }
  366. /**************************************************************************\
  367. * wiauStrC2W
  368. \**************************************************************************/
  369. HRESULT wiauStrC2W(CHAR *pszSrc, WCHAR *pwszDst, INT iSize)
  370. {
  371. HRESULT hr = S_OK;
  372. INT iWritten = 0;
  373. REQUIRE_ARGS(!pszSrc || !pwszDst || iSize < 1, hr, "wiauStrC2W");
  374. iWritten = MultiByteToWideChar(CP_ACP, 0, pszSrc, -1, pwszDst, iSize / sizeof(*pwszDst));
  375. REQUIRE_FILEIO(iWritten != 0, hr, "wiauStrC2W", "MultiByteToWideChar failed");
  376. Cleanup:
  377. return hr;
  378. }
  379. /**************************************************************************\
  380. * wiauStrW2W
  381. \**************************************************************************/
  382. HRESULT wiauStrW2W(WCHAR *pwszSrc, WCHAR *pwszDst, INT iSize)
  383. {
  384. HRESULT hr = S_OK;
  385. REQUIRE_ARGS(!pwszSrc || !pwszDst || iSize < 1, hr, "wiauStrW2W");
  386. if ((lstrlenW(pwszSrc) + 1) > (iSize / (INT) sizeof(*pwszDst))) {
  387. hr = ERROR_INSUFFICIENT_BUFFER;
  388. goto Cleanup;
  389. }
  390. lstrcpyW(pwszDst, pwszSrc);
  391. Cleanup:
  392. return hr;
  393. }
  394. /**************************************************************************\
  395. * wiauStrC2C
  396. \**************************************************************************/
  397. HRESULT wiauStrC2C(CHAR *pszSrc, CHAR *pszDst, INT iSize)
  398. {
  399. HRESULT hr = S_OK;
  400. REQUIRE_ARGS(!pszSrc || !pszDst || iSize < 1, hr, "wiauStrC2C");
  401. if ((lstrlenA(pszSrc) + 1) > iSize) {
  402. hr = ERROR_INSUFFICIENT_BUFFER;
  403. goto Cleanup;
  404. }
  405. lstrcpyA(pszDst, pszSrc);
  406. Cleanup:
  407. return hr;
  408. }