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.

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