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.

739 lines
17 KiB

  1. /******************************************************************
  2. Connection.CPP -- C provider class implementation
  3. Copyright (c) 2000-2001 Microsoft Corporation, All Rights Reserved
  4. Description: Connection Provider
  5. ******************************************************************/
  6. //#include <windows.h>
  7. #include "precomp.h"
  8. #include "Connection.h"
  9. CConnection MyCConnection (
  10. PROVIDER_NAME_CONNECTION ,
  11. Namespace
  12. ) ;
  13. /*****************************************************************************
  14. *
  15. * FUNCTION : CConnection::CConnection
  16. *
  17. * DESCRIPTION : Constructor
  18. *
  19. *****************************************************************************/
  20. CConnection :: CConnection (
  21. LPCWSTR lpwszName,
  22. LPCWSTR lpwszNameSpace
  23. ) : Provider ( lpwszName , lpwszNameSpace )
  24. {
  25. }
  26. /*****************************************************************************
  27. *
  28. * FUNCTION : CConnection::~CConnection
  29. *
  30. * DESCRIPTION : Destructor
  31. *
  32. *****************************************************************************/
  33. CConnection :: ~CConnection ()
  34. {
  35. }
  36. /*****************************************************************************
  37. *
  38. * FUNCTION : CConnection::EnumerateInstances
  39. *
  40. * DESCRIPTION : Returns all the instances of this class.
  41. *
  42. *****************************************************************************/
  43. HRESULT CConnection :: EnumerateInstances (
  44. MethodContext *pMethodContext,
  45. long lFlags
  46. )
  47. {
  48. HRESULT hRes = WBEM_S_NO_ERROR;
  49. DWORD dwPropertiesReq = CONNECTIONS_ALL_PROPS;
  50. // Passing empty string to indicate no NULL computer name and shareName
  51. hRes = EnumConnectionInfo (
  52. L"",
  53. L"",
  54. pMethodContext,
  55. dwPropertiesReq
  56. );
  57. return hRes ;
  58. }
  59. /*****************************************************************************
  60. *
  61. * FUNCTION : CConnection::GetObject
  62. *
  63. * DESCRIPTION : Find a single instance based on the key properties for the
  64. * class.
  65. *
  66. *****************************************************************************/
  67. HRESULT CConnection :: GetObject (
  68. CInstance *pInstance,
  69. long lFlags ,
  70. CFrameworkQuery &Query
  71. )
  72. {
  73. HRESULT hRes = WBEM_S_NO_ERROR;
  74. CHString t_ShareName ;
  75. CHString t_ComputerName;
  76. CHString t_UserName;
  77. if ( pInstance->GetCHString ( IDS_ShareName , t_ShareName ) == FALSE )
  78. {
  79. hRes = WBEM_E_INVALID_PARAMETER ;
  80. }
  81. if ( SUCCEEDED ( hRes ) )
  82. {
  83. if ( pInstance->GetCHString ( IDS_ComputerName , t_ComputerName ) == FALSE )
  84. {
  85. hRes = WBEM_E_INVALID_PARAMETER ;
  86. }
  87. }
  88. if ( SUCCEEDED ( hRes ) )
  89. {
  90. if ( pInstance->GetCHString ( IDS_UserName , t_UserName ) == FALSE )
  91. {
  92. hRes = WBEM_E_INVALID_PARAMETER ;
  93. }
  94. }
  95. if ( SUCCEEDED ( hRes ) )
  96. {
  97. DWORD dwPropertiesReq;
  98. hRes = WBEM_E_NOT_FOUND;
  99. if ( Query.AllPropertiesAreRequired() )
  100. {
  101. dwPropertiesReq = CONNECTIONS_ALL_PROPS;
  102. }
  103. else
  104. {
  105. SetPropertiesReq ( Query, dwPropertiesReq );
  106. }
  107. #ifdef NTONLY
  108. hRes = FindAndSetNTConnection ( t_ShareName.GetBuffer(0), t_ComputerName, t_UserName, dwPropertiesReq, pInstance, Get );
  109. #endif
  110. #if 0
  111. #ifdef WIN9XONLY
  112. hRes = FindAndSet9XConnection ( t_ShareName, t_ComputerName, t_UserName, dwPropertiesReq, pInstance, Get );
  113. #endif
  114. #endif
  115. }
  116. return hRes ;
  117. }
  118. /*****************************************************************************
  119. *
  120. * FUNCTION : CConnection::ExecQuery
  121. *
  122. * DESCRIPTION : Optimization of a query only on one of the key values
  123. *
  124. *****************************************************************************/
  125. HRESULT CConnection :: ExecQuery (
  126. MethodContext *pMethodContext,
  127. CFrameworkQuery &Query,
  128. long lFlags
  129. )
  130. {
  131. HRESULT hRes = WBEM_S_NO_ERROR;
  132. DWORD dwPropertiesReq;
  133. DWORD t_Size;
  134. if ( Query.AllPropertiesAreRequired() )
  135. {
  136. dwPropertiesReq = CONNECTIONS_ALL_PROPS;
  137. }
  138. else
  139. {
  140. SetPropertiesReq ( Query, dwPropertiesReq );
  141. }
  142. CHStringArray t_ShareValues;
  143. CHStringArray t_ComputerValues;
  144. // Connections can be enumerated to the shares or the connections made from the computer only on one key value we can optimize
  145. // Otherwise we will need to take both the set of instances, take the union of the two sets and then commit.
  146. // Implmenting only if one of the two keyvalues Sharename or Computername is specified.
  147. hRes = Query.GetValuesForProp(
  148. IDS_ShareName,
  149. t_ShareValues
  150. );
  151. hRes = Query.GetValuesForProp(
  152. IDS_ComputerName,
  153. t_ComputerValues
  154. );
  155. if ( SUCCEEDED ( hRes ) )
  156. {
  157. hRes = OptimizeQuery ( t_ShareValues, t_ComputerValues, pMethodContext, dwPropertiesReq );
  158. }
  159. return hRes;
  160. }
  161. #ifdef NTONLY
  162. /*****************************************************************************
  163. *
  164. * FUNCTION : CConnection::EnumNTConnectionsFromComputerToShare
  165. *
  166. * DESCRIPTION : Enumerating all the connections made from a computer to
  167. * a given share
  168. *
  169. *****************************************************************************/
  170. HRESULT CConnection :: EnumNTConnectionsFromComputerToShare (
  171. LPWSTR a_ComputerName,
  172. LPWSTR a_ShareName,
  173. MethodContext *pMethodContext,
  174. DWORD dwPropertiesReq
  175. )
  176. {
  177. HRESULT hRes = WBEM_S_NO_ERROR;
  178. DWORD t_Status = NERR_Success;
  179. DWORD dwNoOfEntriesRead = 0;
  180. DWORD dwTotalConnections = 0;
  181. DWORD dwResumeHandle = 0;
  182. CONNECTION_INFO *pBuf = NULL;
  183. CONNECTION_INFO *pTmpBuf = NULL;
  184. LPWSTR t_ComputerName = NULL;
  185. if ( a_ComputerName && a_ComputerName[0] != L'\0' )
  186. {
  187. //let's skip the \\ chars
  188. t_ComputerName = a_ComputerName + 2;
  189. }
  190. // ShareName and COmputer Name both cannot be null at the same time
  191. while ( TRUE )
  192. {
  193. if ( a_ShareName[0] != L'\0' )
  194. {
  195. t_Status = NetConnectionEnum(
  196. NULL,
  197. a_ShareName,
  198. 1,
  199. (LPBYTE *) &pBuf,
  200. -1,
  201. &dwNoOfEntriesRead,
  202. &dwTotalConnections,
  203. &dwResumeHandle
  204. );
  205. }
  206. else
  207. if ( a_ComputerName[0] != L'\0' )
  208. {
  209. t_Status = NetConnectionEnum(
  210. NULL,
  211. a_ComputerName,
  212. 1,
  213. (LPBYTE *) &pBuf,
  214. -1,
  215. &dwNoOfEntriesRead,
  216. &dwTotalConnections,
  217. &dwResumeHandle
  218. );
  219. }
  220. if ( t_Status == NERR_Success )
  221. {
  222. if ( dwNoOfEntriesRead == 0 )
  223. {
  224. break;
  225. }
  226. else if ( dwNoOfEntriesRead > 0 )
  227. {
  228. try
  229. {
  230. pTmpBuf = pBuf;
  231. for ( int i = 0; i < dwNoOfEntriesRead; i++, pTmpBuf++ )
  232. {
  233. CInstancePtr pInstance ( CreateNewInstance ( pMethodContext ), FALSE );
  234. hRes = LoadInstance ( pInstance, a_ShareName, t_ComputerName ? t_ComputerName : a_ComputerName, pTmpBuf, dwPropertiesReq );
  235. if ( SUCCEEDED ( hRes ) )
  236. {
  237. hRes = pInstance->Commit();
  238. if ( FAILED ( hRes ) )
  239. {
  240. break;
  241. }
  242. }
  243. else
  244. {
  245. break;
  246. }
  247. }
  248. }
  249. catch ( ... )
  250. {
  251. NetApiBufferFree ( pBuf );
  252. pBuf = NULL;
  253. throw;
  254. }
  255. NetApiBufferFree ( pBuf );
  256. pBuf = NULL;
  257. }
  258. }
  259. else
  260. {
  261. if ( t_Status != ERROR_MORE_DATA )
  262. {
  263. if ( t_Status == ERROR_ACCESS_DENIED )
  264. {
  265. hRes = WBEM_E_ACCESS_DENIED;
  266. }
  267. else
  268. {
  269. if ( t_Status == ERROR_NOT_ENOUGH_MEMORY )
  270. {
  271. hRes = WBEM_E_OUT_OF_MEMORY;
  272. }
  273. else
  274. {
  275. hRes = WBEM_E_FAILED;
  276. }
  277. }
  278. break;
  279. }
  280. }
  281. }
  282. return hRes;
  283. }
  284. #endif //NTONLY
  285. #if 0
  286. #ifdef WIN9XONLY
  287. /*****************************************************************************
  288. *
  289. * FUNCTION : CConnection::Enum9XConnectionsFromComputerToShare
  290. *
  291. * DESCRIPTION : Enumerating all the connections made from a computer to
  292. * a given share
  293. *
  294. *****************************************************************************/
  295. Coonnections on win9x is broken, since it cannot return a sharename and it is a part of the
  296. key.
  297. HRESULT CConnection :: Enum9XConnectionsFromComputerToShare (
  298. LPWSTR a_ComputerName,
  299. LPWSTR a_ShareName,
  300. MethodContext *pMethodContext,
  301. DWORD dwPropertiesReq
  302. )
  303. {
  304. HRESULT hRes = WBEM_S_NO_ERROR;
  305. NET_API_STATUS t_Status = NERR_Success;
  306. USHORT dwNoOfEntriesRead = 0;
  307. USHORT dwTotalConnections = 0;
  308. BOOL bFound = FALSE;
  309. CONNECTION_INFO * pBuf = NULL;
  310. CONNECTION_INFO * pTmpBuf = NULL;
  311. unsigned short dwBufferSize = MAX_ENTRIES * sizeof( CONNECTION_INFO );
  312. pBuf = ( CONNECTION_INFO *) malloc(dwBufferSize);
  313. if ( pBuf != NULL )
  314. {
  315. try
  316. {
  317. t_Status = NetConnectionEnum(
  318. NULL,
  319. TOBSTRT ( a_ShareName ), // ShareName
  320. ( short ) 1,
  321. (char FAR *) pBuf,
  322. dwBufferSize,
  323. &dwNoOfEntriesRead,
  324. &dwTotalConnections
  325. );
  326. }
  327. catch ( ... )
  328. {
  329. free ( pBuf );
  330. pBuf = NULL;
  331. throw;
  332. }
  333. // otherwise we are not to frr the buffer, we have use it and then free the buffer.
  334. if ( ( dwNoOfEntriesRead < dwTotalConnections ) && ( t_Status == ERROR_MORE_DATA ) )
  335. {
  336. free ( pBuf );
  337. pBuf = NULL;
  338. dwBufferSize = dwTotalConnections * sizeof( CONNECTION_INFO );
  339. pBuf = ( CONNECTION_INFO *) malloc( dwBufferSize );
  340. if ( pBuf != NULL )
  341. {
  342. try
  343. {
  344. t_Status = NetConnectionEnum(
  345. NULL,
  346. TOBSTRT( a_ShareName), // ShareName
  347. ( short ) 1,
  348. (char FAR *) pBuf,
  349. dwBufferSize,
  350. &dwNoOfEntriesRead,
  351. &dwTotalConnections
  352. );
  353. }
  354. catch ( ... )
  355. {
  356. free ( pBuf );
  357. pBuf = NULL;
  358. throw;
  359. }
  360. // We need to use the buffer before we free it
  361. }
  362. else
  363. {
  364. throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR );;
  365. }
  366. }
  367. // The buffer is yet to be used
  368. if ( ( t_Status == NERR_Success ) && ( dwNoOfEntriesRead == dwTotalConnections ) )
  369. {
  370. // use the buffer first and then free
  371. if ( pBuf != NULL )
  372. {
  373. try
  374. {
  375. pTmpBuf = pBuf;
  376. for ( int i = 0; i < dwNoOfEntriesRead; i++, pTmpBuf ++)
  377. {
  378. CInstancePtr pInstance ( CreateNewInstance ( pMethodContext ), FALSE );
  379. hRes = LoadInstance ( pInstance, a_ShareName, a_ComputerName, pTmpBuf, dwPropertiesReq );
  380. if ( SUCCEEDED ( hRes ) )
  381. {
  382. hRes = pInstance->Commit();
  383. if ( FAILED ( hRes ) )
  384. {
  385. break;
  386. }
  387. }
  388. else
  389. {
  390. break;
  391. }
  392. }
  393. }
  394. catch ( ... )
  395. {
  396. free ( pBuf );
  397. pBuf = NULL;
  398. throw;
  399. }
  400. // finally free the buffer
  401. free (pBuf );
  402. pBuf = NULL;
  403. }
  404. else
  405. {
  406. throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR );
  407. }
  408. }
  409. else
  410. {
  411. hRes = WBEM_E_FAILED;
  412. }
  413. }
  414. else
  415. {
  416. throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR );
  417. }
  418. return hRes;
  419. }
  420. #endif
  421. #endif
  422. /*****************************************************************************
  423. *
  424. * FUNCTION : CConnection:: LoadInstance
  425. *
  426. * DESCRIPTION : Loading an instance with the connection info
  427. *
  428. *****************************************************************************/
  429. HRESULT CConnection :: LoadInstance (
  430. CInstance *pInstance,
  431. LPCWSTR a_Share,
  432. LPCWSTR a_Computer,
  433. CONNECTION_INFO *pBuf,
  434. DWORD dwPropertiesReq
  435. )
  436. {
  437. HRESULT hRes = WBEM_S_NO_ERROR;
  438. if ( a_Share[0] != L'\0' )
  439. {
  440. if ( dwPropertiesReq & CONNECTIONS_PROP_ShareName )
  441. {
  442. if ( pInstance->SetCharSplat ( IDS_ShareName, a_Share ) == FALSE )
  443. {
  444. hRes = WBEM_E_PROVIDER_FAILURE;
  445. }
  446. }
  447. if ( SUCCEEDED ( hRes ) && ( dwPropertiesReq & CONNECTIONS_PROP_ComputerName ) )
  448. {
  449. if ( pInstance->SetCharSplat ( IDS_ComputerName, pBuf->coni1_netname ) == FALSE )
  450. {
  451. hRes = WBEM_E_PROVIDER_FAILURE ;
  452. }
  453. }
  454. }
  455. else
  456. {
  457. if ( dwPropertiesReq & CONNECTIONS_PROP_ComputerName )
  458. {
  459. if ( pInstance->SetCharSplat ( IDS_ComputerName, a_Computer ) == FALSE )
  460. {
  461. hRes = WBEM_E_PROVIDER_FAILURE ;
  462. }
  463. }
  464. if ( SUCCEEDED ( hRes ) && ( dwPropertiesReq & CONNECTIONS_PROP_ShareName ) )
  465. {
  466. if ( pInstance->SetCharSplat ( IDS_ShareName, pBuf->coni1_netname ) == FALSE )
  467. {
  468. hRes = WBEM_E_PROVIDER_FAILURE ;
  469. }
  470. }
  471. }
  472. if ( SUCCEEDED ( hRes ) && ( dwPropertiesReq & CONNECTIONS_PROP_UserName ) )
  473. {
  474. if ( pInstance->SetCharSplat ( IDS_UserName, pBuf->coni1_username ) == FALSE )
  475. {
  476. hRes = WBEM_E_PROVIDER_FAILURE ;
  477. }
  478. }
  479. /* if ( SUCCEEDED ( hRes ) && ( dwPropertiesReq & CONNECTIONS_PROP_ConnectionType ) )
  480. {
  481. DWORD dwConnectionType;
  482. switch ( pBuf->coni1_type )
  483. {
  484. case STYPE_DISKTREE: dwConnectionType = 0; break;
  485. case STYPE_PRINTQ: dwConnectionType = 1; break;
  486. case STYPE_DEVICE: dwConnectionType = 2; break;
  487. case STYPE_IPC: dwConnectionType = 3; break;
  488. default: dwConnectionType = 4; break;
  489. }
  490. if ( pInstance->SetWORD ( ConnectionType, dwConnectionType ) == FALSE )
  491. {
  492. hRes = WBEM_E_PROVIDER_FAILURE ;
  493. }
  494. }
  495. */
  496. if ( SUCCEEDED ( hRes ) && ( dwPropertiesReq & CONNECTIONS_PROP_ConnectionID ) )
  497. {
  498. if ( pInstance->SetWORD ( IDS_ConnectionID, pBuf->coni1_id ) == FALSE )
  499. {
  500. hRes = WBEM_E_PROVIDER_FAILURE ;
  501. }
  502. }
  503. if ( SUCCEEDED ( hRes ) && ( dwPropertiesReq & CONNECTIONS_PROP_NumberOfUsers ) )
  504. {
  505. if ( pInstance->SetWORD ( IDS_NumberOfUsers, pBuf->coni1_num_users ) == FALSE )
  506. {
  507. hRes = WBEM_E_PROVIDER_FAILURE ;
  508. }
  509. }
  510. if ( SUCCEEDED ( hRes ) && ( dwPropertiesReq & CONNECTIONS_PROP_NumberOfFiles ) )
  511. {
  512. if ( pInstance->SetWORD ( IDS_NumberOfFiles, pBuf->coni1_num_opens ) == FALSE )
  513. {
  514. hRes = WBEM_E_PROVIDER_FAILURE ;
  515. }
  516. }
  517. if ( SUCCEEDED ( hRes ) && ( dwPropertiesReq & CONNECTIONS_PROP_ActiveTime ) )
  518. {
  519. if ( pInstance->SetWORD ( IDS_ActiveTime, pBuf->coni1_time ) == FALSE )
  520. {
  521. hRes = WBEM_E_PROVIDER_FAILURE ;
  522. }
  523. }
  524. return hRes;
  525. }
  526. /*****************************************************************************
  527. *
  528. * FUNCTION : CConnection::OptimizeQuery
  529. *
  530. * DESCRIPTION : Optimizes a query based on the Key Values.
  531. *
  532. *****************************************************************************/
  533. HRESULT CConnection::OptimizeQuery (
  534. CHStringArray& a_ShareValues,
  535. CHStringArray& a_ComputerValues,
  536. MethodContext *pMethodContext,
  537. DWORD dwPropertiesReq
  538. )
  539. {
  540. HRESULT hRes = WBEM_S_NO_ERROR;
  541. if ( ( a_ShareValues.GetSize() == 0 ) && ( a_ComputerValues.GetSize() == 0 ) )
  542. {
  543. // This is a query for which there is no where clause, so it means only a few Properties are requested
  544. // hence we need to deliver only those properties of instances to the WinMgmt while enumerating connecctions
  545. hRes = EnumConnectionInfo (
  546. L"",
  547. L"",
  548. pMethodContext,
  549. dwPropertiesReq
  550. );
  551. }
  552. else
  553. if ( a_ComputerValues.GetSize() != 0 )
  554. {
  555. CHString t_ComputerName;
  556. for ( int i = 0; i < a_ComputerValues.GetSize(); i++ )
  557. {
  558. t_ComputerName.Format ( L"%s%s", L"\\\\", (LPCWSTR)a_ComputerValues.GetAt(i) );
  559. hRes = EnumConnectionInfo (
  560. t_ComputerName.GetBuffer(0),
  561. L"", // Share name is empty
  562. pMethodContext,
  563. dwPropertiesReq
  564. );
  565. if ( FAILED ( hRes ) )
  566. {
  567. break;
  568. }
  569. }
  570. }
  571. else
  572. if ( a_ShareValues.GetSize() != 0 )
  573. {
  574. for ( int i = 0; i < a_ShareValues.GetSize(); i++ )
  575. {
  576. hRes = EnumConnectionInfo (
  577. L"",
  578. a_ShareValues.GetAt(i).GetBuffer(0),
  579. pMethodContext,
  580. dwPropertiesReq
  581. );
  582. if ( FAILED ( hRes ) )
  583. {
  584. break;
  585. }
  586. }
  587. }
  588. else
  589. hRes = WBEM_E_PROVIDER_NOT_CAPABLE;
  590. return hRes;
  591. }
  592. /*****************************************************************************
  593. *
  594. * FUNCTION : CConnection::SetPropertiesReq
  595. *
  596. * DESCRIPTION : Setting a bitmap for the required properties
  597. *
  598. *****************************************************************************/
  599. void CConnection :: SetPropertiesReq ( CFrameworkQuery &Query, DWORD &dwPropertiesReq )
  600. {
  601. dwPropertiesReq = 0;
  602. if ( Query.IsPropertyRequired ( IDS_ComputerName ) )
  603. {
  604. dwPropertiesReq |= CONNECTIONS_PROP_ComputerName;
  605. }
  606. if ( Query.IsPropertyRequired ( IDS_ShareName ) )
  607. {
  608. dwPropertiesReq |= CONNECTIONS_PROP_ShareName;
  609. }
  610. if ( Query.IsPropertyRequired ( IDS_UserName ) )
  611. {
  612. dwPropertiesReq |= CONNECTIONS_PROP_UserName;
  613. }
  614. if ( Query.IsPropertyRequired ( IDS_ActiveTime ) )
  615. {
  616. dwPropertiesReq |= CONNECTIONS_PROP_ActiveTime;
  617. }
  618. if ( Query.IsPropertyRequired ( IDS_NumberOfUsers ) )
  619. {
  620. dwPropertiesReq |= CONNECTIONS_PROP_NumberOfUsers;
  621. }
  622. if ( Query.IsPropertyRequired ( IDS_NumberOfFiles ) )
  623. {
  624. dwPropertiesReq |= CONNECTIONS_PROP_NumberOfFiles;
  625. }
  626. if ( Query.IsPropertyRequired ( IDS_ConnectionID ) )
  627. {
  628. dwPropertiesReq |= CONNECTIONS_PROP_ConnectionID;
  629. }
  630. }