windows-nt/Source/XPSP1/NT/net/rras/ras/ui/rassrvui/netcfgdb.c
2020-09-26 16:20:57 +08:00

2145 lines
50 KiB
C

/*
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;
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;
}
// 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;
HRESULT hr;
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))
{
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;
// 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.
HRESULT hr = S_OK;
// 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;
}