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.

669 lines
16 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. cenumres.cxx
  5. Abstract:
  6. Contains methods for implementing the Enumeration of resources(open files)
  7. on a server. Has methods for the CWinNTResourcesCollection object
  8. as well as the CWinNTResourcesEnumVar object.
  9. Author:
  10. Ram Viswanathan (ramv) 03/12/96
  11. Revision History:
  12. --*/
  13. #include "winnt.hxx"
  14. #pragma hdrstop
  15. #if DBG
  16. DECLARE_INFOLEVEL(EnumRes);
  17. DECLARE_DEBUG(EnumRes);
  18. #define EnumResDebugOut(x) EnumResInlineDebugOut x
  19. #endif
  20. CWinNTResourcesCollection::CWinNTResourcesCollection()
  21. {
  22. _pszServerADsPath = NULL;
  23. _pszServerName = NULL;
  24. _pszBasePath = NULL;
  25. _pszUserName = NULL;
  26. _pDispMgr = NULL;
  27. _pCResourcesEnumVar = NULL;
  28. ENLIST_TRACKING(CWinNTResourcesCollection);
  29. }
  30. CWinNTResourcesCollection::~CWinNTResourcesCollection()
  31. {
  32. if(_pszServerADsPath){
  33. FreeADsStr(_pszServerADsPath);
  34. }
  35. if(_pszServerName){
  36. FreeADsStr(_pszServerName);
  37. }
  38. if(_pszBasePath){
  39. FreeADsStr(_pszBasePath);
  40. }
  41. if(_pszUserName){
  42. FreeADsStr(_pszUserName);
  43. }
  44. delete _pDispMgr;
  45. if(_pCResourcesEnumVar){
  46. _pCResourcesEnumVar->Release();
  47. }
  48. }
  49. HRESULT
  50. CWinNTResourcesCollection::Create(LPTSTR pszServerADsPath,
  51. LPTSTR pszBasePath,
  52. LPTSTR pszUserName,
  53. CWinNTCredentials& Credentials,
  54. CWinNTResourcesCollection
  55. ** ppCWinNTResourcesCollection )
  56. {
  57. BOOL fStatus = FALSE, LastError;
  58. HRESULT hr;
  59. CWinNTResourcesCollection *pCWinNTResourcesCollection = NULL;
  60. POBJECTINFO pServerObjectInfo = NULL;
  61. //
  62. // create the Resources collection object
  63. //
  64. pCWinNTResourcesCollection = new CWinNTResourcesCollection();
  65. if(pCWinNTResourcesCollection == NULL){
  66. hr = E_OUTOFMEMORY;
  67. goto cleanup;
  68. }
  69. pCWinNTResourcesCollection->_pszServerADsPath =
  70. AllocADsStr(pszServerADsPath);
  71. if (!pCWinNTResourcesCollection->_pszServerADsPath){
  72. hr = E_OUTOFMEMORY;
  73. goto cleanup;
  74. }
  75. hr = BuildObjectInfo(pszServerADsPath,
  76. &pServerObjectInfo
  77. );
  78. BAIL_IF_ERROR(hr);
  79. pCWinNTResourcesCollection->_pszServerName =
  80. AllocADsStr(pServerObjectInfo->ComponentArray[1]);
  81. if(!(pCWinNTResourcesCollection->_pszServerName)){
  82. hr = E_OUTOFMEMORY;
  83. goto cleanup;
  84. }
  85. pCWinNTResourcesCollection->_Credentials = Credentials;
  86. hr = pCWinNTResourcesCollection->_Credentials.RefServer(
  87. pCWinNTResourcesCollection->_pszServerName);
  88. BAIL_IF_ERROR(hr);
  89. if(pszBasePath){
  90. pCWinNTResourcesCollection->_pszBasePath =
  91. AllocADsStr(pszBasePath);
  92. if(!(pCWinNTResourcesCollection->_pszBasePath)){
  93. hr = E_OUTOFMEMORY;
  94. goto cleanup;
  95. }
  96. }
  97. if(pszUserName){
  98. pCWinNTResourcesCollection->_pszUserName =
  99. AllocADsStr(pszUserName);
  100. if(!(pCWinNTResourcesCollection->_pszUserName)){
  101. hr = E_OUTOFMEMORY;
  102. goto cleanup;
  103. }
  104. }
  105. pCWinNTResourcesCollection->_pDispMgr = new CAggregatorDispMgr;
  106. if (pCWinNTResourcesCollection->_pDispMgr == NULL){
  107. hr = E_OUTOFMEMORY;
  108. goto cleanup;
  109. }
  110. hr = LoadTypeInfoEntry(pCWinNTResourcesCollection->_pDispMgr,
  111. LIBID_ADs,
  112. IID_IADsCollection,
  113. (IADsCollection *)pCWinNTResourcesCollection,
  114. DISPID_NEWENUM
  115. );
  116. BAIL_IF_ERROR(hr);
  117. *ppCWinNTResourcesCollection =pCWinNTResourcesCollection;
  118. cleanup:
  119. if(pServerObjectInfo){
  120. FreeObjectInfo(pServerObjectInfo);
  121. }
  122. if(SUCCEEDED(hr)){
  123. RRETURN(hr);
  124. }
  125. delete pCWinNTResourcesCollection;
  126. RRETURN_EXP_IF_ERR(hr);
  127. }
  128. /* IUnknown methods for Resources collection object */
  129. STDMETHODIMP
  130. CWinNTResourcesCollection::QueryInterface(REFIID riid, LPVOID FAR* ppvObj)
  131. {
  132. if(!ppvObj){
  133. RRETURN(E_POINTER);
  134. }
  135. if (IsEqualIID(riid, IID_IUnknown))
  136. {
  137. *ppvObj = this;
  138. }
  139. else if (IsEqualIID(riid, IID_IDispatch))
  140. {
  141. *ppvObj = (IDispatch *)this;
  142. }
  143. else if (IsEqualIID(riid, IID_ISupportErrorInfo))
  144. {
  145. *ppvObj = (ISupportErrorInfo FAR *) this;
  146. }
  147. else if (IsEqualIID(riid, IID_IADsCollection))
  148. {
  149. *ppvObj = (IADsCollection FAR *)this;
  150. }
  151. else
  152. {
  153. *ppvObj = NULL;
  154. return E_NOINTERFACE;
  155. }
  156. ((LPUNKNOWN)*ppvObj)->AddRef();
  157. RRETURN(S_OK);
  158. }
  159. /* ISupportErrorInfo method */
  160. STDMETHODIMP
  161. CWinNTResourcesCollection::InterfaceSupportsErrorInfo(
  162. THIS_ REFIID riid
  163. )
  164. {
  165. if (IsEqualIID(riid, IID_IADsCollection)) {
  166. RRETURN(S_OK);
  167. } else {
  168. RRETURN(S_FALSE);
  169. }
  170. }
  171. DEFINE_IDispatch_Implementation(CWinNTResourcesCollection);
  172. /* IADsCollection methods */
  173. STDMETHODIMP
  174. CWinNTResourcesCollection::get__NewEnum(THIS_ IUnknown * FAR* retval)
  175. {
  176. HRESULT hr;
  177. CWinNTResourcesEnumVar *pCResourcesEnumVar = NULL;
  178. if(!retval){
  179. RRETURN_EXP_IF_ERR(E_POINTER);
  180. }
  181. *retval = NULL;
  182. hr = CWinNTResourcesEnumVar::Create(_pszServerADsPath,
  183. _pszBasePath,
  184. _pszUserName,
  185. _Credentials,
  186. &pCResourcesEnumVar
  187. );
  188. BAIL_ON_FAILURE(hr);
  189. ADsAssert(pCResourcesEnumVar);
  190. _pCResourcesEnumVar = pCResourcesEnumVar;
  191. hr = _pCResourcesEnumVar->QueryInterface(IID_IUnknown,
  192. (void **)retval
  193. );
  194. BAIL_ON_FAILURE(hr);
  195. RRETURN(S_OK);
  196. error:
  197. delete pCResourcesEnumVar;
  198. RRETURN_EXP_IF_ERR(hr);
  199. }
  200. STDMETHODIMP
  201. CWinNTResourcesCollection::GetObject(THIS_ BSTR bstrResourceName,
  202. VARIANT *pvar
  203. )
  204. {
  205. HRESULT hr = S_OK;
  206. DWORD dwFileId;
  207. IDispatch *pDispatch = NULL;
  208. if(!bstrResourceName || !pvar){
  209. RRETURN_EXP_IF_ERR(E_ADS_BAD_PARAMETER);
  210. }
  211. //
  212. // convert the job name into a fileid
  213. //
  214. dwFileId = (DWORD)_wtol(bstrResourceName);
  215. hr = CWinNTResource::Create(_pszServerADsPath,
  216. dwFileId,
  217. ADS_OBJECT_BOUND,
  218. IID_IDispatch,
  219. _Credentials,
  220. (void **)&pDispatch
  221. );
  222. BAIL_IF_ERROR(hr);
  223. //
  224. // stick this IDispatch pointer into caller provided variant
  225. //
  226. VariantInit(pvar);
  227. V_VT(pvar) = VT_DISPATCH;
  228. V_DISPATCH(pvar) = pDispatch;
  229. cleanup:
  230. RRETURN_EXP_IF_ERR(hr);
  231. }
  232. STDMETHODIMP
  233. CWinNTResourcesCollection::Add(THIS_ BSTR bstrName, VARIANT varNewItem)
  234. {
  235. RRETURN_EXP_IF_ERR(E_NOTIMPL);
  236. }
  237. STDMETHODIMP
  238. CWinNTResourcesCollection::Remove(THIS_ BSTR bstrResourceName)
  239. {
  240. RRETURN_EXP_IF_ERR(E_NOTIMPL);
  241. }
  242. //
  243. // CWinNTResourcesEnumVar methods follow
  244. //
  245. //+---------------------------------------------------------------------------
  246. //
  247. // Function: CWinNTResourcesEnumVar::CWinNTResourcesEnumVar
  248. //
  249. // Synopsis:
  250. //
  251. //
  252. // Arguments:
  253. //
  254. //
  255. // Returns:
  256. //
  257. // Modifies:
  258. //
  259. // History: 11-22-95 RamV Created.
  260. //
  261. //----------------------------------------------------------------------------
  262. CWinNTResourcesEnumVar::CWinNTResourcesEnumVar()
  263. {
  264. _pszServerADsPath = NULL;
  265. _pszServerName = NULL;
  266. _pszBasePath = NULL;
  267. _pszUserName = NULL;
  268. _pbResources = NULL;
  269. _cElements = 0;
  270. _lLBound = 0;
  271. _lCurrentPosition = _lLBound;
  272. _dwTotalEntries = 0;
  273. _dwResumeHandle = 0;
  274. }
  275. //+---------------------------------------------------------------------------
  276. //
  277. // Function: CWinNTResourcesEnumVar::~CWinNTResourcesEnumVar
  278. //
  279. // Synopsis:
  280. //
  281. //
  282. // Arguments:
  283. //
  284. // Returns:
  285. //
  286. // Modifies:
  287. //
  288. // History: 11-22-95 RamV Created.
  289. //
  290. //----------------------------------------------------------------------------
  291. CWinNTResourcesEnumVar::~CWinNTResourcesEnumVar()
  292. {
  293. if(_pszServerADsPath){
  294. FreeADsStr(_pszServerADsPath);
  295. }
  296. if(_pszServerName){
  297. FreeADsStr(_pszServerName);
  298. }
  299. if(_pszBasePath){
  300. FreeADsStr(_pszBasePath);
  301. }
  302. if(_pszUserName){
  303. FreeADsStr(_pszUserName);
  304. }
  305. if(_pbResources){
  306. NetApiBufferFree(_pbResources);
  307. }
  308. }
  309. HRESULT CWinNTResourcesEnumVar::Create(LPTSTR pszServerADsPath,
  310. LPTSTR pszBasePath,
  311. LPTSTR pszUserName,
  312. CWinNTCredentials& Credentials,
  313. CWinNTResourcesEnumVar
  314. **ppCResourcesEnumVar)
  315. {
  316. HRESULT hr;
  317. BOOL fStatus = FALSE;
  318. POBJECTINFO pServerObjectInfo = NULL;
  319. CWinNTResourcesEnumVar FAR* pCResourcesEnumVar = NULL;
  320. *ppCResourcesEnumVar = NULL;
  321. pCResourcesEnumVar = new CWinNTResourcesEnumVar();
  322. if (pCResourcesEnumVar == NULL){
  323. hr = E_OUTOFMEMORY;
  324. goto cleanup;
  325. }
  326. pCResourcesEnumVar->_pszServerADsPath =
  327. AllocADsStr(pszServerADsPath);
  328. if(!(pCResourcesEnumVar->_pszServerADsPath)){
  329. hr = E_OUTOFMEMORY;
  330. goto cleanup;
  331. }
  332. hr = BuildObjectInfo(pszServerADsPath,
  333. &pServerObjectInfo
  334. );
  335. BAIL_IF_ERROR(hr);
  336. pCResourcesEnumVar->_pszServerName =
  337. AllocADsStr(pServerObjectInfo->ComponentArray[1]);
  338. if(!(pCResourcesEnumVar->_pszServerName)){
  339. hr = E_OUTOFMEMORY;
  340. goto cleanup;
  341. }
  342. pCResourcesEnumVar->_Credentials = Credentials;
  343. hr = pCResourcesEnumVar->_Credentials.RefServer(
  344. pCResourcesEnumVar->_pszServerName);
  345. BAIL_IF_ERROR(hr);
  346. if(pszBasePath){
  347. pCResourcesEnumVar->_pszBasePath =
  348. AllocADsStr(pszBasePath);
  349. if(!(pCResourcesEnumVar->_pszBasePath)){
  350. hr = E_OUTOFMEMORY;
  351. goto cleanup;
  352. }
  353. }
  354. if(pszUserName){
  355. pCResourcesEnumVar->_pszUserName =
  356. AllocADsStr(pszUserName);
  357. if(!(pCResourcesEnumVar->_pszUserName)){
  358. hr = E_OUTOFMEMORY;
  359. goto cleanup;
  360. }
  361. }
  362. *ppCResourcesEnumVar = pCResourcesEnumVar;
  363. cleanup:
  364. if(pServerObjectInfo){
  365. FreeObjectInfo(pServerObjectInfo);
  366. }
  367. if(SUCCEEDED(hr)){
  368. RRETURN(hr);
  369. }
  370. delete pCResourcesEnumVar;
  371. RRETURN_EXP_IF_ERR(hr);
  372. }
  373. //+---------------------------------------------------------------------------
  374. //
  375. // Function: CWinNTResourcesEnumVar::Next
  376. //
  377. // Synopsis: Returns cElements number of requested Resource objects in the
  378. // array supplied in pvar.
  379. //
  380. // Arguments: [cElements] -- The number of elements requested by client
  381. // [pvar] -- ptr to array of VARIANTs to for return objects
  382. // [pcElementFetched] -- if non-NULL, then number of elements
  383. // -- actually returned is placed here
  384. //
  385. // Returns: HRESULT -- S_OK if number of elements requested are returned
  386. // -- S_FALSE if number of elements is < requested
  387. //
  388. // Modifies:
  389. //
  390. // History: 11-27-95 RamV Created.
  391. //
  392. //----------------------------------------------------------------------------
  393. STDMETHODIMP
  394. CWinNTResourcesEnumVar::Next(ULONG ulNumElementsRequested,
  395. VARIANT FAR* pvar,
  396. ULONG FAR* pulNumFetched)
  397. {
  398. HRESULT hresult;
  399. ULONG l;
  400. LONG lNewCurrent;
  401. ULONG lNumFetched;
  402. LPFILE_INFO_3 lpFileInfo;
  403. VARIANT v;
  404. IDispatch * pDispatch = NULL;
  405. if (pulNumFetched != NULL){
  406. *pulNumFetched = 0;
  407. }
  408. //
  409. // Initialize the elements to be returned
  410. //
  411. for (l=0; l<ulNumElementsRequested; l++){
  412. VariantInit(&pvar[l]);
  413. }
  414. if(!_pbResources || (_lCurrentPosition == _lLBound +(LONG)_cElements) ){
  415. if (_pbResources){
  416. NetApiBufferFree(_pbResources);
  417. _pbResources = NULL;
  418. }
  419. if(_dwTotalEntries == _cElements && (_dwTotalEntries !=0)){
  420. //
  421. // we got all elements already, no need to do another call
  422. //
  423. RRETURN(S_FALSE);
  424. }
  425. hresult = WinNTEnumResources(_pszServerName,
  426. _pszBasePath,
  427. _pszUserName,
  428. &_pbResources,
  429. &_cElements,
  430. &_dwTotalEntries,
  431. &_dwResumeHandle
  432. );
  433. if(hresult == S_FALSE){
  434. RRETURN(S_FALSE);
  435. }
  436. _lLBound = 0;
  437. _lCurrentPosition = _lLBound;
  438. }
  439. //
  440. // Get each element and place it into the return array
  441. // Don't request more than we have
  442. //
  443. for (lNewCurrent=_lCurrentPosition, lNumFetched=0;
  444. lNewCurrent<(LONG)(_lLBound+_cElements) &&
  445. lNumFetched < ulNumElementsRequested;
  446. lNewCurrent++, lNumFetched++){
  447. lpFileInfo = (LPFILE_INFO_3)(_pbResources + \
  448. lNewCurrent*sizeof(FILE_INFO_3));
  449. hresult = CWinNTResource::Create((LPTSTR)_pszServerADsPath,
  450. ADS_OBJECT_BOUND,
  451. lpFileInfo->fi3_id,
  452. IID_IDispatch,
  453. _Credentials,
  454. (void **)&pDispatch);
  455. BAIL_ON_FAILURE(hresult);
  456. VariantInit(&v);
  457. V_VT(&v) = VT_DISPATCH;
  458. V_DISPATCH(&v) = pDispatch;
  459. pvar[lNumFetched] = v;
  460. }
  461. //
  462. // Tell the caller how many we got (which may be less than the number
  463. // requested), and save the current position
  464. //
  465. if (pulNumFetched != NULL)
  466. *pulNumFetched = lNumFetched;
  467. _lCurrentPosition = lNewCurrent;
  468. //
  469. // If we're returning less than they asked for return S_FALSE, but
  470. // they still have the data (S_FALSE is a success code)
  471. //
  472. return (lNumFetched < ulNumElementsRequested) ?
  473. S_FALSE
  474. : S_OK;
  475. error:
  476. if(FAILED(hresult)){
  477. #if DBG
  478. EnumResDebugOut((DEB_TRACE,
  479. "hresult Failed with value: %ld \n", hresult ));
  480. #endif
  481. }
  482. RRETURN(S_FALSE);
  483. }
  484. HRESULT
  485. WinNTEnumResources(LPTSTR pszServerName,
  486. LPTSTR pszBasePath,
  487. LPTSTR pszUserName,
  488. LPBYTE * ppMem,
  489. LPDWORD pdwEntriesRead,
  490. LPDWORD pdwTotalEntries,
  491. PDWORD_PTR pdwResumeHandle
  492. )
  493. {
  494. LPBYTE pMem = NULL;
  495. CWinNTResource *pCWinNTResource = NULL;
  496. IDispatch *pDispatch = NULL;
  497. VARIANT v;
  498. LONG l;
  499. HRESULT hr;
  500. NET_API_STATUS nasStatus;
  501. UNREFERENCED_PARAMETER(pszBasePath);
  502. UNREFERENCED_PARAMETER(pszUserName);
  503. //
  504. // why have these parameters if they are unreferenced? Because we might
  505. // use them in the future when more complicated enumerations are desired
  506. //
  507. nasStatus = NetFileEnum(pszServerName,
  508. NULL,
  509. pszUserName,
  510. 3, //info level desired
  511. ppMem,
  512. MAX_PREFERRED_LENGTH,
  513. pdwEntriesRead,
  514. pdwTotalEntries,
  515. pdwResumeHandle
  516. );
  517. if(*ppMem == NULL|| (nasStatus != NERR_Success)){
  518. //
  519. // no more entries returned by NetFileEnum
  520. //
  521. RRETURN(S_FALSE);
  522. }
  523. RRETURN(S_OK);
  524. }