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.

778 lines
20 KiB

  1. //++
  2. //
  3. // Copyright (C) Microsoft Corporation, 1987 - 1999
  4. //
  5. // Module Name:
  6. //
  7. // dsgetdc.c
  8. //
  9. // Abstract:
  10. //
  11. // Queries into network drivers
  12. //
  13. // Author:
  14. //
  15. // Anilth - 4-20-1998
  16. //
  17. // Environment:
  18. //
  19. // User mode only.
  20. // Contains NT-specific code.
  21. //
  22. // Revision History:
  23. //
  24. //--
  25. #include "precomp.h"
  26. #include "objbase.h"
  27. VOID PrintDsGetDcName(IN NETDIAG_RESULT *pResults,
  28. IN OUT PLIST_ENTRY plmsgOutput,
  29. IN PDOMAIN_CONTROLLER_INFOW DomainControllerInfo);
  30. NET_API_STATUS SetPrimaryGuid(IN GUID *GuidToSet);
  31. HRESULT
  32. DsGetDcTest(NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults)
  33. /*++
  34. Routine Description:
  35. Ensure that we can find domain controllers
  36. Arguments:
  37. None.
  38. Return Value:
  39. TRUE: Test suceeded.
  40. FALSE: Test failed
  41. --*/
  42. {
  43. NET_API_STATUS NetStatus;
  44. NET_API_STATUS LocalNetStatus;
  45. BOOL RetVal = TRUE;
  46. HRESULT hr = hrOK;
  47. LPTSTR pszDcType;
  48. PTESTED_DOMAIN pTestedDomain = (PTESTED_DOMAIN) pParams->pDomain;
  49. PDOMAIN_CONTROLLER_INFOW LocalDomainControllerInfo = NULL;
  50. //if the machine is a member machine or DC, DsGetDc Test will get called.
  51. //Otherwise, this test will be skipped
  52. pResults->DsGetDc.fPerformed = TRUE;
  53. //the DsGetDc test will be called for every domain, but we only want to initialize
  54. //the message list once.
  55. if(pResults->DsGetDc.lmsgOutput.Flink == NULL)
  56. InitializeListHead(&pResults->DsGetDc.lmsgOutput);
  57. PrintStatusMessage(pParams, 4, IDS_DSGETDC_STATUS_MSG);
  58. //
  59. // Find a generic DC
  60. //
  61. PrintStatusMessage(pParams, 4, IDS_DSGETDC_STATUS_DC);
  62. pszDcType = LoadAndAllocString(IDS_DCTYPE_DC);
  63. NetStatus = DoDsGetDcName( pParams,
  64. pResults,
  65. &pResults->DsGetDc.lmsgOutput,
  66. pTestedDomain,
  67. DS_DIRECTORY_SERVICE_PREFERRED,
  68. pszDcType, //_T("DC"),
  69. TRUE,
  70. &pTestedDomain->DcInfo );
  71. Free(pszDcType);
  72. pTestedDomain->fTriedToFindDcInfo = TRUE;
  73. if ( NetStatus != NO_ERROR ) {
  74. hr = S_FALSE;
  75. goto Error;
  76. }
  77. //
  78. // Find a PDC
  79. // (Failure isn't fatal.)
  80. //
  81. PrintStatusMessage(pParams, 4, IDS_DSGETDC_STATUS_PDC);
  82. pszDcType = LoadAndAllocString(IDS_DCTYPE_PDC);
  83. LocalNetStatus = DoDsGetDcName(pParams,
  84. pResults,
  85. &pResults->DsGetDc.lmsgOutput,
  86. pTestedDomain,
  87. DS_PDC_REQUIRED,
  88. pszDcType, //_T("PDC"),
  89. FALSE,
  90. &LocalDomainControllerInfo );
  91. Free(pszDcType);
  92. if ( LocalNetStatus == NO_ERROR )
  93. {
  94. if ( LocalDomainControllerInfo != NULL )
  95. {
  96. NetApiBufferFree( LocalDomainControllerInfo );
  97. LocalDomainControllerInfo = NULL;
  98. }
  99. }
  100. //
  101. // Find an NT 5 DC
  102. // (Failure isn't fatal.)
  103. //
  104. PrintStatusMessage(pParams, 4, IDS_DSGETDC_STATUS_NT5DC);
  105. pszDcType = LoadAndAllocString(IDS_DCTYPE_W2K_DC);
  106. LocalNetStatus = DoDsGetDcName(pParams,
  107. pResults,
  108. &pResults->DsGetDc.lmsgOutput,
  109. pTestedDomain,
  110. DS_DIRECTORY_SERVICE_REQUIRED,
  111. pszDcType, //_T("Windows 2000 DC"),
  112. FALSE,
  113. &LocalDomainControllerInfo );
  114. Free(pszDcType);
  115. if ( LocalNetStatus == NO_ERROR )
  116. {
  117. if ( LocalDomainControllerInfo != NULL )
  118. {
  119. NetApiBufferFree( LocalDomainControllerInfo );
  120. LocalDomainControllerInfo = NULL;
  121. }
  122. }
  123. //
  124. // Ensure the returned domain GUID is the domain GUID stored in the LSA
  125. //
  126. if ( pTestedDomain == pResults->Global.pMemberDomain )
  127. {
  128. if ( !IsEqualGUID( &pResults->Global.pPrimaryDomainInfo->DomainGuid, &NlDcZeroGuid ) &&
  129. !IsEqualGUID( &pTestedDomain->DcInfo->DomainGuid, &NlDcZeroGuid ) &&
  130. !IsEqualGUID( &pResults->Global.pPrimaryDomainInfo->DomainGuid,
  131. &pTestedDomain->DcInfo->DomainGuid ) )
  132. {
  133. // Need to convert the two GUIDS
  134. WCHAR swzGuid1[64];
  135. WCHAR swzGuid2[64];
  136. StringFromGUID2(&pResults->Global.pPrimaryDomainInfo->DomainGuid,
  137. swzGuid1,
  138. DimensionOf(swzGuid1));
  139. StringFromGUID2(&pTestedDomain->DcInfo->DomainGuid,
  140. swzGuid2,
  141. DimensionOf(swzGuid2));
  142. // " [FATAL] Your machine thinks the domain GUID of domain '%ws' is\n '"
  143. // "' but \n '%ws' thinks it is\n '"
  144. AddMessageToList(&pResults->DsGetDc.lmsgOutput,
  145. Nd_Quiet,
  146. IDS_DSGETDC_FATAL_GUID,
  147. pResults->Global.pPrimaryDomainInfo->DomainNameFlat,
  148. swzGuid1,
  149. pTestedDomain->DcInfo->DomainControllerName,
  150. swzGuid2);
  151. hr = S_FALSE;
  152. //
  153. // Attempt to fix the problem.
  154. //
  155. if ( !pParams->fFixProblems )
  156. {
  157. // "\nConsider running 'nettest /fix' to try to fix this problem\n"
  158. AddMessageToList( &pResults->DsGetDc.lmsgOutput, Nd_Quiet, IDS_DSGETDC_13206 );
  159. }
  160. else
  161. {
  162. NetStatus = SetPrimaryGuid( &pTestedDomain->DcInfo->DomainGuid );
  163. if ( NetStatus != NO_ERROR )
  164. {
  165. if ( NetStatus == ERROR_ACCESS_DENIED )
  166. {
  167. // "\nCannot fix domain GUID since you are not an administrator. Leave then rejoin the domain.\n"
  168. AddMessageToList( &pResults->DsGetDc.lmsgOutput, Nd_Quiet, IDS_DSGETDC_13207 );
  169. }
  170. else
  171. {
  172. // " [FATAL] Failed to fix Domain Guid. [%s]\n"
  173. AddMessageToList( &pResults->DsGetDc.lmsgOutput, Nd_Quiet,
  174. IDS_DSGETDC_13208, NetStatusToString(NetStatus) );
  175. }
  176. }
  177. else
  178. {
  179. // "\nFixed domain GUID. Reboot then run 'nettest' again to ensure everything is working.\n"
  180. AddMessageToList( &pResults->DsGetDc.lmsgOutput, Nd_Quiet, IDS_DSGETDC_13209 );
  181. }
  182. }
  183. }
  184. }
  185. Error:
  186. //$REVIEW (nsun 10/05/98) CliffV deleted DCNameClose()
  187. //DCNameClose();
  188. pResults->DsGetDc.hr = hr;
  189. return hr;
  190. }
  191. VOID
  192. PrintDsGetDcName(
  193. IN NETDIAG_RESULT *pResults,
  194. IN OUT PLIST_ENTRY plmsgOutput,
  195. IN PDOMAIN_CONTROLLER_INFOW DomainControllerInfo
  196. )
  197. /*++
  198. Routine Description:
  199. Prints the information returned from DsGetDcName
  200. Arguments:
  201. DomainControllerInfo - Information to print
  202. Return Value:
  203. None.
  204. --*/
  205. {
  206. // " DC: %ws\n"
  207. AddMessageToList( plmsgOutput,
  208. Nd_Quiet,
  209. IDS_DSGETDC_13210,
  210. DomainControllerInfo->DomainControllerName );
  211. // " Address: %ws\n"
  212. AddMessageToList( plmsgOutput,
  213. Nd_Quiet,
  214. IDS_DSGETDC_13211,
  215. DomainControllerInfo->DomainControllerAddress );
  216. if ( !IsEqualGUID( &DomainControllerInfo->DomainGuid, &NlDcZeroGuid) )
  217. {
  218. WCHAR swzGuid[64];
  219. StringFromGUID2(&DomainControllerInfo->DomainGuid,
  220. swzGuid,
  221. DimensionOf(swzGuid));
  222. // " Domain Guid . . . . . . : %ws\n"
  223. AddMessageToList( plmsgOutput,
  224. Nd_Quiet,
  225. IDS_DSGETDC_13212,
  226. swzGuid);
  227. }
  228. if ( DomainControllerInfo->DomainName != NULL )
  229. {
  230. // " Dom Name: %ws\n"
  231. AddMessageToList( plmsgOutput,
  232. Nd_Quiet,
  233. IDS_DSGETDC_13214,
  234. DomainControllerInfo->DomainName );
  235. }
  236. if ( DomainControllerInfo->DnsForestName != NULL )
  237. {
  238. // " Forest Name: %ws\n"
  239. AddMessageToList( plmsgOutput,
  240. Nd_Quiet,
  241. IDS_DSGETDC_13215,
  242. DomainControllerInfo->DnsForestName );
  243. }
  244. if ( DomainControllerInfo->DcSiteName != NULL )
  245. {
  246. // " Dc Site Name: %ws\n"
  247. AddMessageToList( plmsgOutput,
  248. Nd_Quiet,
  249. IDS_DSGETDC_13216,
  250. DomainControllerInfo->DcSiteName );
  251. }
  252. if ( DomainControllerInfo->ClientSiteName != NULL )
  253. {
  254. // " Our Site Name: %ws\n"
  255. AddMessageToList( plmsgOutput,
  256. Nd_Quiet,
  257. IDS_DSGETDC_13217,
  258. DomainControllerInfo->ClientSiteName );
  259. }
  260. if ( DomainControllerInfo->Flags )
  261. {
  262. ULONG LocalFlags = DomainControllerInfo->Flags;
  263. // " Flags:"
  264. AddMessageToList( plmsgOutput,
  265. Nd_Quiet,
  266. IDS_DSGETDC_13218 );
  267. if ( LocalFlags & DS_PDC_FLAG )
  268. {
  269. // " PDC"
  270. AddMessageToList( plmsgOutput,
  271. Nd_Quiet,
  272. (LocalFlags & DS_DS_FLAG) ? IDS_DSGETDC_13219 : IDS_DSGETDC_NT4_PDC);
  273. LocalFlags &= ~DS_PDC_FLAG;
  274. }
  275. if ( LocalFlags & DS_GC_FLAG ) {
  276. //IDS_DSGETDC_13220 " GC"
  277. AddMessageToList( plmsgOutput,
  278. Nd_Quiet,
  279. IDS_DSGETDC_13220);
  280. LocalFlags &= ~DS_GC_FLAG;
  281. }
  282. if ( LocalFlags & DS_DS_FLAG ) {
  283. //IDS_DSGETDC_13221 " DS"
  284. AddMessageToList( plmsgOutput,
  285. Nd_Quiet,
  286. IDS_DSGETDC_13221);
  287. LocalFlags &= ~DS_DS_FLAG;
  288. }
  289. if ( LocalFlags & DS_KDC_FLAG ) {
  290. //IDS_DSGETDC_13222 " KDC"
  291. AddMessageToList( plmsgOutput,
  292. Nd_Quiet,
  293. IDS_DSGETDC_13222);
  294. LocalFlags &= ~DS_KDC_FLAG;
  295. }
  296. if ( LocalFlags & DS_TIMESERV_FLAG ) {
  297. //IDS_DSGETDC_13223 " TIMESERV"
  298. AddMessageToList( plmsgOutput,
  299. Nd_Quiet,
  300. IDS_DSGETDC_13223);
  301. LocalFlags &= ~DS_TIMESERV_FLAG;
  302. }
  303. if ( LocalFlags & DS_GOOD_TIMESERV_FLAG ) {
  304. //IDS_DSGETDC_13224 " GTIMESERV"
  305. AddMessageToList( plmsgOutput,
  306. Nd_Quiet,
  307. IDS_DSGETDC_13224);
  308. LocalFlags &= ~DS_GOOD_TIMESERV_FLAG;
  309. }
  310. if ( LocalFlags & DS_WRITABLE_FLAG ) {
  311. //IDS_DSGETDC_13225 " WRITABLE"
  312. AddMessageToList( plmsgOutput,
  313. Nd_Quiet,
  314. IDS_DSGETDC_13225);
  315. LocalFlags &= ~DS_WRITABLE_FLAG;
  316. }
  317. if ( LocalFlags & DS_DNS_CONTROLLER_FLAG ) {
  318. //IDS_DSGETDC_13226 " DNS_DC"
  319. AddMessageToList( plmsgOutput,
  320. Nd_Quiet,
  321. IDS_DSGETDC_13226);
  322. LocalFlags &= ~DS_DNS_CONTROLLER_FLAG;
  323. }
  324. if ( LocalFlags & DS_DNS_DOMAIN_FLAG ) {
  325. //IDS_DSGETDC_13227 " DNS_DOMAIN"
  326. AddMessageToList( plmsgOutput,
  327. Nd_Quiet,
  328. IDS_DSGETDC_13227);
  329. LocalFlags &= ~DS_DNS_DOMAIN_FLAG;
  330. }
  331. if ( LocalFlags & DS_DNS_FOREST_FLAG ) {
  332. //IDS_DSGETDC_13228 " DNS_FOREST"
  333. AddMessageToList( plmsgOutput,
  334. Nd_Quiet,
  335. IDS_DSGETDC_13228);
  336. LocalFlags &= ~DS_DNS_FOREST_FLAG;
  337. }
  338. if ( LocalFlags & DS_CLOSEST_FLAG ) {
  339. //IDS_DSGETDC_13229 " CLOSE_SITE"
  340. AddMessageToList( plmsgOutput,
  341. Nd_Quiet,
  342. IDS_DSGETDC_13229);
  343. LocalFlags &= ~DS_CLOSEST_FLAG;
  344. }
  345. if ( LocalFlags != 0 ) {
  346. //IDS_DSGETDC_13230 " 0x%lX"
  347. AddMessageToList( plmsgOutput,
  348. Nd_Quiet,
  349. IDS_DSGETDC_13230,
  350. LocalFlags);
  351. }
  352. //IDS_DSGETDC_13231 "\n"
  353. AddMessageToList( plmsgOutput,
  354. Nd_Quiet,
  355. IDS_DSGETDC_13231);
  356. }
  357. }
  358. NET_API_STATUS
  359. DoDsGetDcName(IN NETDIAG_PARAMS *pParams,
  360. IN OUT NETDIAG_RESULT *pResults,
  361. OUT PLIST_ENTRY plmsgOutput,
  362. IN PTESTED_DOMAIN pTestedDomain,
  363. IN DWORD Flags,
  364. IN LPTSTR pszDcType,
  365. IN BOOLEAN IsFatal,
  366. OUT PDOMAIN_CONTROLLER_INFOW *DomainControllerInfo
  367. )
  368. /*++
  369. Routine Description:
  370. Does a DsGetDcName
  371. Arguments:
  372. plmsgOutput - The message list to dump output
  373. pTestedDomain - Domain to test
  374. Flags - Flags to pass to DsGetDcName
  375. pszDcType - English description of Flags
  376. IsFatal - True if failure is fatal
  377. DomainControllerInfo - Return Domain Controller information
  378. Return Value:
  379. Status of the operation.
  380. --*/
  381. {
  382. NET_API_STATUS NetStatus;
  383. PDOMAIN_CONTROLLER_INFOW LocalDomainControllerInfo = NULL;
  384. LPSTR Severity;
  385. //
  386. // Initialization
  387. //
  388. if ( IsFatal ) {
  389. Severity = "[FATAL]";
  390. } else {
  391. Severity = "[WARNING]";
  392. }
  393. if ( pParams->fReallyVerbose )
  394. {
  395. // "\n Find %s in domain '%ws':\n"
  396. AddMessageToList( plmsgOutput, Nd_ReallyVerbose, IDS_DSGETDC_13232, pszDcType, pTestedDomain->PrintableDomainName );
  397. }
  398. //
  399. // Find a DC in the domain.
  400. // Use the DsGetDcName built into nettest.
  401. //
  402. NetStatus = GetADc( pParams,
  403. pResults,
  404. plmsgOutput,
  405. // Commented out to port to Source Depot - smanda
  406. #ifdef SLM_TREE
  407. NettestDsGetDcNameW,
  408. #else
  409. DsGetDcNameW,
  410. #endif
  411. pTestedDomain,
  412. Flags,
  413. DomainControllerInfo );
  414. if ( NetStatus != NO_ERROR )
  415. {
  416. // " %s Cannot find %s in domain '%ws'. [%s]\n"
  417. AddMessageToList( plmsgOutput,
  418. Nd_Quiet,
  419. IDS_DSGETDC_13233,
  420. Severity,
  421. pszDcType,
  422. pTestedDomain->PrintableDomainName,
  423. NetStatusToString(NetStatus));
  424. if ( NetStatus == ERROR_NO_SUCH_DOMAIN ) {
  425. if ( Flags & DS_DIRECTORY_SERVICE_REQUIRED )
  426. {
  427. // "\n This isn't a problem if domain '%ws' does not have any NT 5.0 DCs.\n"
  428. AddMessageToList( plmsgOutput,
  429. Nd_Quiet,
  430. IDS_DSGETDC_13234,
  431. pTestedDomain->PrintableDomainName );
  432. }
  433. else if ( Flags & DS_PDC_REQUIRED )
  434. {
  435. PrintGuruMessage2(" If the PDC for domain '%ws' is up, ", TestedDomain->PrintableDomainName );
  436. PrintGuru( 0, DSGETDC_GURU );
  437. } else
  438. {
  439. PrintGuruMessage3(" If any %s for domain '%ws' is up, ", DcType, TestedDomain->PrintableDomainName );
  440. PrintGuru( 0, DSGETDC_GURU );
  441. }
  442. }
  443. else
  444. {
  445. PrintGuru( NetStatus, DSGETDC_GURU );
  446. }
  447. //
  448. // If that worked,
  449. // try again through netlogon this time.
  450. //
  451. }
  452. else
  453. {
  454. if (pParams->fReallyVerbose )
  455. {
  456. // " Found this %s in domain '%ws':\n"
  457. AddMessageToList( plmsgOutput,
  458. Nd_ReallyVerbose,
  459. IDS_DSGETDC_13235,
  460. pszDcType,
  461. pTestedDomain->PrintableDomainName );
  462. PrintDsGetDcName( pResults, plmsgOutput, *DomainControllerInfo );
  463. }
  464. else if ( pParams->fVerbose )
  465. {
  466. // " Found %s '%ws' in domain '%ws'.\n"
  467. AddMessageToList( plmsgOutput,
  468. Nd_Verbose,
  469. IDS_DSGETDC_13236,
  470. pszDcType,
  471. (*DomainControllerInfo)->DomainControllerName,
  472. pTestedDomain->PrintableDomainName );
  473. }
  474. if ( ((*DomainControllerInfo)->Flags & (DS_DS_FLAG|DS_KDC_FLAG)) == DS_DS_FLAG )
  475. {
  476. // " %s: KDC is not running on NT 5 DC '%ws' in domain '%ws'."
  477. AddMessageToList( plmsgOutput,
  478. Nd_Quiet,
  479. IDS_DSGETDC_13237,
  480. Severity,
  481. (*DomainControllerInfo)->DomainControllerName,
  482. pTestedDomain->PrintableDomainName );
  483. }
  484. //
  485. // If netlogon is running,
  486. // try it again using the netlogon service.
  487. //
  488. if ( pResults->Global.fNetlogonIsRunning )
  489. {
  490. NetStatus = GetADc( pParams,
  491. pResults,
  492. plmsgOutput,
  493. DsGetDcNameW,
  494. pTestedDomain,
  495. Flags,
  496. &LocalDomainControllerInfo );
  497. if ( NetStatus != NO_ERROR )
  498. {
  499. // " %s: Netlogon cannot find %s in domain '%ws'. [%s]\n"
  500. AddMessageToList( plmsgOutput,
  501. Nd_Quiet,
  502. IDS_DSGETDC_13238,
  503. Severity,
  504. pszDcType,
  505. pTestedDomain->PrintableDomainName,
  506. NetStatusToString(NetStatus));
  507. //
  508. // If that worked,
  509. // sanity check the returned DC.
  510. //
  511. }
  512. else
  513. {
  514. if ( (LocalDomainControllerInfo->Flags & (DS_DS_FLAG|DS_KDC_FLAG)) == DS_DS_FLAG )
  515. {
  516. // " %s: KDC is not running on NT 5 DC '%ws' in domain '%ws'."
  517. AddMessageToList( plmsgOutput,
  518. Nd_Quiet,
  519. IDS_DSGETDC_13239,
  520. Severity,
  521. LocalDomainControllerInfo->DomainControllerName,
  522. pTestedDomain->PrintableDomainName );
  523. }
  524. }
  525. }
  526. }
  527. if ( LocalDomainControllerInfo != NULL ) {
  528. NetApiBufferFree( LocalDomainControllerInfo );
  529. LocalDomainControllerInfo = NULL;
  530. }
  531. return NetStatus;
  532. }
  533. NET_API_STATUS
  534. SetPrimaryGuid(
  535. IN GUID *GuidToSet
  536. )
  537. /*++
  538. Routine Description:
  539. Set the primary GUID to the specified value.
  540. Arguments:
  541. GuidToSet - Guid to set as the primary GUID
  542. Return Value:
  543. NET_API_STATUS - NERR_Success or reason for failure.
  544. --*/
  545. {
  546. NET_API_STATUS NetStatus;
  547. NTSTATUS Status;
  548. LSA_HANDLE PolicyHandle = NULL;
  549. PPOLICY_DNS_DOMAIN_INFO PrimaryDomainInfo = NULL;
  550. OBJECT_ATTRIBUTES ObjAttributes;
  551. //
  552. // Open a handle to the LSA.
  553. //
  554. InitializeObjectAttributes(
  555. &ObjAttributes,
  556. NULL,
  557. 0L,
  558. NULL,
  559. NULL
  560. );
  561. Status = LsaOpenPolicy(
  562. NULL,
  563. &ObjAttributes,
  564. POLICY_VIEW_LOCAL_INFORMATION |
  565. POLICY_TRUST_ADMIN,
  566. &PolicyHandle
  567. );
  568. if (! NT_SUCCESS(Status)) {
  569. NetStatus = NetpNtStatusToApiStatus(Status);
  570. goto Cleanup;
  571. }
  572. //
  573. // Get the name of the primary domain from LSA
  574. //
  575. Status = LsaQueryInformationPolicy(
  576. PolicyHandle,
  577. PolicyDnsDomainInformation,
  578. (PVOID *) &PrimaryDomainInfo
  579. );
  580. if (! NT_SUCCESS(Status)) {
  581. NetStatus = NetpNtStatusToApiStatus(Status);
  582. goto Cleanup;
  583. }
  584. //
  585. // Set the new GUID of the primary domain into the LSA
  586. //
  587. PrimaryDomainInfo->DomainGuid = *GuidToSet;
  588. Status = LsaSetInformationPolicy(
  589. PolicyHandle,
  590. PolicyDnsDomainInformation,
  591. (PVOID) PrimaryDomainInfo
  592. );
  593. if (! NT_SUCCESS(Status)) {
  594. NetStatus = NetpNtStatusToApiStatus(Status);
  595. goto Cleanup;
  596. }
  597. NetStatus = NO_ERROR;
  598. Cleanup:
  599. if ( PrimaryDomainInfo != NULL ) {
  600. (void) LsaFreeMemory((PVOID) PrimaryDomainInfo);
  601. }
  602. if ( PolicyHandle != NULL ) {
  603. (void) LsaClose(PolicyHandle);
  604. }
  605. return NetStatus;
  606. }
  607. /*!--------------------------------------------------------------------------
  608. DsGetDcGlobalPrint
  609. -
  610. Author: KennT
  611. ---------------------------------------------------------------------------*/
  612. void DsGetDcGlobalPrint( NETDIAG_PARAMS* pParams,
  613. NETDIAG_RESULT* pResults)
  614. {
  615. if (pParams->fVerbose || !FHrOK(pResults->DsGetDc.hr))
  616. {
  617. PrintNewLine(pParams, 2);
  618. PrintTestTitleResult(pParams, IDS_DSGETDC_LONG, IDS_DSGETDC_SHORT, pResults->DsGetDc.fPerformed,
  619. pResults->DsGetDc.hr, 0);
  620. if (pParams->fReallyVerbose || !FHrOK(pResults->DsGetDc.hr))
  621. PrintMessageList(pParams, &pResults->DsGetDc.lmsgOutput);
  622. }
  623. }
  624. /*!--------------------------------------------------------------------------
  625. DsGetDcPerInterfacePrint
  626. -
  627. Author: KennT
  628. ---------------------------------------------------------------------------*/
  629. void DsGetDcPerInterfacePrint( NETDIAG_PARAMS* pParams,
  630. NETDIAG_RESULT* pResults,
  631. INTERFACE_RESULT *pInterfaceResults)
  632. {
  633. // no per-interface results
  634. }
  635. /*!--------------------------------------------------------------------------
  636. DsGetDcCleanup
  637. -
  638. Author: KennT
  639. ---------------------------------------------------------------------------*/
  640. void DsGetDcCleanup( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults)
  641. {
  642. MessageListCleanUp(&pResults->DsGetDc.lmsgOutput);
  643. }