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.

528 lines
13 KiB

  1. #include "dglogsnetsh.h"
  2. //#include <netsh.h>
  3. // Imported netsh.exe function
  4. //
  5. RegisterHelper22 RegisterHelper2 = NULL;
  6. RegisterContext22 RegisterContext2 = NULL;
  7. PrintMessage22 PrintMessage2 = NULL;
  8. const WCHAR c_szTroublshootCmdLine[] = L"explorer.exe hcp://system/netdiag/dglogs.htm";
  9. //extern CDiagnostics g_Diagnostics;
  10. CDiagnostics * g_pDiagnostics;
  11. static const GUID g_MyGuid =
  12. { 0xcc41b21b, 0x8040, 0x4bb0, { 0xac, 0x2a, 0x82, 0x6, 0x23, 0x16, 0x9, 0x40 } };
  13. //
  14. // declare the command structs. you need to declare the
  15. // structs based on how you will be grouping them. so,
  16. // for example, the three 'show' commands should be in
  17. // the same struct so you can put them in a single group
  18. //
  19. CMD_ENTRY g_TopLevelCommands[] =
  20. {
  21. CREATE_CMD_ENTRY(SHOW_GUI, HandleShowGui),
  22. };
  23. // table of SHOW commands
  24. //
  25. static CMD_ENTRY isShowCmdTable[] =
  26. {
  27. CREATE_CMD_ENTRY(SHOW_MAIL, HandleShow),
  28. CREATE_CMD_ENTRY(SHOW_NEWS, HandleShow),
  29. CREATE_CMD_ENTRY(SHOW_PROXY, HandleShow),
  30. CREATE_CMD_ENTRY(SHOW_VERSION, HandleShow),
  31. CREATE_CMD_ENTRY(SHOW_OS, HandleShow),
  32. CREATE_CMD_ENTRY(SHOW_COMPUTER, HandleShow),
  33. CREATE_CMD_ENTRY(SHOW_WINS, HandleShow),
  34. CREATE_CMD_ENTRY(SHOW_DNS, HandleShow),
  35. CREATE_CMD_ENTRY(SHOW_GATEWAY, HandleShow),
  36. CREATE_CMD_ENTRY(SHOW_DHCP, HandleShow),
  37. CREATE_CMD_ENTRY(SHOW_IP, HandleShow),
  38. CREATE_CMD_ENTRY(SHOW_ADAPTER, HandleShow),
  39. CREATE_CMD_ENTRY(SHOW_CLIENT, HandleShow),
  40. CREATE_CMD_ENTRY(SHOW_MODEM, HandleShow),
  41. CREATE_CMD_ENTRY(SHOW_ALL, HandleShow),
  42. CREATE_CMD_ENTRY(SHOW_TEST, HandleShow),
  43. };
  44. // table of PING commands
  45. //
  46. static CMD_ENTRY isPingCmdTable[] =
  47. {
  48. CREATE_CMD_ENTRY(PING_MAIL, HandlePing),
  49. CREATE_CMD_ENTRY(PING_NEWS, HandlePing),
  50. CREATE_CMD_ENTRY(PING_PROXY, HandlePing),
  51. CREATE_CMD_ENTRY(PING_WINS, HandlePing),
  52. CREATE_CMD_ENTRY(PING_DNS, HandlePing),
  53. CREATE_CMD_ENTRY(PING_GATEWAY, HandlePing),
  54. CREATE_CMD_ENTRY(PING_DHCP, HandlePing),
  55. CREATE_CMD_ENTRY(PING_IP, HandlePing),
  56. CREATE_CMD_ENTRY(PING_ADAPTER, HandlePing),
  57. CREATE_CMD_ENTRY(PING_LOOPBACK, HandlePing),
  58. CREATE_CMD_ENTRY(PING_IPHOST, HandlePing),
  59. };
  60. // table of connect commands
  61. //
  62. static CMD_ENTRY isConnectCmdTable[] =
  63. {
  64. CREATE_CMD_ENTRY(CONNECT_MAIL, HandleConnect),
  65. CREATE_CMD_ENTRY(CONNECT_NEWS, HandleConnect),
  66. CREATE_CMD_ENTRY(CONNECT_PROXY, HandleConnect),
  67. CREATE_CMD_ENTRY(CONNECT_IPHOST, HandleConnect),
  68. };
  69. // table of above group commands
  70. //
  71. static CMD_GROUP_ENTRY isGroupCmds[] =
  72. {
  73. CREATE_CMD_GROUP_ENTRY(GROUP_SHOW, isShowCmdTable),
  74. CREATE_CMD_GROUP_ENTRY(GROUP_PING, isPingCmdTable),
  75. CREATE_CMD_GROUP_ENTRY(GROUP_CONNECT, isConnectCmdTable),
  76. };
  77. DWORD WINAPI
  78. InitHelperDllEx(
  79. IN DWORD dwNetshVersion,
  80. OUT PVOID pReserved
  81. )
  82. {
  83. DWORD dwSize = 0;
  84. NS_HELPER_ATTRIBUTES attMyAttributes;
  85. GUID guidNetShGuid = NETSH_ROOT_GUID;
  86. HMODULE hModule;
  87. HMODULE hModuleNow;
  88. hModule = LoadLibrary(L"netsh.exe");
  89. if( !hModule || hModule != GetModuleHandle(NULL) )
  90. {
  91. return FALSE;
  92. }
  93. // Load the netsh.exe functions we require.
  94. //
  95. RegisterHelper2 = (RegisterHelper22) GetProcAddress(hModule,"RegisterHelper");
  96. if( RegisterHelper2 )
  97. {
  98. RegisterContext2 = (RegisterContext22) GetProcAddress(hModule,"RegisterContext");
  99. if( RegisterContext2 )
  100. {
  101. PrintMessage2 = (PrintMessage22) GetProcAddress(hModule,"PrintMessage");
  102. }
  103. }
  104. if( !PrintMessage2 )
  105. {
  106. // If PrintMessage2 failed to load they all failed and we bail.
  107. //
  108. return FALSE;
  109. }
  110. g_pDiagnostics = new CDiagnostics;
  111. if( !g_pDiagnostics )
  112. {
  113. return FALSE;
  114. }
  115. if( g_pDiagnostics->Initialize(NETSH_INTERFACE) == FALSE )
  116. {
  117. // TODO figure out what error code to return if Inialize fails
  118. //
  119. return FALSE;
  120. }
  121. g_pDiagnostics->SetInterface(NETSH_INTERFACE);
  122. // Register this module as a helper to the netsh root
  123. // context.
  124. //
  125. ZeroMemory( &attMyAttributes, sizeof(attMyAttributes) );
  126. attMyAttributes.dwVersion = DGLOGS_HELPER_VERSION;
  127. attMyAttributes.guidHelper = g_MyGuid;
  128. attMyAttributes.pfnStart = DglogsStartHelper;
  129. attMyAttributes.pfnStop = NULL;
  130. DWORD dwErr = RegisterHelper2( &guidNetShGuid, &attMyAttributes );
  131. return dwErr;
  132. }
  133. DWORD
  134. WINAPI
  135. DglogsStartHelper(
  136. IN CONST GUID *pguidParent,
  137. IN DWORD dwVersion
  138. )
  139. {
  140. DWORD dwErr = NO_ERROR;
  141. NS_CONTEXT_ATTRIBUTES attMyAttributes;
  142. // Initialize
  143. //
  144. ZeroMemory(&attMyAttributes, sizeof(attMyAttributes));
  145. attMyAttributes.pwszContext = TOKEN_DGLOGS;
  146. attMyAttributes.guidHelper = g_MyGuid;
  147. attMyAttributes.dwVersion = DGLOGS_CONTEXT_VERSION;
  148. attMyAttributes.dwFlags = 0;
  149. attMyAttributes.ulNumTopCmds= sizeof(g_TopLevelCommands)/sizeof(CMD_ENTRY);
  150. attMyAttributes.pTopCmds = (CMD_ENTRY (*)[])g_TopLevelCommands;
  151. attMyAttributes.ulNumGroups = sizeof(isGroupCmds)/sizeof(CMD_GROUP_ENTRY);
  152. attMyAttributes.pCmdGroups = (CMD_GROUP_ENTRY (*)[])isGroupCmds;
  153. attMyAttributes.pfnDumpFn = SampleDump;
  154. dwErr = RegisterContext2( &attMyAttributes );
  155. return dwErr;
  156. }
  157. DWORD
  158. HandleShowGui(
  159. IN LPCWSTR pwszMachine,
  160. IN OUT LPWSTR *ppwcArguments,
  161. IN DWORD dwCurrentIndex,
  162. IN DWORD dwArgCount,
  163. IN DWORD dwFlags,
  164. IN LPCVOID pvData,
  165. OUT BOOL *pbDone
  166. )
  167. {
  168. BOOL fResult = TRUE;
  169. STARTUPINFO si;
  170. PROCESS_INFORMATION pi;
  171. WCHAR szCmdLine[MAX_PATH+1];
  172. ZeroMemory((LPVOID) &si, sizeof(si));
  173. si.cb = sizeof(STARTUPINFO);
  174. // Note, we must do this, since CreateProcess will change this string
  175. //
  176. lstrcpyW(szCmdLine, c_szTroublshootCmdLine);
  177. fResult = CreateProcess(
  178. NULL,
  179. szCmdLine,
  180. NULL,
  181. NULL,
  182. FALSE,
  183. 0,
  184. NULL,
  185. NULL,
  186. &si,
  187. &pi);
  188. if (fResult)
  189. {
  190. CloseHandle(pi.hThread);
  191. CloseHandle(pi.hProcess);
  192. }
  193. return 0;
  194. }
  195. DWORD
  196. HandleShow(
  197. IN LPCWSTR pwszMachine,
  198. IN OUT LPWSTR *ppwcArguments,
  199. IN DWORD dwCurrentIndex,
  200. IN DWORD dwArgCount,
  201. IN DWORD dwFlags,
  202. IN LPCVOID pvData,
  203. OUT BOOL *pbDone
  204. )
  205. /*++
  206. Routine Description
  207. Handles the Show command
  208. Arguments
  209. none
  210. Return Value
  211. none
  212. --*/
  213. {
  214. WCHAR *pszwVerbose = NULL;
  215. WCHAR *pszwInstance = NULL;
  216. BOOLEAN bFlags = FLAG_VERBOSE_LOW;
  217. // Need three arguments (show,netdiag catagory)
  218. //
  219. if( lstrcmpi(ppwcArguments[2], CMD_ADAPTER) == 0 ||
  220. lstrcmpi(ppwcArguments[2], CMD_MODEM) == 0 ||
  221. lstrcmpi(ppwcArguments[2], CMD_CLIENT) == 0 ||
  222. lstrcmpi(ppwcArguments[2], CMD_WINS) == 0 ||
  223. lstrcmpi(ppwcArguments[2], CMD_DHCP) == 0 ||
  224. lstrcmpi(ppwcArguments[2], CMD_DNS) == 0 ||
  225. lstrcmpi(ppwcArguments[2], CMD_IP) == 0 ||
  226. lstrcmpi(ppwcArguments[2], CMD_GATEWAY) == 0 )
  227. {
  228. switch(dwArgCount)
  229. {
  230. case 5:
  231. if( lstrcmpi(ppwcArguments[3],SWITCH_VERBOSE) == 0 ||
  232. lstrcmpi(ppwcArguments[3],SWITCH_PROPERTIES) == 0 )
  233. {
  234. // Has first the switch then the instance
  235. //
  236. pszwVerbose = ppwcArguments[3];
  237. pszwInstance = ppwcArguments[4];
  238. }
  239. else if( lstrcmpi(ppwcArguments[4],SWITCH_VERBOSE) == 0 ||
  240. lstrcmpi(ppwcArguments[4],SWITCH_PROPERTIES) == 0 )
  241. {
  242. // Has first the instance and then the switch
  243. //
  244. pszwVerbose = ppwcArguments[4];
  245. pszwInstance = ppwcArguments[3];
  246. }
  247. else
  248. {
  249. // Invalid number of arguments
  250. //
  251. return ERROR_INVALID_SYNTAX;
  252. }
  253. break;
  254. case 4:
  255. if( lstrcmpi(ppwcArguments[3],SWITCH_VERBOSE) == 0 ||
  256. lstrcmpi(ppwcArguments[3],SWITCH_PROPERTIES) == 0)
  257. {
  258. pszwVerbose = ppwcArguments[3];
  259. }
  260. else
  261. {
  262. // Has na instance but no swicth
  263. //
  264. pszwInstance = ppwcArguments[3];
  265. }
  266. break;
  267. case 3:
  268. // No instance and no switch
  269. //
  270. break;
  271. default:
  272. // Invalid number of arguments
  273. //
  274. return ERROR_INVALID_SYNTAX;
  275. }
  276. }
  277. else if( dwArgCount == 4 &&
  278. (lstrcmpi(ppwcArguments[3],SWITCH_VERBOSE) == 0 ||
  279. lstrcmpi(ppwcArguments[3],SWITCH_PROPERTIES) == 0))
  280. {
  281. // Has a switch
  282. //
  283. pszwVerbose = ppwcArguments[3];
  284. }
  285. else if( dwArgCount == 4 && lstrcmpi(ppwcArguments[3],SWITCH_PROPERTIES) == 0)
  286. {
  287. // Has a switch
  288. //
  289. pszwVerbose = ppwcArguments[3];
  290. }
  291. else if( dwArgCount != 3 )
  292. {
  293. // Invalid number of arguments
  294. //
  295. return ERROR_INVALID_SYNTAX;
  296. }
  297. if( pszwVerbose )
  298. {
  299. if( lstrcmpi(pszwVerbose,SWITCH_VERBOSE) == 0 )
  300. {
  301. bFlags = FLAG_VERBOSE_HIGH;
  302. }
  303. if( lstrcmpi(pszwVerbose,SWITCH_PROPERTIES) == 0 )
  304. {
  305. bFlags = FLAG_VERBOSE_MEDIUM;
  306. }
  307. }
  308. g_pDiagnostics->ExecQuery(ppwcArguments[2], (bFlags | FLAG_CMD_SHOW) ,pszwInstance);
  309. return 0;
  310. }
  311. DWORD
  312. HandlePing(
  313. IN LPCWSTR pwszMachine,
  314. IN OUT LPWSTR *ppwcArguments,
  315. IN DWORD dwCurrentIndex,
  316. IN DWORD dwArgCount,
  317. IN DWORD dwFlags,
  318. IN LPCVOID pvData,
  319. OUT BOOL *pbDone
  320. )
  321. /*++
  322. Routine Description
  323. Handles the Ping command
  324. Arguments
  325. none
  326. Return Value
  327. none
  328. --*/
  329. {
  330. WCHAR *pszwInstance = NULL;
  331. // ERROR_INVALID_SYNTAX;
  332. if( lstrcmpi(ppwcArguments[2],CMD_ADAPTER) == 0 ||
  333. lstrcmpi(ppwcArguments[2],CMD_WINS) == 0 ||
  334. lstrcmpi(ppwcArguments[2],CMD_DHCP) == 0 ||
  335. lstrcmpi(ppwcArguments[2],CMD_DNS) == 0 ||
  336. lstrcmpi(ppwcArguments[2],CMD_IP) == 0 ||
  337. lstrcmpi(ppwcArguments[2],CMD_GATEWAY) == 0 )
  338. {
  339. switch(dwArgCount)
  340. {
  341. case 4:
  342. pszwInstance = ppwcArguments[3];
  343. break;
  344. case 3:
  345. break;
  346. default:
  347. // Invalid number of arguments
  348. //
  349. return ERROR_INVALID_SYNTAX;
  350. }
  351. }
  352. else if( lstrcmpi(ppwcArguments[2], CMD_IPHOST) == 0 )
  353. {
  354. if( dwArgCount == 4 )
  355. {
  356. // The IP host name/Address
  357. //
  358. pszwInstance = ppwcArguments[3];
  359. }
  360. else
  361. {
  362. // Invalid number of arguments
  363. //
  364. return ERROR_INVALID_SYNTAX;
  365. }
  366. }
  367. else if( dwArgCount != 3 )
  368. {
  369. // Invalid number of arguments
  370. //
  371. return ERROR_INVALID_SYNTAX;
  372. }
  373. // Ping the catagory
  374. //
  375. g_pDiagnostics->ExecQuery(ppwcArguments[2], (FLAG_VERBOSE_MEDIUM | FLAG_CMD_PING) ,pszwInstance);
  376. return 0;
  377. }
  378. DWORD
  379. HandleConnect(
  380. IN LPCWSTR pwszMachine,
  381. IN OUT LPWSTR *ppwcArguments,
  382. IN DWORD dwCurrentIndex,
  383. IN DWORD dwArgCount,
  384. IN DWORD dwFlags,
  385. IN LPCVOID pvData,
  386. OUT BOOL *pbDone
  387. )
  388. /*++
  389. Routine Description
  390. Handles the connect command
  391. Arguments
  392. none
  393. Return Value
  394. none
  395. --*/
  396. {
  397. WCHAR *pszwIPHost = NULL;
  398. WCHAR *pszwPort = NULL;
  399. if( lstrcmpi(ppwcArguments[2],CMD_IPHOST) == 0 )
  400. {
  401. // IPhost
  402. //
  403. if( dwArgCount == 5 )
  404. {
  405. // IP host name/Address
  406. //
  407. pszwIPHost = ppwcArguments[3];
  408. pszwPort = ppwcArguments[4];
  409. }
  410. else
  411. {
  412. // Invalid number of arguments
  413. //
  414. return ERROR_INVALID_SYNTAX;
  415. }
  416. }
  417. else if( dwArgCount != 3 )
  418. {
  419. // Invalid number of arguments
  420. //
  421. return ERROR_INVALID_SYNTAX;
  422. }
  423. // Establish the TCP connection
  424. //
  425. g_pDiagnostics->ExecQuery(ppwcArguments[2], (FLAG_VERBOSE_MEDIUM | FLAG_CMD_CONNECT) ,pszwIPHost, pszwPort);
  426. return 0;
  427. }
  428. DWORD
  429. WINAPI
  430. SampleDump(
  431. IN LPCWSTR pwszRouter,
  432. IN OUT LPWSTR *ppwcArguments,
  433. IN DWORD dwArgCount,
  434. IN LPCVOID pvData
  435. )
  436. /*++
  437. Routine Description
  438. No Idea what this function is for, but it looks like I need it for something
  439. Arguments
  440. none
  441. Return Value
  442. none
  443. --*/
  444. {
  445. return NO_ERROR;
  446. }