windows-nt/Source/XPSP1/NT/printscan/wia/drivers/util/other.cpp
2020-09-26 16:20:57 +08:00

536 lines
14 KiB
C++

/*++
Copyright (C) 2000 Microsoft Corporation
Module Name:
gdipconv.cpp
Abstract:
Helper functions for using GDI+ to convert image formats
Author:
DavePar
Revision History:
--*/
#include "pch.h"
/**************************************************************************\
* wiauGetDrvItemContext
\**************************************************************************/
HRESULT wiauGetDrvItemContext(BYTE *pWiasContext, VOID **ppItemCtx, IWiaDrvItem **ppDrvItem)
{
HRESULT hr = S_OK;
//
// Locals
//
IWiaDrvItem *pWiaDrvItem = NULL;
REQUIRE_ARGS(!pWiasContext || !ppItemCtx, hr, "wiauGetDrvItemContext");
*ppItemCtx = NULL;
if (ppDrvItem)
*ppDrvItem = NULL;
hr = wiasGetDrvItem(pWiasContext, &pWiaDrvItem);
REQUIRE_SUCCESS(hr, "wiauGetDrvItemContext", "wiasGetDrvItem failed");
hr = pWiaDrvItem->GetDeviceSpecContext((BYTE **) ppItemCtx);
REQUIRE_SUCCESS(hr, "wiauGetDrvItemContext", "GetDeviceSpecContext failed");
if (!*ppItemCtx)
{
wiauDbgError("wiauGetDrvItemContext", "Item context is null");
hr = E_FAIL;
goto Cleanup;
}
if (ppDrvItem)
{
*ppDrvItem = pWiaDrvItem;
}
Cleanup:
return hr;
}
/**************************************************************************\
* wiauSetImageItemSize
\**************************************************************************/
HRESULT wiauSetImageItemSize(BYTE *pWiasContext, LONG lWidth, LONG lHeight,
LONG lDepth, LONG lSize, PWSTR pwszExt)
{
HRESULT hr = S_OK;
LONG lNewSize = 0;
LONG lWidthInBytes = 0;
GUID guidFormatID = GUID_NULL;
BSTR bstrExt = NULL;
LONG lNumProperties = 2;
PROPVARIANT pv[3];
PROPSPEC ps[3] = {{PRSPEC_PROPID, WIA_IPA_ITEM_SIZE},
{PRSPEC_PROPID, WIA_IPA_BYTES_PER_LINE},
{PRSPEC_PROPID, WIA_IPA_FILENAME_EXTENSION}};
//
// Read the current format GUID
//
hr = wiasReadPropGuid(pWiasContext, WIA_IPA_FORMAT, &guidFormatID, NULL, TRUE);
REQUIRE_SUCCESS(hr, "wiauSetImageItemSize", "wiasReadPropGuid failed");
if (IsEqualCLSID(guidFormatID, WiaImgFmt_BMP) ||
IsEqualCLSID(guidFormatID, WiaImgFmt_MEMORYBMP))
{
lNewSize = sizeof(BITMAPINFOHEADER);
//
// if this is a file, add file header to size
//
if (IsEqualCLSID(guidFormatID, WiaImgFmt_BMP))
{
lNewSize += sizeof(BITMAPFILEHEADER);
}
//
// Calculate number of bytes per line, width must be
// aligned to 4 byte boundary.
//
lWidthInBytes = ((lWidth * lDepth + 31) & ~31) / 8;
//
// Calculate image size
//
lNewSize += lWidthInBytes * lHeight;
//
// Set the extension property
//
if (pwszExt) {
bstrExt = SysAllocString(L"BMP");
REQUIRE_ALLOC(bstrExt, hr, "wiauSetImageItemSize");
}
}
else
{
lNewSize = lSize;
lWidthInBytes = 0;
//
// Set the extension property
//
if (pwszExt) {
bstrExt = SysAllocString(pwszExt);
REQUIRE_ALLOC(bstrExt, hr, "wiauSetImageItemSize");
}
}
//
// Initialize propvar's. Then write the values. Don't need to call
// PropVariantClear when done, since no memory was allocated.
//
if (bstrExt)
lNumProperties++;
for (int i = 0; i < lNumProperties; i++) {
PropVariantInit(&pv[i]);
}
pv[0].vt = VT_I4;
pv[0].lVal = lNewSize;
pv[1].vt = VT_I4;
pv[1].lVal = lWidthInBytes;
pv[2].vt = VT_BSTR;
pv[2].bstrVal = bstrExt;
//
// Write WIA_IPA_ITEM_SIZE and WIA_IPA_BYTES_PER_LINE property values
//
hr = wiasWriteMultiple(pWiasContext, lNumProperties, ps, pv);
REQUIRE_SUCCESS(hr, "wiauSetImageItemSize", "wiasWriteMultiple failed");
Cleanup:
if (bstrExt)
SysFreeString(bstrExt);
return hr;
}
/**************************************************************************\
* wiauPropsInPropSpec
\**************************************************************************/
BOOL wiauPropsInPropSpec(LONG NumPropSpecs, const PROPSPEC *pPropSpecs,
int NumProps, PROPID *pProps)
{
for (int count = 0; count < NumProps; count++)
if (wiauPropInPropSpec(NumPropSpecs, pPropSpecs, pProps[count]))
return TRUE;
return FALSE;
}
/**************************************************************************\
* wiauPropInPropSpec
\**************************************************************************/
BOOL wiauPropInPropSpec(LONG NumPropSpecs, const PROPSPEC *pPropSpecs,
PROPID PropId, int *pIdx)
{
for (int count = 0; count < NumPropSpecs; count++)
if (pPropSpecs[count].propid == PropId)
{
if (pIdx)
*pIdx = count;
return TRUE;
}
return FALSE;
}
/**************************************************************************\
* wiauGetValidFormats
\**************************************************************************/
HRESULT wiauGetValidFormats(IWiaMiniDrv *pDrv, BYTE *pWiasContext, LONG TymedValue,
int *pNumFormats, GUID **ppFormatArray)
{
HRESULT hr = S_OK;
LONG NumFi = 0;
WIA_FORMAT_INFO *pFiArray = NULL;
LONG lErrVal = 0;
GUID *pFA = NULL;
REQUIRE_ARGS(!ppFormatArray || !pNumFormats, hr, "wiauGetValidFormats");
*ppFormatArray = NULL;
*pNumFormats = 0;
hr = pDrv->drvGetWiaFormatInfo(pWiasContext, 0, &NumFi, &pFiArray, &lErrVal);
REQUIRE_SUCCESS(hr, "wiauGetValidFormats", "drvGetWiaFormatInfo failed");
//
// This will allocate more spots than necessary, but pNumFormats will be set correctly
//
pFA = new GUID[NumFi];
REQUIRE_ALLOC(pFA, hr, "wiauGetValidFormats");
for (int count = 0; count < NumFi; count++)
{
if (pFiArray[count].lTymed == TymedValue)
{
pFA[*pNumFormats] = pFiArray[count].guidFormatID;
(*pNumFormats)++;
}
}
*ppFormatArray = pFA;
Cleanup:
return hr;
}
/**************************************************************************\
* wiauGetResourceString
\**************************************************************************/
HRESULT wiauGetResourceString(HINSTANCE hInst, LONG lResourceID, BSTR *pbstrStr)
{
DBG_FN("GetResourceString");
HRESULT hr = S_OK;
//
// Locals
//
INT iLen = 0;
TCHAR tszTempStr[MAX_PATH] = TEXT("");
WCHAR wszTempStr[MAX_PATH] = L"";
REQUIRE_ARGS(!pbstrStr, hr, "GetResourceString");
*pbstrStr = NULL;
//
// Get the string from the resource
//
iLen = LoadString(hInst, lResourceID, tszTempStr, MAX_PATH);
REQUIRE_FILEIO(iLen, hr, "GetResourceString", "LoadString failed");
hr = wiauStrT2W(tszTempStr, wszTempStr, sizeof(wszTempStr));
REQUIRE_SUCCESS(hr, "GetResourceString", "wiauStrT2W failed");
//
// Caller must free this allocated BSTR
//
*pbstrStr = SysAllocString(wszTempStr);
REQUIRE_ALLOC(*pbstrStr, hr, "GetResourceString");
Cleanup:
return hr;
}
/**************************************************************************\
* wiauRegOpenDataW
\**************************************************************************/
HRESULT wiauRegOpenDataW(HKEY hkeyAncestor, HKEY *phkeyDeviceData)
{
DBG_FN("wiauRegOpenDataW");
HRESULT hr = S_OK;
//
// Locals
//
LONG lReturn = 0;
REQUIRE_ARGS(!hkeyAncestor || !phkeyDeviceData, hr, "wiauRegOpenDataW");
lReturn = ::RegOpenKeyExW(hkeyAncestor, L"DeviceData", 0, KEY_READ, phkeyDeviceData);
REQUIRE_WIN32(lReturn, hr, "wiauRegOpenDataW", "RegOpenKeyExW failed");
Cleanup:
return hr;
}
/**************************************************************************\
* wiauRegOpenDataA
\**************************************************************************/
HRESULT wiauRegOpenDataA(HKEY hkeyAncestor, HKEY *phkeyDeviceData)
{
DBG_FN("wiauRegOpenDataA");
HRESULT hr = S_OK;
//
// Locals
//
LONG lReturn = 0;
REQUIRE_ARGS(!hkeyAncestor || !phkeyDeviceData, hr, "wiauRegOpenDataA");
lReturn = ::RegOpenKeyExA(hkeyAncestor, "DeviceData", 0, KEY_READ, phkeyDeviceData);
REQUIRE_WIN32(lReturn, hr, "wiauRegOpenDataA", "RegOpenKeyExA failed");
Cleanup:
return hr;
}
/**************************************************************************\
* wiauRegGetStrW
\**************************************************************************/
HRESULT wiauRegGetStrW(HKEY hkKey, PCWSTR pwszValueName, PWSTR pwszValue, DWORD *pdwLength)
{
DBG_FN("wiauRegGetStrW");
HRESULT hr = S_OK;
//
// Locals
//
LONG lReturn = 0;
DWORD dwType = 0;
REQUIRE_ARGS(!hkKey || !pwszValueName || !pwszValue || !pdwLength, hr, "wiauRegGetStrW");
lReturn = ::RegQueryValueExW(hkKey, pwszValueName, NULL, &dwType, (BYTE *) pwszValue, pdwLength);
REQUIRE_WIN32(lReturn, hr, "wiauRegGetStrW", "RegQueryValueExW failed");
if ((dwType != REG_SZ) &&
(dwType != REG_EXPAND_SZ) &&
(dwType != REG_MULTI_SZ)) {
wiauDbgError("wiauRegGetStrW", "ReqQueryValueEx returned wrong type for key, %d", dwType);
hr = E_FAIL;
goto Cleanup;
}
Cleanup:
return hr;
}
/**************************************************************************\
* wiauRegGetStrA
\**************************************************************************/
HRESULT wiauRegGetStrA(HKEY hkKey, PCSTR pszValueName, PSTR pszValue, DWORD *pdwLength)
{
DBG_FN("wiauRegGetStrA");
HRESULT hr = S_OK;
//
// Locals
//
LONG lReturn = 0;
DWORD dwType = 0;
REQUIRE_ARGS(!hkKey || !pszValueName || !pszValue || !pdwLength, hr, "wiauRegGetStrA");
lReturn = ::RegQueryValueExA(hkKey, pszValueName, NULL, &dwType, (BYTE *) pszValue, pdwLength);
REQUIRE_WIN32(lReturn, hr, "wiauRegGetStrA", "RegQueryValueExA failed");
if ((dwType != REG_SZ) &&
(dwType != REG_EXPAND_SZ) &&
(dwType != REG_MULTI_SZ)) {
wiauDbgError("wiauRegGetStrA", "ReqQueryValueEx returned wrong type for key, %d", dwType);
hr = E_FAIL;
goto Cleanup;
}
Cleanup:
return hr;
}
/**************************************************************************\
* wiauRegGetDwordW
\**************************************************************************/
HRESULT wiauRegGetDwordW(HKEY hkKey, PCTSTR pwszValueName, DWORD *pdwValue)
{
DBG_FN("wiauRegGetDwordW");
HRESULT hr = S_OK;
//
// Locals
//
LONG lReturn = 0;
DWORD dwType = 0;
DWORD dwLength = sizeof(*pdwValue);
REQUIRE_ARGS(!hkKey || !pwszValueName || !pdwValue, hr, "wiauRegGetDwordW");
lReturn = ::RegQueryValueExW(hkKey, pwszValueName, NULL, &dwType, (BYTE *) pdwValue, &dwLength);
REQUIRE_WIN32(lReturn, hr, "wiauRegGetDwordW", "RegQueryValueExW failed");
if (dwType != REG_DWORD) {
wiauDbgError("wiauRegGetDwordW", "ReqQueryValueEx returned wrong type for key, %d", dwType);
hr = E_FAIL;
goto Cleanup;
}
Cleanup:
return hr;
}
/**************************************************************************\
* wiauRegGetDwordA
\**************************************************************************/
HRESULT wiauRegGetDwordA(HKEY hkKey, PCSTR pszValueName, DWORD *pdwValue)
{
DBG_FN("wiauRegGetDwordA");
HRESULT hr = S_OK;
//
// Locals
//
LONG lReturn = 0;
DWORD dwType = 0;
DWORD dwLength = sizeof(*pdwValue);
REQUIRE_ARGS(!hkKey || !pszValueName || !pdwValue, hr, "wiauRegGetDword");
lReturn = ::RegQueryValueExA(hkKey, pszValueName, NULL, &dwType, (BYTE *) pdwValue, &dwLength);
REQUIRE_WIN32(lReturn, hr, "wiauRegGetDwordA", "RegQueryValueExA failed");
if (dwType != REG_DWORD) {
wiauDbgError("wiauRegGetDwordA", "ReqQueryValueExA returned wrong type for key, %d", dwType);
hr = E_FAIL;
goto Cleanup;
}
Cleanup:
return hr;
}
/**************************************************************************\
* wiauStrW2C
\**************************************************************************/
HRESULT wiauStrW2C(WCHAR *pwszSrc, CHAR *pszDst, INT iSize)
{
HRESULT hr = S_OK;
INT iWritten = 0;
REQUIRE_ARGS(!pwszSrc || !pszDst || iSize < 1, hr, "wiauStrW2C");
iWritten = WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, pszDst, iSize, NULL, NULL);
REQUIRE_FILEIO(iWritten != 0, hr, "wiauStrW2C", "WideCharToMultiByte failed");
Cleanup:
return hr;
}
/**************************************************************************\
* wiauStrC2W
\**************************************************************************/
HRESULT wiauStrC2W(CHAR *pszSrc, WCHAR *pwszDst, INT iSize)
{
HRESULT hr = S_OK;
INT iWritten = 0;
REQUIRE_ARGS(!pszSrc || !pwszDst || iSize < 1, hr, "wiauStrC2W");
iWritten = MultiByteToWideChar(CP_ACP, 0, pszSrc, -1, pwszDst, iSize / sizeof(*pwszDst));
REQUIRE_FILEIO(iWritten != 0, hr, "wiauStrC2W", "MultiByteToWideChar failed");
Cleanup:
return hr;
}
/**************************************************************************\
* wiauStrW2W
\**************************************************************************/
HRESULT wiauStrW2W(WCHAR *pwszSrc, WCHAR *pwszDst, INT iSize)
{
HRESULT hr = S_OK;
REQUIRE_ARGS(!pwszSrc || !pwszDst || iSize < 1, hr, "wiauStrW2W");
if ((lstrlenW(pwszSrc) + 1) > (iSize / (INT) sizeof(*pwszDst))) {
hr = ERROR_INSUFFICIENT_BUFFER;
goto Cleanup;
}
lstrcpyW(pwszDst, pwszSrc);
Cleanup:
return hr;
}
/**************************************************************************\
* wiauStrC2C
\**************************************************************************/
HRESULT wiauStrC2C(CHAR *pszSrc, CHAR *pszDst, INT iSize)
{
HRESULT hr = S_OK;
REQUIRE_ARGS(!pszSrc || !pszDst || iSize < 1, hr, "wiauStrC2C");
if ((lstrlenA(pszSrc) + 1) > iSize) {
hr = ERROR_INSUFFICIENT_BUFFER;
goto Cleanup;
}
lstrcpyA(pszDst, pszSrc);
Cleanup:
return hr;
}