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.

646 lines
14 KiB

  1. //++
  2. //
  3. // Copyright (C) Microsoft Corporation, 1987 - 1999
  4. //
  5. // Module Name:
  6. //
  7. // results.c
  8. //
  9. // Abstract:
  10. //
  11. // Test to ensure that a workstation has network (IP) connectivity to
  12. // the outside.
  13. //
  14. // Author:
  15. //
  16. // 15-Dec-1997 (cliffv)
  17. // Anilth - 4-20-1998
  18. //
  19. // Environment:
  20. //
  21. // User mode only.
  22. // Contains NT-specific code.
  23. //
  24. // Revision History:
  25. //
  26. // 1-June-1998 (denisemi) add DnsServerHasDCRecords to check DC dns records
  27. // registration
  28. //
  29. // 26-June-1998 (t-rajkup) add general tcp/ip , dhcp and routing,
  30. // winsock, ipx, wins and netbt information.
  31. //--
  32. //
  33. // Common include files.
  34. //
  35. #include "precomp.h"
  36. #include "netdiag.h"
  37. #include "ipcfg.h"
  38. static TCHAR s_szBuffer[4096];
  39. static TCHAR s_szFormat[4096];
  40. const TCHAR c_szWaitDots[] = _T(".");
  41. void PrintMessage(NETDIAG_PARAMS *pParams, UINT uMessageID, ...)
  42. {
  43. UINT nBuf;
  44. va_list args;
  45. va_start(args, uMessageID);
  46. LoadString(NULL, uMessageID, s_szFormat, sizeof(s_szFormat));
  47. nBuf = _vstprintf(s_szBuffer, s_szFormat, args);
  48. assert(nBuf < DimensionOf(s_szBuffer));
  49. va_end(args);
  50. PrintMessageSz(pParams, s_szBuffer);
  51. }
  52. void PrintMessageSz(NETDIAG_PARAMS *pParams, LPCTSTR pszMessage)
  53. {
  54. if(pParams->fLog)
  55. {
  56. _ftprintf( pParams->pfileLog, pszMessage );
  57. }
  58. _tprintf(pszMessage);
  59. fflush(stdout);
  60. }
  61. /*!--------------------------------------------------------------------------
  62. ResultsCleanup
  63. -
  64. Author: KennT
  65. ---------------------------------------------------------------------------*/
  66. void ResultsCleanup(NETDIAG_PARAMS *pParams, NETDIAG_RESULT *pResults)
  67. {
  68. int i;
  69. // Clean up the global variables
  70. Free( pResults->Global.pszCurrentVersion );
  71. pResults->Global.pszCurrentVersion = NULL;
  72. Free( pResults->Global.pszCurrentBuildNumber );
  73. pResults->Global.pszCurrentBuildNumber = NULL;
  74. Free( pResults->Global.pszCurrentType );
  75. pResults->Global.pszCurrentType = NULL;
  76. Free( pResults->Global.pszProcessorInfo );
  77. pResults->Global.pszProcessorInfo = NULL;
  78. Free( pResults->Global.pszServerType );
  79. pResults->Global.pszServerType = NULL;
  80. // delete the individual strings
  81. for (i=0; i<pResults->Global.cHotFixes; i++)
  82. Free(pResults->Global.pHotFixes[i].pszName);
  83. Free( pResults->Global.pHotFixes );
  84. pResults->Global.pHotFixes = NULL;
  85. pResults->Global.cHotFixes = 0;
  86. // Do NOT free this up. This will get freed up with the list
  87. // of domains.
  88. // pResults->Global.pMemberDomain
  89. // pResults->Global.pLogonDomain
  90. if (pResults->Global.pMemberDomain)
  91. {
  92. Free( pResults->Global.pMemberDomain->DomainSid );
  93. pResults->Global.pMemberDomain->DomainSid = NULL;
  94. }
  95. LsaFreeMemory(pResults->Global.pLogonUser);
  96. pResults->Global.pLogonUser = NULL;
  97. LsaFreeMemory(pResults->Global.pLogonDomainName);
  98. pResults->Global.pLogonDomainName = NULL;
  99. if (pResults->Global.pPrimaryDomainInfo)
  100. {
  101. DsRoleFreeMemory(pResults->Global.pPrimaryDomainInfo);
  102. pResults->Global.pPrimaryDomainInfo = NULL;
  103. }
  104. Free( pResults->Global.pswzLogonServer );
  105. IpConfigCleanup(pParams, pResults);
  106. for (i=0; i<pResults->cNumInterfaces; i++)
  107. {
  108. Free(pResults->pArrayInterface[i].pszName);
  109. pResults->pArrayInterface[i].pszName = NULL;
  110. Free(pResults->pArrayInterface[i].pszFriendlyName);
  111. pResults->pArrayInterface[0].pszFriendlyName = NULL;
  112. }
  113. Free(pResults->pArrayInterface);
  114. pResults->pArrayInterface = NULL;
  115. pResults->cNumInterfaces = 0;
  116. }
  117. /*!--------------------------------------------------------------------------
  118. SetMessageId
  119. -
  120. Author: KennT
  121. ---------------------------------------------------------------------------*/
  122. void SetMessageId(NdMessage *pNdMsg, NdVerbose ndv, UINT uMessageId)
  123. {
  124. assert(pNdMsg);
  125. ClearMessage(pNdMsg);
  126. pNdMsg->ndVerbose = ndv;
  127. pNdMsg->uMessageId = uMessageId;
  128. }
  129. /*!--------------------------------------------------------------------------
  130. SetMessageSz
  131. -
  132. Author: KennT
  133. ---------------------------------------------------------------------------*/
  134. void SetMessageSz(NdMessage *pNdMsg, NdVerbose ndv, LPCTSTR pszMessage)
  135. {
  136. assert(pNdMsg);
  137. ClearMessage(pNdMsg);
  138. pNdMsg->ndVerbose = ndv;
  139. pNdMsg->pszMessage = _tcsdup(pszMessage);
  140. pNdMsg->uMessageId = 0;
  141. }
  142. /*!--------------------------------------------------------------------------
  143. SetMessage
  144. -
  145. Author: KennT
  146. ---------------------------------------------------------------------------*/
  147. void SetMessage(NdMessage *pNdMsg, NdVerbose ndv, UINT uMessageId, ...)
  148. {
  149. UINT nBuf;
  150. va_list args;
  151. va_start(args, uMessageId);
  152. LoadString(NULL, uMessageId, s_szFormat, sizeof(s_szFormat));
  153. nBuf = _vstprintf(s_szBuffer, s_szFormat, args);
  154. assert(nBuf < sizeof(s_szBuffer));
  155. va_end(args);
  156. SetMessageSz(pNdMsg, ndv, s_szBuffer);
  157. }
  158. /*!--------------------------------------------------------------------------
  159. ClearMessage
  160. -
  161. Author: KennT
  162. ---------------------------------------------------------------------------*/
  163. void ClearMessage(NdMessage *pNdMsg)
  164. {
  165. if (pNdMsg == NULL)
  166. return;
  167. if (pNdMsg->pszMessage)
  168. Free(pNdMsg->pszMessage);
  169. ZeroMemory(pNdMsg, sizeof(*pNdMsg));
  170. }
  171. /*!--------------------------------------------------------------------------
  172. PrintNdMessage
  173. -
  174. Author: KennT
  175. ---------------------------------------------------------------------------*/
  176. void PrintNdMessage(NETDIAG_PARAMS *pParams, NdMessage *pNdMsg)
  177. {
  178. LPCTSTR pszMsg = NULL;
  179. assert(pParams);
  180. if (pNdMsg == NULL)
  181. return;
  182. // test verbosity level
  183. if ((pNdMsg->ndVerbose == Nd_DebugVerbose) &&
  184. !pParams->fDebugVerbose)
  185. return;
  186. if ((pNdMsg->ndVerbose == Nd_ReallyVerbose) &&
  187. !pParams->fReallyVerbose)
  188. return;
  189. if ((pNdMsg->ndVerbose == Nd_Verbose) &&
  190. !pParams->fVerbose)
  191. return;
  192. // get the message to print
  193. if (pNdMsg->uMessageId)
  194. {
  195. LoadString(NULL, pNdMsg->uMessageId, s_szBuffer,
  196. DimensionOf(s_szBuffer));
  197. assert(s_szBuffer[0]);
  198. pszMsg = s_szBuffer;
  199. }
  200. else
  201. pszMsg = pNdMsg->pszMessage;
  202. if (pszMsg)
  203. PrintMessageSz(pParams, pszMsg);
  204. fflush(stdout);
  205. }
  206. //---------------------------------------------------------------
  207. // AddMessageToListSz
  208. // Add a string based message at tail of the list.
  209. // Author NSun
  210. //---------------------------------------------------------------
  211. void AddMessageToListSz(PLIST_ENTRY plistHead, NdVerbose ndv, LPCTSTR pszMsg)
  212. {
  213. NdMessageList *plMessage = NULL;
  214. if( NULL == plistHead || NULL == pszMsg )
  215. return;
  216. plMessage = Malloc(sizeof(NdMessageList));
  217. assert(plMessage);
  218. if (plMessage)
  219. {
  220. ZeroMemory(plMessage, sizeof(NdMessageList));
  221. SetMessageSz(&plMessage->msg, ndv, pszMsg);
  222. InsertTailList(plistHead, &plMessage->listEntry);
  223. }
  224. }
  225. void AddIMessageToListSz(PLIST_ENTRY plistHead, NdVerbose ndv, int nIndent, LPCTSTR pszMsg)
  226. {
  227. TCHAR szBuffer[4096];
  228. int i;
  229. NdMessageList *plMessage = NULL;
  230. if( NULL == plistHead || NULL == pszMsg )
  231. return;
  232. assert(nIndent < 4096);
  233. assert((nIndent + StrLen(pszMsg)) < (DimensionOf(szBuffer)-1));
  234. for (i=0; i<nIndent; i++)
  235. szBuffer[i] = _T(' ');
  236. szBuffer[i] = 0;
  237. StrCat(szBuffer, pszMsg);
  238. plMessage = Malloc(sizeof(NdMessageList));
  239. assert(plMessage);
  240. if (plMessage)
  241. {
  242. ZeroMemory(plMessage, sizeof(NdMessageList));
  243. SetMessageSz(&plMessage->msg, ndv, szBuffer);
  244. InsertTailList(plistHead, &plMessage->listEntry);
  245. }
  246. }
  247. //---------------------------------------------------------------
  248. // AddMessageToListId
  249. // Add an ID based message at tail of the list.
  250. // Author NSun
  251. //---------------------------------------------------------------
  252. void AddMessageToListId(PLIST_ENTRY plistHead, NdVerbose ndv, UINT uMessageId)
  253. {
  254. NdMessageList *plMsg = NULL;
  255. if( NULL == plistHead )
  256. return;
  257. plMsg = Malloc(sizeof(NdMessageList));
  258. assert(plMsg);
  259. if (plMsg)
  260. {
  261. ZeroMemory(plMsg, sizeof(NdMessageList));
  262. SetMessageId(&plMsg->msg, ndv, uMessageId);
  263. InsertTailList(plistHead, &plMsg->listEntry);
  264. }
  265. }
  266. //---------------------------------------------------------------
  267. // AddMessageToList
  268. // Add a message based on message ID and optional parameters
  269. // at tail of the list.
  270. // Author NSun
  271. //---------------------------------------------------------------
  272. void AddMessageToList(PLIST_ENTRY plistHead, NdVerbose ndv, UINT uMessageId, ...)
  273. {
  274. NdMessageList *plMessage = NULL;
  275. UINT nBuf;
  276. va_list args;
  277. if(NULL == plistHead)
  278. return;
  279. plMessage = Malloc(sizeof(NdMessageList));
  280. assert(plMessage);
  281. if (plMessage)
  282. {
  283. ZeroMemory(plMessage, sizeof(NdMessageList));
  284. va_start(args, uMessageId);
  285. LoadString(NULL, uMessageId, s_szFormat, sizeof(s_szFormat));
  286. nBuf = _vstprintf(s_szBuffer, s_szFormat, args);
  287. assert(nBuf < sizeof(s_szBuffer));
  288. va_end(args);
  289. SetMessageSz(&plMessage->msg, ndv, s_szBuffer);
  290. InsertTailList(plistHead, &plMessage->listEntry);
  291. }
  292. }
  293. void AddIMessageToList(PLIST_ENTRY plistHead, NdVerbose ndv, int nIndent, UINT uMessageId, ...)
  294. {
  295. NdMessageList *plMessage = NULL;
  296. UINT nBuf;
  297. LPTSTR pszFormat;
  298. va_list args;
  299. int i;
  300. if(NULL == plistHead)
  301. return;
  302. plMessage = Malloc(sizeof(NdMessageList));
  303. for (i=0; i<nIndent; i++)
  304. s_szFormat[i] = _T(' ');
  305. s_szFormat[i] = 0;
  306. pszFormat = s_szFormat + nIndent;
  307. assert(plMessage);
  308. if (plMessage)
  309. {
  310. ZeroMemory(plMessage, sizeof(NdMessageList));
  311. va_start(args, uMessageId);
  312. LoadString(NULL, uMessageId, pszFormat, 4096 - nIndent);
  313. nBuf = _vstprintf(s_szBuffer, s_szFormat, args);
  314. assert(nBuf < sizeof(s_szBuffer));
  315. va_end(args);
  316. SetMessageSz(&plMessage->msg, ndv, s_szBuffer);
  317. InsertTailList(plistHead, &plMessage->listEntry);
  318. }
  319. }
  320. //---------------------------------------------------------------
  321. // PrintMessageList
  322. //
  323. // Author NSun
  324. //---------------------------------------------------------------
  325. void PrintMessageList(NETDIAG_PARAMS *pParams, PLIST_ENTRY plistHead)
  326. {
  327. NdMessageList* plMsg;
  328. PLIST_ENTRY plistEntry = plistHead->Flink;
  329. if( NULL == plistEntry ) return;
  330. for(; plistEntry != plistHead; plistEntry = plistEntry->Flink)
  331. {
  332. assert(plistEntry);
  333. plMsg = CONTAINING_RECORD( plistEntry, NdMessageList, listEntry );
  334. PrintNdMessage(pParams, &plMsg->msg);
  335. }
  336. }
  337. //---------------------------------------------------------------
  338. // MessageListCleanUp
  339. //
  340. // Author NSun
  341. //---------------------------------------------------------------
  342. void MessageListCleanUp(PLIST_ENTRY plistHead)
  343. {
  344. PLIST_ENTRY plistEntry = plistHead->Flink;
  345. NdMessageList* plMsg;
  346. if( NULL == plistEntry )
  347. return;
  348. while(plistEntry != plistHead)
  349. {
  350. assert(plistEntry);
  351. plMsg = CONTAINING_RECORD( plistEntry, NdMessageList, listEntry );
  352. plistEntry = plistEntry->Flink;
  353. ClearMessage(&plMsg->msg);
  354. Free(plMsg);
  355. }
  356. }
  357. void PrintStatusMessage(NETDIAG_PARAMS *pParams, int iIndent, UINT uMessageId, ...)
  358. {
  359. INT nBuf;
  360. va_list args;
  361. int i;
  362. //if not in really verbose mode, print wait dots
  363. PrintWaitDots(pParams);
  364. if (pParams->fReallyVerbose)
  365. {
  366. va_start(args, uMessageId);
  367. LoadString(NULL, uMessageId, s_szFormat, sizeof(s_szFormat));
  368. nBuf = _vsntprintf(s_szBuffer, DimensionOf(s_szBuffer), s_szFormat, args);
  369. assert(nBuf > 0);
  370. s_szBuffer[DimensionOf(s_szBuffer)-1] = 0;
  371. assert(nBuf < sizeof(s_szBuffer));
  372. va_end(args);
  373. if (iIndent)
  374. {
  375. for (i=0; i<iIndent; i++)
  376. s_szFormat[i] = _T(' ');
  377. s_szFormat[i] = 0;
  378. PrintMessageSz(pParams, s_szFormat);
  379. }
  380. PrintMessageSz(pParams, s_szBuffer);
  381. }
  382. }
  383. void PrintStatusMessageSz(NETDIAG_PARAMS *pParams, int iIndent, LPCTSTR pszMessage)
  384. {
  385. int i;
  386. if (pParams->fReallyVerbose)
  387. {
  388. if (iIndent)
  389. {
  390. for (i=0; i<iIndent; i++)
  391. s_szFormat[i] = _T(' ');
  392. s_szFormat[i] = 0;
  393. PrintMessageSz(pParams, s_szFormat);
  394. }
  395. PrintMessageSz(pParams, pszMessage);
  396. }
  397. }
  398. void PrintDebug(NETDIAG_PARAMS *pParams, int iIndent, UINT uMessageId, ...)
  399. {
  400. INT nBuf;
  401. va_list args;
  402. int i;
  403. if (pParams->fDebugVerbose)
  404. {
  405. va_start(args, uMessageId);
  406. LoadString(NULL, uMessageId, s_szFormat, sizeof(s_szFormat));
  407. nBuf = _vsntprintf(s_szBuffer, DimensionOf(s_szBuffer), s_szFormat, args);
  408. assert(nBuf > 0);
  409. s_szBuffer[DimensionOf(s_szBuffer)-1] = 0;
  410. assert(nBuf < sizeof(s_szBuffer));
  411. va_end(args);
  412. if (iIndent)
  413. {
  414. for (i=0; i<iIndent; i++)
  415. s_szFormat[i] = _T(' ');
  416. s_szFormat[i] = 0;
  417. PrintMessageSz(pParams, s_szFormat);
  418. }
  419. PrintMessageSz(pParams, s_szBuffer);
  420. }
  421. }
  422. void PrintDebugSz(NETDIAG_PARAMS *pParams, int iIndent, LPCTSTR pszFormat, ...)
  423. {
  424. INT nBuf;
  425. va_list args;
  426. int i;
  427. if (pParams->fDebugVerbose)
  428. {
  429. va_start(args, pszFormat);
  430. nBuf = _vsntprintf(s_szBuffer, DimensionOf(s_szBuffer), pszFormat, args);
  431. assert(nBuf > 0);
  432. s_szBuffer[DimensionOf(s_szBuffer)-1] = 0;
  433. assert(nBuf < sizeof(s_szBuffer));
  434. va_end(args);
  435. if (iIndent)
  436. {
  437. for (i=0; i<iIndent; i++)
  438. s_szFormat[i] = _T(' ');
  439. s_szFormat[i] = 0;
  440. PrintMessageSz(pParams, s_szFormat);
  441. }
  442. PrintMessageSz(pParams, s_szBuffer);
  443. }
  444. }
  445. VOID
  446. _PrintGuru(
  447. IN NETDIAG_PARAMS * pParams,
  448. IN NET_API_STATUS NetStatus,
  449. IN LPSTR DefaultGuru
  450. )
  451. /*++
  452. Routine Description:
  453. Print the Status and the name of the guru handling the status.
  454. Arguments:
  455. NetStatus - Status used to differentiate
  456. 0: Just print the guru name
  457. -1: Just print the guru name
  458. DefaultGuru - Guru to return if no other guru can be found
  459. Return Value:
  460. Name of Guru responsible for the specified status
  461. --*/
  462. {
  463. LPTSTR Guru;
  464. //
  465. // If a status was given,
  466. // print it.
  467. //
  468. if ( NetStatus != 0 && NetStatus != -1)
  469. {
  470. PrintMessageSz( pParams, NetStatusToString(NetStatus) );
  471. }
  472. //
  473. // Some status codes can be attributed base on the value of the status code.
  474. //
  475. if ( NetStatus >= WSABASEERR && NetStatus <= WSABASEERR + 2000 )
  476. {
  477. Guru = WINSOCK_GURU;
  478. } else if ( NetStatus >= DNS_ERROR_RESPONSE_CODES_BASE && NetStatus <= DNS_ERROR_RESPONSE_CODES_BASE + 1000 ) {
  479. Guru = DNS_GURU;
  480. } else {
  481. Guru = DefaultGuru;
  482. }
  483. PrintMessageSz( pParams, Guru );
  484. PrintNewLine( pParams, 1 );
  485. }
  486. void PrintWaitDots(NETDIAG_PARAMS *pParams)
  487. {
  488. if (!pParams->fReallyVerbose && !pParams->fDebugVerbose)
  489. {
  490. _tprintf(c_szWaitDots);
  491. }
  492. }