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

#include "dglogsnetsh.h"
//#include <netsh.h>
// 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;
}