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.

744 lines
18 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. cenumses.cxx
  5. Abstract:
  6. Contains methods for implementing the Enumeration of session on a
  7. server. Has methods for the CWinNTSessionsCollection object
  8. as well as the CWinNTSessionsEnumVar 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(EnumSession);
  17. DECLARE_DEBUG(EnumSession);
  18. #define EnumSessionDebugOut(x) EnumSessionInlineDebugOut x
  19. #endif
  20. CWinNTSessionsCollection::CWinNTSessionsCollection()
  21. {
  22. _pszServerADsPath = NULL;
  23. _pszServerName = NULL;
  24. _pszClientName = NULL;
  25. _pszUserName = NULL;
  26. _pDispMgr = NULL;
  27. _pCSessionsEnumVar = NULL;
  28. ENLIST_TRACKING(CWinNTSessionsCollection);
  29. }
  30. CWinNTSessionsCollection::~CWinNTSessionsCollection()
  31. {
  32. if(_pszServerADsPath){
  33. FreeADsStr(_pszServerADsPath);
  34. }
  35. if(_pszServerName){
  36. FreeADsStr(_pszServerName);
  37. }
  38. if(_pszClientName){
  39. FreeADsStr(_pszClientName);
  40. }
  41. if(_pszUserName){
  42. FreeADsStr(_pszUserName);
  43. }
  44. delete _pDispMgr;
  45. if(_pCSessionsEnumVar){
  46. _pCSessionsEnumVar->Release();
  47. }
  48. }
  49. HRESULT
  50. CWinNTSessionsCollection::Create(LPTSTR pszServerADsPath,
  51. LPTSTR pszClientName,
  52. LPTSTR pszUserName,
  53. CWinNTCredentials& Credentials,
  54. CWinNTSessionsCollection
  55. ** ppCWinNTSessionsCollection )
  56. {
  57. BOOL fStatus = FALSE;
  58. HRESULT hr;
  59. CWinNTSessionsCollection *pCWinNTSessionsCollection = NULL;
  60. POBJECTINFO pServerObjectInfo = NULL;
  61. //
  62. // create the Sessions collection object
  63. //
  64. pCWinNTSessionsCollection = new CWinNTSessionsCollection();
  65. if(pCWinNTSessionsCollection == NULL){
  66. hr = E_OUTOFMEMORY;
  67. goto cleanup;
  68. }
  69. pCWinNTSessionsCollection->_pszServerADsPath =
  70. AllocADsStr(pszServerADsPath);
  71. if(!(pCWinNTSessionsCollection->_pszServerADsPath)){
  72. hr = E_OUTOFMEMORY;
  73. goto cleanup;
  74. }
  75. hr = BuildObjectInfo(pszServerADsPath,
  76. &pServerObjectInfo
  77. );
  78. BAIL_IF_ERROR(hr);
  79. pCWinNTSessionsCollection->_pszServerName =
  80. AllocADsStr(pServerObjectInfo->ComponentArray[1]);
  81. if(!(pCWinNTSessionsCollection->_pszServerName)){
  82. hr = E_OUTOFMEMORY;
  83. goto cleanup;
  84. }
  85. pCWinNTSessionsCollection->_Credentials = Credentials;
  86. hr = pCWinNTSessionsCollection->_Credentials.RefServer(
  87. pCWinNTSessionsCollection->_pszServerName);
  88. BAIL_IF_ERROR(hr);
  89. if (pszUserName){
  90. pCWinNTSessionsCollection->_pszUserName =
  91. AllocADsStr(pszUserName);
  92. if(!(pCWinNTSessionsCollection->_pszUserName)){
  93. hr = E_OUTOFMEMORY;
  94. goto cleanup;
  95. }
  96. }
  97. if(pszClientName){
  98. pCWinNTSessionsCollection->_pszClientName =
  99. AllocADsStr(pszClientName);
  100. if(!(pCWinNTSessionsCollection->_pszClientName)){
  101. hr = E_OUTOFMEMORY;
  102. goto cleanup;
  103. }
  104. }
  105. pCWinNTSessionsCollection->_pDispMgr = new CAggregatorDispMgr;
  106. if (pCWinNTSessionsCollection->_pDispMgr == NULL){
  107. hr = E_OUTOFMEMORY;
  108. goto cleanup;
  109. }
  110. hr = LoadTypeInfoEntry(pCWinNTSessionsCollection->_pDispMgr,
  111. LIBID_ADs,
  112. IID_IADsCollection,
  113. (IADsCollection *)pCWinNTSessionsCollection,
  114. DISPID_NEWENUM
  115. );
  116. BAIL_IF_ERROR(hr);
  117. *ppCWinNTSessionsCollection = pCWinNTSessionsCollection;
  118. cleanup:
  119. if(pServerObjectInfo){
  120. FreeObjectInfo(pServerObjectInfo);
  121. }
  122. if(SUCCEEDED(hr)){
  123. RRETURN(hr);
  124. }
  125. delete pCWinNTSessionsCollection;
  126. RRETURN_EXP_IF_ERR (hr);
  127. }
  128. /* IUnknown methods for Sessions collection object */
  129. STDMETHODIMP
  130. CWinNTSessionsCollection::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. CWinNTSessionsCollection::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(CWinNTSessionsCollection);
  172. /* IADsCollection methods */
  173. STDMETHODIMP
  174. CWinNTSessionsCollection::get__NewEnum(THIS_ IUnknown * FAR* retval)
  175. {
  176. HRESULT hr;
  177. CWinNTSessionsEnumVar *pCSessionsEnumVar = NULL;
  178. if(!retval){
  179. RRETURN_EXP_IF_ERR(E_POINTER);
  180. }
  181. *retval = NULL;
  182. hr = CWinNTSessionsEnumVar::Create(_pszServerADsPath,
  183. _pszClientName,
  184. _pszUserName,
  185. _Credentials,
  186. &pCSessionsEnumVar);
  187. BAIL_ON_FAILURE(hr);
  188. ADsAssert(pCSessionsEnumVar);
  189. _pCSessionsEnumVar = pCSessionsEnumVar;
  190. hr = _pCSessionsEnumVar->QueryInterface(IID_IUnknown, (void **)retval);
  191. BAIL_ON_FAILURE(hr);
  192. RRETURN(S_OK);
  193. error:
  194. delete pCSessionsEnumVar;
  195. RRETURN_EXP_IF_ERR(hr);
  196. }
  197. STDMETHODIMP
  198. CWinNTSessionsCollection::GetObject(THIS_ BSTR bstrSessionName,
  199. VARIANT *pvar
  200. )
  201. {
  202. LPTSTR pszSession = NULL;
  203. LPTSTR pszUserName;
  204. LPTSTR pszClientName;
  205. IDispatch *pDispatch = NULL;
  206. HRESULT hr;
  207. if(!bstrSessionName || !pvar){
  208. RRETURN_EXP_IF_ERR(E_ADS_BAD_PARAMETER);
  209. }
  210. pszSession = AllocADsStr(bstrSessionName);
  211. if(!pszSession){
  212. RRETURN_EXP_IF_ERR(E_OUTOFMEMORY);
  213. }
  214. hr = SplitIntoUserAndClient(pszSession, &pszUserName, &pszClientName);
  215. BAIL_IF_ERROR(hr);
  216. hr = CWinNTSession::Create(_pszServerADsPath,
  217. pszClientName,
  218. pszUserName,
  219. ADS_OBJECT_BOUND,
  220. IID_IDispatch,
  221. _Credentials,
  222. (void **)&pDispatch);
  223. BAIL_IF_ERROR(hr);
  224. //
  225. // stick this IDispatch pointer into caller provided variant
  226. //
  227. VariantInit(pvar);
  228. V_VT(pvar) = VT_DISPATCH;
  229. V_DISPATCH(pvar) = pDispatch;
  230. cleanup:
  231. FreeADsStr(pszSession);
  232. RRETURN_EXP_IF_ERR(hr);
  233. }
  234. STDMETHODIMP
  235. CWinNTSessionsCollection::Add(THIS_ BSTR bstrName, VARIANT varNewItem)
  236. {
  237. RRETURN_EXP_IF_ERR(E_NOTIMPL);
  238. }
  239. STDMETHODIMP
  240. CWinNTSessionsCollection::Remove(THIS_ BSTR bstrSessionName)
  241. {
  242. LPTSTR pszSession = NULL;
  243. LPTSTR pszUserName;
  244. LPTSTR pszClientName;
  245. TCHAR szUncClientName[MAX_PATH];
  246. TCHAR szUncServerName[MAX_PATH];
  247. HRESULT hr;
  248. NET_API_STATUS nasStatus;
  249. pszSession = AllocADsStr(bstrSessionName);
  250. if(!pszSession){
  251. RRETURN_EXP_IF_ERR(E_OUTOFMEMORY);
  252. }
  253. hr = SplitIntoUserAndClient(pszSession, &pszUserName, &pszClientName);
  254. BAIL_IF_ERROR(hr);
  255. hr = MakeUncName(_pszServerName, szUncServerName);
  256. BAIL_IF_ERROR(hr);
  257. hr = MakeUncName(pszClientName, szUncClientName);
  258. BAIL_IF_ERROR(hr);
  259. nasStatus = NetSessionDel(szUncServerName,
  260. szUncClientName,
  261. pszUserName );
  262. if(nasStatus != NERR_Success){
  263. hr = HRESULT_FROM_WIN32(nasStatus);
  264. }
  265. cleanup:
  266. FreeADsStr(pszSession);
  267. RRETURN_EXP_IF_ERR(hr);
  268. }
  269. //
  270. // CWinNTSessionsEnumVar methods follow
  271. //
  272. //+---------------------------------------------------------------------------
  273. //
  274. // Function: CWinNTSessionsEnumVar::CWinNTSessionsEnumVar
  275. //
  276. // Synopsis:
  277. //
  278. //
  279. // Arguments:
  280. //
  281. //
  282. // Returns:
  283. //
  284. // Modifies:
  285. //
  286. // History: 11-22-95 RamV Created.
  287. //
  288. //----------------------------------------------------------------------------
  289. CWinNTSessionsEnumVar::CWinNTSessionsEnumVar()
  290. {
  291. _pszServerName = NULL;
  292. _pszServerADsPath = NULL;
  293. _pszClientName = NULL;
  294. _pszUserName = NULL;
  295. _pbSessions = NULL;
  296. _cElements = 0;
  297. _lLBound = 0;
  298. _lCurrentPosition = _lLBound;
  299. _dwTotalEntries = 0;
  300. _dwResumeHandle = 0;
  301. }
  302. //+---------------------------------------------------------------------------
  303. //
  304. // Function: CWinNTSessionsEnumVar::~CWinNTSessionsEnumVar
  305. //
  306. // Synopsis:
  307. //
  308. //
  309. // Arguments:
  310. //
  311. // Returns:
  312. //
  313. // Modifies:
  314. //
  315. // History: 11-22-95 RamV Created.
  316. //
  317. //----------------------------------------------------------------------------
  318. CWinNTSessionsEnumVar::~CWinNTSessionsEnumVar()
  319. {
  320. if(_pszServerName){
  321. FreeADsStr(_pszServerName);
  322. }
  323. if(_pszServerADsPath){
  324. FreeADsStr(_pszServerADsPath);
  325. }
  326. if(_pszClientName){
  327. FreeADsStr(_pszClientName);
  328. }
  329. if(_pszUserName){
  330. FreeADsStr(_pszUserName);
  331. }
  332. if(_pbSessions){
  333. NetApiBufferFree(_pbSessions);
  334. }
  335. }
  336. HRESULT CWinNTSessionsEnumVar::Create(LPTSTR pszServerADsPath,
  337. LPTSTR pszClientName,
  338. LPTSTR pszUserName,
  339. CWinNTCredentials& Credentials,
  340. CWinNTSessionsEnumVar \
  341. **ppCSessionsEnumVar)
  342. {
  343. HRESULT hr;
  344. BOOL fStatus = FALSE;
  345. POBJECTINFO pServerObjectInfo = NULL;
  346. CWinNTSessionsEnumVar FAR* pCSessionsEnumVar = NULL;
  347. *ppCSessionsEnumVar = NULL;
  348. pCSessionsEnumVar = new CWinNTSessionsEnumVar();
  349. if (pCSessionsEnumVar == NULL){
  350. hr = E_OUTOFMEMORY;
  351. goto cleanup;
  352. }
  353. pCSessionsEnumVar->_pszServerADsPath =
  354. AllocADsStr(pszServerADsPath);
  355. if(!(pCSessionsEnumVar->_pszServerADsPath)){
  356. hr = E_OUTOFMEMORY;
  357. goto cleanup;
  358. }
  359. hr = BuildObjectInfo(pszServerADsPath,
  360. &pServerObjectInfo
  361. );
  362. BAIL_IF_ERROR(hr);
  363. pCSessionsEnumVar->_pszServerName =
  364. AllocADsStr(pServerObjectInfo->ComponentArray[1]);
  365. if(!(pCSessionsEnumVar->_pszServerName)){
  366. hr = E_OUTOFMEMORY;
  367. goto cleanup;
  368. }
  369. pCSessionsEnumVar->_Credentials = Credentials;
  370. hr = pCSessionsEnumVar->_Credentials.RefServer(
  371. pCSessionsEnumVar->_pszServerName);
  372. BAIL_IF_ERROR(hr);
  373. if(pszClientName){
  374. pCSessionsEnumVar->_pszClientName =
  375. AllocADsStr(pszClientName);
  376. if(!(pCSessionsEnumVar->_pszClientName)){
  377. hr = E_OUTOFMEMORY;
  378. goto cleanup;
  379. }
  380. }
  381. if(pszUserName){
  382. pCSessionsEnumVar->_pszUserName =
  383. AllocADsStr(pszUserName);
  384. if(!(pCSessionsEnumVar->_pszUserName)){
  385. hr = E_OUTOFMEMORY;
  386. goto cleanup;
  387. }
  388. }
  389. *ppCSessionsEnumVar = pCSessionsEnumVar;
  390. cleanup:
  391. if(pServerObjectInfo){
  392. FreeObjectInfo(pServerObjectInfo);
  393. }
  394. if(SUCCEEDED(hr)){
  395. RRETURN(hr);
  396. }
  397. delete pCSessionsEnumVar;
  398. RRETURN_EXP_IF_ERR(hr);
  399. }
  400. //+---------------------------------------------------------------------------
  401. //
  402. // Function: CWinNTSessionsEnumVar::Next
  403. //
  404. // Synopsis: Returns cElements number of requested Session objects in the
  405. // array supplied in pvar.
  406. //
  407. // Arguments: [cElements] -- The number of elements requested by client
  408. // [pvar] -- ptr to array of VARIANTs to for return objects
  409. // [pcElementFetched] -- if non-NULL, then number of elements
  410. // -- actually returned is placed here
  411. //
  412. // Returns: HRESULT -- S_OK if number of elements requested are returned
  413. // -- S_FALSE if number of elements is < requested
  414. //
  415. // Modifies:
  416. //
  417. // History: 11-27-95 RamV Created.
  418. //
  419. //----------------------------------------------------------------------------
  420. STDMETHODIMP
  421. CWinNTSessionsEnumVar::Next(ULONG ulNumElementsRequested,
  422. VARIANT FAR* pvar,
  423. ULONG FAR* pulNumFetched)
  424. {
  425. HRESULT hresult;
  426. ULONG ulIndex;
  427. LONG lNewCurrent;
  428. ULONG lNumFetched;
  429. LPSESSION_INFO_1 lpSessionInfo;
  430. IDispatch * pDispatch = NULL;
  431. LPTSTR pszClientName = NULL;
  432. LPTSTR pszUserName = NULL;
  433. if (pulNumFetched != NULL){
  434. *pulNumFetched = 0;
  435. }
  436. //
  437. // Initialize the elements to be returned
  438. //
  439. for (ulIndex= 0; ulIndex < ulNumElementsRequested; ulIndex++){
  440. VariantInit(&pvar[ulIndex]);
  441. }
  442. if(!_pbSessions || (_lCurrentPosition == _lLBound +(LONG)_cElements) ){
  443. if (_pbSessions){
  444. NetApiBufferFree(_pbSessions);
  445. _pbSessions = NULL;
  446. }
  447. if(_dwTotalEntries == _cElements && (_dwTotalEntries !=0)){
  448. //
  449. // we got all elements already, no need to do another call
  450. //
  451. RRETURN(S_FALSE);
  452. }
  453. hresult = WinNTEnumSessions(_pszServerName,
  454. _pszClientName,
  455. _pszUserName,
  456. &_cElements,
  457. &_dwTotalEntries,
  458. &_dwResumeHandle,
  459. &_pbSessions
  460. );
  461. if(hresult == S_FALSE){
  462. RRETURN(S_FALSE);
  463. }
  464. _lLBound = 0;
  465. _lCurrentPosition = _lLBound;
  466. }
  467. //
  468. // Get each element and place it into the return array
  469. // Don't request more than we have
  470. //
  471. for (lNewCurrent=_lCurrentPosition, lNumFetched=0;
  472. lNewCurrent<(LONG)(_lLBound+_cElements) &&
  473. lNumFetched < ulNumElementsRequested;
  474. lNewCurrent++, lNumFetched++){
  475. lpSessionInfo = (LPSESSION_INFO_1)(_pbSessions +
  476. lNewCurrent*sizeof(SESSION_INFO_1));
  477. pszClientName = lpSessionInfo->sesi1_cname;
  478. pszUserName = lpSessionInfo->sesi1_username;
  479. hresult = CWinNTSession::Create(_pszServerADsPath,
  480. pszClientName,
  481. pszUserName,
  482. ADS_OBJECT_BOUND,
  483. IID_IDispatch,
  484. _Credentials,
  485. (void **)&pDispatch);
  486. BAIL_ON_FAILURE(hresult);
  487. V_VT(&(pvar[lNumFetched])) = VT_DISPATCH;
  488. V_DISPATCH(&(pvar[lNumFetched])) = pDispatch;
  489. }
  490. //
  491. // Tell the caller how many we got (which may be less than the number
  492. // requested), and save the current position
  493. //
  494. if (pulNumFetched != NULL)
  495. *pulNumFetched = lNumFetched;
  496. _lCurrentPosition = lNewCurrent;
  497. //
  498. // If we're returning less than they asked for return S_FALSE, but
  499. // they still have the data (S_FALSE is a success code)
  500. //
  501. return (lNumFetched < ulNumElementsRequested) ?
  502. S_FALSE
  503. : S_OK;
  504. error:
  505. #if DBG
  506. if(FAILED(hresult)){
  507. EnumSessionDebugOut((DEB_TRACE,
  508. "hresult Failed with value: %ld \n", hresult ));
  509. }
  510. #endif
  511. RRETURN(S_FALSE);
  512. }
  513. HRESULT
  514. WinNTEnumSessions(LPTSTR pszServerName,
  515. LPTSTR pszClientName,
  516. LPTSTR pszUserName,
  517. PDWORD pdwEntriesRead,
  518. PDWORD pdwTotalEntries,
  519. PDWORD pdwResumeHandle,
  520. LPBYTE * ppMem
  521. )
  522. {
  523. NET_API_STATUS nasStatus;
  524. UNREFERENCED_PARAMETER(pszClientName);
  525. UNREFERENCED_PARAMETER(pszUserName);
  526. //
  527. // why have these parameters if they are unreferenced? Because we might
  528. // use them in the future when more complicated enumerations are desired
  529. //
  530. nasStatus = NetSessionEnum(pszServerName,
  531. NULL,
  532. NULL,
  533. 1, //info level desired
  534. ppMem,
  535. MAX_PREFERRED_LENGTH,
  536. pdwEntriesRead,
  537. pdwTotalEntries,
  538. pdwResumeHandle);
  539. if(*ppMem == NULL || (nasStatus != NERR_Success)){
  540. //
  541. //no more entries returned by sessions
  542. //
  543. RRETURN(S_FALSE);
  544. }
  545. RRETURN(S_OK);
  546. }
  547. //
  548. // helper functions
  549. //
  550. HRESULT
  551. SplitIntoUserAndClient(LPTSTR pszSession,
  552. LPTSTR * ppszUserName,
  553. LPTSTR * ppszClientName
  554. )
  555. {
  556. HRESULT hr = S_OK;
  557. int i=0;
  558. //
  559. // assumption: Valid strings are passed to this function
  560. // i.e. bstrSession is valid
  561. // we have the format username\clientname
  562. // suppose we have no username then it is "\clientname"
  563. // suppose we dont have clientname it is username\
  564. *ppszUserName = pszSession;
  565. *ppszClientName = pszSession;
  566. if((*ppszClientName = _tcschr(pszSession, TEXT('\\')))== NULL)
  567. {
  568. //
  569. // invalid name specified
  570. //
  571. RRETURN(E_FAIL);
  572. }
  573. **ppszClientName = TEXT('\0');
  574. (*ppszClientName)++;
  575. RRETURN(S_OK);
  576. }