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.

918 lines
23 KiB

  1. //*************************************************************
  2. // File name: PROFILE.C
  3. //
  4. // Description: Profile control panel applet
  5. //
  6. //
  7. // Microsoft Confidential
  8. // Copyright (c) Microsoft Corporation 1992-1994
  9. // All rights reserved
  10. //
  11. //*************************************************************
  12. #include <windows.h>
  13. #include <cpl.h>
  14. #include "profile.h"
  15. //
  16. // Global Variables
  17. //
  18. HINSTANCE hInstance;
  19. LPTSTR glpList;
  20. TCHAR szEnvDomainName[] = TEXT("USERDOMAIN");
  21. TCHAR szEnvUserName[] = TEXT("USERNAME");
  22. TCHAR szEnvComputerName[] = TEXT("COMPUTERNAME");
  23. TCHAR szProfileRegInfo[] = TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon");
  24. TCHAR szProfileType[] = TEXT("ProfileType");
  25. TCHAR szProfilePath[] = TEXT("ProfilePath");
  26. TCHAR szSaveList[] = TEXT("SaveList");
  27. TCHAR szDontSaveList[] = TEXT("DontSaveList");
  28. TCHAR szSaveOnUnlisted[] = TEXT("SaveOnUnlisted");
  29. TCHAR szComma[] = TEXT(",");
  30. TCHAR szOne[] = TEXT("1");
  31. TCHAR szZero[] = TEXT("0");
  32. TCHAR szShellHelp[] = TEXT("ShellHelp");
  33. TCHAR szHelpFileName[] = TEXT("profile.hlp");
  34. UINT uiShellHelp;
  35. BOOL bUserMadeAChange;
  36. //*************************************************************
  37. //
  38. // RunApplet()
  39. //
  40. // Purpose: Called when the user runs the Profile Applet
  41. //
  42. // Parameters: HWND hwnd - Window handle
  43. //
  44. //
  45. // Return: void
  46. //
  47. //*************************************************************
  48. void RunApplet(HWND hwnd)
  49. {
  50. DialogBox(hInstance, MAKEINTRESOURCE(IDD_PROFILE), hwnd,
  51. ProfileDlgProc);
  52. }
  53. //*************************************************************
  54. //
  55. // ProfileDlgProc()
  56. //
  57. // Purpose: Dialog box procedure
  58. //
  59. // Parameters: HWND hDlg - Window handle of dialog box
  60. // UINT message - Window message
  61. // WPARAM wParam - WORD parameter
  62. // LPARAM lParam - LONG parameter
  63. //
  64. //
  65. // Return: (BOOL) TRUE if message was processed
  66. // FALSE if not
  67. //
  68. //*************************************************************
  69. LRESULT CALLBACK ProfileDlgProc(HWND hDlg, UINT message,
  70. WPARAM wParam, LPARAM lParam)
  71. {
  72. switch (message)
  73. {
  74. case WM_INITDIALOG:
  75. return (InitializeDialog(hDlg));
  76. case WM_COMMAND:
  77. switch (LOWORD(wParam)) {
  78. case IDD_DONTSAVECHANGE:
  79. case IDD_SAVECHANGE:
  80. {
  81. WORD wListBoxID, wIndex;
  82. BOOL bFound;
  83. //
  84. // Determine which "change" button the user pressed.
  85. //
  86. if (LOWORD(wParam) == IDD_DONTSAVECHANGE) {
  87. wListBoxID = IDD_DONTSAVELIST;
  88. } else {
  89. wListBoxID = IDD_SAVELIST;
  90. }
  91. //
  92. // Create a list of names to pass to the edit dialog box.
  93. // NamesDlgProc will free this memory for us.
  94. //
  95. glpList = CreateList (hDlg, wListBoxID, NULL, &bFound);
  96. if (!glpList) {
  97. KdPrint(("Received a null pointer from CreateList"));
  98. break;
  99. }
  100. //
  101. // Find index of highlighted name so it is highlighted
  102. // in the change dialog box also.
  103. //
  104. wIndex = (WORD) SendDlgItemMessage (hDlg, wListBoxID,
  105. LB_GETCURSEL, 0, 0);
  106. if (wIndex == (WORD)LB_ERR) {
  107. wIndex = 0;
  108. }
  109. //
  110. // Display the Computer Names dialog box.
  111. //
  112. if (DialogBoxParam (hInstance,
  113. MAKEINTRESOURCE(IDD_COMPUTERNAMES),
  114. hDlg, (DLGPROC)NamesDlgProc, wIndex)) {
  115. //
  116. // User pressed OK button, so update the list box.
  117. //
  118. ParseAndAddComputerNames(hDlg, wListBoxID, glpList);
  119. //
  120. // Free the memory allocated by CreateList inside of
  121. // NamesDlgProc
  122. //
  123. GlobalFree (glpList);
  124. //
  125. // Update the global state.
  126. //
  127. bUserMadeAChange = TRUE;
  128. }
  129. }
  130. break;
  131. case IDD_SAVELIST:
  132. case IDD_DONTSAVELIST:
  133. {
  134. WORD wButtonID;
  135. //
  136. // We are only interested in double click messages.
  137. //
  138. if (HIWORD (wParam) != LBN_DBLCLK) {
  139. break;
  140. }
  141. //
  142. // Determine which listbox was double clicked.
  143. //
  144. if (LOWORD(wParam) == IDD_SAVELIST) {
  145. wButtonID = IDD_SAVECHANGE;
  146. } else {
  147. wButtonID = IDD_DONTSAVECHANGE;
  148. }
  149. //
  150. // Post a message to post up the change dialog box.
  151. //
  152. PostMessage (hDlg, WM_COMMAND, MAKELONG (wButtonID,0), 0);
  153. }
  154. break;
  155. case IDD_DEFAULTSAVE:
  156. case IDD_DEFAULTDONTSAVE:
  157. bUserMadeAChange = TRUE;
  158. break;
  159. case IDOK:
  160. //
  161. // Notify winhelp that we are leaving, save settings
  162. // and leave if appropriate.
  163. //
  164. WinHelp (hDlg, szHelpFileName, HELP_QUIT, 0);
  165. //
  166. // If the user didn't make any changes, then
  167. // return FALSE through EndDialog.
  168. //
  169. if (!bUserMadeAChange) {
  170. EndDialog(hDlg, FALSE);
  171. } else {
  172. if (SaveSettings(hDlg)) {
  173. EndDialog(hDlg, TRUE);
  174. }
  175. }
  176. return TRUE;
  177. case IDCANCEL:
  178. //
  179. // Notify winhelp that we are leaving and exit
  180. //
  181. WinHelp (hDlg, szHelpFileName, HELP_QUIT, 0);
  182. EndDialog(hDlg, FALSE);
  183. return TRUE;
  184. case IDD_HELP:
  185. //
  186. // User requested help.
  187. //
  188. WinHelp (hDlg, szHelpFileName, HELP_CONTENTS, 0);
  189. break;
  190. default:
  191. break;
  192. }
  193. break;
  194. default:
  195. //
  196. // User requested help via the F1 key.
  197. //
  198. if (message == uiShellHelp) {
  199. WinHelp (hDlg, szHelpFileName, HELP_CONTENTS, 0);
  200. }
  201. break;
  202. }
  203. return FALSE;
  204. }
  205. //*************************************************************
  206. //
  207. // InitializeDialog()
  208. //
  209. // Purpose: Initializes the profile dialog box
  210. //
  211. // Parameters: HWND hDlg - Dialog box window handle
  212. //
  213. //
  214. // Return: TRUE - successfully initialized
  215. // FALSE - failed to initialize
  216. //
  217. //*************************************************************
  218. BOOL InitializeDialog (HWND hDlg)
  219. {
  220. TCHAR szDomainName [MAX_DOMAIN_NAME];
  221. TCHAR szUserName [MAX_USER_NAME];
  222. TCHAR szTempBuffer [MAX_TEMP_BUFFER];
  223. TCHAR szUnknown [UNKNOWN_LEN];
  224. TCHAR szFormatBuffer [MAX_TEMP_BUFFER];
  225. LONG lResult;
  226. HKEY hKey;
  227. DWORD dwDisp, dwType, dwMaxBufferSize;
  228. //
  229. // Initialize the save changes global.
  230. //
  231. bUserMadeAChange = FALSE;
  232. //
  233. // Load the "unknown" string from the resources
  234. //
  235. if (!LoadString (hInstance, IDS_UNKNOWN, szUnknown, UNKNOWN_LEN)) {
  236. KdPrint(("Failed to load 'unknown' string."));
  237. return FALSE;
  238. }
  239. //
  240. // Retrieve the domain name
  241. //
  242. if (!GetEnvironmentVariable (szEnvDomainName, szDomainName,
  243. MAX_DOMAIN_NAME)){
  244. //
  245. // Failed to get the domain name. Initalize to Unknown.
  246. //
  247. lstrcpy (szDomainName, szUnknown);
  248. }
  249. //
  250. // Retrieve the user name
  251. //
  252. if (!GetEnvironmentVariable (szEnvUserName, szUserName,
  253. MAX_USER_NAME)){
  254. //
  255. // Failed to get the user name. Initalize to Unknown.
  256. //
  257. lstrcpy (szUserName, szUnknown);
  258. }
  259. //
  260. // Load the format string from the resources
  261. //
  262. if (!LoadString (hInstance, IDS_FORMAT, szFormatBuffer, MAX_TEMP_BUFFER)) {
  263. KdPrint(("Failed to load format string."));
  264. return FALSE;
  265. }
  266. //
  267. // Build the name field, and add it to the dialog box
  268. //
  269. wsprintf (szTempBuffer, szFormatBuffer, szDomainName, szUserName);
  270. SetDlgItemText (hDlg, IDD_USERNAME, szTempBuffer);
  271. //
  272. // Retrieve the local computer name
  273. //
  274. if (!GetEnvironmentVariable (szEnvComputerName, szTempBuffer,
  275. MAX_TEMP_BUFFER)){
  276. //
  277. // Failed to get the computer name. Initalize to Unknown.
  278. //
  279. lstrcpy (szTempBuffer, szUnknown);
  280. }
  281. SetDlgItemText (hDlg, IDD_COMPUTERNAME, szTempBuffer);
  282. //
  283. // Now query the registry
  284. //
  285. // First we need a key
  286. //
  287. lResult = RegCreateKeyEx (HKEY_CURRENT_USER, szProfileRegInfo, 0, NULL,
  288. REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS,
  289. NULL, &hKey, &dwDisp);
  290. if (lResult != ERROR_SUCCESS) {
  291. KdPrint(("Failed to open registry key."));
  292. return FALSE;
  293. }
  294. //
  295. // Query and set the profile path
  296. //
  297. dwMaxBufferSize = MAX_TEMP_BUFFER;
  298. szTempBuffer[0] = TEXT('\0');
  299. RegQueryValueEx (hKey, szProfilePath , NULL, &dwType,
  300. (LPBYTE) szTempBuffer, &dwMaxBufferSize);
  301. if (szTempBuffer[0] == TEXT('\0')) {
  302. lstrcpy (szTempBuffer, szUnknown);
  303. }
  304. SetDlgItemText (hDlg, IDD_PATH, szTempBuffer);
  305. //
  306. // Query and set the computer names to save the profile from
  307. //
  308. dwMaxBufferSize = MAX_TEMP_BUFFER;
  309. szTempBuffer[0] = TEXT('\0');
  310. RegQueryValueEx (hKey, szSaveList , NULL, &dwType,
  311. (LPBYTE) szTempBuffer, &dwMaxBufferSize);
  312. if (szTempBuffer[0] != TEXT('\0')) {
  313. ParseAndAddComputerNames(hDlg, IDD_SAVELIST, szTempBuffer);
  314. }
  315. //
  316. // Query and set the computer names to not save the profile from
  317. //
  318. dwMaxBufferSize = MAX_TEMP_BUFFER;
  319. szTempBuffer[0] = TEXT('\0');
  320. RegQueryValueEx (hKey, szDontSaveList , NULL, &dwType,
  321. (LPBYTE) szTempBuffer, &dwMaxBufferSize);
  322. if (szTempBuffer[0] != TEXT('\0')) {
  323. ParseAndAddComputerNames(hDlg, IDD_DONTSAVELIST, szTempBuffer);
  324. }
  325. //
  326. // Query and set the default choice
  327. //
  328. dwMaxBufferSize = MAX_TEMP_BUFFER;
  329. szTempBuffer[0] = TEXT('\0');
  330. RegQueryValueEx (hKey, szSaveOnUnlisted , NULL, &dwType,
  331. (LPBYTE) szTempBuffer, &dwMaxBufferSize);
  332. //
  333. // If the buffer still has NULL or one in it, then the default
  334. // case is to always save the profile.
  335. //
  336. if ( (szTempBuffer[0] == TEXT('\0')) || (szTempBuffer[0] == TEXT('1')) ) {
  337. CheckDlgButton (hDlg, IDD_DEFAULTSAVE, 1);
  338. } else {
  339. CheckDlgButton (hDlg, IDD_DEFAULTDONTSAVE, 1);
  340. }
  341. //
  342. // Close the registry key
  343. //
  344. RegCloseKey (hKey);
  345. //
  346. // Return success
  347. //
  348. return TRUE;
  349. }
  350. //*************************************************************
  351. //
  352. // ParseAndAddComputerNames()
  353. //
  354. // Purpose: Parse the list of computer names, and add them
  355. // to the list box.
  356. //
  357. // Parameters: HWND hDlg - Window handle of dialog box
  358. // WORD idListBox - ListBox id
  359. // LPTSTR szNames - List of names separated by commas
  360. //
  361. //
  362. // Return: void
  363. //
  364. //*************************************************************
  365. void ParseAndAddComputerNames(HWND hDlg, WORD idListBox, LPTSTR szNames)
  366. {
  367. LPTSTR lpHead, lpTail;
  368. TCHAR chLetter;
  369. //
  370. // Turn off redraw, and empty the listbox.
  371. //
  372. SendDlgItemMessage (hDlg, idListBox, WM_SETREDRAW, 0, 0);
  373. SendDlgItemMessage (hDlg, idListBox, LB_RESETCONTENT, 0, 0);
  374. lpHead = lpTail = szNames;
  375. while (*lpHead) {
  376. //
  377. // Search for the comma, or the end of the list.
  378. //
  379. while (*lpHead != TEXT(',') && *lpHead) {
  380. lpHead++;
  381. }
  382. //
  383. // If the head pointer is not pointing at the
  384. // tail pointer, then we have something to add
  385. // to the list.
  386. //
  387. if (lpHead != lpTail) {
  388. //
  389. // Store the letter pointed to by lpHead in a temporary
  390. // variable (chLetter). Replace that letter with NULL,
  391. // and add the string to the list box starting from
  392. // lpTail. After the string is added, replace the letter
  393. // we used.
  394. //
  395. chLetter = *lpHead;
  396. *lpHead = TEXT('\0');
  397. SendDlgItemMessage (hDlg, idListBox, LB_ADDSTRING, 0,
  398. (LPARAM) lpTail);
  399. *lpHead = chLetter;
  400. }
  401. //
  402. // If we are not at the end of the list, then move the
  403. // head pointer forward one character.
  404. //
  405. if (*lpHead) {
  406. lpHead++;
  407. }
  408. //
  409. // Move the tail pointer to the head pointer
  410. //
  411. lpTail = lpHead;
  412. }
  413. //
  414. // Turn redraw back on, and display the results.
  415. //
  416. SendDlgItemMessage (hDlg, idListBox, WM_SETREDRAW, 1, 0);
  417. InvalidateRect (GetDlgItem(hDlg, idListBox), NULL, TRUE);
  418. }
  419. //*************************************************************
  420. //
  421. // SaveSettings()
  422. //
  423. // Purpose: Saves the current selections to the registry
  424. //
  425. // Parameters: HWND hDlg - Handle to dialog box
  426. //
  427. //
  428. // Return: BOOL - TRUE ok to exit dialog box
  429. // FALSE do not exit dialog box
  430. //
  431. //*************************************************************
  432. BOOL SaveSettings (HWND hDlg)
  433. {
  434. LONG lResult;
  435. HKEY hKey = 0;
  436. DWORD dwDisp;
  437. TCHAR szProfile [PROFILE_NAME_LEN];
  438. TCHAR szTempBuffer [MAX_TEMP_BUFFER];
  439. TCHAR szTempBuffer2 [MAX_TEMP_BUFFER];
  440. TCHAR szComputerName [MAX_COMPUTER_NAME];
  441. TCHAR szSpecificErrorMsg [MAX_ERROR_MSG];
  442. LPTSTR lpSaveList, lpDoNotSaveList;
  443. WORD wError, wMBStyle;
  444. INT iMBResult;
  445. BOOL bFound = FALSE;
  446. BOOL bSaveOnUnlisted;
  447. //
  448. // Check for computer names that exist in both listboxs.
  449. //
  450. if (!CompareLists (hDlg, IDD_SAVELIST, IDD_DONTSAVELIST)) {
  451. KdPrint(("One or more computer names exist in both lists."));
  452. wError = IDS_DUPLICATENAME;
  453. goto AbortSave;
  454. }
  455. //
  456. // Retreive the computer name from the dialog box
  457. //
  458. GetDlgItemText (hDlg, IDD_COMPUTERNAME, szComputerName, MAX_COMPUTER_NAME);
  459. //
  460. // Check the default flag
  461. //
  462. bSaveOnUnlisted = IsDlgButtonChecked (hDlg, IDD_DEFAULTSAVE);
  463. //
  464. // Create the list of computer names on which the profile will not be saved.
  465. //
  466. lpDoNotSaveList = CreateList (hDlg, IDD_DONTSAVELIST, szComputerName,
  467. &bFound);
  468. //
  469. // Check for NULL pointer
  470. //
  471. if (!lpDoNotSaveList) {
  472. KdPrint(("Don't save list: Received a null pointer from CreateList"));
  473. wError = IDS_UNABLETOSAVE;
  474. goto AbortSave;
  475. }
  476. //
  477. // Check to see if the computer was in the list. If so, this is
  478. // an error case.
  479. //
  480. if (bFound) {
  481. KdPrint(("This computer is in the Do Not Save Profile List"));
  482. wError = IDS_NAMEINDONTLIST;
  483. goto AbortSave;
  484. }
  485. //
  486. // Create the list of computer names on which the profile will be saved.
  487. //
  488. lpSaveList = CreateList (hDlg, IDD_SAVELIST, szComputerName, &bFound);
  489. //
  490. // Check for NULL pointer
  491. //
  492. if (!lpSaveList) {
  493. KdPrint(("Do save list: Received a null pointer from CreateList"));
  494. wError = IDS_UNABLETOSAVE;
  495. goto AbortSave;
  496. }
  497. //
  498. // Check to see if the computer was in the list. If not and the
  499. // user has "Do Not save on unlisted computer" turned on, then this
  500. // is an error case.
  501. //
  502. if (!bFound && !bSaveOnUnlisted) {
  503. KdPrint(("This computer is not in the Save Profile List and Do Not save on Unlisted computer is turned on"));
  504. wError = IDS_NONAMEANDDONOTSAVE;
  505. goto AbortSave;
  506. }
  507. //
  508. // Open the registry key
  509. //
  510. lResult = RegCreateKeyEx (HKEY_CURRENT_USER, szProfileRegInfo, 0, NULL,
  511. REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS,
  512. NULL, &hKey, &dwDisp);
  513. if (lResult != ERROR_SUCCESS) {
  514. KdPrint(("Failed to open registry key."));
  515. wError = IDS_UNABLETOSAVE;
  516. goto AbortSave;
  517. }
  518. //
  519. // Write the Do Not Save list to the registry
  520. //
  521. RegSetValueEx (hKey, szDontSaveList, 0, REG_SZ,
  522. (LPBYTE) lpDoNotSaveList,
  523. sizeof (TCHAR) * lstrlen (lpDoNotSaveList) + 1);
  524. //
  525. // Write the Save list to the registry
  526. //
  527. RegSetValueEx (hKey, szSaveList, 0, REG_SZ,
  528. (LPBYTE) lpSaveList,
  529. sizeof (TCHAR) * lstrlen (lpSaveList) + 1);
  530. //
  531. // Write the default setting to the registry
  532. //
  533. if (bSaveOnUnlisted) {
  534. lstrcpy (szTempBuffer, szOne);
  535. } else {
  536. lstrcpy (szTempBuffer, szZero);
  537. }
  538. RegSetValueEx (hKey, szSaveOnUnlisted, 0, REG_SZ,
  539. (LPBYTE) szTempBuffer,
  540. sizeof (TCHAR) * lstrlen (szTempBuffer) + 1);
  541. //
  542. // Close the registry key
  543. //
  544. RegCloseKey (hKey);
  545. //
  546. // Success. Now we need to tell the user to log off all other computers,
  547. // and then log off of this one.
  548. //
  549. wError = IDS_LOGOFFNOTICE;
  550. AbortSave:
  551. //
  552. // Free up the memory allocated by CreateList
  553. //
  554. GlobalFree (lpSaveList);
  555. GlobalFree (lpDoNotSaveList);
  556. //
  557. // Load the error string and message box title
  558. //
  559. if (LoadString (hInstance, IDS_NAME, szProfile, PROFILE_NAME_LEN) &&
  560. LoadString (hInstance, IDS_BASEERRORMSG, szTempBuffer, MAX_TEMP_BUFFER) &&
  561. LoadString (hInstance, wError, szSpecificErrorMsg, MAX_ERROR_MSG)) {
  562. //
  563. // If it is a user error, then we want to prompt with Yes/No buttons
  564. // otherwise offer an OK button.
  565. //
  566. if (wError == IDS_UNABLETOSAVE) {
  567. wMBStyle = MB_OK | MB_ICONEXCLAMATION;
  568. lstrcpy (szTempBuffer2, szSpecificErrorMsg);
  569. } else if (wError == IDS_LOGOFFNOTICE) {
  570. wMBStyle = MB_OK | MB_ICONASTERISK;
  571. lstrcpy (szTempBuffer2, szSpecificErrorMsg);
  572. } else {
  573. wMBStyle = MB_YESNO | MB_DEFBUTTON2 | MB_ICONEXCLAMATION;
  574. wsprintf (szTempBuffer2, szTempBuffer, szSpecificErrorMsg);
  575. }
  576. //
  577. // Display the message
  578. //
  579. iMBResult = MessageBox (hDlg, szTempBuffer2, szProfile,
  580. wMBStyle);
  581. //
  582. // If the user chooses NO, the we don't want to exit the
  583. // dialog box.
  584. //
  585. if (iMBResult == IDNO) {
  586. return FALSE;
  587. } else {
  588. return TRUE;
  589. }
  590. }
  591. // If out of memory, assume user hit OK
  592. return TRUE;
  593. }
  594. //*************************************************************
  595. //
  596. // CreateList()
  597. //
  598. // Purpose: Creates a list of computer names from the
  599. // given listbox. Each name is seperated by
  600. // a comma. Also, if the given computer name
  601. // is found in the list, the bool variable is
  602. // set.
  603. //
  604. // Parameters: HWND hDlg - Window handle
  605. // WORD idListBox - ID of listbox
  606. // LPTSTR szComputerName - Name of computer to watch for
  607. // LPBOOL lpFound - Flag to set if found
  608. //
  609. //
  610. // Return: LPTSTR - Pointer to buffer if successful
  611. // NULL if not
  612. //
  613. //*************************************************************
  614. LPTSTR CreateList (HWND hDlg, WORD idListBox, LPTSTR szComputerName,
  615. LPBOOL lpFound)
  616. {
  617. LPTSTR lpList;
  618. WORD wCount, wIndex;
  619. TCHAR szName[MAX_COMPUTER_NAME];
  620. //
  621. // Initialize the flag
  622. //
  623. *lpFound = FALSE;
  624. //
  625. // Get the number of items in the listbox
  626. //
  627. wCount = (WORD) SendDlgItemMessage (hDlg, idListBox, LB_GETCOUNT, 0, 0);
  628. //
  629. // Allocate a buffer to use
  630. //
  631. lpList = GlobalAlloc (GPTR, (wCount ? wCount : 1) * (MAX_COMPUTER_NAME * sizeof(TCHAR)));
  632. if (!lpList) {
  633. KdPrint(("CreateList: Received a null pointer from GlobalAlloc"));
  634. return NULL;
  635. }
  636. //
  637. // Null terminate
  638. //
  639. lpList[0] = TEXT('\0');
  640. for (wIndex = 0; wIndex < wCount; wIndex++) {
  641. //
  642. // Retreive and item from the list
  643. //
  644. SendDlgItemMessage (hDlg, idListBox, LB_GETTEXT, wIndex,
  645. (LPARAM) szName);
  646. //
  647. // Check to see if we found the requested name.
  648. //
  649. if (!lstrcmpi (szComputerName, szName)) {
  650. *lpFound = TRUE;
  651. }
  652. //
  653. // Add name to the end of the buffer
  654. //
  655. lstrcat (lpList, szName);
  656. //
  657. // If we are not adding the last item, then insert a comma
  658. //
  659. if (wIndex != (wCount - 1)) {
  660. lstrcat (lpList, szComma);
  661. }
  662. }
  663. //
  664. // Success
  665. //
  666. return (lpList);
  667. }
  668. //*************************************************************
  669. //
  670. // CompareLists()
  671. //
  672. // Purpose: Compares one listbox to the other listbox
  673. // looking for names that appear in both.
  674. //
  675. // Parameters: HWND hDlg - Window handle of dialog box
  676. // WORD idList1 - ID of first listbox
  677. // WORD idList2 - ID of second listbox
  678. //
  679. //
  680. // Return: BOOL - TRUE if not duplicates exist
  681. // FALSE if a duplicate does exist
  682. //
  683. //*************************************************************
  684. BOOL CompareLists (HWND hDlg, WORD idList1, WORD idList2)
  685. {
  686. WORD wList1Count, wIndex;
  687. TCHAR szName[MAX_COMPUTER_NAME];
  688. //
  689. // Get the number of items in the first listbox
  690. //
  691. wList1Count = (WORD)SendDlgItemMessage (hDlg, idList1, LB_GETCOUNT, 0, 0);
  692. if (wList1Count == LB_ERR) {
  693. return TRUE;
  694. }
  695. //
  696. // Loop through listbox 1 comparing with listbox 2
  697. //
  698. for (wIndex=0; wIndex < wList1Count; wIndex++) {
  699. SendDlgItemMessage (hDlg, idList1, LB_GETTEXT, wIndex, (LPARAM)szName);
  700. if (SendDlgItemMessage (hDlg, idList2, LB_FINDSTRINGEXACT,
  701. 0, (LPARAM)szName) != LB_ERR) {
  702. return FALSE;
  703. }
  704. }
  705. return TRUE;
  706. }