|
|
/*++
Copyright (c) 2000 Microsoft Corporation
Abstract:
Port Proxy Helper.
--*/ #include "precomp.h"
GUID g_PpGuid = PORTPROXY_GUID;
#define KEY_PORTS L"System\\CurrentControlSet\\Services\\PortProxy"
typedef enum { V4TOV4, V4TOV6, V6TOV4, V6TOV6 } PPTYPE, *PPPTYPE;
typedef struct { PWCHAR Token; PWCHAR ListenFamily; PWCHAR ConnectFamily; PWCHAR KeyString; } PPTYPEINFO, *PPPTYPEINFO;
#define IPV4_STR L"IPv4"
#define IPV6_STR L"IPv6"
PPTYPEINFO PpTypeInfo[] = { { CMD_V4TOV4, IPV4_STR, IPV4_STR, KEY_PORTS L"\\" CMD_V4TOV4 }, { CMD_V4TOV6, IPV4_STR, IPV6_STR, KEY_PORTS L"\\" CMD_V4TOV6 }, { CMD_V6TOV4, IPV6_STR, IPV4_STR, KEY_PORTS L"\\" CMD_V6TOV4 }, { CMD_V6TOV6, IPV6_STR, IPV6_STR, KEY_PORTS L"\\" CMD_V6TOV6 }, };
//
// Port Proxy commands.
//
FN_HANDLE_CMD PpHandleReset;
FN_HANDLE_CMD PpHandleDelV4ToV4; FN_HANDLE_CMD PpHandleDelV4ToV6; FN_HANDLE_CMD PpHandleDelV6ToV4; FN_HANDLE_CMD PpHandleDelV6ToV6;
FN_HANDLE_CMD PpHandleAddSetV4ToV4; FN_HANDLE_CMD PpHandleAddSetV4ToV6; FN_HANDLE_CMD PpHandleAddSetV6ToV4; FN_HANDLE_CMD PpHandleAddSetV6ToV6;
FN_HANDLE_CMD PpHandleShowAll; FN_HANDLE_CMD PpHandleShowV4ToV4; FN_HANDLE_CMD PpHandleShowV4ToV6; FN_HANDLE_CMD PpHandleShowV6ToV4; FN_HANDLE_CMD PpHandleShowV6ToV6;
CMD_ENTRY g_PpAddCmdTable[] = { CREATE_UNDOCUMENTED_CMD_ENTRY(PP_ADD_V4TOV4, PpHandleAddSetV4ToV4), CREATE_UNDOCUMENTED_CMD_ENTRY(PP_ADD_V4TOV6, PpHandleAddSetV4ToV6), CREATE_UNDOCUMENTED_CMD_ENTRY(PP_ADD_V6TOV4, PpHandleAddSetV6ToV4), CREATE_UNDOCUMENTED_CMD_ENTRY(PP_ADD_V6TOV6, PpHandleAddSetV6ToV6), };
CMD_ENTRY g_PpDelCmdTable[] = { CREATE_UNDOCUMENTED_CMD_ENTRY(PP_DEL_V4TOV4, PpHandleDelV4ToV4), CREATE_UNDOCUMENTED_CMD_ENTRY(PP_DEL_V4TOV6, PpHandleDelV4ToV6), CREATE_UNDOCUMENTED_CMD_ENTRY(PP_DEL_V6TOV4, PpHandleDelV6ToV4), CREATE_UNDOCUMENTED_CMD_ENTRY(PP_DEL_V6TOV6, PpHandleDelV6ToV6), };
CMD_ENTRY g_PpSetCmdTable[] = { CREATE_UNDOCUMENTED_CMD_ENTRY(PP_SET_V4TOV4, PpHandleAddSetV4ToV4), CREATE_UNDOCUMENTED_CMD_ENTRY(PP_SET_V4TOV6, PpHandleAddSetV4ToV6), CREATE_UNDOCUMENTED_CMD_ENTRY(PP_SET_V6TOV4, PpHandleAddSetV6ToV4), CREATE_UNDOCUMENTED_CMD_ENTRY(PP_SET_V6TOV6, PpHandleAddSetV6ToV6), };
CMD_ENTRY g_PpShowCmdTable[] = { CREATE_UNDOCUMENTED_CMD_ENTRY(PP_SHOW_ALL, PpHandleShowAll), CREATE_UNDOCUMENTED_CMD_ENTRY(PP_SHOW_V4TOV4, PpHandleShowV4ToV4), CREATE_UNDOCUMENTED_CMD_ENTRY(PP_SHOW_V4TOV6, PpHandleShowV4ToV6), CREATE_UNDOCUMENTED_CMD_ENTRY(PP_SHOW_V6TOV4, PpHandleShowV6ToV4), CREATE_UNDOCUMENTED_CMD_ENTRY(PP_SHOW_V6TOV6, PpHandleShowV6ToV6), };
CMD_GROUP_ENTRY g_PpCmdGroups[] = { CREATE_CMD_GROUP_ENTRY(GROUP_ADD, g_PpAddCmdTable), CREATE_CMD_GROUP_ENTRY(GROUP_DELETE, g_PpDelCmdTable), CREATE_CMD_GROUP_ENTRY(GROUP_SHOW, g_PpShowCmdTable), CREATE_CMD_GROUP_ENTRY(GROUP_SET, g_PpSetCmdTable), };
ULONG g_ulNumPpCmdGroups = sizeof(g_PpCmdGroups)/sizeof(CMD_GROUP_ENTRY);
CMD_ENTRY g_PpTopCmds[] = { CREATE_CMD_ENTRY(IPV6_RESET, PpHandleReset), };
ULONG g_ulNumPpTopCmds = sizeof(g_PpTopCmds)/sizeof(CMD_ENTRY);
DWORD WINAPI PpStartHelper( IN CONST GUID *pguidParent, IN DWORD dwParentVersion ) { DWORD dwErr; NS_CONTEXT_ATTRIBUTES attMyAttributes;
ZeroMemory(&attMyAttributes, sizeof(attMyAttributes));
attMyAttributes.pwszContext = L"portproxy"; attMyAttributes.guidHelper = g_PpGuid; attMyAttributes.dwVersion = PORTPROXY_HELPER_VERSION; attMyAttributes.dwFlags = CMD_FLAG_LOCAL | CMD_FLAG_ONLINE; attMyAttributes.pfnDumpFn = PpDump; attMyAttributes.ulNumTopCmds= g_ulNumPpTopCmds; attMyAttributes.pTopCmds = (CMD_ENTRY (*)[])&g_PpTopCmds; attMyAttributes.ulNumGroups = g_ulNumPpCmdGroups; attMyAttributes.pCmdGroups = (CMD_GROUP_ENTRY (*)[])&g_PpCmdGroups;
dwErr = RegisterContext( &attMyAttributes );
return dwErr; }
VOID ShowPorts( IN PPTYPE Type, IN FORMAT Format ) { ULONG Status, i, ListenChars, ConnectBytes, dwType; HKEY hType, hProto; WCHAR ListenBuffer[256], *ListenAddress, *ListenPort; WCHAR ConnectAddress[256], *ConnectPort;
Status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, PpTypeInfo[Type].KeyString, 0, KEY_QUERY_VALUE, &hType); if (Status != NO_ERROR) { return; } Status = RegOpenKeyEx(hType, TOKEN_VALUE_TCP, 0, KEY_QUERY_VALUE, &hProto); if (Status == NO_ERROR) { for (i=0; ; i++) { ListenChars = sizeof(ListenBuffer)/sizeof(WCHAR); ConnectBytes = sizeof(ConnectAddress); Status = RegEnumValueW(hProto, i, ListenBuffer, &ListenChars, NULL, &dwType, (PVOID)ConnectAddress, &ConnectBytes); if (Status != NO_ERROR) { break; }
if (dwType != REG_SZ) { continue; }
ListenPort = wcschr(ListenBuffer, L'/'); if (ListenPort) { //
// Replace slash with NULL, so we have 2 strings to pass
// to getaddrinfo.
//
ListenAddress = ListenBuffer; *ListenPort++ = L'\0'; } else { //
// If the address data didn't include a connect address
// use "*".
//
ListenAddress = L"*"; ListenPort = ListenBuffer; }
ConnectPort = wcschr(ConnectAddress, L'/'); if (ConnectPort) { //
// Replace slash with NULL, so we have 2 strings to pass
// to getaddrinfo.
//
*ConnectPort++ = L'\0'; } else { //
// If the address data didn't include a connect port
// number, use the same port as the listen port number.
//
ConnectPort = ListenPort; }
if (Format == FORMAT_NORMAL) { if (i==0) { // DisplayMessage(g_hModule, MSG_PORT_PROXY_HEADER,
// PpTypeInfo[Type].ListenFamily,
// PpTypeInfo[Type].ConnectFamily);
} // DisplayMessage(g_hModule, MSG_PORT_PROXY, ListenAddress,
// ListenPort, ConnectAddress, ConnectPort);
} else { DisplayMessageT(DMP_ADD_PORT_PROXY, PpTypeInfo[Type].Token); DisplayMessageT(DMP_STRING_ARG, TOKEN_LISTENPORT, ListenPort); DisplayMessageT(DMP_STRING_ARG, TOKEN_CONNECTADDRESS, ConnectAddress); DisplayMessageT(DMP_STRING_ARG, TOKEN_CONNECTPORT, ConnectPort); DisplayMessageT(DMP_NEWLINE); } } RegCloseKey(hProto); } RegCloseKey(hType); }
ULONG PpHandleShowV4ToV4( IN LPCWSTR MachineName, IN LPWSTR *Argv, IN ULONG CurrentIndex, IN ULONG Argc, IN ULONG Flags, IN LPCVOID Data, OUT BOOL *Done ) { ShowPorts(V4TOV4, FORMAT_NORMAL);
return STATUS_SUCCESS; }
ULONG PpHandleShowV6ToV4( IN LPCWSTR MachineName, IN LPWSTR *Argv, IN ULONG CurrentIndex, IN ULONG Argc, IN ULONG Flags, IN LPCVOID Data, OUT BOOL *Done ) { ShowPorts(V6TOV4, FORMAT_NORMAL);
return STATUS_SUCCESS; }
ULONG PpHandleShowV4ToV6( IN LPCWSTR MachineName, IN LPWSTR *Argv, IN ULONG CurrentIndex, IN ULONG Argc, IN ULONG Flags, IN LPCVOID Data, OUT BOOL *Done ) { ShowPorts(V4TOV6, FORMAT_NORMAL);
return STATUS_SUCCESS; }
ULONG PpHandleShowV6ToV6( IN LPCWSTR MachineName, IN LPWSTR *Argv, IN ULONG CurrentIndex, IN ULONG Argc, IN ULONG Flags, IN LPCVOID Data, OUT BOOL *Done ) { ShowPorts(V6TOV6, FORMAT_NORMAL);
return STATUS_SUCCESS; }
ULONG PpHandleShowAll( IN LPCWSTR MachineName, IN LPWSTR *Argv, IN ULONG CurrentIndex, IN ULONG Argc, IN ULONG Flags, IN LPCVOID Data, OUT BOOL *Done ) { ShowPorts(V4TOV4, FORMAT_NORMAL); ShowPorts(V4TOV6, FORMAT_NORMAL); ShowPorts(V6TOV4, FORMAT_NORMAL); ShowPorts(V6TOV6, FORMAT_NORMAL);
return STATUS_SUCCESS; }
PWCHAR PpFormValue( IN PWCHAR Address, IN PWCHAR Port ) { ULONG Length; PWCHAR Value;
Length = wcslen(Address) + wcslen(Port) + 2; Value = MALLOC(Length * sizeof(WCHAR));
swprintf(Value, L"%s/%s", Address, Port);
return Value; }
TOKEN_VALUE g_ProtocolEnum[] = {{ TOKEN_VALUE_TCP, IPPROTO_TCP }};
ULONG PpHandleAddSetPort( IN PPTYPE Type, IN LPWSTR *Argv, IN ULONG CurrentIndex, IN ULONG Argc ) { ULONG Status, i; TAG_TYPE Tags[] = {{TOKEN_LISTENPORT, NS_REQ_PRESENT, FALSE}, {TOKEN_CONNECTADDRESS, NS_REQ_ZERO, FALSE}, {TOKEN_CONNECTPORT, NS_REQ_ZERO, FALSE}, {TOKEN_LISTENADDRESS, NS_REQ_ZERO, FALSE}, {TOKEN_PROTOCOL, NS_REQ_ZERO, FALSE}}; ULONG TagType[sizeof(Tags)/sizeof(TAG_TYPE)]; PWCHAR ListenAddress = NULL, ListenPort = NULL; PWCHAR ConnectAddress = NULL, ConnectPort = NULL; PWCHAR ProtocolString = NULL; ULONG Protocol = IPPROTO_TCP; PWCHAR KeyValue, KeyData; HKEY hType, hProto;
if ((Type == V4TOV4) || (Type == V6TOV6)) { Tags[1].dwRequired = NS_REQ_PRESENT; }
Status = PreprocessCommand(g_hModule, Argv, CurrentIndex, Argc, Tags, sizeof(Tags)/sizeof(TAG_TYPE), 0, sizeof(Tags)/sizeof(TAG_TYPE), TagType);
for (i=0; (Status == NO_ERROR) && (i < Argc-CurrentIndex); i++) { switch (TagType[i]) { case 0: // LISTENPORT
ListenPort = Argv[CurrentIndex + i]; break;
case 1: // CONNECTADDRESS
ConnectAddress = Argv[CurrentIndex + i]; break;
case 2: // CONNECTPORT
ConnectPort = Argv[CurrentIndex + i]; break;
case 3: // LISTENADDRESS
ListenAddress = Argv[CurrentIndex + i]; break;
case 4: // PROTOCOL
Status = MatchEnumTag(NULL, Argv[CurrentIndex + i], NUM_TOKENS_IN_TABLE(g_ProtocolEnum), g_ProtocolEnum, (PULONG)&Protocol); if (Status != NO_ERROR) { Status = ERROR_INVALID_PARAMETER; } ProtocolString = Argv[CurrentIndex + i]; break;
default: Status = ERROR_INVALID_SYNTAX; break; } }
if (Status != NO_ERROR) { return Status; }
if (ConnectAddress == NULL) { ConnectAddress = L"localhost"; } if (ListenAddress == NULL) { ListenAddress = L"*"; } if (ProtocolString == NULL) { ProtocolString = TOKEN_VALUE_TCP; } if (ConnectPort == NULL) { ConnectPort = ListenPort; }
Status = RegCreateKeyEx(HKEY_LOCAL_MACHINE, PpTypeInfo[Type].KeyString, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hType, NULL); if (Status != NO_ERROR) { return Status; }
Status = RegCreateKeyEx(hType, ProtocolString, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hProto, NULL); if (Status != NO_ERROR) { RegCloseKey(hType); return Status; }
KeyValue = PpFormValue(ListenAddress, ListenPort); KeyData = PpFormValue(ConnectAddress, ConnectPort); if (KeyValue && KeyData) { Status = RegSetValueEx(hProto, KeyValue, 0, REG_SZ, (PVOID)KeyData, wcslen(KeyData) * sizeof(WCHAR)); FREE(KeyValue); }
RegCloseKey(hProto); RegCloseKey(hType);
Ip6to4PokeService();
return Status; }
ULONG PpHandleDeletePort( IN PPTYPE Type, IN LPWSTR *Argv, IN ULONG CurrentIndex, IN ULONG Argc ) { ULONG Status, i; TAG_TYPE Tags[] = {{TOKEN_LISTENPORT, NS_REQ_PRESENT, FALSE}, {TOKEN_LISTENADDRESS, NS_REQ_ZERO, FALSE}, {TOKEN_PROTOCOL, NS_REQ_ZERO, FALSE}}; ULONG TagType[sizeof(Tags)/sizeof(TAG_TYPE)]; PWCHAR ListenAddress = NULL, ListenPort = NULL; PWCHAR ConnectAddress = NULL, ConnectPort = NULL; ULONG Protocol; PWCHAR ProtocolString = NULL; HKEY hType, hProto; PWCHAR Value;
Status = PreprocessCommand(g_hModule, Argv, CurrentIndex, Argc, Tags, sizeof(Tags)/sizeof(TAG_TYPE), 0, sizeof(Tags)/sizeof(TAG_TYPE), TagType);
for (i=0; (Status == NO_ERROR) && (i < Argc-CurrentIndex); i++) { switch (TagType[i]) { case 0: // LISTENPORT
ListenPort = Argv[CurrentIndex + i]; break;
case 1: // LISTENADDRESS
ListenAddress = Argv[CurrentIndex + i]; break;
case 2: // PROTOCOL
Status = MatchEnumTag(NULL, Argv[CurrentIndex + i], NUM_TOKENS_IN_TABLE(g_ProtocolEnum), g_ProtocolEnum, (PULONG)&Protocol); if (Status != NO_ERROR) { Status = ERROR_INVALID_PARAMETER; } ProtocolString = Argv[CurrentIndex + i]; break;
default: Status = ERROR_INVALID_SYNTAX; break; } }
if (Status != NO_ERROR) { return Status; }
if (ListenAddress == NULL) { ListenAddress = L"*"; }
if (ProtocolString == NULL) { ProtocolString = TOKEN_VALUE_TCP; }
Status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, PpTypeInfo[Type].KeyString, 0, KEY_ALL_ACCESS, &hType); if (Status != NO_ERROR) { return Status; }
Status = RegOpenKeyEx(hType, ProtocolString, 0, KEY_ALL_ACCESS, &hProto); if (Status != NO_ERROR) { RegCloseKey(hType); return Status; }
Value = PpFormValue(ListenAddress, ListenPort); if (Value) { Status = RegDeleteValue(hProto, Value); FREE(Value); }
RegCloseKey(hProto); RegCloseKey(hType);
Ip6to4PokeService();
return Status; }
ULONG PpHandleDelV4ToV4( IN LPCWSTR MachineName, IN LPWSTR *Argv, IN ULONG CurrentIndex, IN ULONG Argc, IN ULONG Flags, IN LPCVOID Data, OUT BOOL *Done ) { return PpHandleDeletePort(V4TOV4, Argv, CurrentIndex, Argc); }
ULONG PpHandleDelV4ToV6( IN LPCWSTR MachineName, IN LPWSTR *Argv, IN ULONG CurrentIndex, IN ULONG Argc, IN ULONG Flags, IN LPCVOID Data, OUT BOOL *Done ) { return PpHandleDeletePort(V4TOV6, Argv, CurrentIndex, Argc); }
ULONG PpHandleDelV6ToV4( IN LPCWSTR MachineName, IN LPWSTR *Argv, IN ULONG CurrentIndex, IN ULONG Argc, IN ULONG Flags, IN LPCVOID Data, OUT BOOL *Done ) { return PpHandleDeletePort(V6TOV4, Argv, CurrentIndex, Argc); }
ULONG PpHandleDelV6ToV6( IN LPCWSTR MachineName, IN LPWSTR *Argv, IN ULONG CurrentIndex, IN ULONG Argc, IN ULONG Flags, IN LPCVOID Data, OUT BOOL *Done ) { return PpHandleDeletePort(V6TOV6, Argv, CurrentIndex, Argc); }
ULONG PpHandleAddSetV4ToV4( IN LPCWSTR MachineName, IN LPWSTR *Argv, IN ULONG CurrentIndex, IN ULONG Argc, IN ULONG Flags, IN LPCVOID Data, OUT BOOL *Done ) { return PpHandleAddSetPort(V4TOV4, Argv, CurrentIndex, Argc); }
ULONG PpHandleAddSetV4ToV6( IN LPCWSTR MachineName, IN LPWSTR *Argv, IN ULONG CurrentIndex, IN ULONG Argc, IN ULONG Flags, IN LPCVOID Data, OUT BOOL *Done ) { return PpHandleAddSetPort(V4TOV6, Argv, CurrentIndex, Argc); }
ULONG PpHandleAddSetV6ToV4( IN LPCWSTR MachineName, IN LPWSTR *Argv, IN ULONG CurrentIndex, IN ULONG Argc, IN ULONG Flags, IN LPCVOID Data, OUT BOOL *Done ) { return PpHandleAddSetPort(V6TOV4, Argv, CurrentIndex, Argc); }
ULONG PpHandleAddSetV6ToV6( IN LPCWSTR MachineName, IN LPWSTR *Argv, IN ULONG CurrentIndex, IN ULONG Argc, IN ULONG Flags, IN LPCVOID Data, OUT BOOL *Done ) { return PpHandleAddSetPort(V6TOV6, Argv, CurrentIndex, Argc); }
VOID PpReset( IN PPTYPE Type ) { HKEY hType; ULONG Status;
Status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, PpTypeInfo[Type].KeyString, 0, KEY_ALL_ACCESS, &hType); if (Status != NO_ERROR) { return; }
SHDeleteKey(hType, TOKEN_VALUE_TCP);
RegCloseKey(hType);
Ip6to4PokeService(); }
ULONG PpHandleReset( IN LPCWSTR MachineName, IN LPWSTR *Argv, IN ULONG CurrentIndex, IN ULONG Argc, IN ULONG Flags, IN LPCVOID Data, OUT BOOL *Done ) { PpReset(V4TOV4); PpReset(V4TOV6); PpReset(V6TOV4); PpReset(V6TOV6);
return STATUS_SUCCESS; }
DWORD WINAPI PpDump( IN LPCWSTR pwszRouter, IN OUT LPWSTR *ppwcArguments, IN DWORD dwArgCount, IN LPCVOID pvData ) { // DisplayMessage(g_hModule, DMP_PP_HEADER_COMMENTS);
DisplayMessageT(DMP_PP_PUSHD);
ShowPorts(V4TOV4, FORMAT_DUMP); ShowPorts(V4TOV6, FORMAT_DUMP); ShowPorts(V6TOV4, FORMAT_DUMP); ShowPorts(V6TOV6, FORMAT_DUMP);
DisplayMessageT(DMP_PP_POPD); // DisplayMessage(g_hModule, DMP_PP_FOOTER_COMMENTS);
return NO_ERROR; }
|