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.

1224 lines
28 KiB

  1. /*
  2. File utils.c
  3. Contains common utilities for the ras dialup server ui.
  4. Paul Mayfield, 9/30/97
  5. */
  6. #include "rassrv.h"
  7. // Remoteaccess parameters key
  8. const WCHAR pszregRasParameters[]
  9. = L"SYSTEM\\CurrentControlSet\\Services\\RemoteAccess\\Parameters";
  10. // Registry key values
  11. const WCHAR pszregServerFlags[] = L"ServerFlags";
  12. const WCHAR pszregShowIcon[] = L"Rassrv_EnableIconsInTray";
  13. const WCHAR pszregPure[] = L"UsersConfiguredWithMMC";
  14. const WCHAR pszregLogLevel[] = L"LoggingFlags";
  15. // Here is the instance of the global variables
  16. RASSRVUI_GLOBALS Globals;
  17. DWORD
  18. gblInit(
  19. IN HINSTANCE hInstDll,
  20. OUT RASSRVUI_GLOBALS * pGlobs)
  21. {
  22. // Clear out the memory
  23. ZeroMemory(pGlobs, sizeof(RASSRVUI_GLOBALS));
  24. // Record the module for use in future resource fuction calls.
  25. Globals.hInstDll = hInstDll;
  26. // Initialize the global variable lock
  27. InitializeCriticalSection(&(pGlobs->csLock));
  28. // Create the global heap
  29. pGlobs->hPrivateHeap = HeapCreate(0, 4096, 0);
  30. if (NULL == pGlobs->hPrivateHeap)
  31. {
  32. return GetLastError();
  33. }
  34. // Register the context ID atom for use in the Windows XxxProp calls
  35. // which are used to associate a context with a dialog window handle.
  36. Globals.atmRassrvPageData =
  37. (LPCTSTR)GlobalAddAtom(TEXT("RASSRVUI_PAGE_DATA"));
  38. if (!Globals.atmRassrvPageData)
  39. {
  40. return GetLastError();
  41. }
  42. Globals.atmRassrvPageId =
  43. (LPCTSTR)GlobalAddAtom(TEXT("RASSRVUI_PAGE_ID"));
  44. if (!Globals.atmRassrvPageId)
  45. {
  46. return GetLastError();
  47. }
  48. return NO_ERROR;
  49. }
  50. DWORD
  51. gblCleanup(
  52. IN RASSRVUI_GLOBALS * Globs)
  53. {
  54. if (Globs->hRasServer != NULL)
  55. {
  56. MprAdminServerDisconnect(Globs->hRasServer);
  57. Globs->hRasServer = NULL;
  58. }
  59. if (Globs->hPrivateHeap)
  60. {
  61. HeapDestroy(Globs->hPrivateHeap);
  62. }
  63. GlobalDeleteAtom(LOWORD(Globals.atmRassrvPageData));
  64. GlobalDeleteAtom(LOWORD(Globals.atmRassrvPageId));
  65. DeleteCriticalSection(&(Globs->csLock));
  66. return NO_ERROR;
  67. }
  68. //
  69. // Loads the machine flags
  70. //
  71. DWORD
  72. gblLoadMachineFlags(
  73. IN RASSRVUI_GLOBALS * pGlobs)
  74. {
  75. DWORD dwErr = NO_ERROR;
  76. PDSROLE_PRIMARY_DOMAIN_INFO_BASIC pInfo = NULL;
  77. BOOL bEnabled, bDefault;
  78. // If we're already initialized, there's nothing to
  79. // do
  80. //
  81. if (pGlobs->dwMachineFlags & RASSRVUI_MACHINE_F_Initialized)
  82. {
  83. return NO_ERROR;
  84. }
  85. do
  86. {
  87. // Find out what kind of machine we are
  88. //
  89. dwErr = DsRoleGetPrimaryDomainInformation(
  90. NULL,
  91. DsRolePrimaryDomainInfoBasic,
  92. (LPBYTE *)&pInfo );
  93. if (dwErr != NO_ERROR)
  94. {
  95. break;
  96. }
  97. if ((pInfo->MachineRole != DsRole_RoleStandaloneWorkstation) &&
  98. (pInfo->MachineRole != DsRole_RoleMemberWorkstation))
  99. {
  100. pGlobs->dwMachineFlags |= RASSRVUI_MACHINE_F_Server;
  101. }
  102. if ((pInfo->MachineRole != DsRole_RoleStandaloneWorkstation) &&
  103. (pInfo->MachineRole != DsRole_RoleStandaloneServer))
  104. {
  105. pGlobs->dwMachineFlags |= RASSRVUI_MACHINE_F_Member;
  106. }
  107. // Record that we've been initailized
  108. //
  109. pGlobs->dwMachineFlags |= RASSRVUI_MACHINE_F_Initialized;
  110. } while (FALSE);
  111. // Cleanup
  112. {
  113. if (pInfo)
  114. {
  115. DsRoleFreeMemory (pInfo);
  116. }
  117. }
  118. return dwErr;
  119. }
  120. //
  121. // Establishes communication with the ras server if
  122. // not already established
  123. //
  124. DWORD
  125. gblConnectToRasServer()
  126. {
  127. DWORD dwErr = NO_ERROR;
  128. EnterCriticalSection(&(Globals.csLock));
  129. if (Globals.hRasServer == NULL)
  130. {
  131. dwErr = MprAdminServerConnect(NULL, &Globals.hRasServer);
  132. }
  133. LeaveCriticalSection(&(Globals.csLock));
  134. return dwErr;
  135. }
  136. /* Enhanced list view callback to report drawing information. 'HwndLv' is
  137. ** the handle of the list view control. 'DwItem' is the index of the item
  138. ** being drawn.
  139. **
  140. ** Returns the address of the draw information.
  141. */
  142. LVXDRAWINFO*
  143. LvDrawInfoCallback(
  144. IN HWND hwndLv,
  145. IN DWORD dwItem )
  146. {
  147. /* The enhanced list view is used only to get the "wide selection bar"
  148. ** feature so our option list is not very interesting.
  149. **
  150. ** Fields are 'nCols', 'dxIndent', 'dwFlags', 'adwFlags[]'.
  151. */
  152. static LVXDRAWINFO info = { 1, 0, 0, { 0 } };
  153. return &info;
  154. }
  155. //
  156. // Allocates memory. If bZero is TRUE, it also zeros the memory.
  157. //
  158. PVOID
  159. RassrvAlloc (
  160. IN DWORD dwSize,
  161. IN BOOL bZero)
  162. {
  163. PVOID pvRet = NULL;
  164. HANDLE hHeap = NULL;
  165. hHeap =
  166. (Globals.hPrivateHeap) ? Globals.hPrivateHeap : GetProcessHeap();
  167. pvRet = HeapAlloc(
  168. hHeap,
  169. (bZero) ? HEAP_ZERO_MEMORY: 0,
  170. dwSize);
  171. return pvRet;
  172. }
  173. //
  174. // Frees memory allocated by RassrvAlloc
  175. //
  176. VOID
  177. RassrvFree (
  178. IN PVOID pvBuf)
  179. {
  180. PVOID pvRet;
  181. HANDLE hHeap;
  182. hHeap =
  183. (Globals.hPrivateHeap) ? Globals.hPrivateHeap : GetProcessHeap();
  184. if (pvBuf)
  185. {
  186. HeapFree(hHeap, 0, pvBuf);
  187. }
  188. }
  189. //
  190. // Adds a user to the local machine
  191. //
  192. DWORD
  193. RasSrvAddUser (
  194. IN PWCHAR pszUserLogonName,
  195. IN PWCHAR pszUserComment,
  196. IN PWCHAR pszUserPassword)
  197. {
  198. NET_API_STATUS nStatus;
  199. WCHAR pszDomainUser[1024];
  200. WCHAR pszCompName[1024];
  201. LOCALGROUP_MEMBERS_INFO_3 meminfo;
  202. DWORD dwSize = 1024, dwErr;
  203. USER_INFO_2 * pUser2;
  204. RAS_USER_0 UserInfo;
  205. // Initialize the base user information
  206. USER_INFO_1 User =
  207. {
  208. pszUserLogonName,
  209. pszUserPassword,
  210. 0,
  211. USER_PRIV_USER,
  212. L"",
  213. L"",
  214. UF_SCRIPT | UF_DONT_EXPIRE_PASSWD | UF_NORMAL_ACCOUNT,
  215. L""
  216. };
  217. // Add the user
  218. nStatus = NetUserAdd(
  219. NULL,
  220. 1,
  221. (LPBYTE)&User,
  222. NULL);
  223. // If the user wasn't added, find out why
  224. if (nStatus != NERR_Success)
  225. {
  226. switch (nStatus)
  227. {
  228. case ERROR_ACCESS_DENIED:
  229. return ERROR_ACCESS_DENIED;
  230. case NERR_UserExists:
  231. return ERROR_USER_EXISTS;
  232. case NERR_PasswordTooShort:
  233. return ERROR_INVALID_PASSWORDNAME;
  234. case NERR_InvalidComputer:
  235. case NERR_NotPrimary:
  236. case NERR_GroupExists:
  237. default:
  238. return ERROR_CAN_NOT_COMPLETE;
  239. }
  240. }
  241. // Now that the user is added, add the user's full name
  242. nStatus = NetUserGetInfo(NULL, pszUserLogonName, 2, (LPBYTE*)&pUser2);
  243. if (nStatus == NERR_Success)
  244. {
  245. // Modify the full name in the structure
  246. pUser2->usri2_full_name = pszUserComment;
  247. NetUserSetInfo(NULL, pszUserLogonName, 2, (LPBYTE)pUser2, NULL);
  248. NetApiBufferFree((LPBYTE)pUser2);
  249. }
  250. return NO_ERROR;
  251. }
  252. //
  253. // Deletes a user from the system local user datbase
  254. //
  255. DWORD
  256. RasSrvDeleteUser(
  257. PWCHAR pszUserLogonName)
  258. {
  259. NET_API_STATUS nStatus;
  260. // Delete the user and return the status code. If the
  261. // specified user is not in the user database, consider
  262. // it a success
  263. nStatus = NetUserDel(NULL, pszUserLogonName);
  264. if (nStatus != NERR_Success)
  265. {
  266. switch (nStatus)
  267. {
  268. case ERROR_ACCESS_DENIED:
  269. return ERROR_ACCESS_DENIED;
  270. case NERR_UserNotFound:
  271. return NO_ERROR;
  272. }
  273. return nStatus;
  274. }
  275. return NO_ERROR;
  276. }
  277. //
  278. // Changes the full name and password of a user. If
  279. // either of pszFullName or pszPassword is null, it is
  280. // ignored.
  281. //
  282. DWORD
  283. RasSrvEditUser (
  284. IN PWCHAR pszLogonName,
  285. IN OPTIONAL PWCHAR pszFullName,
  286. IN OPTIONAL PWCHAR pszPassword)
  287. {
  288. NET_API_STATUS nStatus;
  289. DWORD dwSize = 1024, dwErr = NO_ERROR, dwParamErr;
  290. USER_INFO_2 * pUser2;
  291. // if nothing to set, return
  292. if (!pszFullName && !pszPassword)
  293. {
  294. return NO_ERROR;
  295. }
  296. // First, get this user's data so that we can manipulate it.
  297. //
  298. nStatus = NetUserGetInfo(
  299. NULL,
  300. pszLogonName,
  301. 2,
  302. (LPBYTE*)(&pUser2));
  303. if (nStatus != NERR_Success)
  304. {
  305. return nStatus;
  306. }
  307. dwErr = NO_ERROR;
  308. do
  309. {
  310. // Fill in the blanks accordingly
  311. if (pszFullName)
  312. {
  313. pUser2->usri2_full_name = pszFullName;
  314. }
  315. if (pszPassword)
  316. {
  317. pUser2->usri2_password = pszPassword;
  318. }
  319. // Add the user
  320. nStatus = NetUserSetInfo(
  321. NULL, // server name
  322. pszLogonName, // user name
  323. 2, // level
  324. (LPBYTE)pUser2, // buf
  325. &dwParamErr); // param error
  326. if (nStatus != NERR_Success)
  327. {
  328. dwErr = nStatus;
  329. break;
  330. }
  331. } while (FALSE);
  332. // Cleanup
  333. {
  334. NetApiBufferFree(pUser2);
  335. }
  336. return dwErr;
  337. }
  338. // Returns whether a dword registry value was set or not. If the named
  339. // value does not exist, the value of bDefault is assigned.
  340. DWORD
  341. RassrvRegGetDwEx(
  342. IN DWORD * lpdwFlag,
  343. IN DWORD dwDefault,
  344. IN CONST PWCHAR pszKeyName,
  345. IN CONST PWCHAR pszValueName,
  346. IN BOOL bCreate)
  347. {
  348. DWORD dwErr, dwVal, dwType = REG_DWORD, dwSize = sizeof(DWORD);
  349. HKEY hKey = NULL;
  350. if (!lpdwFlag)
  351. {
  352. return ERROR_INVALID_PARAMETER;
  353. }
  354. do
  355. {
  356. if (bCreate)
  357. {
  358. DWORD dwDisposition;
  359. dwErr = RegCreateKeyExW(
  360. HKEY_LOCAL_MACHINE,
  361. pszKeyName,
  362. 0,
  363. NULL,
  364. REG_OPTION_NON_VOLATILE,
  365. KEY_READ,
  366. NULL,
  367. &hKey,
  368. &dwDisposition);
  369. if (dwErr != ERROR_SUCCESS)
  370. {
  371. break;
  372. }
  373. }
  374. else
  375. {
  376. // Open the registry key
  377. dwErr = RegOpenKeyExW(
  378. HKEY_LOCAL_MACHINE,
  379. pszKeyName,
  380. 0,
  381. KEY_READ,
  382. &hKey);
  383. if (dwErr != ERROR_SUCCESS)
  384. {
  385. break;
  386. }
  387. }
  388. // Read the value
  389. dwErr = RegQueryValueExW(
  390. hKey,
  391. pszValueName,
  392. 0,
  393. &dwType,
  394. (BYTE *)&dwVal,
  395. &dwSize);
  396. if (dwErr != ERROR_SUCCESS)
  397. {
  398. dwErr = NO_ERROR;
  399. dwVal = dwDefault;
  400. }
  401. // Return the value read
  402. *lpdwFlag = dwVal;
  403. } while (FALSE);
  404. // Cleanup
  405. {
  406. if (hKey)
  407. {
  408. RegCloseKey(hKey);
  409. }
  410. }
  411. return dwErr;
  412. }
  413. // Returns whether a dword registry value was set or not. If the named
  414. // value does not exist, the value of bDefault is assigned.
  415. DWORD
  416. RassrvRegGetDw(
  417. IN DWORD * lpdwFlag,
  418. IN DWORD dwDefault,
  419. IN CONST PWCHAR pszKeyName,
  420. IN CONST PWCHAR pszValueName)
  421. {
  422. return RassrvRegGetDwEx(
  423. lpdwFlag,
  424. dwDefault,
  425. pszKeyName,
  426. pszValueName,
  427. FALSE);
  428. }
  429. //
  430. // Sets a dword registry value. If the named value does not exist,
  431. // it is automatically created.
  432. //
  433. DWORD
  434. RassrvRegSetDwEx(
  435. IN DWORD dwFlag,
  436. IN CONST PWCHAR pszKeyName,
  437. IN CONST PWCHAR pszValueName,
  438. IN BOOL bCreate)
  439. {
  440. DWORD dwErr = NO_ERROR, dwVal, dwType = REG_DWORD;
  441. DWORD dwSize = sizeof(DWORD);
  442. HKEY hKey = NULL;
  443. dwVal = dwFlag;
  444. do
  445. {
  446. if (bCreate)
  447. {
  448. DWORD dwDisposition;
  449. dwErr = RegCreateKeyExW(
  450. HKEY_LOCAL_MACHINE,
  451. pszKeyName,
  452. 0,
  453. NULL,
  454. REG_OPTION_NON_VOLATILE,
  455. KEY_WRITE,
  456. NULL,
  457. &hKey,
  458. &dwDisposition);
  459. if (dwErr != ERROR_SUCCESS)
  460. {
  461. break;
  462. }
  463. }
  464. else
  465. {
  466. // Open the registry key
  467. dwErr = RegOpenKeyExW(
  468. HKEY_LOCAL_MACHINE,
  469. pszKeyName,
  470. 0,
  471. KEY_WRITE,
  472. &hKey);
  473. if (dwErr != ERROR_SUCCESS)
  474. {
  475. break;
  476. }
  477. }
  478. // Set the value
  479. dwErr = RegSetValueExW(
  480. hKey,
  481. pszValueName,
  482. 0,
  483. dwType,
  484. (CONST BYTE *)&dwVal,
  485. dwSize);
  486. if (dwErr != ERROR_SUCCESS)
  487. {
  488. break;
  489. }
  490. } while (FALSE);
  491. // Cleanup
  492. {
  493. if (hKey)
  494. {
  495. RegCloseKey(hKey);
  496. }
  497. }
  498. return dwErr;
  499. }
  500. DWORD
  501. RassrvRegSetDw(
  502. IN DWORD dwFlag,
  503. IN CONST PWCHAR pszKeyName,
  504. IN CONST PWCHAR pszValueName)
  505. {
  506. return RassrvRegSetDwEx(dwFlag, pszKeyName, pszValueName, FALSE);
  507. }
  508. //
  509. // Warns the user that we are about to switch to MMC returning TRUE if
  510. // user agrees to this and FALSE otherwise
  511. //
  512. BOOL
  513. RassrvWarnMMCSwitch(
  514. IN HWND hwndDlg)
  515. {
  516. PWCHAR pszWarning, pszTitle;
  517. pszWarning =
  518. (PWCHAR) PszLoadString(Globals.hInstDll, WRN_SWITCHING_TO_MMC);
  519. pszTitle =
  520. (PWCHAR) PszLoadString(Globals.hInstDll, WRN_TITLE);
  521. if (MessageBox(
  522. hwndDlg,
  523. pszWarning,
  524. pszTitle,
  525. MB_YESNO | MB_ICONEXCLAMATION) == IDYES)
  526. {
  527. return TRUE;
  528. }
  529. return FALSE;
  530. }
  531. //
  532. // Switches to mmc based on the console identifier passed in
  533. //
  534. DWORD
  535. RassrvLaunchMMC (
  536. IN DWORD dwConsoleId)
  537. {
  538. STARTUPINFOA startupinfo;
  539. PROCESS_INFORMATION procinfo;
  540. CHAR * pszConsole;
  541. CHAR pszBuf[1024], pszDir[1024];
  542. BOOL bSuccess = FALSE;
  543. DWORD dwErr = NO_ERROR;
  544. // Set the command line accordingly
  545. switch (dwConsoleId)
  546. {
  547. case RASSRVUI_NETWORKCONSOLE:
  548. pszConsole = "netmgmt.msc";
  549. break;
  550. case RASSRVUI_USERCONSOLE:
  551. pszConsole = NULL;
  552. break;
  553. case RASSRVUI_SERVICESCONSOLE:
  554. pszConsole = "compmgmt.msc";
  555. break;
  556. case RASSRVUI_MPRCONSOLE:
  557. default:
  558. pszConsole = "rrasmgmt.msc";
  559. break;
  560. }
  561. if (pszConsole)
  562. {
  563. GetSystemDirectoryA (pszDir, sizeof(pszDir));
  564. sprintf (pszBuf, "mmc %s\\%s", pszDir, pszConsole);
  565. }
  566. else
  567. {
  568. strcpy (pszBuf, "mmc.exe");
  569. }
  570. // Launch MMC
  571. ZeroMemory(&startupinfo, sizeof(startupinfo));
  572. startupinfo.cb = sizeof(startupinfo);
  573. // for .Net 704458, close process and thread handle
  574. bSuccess = CreateProcessA(
  575. NULL, // name of executable module
  576. pszBuf, // command line string
  577. NULL, // process security attributes
  578. NULL, // thread security attributes
  579. FALSE, // handle inheritance flag
  580. NORMAL_PRIORITY_CLASS, // creation flags
  581. NULL, // new environment block
  582. NULL, // current directory name
  583. &startupinfo, // STARTUPINFO
  584. &procinfo); // PROCESS_INFORMATION
  585. if( bSuccess )
  586. {
  587. CloseHandle( procinfo.hThread);
  588. CloseHandle( procinfo.hProcess);
  589. }
  590. else
  591. {
  592. dwErr = GetLastError();
  593. }
  594. return dwErr;
  595. }
  596. //
  597. // Retrieve a string from the registry
  598. //
  599. DWORD
  600. RassrvRegGetStr(
  601. OUT PWCHAR pszBuf,
  602. IN PWCHAR pszDefault,
  603. IN CONST PWCHAR pszKeyName,
  604. IN CONST PWCHAR pszValueName)
  605. {
  606. DWORD dwErr = NO_ERROR, dwVal, dwType = REG_SZ, dwSize = 512;
  607. HKEY hKey = NULL;
  608. do
  609. {
  610. // Open the registry key
  611. dwErr = RegOpenKeyExW(
  612. HKEY_LOCAL_MACHINE,
  613. pszKeyName,
  614. 0,
  615. KEY_READ,
  616. &hKey);
  617. if (dwErr != ERROR_SUCCESS)
  618. {
  619. break;
  620. }
  621. // Read the value
  622. dwErr = RegQueryValueExW(
  623. hKey,
  624. pszValueName,
  625. 0,
  626. &dwType,
  627. (BYTE *)pszBuf,
  628. &dwSize);
  629. if (dwErr != ERROR_SUCCESS)
  630. {
  631. dwErr = NO_ERROR;
  632. wcscpy(pszBuf, pszDefault);
  633. }
  634. } while (FALSE);
  635. // Cleanup
  636. {
  637. if (hKey)
  638. {
  639. RegCloseKey(hKey);
  640. }
  641. }
  642. return NO_ERROR;
  643. }
  644. //
  645. // Save a string to the registry
  646. //
  647. DWORD
  648. RassrvRegSetStr(
  649. IN PWCHAR pszStr,
  650. IN CONST PWCHAR pszKeyName,
  651. IN CONST PWCHAR pszValueName)
  652. {
  653. DWORD dwErr = NO_ERROR, dwVal, dwType = REG_SZ, dwSize;
  654. HKEY hKey = NULL;
  655. dwSize = wcslen(pszStr)*sizeof(WCHAR) + sizeof(WCHAR);
  656. do
  657. {
  658. // Open the registry key
  659. dwErr = RegOpenKeyExW(
  660. HKEY_LOCAL_MACHINE,
  661. pszKeyName,
  662. 0,
  663. KEY_WRITE,
  664. &hKey);
  665. if (dwErr != ERROR_SUCCESS)
  666. {
  667. break;
  668. }
  669. // Set the value
  670. dwErr = RegSetValueExW(
  671. hKey,
  672. pszValueName,
  673. 0,
  674. dwType,
  675. (CONST BYTE *)pszStr,
  676. dwSize);
  677. if (dwErr != ERROR_SUCCESS)
  678. {
  679. break;
  680. }
  681. } while (FALSE);
  682. // Cleanup
  683. {
  684. if (hKey)
  685. {
  686. RegCloseKey(hKey);
  687. }
  688. }
  689. return dwErr;
  690. }
  691. //
  692. // Gets the machine flags
  693. //
  694. DWORD
  695. RasSrvGetMachineFlags(
  696. OUT LPDWORD lpdwFlags)
  697. {
  698. GBL_LOCK;
  699. gblLoadMachineFlags(&Globals);
  700. *lpdwFlags = Globals.dwMachineFlags;
  701. GBL_UNLOCK;
  702. return NO_ERROR;
  703. }
  704. //
  705. // Get multilink status
  706. //
  707. DWORD
  708. RasSrvGetMultilink(
  709. OUT BOOL * pbEnabled)
  710. {
  711. DWORD dwFlags = PPPCFG_NegotiateMultilink;
  712. if (!pbEnabled)
  713. {
  714. return ERROR_INVALID_PARAMETER;
  715. }
  716. // Read the flags
  717. RassrvRegGetDw(
  718. &dwFlags,
  719. PPPCFG_NegotiateMultilink,
  720. (const PWCHAR)pszregRasParameters,
  721. (const PWCHAR)pszregServerFlags);
  722. // Assign the enable state accordingly
  723. if (dwFlags & PPPCFG_NegotiateMultilink)
  724. {
  725. *pbEnabled = TRUE;
  726. }
  727. else
  728. {
  729. *pbEnabled = FALSE;
  730. }
  731. return NO_ERROR;
  732. }
  733. //
  734. // Private internal function that enables/disables multilink
  735. //
  736. DWORD
  737. RasSrvSetMultilink(
  738. IN BOOL bEnable)
  739. {
  740. DWORD dwFlags = PPPCFG_NegotiateMultilink;
  741. // Read the flags
  742. RassrvRegGetDw(
  743. &dwFlags,
  744. PPPCFG_NegotiateMultilink,
  745. (const PWCHAR)pszregRasParameters,
  746. (const PWCHAR)pszregServerFlags);
  747. // Assign the enable state accordingly
  748. if (bEnable)
  749. {
  750. dwFlags |= PPPCFG_NegotiateMultilink;
  751. }
  752. else
  753. {
  754. dwFlags &= ~PPPCFG_NegotiateMultilink;
  755. }
  756. // Set the flags
  757. RassrvRegSetDw(
  758. dwFlags,
  759. (CONST PWCHAR)pszregRasParameters,
  760. (CONST PWCHAR)pszregServerFlags);
  761. return NO_ERROR;
  762. }
  763. //
  764. // Initialize the show icon setting
  765. //
  766. DWORD
  767. RasSrvGetIconShow(
  768. OUT BOOL * pbEnabled)
  769. {
  770. DWORD dwErr = NO_ERROR, dwFlags = 0;
  771. BOOL bDefault = TRUE;
  772. // Get machine flags
  773. //
  774. dwErr = RasSrvGetMachineFlags(&dwFlags);
  775. if (dwErr != NO_ERROR)
  776. {
  777. *pbEnabled = FALSE;
  778. return dwErr;
  779. }
  780. // Always off for member server
  781. //
  782. if ((dwFlags & RASSRVUI_MACHINE_F_Server) &&
  783. (dwFlags & RASSRVUI_MACHINE_F_Member))
  784. {
  785. *pbEnabled = FALSE;
  786. return NO_ERROR;
  787. }
  788. // Set default
  789. //
  790. if (dwFlags & RASSRVUI_MACHINE_F_Server)
  791. {
  792. bDefault = FALSE;
  793. }
  794. else
  795. {
  796. bDefault = TRUE;
  797. }
  798. // Load the machine flags and return accordingly
  799. //
  800. *pbEnabled = bDefault;
  801. dwErr = RassrvRegGetDw(
  802. pbEnabled,
  803. bDefault,
  804. (CONST PWCHAR)pszregRasParameters,
  805. (CONST PWCHAR)pszregShowIcon);
  806. return dwErr;
  807. }
  808. //
  809. // Save the show icon setting
  810. //
  811. DWORD
  812. RasSrvSetIconShow(
  813. IN BOOL bEnable)
  814. {
  815. return RassrvRegSetDw(
  816. bEnable,
  817. (CONST PWCHAR)pszregRasParameters,
  818. (CONST PWCHAR)pszregShowIcon);
  819. }
  820. //
  821. // Save the log level
  822. //
  823. DWORD
  824. RasSrvSetLogLevel(
  825. IN DWORD dwLevel)
  826. {
  827. return RassrvRegSetDw(
  828. dwLevel,
  829. (CONST PWCHAR)pszregRasParameters,
  830. (CONST PWCHAR)pszregLogLevel);
  831. }
  832. // Calls WinHelp to popup context sensitive help. 'pdwMap' is an array
  833. // of control-ID help-ID pairs terminated with a 0,0 pair. 'UnMsg' is
  834. // WM_HELP or WM_CONTEXTMENU indicating the message received requesting
  835. // help. 'Wparam' and 'lparam' are the parameters of the message received
  836. // requesting help.
  837. DWORD
  838. RasSrvHelp (
  839. IN HWND hwndDlg,
  840. IN UINT unMsg,
  841. IN WPARAM wparam,
  842. IN LPARAM lparam,
  843. IN const DWORD* pdwMap)
  844. {
  845. HWND hwnd;
  846. UINT unType;
  847. TCHAR pszHelpFile[] = TEXT("Netcfg.hlp");
  848. // Validate parameters
  849. if (! (unMsg==WM_HELP || unMsg==WM_CONTEXTMENU))
  850. {
  851. return ERROR_INVALID_PARAMETER;
  852. }
  853. // If no map is provided, no help will show
  854. if (!pdwMap)
  855. {
  856. return NO_ERROR;
  857. }
  858. // If an actual help topic is request...
  859. if (unMsg == WM_HELP)
  860. {
  861. LPHELPINFO p = (LPHELPINFO )lparam;
  862. TRACE4( "ContextHelp(WM_HELP,t=%d,id=%d,h=$%08x,s=$%08x)",
  863. p->iContextType, p->iCtrlId,p->hItemHandle ,hwndDlg );
  864. if (p->iContextType != HELPINFO_WINDOW)
  865. {
  866. return NO_ERROR;
  867. }
  868. hwnd = p->hItemHandle;
  869. unType = HELP_WM_HELP;
  870. }
  871. // Standard Win95 method that produces a one-item "What's This?"
  872. // menu that user must click to get help.
  873. else
  874. {
  875. TRACE1( "ContextHelp(WM_CONTEXTMENU,h=$%08x)", wparam );
  876. hwnd = (HWND )wparam;
  877. unType = HELP_CONTEXTMENU;
  878. }
  879. WinHelp( hwnd, pszHelpFile, unType, (ULONG_PTR)pdwMap );
  880. return NO_ERROR;
  881. }
  882. BOOL CALLBACK
  883. WSDlgProc(
  884. HWND hwnd,
  885. UINT unMsg,
  886. WPARAM wParam,
  887. LPARAM lParam )
  888. /* Standard Win32 dialog procedure.
  889. */
  890. {
  891. if (unMsg == WM_INITDIALOG)
  892. {
  893. HMENU hmenu;
  894. RECT r1, r2;
  895. /* Remove Close from the system menu since some people think it kills
  896. ** the app and not just the popup.
  897. */
  898. hmenu = GetSystemMenu( hwnd, FALSE );
  899. if (hmenu && DeleteMenu( hmenu, SC_CLOSE, MF_BYCOMMAND ))
  900. {
  901. DrawMenuBar( hwnd );
  902. }
  903. // Center the window
  904. GetWindowRect(hwnd, &r1);
  905. GetWindowRect(GetDesktopWindow(), &r2);
  906. MoveWindow(
  907. hwnd,
  908. (r2.right - r2.left)/2 - (r1.right - r1.left)/2,
  909. (r2.bottom - r2.top)/2 - (r1.bottom - r1.top)/2,
  910. r1.right - r1.left,
  911. r1.bottom - r1.top,
  912. TRUE);
  913. return TRUE;
  914. }
  915. return FALSE;
  916. }
  917. //
  918. // Bring up the start waiting for services dialog
  919. //
  920. DWORD
  921. RasSrvShowServiceWait(
  922. IN HINSTANCE hInst,
  923. IN HWND hwndParent,
  924. OUT HANDLE * phData)
  925. {
  926. // Set the hourglass cursor
  927. *phData = (HANDLE) SetCursor (LoadCursor (NULL, IDC_WAIT));
  928. ShowCursor (TRUE);
  929. return NO_ERROR;
  930. }
  931. //
  932. // Bring down wait for services dialog
  933. //
  934. DWORD
  935. RasSrvFinishServiceWait (
  936. IN HANDLE hData)
  937. {
  938. HICON hIcon = (HICON)hData;
  939. if (hIcon == NULL)
  940. {
  941. hIcon = LoadCursor (NULL, IDC_ARROW);
  942. }
  943. SetCursor (hIcon);
  944. ShowCursor (TRUE);
  945. return NO_ERROR;
  946. }
  947. //-----------------------------------------------------------------------
  948. // Function: EnableBackupPrivilege
  949. //
  950. // Enables/disables backup privilege for the current process.
  951. //-----------------------------------------------------------------------
  952. DWORD
  953. EnableRebootPrivilege(
  954. IN BOOL bEnable)
  955. {
  956. LUID luid;
  957. HANDLE hToken = NULL;
  958. TOKEN_PRIVILEGES tp;
  959. BOOL bOk;
  960. // We first have to try to get the token of the current
  961. // thread since if it is impersonating, adjusting the
  962. // privileges of the process will have no affect.
  963. bOk = OpenThreadToken(
  964. GetCurrentThread(),
  965. TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
  966. TRUE,
  967. &hToken);
  968. if (bOk == FALSE)
  969. {
  970. // There is no thread token -- open it up for the
  971. // process instead.
  972. OpenProcessToken(
  973. GetCurrentProcess(),
  974. TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
  975. &hToken
  976. );
  977. }
  978. // Get the LUID of the privilege
  979. if (!LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &luid))
  980. {
  981. DWORD dwErr = GetLastError();
  982. if(NULL != hToken)
  983. {
  984. CloseHandle(hToken);
  985. }
  986. return dwErr;
  987. }
  988. // Adjust the token privileges
  989. tp.PrivilegeCount = 1;
  990. tp.Privileges[0].Luid = luid;
  991. tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  992. // Commit changes to the system
  993. if (!AdjustTokenPrivileges(
  994. hToken, !bEnable, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL
  995. ))
  996. {
  997. DWORD dwErr = GetLastError();
  998. if(NULL != hToken)
  999. {
  1000. CloseHandle(hToken);
  1001. }
  1002. return dwErr;
  1003. }
  1004. // Even if AdjustTokenPrivileges succeeded (see MSDN) you still
  1005. // need to verify success by calling GetLastError.
  1006. if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
  1007. {
  1008. if(NULL != hToken)
  1009. {
  1010. CloseHandle(hToken);
  1011. }
  1012. return ERROR_NOT_ALL_ASSIGNED;
  1013. }
  1014. if(NULL != hToken)
  1015. {
  1016. CloseHandle(hToken);
  1017. }
  1018. return NO_ERROR;
  1019. }
  1020. // Pops up a warning with the given parent window and reboots
  1021. // windows
  1022. DWORD RasSrvReboot(HWND hwndParent)
  1023. {
  1024. DWORD dwOldState;
  1025. INT iRet;
  1026. PWCHAR pszWarn, pszTitle;
  1027. // Load the strings
  1028. pszWarn =
  1029. (PWCHAR) PszLoadString(Globals.hInstDll, WRN_REBOOT_REQUIRED);
  1030. pszTitle =
  1031. (PWCHAR) PszLoadString(Globals.hInstDll, WRN_TITLE);
  1032. // Display the warning
  1033. iRet = MessageBoxW(
  1034. hwndParent,
  1035. pszWarn,
  1036. pszTitle,
  1037. MB_YESNO | MB_APPLMODAL);
  1038. if (iRet != IDYES)
  1039. {
  1040. return ERROR_CANCELLED;
  1041. }
  1042. // Enable the reboot privelege
  1043. EnableRebootPrivilege(TRUE);
  1044. ExitWindowsEx(EWX_REBOOT, 0);
  1045. // Restore the reboot privelege
  1046. EnableRebootPrivilege(FALSE);
  1047. return NO_ERROR;
  1048. }