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.

1711 lines
47 KiB

  1. #include "diagnostics.h"
  2. //#include <netsh.h>
  3. #include <netshp.h>
  4. #include "Dglogs.h"
  5. #include "DglogsCom.h"
  6. #include "Commdlg.h"
  7. #include "oe.h"
  8. extern PrintMessage22 PrintMessage2;
  9. #undef PrintMessage
  10. #define PrintMessage PrintMessage2
  11. // Wbem Repositories
  12. //
  13. #define TXT_WBEM_REP_CIMV2 L"root\\cimv2"
  14. // Wbem Namespaces
  15. //
  16. #define TXT_WBEM_NS_COMPUTER L"win32_computersystem"
  17. #define TXT_WBEM_NS_OS L"win32_operatingsystem"
  18. #define TXT_WBEM_NS_NETWORK L"win32_networkadapterconfiguration"
  19. #define TXT_WBEM_NS_NETWORK2 L"win32_networkadapter"
  20. #define TXT_WBEM_NS_CLIENT L"win32_networkclient"
  21. #define TXT_WBEM_NS_WMI L"win32_wmisetting"
  22. #define TXT_WBEM_NS_NETDIAG L"netdiagnostics"
  23. #define TXT_WBEM_NS_MODEM L"win32_potsmodem"
  24. // Captions for the different catagories
  25. //
  26. #define TXT_ADAPTER_CAPTION L"Caption"
  27. #define TXT_CLIENT_CAPTION L"Name"
  28. #define TXT_MAIL_CAPTION L"InBoundMailServer"
  29. #define TXT_NEWS_CAPTION L"NewsServer"
  30. #define TXT_PROXY_CAPTION L"IEProxy"
  31. #define TXT_COMPUTER_CAPTION L"Caption"
  32. #define TXT_OS_CAPTION L"Caption"
  33. #define TXT_VERSION_CAPTION L"Version"
  34. #define TXT_MODEM_CAPTION L"Caption"
  35. #define TXT_LOOPBACK_CAPTION L"Loopback"
  36. enum MAIL_TYPE
  37. {
  38. MAIL_NONE,
  39. MAIL_SMTP,
  40. MAIL_SMTP2,
  41. MAIL_IMAP,
  42. MAIL_POP3,
  43. MAIL_HTTP,
  44. };
  45. /*++
  46. Routine Description
  47. The worker thread uses this function to check if the main thread has canceled the worker thread.
  48. i.e. the work thread should abort what ever it is doing, clean up and terminate.
  49. Arguments
  50. none
  51. Return Value
  52. TRUE the worker thread has been terminated
  53. FALSE the worker thread has not been terminated
  54. --*/
  55. inline BOOL CDiagnostics::ShouldTerminate()
  56. {
  57. if( m_bTerminate )
  58. {
  59. // The worker thread already has been canceled.
  60. //
  61. return TRUE;
  62. }
  63. if (WaitForSingleObject(m_hTerminateThread, 0) == WAIT_OBJECT_0)
  64. {
  65. // Worker thread has been canceled
  66. //
  67. m_bTerminate = FALSE;
  68. return TRUE;
  69. }
  70. else
  71. {
  72. // Worker thread has not yet been canceled.
  73. //
  74. return FALSE;
  75. }
  76. }
  77. /*++
  78. Routine Description
  79. Initialize the Diagnostics Object
  80. Arguments
  81. none
  82. Return Value
  83. --*/
  84. CDiagnostics::CDiagnostics()
  85. {
  86. m_bFlags = 0;
  87. m_bInterface = NO_INTERFACE;
  88. lstrcpy(m_szwStatusReport,L"");
  89. m_bReportStatus = FALSE;
  90. m_lWorkDone = 0;
  91. m_lTotalWork = 0;
  92. ClearQuery();
  93. // Max sure that these strings are always NULL terminated
  94. m_szwCategory[MAX_PATH] = L'\0';
  95. m_szwHeader[MAX_PATH] = L'\0';
  96. m_pszwCatagory = NULL;
  97. m_bWinsockInit = FALSE;
  98. m_bDiagInit = FALSE;
  99. }
  100. /*++
  101. Routine Description
  102. Uniniailize the Diagnostics object
  103. Arguments
  104. none
  105. Return Value
  106. --*/
  107. CDiagnostics::~CDiagnostics()
  108. {
  109. // Close the winsock
  110. //
  111. if( m_bWinsockInit )
  112. {
  113. WSACleanup();
  114. m_bWinsockInit = FALSE;
  115. }
  116. if( m_pszwCatagory )
  117. {
  118. HeapFree(GetProcessHeap(),0,m_pszwCatagory);
  119. m_pszwCatagory = NULL;
  120. }
  121. m_bDiagInit = FALSE;
  122. }
  123. /*++
  124. Routine Description
  125. Set the interface i.e. Netsh or COM
  126. Arguments
  127. bInterface -- Interface used to access the data
  128. Return Value
  129. --*/
  130. void CDiagnostics::SetInterface(INTERFACE_TYPE bInterface)
  131. {
  132. m_bInterface = bInterface;
  133. }
  134. /*++
  135. Routine Description
  136. Iniatilze the Diagnostics object
  137. Arguments
  138. Return Value
  139. TRUE -- Successfully
  140. else FALSE
  141. --*/
  142. BOOLEAN CDiagnostics::Initialize(INTERFACE_TYPE bInterface)
  143. {
  144. int iRetVal;
  145. WSADATA wsa;
  146. m_bInterface = bInterface;
  147. // Initialize the WmiGateway object
  148. //
  149. if( FALSE == m_WmiGateway.WbemInitialize(bInterface) )
  150. {
  151. m_bDiagInit = FALSE;
  152. return FALSE;
  153. }
  154. if( !m_bWinsockInit )
  155. {
  156. // Initialize Winsock
  157. //
  158. iRetVal = WSAStartup(MAKEWORD(2,1), &wsa);
  159. if( iRetVal )
  160. {
  161. m_bDiagInit = FALSE;
  162. return FALSE;
  163. }
  164. m_bWinsockInit = TRUE;
  165. }
  166. m_bDiagInit = TRUE;
  167. return TRUE;
  168. }
  169. /*++
  170. Routine Description
  171. Sends an event to client informing the client of its progress.
  172. Arguments
  173. pszwStatusReport -- Message telling the client what it CDiagnostics is currently doing
  174. lPercent -- A percentage indicating its progress.
  175. Return Value
  176. error code
  177. --*/
  178. void CDiagnostics::EventCall(LPCTSTR pszwStatusReport, LONG lPercent)
  179. {
  180. if( m_pDglogsCom )
  181. {
  182. // Alocate memory for the message and send it to the client
  183. //
  184. BSTR bstrResult = SysAllocString(pszwStatusReport);
  185. m_pDglogsCom->Fire_ProgressReport(&bstrResult,lPercent);
  186. }
  187. }
  188. /*++
  189. Routine Description
  190. Sends an event to client informing the client of its progress.
  191. Arguments
  192. pszwMsg -- Message telling the client what it CDiagnostics is currently doing
  193. lValue -- A percentage indicating its progress.
  194. Return Value
  195. void
  196. Note:
  197. If lValue is -1 then send the finished message
  198. --*/
  199. void CDiagnostics::ReportStatus(LPCTSTR pszwMsg, LONG lValue)
  200. {
  201. // Check if the client requested the Status report option
  202. //
  203. if( m_bReportStatus )
  204. {
  205. if( lValue == -1 )
  206. {
  207. // Send the finished message. 100% complete and the final XML result
  208. //
  209. EventCall(ids(IDS_FINISHED_STATUS), 100);
  210. EventCall(pszwMsg, lValue);
  211. m_lWorkDone = 0;
  212. m_lTotalWork = 0;
  213. }
  214. else
  215. {
  216. // Compute the total percentage completed. Make sure we never go over 100%
  217. //
  218. m_lWorkDone += m_lWorkDone+lValue < 100?lValue:0;
  219. EventCall(pszwMsg, m_lWorkDone);
  220. }
  221. }
  222. }
  223. /*++
  224. Routine Description
  225. Counts the occurance of chars in a string
  226. Arguments
  227. pszw -- String to search
  228. c -- Char to count the occurnce of
  229. Return Value
  230. number of time c occured in pszw
  231. Note:
  232. If lValue is -1 then send the finished message
  233. --*/
  234. int wcscount(LPCWSTR pszw, WCHAR c)
  235. {
  236. int n =0;
  237. for(int i=0; pszw[i]!=L'\0'; i++)
  238. {
  239. if( pszw[i] == c )
  240. {
  241. if( i > 0 && pszw[i-1]!=c) n++;
  242. }
  243. }
  244. return n;
  245. }
  246. /*++
  247. Routine Description
  248. Set the query information
  249. Arguments
  250. pszwCatagory -- Catagory
  251. bFlag -- Flags (Show, PING, Connect)
  252. pszwParam1 -- Instance | iphost
  253. pszwParam2 -- Port number
  254. Return Value
  255. void
  256. --*/
  257. void CDiagnostics::SetQuery(WCHAR *pszwCatagory, BOOL bFlag, WCHAR *pszwParam1, WCHAR *pszwParam2)
  258. {
  259. if( pszwCatagory )
  260. {
  261. // Set the catagory. Need to make a copy of the Catagory since the string might disapper i.e. threads
  262. //
  263. LONG Length = wcslen(pszwCatagory);
  264. if( m_pszwCatagory )
  265. {
  266. HeapFree(GetProcessHeap(),0,m_pszwCatagory);
  267. m_pszwCatagory = NULL;
  268. }
  269. // If this memory allocation fails m_pszwCatagory will be Null and the catagory will not be displayed
  270. m_pszwCatagory = (LPWSTR)HeapAlloc(GetProcessHeap(),0,(Length+1)*sizeof(WCHAR));
  271. if( m_pszwCatagory )
  272. {
  273. wcscpy(m_pszwCatagory,pszwCatagory);
  274. }
  275. }
  276. if( bFlag )
  277. {
  278. m_bFlags = bFlag;
  279. }
  280. if( pszwParam1 )
  281. {
  282. m_pszwParam1 = pszwParam1;
  283. }
  284. if( pszwParam2 )
  285. {
  286. m_pszwParam2 = pszwParam2;
  287. }
  288. }
  289. /*++
  290. Routine Description
  291. Clears the Set query information
  292. Arguments
  293. void
  294. Return Value
  295. void
  296. --*/
  297. void CDiagnostics::ClearQuery()
  298. {
  299. m_pszwCatagory = NULL;
  300. m_bFlags = NULL;
  301. m_pszwParam1 = NULL;
  302. m_pszwParam2 = NULL;
  303. }
  304. /*++
  305. Routine Description
  306. Execute the query
  307. Arguments
  308. Return Value
  309. void
  310. --*/
  311. BOOL GetIEProxy(LPWSTR pwszProxy, LONG ProxyLen, LPDWORD pdwPort, LPDWORD pdwEnabled);
  312. BOOLEAN CDiagnostics::ExecQuery(WCHAR *pszwCatagory, BOOL bFlags, WCHAR *pszwParam1, WCHAR *pszwParam2)
  313. {
  314. WCHAR *pszw;
  315. BOOL bAll = FALSE;
  316. SetQuery(pszwCatagory,bFlags,pszwParam1,pszwParam2);
  317. m_WmiGateway.SetCancelOption(m_hTerminateThread);
  318. m_WmiGateway.m_wstrWbemError = L"";
  319. m_bTerminate = FALSE;
  320. m_lWorkDone = 0;
  321. m_lTotalWork = 0;
  322. m_bstrCaption = L"";
  323. if( m_pszwParam1 && !wcsstr(m_pszwParam1,L"*") )
  324. {
  325. if( m_bFlags & FLAG_VERBOSE_LOW )
  326. {
  327. m_bFlags &= ~FLAG_VERBOSE_LOW;
  328. m_bFlags |= FLAG_VERBOSE_MEDIUM;
  329. }
  330. }
  331. if( !m_pszwCatagory )
  332. {
  333. ClearQuery();
  334. return FALSE;
  335. }
  336. // the 3 is the start percentage indicating that something is happening!
  337. ReportStatus(ids(IDS_COLLECTINGINFO_STATUS),3);
  338. if( wcsstr(m_pszwCatagory,L"test") )
  339. {
  340. if( (m_bFlags & FLAG_VERBOSE_LOW) )
  341. {
  342. m_bFlags &= ~FLAG_CMD_SHOW;
  343. }
  344. else
  345. {
  346. m_bFlags |= FLAG_CMD_SHOW;
  347. }
  348. if( m_bFlags & FLAG_VERBOSE_LOW )
  349. {
  350. m_bFlags &= ~FLAG_VERBOSE_LOW;
  351. m_bFlags |= FLAG_VERBOSE_MEDIUM;
  352. }
  353. m_bFlags |= FLAG_CMD_PING | FLAG_CMD_CONNECT;
  354. bAll = TRUE;
  355. }
  356. if( wcsstr(m_pszwCatagory,L"all") )
  357. {
  358. bAll = TRUE;
  359. }
  360. pszw = new WCHAR[lstrlen(m_pszwCatagory) + 3];
  361. if( !pszw )
  362. {
  363. ClearQuery();
  364. return FALSE;
  365. }
  366. wsprintf(pszw,L";%s;",m_pszwCatagory);
  367. ToLowerStr(pszw);
  368. m_nCatagoriesRequested = wcscount(pszw,L';') - 1;
  369. XMLNetdiag(TRUE);
  370. NetShNetdiag(TRUE);
  371. if( ShouldTerminate() ) goto End;
  372. if( wcsstr(pszw,L";iphost;") )
  373. {
  374. ExecIPHost(m_pszwParam1,m_pszwParam2);
  375. }
  376. if( ShouldTerminate() ) goto End;
  377. if( bAll || wcsstr(pszw,L";mail;") )
  378. {
  379. ExecMailQuery();
  380. }
  381. if( ShouldTerminate() ) goto End;
  382. if( bAll || wcsstr(pszw,L";news;") )
  383. {
  384. ExecNewsQuery();
  385. }
  386. if( ShouldTerminate() ) goto End;
  387. if( bAll || wcsstr(pszw,L";ieproxy;") )
  388. {
  389. ExecProxyQuery();
  390. }
  391. if( ShouldTerminate() ) goto End;
  392. if( bAll || wcsstr(pszw,L";loopback;") )
  393. {
  394. ExecLoopbackQuery();
  395. }
  396. if( ShouldTerminate() ) goto End;
  397. if( bAll || wcsstr(pszw,L";computer;") )
  398. {
  399. ExecComputerQuery();
  400. }
  401. if( ShouldTerminate() ) goto End;
  402. if( bAll || wcsstr(pszw,L";os;") )
  403. {
  404. ExecOSQuery();
  405. }
  406. if( ShouldTerminate() ) goto End;
  407. if( bAll || wcsstr(pszw,L";version;") )
  408. {
  409. ExecVersionQuery();
  410. }
  411. if( ShouldTerminate() ) goto End;
  412. if( bAll || wcsstr(pszw,L";modem;") )
  413. {
  414. ExecModemQuery(m_pszwParam1);
  415. }
  416. if( ShouldTerminate() ) goto End;
  417. if( bAll || wcsstr(pszw,L";adapter;") )
  418. {
  419. ExecAdapterQuery(m_pszwParam1);
  420. }
  421. {
  422. BOOL bFlagSave = m_bFlags;
  423. m_bFlags &= ~FLAG_VERBOSE_LOW;
  424. m_bFlags &= ~FLAG_VERBOSE_HIGH;
  425. m_bFlags |= FLAG_VERBOSE_MEDIUM;
  426. if( ShouldTerminate() ) goto End;
  427. if( wcsstr(pszw,L";dns;") )
  428. {
  429. ExecDNSQuery(m_pszwParam1);
  430. }
  431. if( ShouldTerminate() ) goto End;
  432. if( wcsstr(pszw,L";gateway;") )
  433. {
  434. ExecGatewayQuery(m_pszwParam1);
  435. }
  436. if( ShouldTerminate() ) goto End;
  437. if( wcsstr(pszw,L";dhcp;") )
  438. {
  439. ExecDhcpQuery(m_pszwParam1);
  440. }
  441. if( ShouldTerminate() ) goto End;
  442. if( wcsstr(pszw,L";ip;") )
  443. {
  444. ExecIPQuery(m_pszwParam1);
  445. }
  446. if( ShouldTerminate() ) goto End;
  447. if( wcsstr(pszw,L";wins;") )
  448. {
  449. ExecWinsQuery(m_pszwParam1);
  450. }
  451. m_bFlags = bFlagSave;
  452. }
  453. if( ShouldTerminate() ) goto End;
  454. if( bAll || wcsstr(pszw,L";client;") )
  455. {
  456. ExecClientQuery(m_pszwParam1);
  457. }
  458. End:
  459. delete [] pszw;
  460. if( ShouldTerminate() ) return FALSE;
  461. XMLNetdiag(FALSE);
  462. NetShNetdiag(FALSE);
  463. Sleep(50);
  464. ReportStatus(m_wstrXML.c_str(),-1);
  465. ClearQuery();
  466. return TRUE;
  467. }
  468. // Escaoes special XML chars
  469. wstring &CDiagnostics::Escape(LPCTSTR pszw)
  470. {
  471. m_wstrEscapeXml = L"";
  472. if( !pszw )
  473. {
  474. return m_wstrEscapeXml;
  475. }
  476. for(int i=0; pszw[i]!=L'\0'; i++)
  477. {
  478. switch(pszw[i])
  479. {
  480. case L'&':
  481. m_wstrEscapeXml += L"&amp;";
  482. break;
  483. case L'\'':
  484. m_wstrEscapeXml += L"&apos;";
  485. break;
  486. case L'\"':
  487. m_wstrEscapeXml += L"&quot;";
  488. break;
  489. case L'<':
  490. m_wstrEscapeXml += L"&lt;";
  491. break;
  492. case L'>':
  493. m_wstrEscapeXml += L"&gt;";
  494. break;
  495. default:
  496. m_wstrEscapeXml += pszw[i];
  497. }
  498. }
  499. return m_wstrEscapeXml;
  500. }
  501. // Creates the XML start tag
  502. // <Netdiag>
  503. // <Status Value = _____ ></Status>
  504. // ______
  505. // </Netdiag>
  506. void CDiagnostics::XMLNetdiag(BOOLEAN bStartTag, LPCTSTR pszwValue)
  507. {
  508. if( m_bInterface == COM_INTERFACE )
  509. {
  510. if( bStartTag )
  511. {
  512. m_wstrXML = wstring(L"<Netdiag Name = \"Network Diagnostics\">\n");
  513. }
  514. else
  515. {
  516. m_wstrXML += wstring(L"<Status Value = \"") + Escape(pszwValue) + wstring(L"\"> </Status>\n");
  517. m_wstrXML += wstring(L"</Netdiag>\n");
  518. }
  519. }
  520. }
  521. // Creates a the diagnostics header
  522. // <Container Name = "_____" Category = "_____" Caption = "_____">
  523. // <Status Value = _____ ></Status>
  524. // </Container>
  525. void CDiagnostics::XMLHeader(BOOLEAN bStartTag, WCHAR *pszwHeader, WCHAR *pszwCaption, WCHAR *pszwCategory)
  526. {
  527. if( m_bInterface == COM_INTERFACE )
  528. {
  529. if( bStartTag )
  530. {
  531. m_wstrXML += wstring(L"<Container Name = \"") + Escape(pszwHeader) + wstring(L"\" ");
  532. m_wstrXML += wstring(L"Category = \"") + Escape(pszwCategory) + wstring(L"\" ");
  533. m_wstrXML += wstring(L"Caption = \"") + Escape(pszwCaption) + wstring(L"\">\n");
  534. }
  535. else
  536. {
  537. m_wstrXML += wstring(L"<Status Value = \"") + Escape(pszwHeader) + wstring(L"\"> </Status>\n");
  538. m_wstrXML += wstring(L"</Container>");
  539. }
  540. }
  541. }
  542. // Creates the Caption string
  543. // <ClassObjectEnum Name = "_____">
  544. // <Status Value = _____ > </Status>
  545. // </ClassObjectEnum>
  546. //
  547. void CDiagnostics::XMLCaption(BOOLEAN bStartTag, WCHAR *pszwCaption)
  548. {
  549. if( m_bInterface == COM_INTERFACE )
  550. {
  551. if( bStartTag )
  552. {
  553. pszwCaption = (m_nInstance == 1)?NULL:pszwCaption;
  554. if( m_bCaptionDisplayed == FALSE )
  555. {
  556. m_wstrXML += wstring(L"<ClassObjectEnum Name = \"") + Escape(pszwCaption) + wstring(L"\">\n");
  557. m_bCaptionDisplayed = TRUE;
  558. m_IsPropertyListDisplayed = TRUE;
  559. }
  560. }
  561. else
  562. {
  563. if( m_IsPropertyListDisplayed )
  564. {
  565. m_wstrXML += wstring(L"<Status Value = \"") + Escape(pszwCaption) + wstring(L"\"> </Status>\n");
  566. m_wstrXML += wstring(L"</ClassObjectEnum>\n");
  567. }
  568. m_IsPropertyListDisplayed = FALSE;
  569. }
  570. }
  571. }
  572. // Creates a field tag
  573. // <Property Name = "_____" >
  574. // <Status Value = _____ > </Status>
  575. // </Property>
  576. void CDiagnostics::XMLField(BOOLEAN bStartTag, WCHAR *pszwField)
  577. {
  578. if( m_bInterface == COM_INTERFACE )
  579. {
  580. if( bStartTag )
  581. {
  582. m_wstrXML += wstring(L"<Property Name = \"") + Escape(pszwField) + wstring(L"\">\n");
  583. }
  584. else
  585. {
  586. m_wstrXML += wstring(L"<Status Value = \"") + Escape(pszwField) + wstring(L"\"> </Status>\n");
  587. m_wstrXML += wstring(L"</Property>\n");
  588. }
  589. }
  590. }
  591. // Creates a property
  592. // <PropertyValue Value = "_____" Data = "_____" Comment = "_____" >
  593. void CDiagnostics::XMLProperty(BOOLEAN bStartTag, WCHAR *pszwProperty, LPCTSTR pszwData, LPCTSTR pszwComment)
  594. {
  595. if( m_bInterface == COM_INTERFACE )
  596. {
  597. if( bStartTag )
  598. {
  599. m_wstrXML += wstring(L"<PropertyValue ");
  600. m_wstrXML += wstring(L"Value = \"") + Escape(pszwProperty) + wstring(L"\" ");
  601. m_wstrXML += wstring(L"Data = \"") + Escape(pszwData) + wstring(L"\" ");
  602. m_wstrXML += wstring(L"Comment = \"") + Escape(pszwComment) + wstring(L"\" ");
  603. m_wstrXML += wstring(L">\n");
  604. }
  605. else
  606. {
  607. m_wstrXML += Escape(pszwProperty);
  608. m_wstrXML += wstring(L"</PropertyValue>\n");
  609. }
  610. }
  611. }
  612. // Ensurse that the property is valid and should be displayed
  613. BOOLEAN CDiagnostics::Filter(_variant_t &vValue, BOOLEAN bFlags)
  614. {
  615. BOOLEAN retVal;
  616. BOOLEAN bShow = (m_bFlags & FLAG_CMD_SHOW);
  617. BOOLEAN bPing = (m_bFlags & FLAG_CMD_PING) && (bFlags & TYPE_PING);
  618. BOOLEAN bConnect = (m_bFlags & FLAG_CMD_CONNECT) && (bFlags & TYPE_CONNECT);
  619. if( m_bFlags & FLAG_VERBOSE_LOW )
  620. {
  621. return FALSE;
  622. }
  623. if( bFlags & TYPE_HIDE )
  624. {
  625. return FALSE;
  626. }
  627. if( (m_bFlags & FLAG_VERBOSE_HIGH)==0 && (retVal = IsVariantEmpty(vValue)) )
  628. {
  629. return FALSE;
  630. }
  631. if( (bFlags & TYPE_IP) && !m_bAdaterHasIPAddress )
  632. {
  633. return FALSE;
  634. }
  635. if( !bShow )
  636. {
  637. if( bPing || bConnect)
  638. {
  639. return TRUE;
  640. }
  641. return FALSE;
  642. }
  643. return TRUE;
  644. }
  645. // Get a entry from the link list stack
  646. template<class t>
  647. _variant_t *Get(list<t> &l, WCHAR *pszwName, DWORD nInstance)
  648. {
  649. list<t>::iterator iter;
  650. if( l.empty() )
  651. {
  652. return NULL;
  653. }
  654. for( iter = l.begin(); iter != l.end(); iter++)
  655. {
  656. if( lstrcmp(iter->pszwName,pszwName) == 0 )
  657. {
  658. if( nInstance < iter->Value.size() )
  659. {
  660. return &iter->Value[nInstance];
  661. }
  662. else
  663. {
  664. return NULL;
  665. }
  666. }
  667. }
  668. return NULL;
  669. }
  670. // Remove a entry from the list link stack
  671. template<class t>
  672. BOOLEAN RemoveInstance(list<t> &l, DWORD nInstance)
  673. {
  674. list<t>::iterator iter;
  675. for( iter = l.begin(); iter != l.end(); iter++)
  676. {
  677. iter->Value.erase(&iter->Value[nInstance]);
  678. }
  679. return FALSE;
  680. }
  681. // Add/modify an entry in the link list stack
  682. template<class t>
  683. void Set(list<t> &l, WCHAR *pszwName, BOOLEAN bFlags, _variant_t &vValue)
  684. {
  685. list<t>::iterator iter;
  686. for( iter = l.begin(); iter != l.end(); iter++)
  687. {
  688. if( lstrcmp(iter->pszwName,pszwName) == 0 )
  689. {
  690. iter->Value.push_back(vValue);
  691. return;
  692. }
  693. }
  694. l.push_back(Property(pszwName,bFlags));
  695. iter = l.end();
  696. iter--;
  697. iter->Value.push_back(vValue);
  698. return;
  699. }
  700. // Formats the ping data
  701. //
  702. BOOLEAN CDiagnostics::FormatPing(WCHAR * pszwText)
  703. {
  704. if( m_bInterface == NETSH_INTERFACE )
  705. {
  706. if( pszwText )
  707. {
  708. LONG nIndent = m_IsNetdiagDisplayed + m_IsContainerDisplayed + m_IsPropertyListDisplayed + m_IsPropertyDisplayed + m_IsValueDisplayed;
  709. DisplayMessageT(L"%1!s!%2!s!\n",Indent(nIndent),pszwText);
  710. return TRUE;
  711. }
  712. }
  713. if( m_bInterface == COM_INTERFACE )
  714. {
  715. if( !pszwText )
  716. {
  717. m_wstrPing.erase(m_wstrPing.begin(),m_wstrPing.end());
  718. }
  719. else if( m_wstrPing.empty() )
  720. {
  721. m_wstrPing = pszwText;
  722. }
  723. else
  724. {
  725. m_wstrPing += wstring(L"|") + pszwText;
  726. }
  727. return TRUE;
  728. }
  729. return FALSE;
  730. }
  731. BOOLEAN CDiagnostics::ExecClientQuery(WCHAR *pszwInstance)
  732. {
  733. if( !(m_bFlags & FLAG_CMD_SHOW) )
  734. {
  735. return FALSE;
  736. }
  737. EnumWbemProperty PropList;
  738. m_pszwCaption = TXT_CLIENT_CAPTION;
  739. wcsncpy(m_szwCategory,ids(IDS_CATEGORY_NETWORKADAPTERS),MAX_PATH);
  740. wcsncpy(m_szwHeader,ids(IDS_CLIENT_HEADER),MAX_PATH);
  741. PropList.push_back(WbemProperty(NULL,0,TXT_WBEM_REP_CIMV2,TXT_WBEM_NS_CLIENT));
  742. m_WmiGateway.GetWbemProperties(PropList);
  743. FormatEnum(PropList,pszwInstance);
  744. return TRUE;
  745. }
  746. BOOLEAN CDiagnostics::ExecModemQuery(WCHAR *pszwInstance)
  747. {
  748. EnumWbemProperty PropList;
  749. m_pszwCaption = TXT_MODEM_CAPTION;
  750. wcsncpy(m_szwHeader,ids(IDS_MODEM_HEADER),MAX_PATH);
  751. wcsncpy(m_szwCategory,ids(IDS_CATEGORY_MODEM),MAX_PATH);
  752. PropList.push_back(WbemProperty(NULL,0,TXT_WBEM_REP_CIMV2,TXT_WBEM_NS_MODEM));
  753. m_WmiGateway.GetWbemProperties(PropList);
  754. FormatEnum(PropList,pszwInstance);
  755. return TRUE;
  756. }
  757. // Removes adapters that are not present
  758. // It checks the Win32_Netwokadapter NetConnectionStatus field to see if the adapter is valid or not
  759. BOOLEAN CDiagnostics::RemoveInvalidAdapters(EnumWbemProperty & PropList)
  760. {
  761. INT i = 0;
  762. _variant_t *pvIPEnabled;
  763. _variant_t *pvIndex1;
  764. _variant_t *pvIndex2;
  765. _variant_t *pvAdapterStatus;
  766. // Get the Win32_Networkadapter class so we can determine if the adapters in the Win32_Networkadapterconfiguration are valid(Present)
  767. EnumWbemProperty Win32NetworkAdpterList;
  768. Win32NetworkAdpterList.push_back(WbemProperty(NULL,0,TXT_WBEM_REP_CIMV2,TXT_WBEM_NS_NETWORK2));
  769. m_WmiGateway.GetWbemProperties(Win32NetworkAdpterList);
  770. // With WMI you can not Union tables so we need to get both tables (Win32_NetwokAdapterConfiguration and Win32_NetwokAdapter) and walk
  771. // through each entry. Entries with the same index are the same adapter. The NetConnectionStatus says if the adapter is valid.
  772. do
  773. {
  774. pvIPEnabled = Get(PropList,L"IPEnabled",i);
  775. if( pvIPEnabled )
  776. {
  777. DWORD j;
  778. pvIndex1 = Get(PropList,L"Index",i);
  779. if( pvIndex1 )
  780. {
  781. j = 0;
  782. do
  783. {
  784. pvIndex2 = Get(Win32NetworkAdpterList,L"Index",j);
  785. if( pvIndex2 && pvIndex2->ulVal == pvIndex1->ulVal )
  786. {
  787. pvAdapterStatus = Get(Win32NetworkAdpterList,L"NetConnectionStatus",j);
  788. if( pvAdapterStatus != NULL && (pvAdapterStatus->ulVal != 2 && pvAdapterStatus->ulVal != 9) )
  789. {
  790. RemoveInstance(PropList,(DWORD)i);
  791. pvIndex2 = NULL;
  792. i--;
  793. }
  794. }
  795. j++;
  796. }
  797. while(pvIndex2);
  798. }
  799. i++;
  800. }
  801. }
  802. while(pvIPEnabled);
  803. return TRUE;
  804. }
  805. // Gets all of the adapter info from Win32_NetworkAdapterConfiguration
  806. // Sets flags for some of the properties and values it recives (i.e. Ping and IP)
  807. // These flags indicate how to display he data process the data.
  808. BOOLEAN CDiagnostics::ExecAdapterQuery(WCHAR *pszwInstance)
  809. {
  810. EnumWbemProperty PropList;
  811. EnumWbemProperty::iterator iter;
  812. m_pszwCaption = TXT_ADAPTER_CAPTION;
  813. wcsncpy(m_szwHeader,ids(IDS_ADAPTER_HEADER),MAX_PATH);
  814. wcsncpy(m_szwCategory,ids(IDS_CATEGORY_NETWORKADAPTERS),MAX_PATH);
  815. PropList.push_back(WbemProperty(NULL,0,TXT_WBEM_REP_CIMV2,TXT_WBEM_NS_NETWORK));
  816. m_WmiGateway.GetWbemProperties(PropList);
  817. for(iter = PropList.begin(); iter != PropList.end(); iter++)
  818. {
  819. if( 0 == lstrcmp(iter->pszwName, L"DNSServerSearchOrder") ||
  820. 0 == lstrcmp(iter->pszwName, L"IPAddress") ||
  821. 0 == lstrcmp(iter->pszwName, L"WINSPrimaryServer") ||
  822. 0 == lstrcmp(iter->pszwName, L"WINSSecondaryServer") ||
  823. 0 == lstrcmp(iter->pszwName, L"DHCPServer") )
  824. {
  825. iter->bFlags = TYPE_PING | TYPE_IP;
  826. }
  827. if( 0 == lstrcmp(iter->pszwName, L"DefaultIPGateway") )
  828. {
  829. iter->bFlags = TYPE_PING | TYPE_SUBNET | TYPE_IP;
  830. }
  831. }
  832. if( !(m_bFlags & FLAG_VERBOSE_HIGH) )
  833. {
  834. RemoveInvalidAdapters(PropList);
  835. }
  836. FormatEnum(PropList,pszwInstance);
  837. return TRUE;
  838. }
  839. // Get the DNS data from Win32_NetworkAdapter
  840. BOOLEAN CDiagnostics::ExecDNSQuery(WCHAR *pszwInstance)
  841. {
  842. EnumWbemProperty PropList;
  843. m_pszwCaption = TXT_ADAPTER_CAPTION;
  844. wcsncpy(m_szwHeader,ids(IDS_DNS_HEADER),MAX_PATH);
  845. wcsncpy(m_szwCategory,ids(IDS_CATEGORY_NETWORKADAPTERS),MAX_PATH);
  846. PropList.push_back(WbemProperty(L"DNSServerSearchOrder",TYPE_PING | TYPE_IP ,TXT_WBEM_REP_CIMV2,TXT_WBEM_NS_NETWORK));
  847. PropList.push_back(WbemProperty(m_pszwCaption,TYPE_HIDE,TXT_WBEM_REP_CIMV2,TXT_WBEM_NS_NETWORK));
  848. PropList.push_back(WbemProperty(L"IPAddress",TYPE_HIDE,TXT_WBEM_REP_CIMV2,TXT_WBEM_NS_NETWORK));
  849. PropList.push_back(WbemProperty(L"IPEnabled",TYPE_HIDE,TXT_WBEM_REP_CIMV2,TXT_WBEM_NS_NETWORK));
  850. m_WmiGateway.GetWbemProperties(PropList);
  851. if( !(m_bFlags & FLAG_VERBOSE_HIGH) )
  852. {
  853. RemoveInvalidAdapters(PropList);
  854. }
  855. FormatEnum(PropList,pszwInstance);
  856. return TRUE;
  857. }
  858. // Get the IP data from Win32_NetworkAdapter
  859. BOOLEAN CDiagnostics::ExecIPQuery(WCHAR *pszwInstance)
  860. {
  861. EnumWbemProperty PropList;
  862. m_pszwCaption = TXT_ADAPTER_CAPTION;
  863. wcsncpy(m_szwHeader,ids(IDS_IP_HEADER),MAX_PATH);
  864. wcsncpy(m_szwCategory,ids(IDS_CATEGORY_NETWORKADAPTERS),MAX_PATH);
  865. PropList.push_back(WbemProperty(L"IPAddress",TYPE_PING | TYPE_IP,TXT_WBEM_REP_CIMV2,TXT_WBEM_NS_NETWORK));
  866. PropList.push_back(WbemProperty(m_pszwCaption,TYPE_HIDE,TXT_WBEM_REP_CIMV2,TXT_WBEM_NS_NETWORK));
  867. PropList.push_back(WbemProperty(L"IPAddress",TYPE_HIDE,TXT_WBEM_REP_CIMV2,TXT_WBEM_NS_NETWORK));
  868. PropList.push_back(WbemProperty(L"IPEnabled",TYPE_HIDE,TXT_WBEM_REP_CIMV2,TXT_WBEM_NS_NETWORK));
  869. m_WmiGateway.GetWbemProperties(PropList);
  870. if( !(m_bFlags & FLAG_VERBOSE_HIGH) )
  871. {
  872. RemoveInvalidAdapters(PropList);
  873. }
  874. FormatEnum(PropList,pszwInstance);
  875. return TRUE;
  876. }
  877. // Get the WINS data from Win32_NetworkAdapter
  878. BOOLEAN CDiagnostics::ExecWinsQuery(WCHAR *pszwInstance)
  879. {
  880. EnumWbemProperty PropList;
  881. m_pszwCaption = TXT_ADAPTER_CAPTION;
  882. wcsncpy(m_szwHeader,ids(IDS_WINS_HEADER),MAX_PATH);
  883. wcsncpy(m_szwCategory,ids(IDS_CATEGORY_NETWORKADAPTERS),MAX_PATH);
  884. PropList.push_back(WbemProperty(L"WINSPrimaryServer",TYPE_PING | TYPE_IP,TXT_WBEM_REP_CIMV2,TXT_WBEM_NS_NETWORK));
  885. PropList.push_back(WbemProperty(L"WINSSecondaryServer",TYPE_PING | TYPE_IP,TXT_WBEM_REP_CIMV2,TXT_WBEM_NS_NETWORK));
  886. PropList.push_back(WbemProperty(m_pszwCaption,TYPE_HIDE,TXT_WBEM_REP_CIMV2,TXT_WBEM_NS_NETWORK));
  887. PropList.push_back(WbemProperty(L"IPAddress",TYPE_HIDE,TXT_WBEM_REP_CIMV2,TXT_WBEM_NS_NETWORK));
  888. PropList.push_back(WbemProperty(L"IPEnabled",TYPE_HIDE,TXT_WBEM_REP_CIMV2,TXT_WBEM_NS_NETWORK));
  889. m_WmiGateway.GetWbemProperties(PropList);
  890. if( !(m_bFlags & FLAG_VERBOSE_HIGH) )
  891. {
  892. RemoveInvalidAdapters(PropList);
  893. }
  894. FormatEnum(PropList,pszwInstance);
  895. return TRUE;
  896. }
  897. // Get the Gateway data from Win32_NetworkAdapter
  898. BOOLEAN CDiagnostics::ExecGatewayQuery(WCHAR *pszwInstance)
  899. {
  900. EnumWbemProperty PropList;
  901. m_pszwCaption = TXT_ADAPTER_CAPTION;
  902. wcsncpy(m_szwHeader,ids(IDS_GATEWAY_HEADER),MAX_PATH);
  903. wcsncpy(m_szwCategory,ids(IDS_CATEGORY_NETWORKADAPTERS),MAX_PATH);
  904. PropList.push_back(WbemProperty(L"DefaultIPGateway",TYPE_PING | TYPE_IP | TYPE_SUBNET,TXT_WBEM_REP_CIMV2,TXT_WBEM_NS_NETWORK));
  905. PropList.push_back(WbemProperty(L"IPAddress",TYPE_HIDE,TXT_WBEM_REP_CIMV2,TXT_WBEM_NS_NETWORK));
  906. PropList.push_back(WbemProperty(L"IPSubnet",TYPE_HIDE,TXT_WBEM_REP_CIMV2,TXT_WBEM_NS_NETWORK));
  907. PropList.push_back(WbemProperty(m_pszwCaption,TYPE_HIDE,TXT_WBEM_REP_CIMV2,TXT_WBEM_NS_NETWORK));
  908. PropList.push_back(WbemProperty(L"IPEnabled",TYPE_HIDE,TXT_WBEM_REP_CIMV2,TXT_WBEM_NS_NETWORK));
  909. m_WmiGateway.GetWbemProperties(PropList);
  910. if( !(m_bFlags & FLAG_VERBOSE_HIGH) )
  911. {
  912. RemoveInvalidAdapters(PropList);
  913. }
  914. FormatEnum(PropList,pszwInstance);
  915. return TRUE;
  916. }
  917. // Get the DHCP data from Win32_NetworkAdapter
  918. BOOLEAN CDiagnostics::ExecDhcpQuery(WCHAR *pszwInstance)
  919. {
  920. EnumWbemProperty PropList;
  921. m_pszwCaption = TXT_ADAPTER_CAPTION;
  922. wcsncpy(m_szwHeader,ids(IDS_DHCP_HEADER),MAX_PATH);
  923. wcsncpy(m_szwCategory,ids(IDS_CATEGORY_NETWORKADAPTERS),MAX_PATH);
  924. PropList.push_back(WbemProperty(L"DHCPServer",TYPE_PING | TYPE_IP,TXT_WBEM_REP_CIMV2,TXT_WBEM_NS_NETWORK));
  925. PropList.push_back(WbemProperty(m_pszwCaption,TYPE_HIDE,TXT_WBEM_REP_CIMV2,TXT_WBEM_NS_NETWORK));
  926. PropList.push_back(WbemProperty(L"IPAddress",TYPE_HIDE,TXT_WBEM_REP_CIMV2,TXT_WBEM_NS_NETWORK));
  927. m_WmiGateway.GetWbemProperties(PropList);
  928. if( !(m_bFlags & FLAG_VERBOSE_HIGH) )
  929. {
  930. RemoveInvalidAdapters(PropList);
  931. }
  932. FormatEnum(PropList,pszwInstance);
  933. return TRUE;
  934. }
  935. // Get the Computer info data from Win32_ComputerSystem
  936. BOOLEAN CDiagnostics::ExecComputerQuery()
  937. {
  938. if( !(m_bFlags & FLAG_CMD_SHOW) )
  939. {
  940. return FALSE;
  941. }
  942. EnumWbemProperty PropList;
  943. m_pszwCaption = TXT_COMPUTER_CAPTION;
  944. wcsncpy(m_szwCategory,ids(IDS_CATEGORY_SYSTEMINFO),MAX_PATH);
  945. wcsncpy(m_szwHeader,ids(IDS_COMPUTER_HEADER),MAX_PATH);
  946. PropList.push_back(WbemProperty(NULL,0,TXT_WBEM_REP_CIMV2,TXT_WBEM_NS_COMPUTER));
  947. m_WmiGateway.GetWbemProperties(PropList);
  948. FormatEnum(PropList);
  949. return TRUE;
  950. }
  951. // Gets the system info data from Win32_SystemInformation
  952. BOOLEAN CDiagnostics::ExecOSQuery()
  953. {
  954. if( !(m_bFlags & FLAG_CMD_SHOW) )
  955. {
  956. return FALSE;
  957. }
  958. EnumWbemProperty PropList;
  959. m_pszwCaption = TXT_OS_CAPTION;
  960. wcsncpy(m_szwHeader,ids(IDS_OS_HEADER),MAX_PATH);
  961. wcsncpy(m_szwCategory,ids(IDS_CATEGORY_SYSTEMINFO),MAX_PATH);
  962. PropList.push_back(WbemProperty(NULL,0,TXT_WBEM_REP_CIMV2,TXT_WBEM_NS_OS));
  963. m_WmiGateway.GetWbemProperties(PropList);
  964. FormatEnum(PropList);
  965. return TRUE;
  966. }
  967. // Gets the Version info data from Win32_SystemInformation
  968. BOOLEAN CDiagnostics::ExecVersionQuery()
  969. {
  970. if( !(m_bFlags & FLAG_CMD_SHOW) )
  971. {
  972. return FALSE;
  973. }
  974. EnumWbemProperty PropList;
  975. m_pszwCaption = TXT_VERSION_CAPTION;
  976. wcsncpy(m_szwHeader,ids(IDS_VERSION_HEADER),MAX_PATH);
  977. wcsncpy(m_szwCategory,ids(IDS_CATEGORY_SYSTEMINFO),MAX_PATH);
  978. PropList.push_back(WbemProperty(L"Version",0,TXT_WBEM_REP_CIMV2,TXT_WBEM_NS_OS));
  979. PropList.push_back(WbemProperty(L"BuildVersion",0,TXT_WBEM_REP_CIMV2,TXT_WBEM_NS_WMI));
  980. m_WmiGateway.GetWbemProperties(PropList);
  981. FormatEnum(PropList);
  982. return TRUE;
  983. }
  984. // Converts a port number into a string
  985. LPWSTR GetMailType(DWORD dwType)
  986. {
  987. switch(dwType)
  988. {
  989. case MAIL_SMTP:
  990. return ids(IDS_SMTP);
  991. case MAIL_SMTP2:
  992. return ids(IDS_SMTP);
  993. case MAIL_POP3:
  994. return ids(IDS_POP3);
  995. case MAIL_IMAP:
  996. return ids(IDS_IMAP);
  997. case MAIL_HTTP:
  998. return ids(IDS_HTTP);
  999. default:
  1000. return ids(IDS_UNKNOWN);
  1001. }
  1002. }
  1003. //Gets the news and data and formats the results. performs the pings and connects
  1004. BOOLEAN CDiagnostics::ExecNewsQuery()
  1005. {
  1006. HRESULT hr;
  1007. INETSERVER rNewsServer;
  1008. EnumProperty PropList;
  1009. BOOLEAN bConnect = 2;
  1010. m_pszwCaption = TXT_NEWS_CAPTION;
  1011. wcsncpy(m_szwHeader,ids(IDS_NEWS_HEADER),MAX_PATH);
  1012. wcsncpy(m_szwCategory,ids(IDS_CATEGORY_INTERNET),MAX_PATH);
  1013. hr = GetOEDefaultNewsServer2(rNewsServer);
  1014. if( SUCCEEDED(hr) )
  1015. {
  1016. if( strcmp(rNewsServer.szServerName,"") != 0 )
  1017. {
  1018. Property Prop;
  1019. m_bstrCaption = rNewsServer.szServerName;
  1020. Prop.Clear();
  1021. Prop.SetProperty(L"NewsNNTPPort",TYPE_CONNECT);
  1022. Prop.Value.push_back(_variant_t((LONG)rNewsServer.dwPort));
  1023. PropList.push_back(Prop);
  1024. Prop.Clear();
  1025. Prop.SetProperty(L"NewsServer",TYPE_PING | TYPE_CONNECT);
  1026. Prop.Value.push_back(_variant_t(rNewsServer.szServerName));
  1027. PropList.push_back(Prop);
  1028. if( (m_bFlags & FLAG_CMD_CONNECT) )
  1029. {
  1030. WCHAR wszConnect[MAX_PATH+1];
  1031. _bstr_t bstrServer = rNewsServer.szServerName;
  1032. if( Connect((LPWSTR)bstrServer,rNewsServer.dwPort) )
  1033. {
  1034. //L"Successfully connected to %hs port %d"
  1035. _snwprintf(wszConnect,MAX_PATH,ids(IDS_CONNECTEDTOSERVERSUCCESS),rNewsServer.szServerName,rNewsServer.dwPort);
  1036. bConnect = TRUE;
  1037. }
  1038. else
  1039. {
  1040. //"Unable to connect to %hs port %d"
  1041. _snwprintf(wszConnect,MAX_PATH,ids(IDS_CONNECTEDTOSERVERFAILED),rNewsServer.szServerName,rNewsServer.dwPort);
  1042. bConnect = FALSE;
  1043. }
  1044. PropList.push_back(Property(wszConnect,TYPE_TEXT | TYPE_CONNECT));
  1045. }
  1046. }
  1047. }
  1048. else
  1049. {
  1050. m_bstrCaption = ids(IDS_NOTCONFIGURED);
  1051. PropList.push_back(Property((WCHAR*)m_bstrCaption,TYPE_TEXT));
  1052. }
  1053. FormatEnum(PropList, NULL, bConnect);
  1054. m_bstrCaption = L"";
  1055. return TRUE;
  1056. }
  1057. // Get and format the Mail server and port number. This uses the OEACCTMGR not WMI.
  1058. // OEACCTMGR does not work if it is run as a provider
  1059. BOOLEAN CDiagnostics::ExecMailQuery()
  1060. {
  1061. EnumProperty PropList;
  1062. INETSERVER rInBoundMailServer;
  1063. INETSERVER rOutBoundMailServer;
  1064. DWORD dwInBoundMailType;
  1065. DWORD dwOutBoundMailType;
  1066. HRESULT hr;
  1067. BOOLEAN bConnect = 2;
  1068. BOOLEAN bMailConfigured = FALSE;
  1069. // Set the caption, header and category information (describes this object)
  1070. //
  1071. m_pszwCaption = TXT_MAIL_CAPTION;
  1072. wcsncpy(m_szwHeader,ids(IDS_MAIL_HEADER),MAX_PATH);
  1073. wcsncpy(m_szwCategory,ids(IDS_CATEGORY_INTERNET),MAX_PATH);
  1074. hr = GetOEDefaultMailServer2(rInBoundMailServer,
  1075. dwInBoundMailType,
  1076. rOutBoundMailServer,
  1077. dwOutBoundMailType);
  1078. if( SUCCEEDED(hr) )
  1079. {
  1080. if( strcmp(rInBoundMailServer.szServerName,"") != 0 )
  1081. {
  1082. Property Prop;
  1083. _variant_t varValue;
  1084. m_bstrCaption = rInBoundMailServer.szServerName;
  1085. Prop.Clear();
  1086. Prop.SetProperty(L"InBoundMailPort",TYPE_CONNECT);
  1087. Prop.Value.push_back(_variant_t((LONG)rInBoundMailServer.dwPort));
  1088. PropList.push_back(Prop);
  1089. Prop.Clear();
  1090. Prop.SetProperty(L"InBoundMailServer",TYPE_CONNECT | (dwInBoundMailType!=MAIL_HTTP ? TYPE_PING : 0));
  1091. Prop.Value.push_back(_variant_t(rInBoundMailServer.szServerName));
  1092. PropList.push_back(Prop);
  1093. Prop.Clear();
  1094. Prop.SetProperty(L"InBoundMailType",0);
  1095. Prop.Value.push_back(_variant_t(GetMailType(dwInBoundMailType)));
  1096. PropList.push_back(Prop);
  1097. if( (m_bFlags & FLAG_CMD_CONNECT) && dwInBoundMailType != MAIL_HTTP)
  1098. {
  1099. _bstr_t bstrServer = rInBoundMailServer.szServerName;
  1100. WCHAR wszConnect[MAX_PATH+1];
  1101. if( Connect((LPWSTR)bstrServer,rInBoundMailServer.dwPort) )
  1102. {
  1103. _snwprintf(wszConnect,MAX_PATH,ids(IDS_CONNECTEDTOSERVERSUCCESS),rInBoundMailServer.szServerName,rInBoundMailServer.dwPort);
  1104. bConnect = TRUE;
  1105. }
  1106. else
  1107. {
  1108. _snwprintf(wszConnect,MAX_PATH,ids(IDS_CONNECTEDTOSERVERFAILED),rInBoundMailServer.szServerName,rInBoundMailServer.dwPort);
  1109. bConnect = FALSE;
  1110. }
  1111. PropList.push_back(Property(wszConnect,TYPE_TEXT | TYPE_CONNECT));
  1112. }
  1113. bMailConfigured = TRUE;
  1114. }
  1115. if( strcmp(rOutBoundMailServer.szServerName,"") != 0 )
  1116. {
  1117. Property Prop;
  1118. _variant_t varValue;
  1119. if( bMailConfigured )
  1120. {
  1121. m_bstrCaption += L" / ";
  1122. }
  1123. m_bstrCaption += rOutBoundMailServer.szServerName;
  1124. Prop.Clear();
  1125. Prop.SetProperty(L"OutBoundMailPort",TYPE_CONNECT);
  1126. Prop.Value.push_back(_variant_t((LONG)rOutBoundMailServer.dwPort));
  1127. PropList.push_back(Prop);
  1128. Prop.Clear();
  1129. Prop.SetProperty(L"OutBoundMailServer",TYPE_PING | TYPE_CONNECT);
  1130. Prop.Value.push_back(_variant_t(rOutBoundMailServer.szServerName));
  1131. PropList.push_back(Prop);
  1132. Prop.Clear();
  1133. Prop.SetProperty(L"OutBoundMailType",0);
  1134. Prop.Value.push_back(_variant_t(GetMailType(dwOutBoundMailType)));
  1135. PropList.push_back(Prop);
  1136. if( (m_bFlags & FLAG_CMD_CONNECT) && dwOutBoundMailType != MAIL_HTTP)
  1137. {
  1138. _bstr_t bstrServer = rOutBoundMailServer.szServerName;
  1139. WCHAR wszConnect[MAX_PATH+1];
  1140. if( Connect((LPWSTR)bstrServer,rOutBoundMailServer.dwPort) )
  1141. {
  1142. _snwprintf(wszConnect,MAX_PATH,ids(IDS_CONNECTEDTOSERVERSUCCESS),rOutBoundMailServer.szServerName,rOutBoundMailServer.dwPort);
  1143. bConnect = TRUE;
  1144. }
  1145. else
  1146. {
  1147. _snwprintf(wszConnect,MAX_PATH,ids(IDS_CONNECTEDTOSERVERFAILED),rOutBoundMailServer.szServerName,rOutBoundMailServer.dwPort);
  1148. bConnect = FALSE;
  1149. }
  1150. PropList.push_back(Property(wszConnect,TYPE_TEXT | TYPE_CONNECT));
  1151. }
  1152. bMailConfigured = TRUE;
  1153. }
  1154. if( !bMailConfigured )
  1155. {
  1156. m_bstrCaption = ids(IDS_NOTCONFIGURED);
  1157. PropList.push_back(Property((WCHAR*)m_bstrCaption,TYPE_TEXT));
  1158. }
  1159. }
  1160. else
  1161. {
  1162. m_bstrCaption = ids(IDS_NOTCONFIGURED);
  1163. PropList.push_back(Property((WCHAR*)m_bstrCaption,TYPE_TEXT));
  1164. }
  1165. FormatEnum(PropList, NULL, bConnect);
  1166. m_bstrCaption = L"";
  1167. return TRUE;
  1168. }
  1169. // Get IE's proxy settings and process the data
  1170. BOOLEAN CDiagnostics::ExecProxyQuery()
  1171. {
  1172. WCHAR wszProxy[MAX_PATH];
  1173. DWORD dwPort;
  1174. DWORD dwEnabled;
  1175. EnumProperty PropList;
  1176. BOOLEAN bConnectPass = 2;
  1177. WCHAR szw[MAX_PATH+1];
  1178. wcsncpy(m_szwHeader,ids(IDS_PROXY_HEADER),MAX_PATH);
  1179. wcsncpy(m_szwCategory,ids(IDS_CATEGORY_INTERNET),MAX_PATH);
  1180. if( GetIEProxy(wszProxy,MAX_PATH,&dwPort,&dwEnabled) )
  1181. {
  1182. m_bstrCaption = wszProxy;
  1183. if( dwEnabled )
  1184. {
  1185. Property Prop;
  1186. WCHAR szwConnect[MAX_PATH+1];
  1187. LONG nConnect = 0;
  1188. Prop.Clear();
  1189. Prop.SetProperty(L"IEProxy",TYPE_PING | TYPE_CONNECT);
  1190. Prop.Value.push_back(_variant_t(wszProxy));
  1191. PropList.push_back(Prop);
  1192. Prop.Clear();
  1193. Prop.SetProperty(L"IEProxyPort",TYPE_CONNECT);
  1194. Prop.Value.push_back(_variant_t((LONG)dwPort));
  1195. PropList.push_back(Prop);
  1196. if( (m_bFlags & FLAG_CMD_CONNECT) )
  1197. {
  1198. // Connecting to %s port %d
  1199. _snwprintf(szw,MAX_PATH,ids(IDS_CONNECTINGTOSERVER_STATUS),wszProxy,dwPort);
  1200. ReportStatus(szw,0);
  1201. _snwprintf(szwConnect,MAX_PATH,ids(IDS_SERVERCONNECTSTART));
  1202. if( Connect(wszProxy,dwPort) )
  1203. {
  1204. _snwprintf(szwConnect,MAX_PATH,L"%s%s%d",szwConnect,nConnect?L",":L"",dwPort);
  1205. nConnect++;
  1206. }
  1207. if( !nConnect )
  1208. {
  1209. _snwprintf(szwConnect,MAX_PATH,L"%s%s",szwConnect,ids(IDS_NONE));
  1210. bConnectPass = FALSE;
  1211. }
  1212. else
  1213. {
  1214. bConnectPass = TRUE;
  1215. }
  1216. _snwprintf(szwConnect,MAX_PATH,L"%s%s",szwConnect,ids(IDS_SERVERCONNECTEND));
  1217. PropList.push_back(WbemProperty(szwConnect,TYPE_TEXT | TYPE_CONNECT));
  1218. }
  1219. }
  1220. else
  1221. {
  1222. HideAll(PropList);
  1223. lstrcpy(szw,ids(IDS_IEPROXYNOTUSED));
  1224. m_pszwCaption = szw;
  1225. m_bstrCaption = ids(IDS_IEPROXYNOTUSED); //IDS_NOTCONFIGURED
  1226. }
  1227. }
  1228. FormatEnum(PropList,NULL, bConnectPass);
  1229. m_bstrCaption = L"";
  1230. return TRUE;
  1231. }
  1232. // Get teh loopback adapter
  1233. BOOLEAN CDiagnostics::ExecLoopbackQuery()
  1234. {
  1235. EnumWbemProperty PropList;
  1236. EnumWbemProperty::iterator iter;
  1237. _variant_t vLoopback = L"127.0.0.1";
  1238. m_pszwCaption = TXT_LOOPBACK_CAPTION;
  1239. wcsncpy(m_szwHeader,ids(IDS_LOOPBACK_HEADER),MAX_PATH);
  1240. wcsncpy(m_szwCategory,ids(IDS_CATEGORY_INTERNET),MAX_PATH);
  1241. PropList.push_back(WbemProperty(L"Loopback",TYPE_PING));
  1242. iter = PropList.begin();
  1243. iter->Value.push_back(vLoopback);
  1244. FormatEnum(PropList);
  1245. return TRUE;
  1246. }
  1247. // ping or connect to a specified IP host name or IP address
  1248. BOOLEAN CDiagnostics::ExecIPHost(WCHAR *pszwHostName,WCHAR *pszwHostPort)
  1249. {
  1250. EnumProperty PropList;
  1251. WCHAR szw[MAX_PATH+1];
  1252. BOOL bFlag;
  1253. m_pszwCaption = L"IPHost";
  1254. lstrcpy(m_szwHeader,L"IPHost");
  1255. Set(PropList, L"IPHost",TYPE_CONNECT | TYPE_PING,_variant_t(pszwHostName));
  1256. if( m_bFlags & FLAG_CMD_CONNECT )
  1257. {
  1258. WCHAR szw[MAX_PATH+1];
  1259. WCHAR szwConnect[MAX_PATH+1];
  1260. Set(PropList, L"Port",TYPE_CONNECT,_variant_t(pszwHostPort));
  1261. _snwprintf(szw,MAX_PATH,L"Connecting to %s port %s",pszwHostName,pszwHostPort);
  1262. ReportStatus(szw,0);
  1263. _snwprintf(szwConnect,MAX_PATH,ids(IDS_SERVERCONNECTSTART));
  1264. if( IsNumber(pszwHostPort) && Connect(pszwHostName,wcstol(pszwHostPort,NULL,10)) )
  1265. {
  1266. _snwprintf(szwConnect,MAX_PATH,L"%s%s",szwConnect,pszwHostPort);
  1267. }
  1268. else
  1269. {
  1270. _snwprintf(szwConnect,MAX_PATH,L"%s%s",szwConnect,ids(IDS_NONE));
  1271. }
  1272. _snwprintf(szwConnect,MAX_PATH,L"%s%s",szwConnect,ids(IDS_SERVERCONNECTEND));
  1273. PropList.push_back(Property(szwConnect,TYPE_TEXT | TYPE_CONNECT));
  1274. }
  1275. FormatEnum(PropList);
  1276. return TRUE;
  1277. }
  1278. // Init the netsh interface
  1279. void CDiagnostics::NetShNetdiag(BOOLEAN bStartTag, LPCTSTR pszwValue)
  1280. {
  1281. if( m_bInterface == NETSH_INTERFACE )
  1282. {
  1283. m_nIndent = 0;
  1284. m_IsNetdiagDisplayed = FALSE;
  1285. }
  1286. }
  1287. // Format the netsh header
  1288. void CDiagnostics::NetShHeader(BOOLEAN bStartTag,LPCTSTR pszwValue,LPCTSTR pszwCaption)
  1289. {
  1290. if( m_bInterface == NETSH_INTERFACE )
  1291. {
  1292. if( bStartTag )
  1293. {
  1294. DisplayMessageT(L"\n");
  1295. if( pszwValue )
  1296. {
  1297. LONG nIndent = m_IsNetdiagDisplayed;
  1298. DisplayMessageT(L"%1!s!%2!s!",Indent(nIndent),pszwValue);
  1299. if( pszwCaption )
  1300. {
  1301. DisplayMessageT(L" (%1!s!)",pszwCaption);
  1302. }
  1303. DisplayMessageT(L"\n");
  1304. m_IsContainerDisplayed = TRUE;
  1305. }
  1306. else
  1307. {
  1308. m_IsContainerDisplayed = FALSE;
  1309. }
  1310. }
  1311. else
  1312. {
  1313. m_IsContainerDisplayed = FALSE;
  1314. }
  1315. }
  1316. }
  1317. // Format the netsh caption
  1318. void CDiagnostics::NetShCaption(BOOLEAN bStartTag,LPCTSTR pszwValue)
  1319. {
  1320. if( m_bInterface == NETSH_INTERFACE )
  1321. {
  1322. if( bStartTag )
  1323. {
  1324. if( m_nInstance > 1 )
  1325. {
  1326. if( m_bCaptionDisplayed == FALSE )
  1327. {
  1328. if( pszwValue )
  1329. {
  1330. LONG nIndent = m_IsNetdiagDisplayed + m_IsContainerDisplayed;
  1331. DisplayMessageT(L"%1!s!%2!2d!. %3!s!\n",Indent(nIndent),m_nIndex, pszwValue);
  1332. m_IsPropertyListDisplayed = TRUE;
  1333. }
  1334. else
  1335. {
  1336. m_IsPropertyListDisplayed = FALSE;
  1337. }
  1338. m_bCaptionDisplayed = TRUE;
  1339. }
  1340. }
  1341. }
  1342. else
  1343. {
  1344. m_IsPropertyListDisplayed = FALSE;
  1345. }
  1346. }
  1347. }
  1348. void CDiagnostics::NetShField(BOOLEAN bStartTag,LPCTSTR pszwValue)
  1349. {
  1350. if( m_bInterface == NETSH_INTERFACE )
  1351. {
  1352. if( bStartTag )
  1353. {
  1354. m_nPropertyLegth = 0;
  1355. LONG nIndent = m_IsNetdiagDisplayed + m_IsContainerDisplayed + m_IsPropertyListDisplayed;
  1356. if( pszwValue )
  1357. {
  1358. m_nPropertyLegth = DisplayMessageT(L"%1!s!%2!s! = ",Indent(nIndent),pszwValue);
  1359. }
  1360. else
  1361. {
  1362. m_nPropertyLegth = DisplayMessageT(L"%1!s!",Indent(nIndent));
  1363. }
  1364. m_nValueIndex = 0;
  1365. m_IsPropertyDisplayed = TRUE;
  1366. }
  1367. else
  1368. {
  1369. m_IsPropertyDisplayed = FALSE;
  1370. }
  1371. }
  1372. }
  1373. void CDiagnostics::NetShProperty(BOOLEAN bStartTag,LPCTSTR pszwValue,LPCTSTR pszwComment,BOOL bFlags)
  1374. {
  1375. if( m_bInterface == NETSH_INTERFACE )
  1376. {
  1377. if( bStartTag )
  1378. {
  1379. if( (bFlags & TYPE_PING) )
  1380. {
  1381. LONG nIndent = m_IsNetdiagDisplayed + m_IsContainerDisplayed + m_IsPropertyListDisplayed + m_IsPropertyDisplayed;
  1382. if( m_nValueIndex == 0 )
  1383. {
  1384. DisplayMessageT(L"\n");
  1385. }
  1386. DisplayMessageT(L"%1!s!%2!s! %3!s!\n",Indent(nIndent),pszwValue?pszwValue:L"",pszwComment?pszwComment:L"");
  1387. m_nValueIndex++;
  1388. }
  1389. else
  1390. {
  1391. DisplayMessageT(L"%1!s!%2!s! %3!s!\n",m_nValueIndex++?Space(m_nPropertyLegth):L"",pszwValue?pszwValue:L"",pszwComment?pszwComment:L"");
  1392. }
  1393. m_IsValueDisplayed = TRUE;
  1394. }
  1395. else
  1396. {
  1397. m_IsValueDisplayed = FALSE;
  1398. }
  1399. }
  1400. }