00001
00025 #include "stdint.h"
00026 #include <stdlib.h>
00027 #include <string.h>
00028
00029 #if defined(_USE_WIN_API)
00030 #include <windows.h>
00031 #elif defined(_USE_LINUX_API)
00032 #include <float.h>
00033 #include <limits.h>
00034 #include <locale.h>
00035 #include <errno.h>
00036 #ifndef _wcsicmp
00037 #define _wcsicmp wcscasecmp
00038 #endif
00039 #ifndef __USE_XOPEN
00040 #define __USE_XOPEN
00041 #endif
00042 #endif
00043
00044 #include "dn_common.h"
00045
00050 #define _LEN_VARIANT2BSTR (500)
00051
00052 #ifndef _OLEAUTO_H_
00053
00060 BSTR
00061 SysAllocString(const wchar_t *sz)
00062 {
00063 if (sz == NULL)
00064 return NULL;
00065
00066 return SysAllocStringLen(sz, wcslen(sz));
00067 }
00068
00076 BSTR
00077 SysAllocStringLen(const wchar_t *pch, uint16_t cch)
00078 {
00079 uint16_t minlen;
00080 BSTR bstr = NULL;
00081
00082 minlen = sizeof(wchar_t) * (cch + 1);
00083 bstr = (BSTR) malloc(minlen);
00084
00085 if (bstr != NULL) {
00086 memset(bstr, 0, minlen);
00087
00088 if (pch != NULL) {
00089 minlen = wcslen(pch);
00090 minlen = (cch < minlen ? cch : minlen);
00091 memcpy(bstr, pch, sizeof(wchar_t) * minlen);
00092 }
00093 }
00094
00095 return bstr;
00096 }
00097
00103 void
00104 SysFreeString(BSTR bstr)
00105 {
00106 if (bstr != NULL) {
00107 free(bstr);
00108 bstr = NULL;
00109 }
00110 }
00111
00117 uint16_t
00118 SysStringLen(BSTR bstr)
00119 {
00120 uint16_t len = 0;
00121
00122 if (bstr != NULL) {
00123 len = wcslen(bstr);
00124 }
00125
00126 return len;
00127 }
00128
00137 SAFEARRAY*
00138 SafeArrayCreateVector(uint16_t vt, int32_t lLbound, uint32_t cElements)
00139 {
00140 int sz;
00141 SAFEARRAY* psa = NULL;
00142
00143 psa = (SAFEARRAY*) malloc(sizeof(SAFEARRAY));
00144
00145 if (psa != NULL) {
00146 memset(psa, 0, sizeof(SAFEARRAY));
00147
00148 psa->cDims = 1;
00149 psa->vt = vt;
00150 psa->rgsabound[0].lLbound = lLbound;
00151 psa->rgsabound[0].cElements = cElements;
00152
00153 if (cElements > 0) {
00154 switch (vt) {
00155 case VT_UI1:
00156 sz = 1;
00157 break;
00158 case VT_I2:
00159 case VT_UI2:
00160 case VT_BOOL:
00161 sz = 2;
00162 break;
00163 case VT_I4:
00164 case VT_UI4:
00165 case VT_R4:
00166 sz = 4;
00167 break;
00168 case VT_I8:
00169 case VT_UI8:
00170 case VT_R8:
00171 case VT_CY:
00172 sz = 8;
00173 break;
00174 case VT_DATE:
00175 sz = sizeof(DATE);
00176 break;
00177 case VT_BSTR:
00178 sz = sizeof(BSTR);
00179 break;
00180 case VT_VARIANT:
00181 sz = sizeof(VARIANT);
00182 break;
00183 default:
00184 free(psa);
00185 psa = NULL;
00186 goto exit_proc;
00187 }
00188
00189 psa->cbElements = sz;
00190 psa->pvData = malloc(cElements * sz);
00191
00192 if (psa->pvData == NULL) {
00193 free(psa);
00194 psa = NULL;
00195 goto exit_proc;
00196 }
00197
00198 memset(psa->pvData, 0, cElements * sz);
00199 }
00200 }
00201
00202 exit_proc:
00203 return psa;
00204 }
00205
00211 HRESULT
00212 SafeArrayDestroy(SAFEARRAY *psa)
00213 {
00214 int32_t i;
00215
00216 if (psa != NULL) {
00217 if (psa->pvData != NULL) {
00218 switch (psa->vt) {
00219 case VT_BSTR:
00220 for (i = 0; i < psa->rgsabound[0].cElements; i++) {
00221 SysFreeString(*((BSTR*) psa->pvData + i));
00222 }
00223 break;
00224 case VT_VARIANT:
00225 for (i = 0; i < psa->rgsabound[0].cElements; i++) {
00226 VariantClear(((VARIANT*) psa->pvData + i));
00227 }
00228 break;
00229 default:
00230 free(psa->pvData);
00231 break;
00232 }
00233 psa->pvData = NULL;
00234 }
00235 free(psa);
00236 psa = NULL;
00237 }
00238
00239 return S_OK;
00240 }
00241
00247 uint16_t
00248 SafeArrayGetDim(SAFEARRAY *psa)
00249 {
00250 if (psa == NULL)
00251 return 0;
00252
00253 return psa->cDims;
00254 }
00255
00261 uint32_t
00262 SafeArrayGetElemsize(SAFEARRAY *psa)
00263 {
00264 if (psa == NULL)
00265 return 0;
00266
00267 return psa->cbElements;
00268 }
00269
00277 HRESULT
00278 SafeArrayGetLBound(SAFEARRAY *psa, uint16_t nDim, int32_t *plLbound)
00279 {
00280 if (psa == NULL || plLbound == NULL)
00281 return E_INVALIDARG;
00282 if (nDim <= 0 || psa->cDims < nDim)
00283 return DISP_E_BADINDEX;
00284
00285 *plLbound = psa->rgsabound[nDim - 1].lLbound;
00286
00287 return S_OK;
00288 }
00289
00297 HRESULT
00298 SafeArrayGetUBound(SAFEARRAY *psa, uint16_t nDim, int32_t *plUbound)
00299 {
00300 if (psa == NULL || plUbound == NULL)
00301 return E_INVALIDARG;
00302 if (nDim <= 0 || psa->cDims < nDim)
00303 return DISP_E_BADINDEX;
00304
00305 *plUbound = (psa->rgsabound[nDim - 1].cElements
00306 + psa->rgsabound[nDim - 1].lLbound - 1);
00307
00308 return S_OK;
00309 }
00310
00317 HRESULT
00318 SafeArrayGetVartype(SAFEARRAY *psa, uint16_t *pvt)
00319 {
00320 if (psa == NULL || pvt == NULL)
00321 return E_INVALIDARG;
00322
00323 *pvt = psa->vt;
00324
00325 return S_OK;
00326 }
00327
00335 HRESULT
00336 SafeArrayAccessData(SAFEARRAY *psa, void **ppvData)
00337 {
00338 if (psa == NULL || ppvData == NULL)
00339 return E_INVALIDARG;
00340
00341 *ppvData = psa->pvData;
00342
00343 return S_OK;
00344 }
00345
00352 HRESULT
00353 SafeArrayUnaccessData(SAFEARRAY *psa)
00354 {
00355 if (psa == NULL)
00356 return E_INVALIDARG;
00357
00358 return S_OK;
00359 }
00360
00367 void
00368 VariantInit(VARIANT *pvarg)
00369 {
00370 if (pvarg != NULL) {
00371 memset(pvarg, 0, sizeof(VARIANT));
00372 }
00373 }
00374
00381 void
00382 VariantClear(VARIANT *pvarg)
00383 {
00384 if (pvarg != NULL) {
00385 if (pvarg->vt & VT_ARRAY) {
00386 if (pvarg->parray != NULL) {
00387 SafeArrayDestroy(pvarg->parray);
00388 pvarg->parray = NULL;
00389 }
00390 }
00391 else if (pvarg->vt == VT_BSTR) {
00392 if (pvarg->bstrVal != NULL) {
00393 SysFreeString(pvarg->bstrVal);
00394 pvarg->bstrVal = NULL;
00395 }
00396 }
00397 memset(pvarg, 0, sizeof(VARIANT));
00398 }
00399 }
00400
00401 #if (_DN_USE_VARIANT_API)
00402
00408 HRESULT
00409 VariantCopy(VARIANT *pvargDest, const VARIANT *pvargSrc)
00410 {
00411 if ((pvargDest == NULL) || (pvargSrc == NULL)) {
00412 return E_INVALIDARG;
00413 }
00414
00415 if (pvargDest == pvargSrc) {
00416 return S_OK;
00417 }
00418
00419 VariantClear(pvargDest);
00420
00421 if (pvargSrc->vt & VT_ARRAY) {
00422 int32_t i, lLbound = 0;
00423 uint32_t cbElements = 0, cElements;
00424
00425 lLbound = pvargSrc->parray->rgsabound[0].lLbound;
00426 cElements = pvargSrc->parray->rgsabound[0].cElements;
00427 cbElements = pvargSrc->parray->cbElements;
00428
00429 switch (pvargSrc->vt ^ VT_ARRAY) {
00430 case VT_I2:
00431 case VT_I4:
00432 case VT_I8:
00433 case VT_R4:
00434 case VT_R8:
00435 case VT_CY:
00436 case VT_DATE:
00437 case VT_BOOL:
00438 case VT_UI1:
00439 case VT_UI2:
00440 case VT_UI4:
00441 case VT_UI8:
00442 pvargDest->vt = pvargSrc->vt;
00443 pvargDest->parray = SafeArrayCreateVector(pvargSrc->vt ^ VT_ARRAY,
00444 lLbound, cElements);
00445 memcpy(pvargDest->parray->pvData, pvargSrc->parray->pvData,
00446 cbElements * cElements);
00447 break;
00448 case VT_BSTR:
00449 pvargDest->vt = pvargSrc->vt;
00450 pvargDest->parray = SafeArrayCreateVector(VT_BSTR, lLbound, cElements);
00451 for (i = 0; i < cElements; i++) {
00452 *((BSTR*) pvargDest->parray->pvData + i) = SysAllocString(
00453 *((BSTR*) pvargSrc->parray->pvData + i));
00454 }
00455 break;
00456 case VT_VARIANT:
00457 pvargDest->vt = pvargSrc->vt;
00458 pvargDest->parray = SafeArrayCreateVector(VT_VARIANT, lLbound,
00459 cElements);
00460 for (i = 0; i < cElements; i++) {
00461 VariantCopy(((VARIANT*) pvargDest->parray->pvData + i),
00462 ((VARIANT*) pvargSrc->parray->pvData + i));
00463 }
00464 break;
00465 default:
00466 return DISP_E_BADVARTYPE;
00467 }
00468 } else {
00469 switch (pvargSrc->vt) {
00470 case VT_EMPTY:
00471 case VT_NULL:
00472 case VT_I2:
00473 case VT_I4:
00474 case VT_I8:
00475 case VT_R4:
00476 case VT_R8:
00477 case VT_CY:
00478 case VT_DATE:
00479 case VT_ERROR:
00480 case VT_BOOL:
00481 case VT_UI1:
00482 case VT_UI2:
00483 case VT_UI4:
00484 case VT_UI8:
00485 memcpy(pvargDest, pvargSrc, sizeof(VARIANT));
00486 break;
00487 case VT_BSTR:
00488 pvargDest->vt = VT_BSTR;
00489 pvargDest->bstrVal = SysAllocString(pvargSrc->bstrVal);
00490 break;
00491 default:
00492 return DISP_E_BADVARTYPE;
00493 }
00494 }
00495
00496 return S_OK;
00497 }
00498
00505 static HRESULT
00506 Variant2Bstr(BSTR *pbstr, VARIANT *pvarg)
00507 {
00508 HRESULT hr = S_OK;
00509 char chStr[_LEN_VARIANT2BSTR];
00510 wchar_t wchStr[_LEN_VARIANT2BSTR];
00511 struct tm *tmVal;
00512
00513 switch (pvarg->vt) {
00514 case VT_I2:
00515 swprintf(wchStr, _LEN_VARIANT2BSTR, L"%d", pvarg->iVal);
00516 break;
00517 case VT_I4:
00518 swprintf(wchStr, _LEN_VARIANT2BSTR, L"%ld", pvarg->lVal);
00519 break;
00520 case VT_I8:
00521 swprintf(wchStr, _LEN_VARIANT2BSTR, L"%lld", pvarg->llVal);
00522 break;
00523 case VT_R4:
00524 swprintf(wchStr, _LEN_VARIANT2BSTR, L"%.7G", pvarg->fltVal);
00525 break;
00526 case VT_R8:
00527 swprintf(wchStr, _LEN_VARIANT2BSTR, L"%.15G", pvarg->dblVal);
00528 break;
00529 case VT_CY:
00530 swprintf(wchStr, _LEN_VARIANT2BSTR, L"%lld", pvarg->cyVal.int64);
00531 break;
00532 case VT_DATE:
00533 tmVal = gmtime(&pvarg->date);
00534 strftime(chStr, _LEN_VARIANT2BSTR, FORMAT_DATE2BSTR, tmVal);
00535 mbstowcs(wchStr, chStr, _LEN_VARIANT2BSTR);
00536 break;
00537 case VT_BOOL:
00538 swprintf(wchStr, _LEN_VARIANT2BSTR, L"%d", pvarg->boolVal);
00539 break;
00540 case VT_UI1:
00541 swprintf(wchStr, _LEN_VARIANT2BSTR, L"%u", pvarg->bVal);
00542 break;
00543 case VT_UI2:
00544 swprintf(wchStr, _LEN_VARIANT2BSTR, L"%u", pvarg->uiVal);
00545 break;
00546 case VT_UI4:
00547 swprintf(wchStr, _LEN_VARIANT2BSTR, L"%lu", pvarg->ulVal);
00548 break;
00549 case VT_UI8:
00550 swprintf(wchStr, _LEN_VARIANT2BSTR, L"%llu", pvarg->ullVal);
00551 break;
00552 default:
00553 hr = DISP_E_BADVARTYPE;
00554 break;
00555 }
00556
00557 if(SUCCEEDED(hr)) {
00558 *pbstr = SysAllocString(wchStr);
00559 }
00560
00561 return hr;
00562 }
00563
00570 static HRESULT
00571 Bstr2Variant(VARIANT *pvarg, int16_t vt, BSTR bstr)
00572 {
00573 HRESULT hr = S_OK;
00574 int flag = 0, len;
00575 char *chRet, *chStr = NULL;
00576 wchar_t *wchRet;
00577 struct tm tmVal;
00578 VARIANT vntTmp;
00579
00580 if(*bstr == L'\0') {
00581 return DISP_E_TYPEMISMATCH;
00582 }
00583
00584 VariantInit(&vntTmp);
00585
00586 if (pvarg->bstrVal == bstr) {
00587 flag = 1;
00588 }
00589
00590 switch (vt) {
00591 case VT_EMPTY:
00592 case VT_NULL:
00593 break;
00594 case VT_ERROR:
00595 hr = DISP_E_TYPEMISMATCH;
00596 break;
00597 case VT_I2:
00598 case VT_I4:
00599 case VT_BOOL:
00600 errno = 0;
00601 vntTmp.lVal = (int32_t) wcstol(bstr, &wchRet, 0);
00602 if ((wchRet == NULL) || ((*wchRet != L'.') && (*wchRet != L'\0'))) {
00603 hr = DISP_E_TYPEMISMATCH;
00604 }
00605 else if (errno == ERANGE) {
00606 hr = DISP_E_OVERFLOW;
00607 }
00608 else if ((vt == VT_I2) || (vt == VT_BOOL)) {
00609 vntTmp.vt = VT_I4;
00610 hr = VariantChangeType(&vntTmp, &vntTmp, 0, vt);
00611 }
00612 break;
00613 case VT_I8:
00614 errno = 0;
00615 vntTmp.llVal = (int64_t) wcstoll(bstr, &wchRet, 0);
00616 if ((wchRet == NULL) || ((*wchRet != L'.') && (*wchRet != L'\0'))) {
00617 hr = DISP_E_TYPEMISMATCH;
00618 }
00619 else if (errno == ERANGE) {
00620 hr = DISP_E_OVERFLOW;
00621 }
00622 break;
00623 case VT_R4:
00624 errno = 0;
00625 vntTmp.fltVal = wcstof(bstr, &wchRet);
00626 if ((wchRet == NULL) || (*wchRet != L'\0')) {
00627 hr = DISP_E_TYPEMISMATCH;
00628 }
00629 else if (errno == ERANGE) {
00630 hr = DISP_E_OVERFLOW;
00631 }
00632 break;
00633 case VT_R8:
00634 errno = 0;
00635 vntTmp.dblVal = wcstod(bstr, &wchRet);
00636 if ((wchRet == NULL) || (*wchRet != L'\0')) {
00637 hr = DISP_E_TYPEMISMATCH;
00638 }
00639 else if (errno == ERANGE) {
00640 hr = DISP_E_OVERFLOW;
00641 }
00642 break;
00643 case VT_CY:
00644 errno = 0;
00645 vntTmp.cyVal.int64 = (int64_t) wcstoll(bstr, &wchRet, 0);
00646 if ((wchRet == NULL) || ((*wchRet != L'.') && (*wchRet != L'\0'))) {
00647 hr = DISP_E_TYPEMISMATCH;
00648 }
00649 else if (errno == ERANGE) {
00650 hr = DISP_E_OVERFLOW;
00651 }
00652 break;
00653 case VT_UI1:
00654 case VT_UI2:
00655 case VT_UI4:
00656 errno = 0;
00657 vntTmp.ulVal = (uint32_t) wcstoul(bstr, &wchRet, 0);
00658 if ((wchRet == NULL) || ((*wchRet != L'.') && (*wchRet != L'\0'))) {
00659 hr = DISP_E_TYPEMISMATCH;
00660 }
00661 else if (errno == ERANGE) {
00662 hr = DISP_E_OVERFLOW;
00663 }
00664 else if ((vt == VT_UI1) || (vt == VT_UI2)) {
00665 vntTmp.vt = VT_UI4;
00666 hr = VariantChangeType(&vntTmp, &vntTmp, 0, vt);
00667 }
00668 else if (*bstr == L'-') {
00669 hr = DISP_E_OVERFLOW;
00670 }
00671 break;
00672 case VT_UI8:
00673 errno = 0;
00674 vntTmp.ullVal = (uint64_t) wcstoull(bstr, &wchRet, 0);
00675 if ((wchRet == NULL) || ((*wchRet != L'.') && (*wchRet != L'\0'))) {
00676 hr = DISP_E_TYPEMISMATCH;
00677 }
00678 else if (errno == ERANGE) {
00679 hr = DISP_E_OVERFLOW;
00680 }
00681 else if (*bstr == L'-') {
00682 hr = DISP_E_OVERFLOW;
00683 }
00684 break;
00685 case VT_DATE:
00686 len = wcstombs(NULL, bstr, 0) + 1;
00687 if(len <= 0) {
00688 hr = DISP_E_TYPEMISMATCH;
00689 break;
00690 }
00691
00692 chStr = (char *) malloc(len);
00693 if(chStr == NULL) {
00694 hr = E_OUTOFMEMORY;
00695 break;
00696 }
00697
00698 wcstombs(chStr, bstr, len);
00699 memset(&tmVal, 0, sizeof(struct tm));
00700 chRet = strptime(chStr, FORMAT_DATE2BSTR, &tmVal);
00701 if ((chRet == NULL) || (*chRet != '\0')) {
00702 hr = DISP_E_TYPEMISMATCH;
00703 } else {
00704 vntTmp.date = mktime(&tmVal);
00705 }
00706 free(chStr);
00707 break;
00708 default:
00709 hr = DISP_E_BADVARTYPE;
00710 break;
00711 }
00712 errno = 0;
00713
00714 if (SUCCEEDED(hr)) {
00715 *pvarg = vntTmp;
00716 if (flag) {
00717 SysFreeString(bstr);
00718 }
00719 }
00720
00721 VariantClear(&vntTmp);
00722
00723 return hr;
00724 }
00725
00735 HRESULT
00736 VariantChangeType(VARIANT *pvargDest, VARIANT *pvarSrc, uint16_t wFlags,
00737 uint16_t vt)
00738 {
00739 HRESULT hr = S_OK;
00740
00741 if ((pvargDest == NULL) || (pvarSrc == NULL)) {
00742 return E_INVALIDARG;
00743 }
00744
00745 if (pvargDest != pvarSrc) {
00746 VariantClear(pvargDest);
00747 if (vt == pvarSrc->vt) {
00748 return VariantCopy(pvargDest, pvarSrc);
00749 }
00750 } else {
00751 if (vt == pvarSrc->vt) {
00752 return S_OK;
00753 }
00754 }
00755
00756 #define CheckOverflow(typeDst, typeSrc) \
00757 ((sizeof(typeDst) < sizeof(typeSrc)) \
00758 || (pvarSrc->vt == VT_R4) \
00759 || (pvarSrc->vt == VT_R8))
00760
00761 #define IsUnsigned \
00762 ((pvarSrc->vt == VT_UI1) \
00763 || (pvarSrc->vt == VT_UI2) \
00764 || (pvarSrc->vt == VT_UI4) \
00765 || (pvarSrc->vt == VT_UI8))
00766
00767 #define SubChangeType(type, val, chk) \
00768 switch (vt) { \
00769 case VT_EMPTY: \
00770 case VT_NULL: \
00771 memset(pvargDest, 0, sizeof(VARIANT)); \
00772 break; \
00773 case VT_ERROR: \
00774 return DISP_E_TYPEMISMATCH; \
00775 break; \
00776 case VT_I2: \
00777 if(chk) { if(CheckOverflow(int16_t, type) \
00778 && ((!IsUnsigned && ((val) < (type)SHRT_MIN)) \
00779 || ((type)SHRT_MAX < (val)))) { \
00780 return DISP_E_OVERFLOW; \
00781 } } \
00782 pvargDest->iVal = (int16_t)(val); \
00783 break; \
00784 case VT_I4: \
00785 if(chk) { if(CheckOverflow(int32_t, type) \
00786 && ((!IsUnsigned && ((val) < (type)LONG_MIN)) \
00787 || ((type)LONG_MAX < (val)))) { \
00788 return DISP_E_OVERFLOW; \
00789 } } \
00790 pvargDest->lVal = (int32_t)(val); \
00791 break; \
00792 case VT_I8: \
00793 if(chk) { if(CheckOverflow(int64_t, type) \
00794 && ((!IsUnsigned && ((val) < (type)LLONG_MIN)) \
00795 || ((type)LLONG_MAX < (val)))) { \
00796 return DISP_E_OVERFLOW; \
00797 } } \
00798 pvargDest->llVal = (int64_t)(val); \
00799 break; \
00800 case VT_R4: \
00801 if(chk) { if((pvarSrc->vt == VT_R8) \
00802 && (((val) < (double)-FLT_MAX) \
00803 || ((double)FLT_MAX < (val)))) { \
00804 return DISP_E_OVERFLOW; \
00805 } } \
00806 pvargDest->fltVal = (float)(val); \
00807 break; \
00808 case VT_R8: \
00809 pvargDest->dblVal = (double)(val); \
00810 break; \
00811 case VT_CY: \
00812 if(chk) { if(CheckOverflow(int64_t, type) \
00813 && ((!IsUnsigned && ((val) < (type)LLONG_MIN)) \
00814 || ((type)LLONG_MAX < (val)))) { \
00815 return DISP_E_OVERFLOW; \
00816 } } \
00817 pvargDest->cyVal.int64 = (int64_t)(val); \
00818 break; \
00819 case VT_DATE: \
00820 pvargDest->date = (DATE)(val); \
00821 break; \
00822 case VT_BSTR: \
00823 hr = Variant2Bstr(&pvargDest->bstrVal, pvarSrc); \
00824 break;\
00825 case VT_BOOL: \
00826 pvargDest->boolVal = ((val) ? VARIANT_TRUE : VARIANT_FALSE); \
00827 break; \
00828 case VT_UI1: \
00829 if(chk) { if(((val) < (type)0) || \
00830 (CheckOverflow(uint8_t, type) && ((type)USHRT_MAX < (val)))) { \
00831 return DISP_E_OVERFLOW; \
00832 } } \
00833 pvargDest->bVal = (uint8_t)(val); \
00834 break; \
00835 case VT_UI2: \
00836 if(chk) { if(((pvarSrc->vt != VT_I2) && ((val) < (type)0)) || \
00837 (CheckOverflow(uint16_t, type) && ((type)USHRT_MAX < (val)))) { \
00838 return DISP_E_OVERFLOW; \
00839 } } \
00840 pvargDest->uiVal = (uint16_t)(val); \
00841 break; \
00842 case VT_UI4: \
00843 if(chk) { if(((pvarSrc->vt != VT_I4) && ((val) < (type)0)) || \
00844 (CheckOverflow(uint32_t, type) && ((type)ULONG_MAX < (val)))) { \
00845 return DISP_E_OVERFLOW; \
00846 } } \
00847 pvargDest->ulVal = (uint32_t)(val); \
00848 break; \
00849 case VT_UI8: \
00850 if(chk) { if(((pvarSrc->vt != VT_I8) && ((val) < (type)0)) || \
00851 (CheckOverflow(uint64_t, type) && ((type)ULLONG_MAX < (val)))) { \
00852 return DISP_E_OVERFLOW; \
00853 } } \
00854 pvargDest->ullVal = (uint64_t)(val); \
00855 break; \
00856 default: \
00857 return DISP_E_BADVARTYPE; \
00858 }
00859
00860 switch (pvarSrc->vt) {
00861 case VT_EMPTY:
00862 switch (vt) {
00863 case VT_BSTR:
00864 pvargDest->bstrVal = SysAllocString(L"");
00865 break;
00866 case VT_ERROR:
00867 return DISP_E_TYPEMISMATCH;
00868 default:
00869 memset(pvargDest, 0, sizeof(VARIANT));
00870 break;
00871 }
00872 break;
00873 case VT_NULL:
00874 case VT_ERROR:
00875 return DISP_E_TYPEMISMATCH;
00876 case VT_I2:
00877 SubChangeType(int16_t, pvarSrc->iVal, 1);
00878 break;
00879 case VT_I4:
00880 SubChangeType(int32_t, pvarSrc->lVal, 1);
00881 break;
00882 case VT_I8:
00883 SubChangeType(int64_t, pvarSrc->llVal, 1);
00884 break;
00885 case VT_R4:
00886 SubChangeType(float, pvarSrc->fltVal, 1);
00887 break;
00888 case VT_R8:
00889 SubChangeType(double, pvarSrc->dblVal, 1);
00890 break;
00891 case VT_CY:
00892 SubChangeType(int64_t, pvarSrc->cyVal.int64, 1);
00893 break;
00894 case VT_DATE:
00895 SubChangeType(DATE, pvarSrc->date, 1);
00896 break;
00897 case VT_BSTR:
00898 hr = Bstr2Variant(pvargDest, vt, pvarSrc->bstrVal);
00899 break;
00900 case VT_BOOL:
00901 SubChangeType(VARIANT_BOOL, pvarSrc->boolVal, 0);
00902 break;
00903 case VT_UI1:
00904 SubChangeType(uint8_t, pvarSrc->bVal, 1);
00905 break;
00906 case VT_UI2:
00907 SubChangeType(uint16_t, pvarSrc->uiVal, 1);
00908 break;
00909 case VT_UI4:
00910 SubChangeType(uint32_t, pvarSrc->ulVal, 1);
00911 break;
00912 case VT_UI8:
00913 SubChangeType(uint64_t, pvarSrc->ullVal, 1);
00914 break;
00915 default:
00916 return DISP_E_BADVARTYPE;
00917 }
00918
00919 if (SUCCEEDED(hr)) {
00920 pvargDest->vt = vt;
00921 }
00922
00923 return hr;
00924 }
00925 #endif
00926 #endif
00927
00928 #if (_DN_USE_VARIANT_API)
00929
00937 uint32_t
00938 ChangeVarType(VARIANT varSrc, uint16_t vt, void *pDest, uint32_t dwSize)
00939 {
00940 HRESULT hr = S_OK;
00941 uint32_t dwRet, dwCnt = 0;
00942 VARIANT vntTmp;
00943
00944 if ((pDest == NULL) || (dwSize == 0)) {
00945 return 0;
00946 }
00947
00948 VariantInit(&vntTmp);
00949
00950 if (varSrc.vt & VT_ARRAY) {
00951 int32_t i, lMax =
00952 (int32_t) varSrc.parray->rgsabound[0].cElements;
00953 void *pVal, *pPos = pDest;
00954
00955 SafeArrayAccessData(varSrc.parray, &pVal);
00956 for (i = 0; i < lMax; i++) {
00957 VariantClear(&vntTmp);
00958 switch (varSrc.vt ^ VT_ARRAY) {
00959 case VT_I2:
00960 vntTmp.vt = VT_I2;
00961 vntTmp.iVal = *((int16_t *) pVal + i);
00962 break;
00963 case VT_I4:
00964 vntTmp.vt = VT_I4;
00965 vntTmp.lVal = *((int32_t *) pVal + i);
00966 break;
00967 case VT_I8:
00968 vntTmp.vt = VT_I8;
00969 vntTmp.llVal = *((int64_t *) pVal + i);
00970 break;
00971 case VT_R4:
00972 vntTmp.vt = VT_R4;
00973 vntTmp.fltVal = *((float *) pVal + i);
00974 break;
00975 case VT_R8:
00976 vntTmp.vt = VT_R8;
00977 vntTmp.dblVal = *((double *) pVal + i);
00978 break;
00979 case VT_CY:
00980 vntTmp.vt = VT_CY;
00981 vntTmp.cyVal = *((CY *) pVal + i);
00982 break;
00983 case VT_DATE:
00984 vntTmp.vt = VT_DATE;
00985 vntTmp.date = *((DATE *) pVal + i);
00986 break;
00987 case VT_BSTR:
00988 vntTmp.vt = VT_BSTR;
00989 vntTmp.bstrVal = SysAllocString(*((BSTR *) pVal + i));
00990 break;
00991 case VT_BOOL:
00992 vntTmp.vt = VT_BOOL;
00993 vntTmp.boolVal = *((VARIANT_BOOL *) pVal + i);
00994 break;
00995 case VT_VARIANT:
00996 VariantCopy(&vntTmp, (VARIANT *) pVal + i);
00997 break;
00998 case VT_UI1:
00999 vntTmp.vt = VT_UI1;
01000 vntTmp.bVal = *((uint8_t *) pVal + i);
01001 break;
01002 case VT_UI2:
01003 vntTmp.vt = VT_UI2;
01004 vntTmp.uiVal = *((uint16_t *) pVal + i);
01005 break;
01006 case VT_UI4:
01007 vntTmp.vt = VT_UI4;
01008 vntTmp.ulVal = *((uint32_t *) pVal + i);
01009 break;
01010 case VT_UI8:
01011 vntTmp.vt = VT_UI8;
01012 vntTmp.ullVal = *((uint64_t *) pVal + i);
01013 break;
01014 default:
01015 hr = E_INVALIDARG;
01016 break;
01017 }
01018
01019 if (FAILED(hr)) {
01020 break;
01021 }
01022
01023 if (vt != VT_VARIANT) {
01024 if (vntTmp.vt & VT_ARRAY) {
01025 break;
01026 }
01027
01028 dwRet = ChangeVarType(vntTmp, vt, pPos, 1);
01029 if (dwRet == 0) {
01030 break;
01031 }
01032 } else {
01033 hr = VariantCopy((VARIANT*) pPos, &vntTmp);
01034 if (FAILED(hr)) {
01035 break;
01036 }
01037 dwRet = 1;
01038 }
01039
01040 dwCnt += dwRet;
01041 pPos = ((char *) pPos + varSrc.parray->cbElements);
01042
01043 if (dwCnt >= dwSize) {
01044 break;
01045 }
01046 }
01047 SafeArrayUnaccessData(varSrc.parray);
01048 } else {
01049 VariantCopy(&vntTmp, &varSrc);
01050 if (vt != VT_VARIANT) {
01051 hr = VariantChangeType(&vntTmp, &vntTmp, 0, vt);
01052 if (FAILED(hr)) {
01053 dwCnt = 0;
01054 goto exit_proc;
01055 }
01056 }
01057
01058 dwCnt = 1;
01059 switch (vt) {
01060 case VT_I2:
01061 *(int16_t *) pDest = vntTmp.iVal;
01062 break;
01063 case VT_I4:
01064 *(int32_t *) pDest = vntTmp.lVal;
01065 break;
01066 case VT_I8:
01067 *(int64_t *) pDest = vntTmp.llVal;
01068 break;
01069 case VT_R4:
01070 *(float *) pDest = vntTmp.fltVal;
01071 break;
01072 case VT_R8:
01073 *(double *) pDest = vntTmp.dblVal;
01074 break;
01075 case VT_CY:
01076 *(CY *) pDest = vntTmp.cyVal;
01077 break;
01078 case VT_DATE:
01079 *(DATE *) pDest = vntTmp.date;
01080 break;
01081 case VT_BSTR:
01082 *(BSTR *) pDest = SysAllocString(vntTmp.bstrVal);
01083 break;
01084 case VT_BOOL:
01085 *(VARIANT_BOOL *) pDest = vntTmp.boolVal ? VARIANT_TRUE : VARIANT_FALSE;
01086 break;
01087 case VT_VARIANT:
01088 VariantCopy((VARIANT *) pDest, &vntTmp);
01089 break;
01090 case VT_UI1:
01091 *(uint8_t *) pDest = vntTmp.bVal;
01092 break;
01093 case VT_UI2:
01094 *(uint16_t *) pDest = vntTmp.uiVal;
01095 break;
01096 case VT_UI4:
01097 *(uint32_t *) pDest = vntTmp.ulVal;
01098 break;
01099 case VT_UI8:
01100 *(uint64_t *) pDest = vntTmp.ullVal;
01101 break;
01102 default:
01103 dwCnt = 0;
01104 break;
01105 }
01106 }
01107
01108 exit_proc:
01109 VariantClear(&vntTmp);
01110
01111 return dwCnt;
01112 }
01113
01122 HRESULT
01123 GetOptionValue(BSTR bstrSrc, BSTR bstrKey, uint16_t vt, VARIANT *pvarDest)
01124 {
01125 HRESULT hr = S_OK;
01126 int iLevelCount = 0, bGetTitle = 0;
01127 long lTitleTerm;
01128 uint16_t i, uiLenTarget = 0, uiLenOptTitle = 0, uiLenOneOpt = 0;
01129 wchar_t *wchTmp, *wchPos, wchStart = -1, wchEnd = -1;
01130 BSTR bstrTmp, bstrTarget, bstrOptTitle, bstrOneOpt;
01131 VARIANT vntTmp;
01132
01133 if ((bstrKey == NULL) || (pvarDest == NULL)) {
01134 return E_INVALIDARG;
01135 }
01136
01137 if (bstrSrc != NULL) {
01138 bstrTarget = SysAllocString(bstrSrc);
01139 } else {
01140 bstrTarget = SysAllocString(L"");
01141 }
01142
01143 bstrOptTitle = SysAllocString(L"");
01144 bstrOneOpt = SysAllocString(L"");
01145
01146 uiLenTarget = SysStringLen(bstrTarget);
01147 wchTmp = bstrTarget;
01148
01149 for (i = 0; i <= uiLenTarget; i++, wchTmp++) {
01150
01151 if (!iLevelCount) {
01152 switch (*wchTmp) {
01153 case L'(':
01154 case L')':
01155 wchStart = L'(';
01156 wchEnd = L')';
01157 break;
01158 case L'[':
01159 case L']':
01160 wchStart = L'[';
01161 wchEnd = L']';
01162 break;
01163 case L'{':
01164 case L'}':
01165 wchStart = L'{';
01166 wchEnd = L'}';
01167 break;
01168 case L'<':
01169 case L'>':
01170 wchStart = L'<';
01171 wchEnd = L'>';
01172 break;
01173 default:
01174 break;
01175 }
01176 }
01177
01178
01179 if (*wchTmp == wchStart) {
01180 iLevelCount++;
01181 if (iLevelCount == 1) {
01182 memcpy(wchTmp, wchTmp + 1, sizeof(wchar_t) * (uiLenTarget - i));
01183 uiLenTarget--;
01184 i--;
01185 wchTmp--;
01186 continue;
01187 }
01188 }
01189 else if (*wchTmp == wchEnd) {
01190 iLevelCount--;
01191
01192 if (iLevelCount < 0) {
01193 hr = E_FAIL;
01194 goto exit_proc;
01195 }
01196
01197 if (!iLevelCount) {
01198 memcpy(wchTmp, wchTmp + 1, sizeof(wchar_t) * (uiLenTarget - i));
01199 uiLenTarget--;
01200 i--;
01201 wchTmp--;
01202 continue;
01203 }
01204 }
01205
01206
01207 if (!iLevelCount) {
01208 if (*wchTmp == L'=') {
01209 if (bGetTitle) {
01210 hr = E_FAIL;
01211 goto exit_proc;
01212 }
01213
01214 if (uiLenOptTitle > 0) {
01215 SysFreeString(bstrOptTitle);
01216 bstrOptTitle = SysAllocStringLen(wchTmp - uiLenOptTitle,
01217 uiLenOptTitle);
01218 uiLenOptTitle = 0;
01219 }
01220
01221 bGetTitle = 1;
01222 continue;
01223 }
01224
01225 if (*wchTmp == L',' || *wchTmp == L'\0') {
01226 if (uiLenOneOpt > 0) {
01227 SysFreeString(bstrOneOpt);
01228 bstrOneOpt = SysAllocStringLen(wchTmp - uiLenOneOpt,
01229 uiLenOneOpt);
01230 uiLenOneOpt = 0;
01231 }
01232
01233 bstrTmp = bstrOptTitle;
01234 wchPos = bstrTmp;
01235 while (wchPos[0] == L' ') {
01236 wchPos++;
01237 }
01238
01239 lTitleTerm = wcslen(wchPos) - 1;
01240 while (wchPos[lTitleTerm] == L' ') {
01241 wchPos[lTitleTerm] = L'\0';
01242 lTitleTerm--;
01243 }
01244
01245 bstrOptTitle = SysAllocString(wchPos);
01246 SysFreeString(bstrTmp);
01247
01248 if (!_wcsicmp(bstrOptTitle, bstrKey)) {
01249 if (!SysStringLen(bstrOneOpt)) {
01250 if (vt == VT_BOOL) {
01251 pvarDest->vt = VT_BOOL;
01252 pvarDest->boolVal = VARIANT_TRUE;
01253 } else {
01254 VariantClear(pvarDest);
01255 }
01256 hr = S_OK;
01257 goto exit_proc;
01258 }
01259 break;
01260 }
01261
01262 if (*wchTmp == L',') {
01263 SysFreeString(bstrOptTitle);
01264 bstrOptTitle = SysAllocString(L"");
01265 uiLenOptTitle = 0;
01266
01267 SysFreeString(bstrOneOpt);
01268 bstrOneOpt = SysAllocString(L"");
01269 uiLenOneOpt = 0;
01270
01271 bGetTitle = 0;
01272 continue;
01273 } else {
01274 VariantClear(pvarDest);
01275 hr = S_OK;
01276 goto exit_proc;
01277 }
01278 }
01279 }
01280
01281 if (bGetTitle) {
01282 uiLenOneOpt++;
01283 } else {
01284 uiLenOptTitle++;
01285 }
01286 }
01287
01288 if (iLevelCount != 0) {
01289 hr = E_FAIL;
01290 goto exit_proc;
01291 }
01292
01293 bstrTmp = bstrOneOpt;
01294 wchPos = bstrTmp;
01295 while (wchPos[0] == L' ') {
01296 wchPos++;
01297 }
01298
01299 lTitleTerm = wcslen(wchPos) - 1;
01300 while (wchPos[lTitleTerm] == L' ') {
01301 wchPos[lTitleTerm] = L'\0';
01302 lTitleTerm--;
01303 }
01304
01305 bstrOneOpt = SysAllocString(wchPos);
01306 SysFreeString(bstrTmp);
01307
01308 vntTmp.vt = VT_BSTR;
01309 vntTmp.bstrVal = bstrOneOpt;
01310
01311 hr = VariantChangeType(pvarDest, &vntTmp, 0, vt);
01312
01313 exit_proc: SysFreeString(bstrTarget);
01314 SysFreeString(bstrOptTitle);
01315 SysFreeString(bstrOneOpt);
01316
01317 return hr;
01318 }
01319 #endif
01320
01321 #if (_DN_USE_BSTR_API)
01322
01327 wchar_t*
01328 ConvertMultiByte2WideChar(const char* chSrc)
01329 {
01330 wchar_t* chDest = NULL;
01331
01332 if(chSrc != NULL) {
01333 #ifdef _USE_WIN_API
01334 int iLen = MultiByteToWideChar(CP_ACP, 0, chSrc, -1, NULL, 0);
01335 if(iLen > 0) {
01336 chDest = (wchar_t*)malloc(sizeof(wchar_t)*iLen);
01337 if(chDest == NULL) return NULL;
01338 MultiByteToWideChar(CP_ACP, 0, chSrc, -1, chDest, iLen);
01339 }
01340 #else
01341 char* locale = setlocale(LC_ALL, setlocale(LC_CTYPE, ""));
01342 int iLen = mbstowcs(NULL, chSrc, 0) + 1;
01343 if(iLen > 0) {
01344 chDest = (wchar_t*)malloc(sizeof(wchar_t)*iLen);
01345 if(chDest == NULL) return NULL;
01346 mbstowcs(chDest, chSrc, iLen);
01347 }
01348 setlocale(LC_ALL, locale);
01349 #endif
01350 }
01351
01352 return chDest;
01353 }
01354
01360 char*
01361 ConvertWideChar2MultiByte(const wchar_t* chSrc)
01362 {
01363 char* chDest = NULL;
01364
01365 if(chSrc != NULL) {
01366 #ifdef _USE_WIN_API
01367 int iLen = WideCharToMultiByte(CP_ACP, 0, chSrc, -1, NULL, 0, NULL, NULL);
01368 if(iLen > 0) {
01369 chDest = (char*)malloc(iLen);
01370 if(chDest == NULL) return NULL;
01371 WideCharToMultiByte(CP_ACP, 0, chSrc, -1, chDest, iLen, NULL, NULL);
01372 }
01373 #else
01374 char* locale = setlocale(LC_ALL, setlocale(LC_CTYPE, ""));
01375 int iLen = wcstombs(NULL, chSrc, 0) + 1;
01376 if(iLen > 0) {
01377 chDest = (char*)malloc(iLen);
01378 if(chDest == NULL) return NULL;
01379 wcstombs(chDest, chSrc, iLen);
01380 }
01381 setlocale(LC_ALL, locale);
01382 #endif
01383 }
01384
01385 return chDest;
01386 }
01387 #endif