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.
1114 lines
26 KiB
1114 lines
26 KiB
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Microsoft Windows, Copyright (C) Microsoft Corporation, 2000
|
|
|
|
File: Utilities.cpp
|
|
|
|
Content: Implementation of CUtilities.
|
|
|
|
History: 11-15-99 dsie created
|
|
|
|
------------------------------------------------------------------------------*/
|
|
|
|
#include "stdafx.h"
|
|
#include "CAPICOM.h"
|
|
#include "Utilities.h"
|
|
|
|
#include "Common.h"
|
|
#include "Base64.h"
|
|
#include "Convert.h"
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CUtilities
|
|
//
|
|
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Function : CUtilities::GetRandom
|
|
|
|
Synopsis : Return a secure random number.
|
|
|
|
Parameter: long Length - Number of bytes to generate.
|
|
|
|
CAPICOM_ENCODING_TYPE EncodingType - Encoding type.
|
|
|
|
BSTR * pVal - Pointer to BSTR to receive the random value.
|
|
|
|
Remark :
|
|
|
|
------------------------------------------------------------------------------*/
|
|
|
|
STDMETHODIMP CUtilities::GetRandom (long Length,
|
|
CAPICOM_ENCODING_TYPE EncodingType,
|
|
BSTR * pVal)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
DWORD dwFlags = 0;
|
|
DATA_BLOB RandomData = {0, NULL};
|
|
|
|
DebugTrace("Entering CUtilities::GetRandom().\n");
|
|
|
|
try
|
|
{
|
|
//
|
|
// Lock access to this object.
|
|
//
|
|
m_Lock.Lock();
|
|
|
|
//
|
|
// Check parameter.
|
|
//
|
|
if (NULL == pVal)
|
|
{
|
|
hr = E_INVALIDARG;
|
|
|
|
DebugTrace("Error [%#x]: Parameter pVal is NULL.\n", hr);
|
|
goto ErrorExit;
|
|
}
|
|
|
|
//
|
|
// Do we have a cached provider?
|
|
//
|
|
if (!m_hCryptProv)
|
|
{
|
|
if (IsWin2KAndAbove())
|
|
{
|
|
dwFlags = CRYPT_VERIFYCONTEXT;
|
|
}
|
|
|
|
//
|
|
// Get a provider.
|
|
//
|
|
if (FAILED(hr = ::AcquireContext((LPSTR) NULL,
|
|
(LPSTR) NULL,
|
|
PROV_RSA_FULL,
|
|
dwFlags,
|
|
TRUE,
|
|
&m_hCryptProv)) &&
|
|
FAILED(hr = ::AcquireContext(MS_ENHANCED_PROV_A,
|
|
(LPSTR) NULL,
|
|
PROV_RSA_FULL,
|
|
dwFlags,
|
|
TRUE,
|
|
&m_hCryptProv)) &&
|
|
FAILED(hr = ::AcquireContext(MS_STRONG_PROV_A,
|
|
(LPSTR) NULL,
|
|
PROV_RSA_FULL,
|
|
dwFlags,
|
|
TRUE,
|
|
&m_hCryptProv)) &&
|
|
FAILED(hr = ::AcquireContext(MS_DEF_PROV_A,
|
|
(LPSTR) NULL,
|
|
PROV_RSA_FULL,
|
|
dwFlags,
|
|
TRUE,
|
|
&m_hCryptProv)))
|
|
{
|
|
DebugTrace("Error [%#x]: AcquireContext() failed.\n", hr);
|
|
goto ErrorExit;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Sanity check.
|
|
//
|
|
ATLASSERT(m_hCryptProv);
|
|
|
|
//
|
|
// Allocate memory.
|
|
//
|
|
RandomData.cbData = (DWORD) Length;
|
|
if (!(RandomData.pbData = (PBYTE) ::CoTaskMemAlloc(RandomData.cbData)))
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
|
|
DebugTrace("Error [%#x]: CoTaskMemAlloc(RandomData.cbData) failed.\n", hr);
|
|
goto ErrorExit;
|
|
}
|
|
|
|
//
|
|
// Now generate the random value.
|
|
//
|
|
if (!::CryptGenRandom(m_hCryptProv, RandomData.cbData, RandomData.pbData))
|
|
{
|
|
hr = HRESULT_FROM_WIN32(::GetLastError());
|
|
|
|
DebugTrace("Error [%#x]: CryptGenRandom() failed.\n", hr);
|
|
goto ErrorExit;
|
|
}
|
|
|
|
//
|
|
// Export the random data.
|
|
//
|
|
if (FAILED(hr = ::ExportData(RandomData, EncodingType, pVal)))
|
|
{
|
|
DebugTrace("Error [%#x]: ExportData() failed.\n", hr);
|
|
goto ErrorExit;
|
|
}
|
|
}
|
|
|
|
catch(...)
|
|
{
|
|
hr = E_POINTER;
|
|
|
|
DebugTrace("Exception: invalid parameter.\n");
|
|
goto ErrorExit;
|
|
}
|
|
|
|
|
|
UnlockExit:
|
|
//
|
|
// Free resources.
|
|
//
|
|
if (RandomData.pbData)
|
|
{
|
|
::CoTaskMemFree(RandomData.pbData);
|
|
}
|
|
|
|
//
|
|
// Unlock access to this object.
|
|
//
|
|
m_Lock.Unlock();
|
|
|
|
DebugTrace("Leaving CUtilities::GetRandom().\n");
|
|
|
|
return hr;
|
|
|
|
ErrorExit:
|
|
//
|
|
// Sanity check.
|
|
//
|
|
ATLASSERT(FAILED(hr));
|
|
|
|
ReportError(hr);
|
|
|
|
goto UnlockExit;
|
|
}
|
|
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Function : Base64Encode
|
|
|
|
Synopsis : Base64 encode the blob.
|
|
|
|
Parameter: BSTR SrcString - Source string to be base64 encoded.
|
|
|
|
BSTR * pVal - Pointer to BSTR to received base64 encoded string.
|
|
Remark :
|
|
|
|
------------------------------------------------------------------------------*/
|
|
|
|
STDMETHODIMP CUtilities::Base64Encode (BSTR SrcString, BSTR * pVal)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
DATA_BLOB DataBlob = {0, NULL};
|
|
|
|
DebugTrace("Entering CUtilities::Base64Encode().\n");
|
|
|
|
try
|
|
{
|
|
//
|
|
// Lock access to this object.
|
|
//
|
|
m_Lock.Lock();
|
|
|
|
//
|
|
// Check parameter.
|
|
//
|
|
if ((NULL == (DataBlob.pbData = (LPBYTE) SrcString)) ||
|
|
(0 == (DataBlob.cbData = ::SysStringByteLen(SrcString))))
|
|
{
|
|
hr = E_INVALIDARG;
|
|
|
|
DebugTrace("Error [%#x]: Parameter SrcString is NULL or empty.\n", hr);
|
|
goto ErrorExit;
|
|
}
|
|
if (NULL == pVal)
|
|
{
|
|
hr = E_INVALIDARG;
|
|
|
|
DebugTrace("Error [%#x]: Parameter pVal is NULL.\n", hr);
|
|
goto ErrorExit;
|
|
}
|
|
|
|
//
|
|
// Now base64 encode.
|
|
//
|
|
if (FAILED(hr = ::Base64Encode(DataBlob, pVal)))
|
|
{
|
|
DebugTrace("Error [%#x]: Base64Encode() failed.\n", hr);
|
|
goto ErrorExit;
|
|
}
|
|
}
|
|
|
|
catch(...)
|
|
{
|
|
hr = E_POINTER;
|
|
|
|
DebugTrace("Exception: invalid parameter.\n");
|
|
goto ErrorExit;
|
|
}
|
|
|
|
|
|
UnlockExit:
|
|
//
|
|
// Unlock access to this object.
|
|
//
|
|
m_Lock.Unlock();
|
|
|
|
DebugTrace("Leaving CUtilities::Base64Encode().\n");
|
|
|
|
return hr;
|
|
|
|
ErrorExit:
|
|
//
|
|
// Sanity check.
|
|
//
|
|
ATLASSERT(FAILED(hr));
|
|
|
|
ReportError(hr);
|
|
|
|
goto UnlockExit;
|
|
}
|
|
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Function : Base64Decode
|
|
|
|
Synopsis : Base64 decode the blob.
|
|
|
|
Parameter: BSTR EncodedString - Base64 encoded string.
|
|
|
|
BSTR * pVal - Pointer to BSTR to received base64 decoded string.
|
|
Remark :
|
|
|
|
------------------------------------------------------------------------------*/
|
|
|
|
STDMETHODIMP CUtilities::Base64Decode (BSTR EncodedString, BSTR * pVal)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
DATA_BLOB DataBlob = {0, NULL};
|
|
|
|
DebugTrace("Entering CUtilities::Base64Decode().\n");
|
|
|
|
try
|
|
{
|
|
//
|
|
// Lock access to this object.
|
|
//
|
|
m_Lock.Lock();
|
|
|
|
//
|
|
// Make sure parameters are valid.
|
|
//
|
|
if (0 == ::SysStringByteLen(EncodedString))
|
|
{
|
|
hr = E_INVALIDARG;
|
|
|
|
DebugTrace("Error [%#x]: Parameter EncodedString is NULL or empty.\n", hr);
|
|
goto ErrorExit;
|
|
}
|
|
if (NULL == pVal)
|
|
{
|
|
hr = E_INVALIDARG;
|
|
|
|
DebugTrace("Error [%#x]: Parameter pVal is NULL.\n", hr);
|
|
goto ErrorExit;
|
|
}
|
|
|
|
//
|
|
// Now base64 decode.
|
|
//
|
|
if (FAILED(hr = ::Base64Decode(EncodedString, &DataBlob)))
|
|
{
|
|
DebugTrace("Error [%#x]: Base64Decode() failed.\n", hr);
|
|
goto ErrorExit;
|
|
}
|
|
|
|
//
|
|
// Convert blob to BSTR.
|
|
//
|
|
if (FAILED(hr = ::BlobToBstr(&DataBlob, pVal)))
|
|
{
|
|
DebugTrace("Error [%#x]: BlobToBstr() failed.\n", hr);
|
|
goto ErrorExit;
|
|
}
|
|
}
|
|
|
|
catch(...)
|
|
{
|
|
hr = E_POINTER;
|
|
|
|
DebugTrace("Exception: invalid parameter.\n");
|
|
goto ErrorExit;
|
|
}
|
|
|
|
UnlockExit:
|
|
//
|
|
// Free resources.
|
|
//
|
|
if (DataBlob.pbData)
|
|
{
|
|
::CoTaskMemFree((LPVOID) DataBlob.pbData);
|
|
}
|
|
|
|
//
|
|
// Unlock access to this object.
|
|
//
|
|
m_Lock.Unlock();
|
|
|
|
DebugTrace("Leaving CUtilities::Base64Decode().\n");
|
|
|
|
return hr;
|
|
|
|
ErrorExit:
|
|
//
|
|
// Sanity check.
|
|
//
|
|
ATLASSERT(FAILED(hr));
|
|
|
|
ReportError(hr);
|
|
|
|
goto UnlockExit;
|
|
}
|
|
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Function : BinaryToHex
|
|
|
|
Synopsis : Convert binary packed string to hex string.
|
|
|
|
Parameter: BSTR BinaryString - Binary string to be converted.
|
|
|
|
VARIANT * pVal - Pointer to BSTR to receive the converted string.
|
|
|
|
Remark :
|
|
|
|
------------------------------------------------------------------------------*/
|
|
|
|
STDMETHODIMP CUtilities::BinaryToHex (BSTR BinaryString, BSTR * pVal)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
DWORD cbData = 0;
|
|
|
|
DebugTrace("Entering CUtilities::BinaryToHex().\n");
|
|
|
|
try
|
|
{
|
|
//
|
|
// Lock access to this object.
|
|
//
|
|
m_Lock.Lock();
|
|
|
|
//
|
|
// Make sure parameters are valid.
|
|
//
|
|
if (0 == (cbData = ::SysStringByteLen(BinaryString)))
|
|
{
|
|
hr = E_INVALIDARG;
|
|
|
|
DebugTrace("Error [%#x]: Parameter BinaryString is NULL or empty.\n", hr);
|
|
goto ErrorExit;
|
|
}
|
|
if (NULL == pVal)
|
|
{
|
|
hr = E_INVALIDARG;
|
|
|
|
DebugTrace("Error [%#x]: Parameter pVal is NULL.\n", hr);
|
|
goto ErrorExit;
|
|
}
|
|
|
|
//
|
|
// Convert to hex.
|
|
//
|
|
if (FAILED(hr = ::BinaryToHexString((LPBYTE) BinaryString,
|
|
cbData,
|
|
pVal)))
|
|
{
|
|
DebugTrace("Error [%#x]: BinaryToHexString() failed.\n", hr);
|
|
goto ErrorExit;
|
|
}
|
|
}
|
|
|
|
catch(...)
|
|
{
|
|
hr = E_POINTER;
|
|
|
|
DebugTrace("Exception: invalid parameter.\n");
|
|
goto ErrorExit;
|
|
}
|
|
|
|
UnlockExit:
|
|
//
|
|
// Unlock access to this object.
|
|
//
|
|
m_Lock.Unlock();
|
|
|
|
DebugTrace("Leaving CUtilities::BinaryToHex().\n");
|
|
|
|
return hr;
|
|
|
|
ErrorExit:
|
|
//
|
|
// Sanity check.
|
|
//
|
|
ATLASSERT(FAILED(hr));
|
|
|
|
ReportError(hr);
|
|
|
|
goto UnlockExit;
|
|
|
|
}
|
|
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Function : HexToBinary
|
|
|
|
Synopsis : Convert hex string to binary packed string.
|
|
|
|
Parameter: BSTR HexString - Hex string to be converted.
|
|
|
|
VARIANT * pVal - Pointer to BSTR to receive the converted string.
|
|
|
|
Remark :
|
|
|
|
------------------------------------------------------------------------------*/
|
|
|
|
STDMETHODIMP CUtilities::HexToBinary (BSTR HexString, BSTR * pVal)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
DebugTrace("Entering CUtilities::HexToBinary().\n");
|
|
|
|
try
|
|
{
|
|
//
|
|
// Lock access to this object.
|
|
//
|
|
m_Lock.Lock();
|
|
|
|
//
|
|
// Make sure parameters are valid.
|
|
//
|
|
if (0 == ::SysStringByteLen(HexString))
|
|
{
|
|
hr = E_INVALIDARG;
|
|
|
|
DebugTrace("Error [%#x]: Parameter HexString is NULL or empty.\n", hr);
|
|
goto ErrorExit;
|
|
}
|
|
if (NULL == pVal)
|
|
{
|
|
hr = E_INVALIDARG;
|
|
|
|
DebugTrace("Error [%#x]: Parameter pVal is NULL.\n", hr);
|
|
goto ErrorExit;
|
|
}
|
|
|
|
//
|
|
// Convert to binary.
|
|
//
|
|
if (FAILED(hr = ::HexToBinaryString(HexString, pVal)))
|
|
{
|
|
DebugTrace("Error [%#x]: HexToBinaryString() failed.\n", hr);
|
|
goto ErrorExit;
|
|
}
|
|
}
|
|
|
|
catch(...)
|
|
{
|
|
hr = E_POINTER;
|
|
|
|
DebugTrace("Exception: invalid parameter.\n");
|
|
goto ErrorExit;
|
|
}
|
|
|
|
UnlockExit:
|
|
//
|
|
// Unlock access to this object.
|
|
//
|
|
m_Lock.Unlock();
|
|
|
|
DebugTrace("Leaving CUtilities::HexToBinary().\n");
|
|
|
|
return hr;
|
|
|
|
ErrorExit:
|
|
//
|
|
// Sanity check.
|
|
//
|
|
ATLASSERT(FAILED(hr));
|
|
|
|
ReportError(hr);
|
|
|
|
goto UnlockExit;
|
|
|
|
}
|
|
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Function : BinaryStringToByteArray
|
|
|
|
Synopsis : Convert binary packed string to safearray of bytes.
|
|
|
|
Parameter: BSTR BinaryString - Binary string to be converted.
|
|
|
|
VARIANT * pVal - Pointer to VARIANT to receive the converted array.
|
|
|
|
Remark :
|
|
|
|
------------------------------------------------------------------------------*/
|
|
|
|
STDMETHODIMP CUtilities::BinaryStringToByteArray (BSTR BinaryString,
|
|
VARIANT * pVal)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
DWORD dwLength = 0;
|
|
LPBYTE pbByte = NULL;
|
|
LPBYTE pbElement = NULL;
|
|
SAFEARRAY * psa = NULL;
|
|
SAFEARRAYBOUND bound[1] = {0, 0};
|
|
|
|
DebugTrace("Entering CUtilities::BinaryStringToByteArray().\n");
|
|
|
|
try
|
|
{
|
|
//
|
|
// Lock access to this object.
|
|
//
|
|
m_Lock.Lock();
|
|
|
|
//
|
|
// Make sure parameters are valid.
|
|
//
|
|
if (0 == (dwLength = ::SysStringByteLen(BinaryString)))
|
|
{
|
|
hr = E_INVALIDARG;
|
|
|
|
DebugTrace("Error [%#x]: Parameter BinaryString is NULL or empty.\n", hr);
|
|
goto ErrorExit;
|
|
}
|
|
if (NULL == pVal)
|
|
{
|
|
hr = E_INVALIDARG;
|
|
|
|
DebugTrace("Error [%#x]: Parameter pVal is NULL.\n", hr);
|
|
goto ErrorExit;
|
|
}
|
|
|
|
//
|
|
// Initialize.
|
|
//
|
|
::VariantInit(pVal);
|
|
pbByte = (LPBYTE) BinaryString;
|
|
|
|
//
|
|
// Create the array.
|
|
//
|
|
bound[0].cElements = dwLength;
|
|
|
|
if (!(psa = ::SafeArrayCreate(VT_UI1, 1, bound)))
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
|
|
DebugTrace("Error [%#x]: SafeArrayCreate() failed.\n", hr);
|
|
goto ErrorExit;
|
|
}
|
|
|
|
//
|
|
// Now convert each byte in source binary BSTR to variant of byte.
|
|
//
|
|
#ifdef _DEBUG
|
|
VARTYPE vt = VT_EMPTY;
|
|
|
|
if (S_OK == ::SafeArrayGetVartype(psa, &vt))
|
|
{
|
|
DebugTrace("Info: safearray vartype = %d.\n", vt);
|
|
}
|
|
#endif
|
|
//
|
|
// Point to array elements.
|
|
//
|
|
if (FAILED(hr = ::SafeArrayAccessData(psa, (void HUGEP **) &pbElement)))
|
|
{
|
|
DebugTrace("Error [%#x]: SafeArrayAccessData() failed.\n", hr);
|
|
goto ErrorExit;
|
|
}
|
|
|
|
//
|
|
// Fill the array.
|
|
//
|
|
while (dwLength--)
|
|
{
|
|
*pbElement++ = *pbByte++;
|
|
}
|
|
|
|
//
|
|
// Unlock array.
|
|
//
|
|
if (FAILED(hr = ::SafeArrayUnaccessData(psa)))
|
|
{
|
|
DebugTrace("Error [%#x]: SafeArrayUnaccessData() failed.\n", hr);
|
|
goto ErrorExit;
|
|
}
|
|
|
|
//
|
|
// Return array to caller.
|
|
//
|
|
pVal->vt = VT_ARRAY | VT_UI1;
|
|
pVal->parray = psa;
|
|
}
|
|
|
|
catch(...)
|
|
{
|
|
hr = E_POINTER;
|
|
|
|
DebugTrace("Exception: invalid parameter.\n");
|
|
goto ErrorExit;
|
|
}
|
|
|
|
|
|
UnlockExit:
|
|
//
|
|
// Unlock access to this object.
|
|
//
|
|
m_Lock.Unlock();
|
|
|
|
DebugTrace("Leaving CUtilities::BinaryStringToByteArray().\n");
|
|
|
|
return hr;
|
|
|
|
ErrorExit:
|
|
//
|
|
// Sanity check.
|
|
//
|
|
ATLASSERT(FAILED(hr));
|
|
|
|
//
|
|
// Free resources.
|
|
//
|
|
if (psa)
|
|
{
|
|
::SafeArrayDestroy(psa);
|
|
}
|
|
|
|
ReportError(hr);
|
|
|
|
goto UnlockExit;
|
|
}
|
|
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Function : ByteArrayToBinaryString
|
|
|
|
Synopsis : Convert safearray of bytes to binary packed string.
|
|
|
|
Parameter: VARIANT varByteArray - VARIANT byte array.
|
|
|
|
BSTR * pVal - Pointer to BSTR to receive the converted values.
|
|
|
|
Remark :
|
|
|
|
------------------------------------------------------------------------------*/
|
|
|
|
STDMETHODIMP CUtilities::ByteArrayToBinaryString (VARIANT varByteArray,
|
|
BSTR * pVal)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
VARIANT * pvarVal = NULL;
|
|
SAFEARRAY * psa = NULL;
|
|
LPBYTE pbElement = NULL;
|
|
LPBYTE pbByte = NULL;
|
|
long lLoBound = 0;
|
|
long lUpBound = 0;
|
|
BSTR bstrBinary = NULL;
|
|
|
|
DebugTrace("Entering CUtilities::ByteArrayToBinaryString().\n");
|
|
|
|
try
|
|
{
|
|
//
|
|
// Lock access to this object.
|
|
//
|
|
m_Lock.Lock();
|
|
|
|
//
|
|
// Skip over BYREF.
|
|
//
|
|
for (pvarVal = &varByteArray;
|
|
pvarVal && ((VT_VARIANT | VT_BYREF) == V_VT(pvarVal));
|
|
pvarVal = V_VARIANTREF(pvarVal));
|
|
|
|
//
|
|
// Make sure parameters are valid.
|
|
//
|
|
if (!pvarVal)
|
|
{
|
|
hr = E_INVALIDARG;
|
|
|
|
DebugTrace("Error [%#x]: Parameter varByteArray is NULL.\n", hr);
|
|
goto ErrorExit;
|
|
}
|
|
if ((VT_ARRAY | VT_UI1) != V_VT(pvarVal))
|
|
{
|
|
hr = E_INVALIDARG;
|
|
|
|
DebugTrace("Error [%#x]: Parameter varByteArray is not a VT_UI1 array, V_VT(pvarVal) = %d\n",
|
|
hr, V_VT(pvarVal));
|
|
goto ErrorExit;
|
|
}
|
|
if (NULL == pVal)
|
|
{
|
|
hr = E_INVALIDARG;
|
|
|
|
DebugTrace("Error [%#x]: Parameter pVal is NULL.\n", hr);
|
|
goto ErrorExit;
|
|
}
|
|
|
|
//
|
|
// Point to the array.
|
|
//
|
|
psa = V_ARRAY(pvarVal);
|
|
|
|
//
|
|
// Check dimension.
|
|
//
|
|
if (1 != ::SafeArrayGetDim(psa))
|
|
{
|
|
hr = E_INVALIDARG;
|
|
|
|
DebugTrace("Error [%#x]: varByteArray is not 1 dimension, SafeArrayGetDim(psa) = %d.\n",
|
|
hr, ::SafeArrayGetDim(psa));
|
|
goto ErrorExit;
|
|
}
|
|
|
|
//
|
|
// Get array bound.
|
|
//
|
|
if (FAILED(hr = ::SafeArrayGetLBound(psa, 1, &lLoBound)))
|
|
{
|
|
DebugTrace("Error [%#x]: SafeArrayGetLBound() failed.\n", hr);
|
|
goto ErrorExit;
|
|
}
|
|
|
|
if (FAILED(hr = ::SafeArrayGetUBound(psa, 1, &lUpBound)))
|
|
{
|
|
DebugTrace("Error [%#x]: SafeArrayGetUBound() failed.\n", hr);
|
|
goto ErrorExit;
|
|
}
|
|
|
|
//
|
|
// Point to array elements.
|
|
//
|
|
if (FAILED(hr = ::SafeArrayAccessData(psa, (void HUGEP **) &pbElement)))
|
|
{
|
|
DebugTrace("Error [%#x]: SafeArrayAccessData() failed.\n", hr);
|
|
goto ErrorExit;
|
|
}
|
|
|
|
//
|
|
// Allocate memory for the BSTR.
|
|
//
|
|
if (!(bstrBinary = ::SysAllocStringByteLen(NULL, lUpBound - lLoBound + 1)))
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
|
|
DebugTrace("Error [%#x]: SysAllocStringByteLen() failed.\n", hr);
|
|
goto ErrorExit;
|
|
}
|
|
|
|
//
|
|
// Fill the BSTR.
|
|
//
|
|
for (pbByte = (LPBYTE) bstrBinary; lLoBound <= lUpBound; lLoBound++)
|
|
{
|
|
*pbByte++ = *pbElement++;
|
|
}
|
|
|
|
//
|
|
// Unlock array.
|
|
//
|
|
if (FAILED(hr = ::SafeArrayUnaccessData(psa)))
|
|
{
|
|
DebugTrace("Error [%#x]: SafeArrayUnaccessData() failed.\n", hr);
|
|
goto ErrorExit;
|
|
}
|
|
|
|
//
|
|
// Return converted string to caller.
|
|
//
|
|
*pVal = bstrBinary;
|
|
}
|
|
|
|
catch(...)
|
|
{
|
|
hr = E_POINTER;
|
|
|
|
DebugTrace("Exception: invalid parameter.\n");
|
|
goto ErrorExit;
|
|
}
|
|
|
|
|
|
UnlockExit:
|
|
//
|
|
// Unlock access to this object.
|
|
//
|
|
m_Lock.Unlock();
|
|
|
|
DebugTrace("Leaving CUtilities::ByteArrayToBinaryString().\n");
|
|
|
|
return hr;
|
|
|
|
ErrorExit:
|
|
//
|
|
// Sanity check.
|
|
//
|
|
ATLASSERT(FAILED(hr));
|
|
|
|
//
|
|
// Free resources.
|
|
//
|
|
if (bstrBinary)
|
|
{
|
|
::SysFreeString(bstrBinary);
|
|
}
|
|
|
|
ReportError(hr);
|
|
|
|
goto UnlockExit;
|
|
}
|
|
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Function : LocalTimeToUTCTime
|
|
|
|
Synopsis : Convert local time to UTC time.
|
|
|
|
Parameter: DATE LocalTime - Local time to be converted.
|
|
|
|
DATE * pVal - Pointer to DATE to receive the converted time.
|
|
|
|
Remark :
|
|
|
|
------------------------------------------------------------------------------*/
|
|
|
|
STDMETHODIMP CUtilities::LocalTimeToUTCTime (DATE LocalTime, DATE * pVal)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
SYSTEMTIME stLocal;
|
|
SYSTEMTIME stUTC;
|
|
FILETIME ftLocal;
|
|
FILETIME ftUTC;
|
|
|
|
DebugTrace("Entering CUtilities::LocalTimeToUTCTime().\n");
|
|
|
|
try
|
|
{
|
|
//
|
|
// Lock access to this object.
|
|
//
|
|
m_Lock.Lock();
|
|
|
|
//
|
|
// Convert to SYSTEMTIME format.
|
|
//
|
|
if (!::VariantTimeToSystemTime(LocalTime, &stLocal))
|
|
{
|
|
hr = E_INVALIDARG;
|
|
|
|
DebugTrace("Error [%#x]: VariantTimeToSystemTime() failed.\n", hr);
|
|
goto ErrorExit;
|
|
}
|
|
|
|
//
|
|
// Convert to FILETIME format.
|
|
//
|
|
if (!::SystemTimeToFileTime(&stLocal, &ftLocal))
|
|
{
|
|
hr = HRESULT_FROM_WIN32(::GetLastError());
|
|
|
|
DebugTrace("Error [%#x]: SystemTimeToFileTime() failed.\n", hr);
|
|
goto ErrorExit;
|
|
}
|
|
|
|
//
|
|
// Convert to UTC FILETIME.
|
|
//
|
|
if (!::LocalFileTimeToFileTime(&ftLocal, &ftUTC))
|
|
{
|
|
hr = HRESULT_FROM_WIN32(::GetLastError());
|
|
|
|
DebugTrace("Error [%#x]: LocalFileTimeToFileTime() failed.\n", hr);
|
|
goto ErrorExit;
|
|
}
|
|
|
|
//
|
|
// Convert to UTC SYSTEMTIME.
|
|
//
|
|
if (!::FileTimeToSystemTime(&ftUTC, &stUTC))
|
|
{
|
|
hr = HRESULT_FROM_WIN32(::GetLastError());
|
|
|
|
DebugTrace("Error [%#x]: FileTimeToSystemTime() failed.\n", hr);
|
|
goto ErrorExit;
|
|
}
|
|
|
|
//
|
|
// Finally convert it back to DATE format.
|
|
//
|
|
if (!::SystemTimeToVariantTime(&stUTC, pVal))
|
|
{
|
|
hr = E_INVALIDARG;
|
|
|
|
DebugTrace("Error [%#x]: SystemTimeToVariantTime() failed.\n", hr);
|
|
goto ErrorExit;
|
|
}
|
|
}
|
|
|
|
catch(...)
|
|
{
|
|
hr = E_POINTER;
|
|
|
|
DebugTrace("Exception: invalid parameter.\n");
|
|
goto ErrorExit;
|
|
}
|
|
|
|
|
|
UnlockExit:
|
|
//
|
|
// Unlock access to this object.
|
|
//
|
|
m_Lock.Unlock();
|
|
|
|
DebugTrace("Leaving CUtilities::LocalTimeToUTCTime().\n");
|
|
|
|
return hr;
|
|
|
|
ErrorExit:
|
|
//
|
|
// Sanity check.
|
|
//
|
|
ATLASSERT(FAILED(hr));
|
|
|
|
ReportError(hr);
|
|
|
|
goto UnlockExit;
|
|
}
|
|
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Function : UTCTimeToLocalTime
|
|
|
|
Synopsis : Convert UTC time to local time.
|
|
|
|
Parameter: DATE UTCTime - UTC time to be converted.
|
|
|
|
DATE * pVal - Pointer to DATE to receive the converted time.
|
|
|
|
Remark :
|
|
|
|
------------------------------------------------------------------------------*/
|
|
|
|
STDMETHODIMP CUtilities::UTCTimeToLocalTime (DATE UTCTime, DATE * pVal)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
SYSTEMTIME stLocal;
|
|
SYSTEMTIME stUTC;
|
|
FILETIME ftLocal;
|
|
FILETIME ftUTC;
|
|
|
|
DebugTrace("Entering CUtilities::UTCTimeToLocalTime().\n");
|
|
|
|
try
|
|
{
|
|
//
|
|
// Lock access to this object.
|
|
//
|
|
m_Lock.Lock();
|
|
|
|
//
|
|
// Convert to SYSTEMTIME format.
|
|
//
|
|
if (!::VariantTimeToSystemTime(UTCTime, &stUTC))
|
|
{
|
|
hr = E_INVALIDARG;
|
|
|
|
DebugTrace("Error [%#x]: VariantTimeToSystemTime() failed.\n", hr);
|
|
goto ErrorExit;
|
|
}
|
|
|
|
//
|
|
// Convert to FILETIME format.
|
|
//
|
|
if (!::SystemTimeToFileTime(&stUTC, &ftUTC))
|
|
{
|
|
hr = HRESULT_FROM_WIN32(::GetLastError());
|
|
|
|
DebugTrace("Error [%#x]: SystemTimeToFileTime() failed.\n", hr);
|
|
goto ErrorExit;
|
|
}
|
|
|
|
//
|
|
// Convert to local FILETIME.
|
|
//
|
|
if (!::FileTimeToLocalFileTime(&ftUTC, &ftLocal))
|
|
{
|
|
hr = HRESULT_FROM_WIN32(::GetLastError());
|
|
|
|
DebugTrace("Error [%#x]: FileTimeToLocalFileTime() failed.\n", hr);
|
|
goto ErrorExit;
|
|
}
|
|
|
|
//
|
|
// Convert to local SYSTEMTIME.
|
|
//
|
|
if (!::FileTimeToSystemTime(&ftLocal, &stLocal))
|
|
{
|
|
hr = HRESULT_FROM_WIN32(::GetLastError());
|
|
|
|
DebugTrace("Error [%#x]: FileTimeToSystemTime() failed.\n", hr);
|
|
goto ErrorExit;
|
|
}
|
|
|
|
//
|
|
// Finally convert it back to DATE format.
|
|
//
|
|
if (!::SystemTimeToVariantTime(&stLocal, pVal))
|
|
{
|
|
hr = E_INVALIDARG;
|
|
|
|
DebugTrace("Error [%#x]: SystemTimeToVariantTime() failed.\n", hr);
|
|
goto ErrorExit;
|
|
}
|
|
}
|
|
|
|
catch(...)
|
|
{
|
|
hr = E_POINTER;
|
|
|
|
DebugTrace("Exception: invalid parameter.\n");
|
|
goto ErrorExit;
|
|
}
|
|
|
|
|
|
UnlockExit:
|
|
//
|
|
// Unlock access to this object.
|
|
//
|
|
m_Lock.Unlock();
|
|
|
|
DebugTrace("Leaving CUtilities::UTCTimeToLocalTime().\n");
|
|
|
|
return hr;
|
|
|
|
ErrorExit:
|
|
//
|
|
// Sanity check.
|
|
//
|
|
ATLASSERT(FAILED(hr));
|
|
|
|
ReportError(hr);
|
|
|
|
goto UnlockExit;
|
|
}
|