Source code of Windows XP (NT5)
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.

274 lines
6.7 KiB

  1. #include "pch.h"
  2. #include "thisdll.h"
  3. PSTR DuplicateWideStringAsMultibyte(LPCWSTR pwszSource)
  4. {
  5. PSTR pszVal;
  6. char rgszBuffer[30];
  7. DWORD dwErr;
  8. int cch = WideCharToMultiByte(CP_ACP, 0, pwszSource, -1, rgszBuffer, 0, NULL, NULL);
  9. if (cch)
  10. {
  11. pszVal = (PSTR)CoTaskMemAlloc(cch*sizeof(CHAR));
  12. if (pszVal)
  13. {
  14. cch = WideCharToMultiByte(CP_ACP, 0, pwszSource, -1, pszVal, cch, NULL, NULL);
  15. return pszVal;
  16. }
  17. }
  18. else
  19. dwErr = GetLastError();
  20. return NULL;
  21. }
  22. HRESULT CoerceProperty(PROPVARIANT *pvar, VARTYPE vt)
  23. {
  24. BSTR bstr;
  25. switch (vt)
  26. {
  27. case VT_BSTR:
  28. switch (pvar->vt)
  29. {
  30. case VT_LPSTR:
  31. WCHAR wszBuffer[MAX_PATH];
  32. UINT cch;
  33. cch = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pvar->pszVal, -1, wszBuffer, 0);
  34. ASSERTMSG(cch<MAX_PATH, "Trying to convert a really long string");
  35. cch = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pvar->pszVal, -1, wszBuffer, cch);
  36. bstr = SysAllocString(wszBuffer);
  37. if (bstr!=NULL)
  38. {
  39. PropVariantClear(pvar);
  40. pvar->vt=VT_BSTR;
  41. pvar->bstrVal = bstr;
  42. return S_OK;
  43. }
  44. return E_FAIL;
  45. case VT_LPWSTR:
  46. bstr = SysAllocString(pvar->pwszVal);
  47. if (bstr!=NULL)
  48. {
  49. PropVariantClear(pvar);
  50. pvar->vt = VT_BSTR;
  51. pvar->bstrVal = bstr;
  52. return S_OK;
  53. }
  54. return E_FAIL;
  55. case VT_BSTR:
  56. return S_OK;
  57. default:
  58. return E_FAIL;
  59. }
  60. case VT_UI4:
  61. switch (pvar->vt)
  62. {
  63. case VT_UI2:
  64. pvar->vt = VT_UI4;
  65. pvar->ulVal &= 0xffff;
  66. return S_OK;
  67. case VT_UI4:
  68. return S_OK;
  69. case VT_UI8:
  70. //note that we lose the high order DWORD
  71. pvar->vt = VT_UI4;
  72. pvar->uhVal.HighPart = 0;
  73. pvar->ulVal = pvar->uhVal.LowPart;
  74. return S_OK;
  75. default:
  76. return E_FAIL;
  77. }
  78. case VT_UI8:
  79. switch (pvar->vt)
  80. {
  81. case VT_UI2:
  82. pvar->vt = VT_UI8;
  83. pvar->uhVal.LowPart = pvar->uiVal & 0xffff;
  84. return S_OK;
  85. case VT_UI4:
  86. pvar->vt = VT_UI8;
  87. pvar->uhVal.LowPart = pvar->ulVal;
  88. pvar->uhVal.HighPart = 0;
  89. return S_OK;
  90. case VT_UI8:
  91. return S_OK;
  92. default:
  93. return E_FAIL;
  94. }
  95. default:
  96. return E_FAIL;
  97. }
  98. }
  99. HRESULT WMTFromPropVariant(BYTE *buffer, WORD *cbLen, WMT_ATTR_DATATYPE *pdatatype, PROPVARIANT *pvar)
  100. {
  101. int cch;
  102. switch (pvar->vt)
  103. {
  104. case VT_BSTR:
  105. case VT_LPWSTR:
  106. cch = *cbLen / sizeof(WCHAR); // Max number of chars we can put in the BYTE buffer
  107. StrCpyNW((LPWSTR)buffer, (pvar->bstrVal == NULL) ? L"" : pvar->bstrVal, cch);
  108. *pdatatype = WMT_TYPE_STRING;
  109. *cbLen = (WORD)(lstrlen((LPWSTR)buffer)+1) * sizeof(WCHAR);
  110. return S_OK;
  111. case VT_LPSTR:
  112. cch = MultiByteToWideChar(CP_ACP, 0, pvar->pszVal, -1, (LPWSTR)buffer, (*cbLen) / sizeof(WCHAR));
  113. if (cch == 0)
  114. {
  115. return E_FAIL;
  116. }
  117. *pdatatype = WMT_TYPE_STRING;
  118. *cbLen = (WORD)cch * sizeof(WCHAR);
  119. return S_OK;
  120. case VT_UI4:
  121. *((DWORD*)buffer) = pvar->ulVal;
  122. *pdatatype = WMT_TYPE_DWORD;
  123. *cbLen = sizeof(DWORD);
  124. return S_OK;
  125. case VT_UI8:
  126. *((ULONGLONG*)buffer) = pvar->hVal.QuadPart;
  127. *pdatatype = WMT_TYPE_QWORD;
  128. *cbLen = sizeof(ULONGLONG);
  129. return S_OK;
  130. case VT_BOOL:
  131. *pdatatype = WMT_TYPE_BOOL;
  132. *cbLen = 4;
  133. *((BOOL*)buffer) = pvar->boolVal;
  134. return S_OK;
  135. default:
  136. return E_FAIL;
  137. }
  138. }
  139. HRESULT PropVariantFromWMT(UCHAR *pData, WORD cbSize, WMT_ATTR_DATATYPE attrDataType, PROPVARIANT *pvar, VARTYPE vt)
  140. {
  141. PropVariantInit(pvar);
  142. pvar->vt = vt;
  143. switch (vt)
  144. {
  145. case VT_LPWSTR:
  146. case VT_LPSTR:
  147. case VT_BSTR:
  148. {
  149. WCHAR *pwszData, wszBuffer[32]; //Big enough to hold a wsprintf'ed 32 bit decimal
  150. switch (attrDataType)
  151. {
  152. case WMT_TYPE_WORD:
  153. case WMT_TYPE_DWORD:
  154. {
  155. DWORD dwVal = *((DWORD *)pData);
  156. if (attrDataType == WMT_TYPE_WORD)
  157. dwVal &= 0xffff;
  158. wsprintf(wszBuffer, L"%d", dwVal);
  159. pwszData = wszBuffer;
  160. }
  161. break;
  162. case WMT_TYPE_STRING:
  163. pwszData = cbSize ? (WCHAR*)pData : L"";
  164. break;
  165. default:
  166. return E_FAIL;
  167. }
  168. if (!pwszData) // Deal with NULL strings
  169. {
  170. pvar->pwszVal = NULL;
  171. return S_OK;
  172. }
  173. switch (vt)
  174. {
  175. case VT_LPWSTR:
  176. return SHStrDupW(pwszData, &pvar->pwszVal);
  177. case VT_LPSTR:
  178. pvar->pszVal = DuplicateWideStringAsMultibyte((LPCWSTR)pData);
  179. return pvar->pszVal ? S_OK : E_OUTOFMEMORY;
  180. case VT_BSTR:
  181. pvar->bstrVal = SysAllocString(pwszData);
  182. return pvar->bstrVal ? S_OK : E_OUTOFMEMORY;
  183. }
  184. }
  185. break;
  186. case VT_UI4:
  187. {
  188. if (cbSize == 0)
  189. return E_FAIL;
  190. DWORD dwVal = *((DWORD *)pData);
  191. if (attrDataType == WMT_TYPE_WORD)
  192. dwVal &= 0xffff;
  193. switch (attrDataType)
  194. {
  195. case WMT_TYPE_BOOL:
  196. case WMT_TYPE_DWORD:
  197. case WMT_TYPE_WORD:
  198. pvar->ulVal = dwVal;
  199. break;
  200. case WMT_TYPE_STRING:
  201. StrToIntExW((WCHAR*)pData, STIF_DEFAULT, &pvar->intVal);
  202. break;
  203. default:
  204. return E_FAIL;
  205. }
  206. }
  207. break;
  208. case VT_UI8:
  209. if (cbSize == 0)
  210. return E_FAIL;
  211. if (attrDataType == WMT_TYPE_QWORD)
  212. pvar->uhVal = *((ULARGE_INTEGER *)pData);
  213. break;
  214. case VT_BOOL:
  215. if (cbSize == 0)
  216. return E_FAIL;
  217. if (attrDataType == WMT_TYPE_BOOL)
  218. {
  219. pvar->boolVal = *((VARIANT_BOOL*)pData) ? VARIANT_TRUE : VARIANT_FALSE;
  220. break;
  221. }
  222. default:
  223. return E_FAIL;
  224. }
  225. return S_OK;
  226. }