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.

649 lines
15 KiB

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