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.

845 lines
15 KiB

  1. /*++
  2. Copyright (c) 1994-95 Microsoft Corporation
  3. Module Name:
  4. domobj.cpp
  5. Abstract:
  6. Domain object implementation.
  7. Author:
  8. Don Ryan (donryan) 04-Jan-1995
  9. Environment:
  10. User Mode - Win32
  11. Revision History:
  12. --*/
  13. #include "stdafx.h"
  14. #include "llsmgr.h"
  15. #include "lmcons.h"
  16. #include "lmapibuf.h"
  17. #include "lmserver.h"
  18. #include "lmaccess.h"
  19. extern "C" {
  20. #include "dsgetdc.h"
  21. }
  22. #ifdef _DEBUG
  23. #undef THIS_FILE
  24. static char BASED_CODE THIS_FILE[] = __FILE__;
  25. #endif
  26. IMPLEMENT_DYNCREATE(CDomain, CCmdTarget)
  27. BEGIN_MESSAGE_MAP(CDomain, CCmdTarget)
  28. //{{AFX_MSG_MAP(CDomain)
  29. // NOTE - the ClassWizard will add and remove mapping macros here.
  30. //}}AFX_MSG_MAP
  31. END_MESSAGE_MAP()
  32. BEGIN_DISPATCH_MAP(CDomain, CCmdTarget)
  33. //{{AFX_DISPATCH_MAP(CDomain)
  34. DISP_PROPERTY_EX(CDomain, "Name", GetName, SetNotSupported, VT_BSTR)
  35. DISP_PROPERTY_EX(CDomain, "Parent", GetParent, SetNotSupported, VT_DISPATCH)
  36. DISP_PROPERTY_EX(CDomain, "Primary", GetPrimary, SetNotSupported, VT_BSTR)
  37. DISP_PROPERTY_EX(CDomain, "Application", GetApplication, SetNotSupported, VT_DISPATCH)
  38. DISP_PROPERTY_EX(CDomain, "Controller", GetController, SetNotSupported, VT_BSTR)
  39. DISP_PROPERTY_EX(CDomain, "IsLogging", IsLogging, SetNotSupported, VT_BOOL)
  40. DISP_PROPERTY_PARAM(CDomain, "Servers", GetServers, SetNotSupported, VT_DISPATCH, VTS_VARIANT)
  41. DISP_PROPERTY_PARAM(CDomain, "Users", GetUsers, SetNotSupported, VT_DISPATCH, VTS_VARIANT)
  42. DISP_PROPERTY_PARAM(CDomain, "TrustedDomains", GetTrustedDomains, SetNotSupported, VT_DISPATCH, VTS_VARIANT)
  43. DISP_DEFVALUE(CDomain, "Name")
  44. //}}AFX_DISPATCH_MAP
  45. END_DISPATCH_MAP()
  46. CDomain::CDomain(CCmdTarget* pParent, LPCTSTR pName)
  47. /*++
  48. Routine Description:
  49. Constructor for domain object.
  50. Arguments:
  51. pParent - creator of object.
  52. pName - name of domain.
  53. Return Values:
  54. None.
  55. --*/
  56. {
  57. EnableAutomation();
  58. #ifdef ENABLE_PARENT_CHECK
  59. ASSERT(pParent && pParent->IsKindOf(RUNTIME_CLASS(CApplication)));
  60. #endif // ENABLE_PARENT_CHECK
  61. m_pParent = pParent;
  62. ASSERT(pName && *pName);
  63. m_strName = pName;
  64. m_strPrimary.Empty();
  65. m_strController.Empty();
  66. m_pServers = NULL;
  67. m_pDomains = NULL;
  68. m_pUsers = NULL;
  69. m_serverArray.RemoveAll();
  70. m_domainArray.RemoveAll();
  71. m_userArray.RemoveAll();
  72. m_bServersRefreshed = FALSE;
  73. m_bDomainsRefreshed = FALSE;
  74. m_bUsersRefreshed = FALSE;
  75. }
  76. CDomain::~CDomain()
  77. /*++
  78. Routine Description:
  79. Destructor for domain object.
  80. Arguments:
  81. None.
  82. Return Values:
  83. None.
  84. --*/
  85. {
  86. if (m_pUsers)
  87. m_pUsers->InternalRelease();
  88. if (m_pServers)
  89. m_pServers->InternalRelease();
  90. if (m_pDomains)
  91. m_pDomains->InternalRelease();
  92. }
  93. void CDomain::OnFinalRelease()
  94. /*++
  95. Routine Description:
  96. When the last reference for an automation object is released
  97. OnFinalRelease is called. This implementation deletes object.
  98. Arguments:
  99. None.
  100. Return Values:
  101. None.
  102. --*/
  103. {
  104. ResetUsers();
  105. ResetServers();
  106. ResetDomains();
  107. delete this;
  108. }
  109. LPDISPATCH CDomain::GetApplication()
  110. /*++
  111. Routine Description:
  112. Returns the application object.
  113. Arguments:
  114. None.
  115. Return Values:
  116. VT_DISPATCH.
  117. --*/
  118. {
  119. return theApp.GetAppIDispatch();
  120. }
  121. BSTR CDomain::GetController()
  122. /*++
  123. Routine Description:
  124. Returns license controller for domain.
  125. Arguments:
  126. None.
  127. Return Values:
  128. VT_BSTR.
  129. --*/
  130. {
  131. return NULL; // CODEWORK...
  132. }
  133. BSTR CDomain::GetName()
  134. /*++
  135. Routine Description:
  136. Returns the name of the domain.
  137. Arguments:
  138. None.
  139. Return Values:
  140. None.
  141. --*/
  142. {
  143. return m_strName.AllocSysString();
  144. }
  145. LPDISPATCH CDomain::GetParent()
  146. /*++
  147. Routine Description:
  148. Returns the parent of the object.
  149. Arguments:
  150. None.
  151. Return Values:
  152. VT_DISPATCH.
  153. --*/
  154. {
  155. return m_pParent ? m_pParent->GetIDispatch(TRUE) : NULL;
  156. }
  157. BSTR CDomain::GetPrimary()
  158. /*++
  159. Routine Description:
  160. Returns the name of the ANY domain controller.
  161. Arguments:
  162. None.
  163. Return Values:
  164. VT_BSTR.
  165. --*/
  166. {
  167. if (m_strPrimary.IsEmpty())
  168. {
  169. DWORD NetStatus;
  170. PDOMAIN_CONTROLLER_INFO pDcInfo;
  171. NetStatus = DsGetDcName( NULL,
  172. MKSTR(m_strName),
  173. (GUID *)NULL,
  174. NULL,
  175. DS_IS_FLAT_NAME | DS_RETURN_DNS_NAME,
  176. &pDcInfo );
  177. if (NetStatus == ERROR_SUCCESS)
  178. {
  179. m_strPrimary = pDcInfo->DomainControllerName;
  180. ::NetApiBufferFree((LPBYTE)pDcInfo);
  181. }
  182. LlsSetLastStatus(NetStatus); // called api
  183. }
  184. return m_strPrimary.AllocSysString();
  185. }
  186. LPDISPATCH CDomain::GetServers(const VARIANT FAR& index)
  187. /*++
  188. Routine Description:
  189. Returns a collection object containing all of the
  190. servers in the domain or returns an individual server
  191. described by an index into the collection.
  192. Arguments:
  193. index - optional argument that may be a string (VT_BSTR)
  194. indicating the server name or a number (VT_I4) indicating
  195. the position within collection.
  196. Return Values:
  197. VT_DISPATCH or VT_EMPTY.
  198. --*/
  199. {
  200. LPDISPATCH lpdispatch = NULL;
  201. if (!m_pServers)
  202. {
  203. m_pServers = new CServers(this, &m_serverArray);
  204. }
  205. if (m_pServers)
  206. {
  207. if (V_ISVOID((VARIANT FAR*)&index))
  208. {
  209. if (RefreshServers())
  210. {
  211. lpdispatch = m_pServers->GetIDispatch(TRUE);
  212. }
  213. }
  214. else
  215. {
  216. if (m_bServersRefreshed)
  217. {
  218. lpdispatch = m_pServers->GetItem(index);
  219. }
  220. else if (RefreshServers())
  221. {
  222. lpdispatch = m_pServers->GetItem(index);
  223. }
  224. }
  225. }
  226. else
  227. {
  228. LlsSetLastStatus(STATUS_NO_MEMORY);
  229. }
  230. return lpdispatch;
  231. }
  232. LPDISPATCH CDomain::GetTrustedDomains(const VARIANT FAR& index)
  233. /*++
  234. Routine Description:
  235. Returns a collection object containing all of the
  236. domains trusted bythe domain or returns an individual
  237. trusted domain described by an index into the collection.
  238. Arguments:
  239. index - optional argument that may be a string (VT_BSTR)
  240. indicating the domain name or a number (VT_I4) indicating
  241. the position within collection.
  242. Return Values:
  243. VT_DISPATCH or VT_EMPTY.
  244. --*/
  245. {
  246. LPDISPATCH lpdispatch = NULL;
  247. if (!m_pDomains)
  248. {
  249. m_pDomains = new CDomains(this, &m_domainArray);
  250. }
  251. if (m_pDomains)
  252. {
  253. if (V_ISVOID((VARIANT FAR*)&index))
  254. {
  255. if (RefreshDomains())
  256. {
  257. lpdispatch = m_pDomains->GetIDispatch(TRUE);
  258. }
  259. }
  260. else
  261. {
  262. if (m_bDomainsRefreshed)
  263. {
  264. lpdispatch = m_pDomains->GetItem(index);
  265. }
  266. else if (RefreshDomains())
  267. {
  268. lpdispatch = m_pDomains->GetItem(index);
  269. }
  270. }
  271. }
  272. else
  273. {
  274. LlsSetLastStatus(STATUS_NO_MEMORY);
  275. }
  276. return lpdispatch;
  277. }
  278. LPDISPATCH CDomain::GetUsers(const VARIANT FAR& index)
  279. /*++
  280. Routine Description:
  281. Returns a collection object containing all of the
  282. users in the domain or returns an individual user
  283. described by an index into the collection.
  284. Arguments:
  285. index - optional argument that may be a string (VT_BSTR)
  286. indicating the user name or a number (VT_I4) indicating
  287. the position within collection.
  288. Return Values:
  289. VT_DISPATCH or VT_EMPTY.
  290. --*/
  291. {
  292. LPDISPATCH lpdispatch = NULL;
  293. if (!m_pUsers)
  294. {
  295. m_pUsers = new CUsers(this, &m_userArray);
  296. }
  297. if (m_pUsers)
  298. {
  299. if (V_ISVOID((VARIANT FAR*)&index))
  300. {
  301. if (RefreshUsers())
  302. {
  303. lpdispatch = m_pUsers->GetIDispatch(TRUE);
  304. }
  305. }
  306. else
  307. {
  308. if (m_bUsersRefreshed)
  309. {
  310. lpdispatch = m_pUsers->GetItem(index);
  311. }
  312. else if (RefreshUsers())
  313. {
  314. lpdispatch = m_pUsers->GetItem(index);
  315. }
  316. }
  317. }
  318. else
  319. {
  320. LlsSetLastStatus(STATUS_NO_MEMORY);
  321. }
  322. return lpdispatch;
  323. }
  324. BOOL CDomain::IsLogging()
  325. /*++
  326. Routine Description:
  327. Returns true if primary replicating license information.
  328. Arguments:
  329. None.
  330. Return Values:
  331. VT_BOOL.
  332. --*/
  333. {
  334. return TRUE; // CODEWORK... LlsEnterpriseServerFind??
  335. }
  336. BOOL CDomain::RefreshDomains()
  337. /*++
  338. Routine Description:
  339. Refreshs trusted domain array.
  340. Arguments:
  341. None.
  342. Return Values:
  343. VT_BOOL.
  344. --*/
  345. {
  346. ResetDomains();
  347. ULONG DomainCount = 0;
  348. PDS_DOMAIN_TRUSTS pDomains = NULL;
  349. NET_API_STATUS NetStatus = 0;
  350. OutputDebugString( L"CDomain::RefreshDomains\n" );
  351. NetStatus = DsEnumerateDomainTrusts( NULL,
  352. // DS_DOMAIN_IN_FOREST |
  353. DS_DOMAIN_DIRECT_OUTBOUND, //|
  354. // DS_DOMAIN_PRIMARY,
  355. &pDomains,
  356. &DomainCount );
  357. if (NetStatus == NO_ERROR)
  358. {
  359. CDomain* pDomain;
  360. int DomainsAdded = 0;
  361. for ( ;DomainCount--; pDomains++)
  362. {
  363. if ( (pDomains->Flags
  364. & (DS_DOMAIN_IN_FOREST | DS_DOMAIN_DIRECT_OUTBOUND))
  365. && (pDomains->TrustType
  366. & (TRUST_TYPE_DOWNLEVEL | TRUST_TYPE_UPLEVEL)))
  367. {
  368. DBGMSG( L"\tNetbiosDomainName = %s\n" , pDomains->NetbiosDomainName );
  369. pDomain = new CDomain(this, pDomains->NetbiosDomainName);
  370. m_domainArray.SetAtGrow(DomainsAdded, pDomain); // validate later
  371. DomainsAdded++;
  372. }
  373. }
  374. m_domainArray.SetSize(DomainsAdded);
  375. m_bDomainsRefreshed = TRUE;
  376. NetApiBufferFree(pDomains);
  377. }
  378. LlsSetLastStatus(NetStatus); // called api
  379. return m_bDomainsRefreshed;
  380. }
  381. BOOL CDomain::RefreshServers()
  382. /*++
  383. Routine Description:
  384. Refreshs server object array.
  385. Arguments:
  386. None.
  387. Return Values:
  388. VT_BOOL.
  389. --*/
  390. {
  391. ResetServers();
  392. NET_API_STATUS NetStatus;
  393. DWORD ResumeHandle = 0L;
  394. int iServer = 0;
  395. do
  396. {
  397. DWORD EntriesRead;
  398. DWORD TotalEntries;
  399. LPBYTE ReturnBuffer = NULL;
  400. NetStatus = ::NetServerEnum(
  401. NULL, // servername
  402. 100, // level
  403. &ReturnBuffer,
  404. LLS_PREFERRED_LENGTH,
  405. &EntriesRead,
  406. &TotalEntries,
  407. SV_TYPE_NT,
  408. MKSTR(m_strName),
  409. &ResumeHandle
  410. );
  411. if (NetStatus == ERROR_SUCCESS ||
  412. NetStatus == ERROR_MORE_DATA)
  413. {
  414. CServer* pServer;
  415. PSERVER_INFO_100 pServerInfo100;
  416. pServerInfo100 = (PSERVER_INFO_100)ReturnBuffer;
  417. ASSERT(iServer == m_serverArray.GetSize());
  418. m_serverArray.SetSize(m_serverArray.GetSize() + EntriesRead);
  419. while (EntriesRead--)
  420. {
  421. pServer = new CServer(this, pServerInfo100->sv100_name);
  422. m_serverArray.SetAt(iServer++, pServer); // validate later
  423. pServerInfo100++;
  424. }
  425. NetApiBufferFree(ReturnBuffer);
  426. }
  427. } while (NetStatus == ERROR_MORE_DATA);
  428. LlsSetLastStatus(NetStatus); // called api
  429. if (NetStatus == ERROR_SUCCESS)
  430. {
  431. m_bServersRefreshed = TRUE;
  432. }
  433. else
  434. {
  435. ResetServers();
  436. }
  437. return m_bServersRefreshed;
  438. }
  439. BOOL CDomain::RefreshUsers()
  440. /*++
  441. Routine Description:
  442. Refreshs user object array.
  443. Arguments:
  444. None.
  445. Return Values:
  446. VT_BOOL.
  447. --*/
  448. {
  449. ResetUsers();
  450. NET_API_STATUS NetStatus;
  451. DWORD ResumeHandle = 0L;
  452. int iUser = 0;
  453. do
  454. {
  455. DWORD EntriesRead;
  456. DWORD TotalEntries;
  457. LPBYTE ReturnBuffer = NULL;
  458. NetStatus = NetUserEnum(
  459. GetPrimary(), // servername
  460. 0, // level
  461. FILTER_NORMAL_ACCOUNT,
  462. &ReturnBuffer,
  463. LLS_PREFERRED_LENGTH,
  464. &EntriesRead,
  465. &TotalEntries,
  466. &ResumeHandle
  467. );
  468. if (NetStatus == ERROR_SUCCESS ||
  469. NetStatus == ERROR_MORE_DATA)
  470. {
  471. CUser* pUser;
  472. PUSER_INFO_0 pUserInfo0;
  473. pUserInfo0 = (PUSER_INFO_0)ReturnBuffer;
  474. ASSERT(iUser == m_userArray.GetSize());
  475. m_userArray.SetSize(m_userArray.GetSize() + EntriesRead);
  476. while (EntriesRead--)
  477. {
  478. pUser = new CUser(this, pUserInfo0->usri0_name);
  479. m_userArray.SetAt(iUser++, pUser); // validate later
  480. pUserInfo0++;
  481. }
  482. NetApiBufferFree(ReturnBuffer);
  483. }
  484. } while (NetStatus == ERROR_MORE_DATA);
  485. LlsSetLastStatus(NetStatus); // called api
  486. if (NetStatus == ERROR_SUCCESS)
  487. {
  488. m_bUsersRefreshed = TRUE;
  489. }
  490. else
  491. {
  492. ResetUsers();
  493. }
  494. return m_bUsersRefreshed;
  495. }
  496. void CDomain::ResetDomains()
  497. /*++
  498. Routine Description:
  499. Resets domain object array.
  500. Arguments:
  501. None.
  502. Return Values:
  503. None.
  504. --*/
  505. {
  506. CDomain* pDomain;
  507. INT_PTR iDomain = m_domainArray.GetSize();
  508. while (iDomain--)
  509. {
  510. if (pDomain = (CDomain*)m_domainArray[iDomain])
  511. {
  512. ASSERT(pDomain->IsKindOf(RUNTIME_CLASS(CDomain)));
  513. pDomain->InternalRelease();
  514. }
  515. }
  516. m_domainArray.RemoveAll();
  517. m_bDomainsRefreshed = FALSE;
  518. }
  519. void CDomain::ResetServers()
  520. /*++
  521. Routine Description:
  522. Resets server object array.
  523. Arguments:
  524. None.
  525. Return Values:
  526. None.
  527. --*/
  528. {
  529. CServer* pServer;
  530. INT_PTR iServer = m_serverArray.GetSize();
  531. while (iServer--)
  532. {
  533. if (pServer = (CServer*)m_serverArray[iServer])
  534. {
  535. ASSERT(pServer->IsKindOf(RUNTIME_CLASS(CServer)));
  536. pServer->InternalRelease();
  537. }
  538. }
  539. m_serverArray.RemoveAll();
  540. m_bServersRefreshed = FALSE;
  541. }
  542. void CDomain::ResetUsers()
  543. /*++
  544. Routine Description:
  545. Resets user object array.
  546. Arguments:
  547. None.
  548. Return Values:
  549. None.
  550. --*/
  551. {
  552. CUser* pUser;
  553. INT_PTR iUser = m_userArray.GetSize();
  554. while (iUser--)
  555. {
  556. if (pUser = (CUser*)m_userArray[iUser])
  557. {
  558. ASSERT(pUser->IsKindOf(RUNTIME_CLASS(CUser)));
  559. pUser->InternalRelease();
  560. }
  561. }
  562. m_userArray.RemoveAll();
  563. m_bUsersRefreshed = FALSE;
  564. }