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.

675 lines
16 KiB

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