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.

233 lines
5.1 KiB

  1. //
  2. // utils.h
  3. //
  4. inline BOOL IsNumericVariant(VARIANT * pVar)
  5. {
  6. while(V_VT(pVar) == (VT_BYREF|VT_VARIANT)) {
  7. pVar = V_VARIANTREF(pVar);
  8. }
  9. if((V_VT(pVar) & ~(VT_TYPEMASK|VT_BYREF)) != 0) {
  10. return FALSE;
  11. }
  12. switch(V_VT(pVar) & VT_TYPEMASK) {
  13. case VT_I1:
  14. case VT_I2:
  15. case VT_I4:
  16. case VT_I8:
  17. case VT_INT:
  18. case VT_UI1:
  19. case VT_UI2:
  20. case VT_UI4:
  21. case VT_UI8:
  22. case VT_UINT:
  23. case VT_R4:
  24. case VT_R8:
  25. return TRUE;
  26. }
  27. return FALSE;
  28. }
  29. inline BOOL IsArrayVariant(VARIANT * pVar,SAFEARRAY **pArray,VARTYPE *pType)
  30. {
  31. while(V_VT(pVar) == (VT_BYREF|VT_VARIANT)) {
  32. pVar = V_VARIANTREF(pVar);
  33. }
  34. if(!V_ISARRAY(pVar)) {
  35. return FALSE;
  36. }
  37. if(pArray) {
  38. if(V_ISBYREF(pVar)) {
  39. *pArray = *V_ARRAYREF(pVar);
  40. } else {
  41. *pArray = V_ARRAY(pVar);
  42. }
  43. }
  44. if(pType) {
  45. *pType = V_VT(pVar) & VT_TYPEMASK;
  46. }
  47. return TRUE;
  48. }
  49. inline BOOL IsCollectionVariant(VARIANT * pVar,IEnumVARIANT ** pCollection)
  50. {
  51. while(V_VT(pVar) == (VT_BYREF|VT_VARIANT)) {
  52. pVar = V_VARIANTREF(pVar);
  53. }
  54. CComVariant v;
  55. HRESULT hr = v.ChangeType(VT_DISPATCH,pVar);
  56. if(FAILED(hr)) {
  57. return FALSE;
  58. }
  59. //
  60. // look for an enumerator
  61. //
  62. DISPPARAMS params;
  63. LPDISPATCH pDisp = V_DISPATCH(&v);
  64. if(!pDisp) {
  65. return FALSE;
  66. }
  67. CComVariant result;
  68. params.cArgs = 0;
  69. params.cNamedArgs = 0;
  70. hr = pDisp->Invoke(DISPID_NEWENUM,
  71. IID_NULL,
  72. 0,
  73. DISPATCH_PROPERTYGET,
  74. &params,
  75. &result,
  76. NULL,
  77. NULL);
  78. if(FAILED(hr)) {
  79. return FALSE;
  80. }
  81. hr = result.ChangeType(VT_UNKNOWN);
  82. if(FAILED(hr)) {
  83. return FALSE;
  84. }
  85. IEnumVARIANT *pEnum;
  86. hr = V_UNKNOWN(&result)->QueryInterface(IID_IEnumVARIANT,(LPVOID*)&pEnum);
  87. if(FAILED(hr)) {
  88. return FALSE;
  89. }
  90. if(pCollection) {
  91. *pCollection = pEnum;
  92. } else {
  93. pEnum->Release();
  94. }
  95. return TRUE;
  96. }
  97. inline BOOL IsMultiValueVariant(VARIANT * pVar)
  98. {
  99. while(V_VT(pVar) == (VT_BYREF|VT_VARIANT)) {
  100. pVar = V_VARIANTREF(pVar);
  101. }
  102. if(IsArrayVariant(pVar,NULL,NULL)) {
  103. return TRUE;
  104. }
  105. if(IsCollectionVariant(pVar,NULL)) {
  106. return TRUE;
  107. }
  108. return FALSE;
  109. }
  110. inline BOOL IsNoArg(LPVARIANT pVar)
  111. {
  112. //
  113. // explicit "no parameter"
  114. //
  115. if((V_VT(pVar) == VT_ERROR) && (V_ERROR(pVar) == (DISP_E_PARAMNOTFOUND))) {
  116. return TRUE;
  117. }
  118. return FALSE;
  119. }
  120. inline BOOL IsBlank(LPVARIANT pVar)
  121. {
  122. //
  123. // flexable "no parameter" allow 'null' 'nothing'
  124. //
  125. if(IsNoArg(pVar)) {
  126. return TRUE;
  127. }
  128. while(V_VT(pVar) == (VT_BYREF|VT_VARIANT)) {
  129. pVar = V_VARIANTREF(pVar);
  130. }
  131. if(V_ISBYREF(pVar) && !V_BYREF(pVar)) {
  132. return TRUE;
  133. }
  134. if((V_VT(pVar) == VT_EMPTY) || (V_VT(pVar) == VT_NULL)) {
  135. return TRUE;
  136. }
  137. if(((V_VT(pVar) == VT_UNKNOWN) || (V_VT(pVar) == VT_DISPATCH)) && !V_UNKNOWN(pVar)) {
  138. return TRUE;
  139. }
  140. if(((V_VT(pVar) == (VT_BYREF|VT_UNKNOWN)) || (V_VT(pVar) == (VT_BYREF|VT_DISPATCH)))
  141. && !(V_UNKNOWNREF(pVar) && *V_UNKNOWNREF(pVar))) {
  142. return TRUE;
  143. }
  144. //
  145. // consider everything else as a parameter
  146. //
  147. return FALSE;
  148. }
  149. inline BOOL IsBlankString(LPVARIANT pVar)
  150. {
  151. //
  152. // even more flexable, allow "" too
  153. //
  154. if(IsBlank(pVar)) {
  155. return TRUE;
  156. }
  157. while(V_VT(pVar) == (VT_BYREF|VT_VARIANT)) {
  158. pVar = V_VARIANTREF(pVar);
  159. }
  160. if(V_VT(pVar) == VT_BSTR) {
  161. return SysStringLen(V_BSTR(pVar)) ? FALSE : TRUE;
  162. }
  163. if(V_VT(pVar) == (VT_BYREF|VT_BSTR)) {
  164. return (V_BSTRREF(pVar) && SysStringLen(*V_BSTRREF(pVar))) ? FALSE : TRUE;
  165. }
  166. return FALSE;
  167. }
  168. #define DEVFLAGS_HIDDEN 0x00000001
  169. #define DEVFLAGS_SINGLEPROFILE 0x00000002
  170. #define DEVFLAGS_ALL 0x00000003
  171. inline HRESULT TranslateDeviceFlags(LPVARIANT flags,DWORD * di_flags)
  172. {
  173. long fl_final = 0;
  174. CComVariant v;
  175. HRESULT hr;
  176. if(flags) {
  177. if(IsNoArg(flags)) {
  178. fl_final = 0;
  179. } else if(IsNumericVariant(flags)) {
  180. hr = v.ChangeType(VT_I4,flags);
  181. if(FAILED(hr)) {
  182. return hr;
  183. }
  184. fl_final = V_I4(&v);
  185. } else {
  186. return E_INVALIDARG;
  187. }
  188. }
  189. *di_flags = 0;
  190. if(fl_final & ~(DEVFLAGS_ALL)) {
  191. return E_INVALIDARG;
  192. }
  193. if(!(fl_final & DEVFLAGS_HIDDEN)) {
  194. *di_flags |= DIGCF_PRESENT;
  195. }
  196. if(fl_final & DEVFLAGS_SINGLEPROFILE) {
  197. *di_flags |= DIGCF_PROFILE;
  198. }
  199. return S_OK;
  200. }
  201. inline HRESULT GetOptionalString(LPVARIANT param,CComVariant &store,LPCWSTR *pString)
  202. {
  203. HRESULT hr;
  204. *pString = NULL;
  205. if(param) {
  206. if(IsBlank(param)) {
  207. return S_OK;
  208. }
  209. hr = store.ChangeType(VT_BSTR,param);
  210. if(FAILED(hr)) {
  211. return hr;
  212. }
  213. *pString = V_BSTR(&store);
  214. return S_OK;
  215. }
  216. return S_OK;
  217. }