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.

404 lines
10 KiB

  1. //---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1995
  5. //
  6. // File: cenumvar.cxx
  7. //
  8. // Contents: Windows NT 3.5 Enumerator Code
  9. //
  10. // CWinNTNamespaceEnum::Create
  11. // CWinNTNamespaceEnum::CWinNTNamespaceEnum
  12. // CWinNTNamespaceEnum::~CWinNTNamespaceEnum
  13. // CWinNTNamespaceEnum::QueryInterface
  14. // CWinNTNamespaceEnum::AddRef
  15. // CWinNTNamespaceEnum::Release
  16. // CWinNTNamespaceEnum::Next
  17. // CWinNTNamespaceEnum::Skip
  18. // CWinNTNamespaceEnum::Clone
  19. //
  20. // History:
  21. //----------------------------------------------------------------------------
  22. #include "winnt.hxx"
  23. #pragma hdrstop
  24. //+---------------------------------------------------------------------------
  25. //
  26. // Function: CWinNTNamespaceEnum::Create
  27. //
  28. // Synopsis:
  29. //
  30. // Arguments: [pCollection]
  31. // [ppEnumVariant]
  32. //
  33. // Returns: HRESULT
  34. //
  35. // Modifies:
  36. //
  37. // History: 01-30-95 krishnag Created.
  38. //
  39. //----------------------------------------------------------------------------
  40. HRESULT
  41. CWinNTNamespaceEnum::Create(
  42. CWinNTNamespaceEnum FAR* FAR* ppenumvariant,
  43. VARIANT var,
  44. CWinNTCredentials& Credentials
  45. )
  46. {
  47. HRESULT hr = S_OK;
  48. CWinNTNamespaceEnum FAR* penumvariant = NULL;
  49. penumvariant = new CWinNTNamespaceEnum();
  50. if (penumvariant == NULL){
  51. hr = E_OUTOFMEMORY;
  52. BAIL_ON_FAILURE(hr);
  53. }
  54. hr = ObjectTypeList::CreateObjectTypeList(
  55. var,
  56. &penumvariant->_pObjList
  57. );
  58. BAIL_ON_FAILURE(hr);
  59. penumvariant->_Credentials = Credentials;
  60. *ppenumvariant = penumvariant;
  61. RRETURN(hr);
  62. error:
  63. if (penumvariant) {
  64. delete penumvariant;
  65. }
  66. RRETURN_EXP_IF_ERR(hr);
  67. }
  68. //+---------------------------------------------------------------------------
  69. //
  70. // Function: CWinNTNamespaceEnum::CWinNTNamespaceEnum
  71. //
  72. // Synopsis:
  73. //
  74. //
  75. // Arguments:
  76. //
  77. //
  78. // Returns:
  79. //
  80. // Modifies:
  81. //
  82. // History: 01-30-95 krishnag Created.
  83. //
  84. //----------------------------------------------------------------------------
  85. CWinNTNamespaceEnum::CWinNTNamespaceEnum()
  86. {
  87. _pObjList = NULL;
  88. _pBuffer = 0;
  89. _dwObjectReturned = 0;
  90. _dwObjectCurrentEntry = 0;
  91. _dwObjectTotal = 0;
  92. _dwResumeHandle = 0;
  93. _bNoMore = FALSE;
  94. }
  95. //+---------------------------------------------------------------------------
  96. //
  97. // Function: CWinNTNamespaceEnum::~CWinNTNamespaceEnum
  98. //
  99. // Synopsis:
  100. //
  101. //
  102. // Arguments:
  103. //
  104. // Returns:
  105. //
  106. // Modifies:
  107. //
  108. // History: 01-30-95 krishnag Created.
  109. //
  110. //----------------------------------------------------------------------------
  111. CWinNTNamespaceEnum::~CWinNTNamespaceEnum()
  112. {
  113. if (_pBuffer) {
  114. NetApiBufferFree(_pBuffer);
  115. }
  116. if ( _pObjList )
  117. delete _pObjList;
  118. }
  119. HRESULT
  120. CWinNTNamespaceEnum::EnumObjects(
  121. DWORD ObjectType,
  122. ULONG cElements,
  123. VARIANT FAR * pvar,
  124. ULONG FAR * pcElementFetched
  125. )
  126. {
  127. HRESULT hr = S_OK;
  128. switch (ObjectType) {
  129. case WINNT_DOMAIN_ID:
  130. hr = EnumDomains(cElements, pvar, pcElementFetched);
  131. RRETURN(hr);
  132. default:
  133. RRETURN(S_FALSE);
  134. }
  135. }
  136. HRESULT
  137. CWinNTNamespaceEnum::EnumObjects(
  138. ULONG cElements,
  139. VARIANT FAR* pvar,
  140. ULONG FAR* pcElementFetched
  141. )
  142. {
  143. DWORD i;
  144. ULONG cRequested = 0;
  145. ULONG cFetchedByPath = 0;
  146. ULONG cTotalFetched = 0;
  147. VARIANT FAR* pPathvar = pvar;
  148. HRESULT hr = S_FALSE;
  149. DWORD ObjectType;
  150. for (i = 0; i < cElements; i++) {
  151. VariantInit(&pvar[i]);
  152. }
  153. cRequested = cElements;
  154. while (SUCCEEDED(_pObjList->GetCurrentObject(&ObjectType)) &&
  155. ((hr = EnumObjects(ObjectType,
  156. cRequested,
  157. pPathvar,
  158. &cFetchedByPath)) == S_FALSE )) {
  159. pPathvar += cFetchedByPath;
  160. cRequested -= cFetchedByPath;
  161. cTotalFetched += cFetchedByPath;
  162. cFetchedByPath = 0;
  163. if (FAILED(_pObjList->Next())){
  164. if (pcElementFetched)
  165. *pcElementFetched = cTotalFetched;
  166. RRETURN(S_FALSE);
  167. }
  168. }
  169. if (pcElementFetched) {
  170. *pcElementFetched = cTotalFetched + cFetchedByPath;
  171. }
  172. RRETURN_EXP_IF_ERR(hr);
  173. }
  174. //+---------------------------------------------------------------------------
  175. //
  176. // Function: CWinNTNamespaceEnum::Next
  177. //
  178. // Synopsis: Returns cElements number of requested NetOle objects in the
  179. // array supplied in pvar.
  180. //
  181. // Arguments: [cElements] -- The number of elements requested by client
  182. // [pvar] -- ptr to array of VARIANTs to for return objects
  183. // [pcElementFetched] -- if non-NULL, then number of elements
  184. // -- actually returned is placed here
  185. //
  186. // Returns: HRESULT -- S_OK if number of elements requested are returned
  187. // -- S_FALSE if number of elements is < requested
  188. //
  189. // Modifies:
  190. //
  191. // History: 11-3-95 krishnag Created.
  192. //
  193. //----------------------------------------------------------------------------
  194. STDMETHODIMP
  195. CWinNTNamespaceEnum::Next(
  196. ULONG cElements,
  197. VARIANT FAR* pvar,
  198. ULONG FAR* pcElementFetched
  199. )
  200. {
  201. ULONG cElementFetched = 0;
  202. HRESULT hr = S_OK;
  203. if (NULL == pvar)
  204. {
  205. //
  206. // Returning S_FALSE to indicate that we aren't returning
  207. // as many elements as requested.
  208. //
  209. hr = S_FALSE;
  210. }
  211. else
  212. {
  213. hr = EnumObjects(
  214. cElements,
  215. pvar,
  216. &cElementFetched
  217. );
  218. }
  219. if (pcElementFetched) {
  220. *pcElementFetched = cElementFetched;
  221. }
  222. RRETURN_EXP_IF_ERR(hr);
  223. }
  224. HRESULT
  225. CWinNTNamespaceEnum::EnumDomains(
  226. ULONG cElements,
  227. VARIANT FAR* pvar,
  228. ULONG FAR* pcElementFetched
  229. )
  230. {
  231. HRESULT hr = S_FALSE;
  232. IDispatch *pDispatch = NULL;
  233. DWORD i = 0;
  234. BOOL fRepeat = FALSE;
  235. DWORD dwFailureCount = 0;
  236. DWORD dwPermitFailure = 1000;
  237. while (i < cElements) {
  238. hr = GetDomainObject(&pDispatch);
  239. if (hr == S_FALSE) {
  240. break;
  241. }
  242. else if (FAILED(hr)) {
  243. //
  244. // Got an error while retrieving the object, ignore the
  245. // error and continue with the next object.
  246. // If continuously getting error more than dwPermitFailure,
  247. // make the return value S_FALSE, leave the loop.
  248. //
  249. if (fRepeat) {
  250. dwFailureCount++;
  251. if(dwFailureCount > dwPermitFailure) {
  252. hr = S_FALSE;
  253. break;
  254. }
  255. }
  256. else {
  257. fRepeat = TRUE;
  258. dwFailureCount = 1;
  259. }
  260. // we need to move the _dwObjectCurrentEntry
  261. _dwObjectCurrentEntry++;
  262. hr = S_OK;
  263. continue;
  264. }
  265. if (fRepeat) {
  266. fRepeat = FALSE;
  267. }
  268. VariantInit(&pvar[i]);
  269. pvar[i].vt = VT_DISPATCH;
  270. pvar[i].pdispVal = pDispatch;
  271. (*pcElementFetched)++;
  272. i++;
  273. }
  274. RRETURN_EXP_IF_ERR(hr);
  275. }
  276. HRESULT
  277. CWinNTNamespaceEnum::GetDomainObject(
  278. IDispatch ** ppDispatch
  279. )
  280. {
  281. HRESULT hr = S_OK;
  282. PSERVER_INFO_100 pServerInfo100 = NULL;
  283. NET_API_STATUS nasStatus = 0;
  284. if (!_pBuffer || (_dwObjectCurrentEntry == _dwObjectReturned)) {
  285. if (_pBuffer) {
  286. NetApiBufferFree(_pBuffer);
  287. _pBuffer = NULL;
  288. }
  289. _dwObjectCurrentEntry = 0;
  290. _dwObjectReturned = 0;
  291. if (_bNoMore) {
  292. RRETURN(S_FALSE);
  293. }
  294. nasStatus = NetServerEnum(
  295. NULL,
  296. 100,
  297. (LPBYTE *)&_pBuffer,
  298. MAX_PREFERRED_LENGTH,
  299. &_dwObjectReturned,
  300. &_dwObjectTotal,
  301. SV_TYPE_DOMAIN_ENUM,
  302. NULL,
  303. &_dwResumeHandle
  304. );
  305. //
  306. // The following if clause is to handle real errors; anything
  307. // other than ERROR_SUCCESS and ERROR_MORE_DATA
  308. //
  309. if ((nasStatus != ERROR_SUCCESS) && (nasStatus != ERROR_MORE_DATA)) {
  310. hr =S_FALSE;
  311. goto cleanup;
  312. }
  313. if (nasStatus == ERROR_SUCCESS) {
  314. _bNoMore = TRUE;
  315. }
  316. }
  317. //
  318. // Now send back the current object
  319. //
  320. //
  321. // There is a scenario where NetServerEnum returns ERROR_SUCCESS
  322. // when there is no data to send back. However the field
  323. // _dwObjectsReturned will also be 0. We need to check that and
  324. // bail out if necessary
  325. //
  326. if ((nasStatus == ERROR_SUCCESS) && _dwObjectReturned == 0){
  327. RRETURN(S_FALSE);
  328. }
  329. pServerInfo100 = (LPSERVER_INFO_100)_pBuffer;
  330. pServerInfo100 += _dwObjectCurrentEntry;
  331. //
  332. // We couldn't have any credentials coming in from a Namespace
  333. // enumeration, since you can't have credentials coming in from
  334. // a Namespace. So we use null credentials.
  335. //
  336. hr = CWinNTDomain::CreateDomain(
  337. L"WinNT:",
  338. pServerInfo100->sv100_name,
  339. ADS_OBJECT_BOUND,
  340. IID_IDispatch,
  341. _Credentials,
  342. (void **) ppDispatch
  343. );
  344. BAIL_IF_ERROR(hr);
  345. _dwObjectCurrentEntry++;
  346. RRETURN(S_OK);
  347. cleanup:
  348. *ppDispatch = NULL;
  349. return hr;
  350. }