|
|
/*
File netcfgdb.c
Implements a database abstraction on top of the net config items needed by the ras server ui for connections.
Paul Mayfield, 12/15/97 */
#include <rassrv.h>
#include "protedit.h"
// Macro for bounds checking
#define netDbBoundsCheck(db, ind) (((ind) < (db)->dwCompCount) ? TRUE : FALSE)
//
// Defines function that sends pnp event through ndis
//
typedef UINT (* pNdisHandlePnpEventFunc)( IN UINT Layer, IN UINT Operation, IN PUNICODE_STRING LowerComponent, IN PUNICODE_STRING UpperComponent, IN PUNICODE_STRING BindList, IN PVOID ReConfigBuffer, IN UINT ReConfigBufferSize);
//
// Maps a protocol string to its integer id
//
typedef struct _COMP_MAPPING { LPCTSTR pszId; DWORD dwId;
} COMP_MAPPING;
//
// Defines attributes of a network component
//
typedef struct _RASSRV_NET_COMPONENT { DWORD dwType; // Is it client/service/protocol
PWCHAR pszName; // Display name
PWCHAR pszDesc; // Display description
PWCHAR pszId; // Id to destinguish which client/service, etc
BOOL bManip; // Whether is manipulatable by ras (ip, ipx, etc.)
BOOL bHasUi; // For whether has properties ui (non-manip only)
INetCfgComponent * pINetCfgComp;
// The following fields only apply to manipulatable
// components (bManip == TRUE)
//
DWORD dwId; // DWORD counterpart to pszId.
BOOL bEnabled; // whether it is enabled for dialin
BOOL bEnabledOrig; // original value of bEnabled (optimization)
BOOL bExposes; // whether it exposes the network its on
LPBYTE pbData; // pointer to protocol specific data
BOOL bDataDirty; // should the protocol specific data be flushed?
//For whistler bug 347355
//
BOOL bRemovable; //If this component removable //TCP/IP is not user removable
} RASSRV_NET_COMPONENT;
//
// Defines attributes of a network component database
//
typedef struct _RASSRV_COMPONENT_DB { INetCfg * pINetCfg; BOOL bHasINetCfgLock; BOOL bInitCom; DWORD dwCompCount; BOOL bFlushOnClose; RASSRV_NET_COMPONENT ** pComps; PWCHAR pszClientName; INetConnectionUiUtilities * pNetConUtilities;
} RASSRV_COMPONENT_DB;
//
// Definitions of functions taken from ndis
//
const static WCHAR pszNdispnpLib[] = L"ndispnp.dll"; const static CHAR pszNidspnpFunc[] = "NdisHandlePnPEvent";
// Parameters for the protocols
const static WCHAR pszRemoteAccessParamStub[] = L"SYSTEM\\CurrentControlSet\\Services\\RemoteAccess\\Parameters\\"; static WCHAR pszIpParams[] = L"Ip"; static WCHAR pszIpxParams[] = L"Ipx"; static WCHAR pszNetBuiParams[] = L"Nbf"; static WCHAR pszArapParams[] = L"AppleTalk"; static WCHAR pszShowNetworkToClients[] = L"AllowNetworkAccess"; static WCHAR pszShowNetworkArap[] = L"NetworkAccess"; static WCHAR pszEnableForDialin[] = L"EnableIn"; static WCHAR pszIpPoolSubKey[] = L"\\StaticAddressPool\\0";
// Ip specific registry parameters
const static WCHAR pszIpFrom[] = L"From"; const static WCHAR pszIpTo[] = L"To"; const static WCHAR pszIpAddress[] = L"IpAddress"; const static WCHAR pszIpMask[] = L"IpMask"; const static WCHAR pszIpClientSpec[] = L"AllowClientIpAddresses"; const static WCHAR pszIpShowNetworkToClients[] = L"AllowNetworkAccess"; const static WCHAR pszIpUseDhcp[] = L"UseDhcpAddressing";
// Ipx specific registry paramters
const static WCHAR pszIpxAddress[] = L"FirstWanNet"; const static WCHAR pszIpxClientSpec[] = L"AcceptRemoteNodeNumber"; const static WCHAR pszIpxAutoAssign[] = L"AutoWanNetAllocation"; const static WCHAR pszIpxAssignSame[] = L"GlobalWanNet";
// Tcp specific registry parameters
const static WCHAR pszTcpipParamsKey[] = L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\"; const static WCHAR pszTcpEnableRouter[] = L"IPEnableRouter";
const static WCHAR pszEmptyString[] = L"";
//
// Initializes a unicode string
//
VOID SetUnicodeString ( IN OUT UNICODE_STRING* pustr, IN LPCWSTR psz ) { pustr->Buffer = (PWSTR)(psz); pustr->Length = (USHORT)(lstrlenW(pustr->Buffer) * sizeof(WCHAR)); pustr->MaximumLength = pustr->Length + sizeof(WCHAR); }
//
// Sets the expose property of a protocol
//
DWORD protSetExpose( IN BOOL bExposes, IN DWORD dwId) { PWCHAR pszProtocol = NULL, pszKey = NULL; PWCHAR pszAccess = pszShowNetworkToClients; DWORD dwErr; WCHAR pszProtKey[1024];
bExposes = (bExposes) ? 1 : 0;
// Base the registry location on the
// id of the protocol
switch (dwId) { case NETCFGDB_ID_IP: pszProtocol = (PWCHAR)pszIpParams; break;
case NETCFGDB_ID_IPX: pszProtocol = (PWCHAR)pszIpxParams; break;
case NETCFGDB_ID_NETBUI: pszProtocol = (PWCHAR)pszNetBuiParams; break;
case NETCFGDB_ID_ARAP: pszProtocol = (PWCHAR)pszArapParams; pszAccess = (PWCHAR)pszShowNetworkArap; break;
default: return ERROR_CAN_NOT_COMPLETE; }
// Generate the registry key
//
wsprintfW(pszProtKey, L"%s%s", pszRemoteAccessParamStub, pszProtocol); if (! pszKey) { pszKey = pszProtKey; }
// Set the value and return
//
dwErr = RassrvRegSetDw(bExposes, pszKey, pszAccess);
return dwErr; }
//
// Gets the expose property of a protocol
//
DWORD protGetExpose( OUT BOOL* pbExposed, IN DWORD dwId) { PWCHAR pszProtocol = NULL, pszKey = NULL; PWCHAR pszAccess = pszShowNetworkToClients; DWORD dwErr; WCHAR pszProtKey[1024];
switch (dwId) { case NETCFGDB_ID_IP: pszProtocol = (PWCHAR)pszIpParams; break;
case NETCFGDB_ID_IPX: pszProtocol = (PWCHAR)pszIpxParams; break;
case NETCFGDB_ID_NETBUI: pszProtocol = (PWCHAR)pszNetBuiParams; break;
case NETCFGDB_ID_ARAP: pszProtocol = (PWCHAR)pszArapParams; pszAccess = (PWCHAR)pszShowNetworkArap; break;
default: return ERROR_CAN_NOT_COMPLETE; }
// Generate the registry key if needed
if (! pszKey) { wsprintfW( pszProtKey, L"%s%s", pszRemoteAccessParamStub, pszProtocol); pszKey = pszProtKey; }
// Get the value and return it
dwErr = RassrvRegGetDw(pbExposed, TRUE, pszKey, pszAccess);
return dwErr; }
//
// Sets the enable property of a protocol
//
DWORD protSetEnabling( IN BOOL bExposes, IN DWORD dwId) { PWCHAR pszProtocol = NULL; DWORD dwErr; bExposes = (bExposes) ? 1 : 0;
if (dwId == NETCFGDB_ID_IP) { pszProtocol = pszIpParams; } else if (dwId == NETCFGDB_ID_IPX) { pszProtocol = pszIpxParams; } else if (dwId == NETCFGDB_ID_NETBUI) { pszProtocol = pszNetBuiParams; } else if (dwId == NETCFGDB_ID_ARAP) { pszProtocol = pszArapParams; }
if (pszProtocol) { WCHAR pszProtKey[512];
wsprintfW( pszProtKey, L"%s%s", pszRemoteAccessParamStub, pszProtocol);
dwErr = RassrvRegSetDw(bExposes, pszProtKey, pszEnableForDialin); if (dwErr != NO_ERROR) { DbgOutputTrace( "protSetEnabling: Failed for %S: 0x%08x", pszProtocol, dwErr); }
return dwErr; }
return ERROR_CAN_NOT_COMPLETE; }
//
// Gets the Enabling property of a protocol
//
DWORD protGetEnabling( OUT BOOL* pbExposed, IN DWORD dwId) { PWCHAR pszProtocol = NULL; DWORD dwErr;
if (dwId == NETCFGDB_ID_IP) { pszProtocol = pszIpParams; } else if (dwId == NETCFGDB_ID_IPX) { pszProtocol = pszIpxParams; } else if (dwId == NETCFGDB_ID_NETBUI) { pszProtocol = pszNetBuiParams; } else if (dwId == NETCFGDB_ID_ARAP) { pszProtocol = pszArapParams; }
if (pszProtocol) { WCHAR pszProtKey[512];
wsprintfW( pszProtKey, L"%s%s", pszRemoteAccessParamStub, pszProtocol);
dwErr = RassrvRegGetDw( pbExposed, TRUE, pszProtKey, pszEnableForDialin); if (dwErr != NO_ERROR) { DbgOutputTrace( "protGetEnabling: Failed for %S: 0x%08x", pszProtocol, dwErr); }
return dwErr; }
return ERROR_CAN_NOT_COMPLETE; }
//
// Saves the enabling of a service out to the
// system.
//
DWORD svcSetEnabling( IN RASSRV_NET_COMPONENT* pComp) { HANDLE hService = NULL; DWORD dwErr = NO_ERROR;
do { // Or enable the component
//
if (pComp->bEnabled) { if (pComp->dwId == NETCFGDB_ID_FILEPRINT) { // Start the service
//
dwErr = SvcOpenServer(&hService); if (dwErr != NO_ERROR) { break; } dwErr = SvcStart(hService, 10); if (dwErr != NO_ERROR) { break; } } }
} while (FALSE);
// Cleanup
{ if (hService) { SvcClose(hService); } }
return dwErr; }
//
// Gets the enabling property of a service
//
DWORD svcGetEnabling( OUT BOOL* pbExposed, IN DWORD dwId) { HANDLE hService = NULL; DWORD dwErr = NO_ERROR;
do { dwErr = SvcOpenServer(&hService); if (dwErr != NO_ERROR) { break; } dwErr = SvcIsStarted(hService, pbExposed); if (dwErr != NO_ERROR) { break; }
} while (FALSE);
// Cleanup
{ if (hService) { SvcClose(hService); } }
return dwErr; }
//
// Loads the tcpip parameters from the system
//
DWORD TcpipLoadParamsFromSystem( OUT TCPIP_PARAMS *pTcpipParams) { WCHAR buf[256], pszKey[512]; DWORD dwRet = NO_ERROR, dwErr; DWORD dwNet = 0, dwMask = 0;
wsprintfW(pszKey, L"%s%s", pszRemoteAccessParamStub, pszIpParams);
// Load the params from the various registry locations.
dwErr = RassrvRegGetDw( &pTcpipParams->bUseDhcp, TRUE, pszKey, (const PWCHAR)pszIpUseDhcp); if (dwErr != NO_ERROR) { DbgOutputTrace("TcpipLoad: dhcp fail 0x%08x", dwErr); dwRet = dwErr; }
dwErr = RassrvRegGetDw( &pTcpipParams->bCaller, TRUE, pszKey, (const PWCHAR)pszIpClientSpec); if (dwErr != NO_ERROR) { DbgOutputTrace("TcpipLoad: clientspec fail 0x%08x", dwErr); dwRet = dwErr; }
// Read in the "legacy" pool values (w2k RC1, w2k Beta3)
//
{ WCHAR pszNet[256]=L"0.0.0.0", pszMask[256]=L"0.0.0.0"; RassrvRegGetStr( pszNet, L"0.0.0.0", pszKey, (PWCHAR)pszIpAddress); RassrvRegGetStr( pszMask, L"0.0.0.0", pszKey, (PWCHAR)pszIpMask);
dwNet = IpPszToHostAddr(pszNet); dwMask = IpPszToHostAddr(pszMask); }
// Generate the path the the new registry values
//
wcscat(pszKey, pszIpPoolSubKey);
// See if new info is stored by reading the "from"
// value
//
dwErr = RassrvRegGetDwEx( &pTcpipParams->dwPoolStart, 0, pszKey, (const PWCHAR)pszIpFrom, FALSE);
// There is new info in the registry -- use it
//
if (dwErr == ERROR_SUCCESS) { // Read in the "to" value
//
dwErr = RassrvRegGetDwEx( &pTcpipParams->dwPoolEnd, 0, pszKey, (const PWCHAR)pszIpTo, FALSE); if (dwErr != NO_ERROR) { DbgOutputTrace("TcpipLoad: mask fail 0x%08x", dwErr); dwRet = dwErr; } }
// There is not new data in the new section -- use legacy
// values
//
else if (dwErr == ERROR_FILE_NOT_FOUND) { pTcpipParams->dwPoolStart = dwNet; pTcpipParams->dwPoolEnd = (dwNet + ~dwMask); }
// An unexpected error occured
//
else if (dwErr != NO_ERROR) { DbgOutputTrace("TcpipLoad: pool fail 0x%08x", dwErr); dwRet = dwErr; }
return dwRet; }
//
// Commits the given tcpip parameters to the system.
//
DWORD TcpipSaveParamsToSystem( IN TCPIP_PARAMS * pTcpipParams) { WCHAR pszKey[512]; DWORD dwRet = NO_ERROR, dwErr;
wsprintfW(pszKey, L"%s%s", pszRemoteAccessParamStub, pszIpParams);
// Load the params from the various registry locations.
dwErr = RassrvRegSetDw( pTcpipParams->bUseDhcp, pszKey, (const PWCHAR)pszIpUseDhcp); if (dwErr != NO_ERROR) { DbgOutputTrace("TcpipSave: dhcp fail 0x%08x", dwErr); dwRet = dwErr; }
dwErr = RassrvRegSetDw( pTcpipParams->bCaller, pszKey, (const PWCHAR)pszIpClientSpec); if (dwErr != NO_ERROR) { DbgOutputTrace("TcpipSave: callerspec fail 0x%08x", dwErr); dwRet = dwErr; }
wcscat(pszKey, pszIpPoolSubKey);
dwErr = RassrvRegSetDwEx( pTcpipParams->dwPoolStart, pszKey, (const PWCHAR)pszIpFrom, TRUE); if (dwErr != NO_ERROR) { DbgOutputTrace("TcpipSave: from fail 0x%08x", dwErr); dwRet = dwErr; }
dwErr = RassrvRegSetDwEx( pTcpipParams->dwPoolEnd, pszKey, (const PWCHAR)pszIpTo, TRUE); if (dwErr != NO_ERROR) { DbgOutputTrace("TcpipSave: to fail 0x%08x", dwErr); dwRet = dwErr; }
return dwRet; }
//
// Loads the ipx parameters from the system
//
DWORD IpxLoadParamsFromSystem( OUT IPX_PARAMS *pIpxParams) { WCHAR pszKey[512]; DWORD dwRet = NO_ERROR, dwErr;
wsprintfW(pszKey, L"%s%s", pszRemoteAccessParamStub, pszIpxParams);
// Load the params from the various registry locations.
dwErr = RassrvRegGetDw( &pIpxParams->bAutoAssign, TRUE, pszKey, (const PWCHAR)pszIpxAutoAssign); if (dwErr != NO_ERROR) { DbgOutputTrace("IpxLoad: auto-assign fail 0x%08x", dwErr); dwRet = dwErr; }
dwErr = RassrvRegGetDw( &pIpxParams->bCaller, TRUE, pszKey, (const PWCHAR)pszIpxClientSpec); if (dwErr != NO_ERROR) { DbgOutputTrace("IpxLoad: client-spec fail 0x%08x", dwErr); dwRet = dwErr; }
dwErr = RassrvRegGetDw( &pIpxParams->dwIpxAddress, 0, pszKey, (const PWCHAR)pszIpxAddress); if (dwErr != NO_ERROR) { DbgOutputTrace("IpxLoad: address fail 0x%08x", dwErr); dwRet = dwErr; }
dwErr = RassrvRegGetDw( &pIpxParams->bGlobalWan, 0, pszKey, (const PWCHAR)pszIpxAssignSame); if (dwErr != NO_ERROR) { DbgOutputTrace("IpxLoad: same-addr fail 0x%08x", dwErr); dwRet = dwErr; }
return dwRet; }
//
// Commits the given ipx parameters to the system.
//
DWORD IpxSaveParamsToSystem( IN IPX_PARAMS * pIpxParams) { WCHAR pszKey[512]; DWORD dwRet = NO_ERROR, dwErr;
wsprintfW(pszKey, L"%s%s", pszRemoteAccessParamStub, pszIpxParams);
// Save params to the various registry locations.
dwErr = RassrvRegSetDw( pIpxParams->bAutoAssign, pszKey, (const PWCHAR)pszIpxAutoAssign); if (dwErr != NO_ERROR) { DbgOutputTrace("IpxSave: auto-addr save 0x%08x", dwErr); dwRet = dwErr; }
dwErr = RassrvRegSetDw( pIpxParams->bCaller, pszKey, (const PWCHAR)pszIpxClientSpec); if (dwErr != NO_ERROR) { DbgOutputTrace("IpxSave: client-spec fail 0x%08x", dwErr); dwRet = dwErr; }
dwErr = RassrvRegSetDw( pIpxParams->dwIpxAddress, pszKey, (const PWCHAR)pszIpxAddress); if (dwErr != NO_ERROR) { DbgOutputTrace("IpxSave: addr save 0x%08x", dwErr); dwRet = dwErr; }
dwErr = RassrvRegSetDw( pIpxParams->bGlobalWan, pszKey, (const PWCHAR)pszIpxAssignSame); if (dwErr != NO_ERROR) { DbgOutputTrace("IpxSave: assign-same fail 0x%08x", dwErr); dwRet = dwErr; }
return dwRet; }
//
// Dialog procedure that handles the editing of generic protocol
// information. Dialog proc that governs the ipx settings dialog
//
INT_PTR CALLBACK GenericProtSettingsDialogProc ( IN HWND hwndDlg, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam) { switch (uMsg) { case WM_INITDIALOG: { PROT_EDIT_DATA* pEditData = ((PROT_EDIT_DATA*)lParam);
// Set the network exposure check
SendDlgItemMessage( hwndDlg, CID_NetTab_GenProt_CB_ExposeNetwork, BM_SETCHECK, (pEditData->bExpose) ? BST_CHECKED : BST_UNCHECKED, 0); SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam); return FALSE; } break;
case WM_DESTROY: SetWindowLongPtr(hwndDlg, GWLP_USERDATA, 0); break;
case WM_COMMAND: { PROT_EDIT_DATA * pEditData = (PROT_EDIT_DATA*) GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
switch (wParam) { case IDOK: pEditData->bExpose = SendDlgItemMessage( hwndDlg, CID_NetTab_GenProt_CB_ExposeNetwork, BM_GETCHECK, 0, 0) == BST_CHECKED; EndDialog(hwndDlg, 1); break;
case IDCANCEL: EndDialog(hwndDlg, 0); break; } } break; }
return FALSE; }
//
// Function edits the properties of a generic protocol,
// that is a protocol that has no ras-specific properties.
//
DWORD GenericProtocolEditProperties( IN HWND hwndParent, IN OUT PROT_EDIT_DATA * pEditData, IN OUT BOOL * pbCommit) { DWORD dwErr; INT_PTR iRet;
// Popup the dialog box
iRet = DialogBoxParam( Globals.hInstDll, MAKEINTRESOURCE(DID_NetTab_GenProt), hwndParent, GenericProtSettingsDialogProc, (LPARAM)pEditData);
// If ok was pressed, save off the new settings
*pbCommit = FALSE; if ( (iRet) && (iRet != -1) ) { *pbCommit = TRUE; }
return NO_ERROR; }
//
// Releases resources reserved by this
// network component database.
//
DWORD netDbCleanup( RASSRV_COMPONENT_DB* This) { DWORD i, dwCount;
// Free all of the strings
if (This->pComps) { for (i = 0; i < This->dwCompCount; i++) { if (This->pComps[i]) { if (This->pComps[i]->pINetCfgComp) { dwCount = INetCfgComponent_Release( This->pComps[i]->pINetCfgComp); DbgOutputTrace( "netDbCleanup: %ls ref=%x", This->pComps[i]->pszId, dwCount); } if (This->pComps[i]->pszName) { CoTaskMemFree(This->pComps[i]->pszName); } if (This->pComps[i]->pszDesc) { CoTaskMemFree(This->pComps[i]->pszDesc); } if (This->pComps[i]->pszId) { CoTaskMemFree(This->pComps[i]->pszId); } RassrvFree(This->pComps[i]); } } RassrvFree(This->pComps); }
// Reset all of the values
This->dwCompCount = 0; This->pComps = 0;
return NO_ERROR; }
//
// Loads in the netshell library which is responsible for adding
// and removing network components
//
DWORD netDbLoadNetShell ( RASSRV_COMPONENT_DB* This) { if (!This->pNetConUtilities) { HRESULT hr;
hr = HrCreateNetConnectionUtilities(&This->pNetConUtilities); if (FAILED(hr)) { DbgOutputTrace("LoadNetShell: loadlib fial 0x%08x", hr); } }
return NO_ERROR; }
//
// Loads protocol specific info for a ras-manipulatable protocol. This
// function assumes that the component passed in is a ras-manipulatable
// component. (tcpip, ipx, nbf, arap)
//
DWORD netDbLoadProtcolInfo( IN OUT RASSRV_NET_COMPONENT * pNetComp) { LPBYTE pbData;
// Initialize the dirty bit and the data
pNetComp->bDataDirty = FALSE; pNetComp->pbData = NULL;
// Get the enabled and exposed properties
protGetEnabling(&(pNetComp->bEnabled), pNetComp->dwId); protGetExpose(&(pNetComp->bExposes), pNetComp->dwId); pNetComp->bEnabledOrig = pNetComp->bEnabled;
// Load protocol specific data
//
switch (pNetComp->dwId) { case NETCFGDB_ID_IP: pNetComp->pbData = RassrvAlloc(sizeof(TCPIP_PARAMS), TRUE); if (pNetComp->pbData == NULL) { return ERROR_NOT_ENOUGH_MEMORY; } TcpipLoadParamsFromSystem((TCPIP_PARAMS*)(pNetComp->pbData)); break;
case NETCFGDB_ID_IPX: pNetComp->pbData = RassrvAlloc(sizeof(IPX_PARAMS), TRUE); if (pNetComp->pbData == NULL) { return ERROR_NOT_ENOUGH_MEMORY; } IpxLoadParamsFromSystem((IPX_PARAMS*)(pNetComp->pbData)); break; }
return NO_ERROR; }
//
// Loads service specific info for a ras-manipulatable service. This
// function assumes that the component passed in is a ras-manipulatable
// component.
//
DWORD netDbLoadServiceInfo( IN OUT RASSRV_NET_COMPONENT * pNetComp) { // Get the enabled property
//
svcGetEnabling(&(pNetComp->bEnabled), pNetComp->dwId); pNetComp->bEnabledOrig = pNetComp->bEnabled;
return NO_ERROR; }
//
// Returns the protol id of the given component
//
DWORD netDbLoadCompId ( IN OUT RASSRV_NET_COMPONENT * pNetComp) { DWORD i; static const COMP_MAPPING pManipCompMap [] = { { NETCFG_TRANS_CID_MS_TCPIP, NETCFGDB_ID_IP }, { NETCFG_TRANS_CID_MS_NWIPX, NETCFGDB_ID_IPX }, { NETCFG_TRANS_CID_MS_NETBEUI, NETCFGDB_ID_NETBUI }, { NETCFG_TRANS_CID_MS_APPLETALK, NETCFGDB_ID_ARAP }, { NETCFG_SERVICE_CID_MS_SERVER, NETCFGDB_ID_FILEPRINT } };
// See if the id matches any of the protocols that we manage.
//
pNetComp->dwId = NETCFGDB_ID_OTHER; for (i = 0; i < sizeof(pManipCompMap)/sizeof(*pManipCompMap); i++) { if (lstrcmpi(pNetComp->pszId, pManipCompMap[i].pszId) == 0) { pNetComp->dwId = pManipCompMap[i].dwId; break; } }
return pNetComp->dwId; }
//
// Returns TRUE if this iNetCfg component is not hidden and if
// it successfully yeilds it's information.
//
BOOL netDbGetCompInfo( IN INetCfgComponent * pComponent, IN OUT RASSRV_NET_COMPONENT * pNetComp, IN RASSRV_COMPONENT_DB * pCompDb ) { DWORD dwCharacter; GUID Guid; WCHAR * pszwId = NULL; HRESULT hr = S_OK, hr2;
// Make sure that this is not a "hidden" component
//
hr = INetCfgComponent_GetCharacteristics (pComponent, &dwCharacter); if ( (FAILED(hr)) || (dwCharacter & NCF_HIDDEN) ) { return FALSE; } //
//for .Net 605988 filter out IPX, at this point
//pNetComp->pszId should be valid
//
if ( SUCCEEDED(INetCfgComponent_GetId (pComponent, &pszwId) ) ) { WCHAR * pszwTmpId = NULL;
pszwTmpId = StrDupWFromT(NETCFG_TRANS_CID_MS_NWIPX); if(pszwTmpId) { if ( 0 == lstrcmpW(pszwId, pszwTmpId)) { Free0(pszwTmpId); CoTaskMemFree(pszwId); return FALSE; } Free0(pszwTmpId); }
pszwTmpId = StrDupWFromT( TEXT("ms_nwnb") ); if(pszwTmpId) { if ( 0 == lstrcmpW(pszwId, pszwTmpId)) { Free0(pszwTmpId); CoTaskMemFree(pszwId); return FALSE; } Free0(pszwTmpId); }
CoTaskMemFree(pszwId); }
// Get the display name
hr = INetCfgComponent_GetDisplayName (pComponent, &pNetComp->pszName); if (FAILED(hr)) { return FALSE; }
// Assign the has properties value
pNetComp->bHasUi = !!(dwCharacter & NCF_HAS_UI);
// pmay: 323274
//
// Make sure that the component can display properties without
// a context if it claims to support displaying properties.
//
if (pNetComp->bHasUi) { hr2 = INetCfgComponent_RaisePropertyUi( pComponent, GetActiveWindow(), NCRP_QUERY_PROPERTY_UI, NULL); pNetComp->bHasUi = !!(hr2 == S_OK); } // Load the rest of the props
if (FAILED(INetCfgComponent_GetClassGuid (pComponent, &Guid)) || FAILED(INetCfgComponent_GetId (pComponent, &pNetComp->pszId)) || FAILED(INetCfgComponent_GetHelpText(pComponent, &pNetComp->pszDesc)) ) { DbgOutputTrace("GetCompInfo: fail %S", pNetComp->pszName); return FALSE; } // Assign the type
if (memcmp(&Guid, &GUID_DEVCLASS_NETCLIENT, sizeof(GUID)) == 0) { pNetComp->dwType = NETCFGDB_CLIENT; } else if (memcmp(&Guid, &GUID_DEVCLASS_NETSERVICE, sizeof(GUID)) == 0) { pNetComp->dwType = NETCFGDB_SERVICE; } else { pNetComp->dwType = NETCFGDB_PROTOCOL; }
// If this is a protocol that ras server can manipulate,
// initailize its additional fields here.
pNetComp->dwId = netDbLoadCompId(pNetComp); if (pNetComp->dwId != NETCFGDB_ID_OTHER) { if (pNetComp->dwType == NETCFGDB_PROTOCOL) { netDbLoadProtcolInfo(pNetComp); } else if (pNetComp->dwType == NETCFGDB_SERVICE) { netDbLoadServiceInfo(pNetComp); }
pNetComp->bManip = TRUE; }
// Assign the inetcfg component
pNetComp->pINetCfgComp = pComponent; INetCfgComponent_AddRef(pComponent);
//For whistler bug 347355
//
{ BOOL fEnableRemove=FALSE; DWORD dwFlags; fEnableRemove = INetConnectionUiUtilities_UserHasPermission( pCompDb->pNetConUtilities, NCPERM_AddRemoveComponents);
hr = INetCfgComponent_GetCharacteristics(pComponent, &dwFlags ); if( SUCCEEDED(hr) && (NCF_NOT_USER_REMOVABLE & dwFlags) ) { fEnableRemove = FALSE; }
pNetComp->bRemovable = fEnableRemove; }
return TRUE; }
//
// Raise the ui for a ras-manipulatable protocol
//
DWORD netDbRaiseRasProps( IN RASSRV_NET_COMPONENT * pNetComp, IN HWND hwndParent) { PROT_EDIT_DATA ProtEditData; TCPIP_PARAMS TcpParams; IPX_PARAMS IpxParams; BOOL bOk; DWORD dwErr;
// Initialize the protocol data properties structure
//
ProtEditData.bExpose = pNetComp->bExposes; ProtEditData.pbData = NULL;
// Launch the appropriate ui
switch (pNetComp->dwId) { case NETCFGDB_ID_IP: CopyMemory(&TcpParams, pNetComp->pbData, sizeof(TCPIP_PARAMS)); ProtEditData.pbData = (LPBYTE)(&TcpParams); dwErr = TcpipEditProperties(hwndParent, &ProtEditData, &bOk); if (dwErr != NO_ERROR) { return dwErr; } if (bOk) { pNetComp->bDataDirty = TRUE; CopyMemory( pNetComp->pbData, &TcpParams, sizeof(TCPIP_PARAMS)); pNetComp->bExposes = ProtEditData.bExpose;; } break;
case NETCFGDB_ID_IPX: CopyMemory(&IpxParams, pNetComp->pbData, sizeof(IPX_PARAMS)); ProtEditData.pbData = (LPBYTE)(&IpxParams); dwErr = IpxEditProperties(hwndParent, &ProtEditData, &bOk); if (dwErr != NO_ERROR) { return dwErr; } if (bOk) { pNetComp->bDataDirty = TRUE; CopyMemory(pNetComp->pbData, &IpxParams, sizeof(IPX_PARAMS)); pNetComp->bExposes = ProtEditData.bExpose;; } break;
default: dwErr = GenericProtocolEditProperties( hwndParent, &ProtEditData, &bOk); if (dwErr != NO_ERROR) { return dwErr; } if (bOk) { pNetComp->bDataDirty = TRUE; pNetComp->bExposes = ProtEditData.bExpose;; } break; }
return NO_ERROR; }
//
// Comparison function used to sort the network components
// It's easier to implement here rather than the UI
//
int __cdecl netDbCompare ( CONST VOID* pElem1, CONST VOID* pElem2) { RASSRV_NET_COMPONENT * pc1 = *((RASSRV_NET_COMPONENT **)pElem1); RASSRV_NET_COMPONENT * pc2 = *((RASSRV_NET_COMPONENT **)pElem2);
if (pc1->bManip == pc2->bManip) { if (pc1->bManip == FALSE) { return 0; }
if (pc1->dwId == pc2->dwId) { return 0; } else if (pc1->dwId < pc2->dwId) { return -1; }
return 1; } else if (pc1->bManip) { return -1; }
return 1; }
//
// Opens the database of network config components
//
DWORD netDbOpen ( OUT PHANDLE phNetCompDatabase, IN PWCHAR pszClientName) { RASSRV_COMPONENT_DB * This; DWORD dwLength;
// Validate parameters
if (! phNetCompDatabase || !pszClientName) { return ERROR_INVALID_PARAMETER; }
// Allocate the database
This = RassrvAlloc (sizeof(RASSRV_COMPONENT_DB), TRUE); if (This == NULL) { return ERROR_NOT_ENOUGH_MEMORY; }
// Initialize
dwLength = wcslen(pszClientName); if (dwLength) { This->pszClientName = RassrvAlloc((dwLength + 1) * sizeof(WCHAR), FALSE); if (This->pszClientName) { wcscpy(This->pszClientName, pszClientName); } } This->bFlushOnClose = FALSE; *phNetCompDatabase = (HANDLE)This;
// Load the net shell library
netDbLoadNetShell(This);
return NO_ERROR; }
//
// Cleans up all resources held by the database
//
DWORD netDbClose ( IN HANDLE hNetCompDatabase) { RASSRV_COMPONENT_DB* This = (RASSRV_COMPONENT_DB*)hNetCompDatabase;
// Validate parameters
if (!This) { return ERROR_INVALID_PARAMETER; }
// Flush if needed
if (This->bFlushOnClose) { netDbFlush(hNetCompDatabase); } else { // If we've made changes to inetcfg that require backing out,
// do so now.
if (This->pINetCfg) { INetCfg_Cancel(This->pINetCfg); } } netDbCleanup(This);
// Free the client name
if (This->pszClientName) { RassrvFree(This->pszClientName); }
// Release our reference to inetcfg. We will still have it
// at this point if a protocol/client/service was added.
if (This->pINetCfg) { HrUninitializeAndReleaseINetCfg ( This->bInitCom, This->pINetCfg, This->bHasINetCfgLock); }
// Free the netshell library if appropriate
if (This->pNetConUtilities) { INetConnectionUiUtilities_Release(This->pNetConUtilities); }
// Free this
RassrvFree(This);
return NO_ERROR; }
// Commits all changes to the database to the system
DWORD netDbFlush ( IN HANDLE hNetCompDatabase) { RASSRV_COMPONENT_DB * This = (RASSRV_COMPONENT_DB*)hNetCompDatabase; RASSRV_NET_COMPONENT* pComp = NULL; DWORD i;
// Validate parameters
if (!This) { return ERROR_INVALID_PARAMETER; }
// Flush any ras-manipulatable's data if dirty
for (i = 0; i < This->dwCompCount; i++) { pComp = This->pComps[i];
// If the enabling of this component has changed, commit
// that change
if ((pComp->bEnabled != pComp->bEnabledOrig) && (pComp->bManip)) { if (pComp ->dwType == NETCFGDB_PROTOCOL) { protSetEnabling( pComp->bEnabled, pComp->dwId); } else if (pComp->dwType == NETCFGDB_SERVICE) { svcSetEnabling(pComp); } }
// If the ras-server-specific properties of the component
// have changed, commit the changes.
if (pComp->bDataDirty) { protSetExpose(pComp->bExposes, pComp->dwId);
switch (pComp->dwId) { case NETCFGDB_ID_IP: { TCPIP_PARAMS* pTcpParams = (TCPIP_PARAMS*)(pComp->pbData);
TcpipSaveParamsToSystem(pTcpParams); } break;
case NETCFGDB_ID_IPX: { IPX_PARAMS* pIpxParams = (IPX_PARAMS*)(pComp->pbData);
IpxSaveParamsToSystem(pIpxParams); } break; } } }
// If we have a pointer to the inetcfg instance then we can
// commit the changes now
if (This->pINetCfg) { INetCfg_Apply(This->pINetCfg); }
return NO_ERROR; }
//
// Loads the net config database for the first time. Because inetcfg
// requires time to load and be manipulated, we delay the load of this
// database until it is explicitly requested.
//
DWORD netDbLoad( IN HANDLE hNetCompDatabase) { return netDbReload(hNetCompDatabase); }
//
// Reloads net information from system
//
DWORD netDbReload( IN HANDLE hNetCompDatabase) { RASSRV_COMPONENT_DB * This = (RASSRV_COMPONENT_DB*)hNetCompDatabase; DWORD i, j, dwProtCount = 0, dwRefCount; HRESULT hr; RASSRV_NET_COMPONENT TempComp; INetCfgComponent* pComponents [256]; PWCHAR pszName = NULL; static const GUID* c_apguidClasses [] = { &GUID_DEVCLASS_NETTRANS, &GUID_DEVCLASS_NETCLIENT, &GUID_DEVCLASS_NETSERVICE, };
// Validate
if (!This) { return ERROR_INVALID_PARAMETER; }
DbgOutputTrace( "netDbReload %x %x %x %x %x %x %x %x", This->pINetCfg, This->bHasINetCfgLock, This->bInitCom, This->dwCompCount, This->bFlushOnClose, This->pComps, This->pszClientName, This->pNetConUtilities);
// Cleanup any previous values
netDbCleanup(This);
// If we don't have a reference to inetcfg yet, get it
// here.
if (This->pINetCfg == NULL) { This->bInitCom = TRUE; This->bHasINetCfgLock = TRUE; hr = HrCreateAndInitializeINetCfg( &This->bInitCom, &This->pINetCfg, TRUE, 0, This->pszClientName, NULL); // Handle error conditions here
if (S_FALSE == hr) { return ERROR_CAN_NOT_COMPLETE; } else if (FAILED(hr)) { return ERROR_CAN_NOT_COMPLETE; } }
//
// Enumerate all of the client and service components in the system.
//
hr = HrEnumComponentsInClasses ( This->pINetCfg, sizeof(c_apguidClasses) / sizeof(c_apguidClasses[0]), (GUID**)c_apguidClasses, sizeof(pComponents) / sizeof(pComponents[0]), pComponents, &This->dwCompCount); if (!SUCCEEDED(hr)) { return ERROR_CAN_NOT_COMPLETE; }
// Initialize the array of internal objects
This->pComps = RassrvAlloc ( This->dwCompCount * sizeof (RASSRV_NET_COMPONENT*), TRUE); if (!This->pComps) { return ERROR_NOT_ENOUGH_MEMORY; }
// Initialize the installed component array
//
j = 0; ZeroMemory(&TempComp, sizeof(TempComp)); for (i = 0; i < This->dwCompCount; i++) { pszName = L"";
//Add this (RASSRV_COMPONENT_DB *) for whistler bug 347355
//
if (netDbGetCompInfo(pComponents[i], &TempComp, This)) { //
// Currently we do not support IPv6 for incoming connections.
// If this component is IPv6, skip it
//
if ((TempComp.dwType == NETCFGDB_PROTOCOL) && (lstrcmpi(TempComp.pszId, TEXT("ms_tcpip6")) == 0)) { dwRefCount = INetCfgComponent_Release(pComponents[i]); DbgOutputTrace( "netDbReload: skipping %ls ref=%d", pszName, dwRefCount); continue; } This->pComps[j] = RassrvAlloc (sizeof(RASSRV_NET_COMPONENT), FALSE); if (!This->pComps[j]) { return ERROR_NOT_ENOUGH_MEMORY; }
// Fill in the fields
CopyMemory(This->pComps[j], &TempComp, sizeof(TempComp)); ZeroMemory(&TempComp, sizeof(TempComp)); if (This->pComps[j]->dwType == NETCFGDB_PROTOCOL) { dwProtCount++; } pszName = This->pComps[j]->pszName; j++; } dwRefCount = INetCfgComponent_Release(pComponents[i]); DbgOutputTrace( "netDbReload: %ls ref=%d", pszName, dwRefCount); } This->dwCompCount = j;
// Sort the array.
//
qsort( This->pComps, This->dwCompCount, sizeof(This->pComps[0]), netDbCompare);
return NO_ERROR; }
//
// Reload the status of a given component
//
DWORD netDbReloadComponent ( IN HANDLE hNetCompDatabase, IN DWORD dwComponentId) { RASSRV_COMPONENT_DB * This = (RASSRV_COMPONENT_DB*)hNetCompDatabase; RASSRV_NET_COMPONENT* pComp = NULL; DWORD i;
// Validate
if (!This) { return ERROR_INVALID_PARAMETER; }
// Currently, we only need to support the fileprint
// component
//
if (dwComponentId != NETCFGDB_ID_FILEPRINT) { return ERROR_INVALID_PARAMETER; }
// Find the appropriate component
//
for (i = 0; i < This->dwCompCount; i++) { if (This->pComps[i]->dwId == dwComponentId) { pComp = This->pComps[i]; break; } }
// Nothing to do if we can't find the component
//
if (pComp == NULL) { return ERROR_NOT_FOUND; }
// Reload the component information
//
if (dwComponentId == NETCFGDB_ID_FILEPRINT) { svcGetEnabling(&(pComp->bEnabled), NETCFGDB_ID_FILEPRINT); }
return NO_ERROR; }
//
// Reverts the database to the state it was in when opened
//
DWORD netDbRollback ( IN HANDLE hNetCompDatabase) { RASSRV_COMPONENT_DB * This = (RASSRV_COMPONENT_DB*)hNetCompDatabase;
if (!This) { return ERROR_INVALID_PARAMETER; }
This->bFlushOnClose = FALSE;
return NO_ERROR; }
//
// Special function denotes whether the network tab has been
// loaded
//
BOOL netDbIsLoaded ( IN HANDLE hNetCompDatabase) { RASSRV_COMPONENT_DB * This = (RASSRV_COMPONENT_DB*)hNetCompDatabase;
if (!This) { return ERROR_INVALID_PARAMETER; }
return (!!(This->pINetCfg));// || (This->bHasINetCfgLock));
}
//
// Gets the number of components in the database
//
DWORD netDbGetCompCount ( IN HANDLE hNetCompDatabase, OUT LPDWORD lpdwCount) { RASSRV_COMPONENT_DB * This = (RASSRV_COMPONENT_DB*)hNetCompDatabase; DWORD i;
// Validate parameters
if (!This || !lpdwCount) { return ERROR_INVALID_PARAMETER; }
*lpdwCount = This->dwCompCount;
return NO_ERROR; }
//
// Returns a pointer to the name of a component (don't alter it)
//
DWORD netDbGetName( IN HANDLE hNetCompDatabase, IN DWORD dwIndex, OUT PWCHAR* pszName) { RASSRV_COMPONENT_DB * This = (RASSRV_COMPONENT_DB*)hNetCompDatabase;
// Validate
if (!This || !pszName) { return ERROR_INVALID_PARAMETER; }
// Bounds check
if (!netDbBoundsCheck(This, dwIndex)) { return ERROR_INVALID_INDEX; }
// return the name
*pszName = This->pComps[dwIndex]->pszName;
return NO_ERROR; }
//
// Returns a description of a component (don't alter it)
//
DWORD netDbGetDesc( IN HANDLE hNetCompDatabase, IN DWORD dwIndex, IN PWCHAR* pszName) { RASSRV_COMPONENT_DB * This = (RASSRV_COMPONENT_DB*)hNetCompDatabase;
// Validate
if (!This || !pszName) { return ERROR_INVALID_PARAMETER; }
// Bounds check
if (!netDbBoundsCheck(This, dwIndex)) { return ERROR_INVALID_INDEX; }
// return the name
*pszName = This->pComps[dwIndex]->pszDesc;
return NO_ERROR; }
//
// Returns a type of a component (don't alter it)
//
DWORD netDbGetType ( IN HANDLE hNetCompDatabase, IN DWORD dwIndex, OUT LPDWORD lpdwType) { RASSRV_COMPONENT_DB * This = (RASSRV_COMPONENT_DB*)hNetCompDatabase;
// Validate
if (!This || !lpdwType) { return ERROR_INVALID_PARAMETER; }
// Bounds check
if (!netDbBoundsCheck(This, dwIndex)) { return ERROR_INVALID_INDEX; }
// return the name
*lpdwType = This->pComps[dwIndex]->dwType;
return NO_ERROR; }
//
// Get a component id
//
DWORD netDbGetId( IN HANDLE hNetCompDatabase, IN DWORD dwIndex, OUT LPDWORD lpdwId) { RASSRV_COMPONENT_DB * This = (RASSRV_COMPONENT_DB*)hNetCompDatabase;
// Validate
if (!This || !lpdwId) { return ERROR_INVALID_PARAMETER; }
// Bounds check
if (!netDbBoundsCheck(This, dwIndex)) { return ERROR_INVALID_INDEX; }
// return the name
*lpdwId = This->pComps[dwIndex]->dwId;
return NO_ERROR; }
//
// Gets whether the given component is enabled. For non-ras-manipulatable
// components, this yields TRUE
//
DWORD netDbGetEnable( IN HANDLE hNetCompDatabase, IN DWORD dwIndex, OUT PBOOL pbEnabled) { RASSRV_COMPONENT_DB * This = (RASSRV_COMPONENT_DB*)hNetCompDatabase;
// Validate
if (!This || !pbEnabled) { return ERROR_INVALID_PARAMETER; }
// Bounds check
if (!netDbBoundsCheck(This, dwIndex)) { return ERROR_INVALID_INDEX; }
// return the name
if (This->pComps[dwIndex]->bManip) { *pbEnabled = This->pComps[dwIndex]->bEnabled; } else { *pbEnabled = TRUE; }
return NO_ERROR; }
//
// Gets whether the given component is enabled. This function only has
// effect on ras-manipulatable components.
//
DWORD netDbSetEnable( IN HANDLE hNetCompDatabase, IN DWORD dwIndex, IN BOOL bEnabled) { RASSRV_COMPONENT_DB * This = (RASSRV_COMPONENT_DB*)hNetCompDatabase;
// Validate
if (!This) { return ERROR_INVALID_PARAMETER; }
// Bounds check
if (!netDbBoundsCheck(This, dwIndex)) { return ERROR_INVALID_INDEX; }
// return the name
This->pComps[dwIndex]->bEnabled = bEnabled;
return NO_ERROR; }
//
// Returns whether the given network component can
// be manipulated by ras server.
//
DWORD netDbIsRasManipulatable ( IN HANDLE hNetCompDatabase, IN DWORD dwIndex, OUT PBOOL pbManip) { RASSRV_COMPONENT_DB * This = (RASSRV_COMPONENT_DB*)hNetCompDatabase;
// Validate
if (!This || !pbManip) { return ERROR_INVALID_PARAMETER; }
// Bounds check
if (! netDbBoundsCheck(This, dwIndex)) { return ERROR_INVALID_INDEX; }
// return the name
*pbManip = This->pComps[dwIndex]->bManip;
return NO_ERROR; }
//
////Disable/Enable the Uninstall button for whislter bug 347355 gangz
//
DWORD netDbHasRemovePermission( IN HANDLE hNetCompDatabase, IN DWORD dwIndex, OUT PBOOL pbHasPermit) { RASSRV_COMPONENT_DB * This = NULL; INetCfgComponent* pComponent = NULL; BOOL fEnableRemove = FALSE; HRESULT hr = S_OK; DWORD dwErr = NO_ERROR, dwFlags; //Disable/Enable Uninstall button according to its user permission and user
// removability
//
do { This = (RASSRV_COMPONENT_DB*)hNetCompDatabase;
// Validate pointer
if (!This || !pbHasPermit || ( -1 == dwIndex )) { dwErr = ERROR_INVALID_PARAMETER; break; }
// Make sure that netshell library has been opened
if (!This->pNetConUtilities) { dwErr = ERROR_CAN_NOT_COMPLETE; break; }
if (dwIndex >= This->dwCompCount) { dwErr = ERROR_CAN_NOT_COMPLETE; break; }
ASSERT(This->pComps[dwIndex]); if( !(This->pComps[dwIndex]) ) { dwErr = ERROR_CAN_NOT_COMPLETE; break; }
fEnableRemove = This->pComps[dwIndex]->bRemovable;
*pbHasPermit = fEnableRemove; } while(FALSE); return dwErr; }
//
// Returns whether the given network component has
// a properties ui that it can raise
//
DWORD netDbHasPropertiesUI( IN HANDLE hNetCompDatabase, IN DWORD dwIndex, OUT PBOOL pbHasUi) { RASSRV_COMPONENT_DB * This = (RASSRV_COMPONENT_DB*)hNetCompDatabase; RASSRV_NET_COMPONENT* pComp = NULL;
// Validate
if (!This || !pbHasUi) { return ERROR_INVALID_PARAMETER; }
// Bounds check
if (!netDbBoundsCheck(This, dwIndex)) { return ERROR_INVALID_INDEX; }
pComp = This->pComps[dwIndex];
if ((pComp->bManip) && (pComp->dwType == NETCFGDB_PROTOCOL)) { *pbHasUi = TRUE; } else { *pbHasUi = pComp->bHasUi; }
return NO_ERROR; }
//
// Raises the properties of the component at the given index
//
DWORD netDbRaisePropertiesDialog ( IN HANDLE hNetCompDatabase, IN DWORD dwIndex, IN HWND hwndParent) { RASSRV_COMPONENT_DB * This = (RASSRV_COMPONENT_DB*)hNetCompDatabase; RASSRV_NET_COMPONENT* pComp = NULL;
// Validate
if (!This) { return ERROR_INVALID_PARAMETER; }
// Bounds check
if (dwIndex >= This->dwCompCount) { return ERROR_INVALID_INDEX; }
pComp = This->pComps[dwIndex];
// If this is a ras-manipulatable protocol, raise its
// properties manually.
if ((pComp->bManip) && (pComp->dwType == NETCFGDB_PROTOCOL)) { netDbRaiseRasProps(This->pComps[dwIndex], hwndParent); }
// Otherwise, let inetcfg do the work
else { return INetCfgComponent_RaisePropertyUi ( pComp->pINetCfgComp, hwndParent, NCRP_SHOW_PROPERTY_UI, NULL); }
return NO_ERROR; }
//
// Brings up the UI that allows a user to install a component
//
DWORD netDbRaiseInstallDialog( IN HANDLE hNetCompDatabase, IN HWND hwndParent) { RASSRV_COMPONENT_DB * This = (RASSRV_COMPONENT_DB*)hNetCompDatabase; HRESULT hr = S_OK; // For whistler 524777
// Validate
if (!This) { return ERROR_INVALID_PARAMETER; }
// Make sure that netshell library has been opened
if (!This->pNetConUtilities) { return ERROR_CAN_NOT_COMPLETE; } else { // If we have our pointer to the function used to bring up the add
// component dialog (obtained above only once), call it.
// We want to filter out protocols that RAS does not care about
// We do this by sending in a CI_FILTER_INFO structure indicating
// we want non-RAS protocols filtered out
//
CI_FILTER_INFO cfi = {0}; cfi.eFilter = FC_RASSRV; hr = INetConnectionUiUtilities_DisplayAddComponentDialog( This->pNetConUtilities, hwndParent, This->pINetCfg, &cfi);
// Ui will handle reboot
if (hr == NETCFG_S_REBOOT) { netDbReload(hNetCompDatabase); return hr; }
// If the user didn't cancel, refresh the database.
if (S_FALSE != hr) { if (SUCCEEDED (hr)) { netDbReload(hNetCompDatabase); return NO_ERROR; } else { return hr; } } }
return ERROR_CANCELLED; }
//
// Uninstalls the given component
//
DWORD netDbRaiseRemoveDialog ( IN HANDLE hNetCompDatabase, IN DWORD dwIndex, IN HWND hwndParent) { RASSRV_COMPONENT_DB * This = (RASSRV_COMPONENT_DB*)hNetCompDatabase; HRESULT hr;
// Validate
if (!This) { return ERROR_INVALID_PARAMETER; }
// Make sure that netshell library has been opened
if (!This->pNetConUtilities) { return ERROR_CAN_NOT_COMPLETE; }
// If we have our pointer to the function used to bring up the add
// component dialog (obtained above only once), call it.
if (dwIndex < This->dwCompCount) { if (This->pComps[dwIndex]->pINetCfgComp) { hr = INetConnectionUiUtilities_QueryUserAndRemoveComponent( This->pNetConUtilities, hwndParent, This->pINetCfg, This->pComps[dwIndex]->pINetCfgComp);
// Ui will handle reboot
if (hr == NETCFG_S_REBOOT) { netDbReload(hNetCompDatabase); return hr; }
// If the user didn't cancel, refresh the database.
else if (S_FALSE != hr) { if (SUCCEEDED (hr)) { netDbReload(hNetCompDatabase); return NO_ERROR; } else { return hr; } } } }
return ERROR_CANCELLED; }
|