Leaked source code of windows server 2003
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

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