|
|
//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1998 - 2001
//
// File : bridge.cpp
//
// Contents : bridge context specific code
//
// Notes :
//
// Author : Raghu Gatta (rgatta) 11 May 2001
//
//----------------------------------------------------------------------------
#include "precomp.h"
#pragma hdrstop
const TCHAR c_stRegKeyBridgeAdapters[] = _T("SYSTEM\\CurrentControlSet\\Services\\Bridge\\Parameters\\Adapters"); const TCHAR c_stFCMode[] = _T("ForceCompatibilityMode");
CMD_ENTRY g_BridgeSetCmdTable[] = { CREATE_CMD_ENTRY(BRIDGE_SET_ADAPTER, HandleBridgeSetAdapter), };
CMD_ENTRY g_BridgeShowCmdTable[] = { CREATE_CMD_ENTRY(BRIDGE_SHOW_ADAPTER, HandleBridgeShowAdapter), };
CMD_GROUP_ENTRY g_BridgeCmdGroups[] = { CREATE_CMD_GROUP_ENTRY(GROUP_SET, g_BridgeSetCmdTable), CREATE_CMD_GROUP_ENTRY(GROUP_SHOW, g_BridgeShowCmdTable), };
ULONG g_ulBridgeNumGroups = sizeof(g_BridgeCmdGroups)/sizeof(CMD_GROUP_ENTRY);
CMD_ENTRY g_BridgeCmds[] = { CREATE_CMD_ENTRY(INSTALL, HandleBridgeInstall), CREATE_CMD_ENTRY(UNINSTALL, HandleBridgeUninstall), };
ULONG g_ulBridgeNumTopCmds = sizeof(g_BridgeCmds)/sizeof(CMD_ENTRY);
DWORD WINAPI BridgeDump( IN LPCWSTR pwszRouter, IN OUT LPWSTR *ppwcArguments, IN DWORD dwArgCount, IN LPCVOID pvData ) { //
// Output the string that shows our settings.
// The idea here is to spit out a script that,
// when run from the command line (netsh -f script)
// will cause your component to be configured
// exactly as it is when this dump command was run.
//
PrintMessageFromModule( g_hModule, DMP_BRIDGE_HEADER ); PrintMessageFromModule( g_hModule, DMP_BRIDGE_FOOTER );
return NO_ERROR; }
HRESULT HrCycleBridge( IHNetBridge *pIHNetBridge ) { HRESULT hr = S_OK; //
// Check to see if the bridge is up and running.
// If it is, then disable and reenable
//
do { //
// Get the pointer to IID_IHNetConnection interface of this
// bridged connection
//
CComPtr<IHNetConnection> spIHNConn;
hr = pIHNetBridge->QueryInterface( IID_PPV_ARG(IHNetConnection, &spIHNConn) );
assert(SUCCEEDED(hr)); if (FAILED(hr)) { break; }
INetConnection *pINetConn;
hr = spIHNConn->GetINetConnection(&pINetConn);
if (SUCCEEDED(hr)) { NETCON_PROPERTIES* pNCProps;
hr = pINetConn->GetProperties(&pNCProps);
if(SUCCEEDED(hr)) { //
// check status - restart only if already running
//
if (pNCProps->Status == NCS_CONNECTED || pNCProps->Status == NCS_CONNECTING) { pINetConn->Disconnect();
pINetConn->Connect(); } NcFreeNetconProperties(pNCProps); }
ReleaseObj(pINetConn); } } while(FALSE); return hr; }
DWORD SetBridgeAdapterInfo( DWORD adapterId, BOOL bFlag ) { DWORD dwErr = NO_ERROR; IHNetCfgMgr* pIHNetCfgMgr = NULL; HRESULT hr = S_OK;
hr = HrInitializeHomenetConfig( &g_fInitCom, &pIHNetCfgMgr );
if (SUCCEEDED(hr)) { //
// Get the IHNetBridgeSettings
//
CComPtr<IHNetBridgeSettings> spIHNetBridgeSettings;
hr = pIHNetCfgMgr->QueryInterface( IID_PPV_ARG(IHNetBridgeSettings, &spIHNetBridgeSettings) );
if (SUCCEEDED(hr)) { //
// Get the IEnumHNetBridges
//
CComPtr<IEnumHNetBridges> spehBridges;
if ((hr = spIHNetBridgeSettings->EnumBridges(&spehBridges)) == S_OK) { //
// Get the first IHNetBridge
//
CComPtr<IHNetBridge> spIHNetBridge;
if ((hr = spehBridges->Next(1, &spIHNetBridge, NULL)) == S_OK) { { //
// We currently should have only one bridge;
// this may change in the future. The
// code here is just to catch future instances
// where this function would have to change in case
// there is more than one bridge.
//
CComPtr<IHNetBridge> spIHNetBridge2;
if ((hr = spehBridges->Next(1, &spIHNetBridge2, NULL)) == S_OK) { assert(FALSE); } }
//
// Get the IEnumHNetBridgedConnections
//
CComPtr<IEnumHNetBridgedConnections> spehBrdgConns;
if ((hr = spIHNetBridge->EnumMembers(&spehBrdgConns)) == S_OK) { //
// enumerate all the IHNetBridgedConnections
//
DWORD id = 0; IHNetBridgedConnection* pIHNetBConn;
spehBrdgConns->Reset(); while (S_OK == spehBrdgConns->Next(1, &pIHNetBConn, NULL)) { id++;
if (id != adapterId) { //
// release the IHNetBridgedConnection
//
ReleaseObj(pIHNetBConn); continue; } //
// Get the pointer to IID_IHNetConnection interface of this
// bridged connection
//
CComPtr<IHNetConnection> spIHNConn;
hr = pIHNetBConn->QueryInterface( IID_PPV_ARG(IHNetConnection, &spIHNConn) ); assert(SUCCEEDED(hr)); if (SUCCEEDED(hr)) { GUID *pGuid = NULL;
hr = spIHNConn->GetGuid(&pGuid);
if (SUCCEEDED(hr) && (NULL != pGuid)) { PTCHAR pwszKey = NULL; int keyLen; TCHAR wszGuid[128]; HKEY hKey = NULL; DWORD dwDisp = 0; BOOL bCycleBridge = TRUE; DWORD dwOldValue; DWORD dwNewValue = (bFlag) ? 1 : 0;
do { ZeroMemory(wszGuid, sizeof(wszGuid));
StringFromGUID2( *pGuid, wszGuid, ARRAYSIZE(wszGuid) );
keyLen = _tcslen(c_stRegKeyBridgeAdapters) + _tcslen(_T("\\")) + _tcslen(wszGuid) + 1;
pwszKey = (TCHAR *) HeapAlloc( GetProcessHeap(), 0, keyLen * sizeof(TCHAR) ); if (!pwszKey) { break; }
ZeroMemory(pwszKey, sizeof(pwszKey)); _tcscpy(pwszKey, c_stRegKeyBridgeAdapters); _tcscat(pwszKey, _T("\\")); _tcscat(pwszKey, wszGuid);
dwErr = RegCreateKeyEx( HKEY_LOCAL_MACHINE, pwszKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &dwDisp );
if (ERROR_SUCCESS != dwErr) { break; }
//
// if the key was old, get its value
// and compare to see if we need to
// cycle the bridge
//
if (dwDisp && dwDisp == REG_OPENED_EXISTING_KEY) { DWORD dwSize = sizeof(dwOldValue); if (ERROR_SUCCESS == RegQueryValueEx( hKey, c_stFCMode, NULL, NULL, (LPBYTE)&dwOldValue, &dwSize)) { if (dwOldValue == dwNewValue) { //
// no need to cycle the bridge
//
bCycleBridge = FALSE; } } } dwErr = RegSetValueEx( hKey, c_stFCMode, 0, REG_DWORD, (LPBYTE) &dwNewValue, sizeof(dwNewValue) );
if (ERROR_SUCCESS != dwErr) { break; }
if (bCycleBridge) { //
// cycle the (respective) bridge
//
hr = HrCycleBridge( spIHNetBridge ); }
} while(FALSE);
//
// cleanup
//
if (hKey) { RegCloseKey(hKey); }
if (pwszKey) { HeapFree(GetProcessHeap(), 0, pwszKey); }
CoTaskMemFree(pGuid); } }
//
// release the IHNetBridgedConnection
//
ReleaseObj(pIHNetBConn);
break; } //while
} } } }
//
// we are done completely
//
hr = HrUninitializeHomenetConfig( g_fInitCom, pIHNetCfgMgr ); }
return (hr==S_OK) ? dwErr : hr; }
DWORD WINAPI HandleBridgeSetAdapter( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone ) { DWORD dwRet = NO_ERROR; PDWORD pdwTagType = NULL; DWORD dwNumOpt; DWORD dwNumArg; DWORD dwRes; DWORD dwErrIndex =-1, i;
//
// default values
//
DWORD id = 0; DWORD bFCMode = FALSE; TAG_TYPE pttTags[] = { {TOKEN_OPT_ID, NS_REQ_PRESENT, FALSE}, {TOKEN_OPT_FCMODE, NS_REQ_ZERO, FALSE} // not required to allow for
// addition of future flags
};
if (dwCurrentIndex >= dwArgCount) { // No arguments specified. At least interface name should be specified.
return ERROR_INVALID_SYNTAX; } dwNumArg = dwArgCount - dwCurrentIndex;
pdwTagType = (DWORD *) HeapAlloc( GetProcessHeap(), 0, dwNumArg * sizeof(DWORD) );
if (NULL == pdwTagType) { return ERROR_NOT_ENOUGH_MEMORY; }
dwRet = PreprocessCommand( g_hModule, ppwcArguments, dwCurrentIndex, dwArgCount, pttTags, ARRAYSIZE(pttTags), 1, // min args
2, // max args
pdwTagType );
if (NO_ERROR != dwRet) { HeapFree(GetProcessHeap(), 0, pdwTagType);
if (ERROR_INVALID_OPTION_TAG == dwRet) { return ERROR_INVALID_SYNTAX; }
return dwRet; }
for ( i = 0; i < dwNumArg; i++) { switch (pdwTagType[i]) { case 0: { //
// refers to the 'id' field
//
id = _tcstoul(ppwcArguments[dwCurrentIndex + i], NULL, 10); break; } case 1: { //
// refers to the 'forcecompatmode' field
// possible values are : enable or disable
//
TOKEN_VALUE rgEnums[] = { {TOKEN_OPT_VALUE_ENABLE, TRUE}, {TOKEN_OPT_VALUE_DISABLE, FALSE} }; dwRet = MatchEnumTag( g_hModule, ppwcArguments[i + dwCurrentIndex], ARRAYSIZE(rgEnums), rgEnums, &dwRes );
if (dwRet != NO_ERROR) { dwErrIndex = i; i = dwNumArg; dwRet = ERROR_INVALID_PARAMETER; break; }
switch (dwRes) { case 0: bFCMode = FALSE; break;
case 1: bFCMode = TRUE; break; }
break; } default: { i = dwNumArg; dwRet = ERROR_INVALID_PARAMETER; break; } } //switch
if (dwRet != NO_ERROR) { break ; } } //for
//
// adapter id MUST be present
//
if (!pttTags[0].bPresent) { dwRet = ERROR_INVALID_SYNTAX; }
switch(dwRet) { case NO_ERROR: break;
case ERROR_INVALID_PARAMETER: if (dwErrIndex != -1) { PrintError( g_hModule, EMSG_BAD_OPTION_VALUE, ppwcArguments[dwErrIndex + dwCurrentIndex], pttTags[pdwTagType[dwErrIndex]].pwszTag ); } dwRet = ERROR_SUPPRESS_OUTPUT; break; default: //
// error message already printed
//
break; }
if (pdwTagType) { HeapFree(GetProcessHeap(), 0, pdwTagType); }
if (NO_ERROR != dwRet) { return dwRet; }
//
// we have the requisite info - process them
//
//
// since we may or may not have flag info, check for it
//
if (pttTags[1].bPresent) { dwRet = SetBridgeAdapterInfo( id, bFCMode ); }
return dwRet; }
DWORD ShowBridgeAdapterInfo( DWORD id, IHNetConnection *pIHNConn ) { HRESULT hr;
//
// print out the bridged connections details
//
PWSTR pwszName = NULL; PWSTR pwszState = NULL; hr = pIHNConn->GetName(&pwszName);
if (SUCCEEDED(hr) && (NULL != pwszName)) { GUID *pGuid = NULL;
hr = pIHNConn->GetGuid(&pGuid);
if (SUCCEEDED(hr) && (NULL != pGuid)) { WCHAR wszGuid[128]; ZeroMemory(wszGuid, sizeof(wszGuid)); StringFromGUID2(*pGuid, wszGuid, ARRAYSIZE(wszGuid));
//
// check to see if registry settings present
//
// for forcecompatmode:
// + if key is not present --> disabled
// + if key is present
// 0x1 --> enabled
// 0x0 --> disabled
// + all other errors --> unknown
//
{ HKEY hBAKey; DWORD msgState = STRING_UNKNOWN;
if (ERROR_SUCCESS == RegOpenKeyEx( HKEY_LOCAL_MACHINE, c_stRegKeyBridgeAdapters, 0, KEY_READ, &hBAKey)) { HKEY hBCKey; if (ERROR_SUCCESS == RegOpenKeyEx( hBAKey, wszGuid, 0, KEY_READ, &hBCKey)) { DWORD dwFCModeState = 0; DWORD dwSize = sizeof(dwFCModeState); if (ERROR_SUCCESS == RegQueryValueEx( hBCKey, c_stFCMode, NULL, NULL, (LPBYTE)&dwFCModeState, &dwSize)) { switch (dwFCModeState) { case 0: msgState = STRING_DISABLED; break; case 1: msgState = STRING_ENABLED; break; default: msgState = STRING_UNKNOWN; } } else { //
// value not present
//
msgState = STRING_DISABLED; }
RegCloseKey(hBCKey); } else { //
// bridged connection guid key not present
//
msgState = STRING_DISABLED; }
RegCloseKey(hBAKey); }
pwszState = MakeString(g_hModule, msgState); }
PrintMessage( L" %1!2d! %2!-27s! %3!s!%n", id, pwszName, pwszState );
if (pwszState) { FreeString(pwszState); }
CoTaskMemFree(pGuid); }
CoTaskMemFree(pwszName); }
return NO_ERROR; }
DWORD ShowBridgeAllAdapterInfo( BOOL bShowAll, // TRUE to show all
DWORD adapterId // valid only if bShowAll is FALSE
) { IHNetCfgMgr* pIHNetCfgMgr = NULL; HRESULT hr = S_OK;
hr = HrInitializeHomenetConfig( &g_fInitCom, &pIHNetCfgMgr );
if (SUCCEEDED(hr)) { //
// Get the IHNetBridgeSettings
//
CComPtr<IHNetBridgeSettings> spIHNetBridgeSettings;
hr = pIHNetCfgMgr->QueryInterface( IID_PPV_ARG(IHNetBridgeSettings, &spIHNetBridgeSettings) );
if (SUCCEEDED(hr)) { //
// Get the IEnumHNetBridges
//
CComPtr<IEnumHNetBridges> spehBridges;
if ((hr = spIHNetBridgeSettings->EnumBridges(&spehBridges)) == S_OK) { //
// Get the first IHNetBridge
//
CComPtr<IHNetBridge> spIHNetBridge;
if ((hr = spehBridges->Next(1, &spIHNetBridge, NULL)) == S_OK) { { //
// We currently should have only one bridge;
// this may change in the future. The
// code here is just to catch future instances
// where this function would have to change in case
// there is more than one bridge.
//
CComPtr<IHNetBridge> spIHNetBridge2;
if ((hr = spehBridges->Next(1, &spIHNetBridge2, NULL)) == S_OK) { assert(FALSE); } }
//
// Get the IEnumHNetBridgedConnections
//
CComPtr<IEnumHNetBridgedConnections> spehBrdgConns;
if ((hr = spIHNetBridge->EnumMembers(&spehBrdgConns)) == S_OK) { //
// spit out header for displaying the list
//
PrintMessageFromModule( g_hModule, MSG_BRIDGE_ADAPTER_INFO_HDR ); //
// enumerate all the IHNetBridgedConnections
//
DWORD id = 0; IHNetBridgedConnection* pIHNetBConn;
spehBrdgConns->Reset(); while (S_OK == spehBrdgConns->Next(1, &pIHNetBConn, NULL)) { id++;
//
// check if we are looking for a specific id
//
if (FALSE == bShowAll && id != adapterId) { //
// release the IHNetBridgedConnection
//
ReleaseObj(pIHNetBConn); continue; } //
// Get the pointer to IID_IHNetConnection interface of this
// bridged connection
//
CComPtr<IHNetConnection> spIHNConn;
hr = pIHNetBConn->QueryInterface( IID_PPV_ARG(IHNetConnection, &spIHNConn) ); assert(SUCCEEDED(hr)); if (SUCCEEDED(hr)) { ShowBridgeAdapterInfo( id, spIHNConn ); }
//
// release the IHNetBridgedConnection
//
ReleaseObj(pIHNetBConn);
//
// if we reached here and we were looking for a
// specific id, our work is done - break out
//
if (FALSE == bShowAll) { break; } }
//
// spit out footer for displaying the list
//
PrintMessageFromModule( g_hModule, TABLE_SEPARATOR ); } } } }
//
// we are done completely
//
hr = HrUninitializeHomenetConfig( g_fInitCom, pIHNetCfgMgr ); }
return (hr==S_OK) ? NO_ERROR : hr;
}
DWORD WINAPI HandleBridgeShowAdapter( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone ) /*++
Routine Description:
Gets options for showing bridge adapter info
Arguements:
ppwcArguments - Argument array dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg
Return Value:
NO_ERROR --*/ { IHNetCfgMgr* pIHNetCfgMgr = NULL; HRESULT hr = S_OK; BOOL bShowAll = FALSE; DWORD id = 0, i, dwRet = NO_ERROR, dwNumOpt, dwNumArg, dwSize, dwRes; PDWORD pdwTagType = NULL;
TAG_TYPE pttTags[] = { {TOKEN_OPT_ID, NS_REQ_ZERO, FALSE} };
if (dwCurrentIndex > dwArgCount) { //
// No arguments specified
//
return ERROR_INVALID_SYNTAX; }
if (dwCurrentIndex == dwArgCount) { bShowAll = TRUE; }
dwNumArg = dwArgCount - dwCurrentIndex;
pdwTagType = (DWORD *) HeapAlloc( GetProcessHeap(), 0, dwNumArg * sizeof(DWORD) );
if (dwNumArg && NULL == pdwTagType) { return ERROR_NOT_ENOUGH_MEMORY; }
dwRet = PreprocessCommand( g_hModule, ppwcArguments, dwCurrentIndex, dwArgCount, pttTags, ARRAYSIZE(pttTags), 0, // min args
1, // max args
pdwTagType );
if (NO_ERROR == dwRet) { //
// process each argument...
//
for (i = 0; i < (dwArgCount - dwCurrentIndex); i++) { //
// Check its corresponding value in the pdwTagType array.
//
switch (pdwTagType[i]) { case 0: //
// refers to the 'id' field
//
id = _tcstoul(ppwcArguments[dwCurrentIndex + i], NULL, 10); break; default: //
// Since there is only one valid value, means the arg
// wasn't recognized. Shouldn't reach this point because
// PreprocessCommand wouldn't have returned NO_ERROR if
// this was the case.
//
dwRet = ERROR_INVALID_SYNTAX; break; } }
dwRet = ShowBridgeAllAdapterInfo( bShowAll, id ) ; } else { dwRet = ERROR_SHOW_USAGE; }
//
// cleanup
//
if (pdwTagType) { HeapFree(GetProcessHeap(), 0, pdwTagType); }
return dwRet; }
DWORD WINAPI HandleBridgeInstall( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone ) {
PrintMessageFromModule( g_hModule, HLP_BRIDGE_USE_GUI, CMD_INSTALL );
return NO_ERROR; }
DWORD WINAPI HandleBridgeUninstall( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone ) { PrintMessageFromModule( g_hModule, HLP_BRIDGE_USE_GUI, CMD_UNINSTALL );
return NO_ERROR; }
|