Source code of Windows XP (NT5)
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.

917 lines
26 KiB

  1. /*
  2. File Rassrv.h
  3. Functions that perform ras server operations that can be implemented
  4. independent of the ui.
  5. Paul Mayfield, 10/7/97
  6. */
  7. #include "rassrv.h"
  8. // ============================================================
  9. // ============================================================
  10. // Functions to maintain data accross property sheet pages.
  11. // ============================================================
  12. // ============================================================
  13. // This message queries all other pages to find out if
  14. // any other ras server pages exist. If this message is
  15. // not responded to, then we know it's safe to cleanup
  16. // any global context in the wizard/property sheet.
  17. #define RASSRV_CMD_QUERY_LIVING 237
  18. // These commands hide and show ras server pages.
  19. #define RASSRV_CMD_HIDE_PAGES 238
  20. #define RASSRV_CMD_SHOW_PAGES 239
  21. //
  22. // Reasons for RasSrvSErviceInitialize to fail
  23. //
  24. #define RASSRV_REASON_SvcError 0
  25. #define RASSRV_REASON_Pending 1
  26. //
  27. // This structure defines the data that needs to be stored
  28. // for each set of related property pages. Multiple instances
  29. // of this context can exist for each wizard/propsheet.
  30. //
  31. typedef struct _RASSRV_PAGESET_CONTEXT
  32. {
  33. HWND hwndSheet;
  34. HWND hwndFirstPage; // first to be activated in the set
  35. HANDLE hDeviceDatabase;
  36. HANDLE hUserDatabase;
  37. HANDLE hNetCompDatabase;
  38. HANDLE hMiscDatabase;
  39. DWORD dwPagesInited; // Acts as a reference-count mechansim so we know
  40. // what set of pages in the wizard/propsheet are
  41. // referencing this context.
  42. BOOL bShow; // Whether pages that ref this context show be vis.
  43. BOOL bCommitOnClose; // Whether to commit settings changes on close
  44. } RASSRV_PAGESET_CONTEXT;
  45. //
  46. // This structure defines the global context that is available on a
  47. // per-wizard/propsheet basis. Even pages that don't share the same
  48. // RASSRV_PAGESET_CONTEXT context will share this structure if they
  49. // are owned by the same wizard/propsheet.
  50. //
  51. typedef struct _RASSRV_PROPSHEET_CONTEXT
  52. {
  53. BOOL bRemoteAccessWasStarted;
  54. BOOL bRemoteAccessIsRunning;
  55. BOOL bLeaveRemoteAccessRunning;
  56. DWORD dwServiceErr;
  57. } RASSRV_PROPSHEET_CONTEXT;
  58. DWORD
  59. APIENTRY
  60. RassrvCommitSettings (
  61. IN PVOID pvContext,
  62. IN DWORD dwRasWizType);
  63. //
  64. // Verifies that the current state of services in the system
  65. // is condusive to configuring incoming connectins starting
  66. // services as needed.
  67. //
  68. DWORD
  69. RasSrvServiceInitialize(
  70. IN RASSRV_PROPSHEET_CONTEXT * pPropSheetCtx,
  71. IN HWND hwndSheet,
  72. OUT LPDWORD lpdwReason)
  73. {
  74. DWORD dwErr = NO_ERROR;
  75. HANDLE hDialupService = NULL;
  76. BOOL bPending = FALSE;
  77. // If we already know there's an error, then there's no
  78. // need to proceed.
  79. //
  80. if (pPropSheetCtx->dwServiceErr)
  81. {
  82. return pPropSheetCtx->dwServiceErr;
  83. }
  84. // If we already started the service or if we already know the
  85. // service is running, then there's nothing to do.
  86. //
  87. if (pPropSheetCtx->bRemoteAccessWasStarted ||
  88. pPropSheetCtx->bRemoteAccessIsRunning
  89. )
  90. {
  91. return NO_ERROR;
  92. }
  93. do
  94. {
  95. // Get a reference to the service
  96. //
  97. dwErr = SvcOpenRemoteAccess(&hDialupService);
  98. if (dwErr != NO_ERROR)
  99. {
  100. break;
  101. }
  102. // See if we're pending something.
  103. //
  104. dwErr = SvcIsPending(hDialupService, &bPending);
  105. if (dwErr != NO_ERROR)
  106. {
  107. break;
  108. }
  109. // If the service is stopping, then we can't continue
  110. //
  111. if (bPending)
  112. {
  113. *lpdwReason = RASSRV_REASON_Pending;
  114. dwErr = ERROR_CAN_NOT_COMPLETE;
  115. break;
  116. }
  117. // See if we're started
  118. //
  119. dwErr = SvcIsStarted(
  120. hDialupService,
  121. &(pPropSheetCtx->bRemoteAccessIsRunning));
  122. if (dwErr != NO_ERROR)
  123. {
  124. *lpdwReason = RASSRV_REASON_SvcError;
  125. pPropSheetCtx->dwServiceErr = dwErr;
  126. break;
  127. }
  128. // If we find out the service is running, there's nothing to do
  129. if (pPropSheetCtx->bRemoteAccessIsRunning)
  130. {
  131. pPropSheetCtx->bLeaveRemoteAccessRunning = TRUE;
  132. break;
  133. }
  134. // Start the service since it's not running.
  135. dwErr = RasSrvInitializeService();
  136. if (dwErr != NO_ERROR)
  137. {
  138. *lpdwReason = RASSRV_REASON_SvcError;
  139. pPropSheetCtx->dwServiceErr = dwErr;
  140. break;
  141. }
  142. // Record the fact that we did so.
  143. pPropSheetCtx->bRemoteAccessWasStarted = TRUE;
  144. pPropSheetCtx->bRemoteAccessIsRunning = TRUE;
  145. } while (FALSE);
  146. // Cleanup
  147. {
  148. // Cleanup the reference to the dialup service
  149. //
  150. if (hDialupService)
  151. {
  152. SvcClose(hDialupService);
  153. }
  154. }
  155. return dwErr;
  156. }
  157. //
  158. // Abort any changes to the remoteaccess service that were made
  159. // during RasSrvServiceInitialize
  160. //
  161. DWORD
  162. RasSrvServiceCleanup(
  163. IN HWND hwndPage)
  164. {
  165. DWORD dwErr;
  166. RASSRV_PROPSHEET_CONTEXT * pPropSheetCtx = NULL;
  167. pPropSheetCtx = (RASSRV_PROPSHEET_CONTEXT *)
  168. GetProp(GetParent(hwndPage), Globals.atmRassrvPageData);
  169. if (pPropSheetCtx == NULL)
  170. {
  171. return ERROR_CAN_NOT_COMPLETE;
  172. }
  173. // If we started the modified the remote access service, reverse
  174. // the changes and record the fact that we did
  175. if (pPropSheetCtx->bRemoteAccessWasStarted)
  176. {
  177. if ((dwErr = RasSrvCleanupService()) != NO_ERROR)
  178. {
  179. return dwErr;
  180. }
  181. pPropSheetCtx->bRemoteAccessWasStarted = FALSE;
  182. pPropSheetCtx->bLeaveRemoteAccessRunning = FALSE;
  183. pPropSheetCtx->bRemoteAccessIsRunning = FALSE;
  184. }
  185. return NO_ERROR;
  186. }
  187. //
  188. // Intializes a property sheet. This causes a handle to the
  189. // property sheet data object to be placed in the GWLP_USERDATA
  190. // section of the window handle to the page.
  191. //
  192. DWORD
  193. RasSrvPropsheetInitialize(
  194. IN HWND hwndPage,
  195. IN LPPROPSHEETPAGE pPropPage)
  196. {
  197. DWORD dwErr, dwPageId, dwShowCommand;
  198. RASSRV_PAGE_CONTEXT * pPageCtx = NULL;
  199. RASSRV_PAGESET_CONTEXT * pPageSetCtx = NULL;
  200. HWND hwndSheet = GetParent(hwndPage);
  201. int ret;
  202. //
  203. // Retrieve the per page context as well as the per-page-set context.
  204. // these will have been provided by the caller and are placed in the
  205. // lparam.
  206. //
  207. pPageCtx = (RASSRV_PAGE_CONTEXT *) pPropPage->lParam;
  208. pPageSetCtx = (RASSRV_PAGESET_CONTEXT *) pPageCtx->pvContext;
  209. // Associate the page's context with the page.
  210. //
  211. SetProp(hwndPage, Globals.atmRassrvPageData, (HANDLE)pPageCtx);
  212. // Record the handle to the property sheet.
  213. pPageSetCtx->hwndSheet = hwndSheet;
  214. return NO_ERROR;
  215. }
  216. //
  217. // Callback occurs whenever a page is being created or
  218. // destroyed.
  219. //
  220. UINT
  221. CALLBACK
  222. RasSrvInitDestroyPropSheetCb(
  223. IN HWND hwndPage,
  224. IN UINT uMsg,
  225. IN LPPROPSHEETPAGE pPropPage)
  226. {
  227. RASSRV_PAGE_CONTEXT * pPageCtx = NULL;
  228. RASSRV_PAGESET_CONTEXT * pPageSetCtx = NULL;
  229. HWND hwndSheet = GetParent(hwndPage);
  230. BOOL bLastPage = FALSE, bStopService = FALSE;
  231. // Retrieve the per-page context
  232. //pPageCtx = (RASSRV_PAGE_CONTEXT *)
  233. // GetProp(hwndPage, Globals.atmRassrvPageData);
  234. pPageCtx = (RASSRV_PAGE_CONTEXT *) pPropPage->lParam;
  235. if (pPageCtx == NULL)
  236. {
  237. return ERROR_CAN_NOT_COMPLETE;
  238. }
  239. // Get the per-group-of-related-pages context. There may be multiple
  240. // instances of this context per wizard/property sheet. For example,
  241. // the Incoming connections wizard and the DCC host wizard both have
  242. // sets of pages that share different contexts.
  243. //
  244. pPageSetCtx = (RASSRV_PAGESET_CONTEXT *) pPageCtx->pvContext;
  245. // This callback is only used for cleanup
  246. if (uMsg != PSPCB_RELEASE)
  247. {
  248. // Record that the given page is referencing
  249. // the given pageset context.
  250. pPageSetCtx->dwPagesInited |= pPageCtx->dwId;
  251. // Return true to indicate that the page should
  252. // be created.
  253. return TRUE;
  254. }
  255. // Cleanup the page set information.
  256. //
  257. if (pPageSetCtx != NULL)
  258. {
  259. // Record that this page is cleaned up
  260. pPageSetCtx->dwPagesInited &= ~(pPageCtx->dwId);
  261. // When the dwPagesInited variable hits zero,
  262. // it means that no other pages in the current
  263. // wizard/propsheet are referencing this propsheet
  264. // context. Now is the time to cleanup all resources
  265. // held by the context.
  266. if (pPageSetCtx->dwPagesInited == 0)
  267. {
  268. // Commit the settings if we are supposed to do
  269. // so
  270. if (pPageSetCtx->bCommitOnClose)
  271. {
  272. DbgOutputTrace("RasSrvCleanPropSht commit dbs.");
  273. RassrvCommitSettings ((PVOID)pPageSetCtx, pPageCtx->dwType);
  274. }
  275. // Close the databases
  276. DbgOutputTrace("RasSrvCleanPropSht closing dbs.");
  277. if (pPageSetCtx->hUserDatabase)
  278. {
  279. usrCloseLocalDatabase(pPageSetCtx->hUserDatabase);
  280. }
  281. if (pPageSetCtx->hDeviceDatabase)
  282. {
  283. devCloseDatabase(pPageSetCtx->hDeviceDatabase);
  284. }
  285. if (pPageSetCtx->hMiscDatabase)
  286. {
  287. miscCloseDatabase(pPageSetCtx->hMiscDatabase);
  288. }
  289. if (pPageSetCtx->hNetCompDatabase)
  290. {
  291. netDbClose(pPageSetCtx->hNetCompDatabase);
  292. }
  293. // Since there are no other pages referencing this property
  294. // sheet context, go ahead and free it.
  295. DbgOutputTrace (
  296. "RasSrvCleanPropSht %d freeing pageset data.",
  297. pPageCtx->dwId);
  298. RassrvFree(pPageSetCtx);
  299. }
  300. }
  301. // Mark the page as dead
  302. SetProp (hwndPage, Globals.atmRassrvPageData, NULL);
  303. // This page is gone, so clear its context
  304. DbgOutputTrace (
  305. "RasSrvCleanPropSht %d freeing page data.",
  306. pPageCtx->dwId);
  307. RassrvFree(pPageCtx);
  308. return NO_ERROR;
  309. }
  310. // Commits any settings in the given context.
  311. //
  312. DWORD
  313. APIENTRY
  314. RassrvCommitSettings (
  315. IN PVOID pvContext,
  316. IN DWORD dwRasWizType)
  317. {
  318. RASSRV_PAGESET_CONTEXT * pPageSetCtx =
  319. (RASSRV_PAGESET_CONTEXT *)pvContext;
  320. RASSRV_PROPSHEET_CONTEXT * pPropSheetCtx = NULL;
  321. DbgOutputTrace ("RassrvCommitSettings entered : %x", dwRasWizType);
  322. if (pPageSetCtx)
  323. {
  324. BOOL fCallSetPortMapping = TRUE;
  325. // Flush all appropriate settings
  326. if (pPageSetCtx->hUserDatabase)
  327. {
  328. usrFlushLocalDatabase(pPageSetCtx->hUserDatabase);
  329. }
  330. if (pPageSetCtx->hDeviceDatabase)
  331. {
  332. //This must be called before devFlushDatabase
  333. //for whistler bug 123769
  334. //
  335. fCallSetPortMapping = devIsVpnEnableChanged( pPageSetCtx->hDeviceDatabase );
  336. devFlushDatabase(pPageSetCtx->hDeviceDatabase);
  337. }
  338. if (pPageSetCtx->hMiscDatabase)
  339. {
  340. miscFlushDatabase(pPageSetCtx->hMiscDatabase);
  341. }
  342. if (pPageSetCtx->hNetCompDatabase)
  343. {
  344. netDbFlush(pPageSetCtx->hNetCompDatabase);
  345. }
  346. // Set state so that the service will not be stopped.
  347. if (pPageSetCtx->hwndSheet)
  348. {
  349. DbgOutputTrace ("RassrvCommitSettings: keep svc running.");
  350. pPropSheetCtx = (RASSRV_PROPSHEET_CONTEXT *)
  351. GetProp(pPageSetCtx->hwndSheet, Globals.atmRassrvPageData);
  352. if (pPropSheetCtx)
  353. {
  354. pPropSheetCtx->bLeaveRemoteAccessRunning = TRUE;
  355. }
  356. }
  357. //whistler bug 123769,
  358. //<one of the scenarios>
  359. //Set up PortMapping for all possible connections
  360. //when we are going to create a Incoming Connection
  361. //with VPN enabled
  362. if ( fCallSetPortMapping &&
  363. FIsUserAdminOrPowerUser() &&
  364. IsFirewallAvailablePlatform() && //Add this for bug 342810
  365. IsGPAEnableFirewall() )
  366. {
  367. HnPMConfigureIfVpnEnabled( TRUE, pPageSetCtx->hDeviceDatabase );
  368. }
  369. }
  370. return NO_ERROR;
  371. }
  372. //
  373. // Causes the remoteaccess service to not be stopped even if the context
  374. // associated with the given property sheet page is never committed.
  375. //
  376. DWORD
  377. RasSrvLeaveServiceRunning (
  378. IN HWND hwndPage)
  379. {
  380. RASSRV_PAGE_CONTEXT * pPageCtx =
  381. (RASSRV_PAGE_CONTEXT *)GetProp(hwndPage, Globals.atmRassrvPageData);
  382. RASSRV_PAGESET_CONTEXT * pPageSetCtx =
  383. (RASSRV_PAGESET_CONTEXT *) pPageCtx->pvContext;
  384. RASSRV_PROPSHEET_CONTEXT * pPropSheetCtx = NULL;
  385. DbgOutputTrace ("RasSrvLeaveServiceRunning entered for type");
  386. if (! pPageSetCtx)
  387. {
  388. return ERROR_INVALID_PARAMETER;
  389. }
  390. // Let the property sheet know that some settings have been committed
  391. // so that it will not stop the remoteaccess service when it closes.
  392. if (pPageSetCtx->hwndSheet)
  393. {
  394. DbgOutputTrace ("RasSrvLeaveServiceRunning: keep svc running.");
  395. pPropSheetCtx = (RASSRV_PROPSHEET_CONTEXT *)
  396. GetProp(pPageSetCtx->hwndSheet, Globals.atmRassrvPageData);
  397. if (pPropSheetCtx)
  398. {
  399. pPropSheetCtx->bLeaveRemoteAccessRunning = TRUE;
  400. }
  401. }
  402. return NO_ERROR;
  403. }
  404. // Called just before a page is activated. Return NO_ERROR to allow the
  405. // activation and an error code to reject it.
  406. DWORD
  407. RasSrvActivatePage (
  408. IN HWND hwndPage,
  409. IN NMHDR *pData)
  410. {
  411. BOOL fAdminOrPower;
  412. MSGARGS MsgArgs;
  413. RASSRV_PAGE_CONTEXT * pPageCtx =
  414. (RASSRV_PAGE_CONTEXT *)
  415. GetProp(hwndPage, Globals.atmRassrvPageData);
  416. RASSRV_PAGESET_CONTEXT * pPageSetCtx =
  417. (RASSRV_PAGESET_CONTEXT *) pPageCtx->pvContext;
  418. RASSRV_PROPSHEET_CONTEXT * pPropSheetCtx = NULL;
  419. HWND hwndSheet = GetParent(hwndPage);
  420. DWORD dwErr, dwReason = 0;
  421. DbgOutputTrace("RasSrvActivatePage: Entered for %x", pPageCtx->dwId);
  422. ZeroMemory(&MsgArgs, sizeof(MsgArgs));
  423. MsgArgs.dwFlags = MB_OK;
  424. // Make sure we have a context for this page.
  425. if (!pPageSetCtx)
  426. {
  427. return ERROR_CAN_NOT_COMPLETE;
  428. }
  429. // Record the first page in the page set if needed
  430. //
  431. if (pPageSetCtx->hwndFirstPage == NULL)
  432. {
  433. pPageSetCtx->hwndFirstPage = hwndPage;
  434. }
  435. // Make sure that we can show
  436. if (pPageSetCtx->bShow == FALSE)
  437. {
  438. DbgOutputTrace("RasSrvActivatePage: Show turned off");
  439. return ERROR_CAN_NOT_COMPLETE;
  440. }
  441. // Manipulate settings in the property sheet
  442. // context
  443. pPropSheetCtx = GetProp(hwndSheet, Globals.atmRassrvPageData);
  444. // Make sure everything's ok with the services we rely on.
  445. //
  446. if (pPropSheetCtx != NULL)
  447. {
  448. //Check if the current user has enough privileges
  449. //For Whistler Bug #235091
  450. //
  451. fAdminOrPower = FIsUserAdminOrPowerUser();
  452. if ( !fAdminOrPower )
  453. {
  454. if (hwndPage == pPageSetCtx->hwndFirstPage)
  455. {
  456. MsgDlgUtil(
  457. GetActiveWindow(),
  458. ERR_SERVICE_NOT_GRANTED,
  459. &MsgArgs,
  460. Globals.hInstDll,
  461. WRN_TITLE);
  462. PostMessage(hwndSheet, PSM_SETCURSEL, 0, 0);
  463. }
  464. return ERROR_CAN_NOT_COMPLETE;
  465. }
  466. dwErr = RasSrvServiceInitialize(
  467. pPropSheetCtx,
  468. hwndPage,
  469. &dwReason);
  470. if (dwErr != NO_ERROR)
  471. {
  472. if (hwndPage == pPageSetCtx->hwndFirstPage)
  473. {
  474. // Display the appropriate message
  475. //
  476. MsgDlgUtil(
  477. GetActiveWindow(),
  478. (dwReason == RASSRV_REASON_Pending) ?
  479. SID_SERVICE_StopPending :
  480. ERR_SERVICE_CANT_START,
  481. &MsgArgs,
  482. Globals.hInstDll,
  483. WRN_TITLE);
  484. PostMessage(hwndSheet, PSM_SETCURSEL, 0, 0);
  485. PostMessage(hwndSheet, PSM_PRESSBUTTON, (WPARAM)PSBTN_NEXT, 0);
  486. }
  487. return dwErr;
  488. }
  489. }
  490. return NO_ERROR;
  491. }
  492. //
  493. // Flags the context associated with the given page to have its settings
  494. // committed when the dialog closes
  495. //
  496. DWORD
  497. RasSrvCommitSettingsOnClose (
  498. IN HWND hwndPage)
  499. {
  500. RASSRV_PAGE_CONTEXT * pPageCtx =
  501. (RASSRV_PAGE_CONTEXT *) GetProp(hwndPage, Globals.atmRassrvPageData);
  502. RASSRV_PAGESET_CONTEXT * pPageSetCtx =
  503. (RASSRV_PAGESET_CONTEXT *) pPageCtx->pvContext;
  504. pPageSetCtx->bCommitOnClose = TRUE;
  505. return NO_ERROR;
  506. }
  507. //
  508. // Returns the id of the page whose handle is hwndPage
  509. //
  510. DWORD
  511. RasSrvGetPageId (
  512. IN HWND hwndPage,
  513. OUT LPDWORD lpdwId)
  514. {
  515. RASSRV_PAGE_CONTEXT * pPageCtx =
  516. (RASSRV_PAGE_CONTEXT *)GetProp(hwndPage, Globals.atmRassrvPageData);
  517. if (!lpdwId)
  518. {
  519. return ERROR_INVALID_PARAMETER;
  520. }
  521. if (!pPageCtx)
  522. {
  523. return ERROR_NOT_FOUND;
  524. }
  525. *lpdwId = pPageCtx->dwId;
  526. return NO_ERROR;
  527. }
  528. //
  529. // Gets a handle to a particular database, opening the database
  530. // as needed.
  531. //
  532. DWORD
  533. RasSrvGetDatabaseHandle(
  534. IN HWND hwndPage,
  535. IN DWORD dwDatabaseId,
  536. OUT HANDLE * hDatabase)
  537. {
  538. RASSRV_PAGE_CONTEXT * pPageCtx =
  539. (RASSRV_PAGE_CONTEXT *)GetProp(hwndPage, Globals.atmRassrvPageData);
  540. RASSRV_PAGESET_CONTEXT * pPageSetCtx =
  541. (RASSRV_PAGESET_CONTEXT *) pPageCtx->pvContext;
  542. if (!pPageSetCtx || !hDatabase)
  543. {
  544. return ERROR_INVALID_PARAMETER;
  545. }
  546. // Key off of the database id, opening databases as needed
  547. switch (dwDatabaseId)
  548. {
  549. case ID_DEVICE_DATABASE:
  550. if (pPageSetCtx->hDeviceDatabase == NULL)
  551. {
  552. devOpenDatabase(&(pPageSetCtx->hDeviceDatabase));
  553. }
  554. *hDatabase = pPageSetCtx->hDeviceDatabase;
  555. break;
  556. case ID_USER_DATABASE:
  557. if (pPageSetCtx->hUserDatabase == NULL)
  558. {
  559. usrOpenLocalDatabase(&(pPageSetCtx->hUserDatabase));
  560. }
  561. *hDatabase = pPageSetCtx->hUserDatabase;
  562. break;
  563. case ID_MISC_DATABASE:
  564. if (pPageSetCtx->hMiscDatabase == NULL)
  565. {
  566. miscOpenDatabase(&(pPageSetCtx->hMiscDatabase));
  567. }
  568. *hDatabase = pPageSetCtx->hMiscDatabase;
  569. break;
  570. case ID_NETCOMP_DATABASE:
  571. {
  572. if (pPageSetCtx->hNetCompDatabase == NULL)
  573. {
  574. WCHAR buf[64], *pszString = NULL;
  575. DWORD dwCount;
  576. dwCount = GetWindowTextW(
  577. GetParent(hwndPage),
  578. (PWCHAR)buf,
  579. sizeof(buf)/sizeof(WCHAR));
  580. if (dwCount == 0)
  581. {
  582. pszString = (PWCHAR) PszLoadString(
  583. Globals.hInstDll,
  584. SID_DEFAULT_CONNECTION_NAME);
  585. lstrcpynW(
  586. (PWCHAR)buf,
  587. pszString,
  588. sizeof(buf) / sizeof(WCHAR));
  589. }
  590. netDbOpen(&(pPageSetCtx->hNetCompDatabase), (PWCHAR)buf);
  591. }
  592. *hDatabase = pPageSetCtx->hNetCompDatabase;
  593. }
  594. break;
  595. default:
  596. return ERROR_CAN_NOT_COMPLETE;
  597. }
  598. return NO_ERROR;
  599. }
  600. //
  601. // Creates a context to associate with a set of
  602. // related pages in a property sheet or wizard.
  603. //
  604. DWORD
  605. RassrvCreatePageSetCtx(
  606. OUT PVOID * ppvContext)
  607. {
  608. RASSRV_PAGESET_CONTEXT * pPageCtx = NULL;
  609. if (ppvContext == NULL)
  610. {
  611. return ERROR_INVALID_PARAMETER;
  612. }
  613. // Allocate enough memory for a RASSRV_PAGESET_CONTEXT structure
  614. *ppvContext = RassrvAlloc (sizeof(RASSRV_PAGESET_CONTEXT), TRUE);
  615. if (*ppvContext == NULL)
  616. {
  617. return ERROR_NOT_ENOUGH_MEMORY;
  618. }
  619. // Initialize the page set context
  620. pPageCtx = ((RASSRV_PAGESET_CONTEXT*)(*ppvContext));
  621. pPageCtx->bShow = TRUE;
  622. return NO_ERROR;
  623. }
  624. //
  625. // Function causes the ras-server specific pages to allow
  626. // activation or not
  627. //
  628. DWORD
  629. APIENTRY
  630. RassrvShowWizPages (
  631. IN PVOID pvContext,
  632. IN BOOL bShow)
  633. {
  634. RASSRV_PAGESET_CONTEXT * pPageSetCtx =
  635. (RASSRV_PAGESET_CONTEXT *) pvContext;
  636. if (pPageSetCtx)
  637. {
  638. pPageSetCtx->bShow = bShow;
  639. }
  640. return NO_ERROR;
  641. }
  642. //
  643. // Returns the maximum number of pages for the
  644. // a ras server wizard of the given type. Return
  645. // 0 to specify that a wizard not be run.
  646. //
  647. DWORD
  648. APIENTRY
  649. RassrvQueryMaxPageCount(
  650. IN DWORD dwRasWizType)
  651. {
  652. BOOL bAllowWizard;
  653. DWORD dwErr;
  654. HANDLE hRasman;
  655. BOOL bTemp;
  656. // Find out if displaying the incoming connections wizard
  657. // is allowed.
  658. if (RasSrvAllowConnectionsWizard (&bAllowWizard) != NO_ERROR)
  659. {
  660. return 0;
  661. }
  662. // If the wizard is not to be run, return the appropriate
  663. // count.
  664. if (! bAllowWizard)
  665. {
  666. return RASSRVUI_WIZ_PAGE_COUNT_SWITCH;
  667. }
  668. // At this point, we know that everything's kosher. Return
  669. // the number of pages that we support.
  670. switch (dwRasWizType)
  671. {
  672. case RASWIZ_TYPE_INCOMING:
  673. return RASSRVUI_WIZ_PAGE_COUNT_INCOMING;
  674. break;
  675. case RASWIZ_TYPE_DIRECT:
  676. return RASSRVUI_WIZ_PAGE_COUNT_DIRECT;
  677. break;
  678. }
  679. return 0;
  680. }
  681. //
  682. // Filters messages for RasSrv Property Pages. If this function returns
  683. // true, the window proc of the dialog window should return true without
  684. // processing the message.
  685. //
  686. // This message filter does the following:
  687. // 1. Maintains databases and grants access to them.
  688. // 2. Starts/stops remoteaccess service as needed.
  689. // 3. Maintains the per-page, per-pageset, and per-wizard contexts.
  690. //
  691. BOOL
  692. RasSrvMessageFilter(
  693. IN HWND hwndDlg,
  694. IN UINT uMsg,
  695. IN WPARAM wParam,
  696. IN LPARAM lParam)
  697. {
  698. RASSRV_PROPSHEET_CONTEXT * pPropSheetCtx = NULL;
  699. switch (uMsg)
  700. {
  701. // A page is being created. Initailizes all contexts with respect
  702. // to this page and start services as needed.
  703. case WM_INITDIALOG:
  704. // Initialize and add the per-propsheet context if another
  705. // page has not already done so.
  706. //
  707. {
  708. HWND hwndSheet = GetParent(hwndDlg);
  709. pPropSheetCtx = (RASSRV_PROPSHEET_CONTEXT *)
  710. GetProp (
  711. hwndSheet,
  712. Globals.atmRassrvPageData);
  713. if (!pPropSheetCtx)
  714. {
  715. pPropSheetCtx =
  716. RassrvAlloc(
  717. sizeof(RASSRV_PROPSHEET_CONTEXT),
  718. TRUE);
  719. SetProp (
  720. hwndSheet,
  721. Globals.atmRassrvPageData,
  722. (HANDLE)pPropSheetCtx);
  723. }
  724. // Initialize the page
  725. RasSrvPropsheetInitialize(
  726. hwndDlg,
  727. (LPPROPSHEETPAGE)lParam);
  728. }
  729. break;
  730. case WM_DESTROY:
  731. // WM_DESTROY is sent for each page that has been activated.
  732. // Cleanup the global data if it hasn't already been
  733. // cleaned up on a previous call to WM_DESTROY.
  734. //
  735. {
  736. HWND hwndSheet = GetParent(hwndDlg);
  737. pPropSheetCtx = (RASSRV_PROPSHEET_CONTEXT *)
  738. GetProp(hwndSheet, Globals.atmRassrvPageData);
  739. if (pPropSheetCtx)
  740. {
  741. if (!pPropSheetCtx->bLeaveRemoteAccessRunning)
  742. {
  743. DbgOutputTrace("Stop service.");
  744. RasSrvServiceCleanup(hwndDlg);
  745. }
  746. DbgOutputTrace ("Free propsht data.");
  747. RassrvFree (pPropSheetCtx);
  748. // Reset the global data
  749. SetProp (hwndSheet, Globals.atmRassrvPageData, NULL);
  750. }
  751. }
  752. break;
  753. case WM_NOTIFY:
  754. {
  755. NMHDR * pNotifyData = (NMHDR*)lParam;
  756. switch (pNotifyData->code)
  757. {
  758. // The page is becoming active.
  759. case PSN_SETACTIVE:
  760. DbgOutputTrace(
  761. "SetActive: %x %x",
  762. pNotifyData->hwndFrom,
  763. pNotifyData->idFrom);
  764. if (RasSrvActivatePage(hwndDlg, pNotifyData) != NO_ERROR)
  765. {
  766. // reject activation
  767. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
  768. return TRUE;
  769. }
  770. break;
  771. // Ok was pressed on the property sheet
  772. case PSN_APPLY:
  773. RasSrvCommitSettingsOnClose (hwndDlg);
  774. break;
  775. }
  776. }
  777. break;
  778. }
  779. return FALSE;
  780. }