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.

388 lines
7.2 KiB

  1. //---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1995
  5. //
  6. // File: object.cxx
  7. //
  8. // Contents: Windows NT 3.5 Enumerator Code
  9. //
  10. // History:
  11. //----------------------------------------------------------------------------
  12. #include "winnt.hxx"
  13. #pragma hdrstop
  14. HRESULT
  15. BuildObjectArray(
  16. VARIANT var,
  17. SAFEARRAY ** ppFilter,
  18. DWORD * pdwNumElements
  19. );
  20. HRESULT
  21. BuildDefaultObjectArray(
  22. PFILTERS pFilters,
  23. DWORD dwMaxFilters,
  24. SAFEARRAY ** ppFilter,
  25. DWORD * pdwNumElements
  26. );
  27. ObjectTypeList::ObjectTypeList()
  28. {
  29. _pObjList = NULL;
  30. _dwCurrentIndex = 0;
  31. _dwMaxElements = 0;
  32. _dwUBound = 0;
  33. _dwLBound = 0;
  34. }
  35. HRESULT
  36. ObjectTypeList::CreateObjectTypeList(
  37. VARIANT vFilter,
  38. ObjectTypeList ** ppObjectTypeList
  39. )
  40. {
  41. ObjectTypeList * pObjectTypeList = NULL;
  42. HRESULT hr = S_OK;
  43. pObjectTypeList = new ObjectTypeList;
  44. if (!pObjectTypeList) {
  45. hr = E_OUTOFMEMORY;
  46. BAIL_ON_FAILURE(hr);
  47. }
  48. hr = BuildObjectArray(
  49. vFilter,
  50. &pObjectTypeList->_pObjList,
  51. &pObjectTypeList->_dwMaxElements
  52. );
  53. if (FAILED(hr)) {
  54. hr = BuildDefaultObjectArray(
  55. gpFilters,
  56. gdwMaxFilters,
  57. &pObjectTypeList->_pObjList,
  58. &pObjectTypeList->_dwMaxElements
  59. );
  60. BAIL_ON_FAILURE(hr);
  61. }
  62. hr = SafeArrayGetUBound(
  63. pObjectTypeList->_pObjList,
  64. 1,
  65. (long FAR *)&pObjectTypeList->_dwUBound
  66. );
  67. BAIL_ON_FAILURE(hr);
  68. hr = SafeArrayGetLBound(
  69. pObjectTypeList->_pObjList,
  70. 1,
  71. (long FAR *)&pObjectTypeList->_dwLBound
  72. );
  73. BAIL_ON_FAILURE(hr);
  74. pObjectTypeList->_dwCurrentIndex = pObjectTypeList->_dwLBound;
  75. *ppObjectTypeList = pObjectTypeList;
  76. RRETURN(S_OK);
  77. error:
  78. if (pObjectTypeList) {
  79. delete pObjectTypeList;
  80. }
  81. RRETURN_EXP_IF_ERR(hr);
  82. }
  83. ObjectTypeList::~ObjectTypeList()
  84. {
  85. HRESULT hr = S_OK;
  86. if (_pObjList) {
  87. hr = SafeArrayDestroy(_pObjList);
  88. }
  89. }
  90. HRESULT
  91. ObjectTypeList::GetCurrentObject(
  92. PDWORD pdwObject
  93. )
  94. {
  95. HRESULT hr = S_OK;
  96. if (_dwCurrentIndex > _dwUBound) {
  97. return(E_FAIL);
  98. }
  99. hr = SafeArrayGetElement(
  100. _pObjList,
  101. (long FAR *)&_dwCurrentIndex,
  102. (void *)pdwObject
  103. );
  104. RRETURN_EXP_IF_ERR(hr);
  105. }
  106. HRESULT
  107. ObjectTypeList::Next()
  108. {
  109. HRESULT hr = S_OK;
  110. _dwCurrentIndex++;
  111. if (_dwCurrentIndex > _dwUBound) {
  112. return(E_FAIL);
  113. }
  114. RRETURN_EXP_IF_ERR(hr);
  115. }
  116. HRESULT
  117. ObjectTypeList::Reset()
  118. {
  119. HRESULT hr = S_OK;
  120. _dwCurrentIndex = _dwLBound;
  121. return(hr);
  122. }
  123. HRESULT
  124. IsValidFilter(
  125. LPWSTR ObjectName,
  126. DWORD *pdwFilterId,
  127. PFILTERS pFilters,
  128. DWORD dwMaxFilters
  129. )
  130. {
  131. DWORD i = 0;
  132. for (i = 0; i < dwMaxFilters; i++) {
  133. #ifdef WIN95
  134. if (!_wcsicmp(ObjectName, (pFilters + i)->szObjectName)) {
  135. #else
  136. if (CompareStringW(
  137. LOCALE_SYSTEM_DEFAULT,
  138. NORM_IGNORECASE,
  139. ObjectName,
  140. -1,
  141. (pFilters +i)->szObjectName,
  142. -1
  143. ) == CSTR_EQUAL ) {
  144. #endif
  145. *pdwFilterId = (pFilters + i)->dwFilterId;
  146. RRETURN(S_OK);
  147. }
  148. }
  149. *pdwFilterId = 0;
  150. RRETURN(E_FAIL);
  151. }
  152. HRESULT
  153. BuildDefaultObjectArray(
  154. PFILTERS pFilters,
  155. DWORD dwMaxFilters,
  156. SAFEARRAY ** ppFilter,
  157. DWORD * pdwNumElements
  158. )
  159. {
  160. DWORD i;
  161. HRESULT hr = S_OK;
  162. SAFEARRAYBOUND sabNewArray;
  163. SAFEARRAY * pFilter = NULL;
  164. sabNewArray.cElements = dwMaxFilters;
  165. sabNewArray.lLbound = 0;
  166. pFilter = SafeArrayCreate(
  167. VT_I4,
  168. 1,
  169. &sabNewArray
  170. );
  171. if (!pFilter){
  172. hr = E_OUTOFMEMORY;
  173. BAIL_ON_FAILURE(hr);
  174. }
  175. for (i = 0; i < dwMaxFilters; i++) {
  176. hr = SafeArrayPutElement(
  177. pFilter,
  178. (long *)&i,
  179. (void *)&((pFilters + i)->dwFilterId)
  180. );
  181. BAIL_ON_FAILURE(hr);
  182. }
  183. *ppFilter = pFilter;
  184. *pdwNumElements = dwMaxFilters;
  185. RRETURN(S_OK);
  186. error:
  187. if (pFilter) {
  188. SafeArrayDestroy(pFilter);
  189. }
  190. *ppFilter = NULL;
  191. *pdwNumElements = 0;
  192. RRETURN(hr);
  193. }
  194. HRESULT
  195. BuildObjectArray(
  196. VARIANT var,
  197. SAFEARRAY ** ppFilter,
  198. DWORD * pdwNumElements
  199. )
  200. {
  201. LONG uDestCount = 0;
  202. LONG dwSLBound = 0;
  203. LONG dwSUBound = 0;
  204. VARIANT v;
  205. VARIANT varDest;
  206. LONG i;
  207. HRESULT hr = S_OK;
  208. SAFEARRAYBOUND sabNewArray;
  209. DWORD dwFilterId;
  210. SAFEARRAY * pFilter = NULL;
  211. if (!(V_VT(&var) == (VT_VARIANT|VT_ARRAY))) {
  212. RRETURN(E_FAIL);
  213. }
  214. //
  215. // Check that there is only one dimension in this array
  216. //
  217. if ((V_ARRAY(&var))->cDims != 1) {
  218. hr = E_FAIL;
  219. BAIL_ON_FAILURE(hr);
  220. }
  221. //
  222. // Check that there is atleast one element in this array
  223. //
  224. if ((V_ARRAY(&var))->rgsabound[0].cElements == 0){
  225. hr = E_FAIL;
  226. BAIL_ON_FAILURE(hr);
  227. }
  228. //
  229. // We know that this is a valid single dimension array
  230. //
  231. hr = SafeArrayGetLBound(V_ARRAY(&var),
  232. 1,
  233. (long FAR *)&dwSLBound
  234. );
  235. BAIL_ON_FAILURE(hr);
  236. hr = SafeArrayGetUBound(V_ARRAY(&var),
  237. 1,
  238. (long FAR *)&dwSUBound
  239. );
  240. BAIL_ON_FAILURE(hr);
  241. sabNewArray.cElements = dwSUBound - dwSLBound + 1;
  242. sabNewArray.lLbound = dwSLBound;
  243. pFilter = SafeArrayCreate(
  244. VT_I4,
  245. 1,
  246. &sabNewArray
  247. );
  248. if (!pFilter) {
  249. hr = E_OUTOFMEMORY;
  250. BAIL_ON_FAILURE(hr);
  251. }
  252. for (i = dwSLBound; i <= dwSUBound; i++) {
  253. VariantInit(&v);
  254. hr = SafeArrayGetElement(V_ARRAY(&var),
  255. (long FAR *)&i,
  256. &v
  257. );
  258. if (FAILED(hr)) {
  259. continue;
  260. }
  261. hr = IsValidFilter(
  262. V_BSTR(&v),
  263. &dwFilterId,
  264. gpFilters,
  265. gdwMaxFilters
  266. );
  267. if (FAILED(hr)) {
  268. VariantClear(&v);
  269. continue;
  270. }
  271. VariantClear(&v);
  272. hr = SafeArrayPutElement(
  273. pFilter,
  274. (long*)&uDestCount,
  275. (void *)&dwFilterId
  276. );
  277. if(FAILED(hr)){
  278. continue;
  279. }
  280. uDestCount++;
  281. }
  282. //
  283. // There was nothing of value that could be retrieved from the
  284. // filter.
  285. //
  286. if ( !uDestCount) {
  287. hr = E_FAIL;
  288. BAIL_ON_FAILURE(hr);
  289. }
  290. *pdwNumElements = uDestCount;
  291. *ppFilter = pFilter;
  292. RRETURN(S_OK);
  293. error:
  294. if (pFilter) {
  295. SafeArrayDestroy(pFilter);
  296. }
  297. *ppFilter = NULL;
  298. *pdwNumElements = 0;
  299. RRETURN_EXP_IF_ERR(hr);
  300. }