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.
301 lines
7.5 KiB
301 lines
7.5 KiB
#include "pch.h"
|
|
#include "thisdll.h"
|
|
|
|
PSTR DuplicateWideStringAsMultibyte(LPCWSTR pwszSource)
|
|
{
|
|
PSTR pszVal;
|
|
// Get the size required.
|
|
int cch = WideCharToMultiByte(CP_ACP, 0, pwszSource, -1, NULL, 0, NULL, NULL);
|
|
if (cch)
|
|
{
|
|
pszVal = (PSTR)CoTaskMemAlloc(cch*sizeof(CHAR));
|
|
if (pszVal)
|
|
{
|
|
cch = WideCharToMultiByte(CP_ACP, 0, pwszSource, -1, pszVal, cch, NULL, NULL);
|
|
return pszVal;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
HRESULT CoerceProperty(PROPVARIANT *pvar, VARTYPE vt)
|
|
{
|
|
BSTR bstr;
|
|
HRESULT hr;
|
|
switch (vt)
|
|
{
|
|
case VT_BSTR:
|
|
switch (pvar->vt)
|
|
{
|
|
case VT_LPSTR:
|
|
UINT cch;
|
|
cch = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pvar->pszVal, -1, NULL, 0);
|
|
// cch is required buffer size in WCHARs, including NULL terminator.
|
|
// SysAllocStringLen takes buffer size in WCHARs, *excluding* NULL terminator, and allocates one WCHAR extra.
|
|
bstr = SysAllocStringLen(NULL, cch - 1);
|
|
if (bstr != NULL)
|
|
{
|
|
cch = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pvar->pszVal, -1, bstr, cch);
|
|
PropVariantClear(pvar);
|
|
pvar->vt=VT_BSTR;
|
|
pvar->bstrVal = bstr;
|
|
hr = S_OK;
|
|
}
|
|
else
|
|
{
|
|
hr = E_FAIL;
|
|
}
|
|
break;
|
|
|
|
case VT_LPWSTR:
|
|
bstr = SysAllocString(pvar->pwszVal);
|
|
if (bstr!=NULL)
|
|
{
|
|
PropVariantClear(pvar);
|
|
pvar->vt = VT_BSTR;
|
|
pvar->bstrVal = bstr;
|
|
hr = S_OK;
|
|
}
|
|
else
|
|
{
|
|
hr = E_FAIL;
|
|
}
|
|
break;
|
|
|
|
case VT_BSTR:
|
|
hr = S_OK;
|
|
break;
|
|
|
|
default:
|
|
hr = E_FAIL;
|
|
break;;
|
|
}
|
|
break;
|
|
|
|
case VT_UI4:
|
|
hr = S_OK;
|
|
switch (pvar->vt)
|
|
{
|
|
case VT_UI2:
|
|
pvar->vt = VT_UI4;
|
|
pvar->ulVal &= 0xffff;
|
|
break;
|
|
|
|
case VT_UI4:
|
|
break;
|
|
|
|
case VT_UI8:
|
|
//note that we lose the high order DWORD
|
|
pvar->vt = VT_UI4;
|
|
pvar->uhVal.HighPart = 0;
|
|
pvar->ulVal = pvar->uhVal.LowPart;
|
|
break;
|
|
|
|
default:
|
|
hr = E_FAIL;
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case VT_UI8:
|
|
hr = S_OK;
|
|
switch (pvar->vt)
|
|
{
|
|
case VT_UI2:
|
|
pvar->vt = VT_UI8;
|
|
pvar->uhVal.LowPart = pvar->uiVal & 0xffff;
|
|
break;
|
|
|
|
case VT_UI4:
|
|
pvar->vt = VT_UI8;
|
|
pvar->uhVal.LowPart = pvar->ulVal;
|
|
pvar->uhVal.HighPart = 0;
|
|
break;
|
|
|
|
case VT_UI8:
|
|
break;
|
|
|
|
default:
|
|
hr = E_FAIL;
|
|
break;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
hr = E_FAIL;
|
|
break;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT WMTFromPropVariant(BYTE *buffer, WORD *cbLen, WMT_ATTR_DATATYPE *pdatatype, PROPVARIANT *pvar)
|
|
{
|
|
HRESULT hr;
|
|
int cch;
|
|
switch (pvar->vt)
|
|
{
|
|
case VT_BSTR:
|
|
case VT_LPWSTR:
|
|
cch = *cbLen / sizeof(WCHAR); // Max number of chars we can put in the BYTE buffer
|
|
hr = StringCchCopy((LPWSTR)buffer, cch, (pvar->bstrVal == NULL) ? L"" : pvar->bstrVal);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
*pdatatype = WMT_TYPE_STRING;
|
|
*cbLen = (WORD)(lstrlen((LPWSTR)buffer)+1) * sizeof(WCHAR);
|
|
}
|
|
break;
|
|
|
|
case VT_LPSTR:
|
|
cch = MultiByteToWideChar(CP_ACP, 0, pvar->pszVal, -1, (LPWSTR)buffer, (*cbLen) / sizeof(WCHAR));
|
|
if (cch == 0)
|
|
{
|
|
hr = E_FAIL;
|
|
}
|
|
else
|
|
{
|
|
*pdatatype = WMT_TYPE_STRING;
|
|
*cbLen = (WORD)cch * sizeof(WCHAR);
|
|
hr = S_OK;
|
|
}
|
|
break;
|
|
|
|
case VT_UI4:
|
|
*((DWORD*)buffer) = pvar->ulVal;
|
|
*pdatatype = WMT_TYPE_DWORD;
|
|
*cbLen = sizeof(DWORD);
|
|
hr = S_OK;
|
|
break;
|
|
|
|
case VT_UI8:
|
|
*((ULONGLONG*)buffer) = pvar->hVal.QuadPart;
|
|
*pdatatype = WMT_TYPE_QWORD;
|
|
*cbLen = sizeof(ULONGLONG);
|
|
hr = S_OK;
|
|
break;
|
|
|
|
case VT_BOOL:
|
|
*pdatatype = WMT_TYPE_BOOL;
|
|
*cbLen = 4;
|
|
*((BOOL*)buffer) = pvar->boolVal;
|
|
hr = S_OK;
|
|
break;
|
|
|
|
default:
|
|
hr = E_FAIL;
|
|
break;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT PropVariantFromWMT(UCHAR *pData, WORD cbSize, WMT_ATTR_DATATYPE attrDataType, PROPVARIANT *pvar, VARTYPE vt)
|
|
{
|
|
PropVariantInit(pvar);
|
|
|
|
pvar->vt = vt;
|
|
|
|
switch (vt)
|
|
{
|
|
case VT_LPWSTR:
|
|
case VT_LPSTR:
|
|
case VT_BSTR:
|
|
{
|
|
WCHAR *pwszData, wszBuffer[32]; //Big enough to hold a wsprintf'ed 32 bit decimal
|
|
|
|
switch (attrDataType)
|
|
{
|
|
case WMT_TYPE_WORD:
|
|
case WMT_TYPE_DWORD:
|
|
{
|
|
DWORD dwVal = *((DWORD *)pData);
|
|
if (attrDataType == WMT_TYPE_WORD)
|
|
dwVal &= 0xffff;
|
|
|
|
StringCchPrintf(wszBuffer, ARRAYSIZE(wszBuffer), L"%d", dwVal);
|
|
pwszData = wszBuffer;
|
|
}
|
|
break;
|
|
|
|
case WMT_TYPE_STRING:
|
|
pwszData = cbSize ? (WCHAR*)pData : L"";
|
|
break;
|
|
|
|
default:
|
|
return E_FAIL;
|
|
}
|
|
|
|
if (!pwszData) // Deal with NULL strings
|
|
{
|
|
pvar->pwszVal = NULL;
|
|
return S_OK;
|
|
}
|
|
|
|
switch (vt)
|
|
{
|
|
case VT_LPWSTR:
|
|
return SHStrDupW(pwszData, &pvar->pwszVal);
|
|
|
|
case VT_LPSTR:
|
|
pvar->pszVal = DuplicateWideStringAsMultibyte((LPCWSTR)pData);
|
|
return pvar->pszVal ? S_OK : E_OUTOFMEMORY;
|
|
|
|
case VT_BSTR:
|
|
pvar->bstrVal = SysAllocString(pwszData);
|
|
return pvar->bstrVal ? S_OK : E_OUTOFMEMORY;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case VT_UI4:
|
|
{
|
|
if (cbSize == 0)
|
|
return E_FAIL;
|
|
|
|
DWORD dwVal = *((DWORD *)pData);
|
|
if (attrDataType == WMT_TYPE_WORD)
|
|
dwVal &= 0xffff;
|
|
|
|
switch (attrDataType)
|
|
{
|
|
case WMT_TYPE_BOOL:
|
|
case WMT_TYPE_DWORD:
|
|
case WMT_TYPE_WORD:
|
|
pvar->ulVal = dwVal;
|
|
break;
|
|
|
|
case WMT_TYPE_STRING:
|
|
StrToIntExW((WCHAR*)pData, STIF_DEFAULT, &pvar->intVal);
|
|
break;
|
|
|
|
default:
|
|
return E_FAIL;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case VT_UI8:
|
|
if (cbSize == 0)
|
|
return E_FAIL;
|
|
|
|
if (attrDataType == WMT_TYPE_QWORD)
|
|
pvar->uhVal = *((ULARGE_INTEGER *)pData);
|
|
break;
|
|
|
|
case VT_BOOL:
|
|
if (cbSize == 0)
|
|
return E_FAIL;
|
|
|
|
if (attrDataType == WMT_TYPE_BOOL)
|
|
{
|
|
pvar->boolVal = *((VARIANT_BOOL*)pData) ? VARIANT_TRUE : VARIANT_FALSE;
|
|
break;
|
|
}
|
|
|
|
default:
|
|
return E_FAIL;
|
|
}
|
|
return S_OK;
|
|
}
|
|
|