windows-nt/Source/XPSP1/NT/net/rras/ras/ui/rassrvui/rassrv.c

918 lines
26 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*
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);
//
// 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;
}
// 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 );
}
}
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;
}