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.

1322 lines
40 KiB

  1. /*
  2. ***************************************************************
  3. *
  4. * This file contains the routines to read and write to the reg database
  5. *
  6. * Copyright 1993, Microsoft Corporation
  7. *
  8. * History:
  9. *
  10. * 07/94 - VijR (Created)
  11. *
  12. ***************************************************************
  13. */
  14. #include <windows.h>
  15. #include <mmsystem.h>
  16. #include <string.h>
  17. #include <cpl.h>
  18. #include <shellapi.h>
  19. #include <ole2.h>
  20. #define NOSTATUSBAR
  21. #include <commctrl.h>
  22. #include <prsht.h>
  23. #include <regstr.h>
  24. #include <shlwapi.h>
  25. #include <shlwapip.h>
  26. #include "mmcpl.h"
  27. #include "draw.h"
  28. #include "medhelp.h"
  29. /*
  30. ***************************************************************
  31. * Definitions
  32. ***************************************************************
  33. */
  34. #define KEYLEN 8 //length of artificially created key
  35. #define MAXSCHEME 37 //max length of scheme name
  36. /*
  37. ***************************************************************
  38. * File Globals
  39. ***************************************************************
  40. */
  41. static SZCODE aszDefaultScheme[] = TEXT("Appevents\\schemes");
  42. static SZCODE aszDefaultApp[] = TEXT("Appevents\\schemes\\apps\\.default");
  43. static SZCODE aszApps[] = TEXT("Appevents\\schemes\\apps");
  44. static SZCODE aszLabels[] = TEXT("Appevents\\eventlabels");
  45. static SZCODE aszDisplayLabels[] = TEXT("DispFileName");
  46. static SZCODE aszNames[] = TEXT("Appevents\\schemes\\Names");
  47. static SZCODE aszDefault[] = TEXT(".default");
  48. static SZCODE aszCurrent[] = TEXT(".current");
  49. static SZCODE aszMMTask[] = TEXT("MMTask");
  50. static INTCODE aKeyWordIds[] =
  51. {
  52. ID_SCHEMENAME, IDH_SAVEAS_SCHEMENAME,
  53. 0,0
  54. };
  55. static SZCODE cszSslashS[] = TEXT("%s\\%s");
  56. /*
  57. ***************************************************************
  58. * extern
  59. ***************************************************************
  60. */
  61. extern HWND ghWnd;
  62. extern BOOL gfChanged;
  63. extern BOOL gfNewScheme;
  64. extern BOOL gfDeletingTree;
  65. extern int giScheme;
  66. extern TCHAR gszDefaultApp[];
  67. extern TCHAR gszNullScheme[];
  68. extern TCHAR gszCmdLineApp[];
  69. extern TCHAR gszCmdLineEvent[];
  70. /*
  71. ***************************************************************
  72. * Prototypes
  73. ***************************************************************
  74. */
  75. BOOL PASCAL RemoveScheme (HWND);
  76. BOOL PASCAL RegAddScheme (HWND, LPTSTR);
  77. BOOL PASCAL RegNewScheme (HWND, LPTSTR, LPTSTR, BOOL);
  78. BOOL PASCAL RegSetDefault (LPTSTR);
  79. BOOL PASCAL RegDeleteScheme (HWND, int);
  80. BOOL PASCAL LoadEvents (HWND, HTREEITEM, PMODULE);
  81. BOOL PASCAL LoadModules (HWND, LPTSTR);
  82. BOOL PASCAL ClearModules (HWND, HWND, BOOL);
  83. BOOL PASCAL NewModule (HWND, LPTSTR, LPTSTR, LPTSTR, int);
  84. BOOL PASCAL FindEventLabel (LPTSTR, LPTSTR);
  85. BOOL PASCAL AddScheme (HWND, LPTSTR, LPTSTR, BOOL, int);
  86. void PASCAL GetMediaPath (LPTSTR, size_t);
  87. void PASCAL RemoveMediaPath (LPTSTR, LPTSTR);
  88. void PASCAL AddMediaPath (LPTSTR, LPTSTR);
  89. int ExRegQueryValue (HKEY, LPTSTR, LPBYTE, DWORD *);
  90. //sndfile.c
  91. BOOL PASCAL ShowSoundMapping (HWND, PEVENT);
  92. int StrByteLen (LPTSTR);
  93. //drivers.c
  94. int lstrnicmp (LPTSTR, LPTSTR, size_t);
  95. LPTSTR lstrchr (LPTSTR, TCHAR);
  96. /*
  97. ***************************************************************
  98. ***************************************************************
  99. */
  100. static void AppendRegKeys (
  101. LPTSTR szBuf,
  102. LPCTSTR szLeft,
  103. LPCTSTR szRight)
  104. {
  105. static SZCODE cszSlash[] = TEXT("\\");
  106. lstrcpy (szBuf, szLeft);
  107. lstrcat (szBuf, cszSlash);
  108. lstrcat (szBuf, szRight);
  109. }
  110. /*
  111. ***************************************************************
  112. * SaveSchemeDlg
  113. *
  114. * Description: Dialog handler for save schemes dialog.
  115. * checks if given scheme name exists and if so
  116. * whether it should be overwritten.
  117. * if yes then delete current scheme.
  118. * scheme under a new name, else just add a new scheme
  119. * The user can choose to cancel
  120. *
  121. * Arguments:
  122. * HWND hDlg - window handle of dialog window
  123. * UINT uiMessage - message number
  124. * WPARAM wParam - message-dependent
  125. * LPARAM lParam - message-dependent
  126. *
  127. * Returns: BOOL
  128. * TRUE if message has been processed, else FALSE
  129. *
  130. ***************************************************************************
  131. */
  132. INT_PTR CALLBACK SaveSchemeDlg(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  133. {
  134. TCHAR szBuf[MAXSTR];
  135. TCHAR szTemp[MAXSTR];
  136. TCHAR szMesg[MAXSTR];
  137. int iResult;
  138. int iIndex;
  139. HWND hDlgParent = ghWnd;
  140. switch (uMsg)
  141. {
  142. case WM_INITDIALOG:
  143. szBuf[0] = TEXT('\0');
  144. DPF("IN Init\n");
  145. Edit_LimitText(GetDlgItem(hDlg, ID_SCHEMENAME), MAXSCHEME);
  146. Edit_SetText(GetDlgItem(hDlg, ID_SCHEMENAME), (LPTSTR)lParam);
  147. // dump the text from lparam into the edit control.
  148. break;
  149. case WM_COMMAND:
  150. switch (wParam)
  151. {
  152. case IDOK:
  153. {
  154. LPTSTR pszKey;
  155. Edit_GetText(GetDlgItem(hDlg, ID_SCHEMENAME), szBuf, MAXSTR);
  156. //prevent null-string names
  157. if (lstrlen(szBuf) == 0)
  158. {
  159. LoadString(ghInstance, IDS_INVALIDFILE, szTemp, MAXSTR);
  160. MessageBox(hDlg, szTemp, gszChangeScheme, MB_ICONERROR | MB_OK);
  161. break;
  162. }
  163. iIndex = ComboBox_FindStringExact(GetDlgItem(hDlgParent,
  164. CB_SCHEMES), 0, szBuf);
  165. pszKey = (LPTSTR)ComboBox_GetItemData(GetDlgItem(hDlgParent,CB_SCHEMES), iIndex);
  166. if (iIndex != CB_ERR)
  167. {
  168. if (!lstrcmpi((LPTSTR)pszKey, aszDefault) || !lstrcmpi((LPTSTR)pszKey, gszNullScheme))
  169. {
  170. LoadString(ghInstance, IDS_NOOVERWRITEDEFAULT, szTemp,
  171. MAXSTR);
  172. wsprintf(szMesg, szTemp, (LPTSTR)szBuf);
  173. iResult = MessageBox(hDlg, szMesg, gszChangeScheme,
  174. MB_ICONEXCLAMATION | MB_TASKMODAL | MB_OKCANCEL);
  175. if (iResult == IDOK)
  176. {
  177. break;
  178. }
  179. }
  180. else
  181. {
  182. LoadString(ghInstance, IDS_OVERWRITESCHEME, szTemp,
  183. MAXSTR);
  184. wsprintf(szMesg, szTemp, (LPTSTR)szBuf);
  185. iResult = MessageBox(hDlg, szMesg, gszChangeScheme,
  186. MB_ICONEXCLAMATION | MB_TASKMODAL | MB_YESNOCANCEL);
  187. if (iResult == IDYES)
  188. {
  189. RegDeleteScheme(GetDlgItem(hDlgParent,
  190. CB_SCHEMES), iIndex);
  191. RegAddScheme(hDlgParent, szBuf);
  192. PropSheet_Changed(GetParent(hDlg),hDlg);
  193. }
  194. else
  195. {
  196. if (iResult == IDNO)
  197. break;
  198. if (iResult == IDCANCEL)
  199. {
  200. EndDialog(hDlg, FALSE);
  201. break;
  202. }
  203. }
  204. }
  205. }
  206. else
  207. {
  208. RegAddScheme(hDlgParent, szBuf);
  209. PropSheet_Changed(GetParent(hDlg),hDlg);
  210. }
  211. gfChanged = TRUE;
  212. EndDialog(hDlg, TRUE);
  213. DPF("Done save\n");
  214. break;
  215. }
  216. case IDCANCEL:
  217. EndDialog(hDlg, FALSE);
  218. DPF("Done save\n");
  219. break;
  220. case ID_SCHEMENAME:
  221. if ((HIWORD(lParam) == EN_ERRSPACE) ||
  222. (HIWORD(lParam) == EN_MAXTEXT))
  223. MessageBeep(MB_OK);
  224. else
  225. if (HIWORD(lParam) == EN_CHANGE)
  226. {
  227. GetWindowText(GetDlgItem(hDlg, ID_SCHEMENAME), szBuf,
  228. MAXSTR - 1);
  229. EnableWindow(GetDlgItem(hDlg, IDOK), *szBuf);
  230. }
  231. break;
  232. default:
  233. break;
  234. }
  235. break;
  236. case WM_CONTEXTMENU:
  237. WinHelp((HWND)wParam, NULL, HELP_CONTEXTMENU,
  238. (UINT_PTR)(LPTSTR)aKeyWordIds);
  239. break;
  240. case WM_HELP:
  241. WinHelp(((LPHELPINFO)lParam)->hItemHandle, NULL, HELP_WM_HELP
  242. , (UINT_PTR)(LPTSTR)aKeyWordIds);
  243. break;
  244. }
  245. return FALSE;
  246. }
  247. /*
  248. ***************************************************************
  249. * RegNewScheme
  250. *
  251. * Description:
  252. * Saves the scheme in the reg database. If the fQuery flag is
  253. * set then a messages box is brought up, asking if the schem should
  254. * be saved
  255. *
  256. * Arguments:
  257. * HWND hDlg - Handle to the dialog
  258. * LPTSTR lpszScheme - pointer to scheme name.
  259. * BOOL fQuery - If TRUE and lpszScheme is in reg.db bring up msgbox.
  260. *
  261. * Returns: BOOL
  262. * TRUE if the new scheme is succesfully added or if the user chooses
  263. * not to save
  264. *
  265. ***************************************************************
  266. */
  267. BOOL PASCAL RegNewScheme(HWND hDlg, LPTSTR lpszKey, LPTSTR lpszLabel,
  268. BOOL fQuery)
  269. {
  270. PMODULE npModule;
  271. PEVENT npPtr;
  272. TCHAR szBuf[MAXSTR];
  273. TCHAR szLabel[MAXSTR];
  274. HTREEITEM hti;
  275. TV_ITEM tvi;
  276. HWND hwndTree = GetDlgItem(hDlg, IDC_EVENT_TREE);
  277. if (fQuery)
  278. {
  279. LoadString(ghInstance, IDS_SAVECHANGE, szBuf, MAXSTR);
  280. LoadString(ghInstance, IDS_SAVESCHEME, szLabel, MAXSTR);
  281. if (MessageBox(hDlg, szBuf, szLabel,
  282. MB_ICONEXCLAMATION | MB_TASKMODAL | MB_YESNO) == IDNO)
  283. return TRUE;
  284. }
  285. for (hti = TreeView_GetRoot(hwndTree); hti; hti = TreeView_GetNextSibling(hwndTree, hti))
  286. {
  287. tvi.mask = TVIF_PARAM;
  288. tvi.hItem = hti;
  289. TreeView_GetItem(hwndTree, &tvi);
  290. npModule = (PMODULE)tvi.lParam;
  291. if ((npPtr = npModule->npList) == NULL)
  292. break;
  293. for (; npPtr != NULL; npPtr = npPtr->npNextEvent)
  294. {
  295. HKEY hk = NULL;
  296. DWORD dwType;
  297. static SZCODE cszFmt[] = TEXT("%s\\%s\\%s\\%s");
  298. wsprintf(szBuf, cszFmt, (LPTSTR)aszApps,
  299. (LPTSTR)npModule->pszKey, (LPTSTR)npPtr->pszEvent, lpszKey);
  300. DPF("setting %s to %s\n", (LPTSTR)szBuf, (LPTSTR)npPtr->pszPath);
  301. RemoveMediaPath (szLabel, npPtr->pszPath);
  302. dwType = (lstrchr (szLabel, TEXT('%'))) ? REG_EXPAND_SZ : REG_SZ;
  303. // Set file name
  304. if ((RegCreateKey (HKEY_CURRENT_USER, szBuf, &hk) == ERROR_SUCCESS) && hk)
  305. {
  306. if (RegSetValueEx (hk, NULL, 0, dwType, (LPBYTE)szLabel,
  307. (1+lstrlen(szLabel))*sizeof(TCHAR)) != ERROR_SUCCESS)
  308. {
  309. DPF("fail %s for %s,\n", (LPTSTR)szLabel, (LPTSTR)szBuf);
  310. }
  311. RegCloseKey (hk);
  312. }
  313. }
  314. }
  315. return TRUE;
  316. }
  317. /*
  318. ***************************************************************
  319. * RegAddScheme
  320. *
  321. * Description:
  322. * Adds the given scheme to the reg database by creating a key using
  323. * upto the first KEYLEN letters of the schemename. If the strlen
  324. * id less than KEYLEN, '0's are added till the key is KEYLEN long.
  325. * This key is checked for uniqueness and then RegNewScheme is called.
  326. *
  327. * Arguments:
  328. * HWND hDlg - Handle to the dialog
  329. * LPTSTR lpszScheme - pointer to scheme name.
  330. *
  331. * Returns: BOOL
  332. * TRUE if message successful, else FALSE
  333. *
  334. ***************************************************************
  335. */
  336. BOOL PASCAL RegAddScheme(HWND hDlg, LPTSTR lpszScheme)
  337. {
  338. TCHAR szKey[32];
  339. LPTSTR pszKey;
  340. int iIndex;
  341. int iLen;
  342. int iStrLen;
  343. HWND hWndC;
  344. HKEY hkScheme;
  345. HKEY hkBase;
  346. hWndC = GetDlgItem(hDlg, CB_SCHEMES);
  347. iLen = StrByteLen(lpszScheme);
  348. iStrLen = lstrlen(lpszScheme);
  349. if (iStrLen < KEYLEN)
  350. {
  351. lstrcpy(szKey, lpszScheme);
  352. iIndex = iLen;
  353. szKey[iIndex] = TEXT('0');
  354. szKey[iIndex+sizeof(TCHAR)] = TEXT('\0');
  355. }
  356. else
  357. {
  358. lstrcpyn(szKey, lpszScheme, KEYLEN-1);
  359. iIndex = StrByteLen(szKey);
  360. szKey[iIndex] = TEXT('0');
  361. szKey[iIndex+sizeof(TCHAR)] = TEXT('\0');
  362. }
  363. if (RegOpenKey(HKEY_CURRENT_USER, aszNames, &hkBase) != ERROR_SUCCESS)
  364. {
  365. DPF("Failed to open asznames\n");
  366. return FALSE;
  367. }
  368. gfNewScheme = FALSE;
  369. while (RegOpenKey(hkBase, szKey, &hkScheme) == ERROR_SUCCESS)
  370. {
  371. szKey[iIndex]++;
  372. RegCloseKey(hkScheme);
  373. }
  374. if (RegSetValue(hkBase, szKey, REG_SZ, lpszScheme, 0) != ERROR_SUCCESS)
  375. {
  376. static SZCODE cszFmt[] = TEXT("%lx");
  377. wsprintf((LPTSTR)szKey, cszFmt, GetCurrentTime()); //High chance of unique ness. This is to deal with some
  378. //DBCS problems.
  379. if (RegSetValue(hkBase, szKey, REG_SZ, lpszScheme, 0) != ERROR_SUCCESS)
  380. {
  381. DPF("Couldn't set scheme value %s\n", lpszScheme);
  382. RegCloseKey(hkBase);
  383. return FALSE;
  384. }
  385. }
  386. RegCloseKey(hkBase);
  387. if (RegNewScheme(hDlg, szKey, lpszScheme, FALSE))
  388. {
  389. iIndex = ComboBox_GetCount(hWndC);
  390. ComboBox_InsertString(hWndC, iIndex, lpszScheme);
  391. pszKey = (LPTSTR)LocalAlloc(LPTR, (lstrlen(szKey)*sizeof(TCHAR)) + sizeof(TCHAR));
  392. if (pszKey == NULL)
  393. {
  394. DPF("Failed Alloc\n");
  395. return FALSE;
  396. }
  397. lstrcpy(pszKey, szKey);
  398. ComboBox_SetItemData(hWndC, iIndex, (LPVOID)pszKey);
  399. ComboBox_SetCurSel(hWndC, iIndex);
  400. giScheme = ComboBox_GetCurSel(hWndC);
  401. EnableWindow(GetDlgItem(hDlg, ID_REMOVE_SCHEME), TRUE);
  402. }
  403. return TRUE;
  404. }
  405. /*
  406. ***************************************************************
  407. * RemoveScheme(hDlg)
  408. *
  409. * Description:
  410. * Deletes current scheme; removes it from dialog
  411. * combo box, sets the current scheme to <None>,
  412. * if it is set to be default. removes it as default
  413. * The remove and save buttons
  414. * are disabled since the <none> scheme is selected
  415. *
  416. * Arguments:
  417. * HWND hDlg window handle of dialog window
  418. *
  419. * Returns: BOOL
  420. * TRUE if message successful, else FALSE
  421. *
  422. ***************************************************************
  423. */
  424. BOOL PASCAL RemoveScheme(HWND hDlg)
  425. {
  426. TCHAR szBuf[MAXSTR];
  427. TCHAR szScheme[MAXSTR];
  428. TCHAR szMsg[MAXSTR];
  429. int i;
  430. HWND hWndC;
  431. HWND hwndTree = GetDlgItem(hDlg, IDC_EVENT_TREE);
  432. hWndC = GetDlgItem(hDlg, CB_SCHEMES);
  433. /* first confirm that this scheme is really to be deleted.
  434. */
  435. i = ComboBox_GetCurSel(hWndC);
  436. if (i == CB_ERR)
  437. return FALSE;
  438. LoadString(ghInstance, IDS_CONFIRMREMOVE, szMsg, MAXSTR);
  439. ComboBox_GetLBText(hWndC, i, szScheme);
  440. wsprintf(szBuf, szMsg, (LPTSTR)szScheme);
  441. if (MessageBox(hDlg, szBuf, gszRemoveScheme,
  442. MB_ICONEXCLAMATION | MB_TASKMODAL | MB_YESNO) == IDYES)
  443. {
  444. static SZCODE aszControlIniSchemeFormat[] = TEXT("SoundScheme.%s");
  445. static SZCODE aszControlIni[] = TEXT("control.ini");
  446. static SZCODE aszSoundSchemes[] = TEXT("SoundSchemes");
  447. TCHAR szControlIniScheme[MAXSTR];
  448. /* Remove from the list of schemes, and select none */
  449. EnableWindow(GetDlgItem(hDlg, ID_REMOVE_SCHEME), FALSE);
  450. EnableWindow(GetDlgItem(hDlg, ID_SAVE_SCHEME), FALSE);
  451. ClearModules(hDlg, hwndTree, TRUE);
  452. RegDeleteScheme(hWndC, i);
  453. wsprintf(szControlIniScheme, aszControlIniSchemeFormat, szScheme);
  454. WritePrivateProfileString(szControlIniScheme, NULL, NULL, aszControlIni);
  455. WritePrivateProfileString(aszSoundSchemes, szScheme, NULL, aszControlIni);
  456. return TRUE;
  457. }
  458. return FALSE;
  459. }
  460. /*
  461. ***************************************************************
  462. * RegSetDefault
  463. *
  464. * Description: Sets the given scheme as the default scheme in the reg
  465. * database
  466. *
  467. * Arguments:
  468. * LPTSTR lpKey - name of default scheme
  469. *
  470. * Returns: BOOL
  471. * TRUE if value set successful, else FALSE
  472. *
  473. ***************************************************************
  474. */
  475. BOOL PASCAL RegSetDefault(LPTSTR lpszKey)
  476. {
  477. if (RegSetValue(HKEY_CURRENT_USER, aszDefaultScheme, REG_SZ, lpszKey,
  478. 0) != ERROR_SUCCESS)
  479. {
  480. DPF("Failed to set Value %s,\n", lpszKey);
  481. return FALSE;
  482. }
  483. return TRUE;
  484. }
  485. /*
  486. ***************************************************************
  487. * RegDeleteScheme
  488. *
  489. * Description: Deletes the given scheme from the reg database.
  490. *
  491. * Arguments:
  492. * HWND hDlg - Dialog window handle
  493. * int iIndex - Index in Combobox
  494. *
  495. * Returns: BOOL
  496. * TRUE if deletion is successful, else FALSE
  497. *
  498. ***************************************************************
  499. */
  500. BOOL PASCAL RegDeleteScheme(HWND hWndC, int iIndex)
  501. {
  502. LPTSTR pszKey;
  503. TCHAR szKey[MAXSTR];
  504. TCHAR szBuf[MAXSTR];
  505. TCHAR szEvent[MAXSTR];
  506. TCHAR szApp[MAXSTR];
  507. HKEY hkApp;
  508. HKEY hkAppList;
  509. LONG cbSize;
  510. int iEvent;
  511. int iApp;
  512. if (hWndC)
  513. {
  514. pszKey = (LPTSTR)ComboBox_GetItemData(hWndC, iIndex);
  515. lstrcpy(szKey, pszKey);
  516. if (ComboBox_DeleteString(hWndC, iIndex) == CB_ERR)
  517. {
  518. DPF("Couldn't delete string %s,\n", (LPTSTR)szKey);
  519. return FALSE;
  520. }
  521. //ComboBox_SetCurSel(hWndC, 0);
  522. AppendRegKeys (szBuf, aszNames, szKey);
  523. if (RegDeleteKey(HKEY_CURRENT_USER, szBuf) != ERROR_SUCCESS)
  524. {
  525. DPF("Failed to delete %s key\n", (LPTSTR)szBuf);
  526. //return FALSE;
  527. }
  528. cbSize = sizeof(szBuf);
  529. if ((RegQueryValue(HKEY_CURRENT_USER, aszDefaultScheme, szBuf, &cbSize)
  530. != ERROR_SUCCESS) || (cbSize < 2))
  531. {
  532. DPF("Failed to get value of default scheme\n");
  533. RegSetDefault(gszNullScheme);
  534. }
  535. else
  536. if (!lstrcmpi(szBuf, szKey))
  537. {
  538. RegSetDefault(gszNullScheme);
  539. RegDeleteScheme(NULL, 0);
  540. }
  541. }
  542. else
  543. {
  544. lstrcpy(szKey, (LPTSTR)aszCurrent);
  545. }
  546. if (RegOpenKey(HKEY_CURRENT_USER, aszApps, &hkAppList) != ERROR_SUCCESS)
  547. {
  548. DPF("Failed to open that %s key\n", (LPTSTR)aszApps);
  549. return FALSE;
  550. }
  551. for (iApp = 0; RegEnumKey(hkAppList, iApp, szApp, sizeof(szApp)/sizeof(TCHAR))
  552. == ERROR_SUCCESS; iApp++)
  553. {
  554. if (RegOpenKey(hkAppList, szApp, &hkApp) != ERROR_SUCCESS)
  555. {
  556. DPF("Failed to open the %s key\n", (LPTSTR)szApp);
  557. continue;
  558. }
  559. for (iEvent = 0; RegEnumKey(hkApp, iEvent, szEvent, sizeof(szEvent)/sizeof(TCHAR))
  560. == ERROR_SUCCESS; iEvent++)
  561. {
  562. AppendRegKeys (szBuf, szEvent, szKey);
  563. if (RegDeleteKey(hkApp, szBuf) != ERROR_SUCCESS)
  564. DPF("No entry for scheme %s under event %s\n", (LPTSTR)szKey,
  565. (LPTSTR)szEvent);
  566. }
  567. RegCloseKey(hkApp);
  568. }
  569. RegCloseKey(hkAppList);
  570. return TRUE;
  571. }
  572. /*
  573. ***************************************************************
  574. * LoadEvents
  575. *
  576. * Description:
  577. * Adds all the events to the CB_EVENTS Combobox, corresponding to
  578. * the selected module.
  579. *
  580. * Parameters:
  581. * HWND hDlg - handle to dialog window.
  582. * int iIndex - The index of the selected module in the Combobox.
  583. *
  584. * Returns: BOOL
  585. * TRUE if all the events for the selected module were read from the reg
  586. * database, else FALSE
  587. ***************************************************************
  588. */
  589. BOOL PASCAL LoadEvents(HWND hwndTree, HTREEITEM htiParent, PMODULE npModule)
  590. {
  591. PEVENT npPtr;
  592. HTREEITEM hti;
  593. TV_INSERTSTRUCT ti;
  594. if (npModule == NULL)
  595. {
  596. DPF("Couldn't find module\n");
  597. return FALSE;
  598. }
  599. npPtr = npModule->npList;
  600. for (; npPtr != NULL; npPtr = npPtr->npNextEvent)
  601. {
  602. if (!gszCmdLineEvent[0])
  603. {
  604. npPtr->iNode = 2;
  605. ti.hParent = htiParent;
  606. ti.hInsertAfter = TVI_SORT;
  607. ti.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
  608. if (npPtr->fHasSound)
  609. ti.item.iImage = ti.item.iSelectedImage = 1;
  610. else
  611. ti.item.iImage = ti.item.iSelectedImage = 2;
  612. ti.item.pszText = npPtr->pszEventLabel;
  613. ti.item.lParam = (LPARAM)npPtr;
  614. hti = TreeView_InsertItem(hwndTree, &ti);
  615. if (!hti)
  616. {
  617. DPF("Couldn't add event Dataitem\n");
  618. return FALSE;
  619. }
  620. }
  621. else
  622. {
  623. // If a command line event was specified, only show this event.
  624. if (!lstrcmpi(npPtr->pszEventLabel, gszCmdLineEvent))
  625. {
  626. npPtr->iNode = 2;
  627. ti.hParent = htiParent;
  628. ti.hInsertAfter = TVI_SORT;
  629. ti.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
  630. if (npPtr->fHasSound)
  631. ti.item.iImage = ti.item.iSelectedImage = 1;
  632. else
  633. ti.item.iImage = ti.item.iSelectedImage = 2;
  634. ti.item.pszText = npPtr->pszEventLabel;
  635. ti.item.lParam = (LPARAM)npPtr;
  636. hti = TreeView_InsertItem(hwndTree, &ti);
  637. if (!hti)
  638. {
  639. DPF("Couldn't add event Dataitem\n");
  640. return FALSE;
  641. }
  642. break;
  643. }
  644. }
  645. }
  646. return TRUE;
  647. }
  648. /*
  649. ***************************************************************
  650. * LoadModules
  651. *
  652. * Description: Adds all the strings and event data items to the
  653. * list box for the given scheme
  654. *
  655. * Arguments:
  656. * HWND hDlg - window handle of dialog window
  657. * LPTSTR lpszScheme - The current scheme
  658. *
  659. * Returns: BOOL
  660. * TRUE if the modules for the scheme were read from reg db else FALSE
  661. *
  662. ***************************************************************
  663. */
  664. BOOL PASCAL LoadModules(HWND hDlg, LPTSTR lpszScheme)
  665. {
  666. TCHAR szLabel[MAXSTR];
  667. TCHAR szApp[MAXSTR];
  668. TCHAR szBuf[MAXSTR];
  669. HWND hwndTree;
  670. HKEY hKeyDisplayName;
  671. HKEY hkAppList;
  672. int iApp;
  673. DWORD cbSize;
  674. HTREEITEM hti;
  675. HWND hWndC = GetDlgItem(hDlg, CB_SCHEMES);
  676. hwndTree = GetDlgItem(hDlg, IDC_EVENT_TREE);
  677. ClearModules(hDlg, hwndTree, FALSE);
  678. if (RegOpenKey(HKEY_CURRENT_USER, aszApps, &hkAppList) != ERROR_SUCCESS)
  679. {
  680. DPF("Failed to open %s key\n", (LPTSTR)aszApps);
  681. return FALSE;
  682. }
  683. SendMessage(hwndTree, WM_SETREDRAW, FALSE, 0L);
  684. for (iApp = 0; RegEnumKey(hkAppList, iApp, szApp, sizeof(szApp)/sizeof(TCHAR))
  685. == ERROR_SUCCESS; iApp++)
  686. {
  687. AppendRegKeys (szBuf, aszApps, szApp);
  688. if (RegOpenKey (HKEY_CURRENT_USER, szBuf, &hKeyDisplayName) != ERROR_SUCCESS)
  689. {
  690. DPF("Failed to open key %s for event %s\n", (LPTSTR)szBuf, (LPTSTR)szApp);
  691. // If Key is not found, Display event name
  692. lstrcpy((LPTSTR)szLabel, szApp);
  693. }
  694. else
  695. {
  696. cbSize = sizeof(szLabel)/sizeof(TCHAR);
  697. if (ERROR_SUCCESS != SHLoadRegUIString(hKeyDisplayName, aszDisplayLabels, szLabel, cbSize))
  698. {
  699. // Load Default String if Localized String is not found
  700. if (ERROR_SUCCESS != SHLoadRegUIString(hKeyDisplayName, TEXT(""), szLabel, cbSize))
  701. {
  702. // If Default String is not found, load Event name
  703. DPF("Failed to get Display value for %s key\n", (LPTSTR)szApp);
  704. lstrcpy((LPTSTR)szLabel, szApp);
  705. }
  706. }
  707. RegCloseKey (hKeyDisplayName);
  708. }
  709. if(!lstrcmpi((LPTSTR)szLabel, (LPTSTR)aszMMTask))
  710. continue;
  711. if (!NewModule(hwndTree, lpszScheme, szLabel, szApp, iApp))
  712. {
  713. DPF("failed in new module for %s module\n", (LPTSTR)szApp);
  714. RegCloseKey(hkAppList);
  715. return FALSE;
  716. }
  717. }
  718. hti = NULL;
  719. for (hti = TreeView_GetRoot(hwndTree); hti; hti = TreeView_GetNextSibling(hwndTree, hti))
  720. TreeView_Expand(hwndTree, hti, TVE_EXPAND);
  721. SendMessage(hwndTree, WM_VSCROLL, (WPARAM)SB_TOP, 0L);
  722. SendMessage(hwndTree, WM_SETREDRAW, TRUE, 0L);
  723. // Select the event if one was passed on the command line.
  724. if (gszCmdLineEvent[0])
  725. {
  726. if ((hti = TreeView_GetRoot(hwndTree)) != NULL) {
  727. if ((hti = TreeView_GetChild(hwndTree, hti)) != NULL) {
  728. TreeView_SelectItem(hwndTree, hti);
  729. }
  730. }
  731. }
  732. RegCloseKey(hkAppList);
  733. if (iApp == 0)
  734. return FALSE;
  735. return TRUE;
  736. }
  737. /***************************************************************
  738. * NewModule
  739. *
  740. * Description:
  741. * Adds a data item associated with the module in the CB_MODULE
  742. * Combobox control.
  743. *
  744. * Parameters:
  745. * HWND hDlg - Dialog window handle.
  746. * LPTSTR lpszScheme - the handle to the key of the current scheme
  747. * LPTSTR lpszLabel - the string to be added to the Combobox
  748. * LPTSTR lpszKey - a string to be added as a data item
  749. * int iVal - Combobox index where the data item should go
  750. *
  751. * returns: BOOL
  752. * TRUE if data item is successfully added
  753. *
  754. ***************************************************************
  755. */
  756. BOOL PASCAL NewModule(HWND hwndTree, LPTSTR lpszScheme, LPTSTR lpszLabel,
  757. LPTSTR lpszKey, int iVal)
  758. {
  759. //int iIndex;
  760. int iEvent;
  761. LONG cbSize;
  762. HKEY hkApp;
  763. PMODULE npModule;
  764. PEVENT npPtr = NULL;
  765. PEVENT npNextPtr = NULL;
  766. TCHAR szEvent[MAXSTR];
  767. TCHAR szBuf[MAXSTR];
  768. TCHAR szTemp[MAXSTR];
  769. HTREEITEM hti;
  770. TV_INSERTSTRUCT ti;
  771. DWORD dwType;
  772. HKEY hkEvent;
  773. HKEY hKeyDisplayName;
  774. npModule = (PMODULE)LocalAlloc(LPTR, sizeof(MODULE));
  775. if (npModule == NULL)
  776. {
  777. DPF("Failed Alloc\n");
  778. return FALSE;
  779. }
  780. npModule->pszKey = (LPTSTR)LocalAlloc(LPTR, (lstrlen(lpszKey)*sizeof(TCHAR)) + sizeof(TCHAR));
  781. npModule->pszLabel = (LPTSTR)LocalAlloc(LPTR, (lstrlen(lpszLabel)*sizeof(TCHAR)) + sizeof(TCHAR));
  782. if (npModule->pszKey == NULL)
  783. {
  784. DPF("Failed Alloc\n");
  785. return FALSE;
  786. }
  787. if (npModule->pszLabel == NULL)
  788. {
  789. DPF("Failed Alloc\n");
  790. return FALSE;
  791. }
  792. lstrcpy(npModule->pszKey, lpszKey);
  793. lstrcpy(npModule->pszLabel, lpszLabel);
  794. AppendRegKeys (szBuf, aszApps, lpszKey);
  795. if (RegOpenKey(HKEY_CURRENT_USER, szBuf, &hkApp) != ERROR_SUCCESS)
  796. {
  797. DPF("Failed to open %s key\n", (LPTSTR)szBuf);
  798. return FALSE;
  799. }
  800. for (iEvent = 0; RegEnumKey(hkApp, iEvent, szEvent, sizeof(szEvent)/sizeof(TCHAR))
  801. == ERROR_SUCCESS; iEvent++)
  802. {
  803. npPtr = (PEVENT)LocalAlloc(LPTR, sizeof(EVENT));
  804. if (npPtr == NULL)
  805. {
  806. DPF("Failed Alloc\n");
  807. RegCloseKey(hkApp);
  808. return FALSE;
  809. }
  810. npPtr->npNextEvent = NULL;
  811. npPtr->pszEvent = (LPTSTR)LocalAlloc(LPTR, (lstrlen(szEvent)*sizeof(TCHAR)) + sizeof(TCHAR));
  812. if (npPtr->pszEvent == NULL)
  813. {
  814. DPF("Failed Alloc\n");
  815. RegCloseKey(hkApp);
  816. return FALSE;
  817. }
  818. lstrcpy(npPtr->pszEvent, szEvent);
  819. AppendRegKeys (szBuf, aszLabels, szEvent);
  820. if (RegOpenKey (HKEY_CURRENT_USER, szBuf, &hKeyDisplayName) != ERROR_SUCCESS)
  821. {
  822. DPF("Failed to open key %s for event %s\n", (LPTSTR)szBuf, (LPTSTR)szEvent);
  823. // If Key is not found, Display event name
  824. lstrcpy(szTemp, szEvent);
  825. }
  826. else
  827. {
  828. cbSize = sizeof(szTemp)/sizeof(TCHAR);
  829. if (ERROR_SUCCESS != SHLoadRegUIString(hKeyDisplayName, aszDisplayLabels, szTemp, cbSize))
  830. {
  831. // Load Default String if Localized String is not found
  832. if (ERROR_SUCCESS != SHLoadRegUIString(hKeyDisplayName, TEXT(""), szTemp, cbSize))
  833. {
  834. // If Default String is not found, load Event name
  835. DPF("Failed to get Display value for %s key\n", (LPTSTR)szEvent);
  836. lstrcpy(szTemp, szEvent);
  837. }
  838. }
  839. RegCloseKey (hKeyDisplayName);
  840. }
  841. npPtr->pszEventLabel = (LPTSTR)LocalAlloc(LPTR, (lstrlen(szTemp)*sizeof(TCHAR)) + sizeof(TCHAR));
  842. if (npPtr->pszEventLabel == NULL)
  843. {
  844. DPF("Failed Alloc\n");
  845. RegCloseKey(hkApp);
  846. return FALSE;
  847. }
  848. lstrcpy(npPtr->pszEventLabel, szTemp);
  849. // Query name of file; key is szEvent
  850. AppendRegKeys (szBuf, szEvent, lpszScheme);
  851. cbSize = sizeof(szTemp);
  852. if (ExRegQueryValue(hkApp, szBuf, (LPBYTE)szTemp, &cbSize) != ERROR_SUCCESS)
  853. {
  854. TCHAR szCurrentScheme[MAX_PATH];
  855. AppendRegKeys (szCurrentScheme, szEvent, aszCurrent);
  856. if (lstrcmpi(gszNullScheme, lpszScheme) && !ExRegQueryValue(hkApp, szCurrentScheme, (LPBYTE)szTemp, &cbSize))
  857. {
  858. HKEY hkNew;
  859. if (!RegCreateKey(hkApp, szBuf, &hkNew))
  860. {
  861. if (!RegSetValue(hkNew, NULL, REG_SZ, szTemp, lstrlen(szTemp)+sizeof(TCHAR)) && cbSize >= 5)
  862. npPtr->fHasSound = TRUE;
  863. else
  864. szTemp[0] = TEXT('\0');
  865. RegCloseKey(hkNew);
  866. }
  867. }
  868. else
  869. szTemp[0] = TEXT('\0');
  870. }
  871. else if(cbSize < 5)
  872. szTemp[0] = TEXT('\0');
  873. else
  874. npPtr->fHasSound = TRUE;
  875. npPtr->pszPath = (LPTSTR)LocalAlloc(LPTR, (lstrlen(szTemp)*sizeof(TCHAR)) + sizeof(TCHAR));
  876. if (npPtr->pszPath == NULL)
  877. {
  878. DPF("Failed Alloc\n");
  879. RegCloseKey(hkApp);
  880. return FALSE;
  881. }
  882. lstrcpy(npPtr->pszPath, szTemp);
  883. npPtr->npNextEvent = NULL;
  884. if (!npModule->npList)
  885. {
  886. npModule->npList = npPtr;
  887. npNextPtr = npPtr;
  888. }
  889. else
  890. {
  891. npNextPtr->npNextEvent = npPtr;
  892. npNextPtr = npNextPtr->npNextEvent;
  893. }
  894. }
  895. RegCloseKey(hkApp);
  896. npModule->iNode = 1;
  897. ti.hParent = TVI_ROOT;
  898. if (!gszCmdLineApp[0])
  899. {
  900. if (!lstrcmpi((LPTSTR)npModule->pszLabel, (LPTSTR)gszDefaultApp))
  901. ti.hInsertAfter = TVI_FIRST;
  902. else
  903. ti.hInsertAfter = TVI_LAST;
  904. ti.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
  905. ti.item.iImage = ti.item.iSelectedImage = 0;
  906. ti.item.pszText = npModule->pszLabel;
  907. ti.item.lParam = (LPARAM)npModule;
  908. hti = TreeView_InsertItem(hwndTree, &ti);
  909. if (!hti)
  910. {
  911. DPF("Couldn't add module dataitem\n");
  912. return FALSE;
  913. }
  914. LoadEvents(hwndTree, hti, npModule);
  915. }
  916. else
  917. {
  918. // If a command line app was specified, only show it's events.
  919. if (!lstrcmpi((LPTSTR)npModule->pszLabel, (LPTSTR)gszCmdLineApp))
  920. {
  921. ti.hInsertAfter = TVI_LAST;
  922. ti.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
  923. ti.item.iImage = ti.item.iSelectedImage = 0;
  924. ti.item.pszText = npModule->pszLabel;
  925. ti.item.lParam = (LPARAM)npModule;
  926. hti = TreeView_InsertItem(hwndTree, &ti);
  927. if (!hti)
  928. {
  929. DPF("Couldn't add module dataitem\n");
  930. return FALSE;
  931. }
  932. LoadEvents(hwndTree, hti, npModule);
  933. }
  934. }
  935. return TRUE;
  936. }
  937. /*
  938. ***************************************************************
  939. * ClearModules
  940. *
  941. * Description:
  942. * Frees the storage used for mappings, and removes the
  943. * entries in the list box
  944. *
  945. * Parameters:
  946. * HWND hDlg - Dialog window handle.
  947. * BOOL fDisable - If true disable save, remove and browse controls
  948. *
  949. * returns: BOOL
  950. *
  951. ***************************************************************
  952. */
  953. BOOL PASCAL ClearModules(HWND hDlg, HWND hwndTree, BOOL fDisable)
  954. {
  955. PMODULE npModule;
  956. PEVENT npPtr;
  957. PEVENT pEvent;
  958. HTREEITEM hti;
  959. TV_ITEM tvi;
  960. hti = NULL;
  961. for (hti = TreeView_GetRoot(hwndTree); hti; hti = TreeView_GetNextSibling(hwndTree, hti))
  962. {
  963. tvi.mask = TVIF_PARAM;
  964. tvi.hItem = hti;
  965. TreeView_GetItem(hwndTree, &tvi);
  966. npModule = (PMODULE)tvi.lParam;
  967. if (npModule)
  968. {
  969. for (npPtr = npModule->npList; npPtr != NULL;)
  970. {
  971. pEvent = npPtr;
  972. npPtr = npPtr->npNextEvent;
  973. if (pEvent)
  974. {
  975. LocalFree((HLOCAL)pEvent->pszEvent);
  976. LocalFree((HLOCAL)pEvent->pszEventLabel);
  977. if (pEvent->pszPath)
  978. LocalFree((HLOCAL)pEvent->pszPath);
  979. LocalFree((HLOCAL)pEvent);
  980. }
  981. }
  982. LocalFree((HLOCAL)npModule->pszKey);
  983. LocalFree((HLOCAL)npModule->pszLabel);
  984. LocalFree((HLOCAL)npModule);
  985. }
  986. }
  987. gfDeletingTree = TRUE;
  988. SendMessage(hwndTree, WM_SETREDRAW, FALSE, 0L);
  989. TreeView_DeleteAllItems(hwndTree);
  990. SendMessage(hwndTree, WM_SETREDRAW, TRUE, 0L);
  991. gfDeletingTree = FALSE;
  992. //if (hti)
  993. // LocalFree((HLOCAL)szScheme);
  994. return TRUE;
  995. }
  996. /*
  997. ***************************************************************
  998. * AddScheme
  999. *
  1000. * Description:
  1001. * Adds a scheme to the CB_SCHEME combobox
  1002. *
  1003. * Parameters:
  1004. * HWND hDlg - Dialog window handle.
  1005. * LPTSTR szLabel -- Printable name of scheme
  1006. * LPTSTR szScheme -- registry key for scheme
  1007. * BOOL fInsert -- Insert or add
  1008. * int iInsert -- position to insert if finsert is set
  1009. *
  1010. * returns: BOOL
  1011. *
  1012. ***************************************************************
  1013. */
  1014. BOOL PASCAL AddScheme(HWND hWndC, LPTSTR szLabel, LPTSTR szScheme,
  1015. BOOL fInsert, int iInsert)
  1016. {
  1017. int iIndex = 0;
  1018. LPTSTR pszKey;
  1019. pszKey = (LPTSTR)LocalAlloc(LPTR, (lstrlen(szScheme)*sizeof(TCHAR)) + sizeof(TCHAR));
  1020. if (pszKey == NULL)
  1021. {
  1022. DPF("Failed Alloc\n");
  1023. return FALSE;
  1024. }
  1025. lstrcpy(pszKey, szScheme);
  1026. if (fInsert)
  1027. {
  1028. if (ComboBox_InsertString(hWndC, iInsert, szLabel) != CB_ERR)
  1029. {
  1030. if (ComboBox_SetItemData(hWndC, iInsert,(LPVOID)pszKey) == CB_ERR)
  1031. {
  1032. DPF("couldn't set itemdata %s\n", (LPTSTR)pszKey);
  1033. return FALSE;
  1034. }
  1035. }
  1036. else
  1037. {
  1038. DPF("couldn't insert %s\n", (LPTSTR)szLabel);
  1039. return FALSE;
  1040. }
  1041. }
  1042. else
  1043. {
  1044. if ((iIndex = ComboBox_AddString(hWndC, szLabel)) != CB_ERR)
  1045. {
  1046. if (ComboBox_SetItemData(hWndC, iIndex, (LPVOID)pszKey) == CB_ERR)
  1047. {
  1048. DPF("couldn't set itemdata %s\n", (LPTSTR)pszKey);
  1049. return FALSE;
  1050. }
  1051. }
  1052. else
  1053. {
  1054. DPF("couldn't add %s\n", (LPTSTR)szLabel);
  1055. return FALSE;
  1056. }
  1057. }
  1058. return TRUE;
  1059. }
  1060. /*
  1061. ***************************************************************
  1062. * GetMediaPath
  1063. *
  1064. * Description:
  1065. * Fills in a buffer with the current setting for MediaPath,
  1066. * with a trailing backslash (usually "c:\windows\media\" etc).
  1067. * If there's no setting (very unlikely), the return buffer
  1068. * will be given "".
  1069. *
  1070. ***************************************************************
  1071. */
  1072. void PASCAL GetMediaPath (LPTSTR pszMediaPath, size_t cchMax)
  1073. {
  1074. static TCHAR szMediaPath[ MAX_PATH ] = TEXT("");
  1075. if (szMediaPath[0] == TEXT('\0'))
  1076. {
  1077. HKEY hk;
  1078. if (RegOpenKey (HKEY_LOCAL_MACHINE, REGSTR_PATH_SETUP, &hk) == 0)
  1079. {
  1080. DWORD dwType;
  1081. DWORD cb = sizeof(szMediaPath);
  1082. if (RegQueryValueEx (hk, REGSTR_VAL_MEDIA, NULL,
  1083. &dwType, (LPBYTE)szMediaPath, &cb) != 0)
  1084. {
  1085. szMediaPath[0] = TEXT('\0');
  1086. }
  1087. if ( (szMediaPath[0] != TEXT('\0')) &&
  1088. (szMediaPath[ lstrlen(szMediaPath)-1 ] != TEXT('\\')) )
  1089. {
  1090. lstrcat (szMediaPath, TEXT("\\"));
  1091. }
  1092. RegCloseKey (hk);
  1093. }
  1094. }
  1095. lstrcpyn (pszMediaPath, szMediaPath, cchMax-1);
  1096. }
  1097. /*
  1098. ***************************************************************
  1099. * RemoveMediaPath
  1100. *
  1101. * Description:
  1102. * Checks to see if a given filename resides within MediaPath;
  1103. * if so, yanks its parent path ("c:\win\media\ding.wav" becomes
  1104. * just "ding.wav", etc)
  1105. *
  1106. ***************************************************************
  1107. */
  1108. void PASCAL RemoveMediaPath (LPTSTR pszTarget, LPTSTR pszSource)
  1109. {
  1110. TCHAR szMediaPath[ MAX_PATH ] = TEXT("");
  1111. GetMediaPath (szMediaPath, MAX_PATH);
  1112. if (szMediaPath[0] == TEXT('\0'))
  1113. {
  1114. lstrcpy (pszTarget, pszSource);
  1115. }
  1116. else
  1117. {
  1118. size_t cch = lstrlen (szMediaPath);
  1119. if (!lstrnicmp (pszSource, szMediaPath, cch))
  1120. {
  1121. lstrcpy (pszTarget, &pszSource[ cch ]);
  1122. }
  1123. else
  1124. {
  1125. lstrcpy (pszTarget, pszSource);
  1126. }
  1127. }
  1128. }
  1129. /*
  1130. ***************************************************************
  1131. * AddMediaPath
  1132. *
  1133. * Description:
  1134. * If the given filename doesn't have a path, prepends the
  1135. * current setting of MediaPath to it ("ding.wav"->"c:\win\media\ding.wav")
  1136. *
  1137. ***************************************************************
  1138. */
  1139. void PASCAL AddMediaPath (LPTSTR pszTarget, LPTSTR pszSource)
  1140. {
  1141. if (lstrchr (pszSource, TEXT('\\')) != NULL)
  1142. {
  1143. lstrcpy (pszTarget, pszSource);
  1144. }
  1145. else
  1146. {
  1147. TCHAR szMediaPath[ MAX_PATH ] = TEXT("");
  1148. GetMediaPath (szMediaPath, MAX_PATH);
  1149. if (szMediaPath[0] == TEXT('\0'))
  1150. {
  1151. lstrcpy (pszTarget, pszSource);
  1152. }
  1153. else
  1154. {
  1155. lstrcpy (pszTarget, szMediaPath);
  1156. lstrcat (pszTarget, pszSource);
  1157. }
  1158. }
  1159. }
  1160. /*
  1161. ***************************************************************
  1162. * ExRegQueryValue
  1163. *
  1164. * Description:
  1165. * Just a wrapper for RegQueryValue(); this one doesn't choke
  1166. * on REG_EXPAND_SZ's.
  1167. *
  1168. ***************************************************************
  1169. */
  1170. int ExRegQueryValue (HKEY hkParent, LPTSTR szSubKey, LPBYTE pszBuffer, DWORD *pdwSize)
  1171. {
  1172. HKEY hkSubKey;
  1173. int rc;
  1174. if ((rc = RegOpenKey (hkParent, szSubKey, &hkSubKey)) == ERROR_SUCCESS)
  1175. {
  1176. DWORD dwType;
  1177. rc = RegQueryValueEx (hkSubKey, NULL, NULL, &dwType, pszBuffer, pdwSize);
  1178. RegCloseKey (hkSubKey);
  1179. }
  1180. return rc;
  1181. }