You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1034 lines
29 KiB
1034 lines
29 KiB
/*
|
|
File Rassrv.h
|
|
|
|
Functions that perform ras server operations that can be implemented
|
|
independent of the ui.
|
|
|
|
Paul Mayfield, 10/7/97
|
|
*/
|
|
|
|
#include "rassrv.h"
|
|
|
|
// ============================================================
|
|
// ============================================================
|
|
// Functions to maintain data accross property sheet pages.
|
|
// ============================================================
|
|
// ============================================================
|
|
|
|
// This message queries all other pages to find out if
|
|
// any other ras server pages exist. If this message is
|
|
// not responded to, then we know it's safe to cleanup
|
|
// any global context in the wizard/property sheet.
|
|
#define RASSRV_CMD_QUERY_LIVING 237
|
|
|
|
// These commands hide and show ras server pages.
|
|
#define RASSRV_CMD_HIDE_PAGES 238
|
|
#define RASSRV_CMD_SHOW_PAGES 239
|
|
|
|
//
|
|
// Reasons for RasSrvSErviceInitialize to fail
|
|
//
|
|
#define RASSRV_REASON_SvcError 0
|
|
#define RASSRV_REASON_Pending 1
|
|
|
|
//
|
|
// This structure defines the data that needs to be stored
|
|
// for each set of related property pages. Multiple instances
|
|
// of this context can exist for each wizard/propsheet.
|
|
//
|
|
typedef struct _RASSRV_PAGESET_CONTEXT
|
|
{
|
|
HWND hwndSheet;
|
|
HWND hwndFirstPage; // first to be activated in the set
|
|
|
|
HANDLE hDeviceDatabase;
|
|
HANDLE hUserDatabase;
|
|
HANDLE hNetCompDatabase;
|
|
HANDLE hMiscDatabase;
|
|
|
|
DWORD dwPagesInited; // Acts as a reference-count mechansim so we know
|
|
// what set of pages in the wizard/propsheet are
|
|
// referencing this context.
|
|
|
|
BOOL bShow; // Whether pages that ref this context show be vis.
|
|
BOOL bCommitOnClose; // Whether to commit settings changes on close
|
|
} RASSRV_PAGESET_CONTEXT;
|
|
|
|
//
|
|
// This structure defines the global context that is available on a
|
|
// per-wizard/propsheet basis. Even pages that don't share the same
|
|
// RASSRV_PAGESET_CONTEXT context will share this structure if they
|
|
// are owned by the same wizard/propsheet.
|
|
//
|
|
typedef struct _RASSRV_PROPSHEET_CONTEXT
|
|
{
|
|
BOOL bRemoteAccessWasStarted;
|
|
BOOL bRemoteAccessIsRunning;
|
|
BOOL bLeaveRemoteAccessRunning;
|
|
DWORD dwServiceErr;
|
|
} RASSRV_PROPSHEET_CONTEXT;
|
|
|
|
DWORD
|
|
APIENTRY
|
|
RassrvCommitSettings (
|
|
IN PVOID pvContext,
|
|
IN DWORD dwRasWizType);
|
|
|
|
|
|
DWORD
|
|
RassrvICConfigAccess(
|
|
IN BOOL fSet,
|
|
IN DWORD * pdwValue );
|
|
|
|
|
|
//
|
|
// Verifies that the current state of services in the system
|
|
// is condusive to configuring incoming connectins starting
|
|
// services as needed.
|
|
//
|
|
DWORD
|
|
RasSrvServiceInitialize(
|
|
IN RASSRV_PROPSHEET_CONTEXT * pPropSheetCtx,
|
|
IN HWND hwndSheet,
|
|
OUT LPDWORD lpdwReason)
|
|
{
|
|
DWORD dwErr = NO_ERROR;
|
|
HANDLE hDialupService = NULL;
|
|
BOOL bPending = FALSE;
|
|
|
|
// If we already know there's an error, then there's no
|
|
// need to proceed.
|
|
//
|
|
if (pPropSheetCtx->dwServiceErr)
|
|
{
|
|
return pPropSheetCtx->dwServiceErr;
|
|
}
|
|
|
|
// If we already started the service or if we already know the
|
|
// service is running, then there's nothing to do.
|
|
//
|
|
if (pPropSheetCtx->bRemoteAccessWasStarted ||
|
|
pPropSheetCtx->bRemoteAccessIsRunning
|
|
)
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
|
|
do
|
|
{
|
|
// Get a reference to the service
|
|
//
|
|
dwErr = SvcOpenRemoteAccess(&hDialupService);
|
|
if (dwErr != NO_ERROR)
|
|
{
|
|
break;
|
|
}
|
|
|
|
// See if we're pending something.
|
|
//
|
|
dwErr = SvcIsPending(hDialupService, &bPending);
|
|
if (dwErr != NO_ERROR)
|
|
{
|
|
break;
|
|
}
|
|
|
|
// If the service is stopping, then we can't continue
|
|
//
|
|
if (bPending)
|
|
{
|
|
*lpdwReason = RASSRV_REASON_Pending;
|
|
dwErr = ERROR_CAN_NOT_COMPLETE;
|
|
break;
|
|
}
|
|
|
|
// See if we're started
|
|
//
|
|
dwErr = SvcIsStarted(
|
|
hDialupService,
|
|
&(pPropSheetCtx->bRemoteAccessIsRunning));
|
|
if (dwErr != NO_ERROR)
|
|
{
|
|
*lpdwReason = RASSRV_REASON_SvcError;
|
|
pPropSheetCtx->dwServiceErr = dwErr;
|
|
break;
|
|
}
|
|
|
|
// If we find out the service is running, there's nothing to do
|
|
if (pPropSheetCtx->bRemoteAccessIsRunning)
|
|
{
|
|
pPropSheetCtx->bLeaveRemoteAccessRunning = TRUE;
|
|
break;
|
|
}
|
|
|
|
// Start the service since it's not running.
|
|
dwErr = RasSrvInitializeService();
|
|
if (dwErr != NO_ERROR)
|
|
{
|
|
*lpdwReason = RASSRV_REASON_SvcError;
|
|
pPropSheetCtx->dwServiceErr = dwErr;
|
|
break;
|
|
}
|
|
|
|
// Record the fact that we did so.
|
|
pPropSheetCtx->bRemoteAccessWasStarted = TRUE;
|
|
pPropSheetCtx->bRemoteAccessIsRunning = TRUE;
|
|
|
|
} while (FALSE);
|
|
|
|
// Cleanup
|
|
{
|
|
// Cleanup the reference to the dialup service
|
|
//
|
|
if (hDialupService)
|
|
{
|
|
SvcClose(hDialupService);
|
|
}
|
|
}
|
|
|
|
return dwErr;
|
|
}
|
|
|
|
//
|
|
// Abort any changes to the remoteaccess service that were made
|
|
// during RasSrvServiceInitialize
|
|
//
|
|
DWORD
|
|
RasSrvServiceCleanup(
|
|
IN HWND hwndPage)
|
|
{
|
|
DWORD dwErr;
|
|
RASSRV_PROPSHEET_CONTEXT * pPropSheetCtx = NULL;
|
|
|
|
pPropSheetCtx = (RASSRV_PROPSHEET_CONTEXT *)
|
|
GetProp(GetParent(hwndPage), Globals.atmRassrvPageData);
|
|
|
|
if (pPropSheetCtx == NULL)
|
|
{
|
|
return ERROR_CAN_NOT_COMPLETE;
|
|
}
|
|
|
|
// If we started the modified the remote access service, reverse
|
|
// the changes and record the fact that we did
|
|
if (pPropSheetCtx->bRemoteAccessWasStarted)
|
|
{
|
|
if ((dwErr = RasSrvCleanupService()) != NO_ERROR)
|
|
{
|
|
return dwErr;
|
|
}
|
|
|
|
pPropSheetCtx->bRemoteAccessWasStarted = FALSE;
|
|
pPropSheetCtx->bLeaveRemoteAccessRunning = FALSE;
|
|
pPropSheetCtx->bRemoteAccessIsRunning = FALSE;
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
//
|
|
// Intializes a property sheet. This causes a handle to the
|
|
// property sheet data object to be placed in the GWLP_USERDATA
|
|
// section of the window handle to the page.
|
|
//
|
|
DWORD
|
|
RasSrvPropsheetInitialize(
|
|
IN HWND hwndPage,
|
|
IN LPPROPSHEETPAGE pPropPage)
|
|
{
|
|
DWORD dwErr, dwPageId, dwShowCommand;
|
|
RASSRV_PAGE_CONTEXT * pPageCtx = NULL;
|
|
RASSRV_PAGESET_CONTEXT * pPageSetCtx = NULL;
|
|
HWND hwndSheet = GetParent(hwndPage);
|
|
int ret;
|
|
|
|
//
|
|
// Retrieve the per page context as well as the per-page-set context.
|
|
// these will have been provided by the caller and are placed in the
|
|
// lparam.
|
|
//
|
|
pPageCtx = (RASSRV_PAGE_CONTEXT *) pPropPage->lParam;
|
|
pPageSetCtx = (RASSRV_PAGESET_CONTEXT *) pPageCtx->pvContext;
|
|
|
|
// Associate the page's context with the page.
|
|
//
|
|
SetProp(hwndPage, Globals.atmRassrvPageData, (HANDLE)pPageCtx);
|
|
|
|
// Record the handle to the property sheet.
|
|
pPageSetCtx->hwndSheet = hwndSheet;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
//
|
|
// Callback occurs whenever a page is being created or
|
|
// destroyed.
|
|
//
|
|
UINT
|
|
CALLBACK
|
|
RasSrvInitDestroyPropSheetCb(
|
|
IN HWND hwndPage,
|
|
IN UINT uMsg,
|
|
IN LPPROPSHEETPAGE pPropPage)
|
|
{
|
|
RASSRV_PAGE_CONTEXT * pPageCtx = NULL;
|
|
RASSRV_PAGESET_CONTEXT * pPageSetCtx = NULL;
|
|
HWND hwndSheet = GetParent(hwndPage);
|
|
BOOL bLastPage = FALSE, bStopService = FALSE;
|
|
|
|
// Retrieve the per-page context
|
|
//pPageCtx = (RASSRV_PAGE_CONTEXT *)
|
|
// GetProp(hwndPage, Globals.atmRassrvPageData);
|
|
pPageCtx = (RASSRV_PAGE_CONTEXT *) pPropPage->lParam;
|
|
if (pPageCtx == NULL)
|
|
{
|
|
return ERROR_CAN_NOT_COMPLETE;
|
|
}
|
|
|
|
// Get the per-group-of-related-pages context. There may be multiple
|
|
// instances of this context per wizard/property sheet. For example,
|
|
// the Incoming connections wizard and the DCC host wizard both have
|
|
// sets of pages that share different contexts.
|
|
//
|
|
pPageSetCtx = (RASSRV_PAGESET_CONTEXT *) pPageCtx->pvContext;
|
|
|
|
// This callback is only used for cleanup
|
|
if (uMsg != PSPCB_RELEASE)
|
|
{
|
|
// Record that the given page is referencing
|
|
// the given pageset context.
|
|
pPageSetCtx->dwPagesInited |= pPageCtx->dwId;
|
|
|
|
// Return true to indicate that the page should
|
|
// be created.
|
|
return TRUE;
|
|
}
|
|
|
|
// Cleanup the page set information.
|
|
//
|
|
if (pPageSetCtx != NULL)
|
|
{
|
|
// Record that this page is cleaned up
|
|
pPageSetCtx->dwPagesInited &= ~(pPageCtx->dwId);
|
|
|
|
// When the dwPagesInited variable hits zero,
|
|
// it means that no other pages in the current
|
|
// wizard/propsheet are referencing this propsheet
|
|
// context. Now is the time to cleanup all resources
|
|
// held by the context.
|
|
if (pPageSetCtx->dwPagesInited == 0)
|
|
{
|
|
// Commit the settings if we are supposed to do
|
|
// so
|
|
if (pPageSetCtx->bCommitOnClose)
|
|
{
|
|
DbgOutputTrace("RasSrvCleanPropSht commit dbs.");
|
|
RassrvCommitSettings ((PVOID)pPageSetCtx, pPageCtx->dwType);
|
|
}
|
|
|
|
// Close the databases
|
|
DbgOutputTrace("RasSrvCleanPropSht closing dbs.");
|
|
if (pPageSetCtx->hUserDatabase)
|
|
{
|
|
usrCloseLocalDatabase(pPageSetCtx->hUserDatabase);
|
|
}
|
|
|
|
if (pPageSetCtx->hDeviceDatabase)
|
|
{
|
|
devCloseDatabase(pPageSetCtx->hDeviceDatabase);
|
|
}
|
|
|
|
if (pPageSetCtx->hMiscDatabase)
|
|
{
|
|
miscCloseDatabase(pPageSetCtx->hMiscDatabase);
|
|
}
|
|
|
|
if (pPageSetCtx->hNetCompDatabase)
|
|
{
|
|
netDbClose(pPageSetCtx->hNetCompDatabase);
|
|
}
|
|
|
|
// Since there are no other pages referencing this property
|
|
// sheet context, go ahead and free it.
|
|
DbgOutputTrace (
|
|
"RasSrvCleanPropSht %d freeing pageset data.",
|
|
pPageCtx->dwId);
|
|
RassrvFree(pPageSetCtx);
|
|
}
|
|
}
|
|
|
|
// Mark the page as dead
|
|
SetProp (hwndPage, Globals.atmRassrvPageData, NULL);
|
|
|
|
// This page is gone, so clear its context
|
|
DbgOutputTrace (
|
|
"RasSrvCleanPropSht %d freeing page data.",
|
|
pPageCtx->dwId);
|
|
RassrvFree(pPageCtx);
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
// For whistler 480871
|
|
//
|
|
DWORD
|
|
RasSrvIsICConfigured(
|
|
OUT BOOL * pfConfig)
|
|
{
|
|
DWORD dwErr = NO_ERROR, dwValue;
|
|
|
|
if( NULL == pfConfig )
|
|
{
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
dwErr = RassrvICConfigAccess( FALSE, // Query Value
|
|
&dwValue );
|
|
if( NO_ERROR == dwErr )
|
|
{
|
|
*pfConfig = ( dwValue > 0 )? TRUE : FALSE;
|
|
}
|
|
|
|
return dwErr;
|
|
}
|
|
|
|
DWORD
|
|
RassrvSetICConfig(
|
|
IN DWORD dwValue
|
|
)
|
|
{
|
|
return RassrvICConfigAccess( TRUE, // Set Value
|
|
&dwValue );
|
|
}
|
|
|
|
DWORD
|
|
RassrvICConfigAccess(
|
|
IN BOOL fSet,
|
|
IN DWORD * pdwValue
|
|
)
|
|
{
|
|
DWORD dwErr = NO_ERROR;
|
|
const WCHAR pwszServiceKey[] =
|
|
L"SYSTEM\\CurrentControlSet\\Services\\RemoteAccess\\Parameters";
|
|
const WCHAR pwszValue[] = L"IcConfigured";
|
|
HKEY hkParam = NULL;
|
|
|
|
if ( NULL == pdwValue )
|
|
{
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
do
|
|
{
|
|
// Attempt to open the service registry key
|
|
dwErr = RegOpenKeyExW(
|
|
HKEY_LOCAL_MACHINE,
|
|
pwszServiceKey,
|
|
0,
|
|
KEY_READ | KEY_WRITE,
|
|
&hkParam);
|
|
|
|
// If we opened the key ok, then we can assume
|
|
// that the service is installed
|
|
if ( ERROR_SUCCESS != dwErr )
|
|
{
|
|
break;
|
|
}
|
|
|
|
// Set or Clear the IcConfigured Value
|
|
//
|
|
if ( fSet )
|
|
{
|
|
dwErr = RegSetValueExW( hkParam,
|
|
pwszValue,
|
|
0,
|
|
REG_DWORD,
|
|
(BYTE*)pdwValue,
|
|
sizeof(DWORD)
|
|
);
|
|
}
|
|
else // Query the IcConfigured Value
|
|
{
|
|
|
|
DWORD dwType, dwSize;
|
|
|
|
dwSize = sizeof(DWORD);
|
|
*pdwValue = 0;
|
|
RegQueryValueEx( hkParam,
|
|
pwszValue,
|
|
0,
|
|
&dwType,
|
|
(BYTE*)pdwValue,
|
|
&dwSize
|
|
);
|
|
|
|
}
|
|
}
|
|
while(FALSE);
|
|
|
|
if ( hkParam )
|
|
{
|
|
RegCloseKey( hkParam );
|
|
}
|
|
|
|
return dwErr;
|
|
}
|
|
|
|
// Commits any settings in the given context.
|
|
//
|
|
DWORD
|
|
APIENTRY
|
|
RassrvCommitSettings (
|
|
IN PVOID pvContext,
|
|
IN DWORD dwRasWizType)
|
|
{
|
|
RASSRV_PAGESET_CONTEXT * pPageSetCtx =
|
|
(RASSRV_PAGESET_CONTEXT *)pvContext;
|
|
|
|
RASSRV_PROPSHEET_CONTEXT * pPropSheetCtx = NULL;
|
|
|
|
DbgOutputTrace ("RassrvCommitSettings entered : %x", dwRasWizType);
|
|
|
|
if (pPageSetCtx)
|
|
{
|
|
BOOL fCallSetPortMapping = TRUE;
|
|
|
|
// Flush all appropriate settings
|
|
if (pPageSetCtx->hUserDatabase)
|
|
{
|
|
usrFlushLocalDatabase(pPageSetCtx->hUserDatabase);
|
|
}
|
|
|
|
if (pPageSetCtx->hDeviceDatabase)
|
|
{
|
|
//This must be called before devFlushDatabase
|
|
//for whistler bug 123769
|
|
//
|
|
fCallSetPortMapping = devIsVpnEnableChanged( pPageSetCtx->hDeviceDatabase );
|
|
|
|
devFlushDatabase(pPageSetCtx->hDeviceDatabase);
|
|
}
|
|
|
|
if (pPageSetCtx->hMiscDatabase)
|
|
{
|
|
miscFlushDatabase(pPageSetCtx->hMiscDatabase);
|
|
}
|
|
|
|
if (pPageSetCtx->hNetCompDatabase)
|
|
{
|
|
netDbFlush(pPageSetCtx->hNetCompDatabase);
|
|
}
|
|
|
|
// Set state so that the service will not be stopped.
|
|
if (pPageSetCtx->hwndSheet)
|
|
{
|
|
DbgOutputTrace ("RassrvCommitSettings: keep svc running.");
|
|
pPropSheetCtx = (RASSRV_PROPSHEET_CONTEXT *)
|
|
GetProp(pPageSetCtx->hwndSheet, Globals.atmRassrvPageData);
|
|
|
|
if (pPropSheetCtx)
|
|
{
|
|
pPropSheetCtx->bLeaveRemoteAccessRunning = TRUE;
|
|
}
|
|
}
|
|
|
|
//whistler bug 123769,
|
|
//<one of the scenarios>
|
|
//Set up PortMapping for all possible connections
|
|
//when we are going to create a Incoming Connection
|
|
//with VPN enabled
|
|
|
|
if ( fCallSetPortMapping &&
|
|
FIsUserAdminOrPowerUser() &&
|
|
IsFirewallAvailablePlatform() && //Add this for bug 342810
|
|
IsGPAEnableFirewall() )
|
|
{
|
|
HnPMConfigureIfVpnEnabled( TRUE, pPageSetCtx->hDeviceDatabase );
|
|
}
|
|
|
|
// For whistler 480871
|
|
// Mark the registry if IC is configured
|
|
RassrvSetICConfig( 1 );
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
//
|
|
// Causes the remoteaccess service to not be stopped even if the context
|
|
// associated with the given property sheet page is never committed.
|
|
//
|
|
DWORD
|
|
RasSrvLeaveServiceRunning (
|
|
IN HWND hwndPage)
|
|
{
|
|
RASSRV_PAGE_CONTEXT * pPageCtx =
|
|
(RASSRV_PAGE_CONTEXT *)GetProp(hwndPage, Globals.atmRassrvPageData);
|
|
RASSRV_PAGESET_CONTEXT * pPageSetCtx =
|
|
(RASSRV_PAGESET_CONTEXT *) pPageCtx->pvContext;
|
|
RASSRV_PROPSHEET_CONTEXT * pPropSheetCtx = NULL;
|
|
|
|
DbgOutputTrace ("RasSrvLeaveServiceRunning entered for type");
|
|
|
|
if (! pPageSetCtx)
|
|
{
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
// Let the property sheet know that some settings have been committed
|
|
// so that it will not stop the remoteaccess service when it closes.
|
|
if (pPageSetCtx->hwndSheet)
|
|
{
|
|
DbgOutputTrace ("RasSrvLeaveServiceRunning: keep svc running.");
|
|
pPropSheetCtx = (RASSRV_PROPSHEET_CONTEXT *)
|
|
GetProp(pPageSetCtx->hwndSheet, Globals.atmRassrvPageData);
|
|
if (pPropSheetCtx)
|
|
{
|
|
pPropSheetCtx->bLeaveRemoteAccessRunning = TRUE;
|
|
}
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
// Called just before a page is activated. Return NO_ERROR to allow the
|
|
// activation and an error code to reject it.
|
|
DWORD
|
|
RasSrvActivatePage (
|
|
IN HWND hwndPage,
|
|
IN NMHDR *pData)
|
|
{
|
|
BOOL fAdminOrPower;
|
|
MSGARGS MsgArgs;
|
|
|
|
|
|
RASSRV_PAGE_CONTEXT * pPageCtx =
|
|
(RASSRV_PAGE_CONTEXT *)
|
|
GetProp(hwndPage, Globals.atmRassrvPageData);
|
|
|
|
RASSRV_PAGESET_CONTEXT * pPageSetCtx =
|
|
(RASSRV_PAGESET_CONTEXT *) pPageCtx->pvContext;
|
|
|
|
RASSRV_PROPSHEET_CONTEXT * pPropSheetCtx = NULL;
|
|
HWND hwndSheet = GetParent(hwndPage);
|
|
DWORD dwErr, dwReason = 0;
|
|
|
|
DbgOutputTrace("RasSrvActivatePage: Entered for %x", pPageCtx->dwId);
|
|
|
|
ZeroMemory(&MsgArgs, sizeof(MsgArgs));
|
|
MsgArgs.dwFlags = MB_OK;
|
|
|
|
// Make sure we have a context for this page.
|
|
if (!pPageSetCtx)
|
|
{
|
|
return ERROR_CAN_NOT_COMPLETE;
|
|
}
|
|
|
|
// Record the first page in the page set if needed
|
|
//
|
|
if (pPageSetCtx->hwndFirstPage == NULL)
|
|
{
|
|
pPageSetCtx->hwndFirstPage = hwndPage;
|
|
}
|
|
|
|
// Make sure that we can show
|
|
if (pPageSetCtx->bShow == FALSE)
|
|
{
|
|
DbgOutputTrace("RasSrvActivatePage: Show turned off");
|
|
return ERROR_CAN_NOT_COMPLETE;
|
|
}
|
|
|
|
// Manipulate settings in the property sheet
|
|
// context
|
|
pPropSheetCtx = GetProp(hwndSheet, Globals.atmRassrvPageData);
|
|
|
|
|
|
|
|
// Make sure everything's ok with the services we rely on.
|
|
//
|
|
if (pPropSheetCtx != NULL)
|
|
{
|
|
|
|
//Check if the current user has enough privileges
|
|
//For Whistler Bug #235091
|
|
//
|
|
fAdminOrPower = FIsUserAdminOrPowerUser();
|
|
if ( !fAdminOrPower )
|
|
{
|
|
if (hwndPage == pPageSetCtx->hwndFirstPage)
|
|
{
|
|
MsgDlgUtil(
|
|
GetActiveWindow(),
|
|
ERR_SERVICE_NOT_GRANTED,
|
|
&MsgArgs,
|
|
Globals.hInstDll,
|
|
WRN_TITLE);
|
|
|
|
PostMessage(hwndSheet, PSM_SETCURSEL, 0, 0);
|
|
}
|
|
|
|
return ERROR_CAN_NOT_COMPLETE;
|
|
}
|
|
|
|
dwErr = RasSrvServiceInitialize(
|
|
pPropSheetCtx,
|
|
hwndPage,
|
|
&dwReason);
|
|
|
|
if (dwErr != NO_ERROR)
|
|
{
|
|
if (hwndPage == pPageSetCtx->hwndFirstPage)
|
|
{
|
|
// Display the appropriate message
|
|
//
|
|
MsgDlgUtil(
|
|
GetActiveWindow(),
|
|
(dwReason == RASSRV_REASON_Pending) ?
|
|
SID_SERVICE_StopPending :
|
|
ERR_SERVICE_CANT_START,
|
|
&MsgArgs,
|
|
Globals.hInstDll,
|
|
WRN_TITLE);
|
|
|
|
PostMessage(hwndSheet, PSM_SETCURSEL, 0, 0);
|
|
PostMessage(hwndSheet, PSM_PRESSBUTTON, (WPARAM)PSBTN_NEXT, 0);
|
|
}
|
|
|
|
return dwErr;
|
|
}
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
//
|
|
// Flags the context associated with the given page to have its settings
|
|
// committed when the dialog closes
|
|
//
|
|
DWORD
|
|
RasSrvCommitSettingsOnClose (
|
|
IN HWND hwndPage)
|
|
{
|
|
RASSRV_PAGE_CONTEXT * pPageCtx =
|
|
(RASSRV_PAGE_CONTEXT *) GetProp(hwndPage, Globals.atmRassrvPageData);
|
|
RASSRV_PAGESET_CONTEXT * pPageSetCtx =
|
|
(RASSRV_PAGESET_CONTEXT *) pPageCtx->pvContext;
|
|
|
|
pPageSetCtx->bCommitOnClose = TRUE;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
//
|
|
// Returns the id of the page whose handle is hwndPage
|
|
//
|
|
DWORD
|
|
RasSrvGetPageId (
|
|
IN HWND hwndPage,
|
|
OUT LPDWORD lpdwId)
|
|
{
|
|
RASSRV_PAGE_CONTEXT * pPageCtx =
|
|
(RASSRV_PAGE_CONTEXT *)GetProp(hwndPage, Globals.atmRassrvPageData);
|
|
|
|
if (!lpdwId)
|
|
{
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (!pPageCtx)
|
|
{
|
|
return ERROR_NOT_FOUND;
|
|
}
|
|
|
|
*lpdwId = pPageCtx->dwId;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
//
|
|
// Gets a handle to a particular database, opening the database
|
|
// as needed.
|
|
//
|
|
DWORD
|
|
RasSrvGetDatabaseHandle(
|
|
IN HWND hwndPage,
|
|
IN DWORD dwDatabaseId,
|
|
OUT HANDLE * hDatabase)
|
|
{
|
|
RASSRV_PAGE_CONTEXT * pPageCtx =
|
|
(RASSRV_PAGE_CONTEXT *)GetProp(hwndPage, Globals.atmRassrvPageData);
|
|
RASSRV_PAGESET_CONTEXT * pPageSetCtx =
|
|
(RASSRV_PAGESET_CONTEXT *) pPageCtx->pvContext;
|
|
|
|
if (!pPageSetCtx || !hDatabase)
|
|
{
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
// Key off of the database id, opening databases as needed
|
|
switch (dwDatabaseId)
|
|
{
|
|
case ID_DEVICE_DATABASE:
|
|
if (pPageSetCtx->hDeviceDatabase == NULL)
|
|
{
|
|
devOpenDatabase(&(pPageSetCtx->hDeviceDatabase));
|
|
}
|
|
*hDatabase = pPageSetCtx->hDeviceDatabase;
|
|
break;
|
|
|
|
case ID_USER_DATABASE:
|
|
if (pPageSetCtx->hUserDatabase == NULL)
|
|
{
|
|
usrOpenLocalDatabase(&(pPageSetCtx->hUserDatabase));
|
|
}
|
|
*hDatabase = pPageSetCtx->hUserDatabase;
|
|
break;
|
|
|
|
case ID_MISC_DATABASE:
|
|
if (pPageSetCtx->hMiscDatabase == NULL)
|
|
{
|
|
miscOpenDatabase(&(pPageSetCtx->hMiscDatabase));
|
|
}
|
|
*hDatabase = pPageSetCtx->hMiscDatabase;
|
|
break;
|
|
|
|
case ID_NETCOMP_DATABASE:
|
|
{
|
|
if (pPageSetCtx->hNetCompDatabase == NULL)
|
|
{
|
|
WCHAR buf[64], *pszString = NULL;
|
|
DWORD dwCount;
|
|
|
|
dwCount = GetWindowTextW(
|
|
GetParent(hwndPage),
|
|
(PWCHAR)buf,
|
|
sizeof(buf)/sizeof(WCHAR));
|
|
if (dwCount == 0)
|
|
{
|
|
pszString = (PWCHAR) PszLoadString(
|
|
Globals.hInstDll,
|
|
SID_DEFAULT_CONNECTION_NAME);
|
|
lstrcpynW(
|
|
(PWCHAR)buf,
|
|
pszString,
|
|
sizeof(buf) / sizeof(WCHAR));
|
|
}
|
|
netDbOpen(&(pPageSetCtx->hNetCompDatabase), (PWCHAR)buf);
|
|
|
|
}
|
|
*hDatabase = pPageSetCtx->hNetCompDatabase;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return ERROR_CAN_NOT_COMPLETE;
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
//
|
|
// Creates a context to associate with a set of
|
|
// related pages in a property sheet or wizard.
|
|
//
|
|
DWORD
|
|
RassrvCreatePageSetCtx(
|
|
OUT PVOID * ppvContext)
|
|
{
|
|
RASSRV_PAGESET_CONTEXT * pPageCtx = NULL;
|
|
|
|
if (ppvContext == NULL)
|
|
{
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
// Allocate enough memory for a RASSRV_PAGESET_CONTEXT structure
|
|
*ppvContext = RassrvAlloc (sizeof(RASSRV_PAGESET_CONTEXT), TRUE);
|
|
if (*ppvContext == NULL)
|
|
{
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
|
|
// Initialize the page set context
|
|
pPageCtx = ((RASSRV_PAGESET_CONTEXT*)(*ppvContext));
|
|
pPageCtx->bShow = TRUE;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
//
|
|
// Function causes the ras-server specific pages to allow
|
|
// activation or not
|
|
//
|
|
DWORD
|
|
APIENTRY
|
|
RassrvShowWizPages (
|
|
IN PVOID pvContext,
|
|
IN BOOL bShow)
|
|
{
|
|
RASSRV_PAGESET_CONTEXT * pPageSetCtx =
|
|
(RASSRV_PAGESET_CONTEXT *) pvContext;
|
|
|
|
if (pPageSetCtx)
|
|
{
|
|
pPageSetCtx->bShow = bShow;
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
//
|
|
// Returns the maximum number of pages for the
|
|
// a ras server wizard of the given type. Return
|
|
// 0 to specify that a wizard not be run.
|
|
//
|
|
DWORD
|
|
APIENTRY
|
|
RassrvQueryMaxPageCount(
|
|
IN DWORD dwRasWizType)
|
|
{
|
|
BOOL bAllowWizard;
|
|
DWORD dwErr;
|
|
HANDLE hRasman;
|
|
BOOL bTemp;
|
|
|
|
// Find out if displaying the incoming connections wizard
|
|
// is allowed.
|
|
if (RasSrvAllowConnectionsWizard (&bAllowWizard) != NO_ERROR)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
// If the wizard is not to be run, return the appropriate
|
|
// count.
|
|
if (! bAllowWizard)
|
|
{
|
|
return RASSRVUI_WIZ_PAGE_COUNT_SWITCH;
|
|
}
|
|
|
|
// At this point, we know that everything's kosher. Return
|
|
// the number of pages that we support.
|
|
switch (dwRasWizType)
|
|
{
|
|
case RASWIZ_TYPE_INCOMING:
|
|
return RASSRVUI_WIZ_PAGE_COUNT_INCOMING;
|
|
break;
|
|
|
|
case RASWIZ_TYPE_DIRECT:
|
|
return RASSRVUI_WIZ_PAGE_COUNT_DIRECT;
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
//
|
|
// Filters messages for RasSrv Property Pages. If this function returns
|
|
// true, the window proc of the dialog window should return true without
|
|
// processing the message.
|
|
//
|
|
// This message filter does the following:
|
|
// 1. Maintains databases and grants access to them.
|
|
// 2. Starts/stops remoteaccess service as needed.
|
|
// 3. Maintains the per-page, per-pageset, and per-wizard contexts.
|
|
//
|
|
BOOL
|
|
RasSrvMessageFilter(
|
|
IN HWND hwndDlg,
|
|
IN UINT uMsg,
|
|
IN WPARAM wParam,
|
|
IN LPARAM lParam)
|
|
{
|
|
RASSRV_PROPSHEET_CONTEXT * pPropSheetCtx = NULL;
|
|
|
|
switch (uMsg)
|
|
{
|
|
// A page is being created. Initailizes all contexts with respect
|
|
// to this page and start services as needed.
|
|
case WM_INITDIALOG:
|
|
// Initialize and add the per-propsheet context if another
|
|
// page has not already done so.
|
|
//
|
|
{
|
|
HWND hwndSheet = GetParent(hwndDlg);
|
|
pPropSheetCtx = (RASSRV_PROPSHEET_CONTEXT *)
|
|
GetProp (
|
|
hwndSheet,
|
|
Globals.atmRassrvPageData);
|
|
if (!pPropSheetCtx)
|
|
{
|
|
pPropSheetCtx =
|
|
RassrvAlloc(
|
|
sizeof(RASSRV_PROPSHEET_CONTEXT),
|
|
TRUE);
|
|
|
|
SetProp (
|
|
hwndSheet,
|
|
Globals.atmRassrvPageData,
|
|
(HANDLE)pPropSheetCtx);
|
|
}
|
|
|
|
// Initialize the page
|
|
RasSrvPropsheetInitialize(
|
|
hwndDlg,
|
|
(LPPROPSHEETPAGE)lParam);
|
|
}
|
|
break;
|
|
|
|
case WM_DESTROY:
|
|
// WM_DESTROY is sent for each page that has been activated.
|
|
// Cleanup the global data if it hasn't already been
|
|
// cleaned up on a previous call to WM_DESTROY.
|
|
//
|
|
{
|
|
HWND hwndSheet = GetParent(hwndDlg);
|
|
pPropSheetCtx = (RASSRV_PROPSHEET_CONTEXT *)
|
|
GetProp(hwndSheet, Globals.atmRassrvPageData);
|
|
if (pPropSheetCtx)
|
|
{
|
|
if (!pPropSheetCtx->bLeaveRemoteAccessRunning)
|
|
{
|
|
DbgOutputTrace("Stop service.");
|
|
RasSrvServiceCleanup(hwndDlg);
|
|
}
|
|
DbgOutputTrace ("Free propsht data.");
|
|
RassrvFree (pPropSheetCtx);
|
|
|
|
// Reset the global data
|
|
SetProp (hwndSheet, Globals.atmRassrvPageData, NULL);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case WM_NOTIFY:
|
|
{
|
|
NMHDR * pNotifyData = (NMHDR*)lParam;
|
|
|
|
switch (pNotifyData->code)
|
|
{
|
|
// The page is becoming active.
|
|
case PSN_SETACTIVE:
|
|
DbgOutputTrace(
|
|
"SetActive: %x %x",
|
|
pNotifyData->hwndFrom,
|
|
pNotifyData->idFrom);
|
|
|
|
if (RasSrvActivatePage(hwndDlg, pNotifyData) != NO_ERROR)
|
|
{
|
|
// reject activation
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
|
|
return TRUE;
|
|
}
|
|
break;
|
|
|
|
// Ok was pressed on the property sheet
|
|
case PSN_APPLY:
|
|
RasSrvCommitSettingsOnClose (hwndDlg);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|