Leaked source code of windows server 2003
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

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