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.

1851 lines
47 KiB

  1. /*++
  2. Microsoft Confidential
  3. Copyright (c) 1992-1997 Microsoft Corporation
  4. All rights reserved
  5. Module Name:
  6. envvar.c
  7. Abstract:
  8. Implements the Environment Variables dialog of the System
  9. Control Panel Applet
  10. Author:
  11. Eric Flo (ericflo) 19-Jun-1995
  12. Revision History:
  13. 15-Oct-1997 scotthal
  14. Complete overhaul
  15. --*/
  16. #include "sysdm.h"
  17. #include <help.h>
  18. // C Runtime
  19. #include <stddef.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include <tchar.h>
  23. // for Hydra
  24. #include <winsta.h>
  25. //==========================================================================
  26. // Local Definitions
  27. //==========================================================================
  28. #define LB_SYSVAR 1
  29. #define LB_USERVAR 2
  30. #define SYSTEMROOT TEXT("SystemRoot")
  31. #define SYSTEMDRIVE TEXT("SystemDrive")
  32. //==========================================================================
  33. // Typedefs and Structs
  34. //==========================================================================
  35. // Registry valuename linked-list structure
  36. typedef struct _regval
  37. {
  38. struct _regval *prvNext;
  39. LPTSTR szValueName;
  40. } REGVAL;
  41. //==========================================================================
  42. // Local Functions
  43. //==========================================================================
  44. void EVDoCommand(HWND hDlg, HWND hwndCtl, int idCtl, int iNotify );
  45. void EVSave(HWND hDlg);
  46. void EVCleanUp (HWND hDlg);
  47. PENVAR GetVar(HWND hDlg, UINT VarType, int iSelection);
  48. int FindVar (HWND hwndLB, LPTSTR szVar);
  49. void
  50. SetVar(
  51. IN HWND hDlg,
  52. IN UINT VarType,
  53. IN LPCTSTR szVarName,
  54. IN LPCTSTR szVarValue
  55. );
  56. void
  57. DeleteVar(
  58. IN HWND hDlg,
  59. IN UINT VarType,
  60. IN LPCTSTR szVarName
  61. );
  62. //
  63. // New.../Edit... subdialog functions
  64. //
  65. INT_PTR
  66. APIENTRY
  67. EnvVarsEditDlg(
  68. IN HWND hDlg,
  69. IN UINT uMsg,
  70. IN WPARAM wParam,
  71. IN LPARAM lParam
  72. );
  73. void
  74. EVDoEdit(
  75. IN HWND hWnd,
  76. IN UINT VarType,
  77. IN UINT EditType,
  78. IN int iSelection
  79. );
  80. BOOL
  81. ExpandSystemVar(
  82. IN LPCTSTR pszSrc,
  83. OUT LPTSTR pszDst,
  84. IN DWORD cchDst
  85. );
  86. //==========================================================================
  87. // "Global" Variables for this page
  88. //==========================================================================
  89. BOOL bEditSystemVars = FALSE;
  90. DWORD cxLBSysVars = 0;
  91. BOOL bUserVars = TRUE;
  92. //
  93. // Help ID's
  94. //
  95. DWORD aEnvVarsHelpIds[] = {
  96. IDC_STATIC, NO_HELP,
  97. IDC_ENVVAR_SYS_USERGROUP, (IDH_ENV + 2),
  98. IDC_ENVVAR_SYS_LB_USERVARS, (IDH_ENV + 2),
  99. IDC_ENVVAR_SYS_SYSGROUP, (IDH_ENV + 0),
  100. IDC_ENVVAR_SYS_LB_SYSVARS, (IDH_ENV + 0),
  101. IDC_ENVVAR_SYS_NEWUV, (IDH_ENV + 7),
  102. IDC_ENVVAR_SYS_EDITUV, (IDH_ENV + 8),
  103. IDC_ENVVAR_SYS_NDELUV, (IDH_ENV + 9),
  104. IDC_ENVVAR_SYS_NEWSV, (IDH_ENV + 10),
  105. IDC_ENVVAR_SYS_EDITSV, (IDH_ENV + 11),
  106. IDC_ENVVAR_SYS_DELSV, (IDH_ENV + 12),
  107. 0, 0
  108. };
  109. TCHAR szUserEnv[] = TEXT( "Environment" );
  110. TCHAR szSysEnv[] = TEXT( "System\\CurrentControlSet\\Control\\Session Manager\\Environment" );
  111. BOOL
  112. InitEnvVarsDlg(
  113. IN HWND hDlg
  114. )
  115. /*++
  116. Routine Description:
  117. Initializes the environment variables page
  118. Arguments:
  119. hDlg -
  120. Supplies window handle
  121. Return Value:
  122. TRUE if successful
  123. FALSE if an error occurs
  124. --*/
  125. {
  126. TCHAR szBuffer1[200];
  127. TCHAR szBuffer2[300];
  128. TCHAR szUserName[MAX_USER_NAME];
  129. DWORD dwSize = MAX_USER_NAME;
  130. HWND hwndTemp;
  131. HKEY hkeyEnv;
  132. TCHAR *pszValue;
  133. HANDLE hKey;
  134. DWORD dwBufz, dwValz, dwIndex, dwType;
  135. LONG Error;
  136. TCHAR szTemp[BUFZ];
  137. LPTSTR pszString;
  138. ENVARS *penvar;
  139. int n;
  140. LV_COLUMN col;
  141. LV_ITEM item;
  142. RECT rect;
  143. int cxFirstCol;
  144. DWORD dwSysRegMode;
  145. HourGlass (TRUE);
  146. //
  147. // Create the first column
  148. //
  149. LoadString (hInstance, IDS_ENVVAR_VARIABLE_HEADING, szBuffer1, 200);
  150. if (!GetClientRect (GetDlgItem(hDlg, IDC_ENVVAR_SYS_LB_SYSVARS), &rect)) {
  151. rect.right = 300;
  152. }
  153. cxFirstCol = (int)(rect.right * .3);
  154. col.mask = LVCF_FMT | LVCF_SUBITEM | LVCF_TEXT | LVCF_WIDTH;
  155. col.fmt = LVCFMT_LEFT;
  156. col.cx = cxFirstCol;
  157. col.pszText = szBuffer1;
  158. col.iSubItem = 0;
  159. SendDlgItemMessage (hDlg, IDC_ENVVAR_SYS_LB_SYSVARS, LVM_INSERTCOLUMN,
  160. 0, (LPARAM) &col);
  161. SendDlgItemMessage (hDlg, IDC_ENVVAR_SYS_LB_USERVARS, LVM_INSERTCOLUMN,
  162. 0, (LPARAM) &col);
  163. //
  164. // Create the second column
  165. //
  166. LoadString (hInstance, IDS_ENVVAR_VALUE_HEADING, szBuffer1, 200);
  167. col.cx = rect.right - cxFirstCol - GetSystemMetrics(SM_CYHSCROLL);
  168. col.iSubItem = 1;
  169. SendDlgItemMessage (hDlg, IDC_ENVVAR_SYS_LB_SYSVARS, LVM_INSERTCOLUMN,
  170. 1, (LPARAM) &col);
  171. SendDlgItemMessage (hDlg, IDC_ENVVAR_SYS_LB_USERVARS, LVM_INSERTCOLUMN,
  172. 1, (LPARAM) &col);
  173. ////////////////////////////////////////////////////////////////////
  174. // Display System Variables from registry in listbox
  175. ////////////////////////////////////////////////////////////////////
  176. hwndTemp = GetDlgItem (hDlg, IDC_ENVVAR_SYS_LB_SYSVARS);
  177. hKey = MemAlloc (LPTR, BUFZ*SIZEOF(TCHAR));
  178. pszString = (LPTSTR) MemAlloc (LPTR, BUFZ*sizeof(TCHAR));
  179. cxLBSysVars = 0;
  180. hkeyEnv = NULL;
  181. // If user is an admin, then try to open the System Environment variables area with R/W, allow to edit
  182. if (IsUserAdmin())
  183. {
  184. dwSysRegMode = KEY_READ | KEY_WRITE;
  185. bEditSystemVars = TRUE;
  186. }
  187. else // If not ad admin, open with Read-Only, disallow edit of System Env variables area
  188. {
  189. dwSysRegMode = KEY_READ;
  190. bEditSystemVars = FALSE;
  191. }
  192. // On failure, just try to open it for reading
  193. if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, szSysEnv, 0, dwSysRegMode, &hkeyEnv) != ERROR_SUCCESS) {
  194. hkeyEnv = NULL;
  195. }
  196. if (hkeyEnv)
  197. {
  198. pszValue = (TCHAR *) hKey;
  199. dwBufz = ARRAYSIZE(szTemp);
  200. dwValz = BUFZ * SIZEOF(TCHAR);
  201. dwIndex = 0;
  202. // Read all values until an error is encountered
  203. while (!RegEnumValue(hkeyEnv,
  204. dwIndex++, // Index'th value name/data
  205. szTemp, // Ptr to ValueName buffer
  206. &dwBufz, // Size of ValueName buffer
  207. NULL, // Title index return
  208. &dwType, // Type code of entry
  209. (LPBYTE) pszValue, // Ptr to ValueData buffer
  210. &dwValz)) // Size of ValueData buffer
  211. {
  212. if ((dwType != REG_SZ) && (dwType != REG_EXPAND_SZ))
  213. goto SysLoop;
  214. //
  215. // Clip length of returned Environment variable string
  216. // to MAX_VALUE_LEN-1, as necessary.
  217. //
  218. pszValue[MAX_VALUE_LEN-1] = TEXT('\0');
  219. ExpandSystemVar (pszValue, pszString, BUFZ);
  220. penvar = (ENVARS *) MemAlloc (LPTR, SIZEOF(ENVARS));
  221. penvar->dwType = dwType;
  222. penvar->szValueName = CloneString( szTemp );
  223. penvar->szValue = CloneString( pszValue );
  224. penvar->szExpValue = CloneString( pszString );
  225. item.mask = LVIF_TEXT | LVIF_PARAM;
  226. item.iItem = (dwIndex - 1);
  227. item.iSubItem = 0;
  228. item.pszText = penvar->szValueName;
  229. item.lParam = (LPARAM) penvar;
  230. n = (int)SendMessage (hwndTemp, LVM_INSERTITEM, 0, (LPARAM) &item);
  231. if (n != -1) {
  232. item.mask = LVIF_TEXT;
  233. item.iItem = n;
  234. item.iSubItem = 1;
  235. item.pszText = penvar->szExpValue;
  236. SendMessage (hwndTemp, LVM_SETITEMTEXT, n, (LPARAM) &item);
  237. }
  238. SysLoop:
  239. // Reset vars for next iteration
  240. dwBufz = ARRAYSIZE(szTemp);
  241. dwValz = BUFZ * SIZEOF(TCHAR);
  242. }
  243. RegCloseKey (hkeyEnv);
  244. }
  245. ////////////////////////////////////////////////////////////////////
  246. // Display USER variables from registry in listbox
  247. ////////////////////////////////////////////////////////////////////
  248. //
  249. // Set the "User Environments for <username>" string
  250. //
  251. if (GetUserName(szUserName, &dwSize) &&
  252. LoadString (hInstance, IDS_USERENVVARS, szBuffer1, 200)) {
  253. wsprintf (szBuffer2, szBuffer1, szUserName);
  254. SetDlgItemText (hDlg, IDC_ENVVAR_SYS_USERGROUP, szBuffer2);
  255. }
  256. Error = RegCreateKey (HKEY_CURRENT_USER, szUserEnv, &hkeyEnv);
  257. if (Error == ERROR_SUCCESS && hKey)
  258. {
  259. hwndTemp = GetDlgItem (hDlg, IDC_ENVVAR_SYS_LB_USERVARS);
  260. pszValue = (TCHAR *) hKey;
  261. dwBufz = ARRAYSIZE(szTemp);
  262. dwValz = BUFZ * SIZEOF(TCHAR);
  263. dwIndex = 0;
  264. // Read all values until an error is encountered
  265. while (!RegEnumValue(hkeyEnv,
  266. dwIndex++, // Index'th value name/data
  267. szTemp, // Ptr to ValueName buffer
  268. &dwBufz, // Size of ValueName buffer
  269. NULL, // Title index return
  270. &dwType, // Type code of entry
  271. (LPBYTE) pszValue, // Ptr to ValueData buffer
  272. &dwValz)) // Size of ValueData buffer
  273. {
  274. if ((dwType != REG_SZ) && (dwType != REG_EXPAND_SZ))
  275. goto UserLoop;
  276. //
  277. // Clip length of returned Environment variable string
  278. // to MAX_VALUE_LEN-1, as necessary.
  279. //
  280. pszValue[MAX_VALUE_LEN-1] = TEXT('\0');
  281. ExpandEnvironmentStrings (pszValue, pszString, BUFZ);
  282. penvar = (ENVARS *) MemAlloc (LPTR, sizeof(ENVARS));
  283. penvar->dwType = dwType;
  284. penvar->szValueName = CloneString (szTemp);
  285. penvar->szValue = CloneString (pszValue);
  286. penvar->szExpValue = CloneString (pszString);
  287. item.mask = LVIF_TEXT | LVIF_PARAM;
  288. item.iItem = (dwIndex - 1);
  289. item.iSubItem = 0;
  290. item.pszText = penvar->szValueName;
  291. item.lParam = (LPARAM) penvar;
  292. n = (int)SendMessage (hwndTemp, LVM_INSERTITEM, 0, (LPARAM) &item);
  293. if (n != -1) {
  294. item.mask = LVIF_TEXT;
  295. item.iItem = n;
  296. item.iSubItem = 1;
  297. item.pszText = penvar->szExpValue;
  298. SendMessage (hwndTemp, LVM_SETITEMTEXT, n, (LPARAM) &item);
  299. }
  300. UserLoop:
  301. // Reset vars for next iteration
  302. dwBufz = ARRAYSIZE(szTemp);
  303. dwValz = BUFZ * SIZEOF(TCHAR);
  304. }
  305. RegCloseKey (hkeyEnv);
  306. }
  307. else
  308. {
  309. // Report opening USER Environment key
  310. if (MsgBoxParam (hDlg, IsUserAnAdmin() ? IDS_SYSDM_NOOPEN_USER_UNK : IDS_SYSDM_NOOPEN_USER_NOTADMIN,
  311. IDS_SYSDM_TITLE, MB_OKCANCEL | MB_ICONEXCLAMATION) == IDCANCEL)
  312. {
  313. // Free allocated memory since we are returning from here
  314. MemFree ((LPVOID)hKey);
  315. MemFree (pszString);
  316. HourGlass (FALSE);
  317. return FALSE;
  318. }
  319. }
  320. //
  321. // Select the first items in the listviews
  322. // It is important to set the User listview first, and
  323. // then the system. When the system listview is set,
  324. // we will receive a LVN_ITEMCHANGED notification and
  325. // clear the focus in the User listview. But when someone
  326. // tabs to the control the arrow keys will work correctly.
  327. //
  328. item.mask = LVIF_STATE;
  329. item.iItem = 0;
  330. item.iSubItem = 0;
  331. item.state = LVIS_SELECTED | LVIS_FOCUSED;
  332. item.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
  333. SendDlgItemMessage (hDlg, IDC_ENVVAR_SYS_LB_USERVARS,
  334. LVM_SETITEMSTATE, 0, (LPARAM) &item);
  335. SendDlgItemMessage (hDlg, IDC_ENVVAR_SYS_LB_SYSVARS,
  336. LVM_SETITEMSTATE, 0, (LPARAM) &item);
  337. MemFree ((LPVOID)hKey);
  338. MemFree (pszString);
  339. // Set extended LV style for whole line selection
  340. SendDlgItemMessage(hDlg, IDC_ENVVAR_SYS_LB_SYSVARS, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT);
  341. SendDlgItemMessage(hDlg, IDC_ENVVAR_SYS_LB_USERVARS, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT);
  342. HourGlass (FALSE);
  343. //
  344. // Disable System Var Editing buttons if
  345. // user is not an administrator
  346. //
  347. EnableWindow(
  348. GetDlgItem(hDlg, IDC_ENVVAR_SYS_NEWSV),
  349. bEditSystemVars
  350. );
  351. EnableWindow(
  352. GetDlgItem(hDlg, IDC_ENVVAR_SYS_EDITSV),
  353. bEditSystemVars
  354. );
  355. EnableWindow(
  356. GetDlgItem(hDlg, IDC_ENVVAR_SYS_DELSV),
  357. bEditSystemVars
  358. );
  359. ///////////////////
  360. // Return succes //
  361. ///////////////////
  362. return TRUE;
  363. }
  364. INT_PTR
  365. APIENTRY
  366. EnvVarsDlgProc(
  367. IN HWND hDlg,
  368. IN UINT uMsg,
  369. IN WPARAM wParam,
  370. IN LPARAM lParam
  371. )
  372. /*++
  373. Routine Description:
  374. Handles messages sent to the Environment Variables dialog box
  375. Arguments:
  376. hDlg -
  377. Supplies window handle
  378. uMsg -
  379. Supplies message being sent
  380. wParam -
  381. Supplies message parameter
  382. lParam -
  383. Supplies message parameter
  384. Return Value:
  385. TRUE if message was handled
  386. FALSE if message was unhandled
  387. --*/
  388. {
  389. INT i = 0;
  390. HWND hWndTemp = NULL;
  391. switch (uMsg)
  392. {
  393. case WM_INITDIALOG:
  394. if (!InitEnvVarsDlg(hDlg)) {
  395. EndDialog (hDlg, 0);
  396. }
  397. break;
  398. case WM_NOTIFY:
  399. switch (((NMHDR FAR*)lParam)->code)
  400. {
  401. case LVN_KEYDOWN:
  402. switch (((NMHDR FAR*)lParam)->idFrom) {
  403. case IDC_ENVVAR_SYS_LB_USERVARS:
  404. i = IDC_ENVVAR_SYS_NDELUV;
  405. break;
  406. case IDC_ENVVAR_SYS_LB_SYSVARS:
  407. i = IDC_ENVVAR_SYS_DELSV;
  408. break;
  409. default:
  410. return(FALSE);
  411. break;
  412. } // switch
  413. hWndTemp = GetDlgItem(hDlg, i);
  414. if ((VK_DELETE == ((LV_KEYDOWN FAR *) lParam)->wVKey)) {
  415. if (IsWindowEnabled(hWndTemp)) {
  416. SendMessage(
  417. hDlg,
  418. WM_COMMAND,
  419. MAKEWPARAM(i, BN_CLICKED),
  420. (LPARAM) hWndTemp
  421. );
  422. } // if (IsWindowEnabled...
  423. else {
  424. MessageBeep(MB_ICONASTERISK);
  425. } // else
  426. } // if (VK_DELETE...
  427. break;
  428. case NM_DBLCLK:
  429. switch (((NMHDR FAR*)lParam)->idFrom) {
  430. case IDC_ENVVAR_SYS_LB_USERVARS:
  431. i = IDC_ENVVAR_SYS_EDITUV;
  432. break;
  433. case IDC_ENVVAR_SYS_LB_SYSVARS:
  434. i = IDC_ENVVAR_SYS_EDITSV;
  435. break;
  436. default:
  437. return(FALSE);
  438. break;
  439. } // switch
  440. hWndTemp = GetDlgItem(hDlg, i);
  441. if (IsWindowEnabled(hWndTemp)) {
  442. SendMessage(
  443. hDlg,
  444. WM_COMMAND,
  445. MAKEWPARAM(i, BN_CLICKED),
  446. (LPARAM) hWndTemp
  447. );
  448. } // if (IsWindowEnabled...
  449. else {
  450. MessageBeep(MB_ICONASTERISK);
  451. } // else
  452. break;
  453. default:
  454. return FALSE;
  455. }
  456. break;
  457. case WM_COMMAND:
  458. EVDoCommand(hDlg, (HWND)lParam, LOWORD(wParam), HIWORD(wParam));
  459. break;
  460. case WM_DESTROY:
  461. EVCleanUp (hDlg);
  462. break;
  463. case WM_HELP: // F1
  464. WinHelp((HWND)((LPHELPINFO) lParam)->hItemHandle, HELP_FILE, HELP_WM_HELP, (DWORD_PTR) (LPSTR) aEnvVarsHelpIds);
  465. break;
  466. case WM_CONTEXTMENU: // right mouse click
  467. WinHelp((HWND) wParam, HELP_FILE, HELP_CONTEXTMENU, (DWORD_PTR) (LPSTR) aEnvVarsHelpIds);
  468. break;
  469. default:
  470. return FALSE;
  471. }
  472. return TRUE;
  473. }
  474. void
  475. EVDoCommand(
  476. IN HWND hDlg,
  477. IN HWND hwndCtl,
  478. IN int idCtl,
  479. IN int iNotify
  480. )
  481. /*++
  482. Routine Description:
  483. Handles WM_COMMAND messages sent to Environment Variables dialog box
  484. Arguments:
  485. hDlg -
  486. Supplies window handle
  487. hwndCtl -
  488. Supplies window handle of control which sent the WM_COMMAND
  489. idCtl -
  490. Supplies ID of control which sent the WM_COMMAND
  491. iNotify -
  492. Supplies notification code
  493. Return Value:
  494. None
  495. --*/
  496. {
  497. TCHAR szTemp[MAX_PATH];
  498. int i;
  499. HWND hwndTemp;
  500. PENVAR penvar;
  501. switch (idCtl) {
  502. case IDOK:
  503. EVSave(hDlg);
  504. EndDialog(hDlg, 0);
  505. break;
  506. case IDCANCEL:
  507. EndDialog(hDlg, 0);
  508. break;
  509. case IDC_ENVVAR_SYS_EDITSV:
  510. EVDoEdit(
  511. hDlg,
  512. SYSTEM_VAR,
  513. EDIT_VAR,
  514. GetSelectedItem(GetDlgItem(hDlg, IDC_ENVVAR_SYS_LB_SYSVARS))
  515. );
  516. break;
  517. case IDC_ENVVAR_SYS_EDITUV:
  518. EVDoEdit(
  519. hDlg,
  520. USER_VAR,
  521. EDIT_VAR,
  522. GetSelectedItem(GetDlgItem(hDlg, IDC_ENVVAR_SYS_LB_USERVARS))
  523. );
  524. break;
  525. case IDC_ENVVAR_SYS_NEWSV:
  526. EVDoEdit(hDlg, SYSTEM_VAR, NEW_VAR, -1);
  527. break;
  528. case IDC_ENVVAR_SYS_NEWUV:
  529. EVDoEdit(hDlg, USER_VAR, NEW_VAR, -1);
  530. break;
  531. case IDC_ENVVAR_SYS_DELSV:
  532. i = GetSelectedItem(GetDlgItem(hDlg, IDC_ENVVAR_SYS_LB_SYSVARS));
  533. if (-1 != i)
  534. {
  535. penvar = GetVar(hDlg, SYSTEM_VAR, i);
  536. if (penvar)
  537. {
  538. DeleteVar(hDlg, SYSTEM_VAR, penvar->szValueName);
  539. }
  540. } // if
  541. break;
  542. case IDC_ENVVAR_SYS_NDELUV:
  543. i = GetSelectedItem(GetDlgItem(hDlg, IDC_ENVVAR_SYS_LB_USERVARS));
  544. if (-1 != i)
  545. {
  546. penvar = GetVar(hDlg, USER_VAR, i);
  547. if (penvar)
  548. {
  549. DeleteVar(hDlg, USER_VAR, penvar->szValueName);
  550. }
  551. } // if
  552. break;
  553. default:
  554. break;
  555. } // switch
  556. return;
  557. }
  558. void
  559. DeleteVar(
  560. IN HWND hDlg,
  561. IN UINT VarType,
  562. IN LPCTSTR szVarName
  563. )
  564. /*++
  565. Routine Description:
  566. Deletes an environment variable of a given name and type
  567. Arguments:
  568. hDlg -
  569. Supplies window handle
  570. VarType -
  571. Supplies variable type (user or system)
  572. szVarName -
  573. Supplies variable name
  574. Return Value:
  575. None, although it really should have one someday.
  576. --*/
  577. {
  578. TCHAR szTemp2[MAX_PATH];
  579. int i, n;
  580. TCHAR *bBuffer;
  581. TCHAR *pszTemp;
  582. LPTSTR pszString;
  583. HWND hwndTemp;
  584. ENVARS *penvar;
  585. LV_ITEM item;
  586. // Delete listbox entry that matches value in szVarName
  587. // If found, delete entry else ignore
  588. wsprintf(
  589. szTemp2,
  590. TEXT("%s"),
  591. szVarName
  592. );
  593. if (szTemp2[0] == TEXT('\0'))
  594. return;
  595. // Determine which Listbox to use (SYSTEM or USER vars)
  596. switch (VarType) {
  597. case SYSTEM_VAR:
  598. i = IDC_ENVVAR_SYS_LB_SYSVARS;
  599. break;
  600. case USER_VAR:
  601. default:
  602. i = IDC_ENVVAR_SYS_LB_USERVARS;
  603. break;
  604. } // switch (VarType)
  605. hwndTemp = GetDlgItem (hDlg, i);
  606. n = FindVar (hwndTemp, szTemp2);
  607. if (n != -1)
  608. {
  609. // Free existing strings (listbox and ours)
  610. item.mask = LVIF_PARAM;
  611. item.iItem = n;
  612. item.iSubItem = 0;
  613. if (SendMessage (hwndTemp, LVM_GETITEM, 0, (LPARAM) &item)) {
  614. penvar = (ENVARS *) item.lParam;
  615. } else {
  616. penvar = NULL;
  617. }
  618. if (penvar) {
  619. MemFree (penvar->szValueName);
  620. MemFree (penvar->szValue);
  621. MemFree (penvar->szExpValue);
  622. MemFree ((LPVOID) penvar);
  623. }
  624. SendMessage (hwndTemp, LVM_DELETEITEM, n, 0L);
  625. PropSheet_Changed(GetParent(hDlg), hDlg);
  626. // Fix selection state in listview
  627. if (n > 0) {
  628. n--;
  629. }
  630. item.mask = LVIF_STATE;
  631. item.iItem = n;
  632. item.iSubItem = 0;
  633. item.state = LVIS_SELECTED | LVIS_FOCUSED;
  634. item.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
  635. SendDlgItemMessage (hDlg, i,
  636. LVM_SETITEMSTATE, n, (LPARAM) &item);
  637. }
  638. return;
  639. }
  640. void
  641. SetVar(
  642. IN HWND hDlg,
  643. IN UINT VarType,
  644. IN LPCTSTR szVarName,
  645. IN LPCTSTR szVarValue
  646. )
  647. /*++
  648. Routine Description:
  649. Given an environment variable's type (system or user), name, and value,
  650. creates a ENVVARS structure for that environment variable and inserts
  651. it into the proper list view control, deleteing any existing variable
  652. of the same name.
  653. Arguments:
  654. hDlg -
  655. Supplies window handle
  656. VarType -
  657. Supplies the type of the environment variable (system or user)
  658. szVarName -
  659. Supplies the name of the environment variable
  660. szVarValue -
  661. Supplies the value of the environment variable
  662. Return Value:
  663. None, although it really should have one someday.
  664. --*/
  665. {
  666. TCHAR szTemp2[BUFZ];
  667. int i, n;
  668. TCHAR *bBuffer;
  669. TCHAR *pszTemp;
  670. LPTSTR pszString;
  671. HWND hwndTemp;
  672. int idTemp;
  673. ENVARS *penvar;
  674. LV_ITEM item;
  675. wnsprintf(szTemp2, ARRAYSIZE(szTemp2), TEXT("%s"), szVarName);
  676. // Strip trailing whitespace from end of Env Variable
  677. i = lstrlen(szTemp2) - 1;
  678. while (i >= 0)
  679. {
  680. if (_istspace(szTemp2[i]))
  681. szTemp2[i--] = TEXT('\0');
  682. else
  683. break;
  684. }
  685. // Make sure variable name does not contain the "=" sign.
  686. pszTemp = _tcspbrk (szTemp2, TEXT("="));
  687. if (pszTemp)
  688. *pszTemp = TEXT('\0');
  689. if (szTemp2[0] == TEXT('\0'))
  690. return;
  691. bBuffer = (TCHAR *) MemAlloc (LPTR, BUFZ * sizeof(TCHAR));
  692. if (bBuffer)
  693. {
  694. pszString = (LPTSTR) MemAlloc (LPTR, BUFZ * sizeof(TCHAR));
  695. if (pszString)
  696. {
  697. wnsprintf(bBuffer, (BUFZ), TEXT("%s"), szVarValue);
  698. // Determine which Listbox to use (SYSTEM or USER vars)
  699. switch (VarType)
  700. {
  701. case SYSTEM_VAR:
  702. idTemp = IDC_ENVVAR_SYS_LB_SYSVARS;
  703. break;
  704. case USER_VAR:
  705. default:
  706. idTemp = IDC_ENVVAR_SYS_LB_USERVARS;
  707. break;
  708. } // switch (VarType)
  709. hwndTemp = GetDlgItem(hDlg, idTemp);
  710. n = FindVar(hwndTemp, szTemp2);
  711. if (n != -1)
  712. {
  713. // Free existing strings (listview and ours)
  714. item.mask = LVIF_PARAM;
  715. item.iItem = n;
  716. item.iSubItem = 0;
  717. if (SendMessage(hwndTemp, LVM_GETITEM, 0, (LPARAM) &item))
  718. {
  719. penvar = (ENVARS *) item.lParam;
  720. }
  721. else
  722. {
  723. penvar = NULL;
  724. }
  725. if (penvar)
  726. {
  727. MemFree(penvar->szValueName);
  728. MemFree(penvar->szValue);
  729. MemFree(penvar->szExpValue);
  730. }
  731. SendMessage(hwndTemp, LVM_DELETEITEM, n, 0L);
  732. }
  733. else
  734. {
  735. // Get some storage for new Env Var
  736. penvar = (ENVARS *) MemAlloc(LPTR, sizeof(ENVARS));
  737. }
  738. // If there are two '%' chars in string, then this is a
  739. // REG_EXPAND_SZ style environment string
  740. pszTemp = _tcspbrk (bBuffer, TEXT("%"));
  741. if (penvar)
  742. {
  743. if (pszTemp && _tcspbrk (pszTemp, TEXT("%")))
  744. penvar->dwType = REG_EXPAND_SZ;
  745. else
  746. penvar->dwType = REG_SZ;
  747. }
  748. switch (VarType)
  749. {
  750. case SYSTEM_VAR:
  751. ExpandSystemVar(bBuffer, pszString, BUFZ);
  752. break;
  753. case USER_VAR:
  754. ExpandEnvironmentStrings (bBuffer, pszString, BUFZ);
  755. break;
  756. default:
  757. break;
  758. } // switch
  759. if (penvar)
  760. {
  761. penvar->szValueName = CloneString (szTemp2);
  762. penvar->szValue = CloneString (bBuffer);
  763. penvar->szExpValue = CloneString (pszString);
  764. item.mask = LVIF_TEXT | LVIF_PARAM;
  765. item.iItem = ListView_GetItemCount(hwndTemp);
  766. item.iSubItem = 0;
  767. item.pszText = penvar->szValueName;
  768. item.lParam = (LPARAM) penvar;
  769. n = (int)SendMessage (hwndTemp, LVM_INSERTITEM, 0, (LPARAM) &item);
  770. }
  771. else
  772. {
  773. n = -1;
  774. }
  775. if (n != -1)
  776. {
  777. item.mask = LVIF_TEXT;
  778. item.iItem = n;
  779. item.iSubItem = 1;
  780. item.pszText = penvar->szExpValue;
  781. SendMessage (hwndTemp, LVM_SETITEMTEXT, n, (LPARAM) &item);
  782. item.mask = LVIF_STATE;
  783. item.iItem = n;
  784. item.iSubItem = 0;
  785. item.state = LVIS_SELECTED | LVIS_FOCUSED;
  786. item.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
  787. SendDlgItemMessage (hDlg, idTemp, LVM_SETITEMSTATE, n, (LPARAM) &item);
  788. }
  789. MemFree(pszString);
  790. }
  791. MemFree(bBuffer);
  792. }
  793. return;
  794. }
  795. void
  796. EVDoEdit(
  797. IN HWND hWnd,
  798. IN UINT VarType,
  799. IN UINT EditType,
  800. IN int iSelection
  801. )
  802. /*++
  803. Routine Description:
  804. Sets up for, executes, and cleans up after an Environment Variable
  805. New... or Edit... dialog. Called when user presses a New... or Edit...
  806. button.
  807. Arguments:
  808. hWnd -
  809. Supplies window handle
  810. VarType -
  811. Supplies the type of the variable: User (USER_VAR) or
  812. System (SYSTEM_VAR)
  813. EditType -
  814. Supplies the type of the edit: create New (NEW_VAR) or
  815. Edit existing (EDIT_VAR)
  816. iSelection -
  817. Supplies the currently selected variable of type VarType. This
  818. value is ignored if EditType is NEW_VAR.
  819. Return Value:
  820. None. May alter the contents of a list view control as a side effect.
  821. --*/
  822. {
  823. LRESULT Result = 0;
  824. BOOL fVarChanged = FALSE;
  825. HWND hWndLB = NULL;
  826. ENVARS *penvar = NULL;
  827. LV_ITEM item;
  828. ASSERT((-1 != iSelection) || (NEW_VAR == EditType));
  829. g_VarType = VarType;
  830. g_EditType = EditType;
  831. penvar = GetVar(hWnd, VarType, iSelection);
  832. switch (EditType) {
  833. case NEW_VAR:
  834. ZeroMemory((LPVOID) g_szVarName, (DWORD) BUFZ * sizeof(TCHAR));
  835. ZeroMemory((LPVOID) g_szVarValue, (DWORD) BUFZ * sizeof(TCHAR));
  836. break;
  837. case EDIT_VAR:
  838. if (penvar) {
  839. wsprintf(
  840. g_szVarName,
  841. TEXT("%s"),
  842. penvar->szValueName
  843. );
  844. wsprintf(
  845. g_szVarValue,
  846. TEXT("%s"),
  847. penvar->szValue
  848. );
  849. } // if
  850. else {
  851. MessageBeep(MB_ICONASTERISK);
  852. return;
  853. } // else
  854. break;
  855. case INVALID_EDIT_TYPE:
  856. default:
  857. return;
  858. } // switch
  859. Result = DialogBox(
  860. hInstance,
  861. (LPTSTR) MAKEINTRESOURCE(IDD_ENVVAREDIT),
  862. hWnd,
  863. EnvVarsEditDlg
  864. );
  865. //
  866. // Only update the list view control if the user
  867. // actually changed or created a variable
  868. //
  869. switch (Result) {
  870. case EDIT_CHANGE:
  871. if (EDIT_VAR == EditType) {
  872. fVarChanged =
  873. lstrcmp(penvar->szValueName, g_szVarName) ||
  874. lstrcmp(penvar->szValue, g_szVarValue);
  875. } // if (EDIT_VAR...
  876. else if (NEW_VAR == EditType) {
  877. fVarChanged =
  878. lstrlen(g_szVarName) && lstrlen(g_szVarValue);
  879. } // else if (NEW_VAR...
  880. else {
  881. fVarChanged = FALSE;
  882. } // else
  883. if (fVarChanged) {
  884. if (EDIT_VAR == EditType) {
  885. DeleteVar(hWnd, VarType, penvar->szValueName);
  886. } // if (EDIT_VAR...
  887. SetVar(hWnd, VarType, g_szVarName, g_szVarValue);
  888. } // if (fVarChanged)
  889. break;
  890. default:
  891. break;
  892. } // switch (Result)
  893. g_VarType = INVALID_VAR_TYPE;
  894. g_EditType = INVALID_EDIT_TYPE;
  895. return;
  896. }
  897. PENVAR
  898. GetVar(
  899. IN HWND hDlg,
  900. IN UINT VarType,
  901. IN int iSelection
  902. )
  903. /*++
  904. Routine Description:
  905. Returns a given System or User environment variable, as stored
  906. in the System or User environment variable listview control.
  907. Changing the structure returned by this routine is not
  908. recommended, because it will alter the values actually stored
  909. in the listview control.
  910. Arguments:
  911. hDlg -
  912. Supplies window handle
  913. VarType -
  914. Supplies variable type--System or User
  915. iSelection -
  916. Supplies the selection index into the listview control of
  917. the desired environment variable
  918. Return Value:
  919. Pointer to a valid ENVARS structure if successful.
  920. NULL if unsuccessful.
  921. --*/
  922. {
  923. HWND hWndLB = NULL;
  924. PENVAR penvar = NULL;
  925. LV_ITEM item;
  926. switch (VarType)
  927. {
  928. case SYSTEM_VAR:
  929. hWndLB = GetDlgItem(hDlg, IDC_ENVVAR_SYS_LB_SYSVARS);
  930. break;
  931. case USER_VAR:
  932. hWndLB = GetDlgItem(hDlg, IDC_ENVVAR_SYS_LB_USERVARS);
  933. break;
  934. case INVALID_VAR_TYPE:
  935. default:
  936. return NULL;
  937. } // switch (VarType)
  938. item.mask = LVIF_PARAM;
  939. item.iItem = iSelection;
  940. item.iSubItem = 0;
  941. if (iSelection >= 0 && SendMessage (hWndLB, LVM_GETITEM, 0, (LPARAM) &item))
  942. {
  943. penvar = (ENVARS *) item.lParam;
  944. }
  945. else
  946. {
  947. penvar = NULL;
  948. }
  949. return penvar;
  950. }
  951. int
  952. FindVar(
  953. IN HWND hwndLV,
  954. IN LPTSTR szVar
  955. )
  956. /*++
  957. Routine Description:
  958. Find the USER Environment variable that matches passed string
  959. and return its listview index or -1
  960. Arguments:
  961. hwndLV -
  962. Supplies window handle to the list view control containing the
  963. environment variables
  964. szVar -
  965. Supplies the variable name in string form
  966. Return Value:
  967. List view item index which matches the passed in string if the string
  968. is the name of an environment variable
  969. -1 if the passed in string is not the name of an environment variable
  970. --*/
  971. {
  972. LV_FINDINFO FindInfo;
  973. FindInfo.flags = LVFI_STRING;
  974. FindInfo.psz = szVar;
  975. return (int)(SendMessage (hwndLV, LVM_FINDITEM, (WPARAM) -1, (LPARAM) &FindInfo));
  976. }
  977. //
  978. // Hydra's
  979. // WinStationBroadcastSystemMessage(
  980. //
  981. typedef
  982. LONG
  983. (*PWINSTABSM_ROUTINE) (
  984. HANDLE hServer,
  985. BOOL sendToAllWinstations, // you set this to TRUE
  986. ULONG sessionID, // set to NULL, due to above
  987. ULONG timeOut,
  988. DWORD dwFlags,
  989. DWORD *lpdwRecipients,
  990. ULONG uiMessage,
  991. WPARAM wParam,
  992. LPARAM lParam,
  993. LONG *pResponse);
  994. PWINSTABSM_ROUTINE fp_WinStaBroadcastSystemMessage;
  995. // load winsta.dll (if any) and initialize the global function pointers to use
  996. HANDLE
  997. InitializeHydraInterface(
  998. void
  999. )
  1000. {
  1001. HANDLE hwinStaLib=NULL;
  1002. //
  1003. // Load the Terminal Server base library that contains the user message dispatch
  1004. // routines if termial server is running.
  1005. //
  1006. if (hwinStaLib = LoadLibrary(TEXT("WINSTA.DLL")))
  1007. {
  1008. fp_WinStaBroadcastSystemMessage = (PWINSTABSM_ROUTINE)GetProcAddress(
  1009. hwinStaLib,"WinStationBroadcastSystemMessage");
  1010. if (fp_WinStaBroadcastSystemMessage )
  1011. {
  1012. return (hwinStaLib);
  1013. }
  1014. else
  1015. {
  1016. // this must not be a NT5 running Terminal Services, which means
  1017. // it could be NT5 WKS, or some flavor of NT4.
  1018. // So, we just bail out, no problem.
  1019. FreeLibrary(hwinStaLib);
  1020. return (NULL);
  1021. }
  1022. }
  1023. return NULL;
  1024. }
  1025. void
  1026. EVSave(
  1027. IN HWND hDlg
  1028. )
  1029. /*++
  1030. Routine Description:
  1031. Saves the environment variables in the registry
  1032. Arguments:
  1033. hDlg -
  1034. Supplies window handle
  1035. Return Value:
  1036. None
  1037. --*/
  1038. {
  1039. TCHAR szTemp[BUFZ];
  1040. int selection;
  1041. int i, n;
  1042. TCHAR *bBuffer;
  1043. TCHAR *pszTemp;
  1044. LPTSTR pszString;
  1045. HWND hwndTemp;
  1046. ENVARS *penvar;
  1047. REGVAL *prvFirst;
  1048. REGVAL *prvRegVal;
  1049. HKEY hkeyEnv;
  1050. DWORD dwBufz, dwIndex, dwType;
  1051. LV_ITEM item;
  1052. HourGlass (TRUE);
  1053. /////////////////////////////////////////////////////////////////
  1054. // Set all new USER environment variables to current values
  1055. // but delete all old environment variables first
  1056. /////////////////////////////////////////////////////////////////
  1057. if (RegOpenKeyEx (HKEY_CURRENT_USER, szUserEnv, 0,
  1058. KEY_READ | KEY_WRITE, &hkeyEnv)
  1059. == ERROR_SUCCESS)
  1060. {
  1061. dwBufz = ARRAYSIZE(szTemp);
  1062. dwIndex = 0;
  1063. // Delete all values of type REG_SZ & REG_EXPAND_SZ under key
  1064. // First: Make a linked list of all USER Env string vars
  1065. prvFirst = (REGVAL *) NULL;
  1066. while (!RegEnumValue(hkeyEnv,
  1067. dwIndex++, // Index'th value name/data
  1068. szTemp, // Ptr to ValueName buffer
  1069. &dwBufz, // Size of ValueName buffer
  1070. NULL, // Title index return
  1071. &dwType, // Type code of entry
  1072. NULL, // Ptr to ValueData buffer
  1073. NULL)) // Size of ValueData buffer
  1074. {
  1075. if ((dwType != REG_SZ) && (dwType != REG_EXPAND_SZ))
  1076. goto EVSGetNextUserVar;
  1077. if (prvFirst)
  1078. {
  1079. prvRegVal->prvNext = (REGVAL *) MemAlloc (LPTR, sizeof(REGVAL));
  1080. prvRegVal = prvRegVal->prvNext;
  1081. }
  1082. else // First time thru
  1083. {
  1084. prvFirst = prvRegVal = (REGVAL *) MemAlloc (LPTR, sizeof(REGVAL));
  1085. }
  1086. prvRegVal->prvNext = NULL;
  1087. prvRegVal->szValueName = CloneString (szTemp);
  1088. // Reset vars for next call
  1089. EVSGetNextUserVar:
  1090. dwBufz = ARRAYSIZE(szTemp);
  1091. }
  1092. // Now traverse the list, deleting them all
  1093. prvRegVal = prvFirst;
  1094. while (prvRegVal)
  1095. {
  1096. RegDeleteValue (hkeyEnv, prvRegVal->szValueName);
  1097. MemFree (prvRegVal->szValueName);
  1098. prvFirst = prvRegVal;
  1099. prvRegVal = prvRegVal->prvNext;
  1100. MemFree ((LPVOID) prvFirst);
  1101. }
  1102. ///////////////////////////////////////////////////////////////
  1103. // Set all new USER environment variables to current values
  1104. ///////////////////////////////////////////////////////////////
  1105. hwndTemp = GetDlgItem (hDlg, IDC_ENVVAR_SYS_LB_USERVARS);
  1106. if ((n = (int)SendMessage (hwndTemp, LVM_GETITEMCOUNT, 0, 0L)) != LB_ERR)
  1107. {
  1108. item.mask = LVIF_PARAM;
  1109. item.iSubItem = 0;
  1110. for (i = 0; i < n; i++)
  1111. {
  1112. item.iItem = i;
  1113. if (SendMessage (hwndTemp, LVM_GETITEM, 0, (LPARAM) &item)) {
  1114. penvar = (ENVARS *) item.lParam;
  1115. } else {
  1116. penvar = NULL;
  1117. }
  1118. if (penvar) {
  1119. if (RegSetValueEx (hkeyEnv,
  1120. penvar->szValueName,
  1121. 0L,
  1122. penvar->dwType,
  1123. (LPBYTE) penvar->szValue,
  1124. (lstrlen (penvar->szValue)+1) * sizeof(TCHAR)))
  1125. {
  1126. // Report error trying to set registry values
  1127. if (MsgBoxParam (hDlg, IsUserAnAdmin() ? IDS_SYSDM_NONEW_ENV_UNK : IDS_SYSDM_NONEW_ENV_NOTADMIN, IDS_SYSDM_TITLE,
  1128. MB_OKCANCEL | MB_ICONEXCLAMATION) == IDCANCEL)
  1129. break;
  1130. }
  1131. }
  1132. }
  1133. }
  1134. RegFlushKey (hkeyEnv);
  1135. RegCloseKey (hkeyEnv);
  1136. }
  1137. else
  1138. {
  1139. // Report opening USER Environment key
  1140. if (MsgBoxParam (hDlg, IsUserAnAdmin() ? IDS_SYSDM_NOOPEN_USER_UNK : IDS_SYSDM_NOOPEN_USER_NOTADMIN, IDS_SYSDM_TITLE,
  1141. MB_OKCANCEL | MB_ICONEXCLAMATION) == IDCANCEL)
  1142. goto Exit;
  1143. }
  1144. /////////////////////////////////////////////////////////////////
  1145. // Set all new SYSTEM environment variables to current values
  1146. // but delete all old environment variables first
  1147. /////////////////////////////////////////////////////////////////
  1148. if (!bEditSystemVars)
  1149. goto SkipSystemVars;
  1150. if (RegOpenKeyEx (HKEY_LOCAL_MACHINE,
  1151. szSysEnv,
  1152. 0,
  1153. KEY_READ | KEY_WRITE,
  1154. &hkeyEnv)
  1155. == ERROR_SUCCESS)
  1156. {
  1157. dwBufz = ARRAYSIZE(szTemp);
  1158. dwIndex = 0;
  1159. // Delete all values of type REG_SZ & REG_EXPAND_SZ under key
  1160. // First: Make a linked list of all Env string vars
  1161. prvFirst = (REGVAL *) NULL;
  1162. while (!RegEnumValue(hkeyEnv,
  1163. dwIndex++, // Index'th value name/data
  1164. szTemp, // Ptr to ValueName buffer
  1165. &dwBufz, // Size of ValueName buffer
  1166. NULL, // Title index return
  1167. &dwType, // Type code of entry
  1168. NULL, // Ptr to ValueData buffer
  1169. NULL)) // Size of ValueData buffer
  1170. {
  1171. if ((dwType != REG_SZ) && (dwType != REG_EXPAND_SZ))
  1172. goto EVSGetNextSysVar;
  1173. if (prvFirst)
  1174. {
  1175. prvRegVal->prvNext = (REGVAL *) MemAlloc (LPTR, sizeof(REGVAL));
  1176. prvRegVal = prvRegVal->prvNext;
  1177. }
  1178. else // First time thru
  1179. {
  1180. prvFirst = prvRegVal = (REGVAL *) MemAlloc (LPTR, sizeof(REGVAL));
  1181. }
  1182. prvRegVal->prvNext = NULL;
  1183. prvRegVal->szValueName = CloneString (szTemp);
  1184. // Reset vars for next call
  1185. EVSGetNextSysVar:
  1186. dwBufz = ARRAYSIZE(szTemp);
  1187. }
  1188. // Now traverse the list, deleting them all
  1189. prvRegVal = prvFirst;
  1190. while (prvRegVal)
  1191. {
  1192. RegDeleteValue (hkeyEnv, prvRegVal->szValueName);
  1193. MemFree (prvRegVal->szValueName);
  1194. prvFirst = prvRegVal;
  1195. prvRegVal = prvRegVal->prvNext;
  1196. MemFree ((LPVOID) prvFirst);
  1197. }
  1198. ///////////////////////////////////////////////////////////////
  1199. // Set all new SYSTEM environment variables to current values
  1200. ///////////////////////////////////////////////////////////////
  1201. hwndTemp = GetDlgItem (hDlg, IDC_ENVVAR_SYS_LB_SYSVARS);
  1202. if ((n = (int)SendMessage (hwndTemp, LVM_GETITEMCOUNT, 0, 0L)) != LB_ERR)
  1203. {
  1204. item.mask = LVIF_PARAM;
  1205. item.iSubItem = 0;
  1206. for (i = 0; i < n; i++)
  1207. {
  1208. item.iItem = i;
  1209. if (SendMessage (hwndTemp, LVM_GETITEM, 0, (LPARAM) &item)) {
  1210. penvar = (ENVARS *) item.lParam;
  1211. } else {
  1212. penvar = NULL;
  1213. }
  1214. if (penvar) {
  1215. if (RegSetValueEx (hkeyEnv,
  1216. penvar->szValueName,
  1217. 0L,
  1218. penvar->dwType,
  1219. (LPBYTE) penvar->szValue,
  1220. (lstrlen (penvar->szValue)+1) * sizeof(TCHAR)))
  1221. {
  1222. // Report error trying to set registry values
  1223. if (MsgBoxParam (hDlg, IsUserAnAdmin() ? IDS_SYSDM_NONEW_ENV_UNK : IDS_SYSDM_NONEW_ENV_NOTADMIN, IDS_SYSDM_TITLE,
  1224. MB_OKCANCEL | MB_ICONEXCLAMATION) == IDCANCEL)
  1225. break;
  1226. }
  1227. }
  1228. }
  1229. }
  1230. RegFlushKey (hkeyEnv);
  1231. RegCloseKey (hkeyEnv);
  1232. }
  1233. else
  1234. {
  1235. // Report opening SYSTEM Environment key
  1236. if (MsgBoxParam (hDlg, IsUserAnAdmin() ? IDS_SYSDM_NOOPEN_SYS_UNK : IDS_SYSDM_NOOPEN_SYS_NOTADMIN, IDS_SYSDM_TITLE,
  1237. MB_OKCANCEL | MB_ICONEXCLAMATION) == IDCANCEL)
  1238. goto Exit;
  1239. }
  1240. SkipSystemVars:
  1241. // Send public message announcing change to Environment
  1242. SendMessageTimeout( (HWND)-1, WM_WININICHANGE, 0L, (LPARAM)szUserEnv,
  1243. SMTO_ABORTIFHUNG, 1000, NULL );
  1244. // the folllowing block will send a message to all terminal server session
  1245. // if and only if this is a NT5 and terminal services has been enabled.
  1246. if ( IsUserAdmin() )
  1247. {
  1248. HANDLE hwinStaLib;
  1249. // if this is an NT5, then we get a valid handle to winsta.dll library
  1250. // and the function pointer will be valid/initialized
  1251. hwinStaLib = InitializeHydraInterface();
  1252. if ( hwinStaLib)
  1253. {
  1254. // these are not used
  1255. DWORD dwRecipients=0;
  1256. LONG dwResponse=0;
  1257. // Broadcast the message to all hydra sessions (if any)
  1258. fp_WinStaBroadcastSystemMessage( SERVERNAME_CURRENT, TRUE, 0,
  1259. 1 /*timeout in seconds*/ , BSF_NOHANG,
  1260. &dwRecipients,
  1261. WM_WININICHANGE, 0L,
  1262. (LPARAM)szUserEnv,
  1263. &dwResponse );
  1264. //Close the handle to Winsta
  1265. FreeLibrary (hwinStaLib);
  1266. }
  1267. }
  1268. Exit:
  1269. HourGlass (FALSE);
  1270. }
  1271. void
  1272. EVCleanUp(
  1273. IN HWND hDlg
  1274. )
  1275. /*++
  1276. Routine Description:
  1277. Frees memory allocated for environment variables
  1278. Arguments:
  1279. hDlg -
  1280. Supplies window handle
  1281. Return Value:
  1282. None.
  1283. --*/
  1284. {
  1285. int i, n;
  1286. HWND hwndTemp;
  1287. ENVARS *penvar;
  1288. LV_ITEM item;
  1289. //
  1290. // Free alloc'd strings and memory for UserEnvVars list box items
  1291. //
  1292. hwndTemp = GetDlgItem (hDlg, IDC_ENVVAR_SYS_LB_USERVARS);
  1293. n = (int)SendMessage (hwndTemp, LVM_GETITEMCOUNT, 0, 0L);
  1294. item.mask = LVIF_PARAM;
  1295. item.iSubItem = 0;
  1296. for (i = 0; i < n; i++) {
  1297. item.iItem = i;
  1298. if (SendMessage (hwndTemp, LVM_GETITEM, 0, (LPARAM) &item)) {
  1299. penvar = (ENVARS *) item.lParam;
  1300. } else {
  1301. penvar = NULL;
  1302. }
  1303. if (penvar) {
  1304. MemFree (penvar->szValueName);
  1305. MemFree (penvar->szValue);
  1306. MemFree (penvar->szExpValue);
  1307. MemFree ((LPVOID) penvar);
  1308. }
  1309. }
  1310. //
  1311. // Free alloc'd strings and memory for SysEnvVars list box items
  1312. //
  1313. hwndTemp = GetDlgItem (hDlg, IDC_ENVVAR_SYS_LB_SYSVARS);
  1314. n = (int)SendMessage (hwndTemp, LVM_GETITEMCOUNT, 0, 0L);
  1315. for (i = 0; i < n; i++) {
  1316. item.iItem = i;
  1317. if (SendMessage (hwndTemp, LVM_GETITEM, 0, (LPARAM) &item)) {
  1318. penvar = (ENVARS *) item.lParam;
  1319. } else {
  1320. penvar = NULL;
  1321. }
  1322. if (penvar) {
  1323. MemFree (penvar->szValueName);
  1324. MemFree (penvar->szValue);
  1325. MemFree (penvar->szExpValue);
  1326. MemFree ((LPVOID) penvar);
  1327. }
  1328. }
  1329. }
  1330. BOOL
  1331. ExpandSystemVar(
  1332. IN LPCTSTR pszSrc,
  1333. OUT LPTSTR pszDst,
  1334. IN DWORD cchDst
  1335. )
  1336. /*++
  1337. Routine Description:
  1338. Private version of ExpandEnvironmentStrings() which only expands
  1339. references to the variables "SystemRoot" and "SystemDrive".
  1340. This behavior is intended to match the way SMSS expands system
  1341. environment variables.
  1342. Arguments:
  1343. pszSrc -
  1344. Supplies the system variable value to be expanded.
  1345. pszDst -
  1346. Returns the expanded system variable value.
  1347. cchDst -
  1348. Supplies the size, in characters, of the buffer pointed to
  1349. by pszDst
  1350. Return Value:
  1351. TRUE if there was room in the supplied buffer for the entire
  1352. expanded string.
  1353. FALSE if there was insufficient space in the supplied buffer
  1354. for the entire expanded string.
  1355. --*/
  1356. {
  1357. TCHAR ch;
  1358. LPTSTR p;
  1359. TCHAR szVar[BUFZ];
  1360. DWORD cch;
  1361. do {
  1362. ch = *pszSrc++;
  1363. if (ch != TEXT('%') ) {
  1364. // no space left, truncate string and return false
  1365. if (--cchDst == 0) {
  1366. *pszDst = TEXT('\0');
  1367. return FALSE;
  1368. }
  1369. *pszDst++ = ch;
  1370. } else {
  1371. /*
  1372. * Expand variable
  1373. */
  1374. // look for the next '%'
  1375. p = szVar;
  1376. while( *pszSrc != TEXT('\0') && *pszSrc != TEXT('%') )
  1377. *p++ = *pszSrc++;
  1378. *p = TEXT('\0');
  1379. if (*pszSrc == TEXT('\0')) {
  1380. // end of string, first '%' must be literal
  1381. cch = lstrlen(szVar) + 1;
  1382. // no more space, return false
  1383. if (cch + 1 > cchDst) {
  1384. *pszDst++ = TEXT('\0');
  1385. return FALSE;
  1386. }
  1387. *pszDst++ = TEXT('%');
  1388. CopyMemory( pszDst, szVar, cch * sizeof(TCHAR));
  1389. return TRUE;
  1390. } else {
  1391. // we found the ending '%' sign, expand that string
  1392. //
  1393. // We're expanding a SYSTEM variable, so only expand
  1394. // references to SystemRoot and SystemDrive.
  1395. //
  1396. if ((!lstrcmpi(szVar, SYSTEMROOT)) || (!lstrcmpi(szVar, SYSTEMDRIVE))) {
  1397. cch = GetEnvironmentVariable(szVar, pszDst, cchDst);
  1398. } /* if */
  1399. else {
  1400. cch = 0;
  1401. } /* else */
  1402. if (cch == 0 || cch >= cchDst) {
  1403. //String didn't expand, copy it as a literal
  1404. cch = lstrlen(szVar);
  1405. // no space left, trunc string and return FALSE
  1406. if (cch + 2 + 1 > cchDst ) {
  1407. *pszDst = TEXT('\0');
  1408. return FALSE;
  1409. }
  1410. *pszDst++ = TEXT('%');
  1411. CopyMemory(pszDst, szVar, cch * sizeof(TCHAR));
  1412. pszDst += cch;
  1413. *pszDst++ = TEXT('%');
  1414. // cchDst -= two %'s and the string
  1415. cchDst -= (2 + cch);
  1416. } else {
  1417. // string was expanded in place, bump pointer past its end
  1418. pszDst += cch;
  1419. cchDst -= cch;
  1420. }
  1421. // continue with next char after ending '%'
  1422. pszSrc++;
  1423. }
  1424. }
  1425. } while( ch != TEXT('\0') );
  1426. return TRUE;
  1427. }