1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
| #include <windows.h>
/* Get a HRESULT from a Win32 error code, or E_UNEXPECTED */
static HRESULT GetHResultFromWin32(DWORD error)
{
HRESULT hr = HRESULT_FROM_WIN32(error);
if(SUCCEEDED(hr))
hr = E_UNEXPECTED;
return hr;
}
/* Convert a char string into an unicode string. */
HRESULT GetUnicodeString(
LPCSTR sczInA, /*[in] char string.*/
UINT codePage, /*[in] Code page identifier, or CP_ACP etc.*/
LPWSTR * pSzOutW, /*[out] Receives a pointer to the new wide character string.*/
int * pCchWritten /*[out/opt] If set, receives the length of the wide character string, in characters. */
)
{
HRESULT hrRet = E_UNEXPECTED;
int cchSizeW = 0;
/*Initialize optional output parameters to their default values*/
if(pCchWritten != NULL)
*pCchWritten = 0;
/*Test other output parameters, and initialize to their default values as long as possible*/
if(pSzOutW==NULL)
return E_POINTER;
*pSzOutW = NULL;
/*Test input parameters*/
if(sczInA==NULL)
return E_INVALIDARG;
/*Calculate size*/
cchSizeW = MultiByteToWideChar(codePage, MB_ERR_INVALID_CHARS, sczInA, -1, NULL, 0);
if(cchSizeW <= 0)
hrRet = GetHResultFromWin32(GetLastError());
else
{
/*Alloc buffer*/
LPWSTR szOutW = malloc(cchSizeW * sizeof *szOutW);
if(szOutW==NULL)
hrRet = E_OUTOFMEMORY;
else
{
/*Use buffer*/
BOOL bKeepMem = FALSE;
int cchWritten = MultiByteToWideChar(codePage, MB_ERR_INVALID_CHARS, sczInA, -1, szOutW, cchSizeW);
if(cchWritten <= 0)
hrRet = GetHResultFromWin32(GetLastError()); /*This error is very unlikely to happen, since it was tested before*/
else
{
/*OK!*/
hrRet = S_OK;
bKeepMem = TRUE;
*pSzOutW = szOutW;
if(pCchWritten!=NULL)
*pCchWritten = cchWritten;
}
if(!bKeepMem)
free(szOutW);
}
}
return hrRet;
}
/* Convert a char string into an unicode BSTR. */
HRESULT GetUnicodeBstr(
LPCSTR sczInA, /*[in]*/
UINT codePage, /*[in]*/
BSTR * pBsOutW, /*[out]*/
int * pCchWritten /*[out/opt]*/
)
{
HRESULT hrRet = E_UNEXPECTED;
int cchSizeW = 0;
/*Initialize optional output parameters to their default values*/
if(pCchWritten != NULL)
*pCchWritten = 0;
/*Test other output parameters, and initialize to their default values as long as possible*/
if(pBsOutW==NULL)
return E_POINTER;
*pBsOutW = NULL;
/*Test input parameters*/
if(sczInA==NULL)
return E_INVALIDARG;
/*Calculate size*/
cchSizeW = MultiByteToWideChar(codePage, MB_ERR_INVALID_CHARS, sczInA, -1, NULL, 0);
if(cchSizeW <= 0)
hrRet = GetHResultFromWin32(GetLastError());
else
{
/*Alloc buffer*/
DWORD cchLengthW = cchSizeW-1;
BSTR szOutW = SysAllocStringLen(NULL, cchLengthW);
if(szOutW==NULL)
hrRet = E_OUTOFMEMORY;
else
{
/*Use buffer*/
BOOL bKeepMem = FALSE;
int cchWritten = MultiByteToWideChar(codePage, MB_ERR_INVALID_CHARS, sczInA, -1, szOutW, cchSizeW);
if(cchWritten <= 0)
hrRet = GetHResultFromWin32(GetLastError()); /*This error is very unlikely to happen, since it was tested before*/
else
{
/*OK!*/
hrRet = S_OK;
bKeepMem = TRUE;
*pBsOutW = szOutW;
if(pCchWritten!=NULL)
*pCchWritten = cchWritten;
}
if(!bKeepMem)
SysFreeString(szOutW);
}
}
return hrRet;
}
/* Delete a wide character string allocated by GetUnicodeString() */
HRESULT FreeUnicodeString(LPWSTR szDelW)
{
if(szDelW==NULL)
return S_FALSE;
free(szDelW);
return S_OK;
} |