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.

804 lines
20 KiB

  1. /******************************************************************
  2. DfsReplica.CPP -- WMI provider class implementation
  3. Copyright (c) 2000-2001 Microsoft Corporation, All Rights Reserved
  4. DESCRIPTION DFS Provider
  5. ******************************************************************/
  6. #include "precomp.h"
  7. #include <computerAPI.h>
  8. CDfsReplica MyCDFSReplicaSet (
  9. PROVIDER_NAME_DFSREPLICA ,
  10. Namespace
  11. ) ;
  12. /*****************************************************************************
  13. *
  14. * FUNCTION : CDfsReplica::CDfsReplica
  15. *
  16. * DESCRIPTION : Constructor
  17. *
  18. *****************************************************************************/
  19. CDfsReplica :: CDfsReplica (
  20. LPCWSTR lpwszName,
  21. LPCWSTR lpwszNameSpace
  22. ) : Provider ( lpwszName , lpwszNameSpace )
  23. {
  24. m_ComputerName = GetLocalComputerName();
  25. }
  26. /*****************************************************************************
  27. *
  28. * FUNCTION : CDfsReplica::~CDfsReplica
  29. *
  30. * DESCRIPTION : Destructor
  31. *
  32. *****************************************************************************/
  33. CDfsReplica :: ~CDfsReplica ()
  34. {
  35. }
  36. /*****************************************************************************
  37. *
  38. * FUNCTION : CDfsReplica::EnumerateInstances
  39. *
  40. * DESCRIPTION : Returns all the instances of this class.
  41. *
  42. *****************************************************************************/
  43. HRESULT CDfsReplica :: EnumerateInstances (
  44. MethodContext *pMethodContext,
  45. long lFlags
  46. )
  47. {
  48. HRESULT hRes = WBEM_S_NO_ERROR ;
  49. DWORD dwPropertiesReq = DFSREPLICA_ALL_PROPS;
  50. hRes = EnumerateAllReplicas ( pMethodContext, dwPropertiesReq );
  51. return hRes ;
  52. }
  53. /*****************************************************************************
  54. *
  55. * FUNCTION : CDfsReplica::GetObject
  56. *
  57. * DESCRIPTION : Find a single instance based on the key properties for the
  58. * class.
  59. *
  60. *****************************************************************************/
  61. HRESULT CDfsReplica :: GetObject (
  62. CInstance *pInstance,
  63. long lFlags,
  64. CFrameworkQuery& Query
  65. )
  66. {
  67. HRESULT hRes = WBEM_S_NO_ERROR;
  68. DWORD dwPropertiesReq = 0;
  69. CHString t_Link ;
  70. CHString t_Server;
  71. CHString t_Share;
  72. hRes = GetKeys(pInstance, t_Link, t_Server, t_Share);
  73. if ( SUCCEEDED ( hRes ) )
  74. {
  75. if ( Query.AllPropertiesAreRequired() )
  76. {
  77. dwPropertiesReq = DFSREPLICA_ALL_PROPS;
  78. }
  79. else
  80. {
  81. if ( Query.IsPropertyRequired ( LINKNAME ) )
  82. {
  83. dwPropertiesReq |= DFSREPLICA_PROP_LinkName;
  84. }
  85. if ( Query.IsPropertyRequired ( SERVERNAME ) )
  86. {
  87. dwPropertiesReq |= DFSREPLICA_PROP_ServerName;
  88. }
  89. if ( Query.IsPropertyRequired ( SHARENAME ) )
  90. {
  91. dwPropertiesReq |= DFSREPLICA_PROP_ShareName;
  92. }
  93. if ( Query.IsPropertyRequired ( STATE ) )
  94. {
  95. dwPropertiesReq |= DFSREPLICA_PROP_State;
  96. }
  97. }
  98. bool bRoot = false;
  99. hRes = FindAndSetDfsReplica ( t_Link, t_Server, t_Share, dwPropertiesReq, pInstance, eGet, bRoot );
  100. }
  101. return hRes ;
  102. }
  103. /*****************************************************************************
  104. *
  105. * FUNCTION : CDfsReplica::PutInstance
  106. *
  107. * DESCRIPTION : PutInstance should be used in provider classes that can
  108. * write instance information back to the hardware or
  109. * software. For example: Win32_Environment will allow a
  110. * PutInstance to create or update an environment variable.
  111. * However, a class like MotherboardDevice will not allow
  112. * editing of the number of slots, since it is difficult for
  113. * a provider to affect that number.
  114. *
  115. *****************************************************************************/
  116. HRESULT CDfsReplica :: PutInstance (
  117. const CInstance &Instance,
  118. long lFlags
  119. )
  120. {
  121. HRESULT hRes = WBEM_S_NO_ERROR;
  122. DWORD dwPropertiesReq = 0;
  123. CHString t_Link ;
  124. CHString t_Server;
  125. CHString t_Share;
  126. bool bRoot = false;
  127. // Get the Compound Key
  128. hRes = GetKeys(&Instance, t_Link, t_Server, t_Share);
  129. if ( SUCCEEDED ( hRes ) )
  130. {
  131. hRes = FindAndSetDfsReplica ( t_Link, t_Server, t_Share, dwPropertiesReq, NULL, eAdd, bRoot );
  132. }
  133. bool bFound;
  134. if (SUCCEEDED(hRes))
  135. {
  136. bFound = true;
  137. }
  138. else if (hRes == WBEM_E_NOT_FOUND)
  139. {
  140. bFound = false;
  141. hRes = WBEM_S_NO_ERROR;
  142. }
  143. if (SUCCEEDED(hRes))
  144. {
  145. DWORD dwOperationsReq = (WBEM_FLAG_CREATE_OR_UPDATE | WBEM_FLAG_CREATE_ONLY | WBEM_FLAG_UPDATE_ONLY);
  146. switch ( lFlags & dwOperationsReq )
  147. {
  148. case WBEM_FLAG_CREATE_OR_UPDATE:
  149. {
  150. if (bFound)
  151. {
  152. hRes = WBEM_E_INVALID_PARAMETER;
  153. }
  154. else
  155. {
  156. if (NetDfsAdd (
  157. t_Link.GetBuffer ( 0 ),
  158. t_Server.GetBuffer ( 0 ),
  159. t_Share.GetBuffer ( 0 ),
  160. L"",
  161. 0
  162. ) == NERR_Success)
  163. {
  164. hRes = WBEM_S_NO_ERROR;
  165. }
  166. else
  167. {
  168. hRes = WBEM_E_FAILED;
  169. }
  170. }
  171. break;
  172. }
  173. case WBEM_FLAG_CREATE_ONLY:
  174. {
  175. if (!bFound)
  176. {
  177. if (NetDfsAdd (
  178. t_Link.GetBuffer ( 0 ),
  179. t_Server.GetBuffer ( 0 ),
  180. t_Share.GetBuffer ( 0 ),
  181. L"",
  182. 0
  183. ) == NERR_Success)
  184. {
  185. hRes = WBEM_S_NO_ERROR;
  186. }
  187. else
  188. {
  189. hRes = WBEM_E_FAILED;
  190. }
  191. }
  192. else
  193. {
  194. hRes = WBEM_E_ALREADY_EXISTS;
  195. }
  196. break;
  197. }
  198. default:
  199. {
  200. hRes = WBEM_E_INVALID_PARAMETER;
  201. }
  202. }
  203. }
  204. return hRes ;
  205. }
  206. /*****************************************************************************
  207. *
  208. * FUNCTION : CDfsReplica::DeleteInstance
  209. *
  210. * DESCRIPTION : DeleteInstance, like PutInstance, actually writes information
  211. * to the software or hardware. For most hardware devices,
  212. * DeleteInstance should not be implemented, but for software
  213. * configuration, DeleteInstance implementation is plausible.
  214. *
  215. *****************************************************************************/
  216. HRESULT CDfsReplica :: DeleteInstance (
  217. const CInstance &Instance,
  218. long lFlags
  219. )
  220. {
  221. HRESULT hRes = WBEM_S_NO_ERROR;
  222. DWORD dwPropertiesReq = 0;
  223. CHString t_Link ;
  224. CHString t_Server;
  225. CHString t_Share;
  226. bool bRoot = false;
  227. // Get the Compound Key
  228. hRes = GetKeys(&Instance, t_Link, t_Server, t_Share);
  229. if ( SUCCEEDED ( hRes ) )
  230. {
  231. hRes = FindAndSetDfsReplica ( t_Link, t_Server, t_Share, dwPropertiesReq, NULL, eDelete, bRoot );
  232. }
  233. if ( SUCCEEDED ( hRes ) )
  234. {
  235. NET_API_STATUS t_Status = NERR_Success;
  236. if (!bRoot)
  237. {
  238. t_Status = NetDfsRemove(
  239. t_Link.GetBuffer(0),
  240. t_Server.GetBuffer(0),
  241. t_Share.GetBuffer(0)
  242. );
  243. if ( t_Status != NERR_Success )
  244. {
  245. hRes = WBEM_E_FAILED;
  246. }
  247. }
  248. else
  249. {
  250. wchar_t *pEntryPath = t_Link.GetBuffer(0);
  251. if ((wcslen(pEntryPath) > 4) &&
  252. (pEntryPath[0] == pEntryPath[1]) &&
  253. (pEntryPath[0] == L'\\'))
  254. {
  255. wchar_t *pSlash = wcschr(&(pEntryPath[2]), L'\\');
  256. if (pSlash > &(pEntryPath[2]))
  257. {
  258. wchar_t *pServer = new wchar_t[pSlash - &(pEntryPath[2]) + 1];
  259. BOOL bRemove = FALSE;
  260. try
  261. {
  262. wcsncpy(pServer, &(pEntryPath[2]), pSlash - &(pEntryPath[2]));
  263. pServer[pSlash - &(pEntryPath[2])] = L'\0';
  264. if (0 == m_ComputerName.CompareNoCase(pServer))
  265. {
  266. bRemove = TRUE;
  267. }
  268. else
  269. {
  270. DWORD dwDnsName = 256;
  271. DWORD dwDnsNameSize = 256;
  272. wchar_t *pDnsName = new wchar_t[dwDnsName];
  273. try
  274. {
  275. while (!ProviderGetComputerNameEx(ComputerNamePhysicalDnsHostname, pDnsName, &dwDnsName))
  276. {
  277. if (GetLastError() != ERROR_MORE_DATA)
  278. {
  279. delete [] pDnsName;
  280. pDnsName = NULL;
  281. break;
  282. }
  283. else
  284. {
  285. delete [] pDnsName;
  286. pDnsName = NULL;
  287. dwDnsName = dwDnsNameSize * 2;
  288. dwDnsNameSize = dwDnsName;
  289. pDnsName = new wchar_t[dwDnsName];
  290. }
  291. }
  292. }
  293. catch (...)
  294. {
  295. if (pDnsName)
  296. {
  297. delete [] pDnsName;
  298. pDnsName = NULL;
  299. }
  300. throw;
  301. }
  302. if (pDnsName)
  303. {
  304. if (_wcsicmp(pDnsName, pServer) == 0)
  305. {
  306. bRemove = TRUE;
  307. }
  308. delete [] pDnsName;
  309. pDnsName = NULL;
  310. }
  311. }
  312. }
  313. catch(...)
  314. {
  315. if (pServer)
  316. {
  317. delete [] pServer;
  318. }
  319. throw;
  320. }
  321. if (bRemove)
  322. {
  323. t_Status = NetDfsRemoveStdRoot(
  324. t_Server.GetBuffer(0),
  325. t_Share.GetBuffer(0),
  326. 0
  327. );
  328. if ( t_Status != NERR_Success )
  329. {
  330. hRes = WBEM_E_FAILED;
  331. }
  332. }
  333. else
  334. {
  335. //can't delete roots not on this machine
  336. hRes = WBEM_E_PROVIDER_NOT_CAPABLE;
  337. }
  338. delete [] pServer;
  339. }
  340. else
  341. {
  342. hRes = WBEM_E_FAILED;
  343. }
  344. }
  345. else
  346. {
  347. hRes = WBEM_E_FAILED;
  348. }
  349. }
  350. }
  351. return hRes ;
  352. }
  353. /*****************************************************************************
  354. *
  355. * FUNCTION : CDfsReplica::EnumerateAllReplicas
  356. *
  357. * DESCRIPTION : Enumerates all the Dfs Replicas of all junction points
  358. *
  359. ******************************************************************************/
  360. HRESULT CDfsReplica::EnumerateAllReplicas ( MethodContext *pMethodContext, DWORD dwPropertiesReq )
  361. {
  362. HRESULT hRes = WBEM_S_NO_ERROR;
  363. BOOL bLoadReplicaFailure = FALSE;
  364. PDFS_STORAGE_INFO pRepBuf;
  365. PDFS_INFO_300 pData300 = NULL;
  366. DWORD er300 = 0;
  367. DWORD tr300 = 0;
  368. // Call the NetDfsEnum function, specifying level 300.
  369. DWORD res = NetDfsEnum( m_ComputerName.GetBuffer ( 0 ), 300, -1, (LPBYTE *) &pData300, &er300, &tr300 );
  370. // If no error occurred,
  371. if(res==NERR_Success)
  372. {
  373. if ( pData300 != NULL )
  374. {
  375. try
  376. {
  377. PDFS_INFO_300 p300 = pData300;
  378. CInstancePtr pInstance;
  379. for ( int i = 0; (i < er300) && SUCCEEDED( hRes ); i++, p300++ )
  380. {
  381. DWORD er4 = 0;
  382. DWORD tr4 = 0;
  383. PDFS_INFO_4 pData4 = NULL;
  384. if (p300->DfsName != NULL)
  385. {
  386. if ( ( res = NetDfsEnum(p300->DfsName, 4, -1, (LPBYTE *) &pData4, &er4, &tr4) ) == NERR_Success)
  387. {
  388. if ( pData4 != NULL )
  389. {
  390. try
  391. {
  392. PDFS_INFO_4 p4 = pData4;
  393. for ( int ii = 0; (ii < er4) && SUCCEEDED ( hRes ); ii++, p4++ )
  394. {
  395. // Walk all the replicas on each link
  396. pRepBuf = p4->Storage;
  397. for ( int j = 0; j < p4->NumberOfStorages; j++, pRepBuf++ )
  398. {
  399. pInstance.Attach(CreateNewInstance( pMethodContext ));
  400. hRes = LoadDfsReplica ( dwPropertiesReq, pInstance, p4->EntryPath, pRepBuf );
  401. if ( SUCCEEDED ( hRes ) )
  402. {
  403. hRes = pInstance->Commit();
  404. }
  405. else
  406. {
  407. bLoadReplicaFailure = TRUE;
  408. }
  409. }
  410. }
  411. }
  412. catch(...)
  413. {
  414. NetApiBufferFree(pData4);
  415. pData4 = NULL;
  416. throw;
  417. }
  418. NetApiBufferFree(pData4);
  419. pData4 = NULL;
  420. }
  421. }
  422. // Check to see if there are ANY roots
  423. else if (
  424. (res != ERROR_NO_MORE_ITEMS) &&
  425. (res != ERROR_NO_SUCH_DOMAIN) &&
  426. (res != ERROR_NOT_FOUND) &&
  427. (res != ERROR_ACCESS_DENIED)
  428. )
  429. {
  430. hRes = WBEM_E_FAILED;
  431. }
  432. }
  433. }
  434. }
  435. catch ( ... )
  436. {
  437. NetApiBufferFree(pData300);
  438. pData300 = NULL;
  439. throw;
  440. }
  441. NetApiBufferFree(pData300);
  442. pData300 = NULL;
  443. }
  444. }
  445. else
  446. {
  447. if ( (res != ERROR_NO_MORE_ITEMS) && (res != ERROR_NO_SUCH_DOMAIN) && (res != ERROR_NOT_FOUND) ) // Check to see if there are ANY roots
  448. {
  449. if ( ERROR_ACCESS_DENIED == res )
  450. {
  451. hRes = WBEM_E_ACCESS_DENIED ;
  452. }
  453. else
  454. {
  455. hRes = WBEM_E_FAILED ;
  456. }
  457. }
  458. // No replicas
  459. else if (res == ERROR_NO_MORE_ITEMS)
  460. {
  461. hRes = WBEM_S_NO_ERROR;
  462. }
  463. }
  464. if ( bLoadReplicaFailure )
  465. {
  466. hRes = WBEM_E_PROVIDER_FAILURE;
  467. }
  468. return hRes;
  469. }
  470. /*****************************************************************************
  471. *
  472. * FUNCTION : CDfsReplica::FindAndSetDfsReplica
  473. *
  474. * DESCRIPTION : Finds an entry matching the dfsEntryPath and loads the
  475. * Instance if found or acts based on the Operation passed
  476. *
  477. ******************************************************************************/
  478. HRESULT CDfsReplica::FindAndSetDfsReplica ( LPCWSTR a_EntryPath, LPCWSTR a_ServerName, LPCWSTR a_ShareName,
  479. DWORD dwPropertiesReq, CInstance *pInstance, DWORD eOperation, bool &bRoot )
  480. {
  481. PDFS_STORAGE_INFO pRepBuf;
  482. HRESULT hRes = WBEM_E_NOT_FOUND;
  483. PDFS_INFO_300 pData300 = NULL;
  484. DWORD er300 = 0;
  485. DWORD tr300 = 0;
  486. DWORD res = NERR_Success;
  487. // Call the NetDfsEnum function, specifying level 300.
  488. if( ( res = NetDfsEnum( m_ComputerName.GetBuffer ( 0 ), 300, -1, (LPBYTE *) &pData300, &er300, &tr300 ) ) == NERR_Success )
  489. {
  490. if ( pData300 != NULL )
  491. {
  492. try
  493. {
  494. BOOL bContinue = TRUE;
  495. PDFS_INFO_300 p300 = pData300;
  496. for ( int i = 0; (i < er300) && bContinue; i++, p300++ )
  497. {
  498. if ( p300->DfsName != NULL )
  499. {
  500. PDFS_INFO_4 pData4 = NULL;
  501. DWORD er4=0;
  502. DWORD tr4=0;
  503. if ( ( res = NetDfsEnum(p300->DfsName, 4, -1, (LPBYTE *) &pData4, &er4, &tr4) ) == NERR_Success )
  504. {
  505. if ( pData4 != NULL )
  506. {
  507. try
  508. {
  509. BOOL bFound = FALSE;
  510. PDFS_INFO_4 p4 = pData4;
  511. for ( int jj = 0; (jj < er4) && bContinue; jj++, bContinue && (jj < er4) ? p4++ : p4 )
  512. {
  513. if ( _wcsicmp ( a_EntryPath, p4->EntryPath ) == 0 )
  514. {
  515. bFound = TRUE;
  516. bContinue = FALSE;
  517. }
  518. }
  519. if ( bFound )
  520. {
  521. bFound = FALSE;
  522. bContinue = TRUE;
  523. pRepBuf = p4->Storage;
  524. for ( int j = 0; j < p4->NumberOfStorages && bContinue; j++, bContinue && (j < p4->NumberOfStorages) ? pRepBuf++ : pRepBuf )
  525. {
  526. if ( ( _wcsicmp(a_ServerName, pRepBuf->ServerName ) == 0 ) &&
  527. ( _wcsicmp(a_ShareName, pRepBuf->ShareName ) == 0 ) )
  528. {
  529. bFound = TRUE;
  530. bRoot = (pData4 == p4);
  531. bContinue = FALSE;
  532. }
  533. }
  534. if ( bFound )
  535. {
  536. switch ( eOperation )
  537. {
  538. case eGet :
  539. {
  540. hRes = LoadDfsReplica ( dwPropertiesReq, pInstance, p4->EntryPath, pRepBuf );
  541. break;
  542. }
  543. case eDelete:
  544. {
  545. hRes = WBEM_S_NO_ERROR;
  546. break;
  547. }
  548. case eAdd:
  549. {
  550. hRes = WBEM_S_NO_ERROR;
  551. break;
  552. }
  553. }
  554. }
  555. else
  556. {
  557. // we didn't find replica
  558. bContinue = FALSE;
  559. }
  560. }
  561. }
  562. catch(...)
  563. {
  564. NetApiBufferFree(pData4);
  565. pData4 = NULL;
  566. throw;
  567. }
  568. NetApiBufferFree(pData4);
  569. pData4 = NULL;
  570. }
  571. }
  572. // Check to see if there are ANY roots
  573. else if (
  574. (res != ERROR_NO_MORE_ITEMS) &&
  575. (res != ERROR_NO_SUCH_DOMAIN) &&
  576. (res != ERROR_NOT_FOUND) &&
  577. (res != ERROR_ACCESS_DENIED)
  578. )
  579. {
  580. hRes = WBEM_E_FAILED;
  581. bContinue = FALSE;
  582. }
  583. }
  584. }
  585. }
  586. catch ( ... )
  587. {
  588. NetApiBufferFree(pData300);
  589. pData300 = NULL;
  590. throw;
  591. }
  592. NetApiBufferFree(pData300);
  593. pData300 = NULL;
  594. }
  595. }
  596. else if ( (res != ERROR_NO_MORE_ITEMS) && (res != ERROR_NO_SUCH_DOMAIN) && (res != ERROR_NOT_FOUND) ) // Check to see if there are ANY roots
  597. {
  598. if ( ERROR_ACCESS_DENIED == res )
  599. {
  600. hRes = WBEM_E_ACCESS_DENIED ;
  601. }
  602. else
  603. {
  604. hRes = WBEM_E_FAILED ;
  605. }
  606. }
  607. return hRes;
  608. }
  609. /*****************************************************************************
  610. *
  611. * FUNCTION : CDfsReplica::LoadDfsReplica
  612. *
  613. * DESCRIPTION : Loads a Dfs Replica into the instance
  614. *
  615. ******************************************************************************/
  616. HRESULT CDfsReplica::LoadDfsReplica ( DWORD dwPropertiesReq, CInstance *pInstance, LPWSTR lpLinkName, PDFS_STORAGE_INFO pRepBuf )
  617. {
  618. HRESULT hRes = WBEM_S_NO_ERROR;
  619. if ( dwPropertiesReq & DFSREPLICA_PROP_LinkName )
  620. {
  621. if ( pInstance->SetCHString ( LINKNAME, lpLinkName ) == FALSE )
  622. {
  623. hRes = WBEM_E_FAILED;
  624. }
  625. }
  626. if ( dwPropertiesReq & DFSREPLICA_PROP_ServerName )
  627. {
  628. if ( pInstance->SetCHString ( SERVERNAME, pRepBuf->ServerName ) == FALSE )
  629. {
  630. hRes = WBEM_E_FAILED;
  631. }
  632. }
  633. if ( dwPropertiesReq & DFSREPLICA_PROP_ShareName )
  634. {
  635. if ( pInstance->SetCHString ( SHARENAME, pRepBuf->ShareName ) == FALSE )
  636. {
  637. hRes = WBEM_E_FAILED;
  638. }
  639. }
  640. if ( dwPropertiesReq & DFSREPLICA_PROP_State )
  641. {
  642. // need to check the state and then valuemap
  643. DWORD dwState = 0xffff;
  644. switch ( pRepBuf->State )
  645. {
  646. case DFS_STORAGE_STATE_OFFLINE :
  647. {
  648. dwState = 0;
  649. break;
  650. }
  651. case DFS_STORAGE_STATE_ONLINE :
  652. {
  653. dwState = 1;
  654. break;
  655. }
  656. case DFS_STORAGE_STATE_ACTIVE :
  657. {
  658. dwState = 2;
  659. break;
  660. }
  661. }
  662. if ( !pInstance->SetDWORD ( STATE, dwState ) )
  663. {
  664. hRes = WBEM_E_FAILED;
  665. }
  666. }
  667. return hRes;
  668. }
  669. /*****************************************************************************
  670. *
  671. * FUNCTION : CDfsReplica::GetKeys
  672. *
  673. * DESCRIPTION : Get the multi part key
  674. *
  675. *****************************************************************************/
  676. HRESULT CDfsReplica::GetKeys(const CInstance *pInstance, CHString &sLink, CHString &sServer, CHString &sShare)
  677. {
  678. HRESULT hRes = WBEM_S_NO_ERROR;
  679. // Get the Compound Key
  680. if ( !pInstance->GetCHString ( LINKNAME , sLink ) ||
  681. !pInstance->GetCHString ( SERVERNAME , sServer ) ||
  682. !pInstance->GetCHString ( SHARENAME , sShare ) )
  683. {
  684. hRes = WBEM_E_FAILED;
  685. }
  686. return hRes;
  687. }