#include "dglogsnetsh.h" //#include // Imported netsh.exe function // RegisterHelper22 RegisterHelper2 = NULL; RegisterContext22 RegisterContext2 = NULL; PrintMessage22 PrintMessage2 = NULL; const WCHAR c_szTroublshootCmdLine[] = L"explorer.exe hcp://system/netdiag/dglogs.htm"; //extern CDiagnostics g_Diagnostics; CDiagnostics * g_pDiagnostics; static const GUID g_MyGuid = { 0xcc41b21b, 0x8040, 0x4bb0, { 0xac, 0x2a, 0x82, 0x6, 0x23, 0x16, 0x9, 0x40 } }; // // declare the command structs. you need to declare the // structs based on how you will be grouping them. so, // for example, the three 'show' commands should be in // the same struct so you can put them in a single group // CMD_ENTRY g_TopLevelCommands[] = { CREATE_CMD_ENTRY(SHOW_GUI, HandleShowGui), }; // table of SHOW commands // static CMD_ENTRY isShowCmdTable[] = { CREATE_CMD_ENTRY(SHOW_MAIL, HandleShow), CREATE_CMD_ENTRY(SHOW_NEWS, HandleShow), CREATE_CMD_ENTRY(SHOW_PROXY, HandleShow), CREATE_CMD_ENTRY(SHOW_VERSION, HandleShow), CREATE_CMD_ENTRY(SHOW_OS, HandleShow), CREATE_CMD_ENTRY(SHOW_COMPUTER, HandleShow), CREATE_CMD_ENTRY(SHOW_WINS, HandleShow), CREATE_CMD_ENTRY(SHOW_DNS, HandleShow), CREATE_CMD_ENTRY(SHOW_GATEWAY, HandleShow), CREATE_CMD_ENTRY(SHOW_DHCP, HandleShow), CREATE_CMD_ENTRY(SHOW_IP, HandleShow), CREATE_CMD_ENTRY(SHOW_ADAPTER, HandleShow), CREATE_CMD_ENTRY(SHOW_CLIENT, HandleShow), CREATE_CMD_ENTRY(SHOW_MODEM, HandleShow), CREATE_CMD_ENTRY(SHOW_ALL, HandleShow), CREATE_CMD_ENTRY(SHOW_TEST, HandleShow), }; // table of PING commands // static CMD_ENTRY isPingCmdTable[] = { CREATE_CMD_ENTRY(PING_MAIL, HandlePing), CREATE_CMD_ENTRY(PING_NEWS, HandlePing), CREATE_CMD_ENTRY(PING_PROXY, HandlePing), CREATE_CMD_ENTRY(PING_WINS, HandlePing), CREATE_CMD_ENTRY(PING_DNS, HandlePing), CREATE_CMD_ENTRY(PING_GATEWAY, HandlePing), CREATE_CMD_ENTRY(PING_DHCP, HandlePing), CREATE_CMD_ENTRY(PING_IP, HandlePing), CREATE_CMD_ENTRY(PING_ADAPTER, HandlePing), CREATE_CMD_ENTRY(PING_LOOPBACK, HandlePing), CREATE_CMD_ENTRY(PING_IPHOST, HandlePing), }; // table of connect commands // static CMD_ENTRY isConnectCmdTable[] = { CREATE_CMD_ENTRY(CONNECT_MAIL, HandleConnect), CREATE_CMD_ENTRY(CONNECT_NEWS, HandleConnect), CREATE_CMD_ENTRY(CONNECT_PROXY, HandleConnect), CREATE_CMD_ENTRY(CONNECT_IPHOST, HandleConnect), }; // table of above group commands // static CMD_GROUP_ENTRY isGroupCmds[] = { CREATE_CMD_GROUP_ENTRY(GROUP_SHOW, isShowCmdTable), CREATE_CMD_GROUP_ENTRY(GROUP_PING, isPingCmdTable), CREATE_CMD_GROUP_ENTRY(GROUP_CONNECT, isConnectCmdTable), }; DWORD WINAPI InitHelperDllEx( IN DWORD dwNetshVersion, OUT PVOID pReserved ) { DWORD dwSize = 0; NS_HELPER_ATTRIBUTES attMyAttributes; GUID guidNetShGuid = NETSH_ROOT_GUID; HMODULE hModule; HMODULE hModuleNow; hModule = LoadLibrary(L"netsh.exe"); if( !hModule || hModule != GetModuleHandle(NULL) ) { return FALSE; } // Load the netsh.exe functions we require. // RegisterHelper2 = (RegisterHelper22) GetProcAddress(hModule,"RegisterHelper"); if( RegisterHelper2 ) { RegisterContext2 = (RegisterContext22) GetProcAddress(hModule,"RegisterContext"); if( RegisterContext2 ) { PrintMessage2 = (PrintMessage22) GetProcAddress(hModule,"PrintMessage"); } } if( !PrintMessage2 ) { // If PrintMessage2 failed to load they all failed and we bail. // return FALSE; } g_pDiagnostics = new CDiagnostics; if( !g_pDiagnostics ) { return FALSE; } if( g_pDiagnostics->Initialize(NETSH_INTERFACE) == FALSE ) { // TODO figure out what error code to return if Inialize fails // return FALSE; } g_pDiagnostics->SetInterface(NETSH_INTERFACE); // Register this module as a helper to the netsh root // context. // ZeroMemory( &attMyAttributes, sizeof(attMyAttributes) ); attMyAttributes.dwVersion = DGLOGS_HELPER_VERSION; attMyAttributes.guidHelper = g_MyGuid; attMyAttributes.pfnStart = DglogsStartHelper; attMyAttributes.pfnStop = NULL; DWORD dwErr = RegisterHelper2( &guidNetShGuid, &attMyAttributes ); return dwErr; } DWORD WINAPI DglogsStartHelper( IN CONST GUID *pguidParent, IN DWORD dwVersion ) { DWORD dwErr = NO_ERROR; NS_CONTEXT_ATTRIBUTES attMyAttributes; // Initialize // ZeroMemory(&attMyAttributes, sizeof(attMyAttributes)); attMyAttributes.pwszContext = TOKEN_DGLOGS; attMyAttributes.guidHelper = g_MyGuid; attMyAttributes.dwVersion = DGLOGS_CONTEXT_VERSION; attMyAttributes.dwFlags = 0; attMyAttributes.ulNumTopCmds= sizeof(g_TopLevelCommands)/sizeof(CMD_ENTRY); attMyAttributes.pTopCmds = (CMD_ENTRY (*)[])g_TopLevelCommands; attMyAttributes.ulNumGroups = sizeof(isGroupCmds)/sizeof(CMD_GROUP_ENTRY); attMyAttributes.pCmdGroups = (CMD_GROUP_ENTRY (*)[])isGroupCmds; attMyAttributes.pfnDumpFn = SampleDump; dwErr = RegisterContext2( &attMyAttributes ); return dwErr; } DWORD HandleShowGui( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone ) { BOOL fResult = TRUE; STARTUPINFO si; PROCESS_INFORMATION pi; WCHAR szCmdLine[MAX_PATH+1]; ZeroMemory((LPVOID) &si, sizeof(si)); si.cb = sizeof(STARTUPINFO); // Note, we must do this, since CreateProcess will change this string // lstrcpyW(szCmdLine, c_szTroublshootCmdLine); fResult = CreateProcess( NULL, szCmdLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); if (fResult) { CloseHandle(pi.hThread); CloseHandle(pi.hProcess); } return 0; } DWORD HandleShow( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone ) /*++ Routine Description Handles the Show command Arguments none Return Value none --*/ { WCHAR *pszwVerbose = NULL; WCHAR *pszwInstance = NULL; BOOLEAN bFlags = FLAG_VERBOSE_LOW; // Need three arguments (show,netdiag catagory) // if( lstrcmpi(ppwcArguments[2], CMD_ADAPTER) == 0 || lstrcmpi(ppwcArguments[2], CMD_MODEM) == 0 || lstrcmpi(ppwcArguments[2], CMD_CLIENT) == 0 || lstrcmpi(ppwcArguments[2], CMD_WINS) == 0 || lstrcmpi(ppwcArguments[2], CMD_DHCP) == 0 || lstrcmpi(ppwcArguments[2], CMD_DNS) == 0 || lstrcmpi(ppwcArguments[2], CMD_IP) == 0 || lstrcmpi(ppwcArguments[2], CMD_GATEWAY) == 0 ) { switch(dwArgCount) { case 5: if( lstrcmpi(ppwcArguments[3],SWITCH_VERBOSE) == 0 || lstrcmpi(ppwcArguments[3],SWITCH_PROPERTIES) == 0 ) { // Has first the switch then the instance // pszwVerbose = ppwcArguments[3]; pszwInstance = ppwcArguments[4]; } else if( lstrcmpi(ppwcArguments[4],SWITCH_VERBOSE) == 0 || lstrcmpi(ppwcArguments[4],SWITCH_PROPERTIES) == 0 ) { // Has first the instance and then the switch // pszwVerbose = ppwcArguments[4]; pszwInstance = ppwcArguments[3]; } else { // Invalid number of arguments // return ERROR_INVALID_SYNTAX; } break; case 4: if( lstrcmpi(ppwcArguments[3],SWITCH_VERBOSE) == 0 || lstrcmpi(ppwcArguments[3],SWITCH_PROPERTIES) == 0) { pszwVerbose = ppwcArguments[3]; } else { // Has na instance but no swicth // pszwInstance = ppwcArguments[3]; } break; case 3: // No instance and no switch // break; default: // Invalid number of arguments // return ERROR_INVALID_SYNTAX; } } else if( dwArgCount == 4 && (lstrcmpi(ppwcArguments[3],SWITCH_VERBOSE) == 0 || lstrcmpi(ppwcArguments[3],SWITCH_PROPERTIES) == 0)) { // Has a switch // pszwVerbose = ppwcArguments[3]; } else if( dwArgCount == 4 && lstrcmpi(ppwcArguments[3],SWITCH_PROPERTIES) == 0) { // Has a switch // pszwVerbose = ppwcArguments[3]; } else if( dwArgCount != 3 ) { // Invalid number of arguments // return ERROR_INVALID_SYNTAX; } if( pszwVerbose ) { if( lstrcmpi(pszwVerbose,SWITCH_VERBOSE) == 0 ) { bFlags = FLAG_VERBOSE_HIGH; } if( lstrcmpi(pszwVerbose,SWITCH_PROPERTIES) == 0 ) { bFlags = FLAG_VERBOSE_MEDIUM; } } g_pDiagnostics->ExecQuery(ppwcArguments[2], (bFlags | FLAG_CMD_SHOW) ,pszwInstance); return 0; } DWORD HandlePing( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone ) /*++ Routine Description Handles the Ping command Arguments none Return Value none --*/ { WCHAR *pszwInstance = NULL; // ERROR_INVALID_SYNTAX; if( lstrcmpi(ppwcArguments[2],CMD_ADAPTER) == 0 || lstrcmpi(ppwcArguments[2],CMD_WINS) == 0 || lstrcmpi(ppwcArguments[2],CMD_DHCP) == 0 || lstrcmpi(ppwcArguments[2],CMD_DNS) == 0 || lstrcmpi(ppwcArguments[2],CMD_IP) == 0 || lstrcmpi(ppwcArguments[2],CMD_GATEWAY) == 0 ) { switch(dwArgCount) { case 4: pszwInstance = ppwcArguments[3]; break; case 3: break; default: // Invalid number of arguments // return ERROR_INVALID_SYNTAX; } } else if( lstrcmpi(ppwcArguments[2], CMD_IPHOST) == 0 ) { if( dwArgCount == 4 ) { // The IP host name/Address // pszwInstance = ppwcArguments[3]; } else { // Invalid number of arguments // return ERROR_INVALID_SYNTAX; } } else if( dwArgCount != 3 ) { // Invalid number of arguments // return ERROR_INVALID_SYNTAX; } // Ping the catagory // g_pDiagnostics->ExecQuery(ppwcArguments[2], (FLAG_VERBOSE_MEDIUM | FLAG_CMD_PING) ,pszwInstance); return 0; } DWORD HandleConnect( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone ) /*++ Routine Description Handles the connect command Arguments none Return Value none --*/ { WCHAR *pszwIPHost = NULL; WCHAR *pszwPort = NULL; if( lstrcmpi(ppwcArguments[2],CMD_IPHOST) == 0 ) { // IPhost // if( dwArgCount == 5 ) { // IP host name/Address // pszwIPHost = ppwcArguments[3]; pszwPort = ppwcArguments[4]; } else { // Invalid number of arguments // return ERROR_INVALID_SYNTAX; } } else if( dwArgCount != 3 ) { // Invalid number of arguments // return ERROR_INVALID_SYNTAX; } // Establish the TCP connection // g_pDiagnostics->ExecQuery(ppwcArguments[2], (FLAG_VERBOSE_MEDIUM | FLAG_CMD_CONNECT) ,pszwIPHost, pszwPort); return 0; } DWORD WINAPI SampleDump( IN LPCWSTR pwszRouter, IN OUT LPWSTR *ppwcArguments, IN DWORD dwArgCount, IN LPCVOID pvData ) /*++ Routine Description No Idea what this function is for, but it looks like I need it for something Arguments none Return Value none --*/ { return NO_ERROR; }