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.

749 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. if (NULL == pvar)
  437. {
  438. RRETURN(S_FALSE);
  439. }
  440. //
  441. // Initialize the elements to be returned
  442. //
  443. for (ulIndex= 0; ulIndex < ulNumElementsRequested; ulIndex++){
  444. VariantInit(&pvar[ulIndex]);
  445. }
  446. if(!_pbSessions || (_lCurrentPosition == _lLBound +(LONG)_cElements) ){
  447. if (_pbSessions){
  448. NetApiBufferFree(_pbSessions);
  449. _pbSessions = NULL;
  450. }
  451. if(_dwTotalEntries == _cElements && (_dwTotalEntries !=0)){
  452. //
  453. // we got all elements already, no need to do another call
  454. //
  455. RRETURN(S_FALSE);
  456. }
  457. hresult = WinNTEnumSessions(_pszServerName,
  458. _pszClientName,
  459. _pszUserName,
  460. &_cElements,
  461. &_dwTotalEntries,
  462. &_dwResumeHandle,
  463. &_pbSessions
  464. );
  465. if(hresult == S_FALSE){
  466. RRETURN(S_FALSE);
  467. }
  468. _lLBound = 0;
  469. _lCurrentPosition = _lLBound;
  470. }
  471. //
  472. // Get each element and place it into the return array
  473. // Don't request more than we have
  474. //
  475. for (lNewCurrent=_lCurrentPosition, lNumFetched=0;
  476. lNewCurrent<(LONG)(_lLBound+_cElements) &&
  477. lNumFetched < ulNumElementsRequested;
  478. lNewCurrent++, lNumFetched++){
  479. lpSessionInfo = (LPSESSION_INFO_1)(_pbSessions +
  480. lNewCurrent*sizeof(SESSION_INFO_1));
  481. pszClientName = lpSessionInfo->sesi1_cname;
  482. pszUserName = lpSessionInfo->sesi1_username;
  483. hresult = CWinNTSession::Create(_pszServerADsPath,
  484. pszClientName,
  485. pszUserName,
  486. ADS_OBJECT_BOUND,
  487. IID_IDispatch,
  488. _Credentials,
  489. (void **)&pDispatch);
  490. BAIL_ON_FAILURE(hresult);
  491. V_VT(&(pvar[lNumFetched])) = VT_DISPATCH;
  492. V_DISPATCH(&(pvar[lNumFetched])) = pDispatch;
  493. }
  494. //
  495. // Tell the caller how many we got (which may be less than the number
  496. // requested), and save the current position
  497. //
  498. if (pulNumFetched != NULL)
  499. *pulNumFetched = lNumFetched;
  500. _lCurrentPosition = lNewCurrent;
  501. //
  502. // If we're returning less than they asked for return S_FALSE, but
  503. // they still have the data (S_FALSE is a success code)
  504. //
  505. return (lNumFetched < ulNumElementsRequested) ?
  506. S_FALSE
  507. : S_OK;
  508. error:
  509. #if DBG
  510. if(FAILED(hresult)){
  511. EnumSessionDebugOut((DEB_TRACE,
  512. "hresult Failed with value: %ld \n", hresult ));
  513. }
  514. #endif
  515. RRETURN(S_FALSE);
  516. }
  517. HRESULT
  518. WinNTEnumSessions(LPTSTR pszServerName,
  519. LPTSTR pszClientName,
  520. LPTSTR pszUserName,
  521. PDWORD pdwEntriesRead,
  522. PDWORD pdwTotalEntries,
  523. PDWORD pdwResumeHandle,
  524. LPBYTE * ppMem
  525. )
  526. {
  527. NET_API_STATUS nasStatus;
  528. UNREFERENCED_PARAMETER(pszClientName);
  529. UNREFERENCED_PARAMETER(pszUserName);
  530. //
  531. // why have these parameters if they are unreferenced? Because we might
  532. // use them in the future when more complicated enumerations are desired
  533. //
  534. nasStatus = NetSessionEnum(pszServerName,
  535. NULL,
  536. NULL,
  537. 1, //info level desired
  538. ppMem,
  539. MAX_PREFERRED_LENGTH,
  540. pdwEntriesRead,
  541. pdwTotalEntries,
  542. pdwResumeHandle);
  543. if(*ppMem == NULL || (nasStatus != NERR_Success)){
  544. //
  545. //no more entries returned by sessions
  546. //
  547. RRETURN(S_FALSE);
  548. }
  549. RRETURN(S_OK);
  550. }
  551. //
  552. // helper functions
  553. //
  554. HRESULT
  555. SplitIntoUserAndClient(LPTSTR pszSession,
  556. LPTSTR * ppszUserName,
  557. LPTSTR * ppszClientName
  558. )
  559. {
  560. HRESULT hr = S_OK;
  561. int i=0;
  562. //
  563. // assumption: Valid strings are passed to this function
  564. // i.e. bstrSession is valid
  565. // we have the format username\clientname
  566. // suppose we have no username then it is "\clientname"
  567. // suppose we dont have clientname it is username\
  568. *ppszUserName = pszSession;
  569. *ppszClientName = pszSession;
  570. if((*ppszClientName = _tcschr(pszSession, TEXT('\\')))== NULL)
  571. {
  572. //
  573. // invalid name specified
  574. //
  575. RRETURN(E_FAIL);
  576. }
  577. **ppszClientName = TEXT('\0');
  578. (*ppszClientName)++;
  579. RRETURN(S_OK);
  580. }