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

/*
***************************************************************
*
* This file contains the routines to read and write to the reg database
*
* Copyright 1993, Microsoft Corporation
*
* History:
*
* 07/94 - VijR (Created)
*
***************************************************************
*/
#include <windows.h>
#include <mmsystem.h>
#include <string.h>
#include <cpl.h>
#include <shellapi.h>
#include <ole2.h>
#define NOSTATUSBAR
#include <commctrl.h>
#include <prsht.h>
#include <regstr.h>
#include <shlwapi.h>
#include <shlwapip.h>
#include "mmcpl.h"
#include "draw.h"
#include "medhelp.h"
/*
***************************************************************
* Definitions
***************************************************************
*/
#define KEYLEN 8 //length of artificially created key
#define MAXSCHEME 37 //max length of scheme name
/*
***************************************************************
* File Globals
***************************************************************
*/
static SZCODE aszDefaultScheme[] = TEXT("Appevents\\schemes");
static SZCODE aszDefaultApp[] = TEXT("Appevents\\schemes\\apps\\.default");
static SZCODE aszApps[] = TEXT("Appevents\\schemes\\apps");
static SZCODE aszLabels[] = TEXT("Appevents\\eventlabels");
static SZCODE aszDisplayLabels[] = TEXT("DispFileName");
static SZCODE aszNames[] = TEXT("Appevents\\schemes\\Names");
static SZCODE aszDefault[] = TEXT(".default");
static SZCODE aszCurrent[] = TEXT(".current");
static SZCODE aszMMTask[] = TEXT("MMTask");
static INTCODE aKeyWordIds[] =
{
ID_SCHEMENAME, IDH_SAVEAS_SCHEMENAME,
0,0
};
static SZCODE cszSslashS[] = TEXT("%s\\%s");
/*
***************************************************************
* extern
***************************************************************
*/
extern HWND ghWnd;
extern BOOL gfChanged;
extern BOOL gfNewScheme;
extern BOOL gfDeletingTree;
extern int giScheme;
extern TCHAR gszDefaultApp[];
extern TCHAR gszNullScheme[];
extern TCHAR gszCmdLineApp[];
extern TCHAR gszCmdLineEvent[];
/*
***************************************************************
* Prototypes
***************************************************************
*/
BOOL PASCAL RemoveScheme (HWND);
BOOL PASCAL RegAddScheme (HWND, LPTSTR);
BOOL PASCAL RegNewScheme (HWND, LPTSTR, LPTSTR, BOOL);
BOOL PASCAL RegSetDefault (LPTSTR);
BOOL PASCAL RegDeleteScheme (HWND, int);
BOOL PASCAL LoadEvents (HWND, HTREEITEM, PMODULE);
BOOL PASCAL LoadModules (HWND, LPTSTR);
BOOL PASCAL ClearModules (HWND, HWND, BOOL);
BOOL PASCAL NewModule (HWND, LPTSTR, LPTSTR, LPTSTR, int);
BOOL PASCAL FindEventLabel (LPTSTR, LPTSTR);
BOOL PASCAL AddScheme (HWND, LPTSTR, LPTSTR, BOOL, int);
void PASCAL GetMediaPath (LPTSTR, size_t);
void PASCAL RemoveMediaPath (LPTSTR, LPTSTR);
void PASCAL AddMediaPath (LPTSTR, LPTSTR);
int ExRegQueryValue (HKEY, LPTSTR, LPBYTE, DWORD *);
//sndfile.c
BOOL PASCAL ShowSoundMapping (HWND, PEVENT);
int StrByteLen (LPTSTR);
//drivers.c
int lstrnicmp (LPTSTR, LPTSTR, size_t);
LPTSTR lstrchr (LPTSTR, TCHAR);
/*
***************************************************************
***************************************************************
*/
static void AppendRegKeys (
LPTSTR szBuf,
LPCTSTR szLeft,
LPCTSTR szRight)
{
static SZCODE cszSlash[] = TEXT("\\");
lstrcpy (szBuf, szLeft);
lstrcat (szBuf, cszSlash);
lstrcat (szBuf, szRight);
}
/*
***************************************************************
* SaveSchemeDlg
*
* Description: Dialog handler for save schemes dialog.
* checks if given scheme name exists and if so
* whether it should be overwritten.
* if yes then delete current scheme.
* scheme under a new name, else just add a new scheme
* The user can choose to cancel
*
* Arguments:
* HWND hDlg - window handle of dialog window
* UINT uiMessage - message number
* WPARAM wParam - message-dependent
* LPARAM lParam - message-dependent
*
* Returns: BOOL
* TRUE if message has been processed, else FALSE
*
***************************************************************************
*/
INT_PTR CALLBACK SaveSchemeDlg(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
TCHAR szBuf[MAXSTR];
TCHAR szTemp[MAXSTR];
TCHAR szMesg[MAXSTR];
int iResult;
int iIndex;
HWND hDlgParent = ghWnd;
switch (uMsg)
{
case WM_INITDIALOG:
szBuf[0] = TEXT('\0');
DPF("IN Init\n");
Edit_LimitText(GetDlgItem(hDlg, ID_SCHEMENAME), MAXSCHEME);
Edit_SetText(GetDlgItem(hDlg, ID_SCHEMENAME), (LPTSTR)lParam);
// dump the text from lparam into the edit control.
break;
case WM_COMMAND:
switch (wParam)
{
case IDOK:
{
LPTSTR pszKey;
Edit_GetText(GetDlgItem(hDlg, ID_SCHEMENAME), szBuf, MAXSTR);
//prevent null-string names
if (lstrlen(szBuf) == 0)
{
LoadString(ghInstance, IDS_INVALIDFILE, szTemp, MAXSTR);
MessageBox(hDlg, szTemp, gszChangeScheme, MB_ICONERROR | MB_OK);
break;
}
iIndex = ComboBox_FindStringExact(GetDlgItem(hDlgParent,
CB_SCHEMES), 0, szBuf);
pszKey = (LPTSTR)ComboBox_GetItemData(GetDlgItem(hDlgParent,CB_SCHEMES), iIndex);
if (iIndex != CB_ERR)
{
if (!lstrcmpi((LPTSTR)pszKey, aszDefault) || !lstrcmpi((LPTSTR)pszKey, gszNullScheme))
{
LoadString(ghInstance, IDS_NOOVERWRITEDEFAULT, szTemp,
MAXSTR);
wsprintf(szMesg, szTemp, (LPTSTR)szBuf);
iResult = MessageBox(hDlg, szMesg, gszChangeScheme,
MB_ICONEXCLAMATION | MB_TASKMODAL | MB_OKCANCEL);
if (iResult == IDOK)
{
break;
}
}
else
{
LoadString(ghInstance, IDS_OVERWRITESCHEME, szTemp,
MAXSTR);
wsprintf(szMesg, szTemp, (LPTSTR)szBuf);
iResult = MessageBox(hDlg, szMesg, gszChangeScheme,
MB_ICONEXCLAMATION | MB_TASKMODAL | MB_YESNOCANCEL);
if (iResult == IDYES)
{
RegDeleteScheme(GetDlgItem(hDlgParent,
CB_SCHEMES), iIndex);
RegAddScheme(hDlgParent, szBuf);
PropSheet_Changed(GetParent(hDlg),hDlg);
}
else
{
if (iResult == IDNO)
break;
if (iResult == IDCANCEL)
{
EndDialog(hDlg, FALSE);
break;
}
}
}
}
else
{
RegAddScheme(hDlgParent, szBuf);
PropSheet_Changed(GetParent(hDlg),hDlg);
}
gfChanged = TRUE;
EndDialog(hDlg, TRUE);
DPF("Done save\n");
break;
}
case IDCANCEL:
EndDialog(hDlg, FALSE);
DPF("Done save\n");
break;
case ID_SCHEMENAME:
if ((HIWORD(lParam) == EN_ERRSPACE) ||
(HIWORD(lParam) == EN_MAXTEXT))
MessageBeep(MB_OK);
else
if (HIWORD(lParam) == EN_CHANGE)
{
GetWindowText(GetDlgItem(hDlg, ID_SCHEMENAME), szBuf,
MAXSTR - 1);
EnableWindow(GetDlgItem(hDlg, IDOK), *szBuf);
}
break;
default:
break;
}
break;
case WM_CONTEXTMENU:
WinHelp((HWND)wParam, NULL, HELP_CONTEXTMENU,
(UINT_PTR)(LPTSTR)aKeyWordIds);
break;
case WM_HELP:
WinHelp(((LPHELPINFO)lParam)->hItemHandle, NULL, HELP_WM_HELP
, (UINT_PTR)(LPTSTR)aKeyWordIds);
break;
}
return FALSE;
}
/*
***************************************************************
* RegNewScheme
*
* Description:
* Saves the scheme in the reg database. If the fQuery flag is
* set then a messages box is brought up, asking if the schem should
* be saved
*
* Arguments:
* HWND hDlg - Handle to the dialog
* LPTSTR lpszScheme - pointer to scheme name.
* BOOL fQuery - If TRUE and lpszScheme is in reg.db bring up msgbox.
*
* Returns: BOOL
* TRUE if the new scheme is succesfully added or if the user chooses
* not to save
*
***************************************************************
*/
BOOL PASCAL RegNewScheme(HWND hDlg, LPTSTR lpszKey, LPTSTR lpszLabel,
BOOL fQuery)
{
PMODULE npModule;
PEVENT npPtr;
TCHAR szBuf[MAXSTR];
TCHAR szLabel[MAXSTR];
HTREEITEM hti;
TV_ITEM tvi;
HWND hwndTree = GetDlgItem(hDlg, IDC_EVENT_TREE);
if (fQuery)
{
LoadString(ghInstance, IDS_SAVECHANGE, szBuf, MAXSTR);
LoadString(ghInstance, IDS_SAVESCHEME, szLabel, MAXSTR);
if (MessageBox(hDlg, szBuf, szLabel,
MB_ICONEXCLAMATION | MB_TASKMODAL | MB_YESNO) == IDNO)
return TRUE;
}
for (hti = TreeView_GetRoot(hwndTree); hti; hti = TreeView_GetNextSibling(hwndTree, hti))
{
tvi.mask = TVIF_PARAM;
tvi.hItem = hti;
TreeView_GetItem(hwndTree, &tvi);
npModule = (PMODULE)tvi.lParam;
if ((npPtr = npModule->npList) == NULL)
break;
for (; npPtr != NULL; npPtr = npPtr->npNextEvent)
{
HKEY hk = NULL;
DWORD dwType;
static SZCODE cszFmt[] = TEXT("%s\\%s\\%s\\%s");
wsprintf(szBuf, cszFmt, (LPTSTR)aszApps,
(LPTSTR)npModule->pszKey, (LPTSTR)npPtr->pszEvent, lpszKey);
DPF("setting %s to %s\n", (LPTSTR)szBuf, (LPTSTR)npPtr->pszPath);
RemoveMediaPath (szLabel, npPtr->pszPath);
dwType = (lstrchr (szLabel, TEXT('%'))) ? REG_EXPAND_SZ : REG_SZ;
// Set file name
if ((RegCreateKey (HKEY_CURRENT_USER, szBuf, &hk) == ERROR_SUCCESS) && hk)
{
if (RegSetValueEx (hk, NULL, 0, dwType, (LPBYTE)szLabel,
(1+lstrlen(szLabel))*sizeof(TCHAR)) != ERROR_SUCCESS)
{
DPF("fail %s for %s,\n", (LPTSTR)szLabel, (LPTSTR)szBuf);
}
RegCloseKey (hk);
}
}
}
return TRUE;
}
/*
***************************************************************
* RegAddScheme
*
* Description:
* Adds the given scheme to the reg database by creating a key using
* upto the first KEYLEN letters of the schemename. If the strlen
* id less than KEYLEN, '0's are added till the key is KEYLEN long.
* This key is checked for uniqueness and then RegNewScheme is called.
*
* Arguments:
* HWND hDlg - Handle to the dialog
* LPTSTR lpszScheme - pointer to scheme name.
*
* Returns: BOOL
* TRUE if message successful, else FALSE
*
***************************************************************
*/
BOOL PASCAL RegAddScheme(HWND hDlg, LPTSTR lpszScheme)
{
TCHAR szKey[32];
LPTSTR pszKey;
int iIndex;
int iLen;
int iStrLen;
HWND hWndC;
HKEY hkScheme;
HKEY hkBase;
hWndC = GetDlgItem(hDlg, CB_SCHEMES);
iLen = StrByteLen(lpszScheme);
iStrLen = lstrlen(lpszScheme);
if (iStrLen < KEYLEN)
{
lstrcpy(szKey, lpszScheme);
iIndex = iLen;
szKey[iIndex] = TEXT('0');
szKey[iIndex+sizeof(TCHAR)] = TEXT('\0');
}
else
{
lstrcpyn(szKey, lpszScheme, KEYLEN-1);
iIndex = StrByteLen(szKey);
szKey[iIndex] = TEXT('0');
szKey[iIndex+sizeof(TCHAR)] = TEXT('\0');
}
if (RegOpenKey(HKEY_CURRENT_USER, aszNames, &hkBase) != ERROR_SUCCESS)
{
DPF("Failed to open asznames\n");
return FALSE;
}
gfNewScheme = FALSE;
while (RegOpenKey(hkBase, szKey, &hkScheme) == ERROR_SUCCESS)
{
szKey[iIndex]++;
RegCloseKey(hkScheme);
}
if (RegSetValue(hkBase, szKey, REG_SZ, lpszScheme, 0) != ERROR_SUCCESS)
{
static SZCODE cszFmt[] = TEXT("%lx");
wsprintf((LPTSTR)szKey, cszFmt, GetCurrentTime()); //High chance of unique ness. This is to deal with some
//DBCS problems.
if (RegSetValue(hkBase, szKey, REG_SZ, lpszScheme, 0) != ERROR_SUCCESS)
{
DPF("Couldn't set scheme value %s\n", lpszScheme);
RegCloseKey(hkBase);
return FALSE;
}
}
RegCloseKey(hkBase);
if (RegNewScheme(hDlg, szKey, lpszScheme, FALSE))
{
iIndex = ComboBox_GetCount(hWndC);
ComboBox_InsertString(hWndC, iIndex, lpszScheme);
pszKey = (LPTSTR)LocalAlloc(LPTR, (lstrlen(szKey)*sizeof(TCHAR)) + sizeof(TCHAR));
if (pszKey == NULL)
{
DPF("Failed Alloc\n");
return FALSE;
}
lstrcpy(pszKey, szKey);
ComboBox_SetItemData(hWndC, iIndex, (LPVOID)pszKey);
ComboBox_SetCurSel(hWndC, iIndex);
giScheme = ComboBox_GetCurSel(hWndC);
EnableWindow(GetDlgItem(hDlg, ID_REMOVE_SCHEME), TRUE);
}
return TRUE;
}
/*
***************************************************************
* RemoveScheme(hDlg)
*
* Description:
* Deletes current scheme; removes it from dialog
* combo box, sets the current scheme to <None>,
* if it is set to be default. removes it as default
* The remove and save buttons
* are disabled since the <none> scheme is selected
*
* Arguments:
* HWND hDlg window handle of dialog window
*
* Returns: BOOL
* TRUE if message successful, else FALSE
*
***************************************************************
*/
BOOL PASCAL RemoveScheme(HWND hDlg)
{
TCHAR szBuf[MAXSTR];
TCHAR szScheme[MAXSTR];
TCHAR szMsg[MAXSTR];
int i;
HWND hWndC;
HWND hwndTree = GetDlgItem(hDlg, IDC_EVENT_TREE);
hWndC = GetDlgItem(hDlg, CB_SCHEMES);
/* first confirm that this scheme is really to be deleted.
*/
i = ComboBox_GetCurSel(hWndC);
if (i == CB_ERR)
return FALSE;
LoadString(ghInstance, IDS_CONFIRMREMOVE, szMsg, MAXSTR);
ComboBox_GetLBText(hWndC, i, szScheme);
wsprintf(szBuf, szMsg, (LPTSTR)szScheme);
if (MessageBox(hDlg, szBuf, gszRemoveScheme,
MB_ICONEXCLAMATION | MB_TASKMODAL | MB_YESNO) == IDYES)
{
static SZCODE aszControlIniSchemeFormat[] = TEXT("SoundScheme.%s");
static SZCODE aszControlIni[] = TEXT("control.ini");
static SZCODE aszSoundSchemes[] = TEXT("SoundSchemes");
TCHAR szControlIniScheme[MAXSTR];
/* Remove from the list of schemes, and select none */
EnableWindow(GetDlgItem(hDlg, ID_REMOVE_SCHEME), FALSE);
EnableWindow(GetDlgItem(hDlg, ID_SAVE_SCHEME), FALSE);
ClearModules(hDlg, hwndTree, TRUE);
RegDeleteScheme(hWndC, i);
wsprintf(szControlIniScheme, aszControlIniSchemeFormat, szScheme);
WritePrivateProfileString(szControlIniScheme, NULL, NULL, aszControlIni);
WritePrivateProfileString(aszSoundSchemes, szScheme, NULL, aszControlIni);
return TRUE;
}
return FALSE;
}
/*
***************************************************************
* RegSetDefault
*
* Description: Sets the given scheme as the default scheme in the reg
* database
*
* Arguments:
* LPTSTR lpKey - name of default scheme
*
* Returns: BOOL
* TRUE if value set successful, else FALSE
*
***************************************************************
*/
BOOL PASCAL RegSetDefault(LPTSTR lpszKey)
{
if (RegSetValue(HKEY_CURRENT_USER, aszDefaultScheme, REG_SZ, lpszKey,
0) != ERROR_SUCCESS)
{
DPF("Failed to set Value %s,\n", lpszKey);
return FALSE;
}
return TRUE;
}
/*
***************************************************************
* RegDeleteScheme
*
* Description: Deletes the given scheme from the reg database.
*
* Arguments:
* HWND hDlg - Dialog window handle
* int iIndex - Index in Combobox
*
* Returns: BOOL
* TRUE if deletion is successful, else FALSE
*
***************************************************************
*/
BOOL PASCAL RegDeleteScheme(HWND hWndC, int iIndex)
{
LPTSTR pszKey;
TCHAR szKey[MAXSTR];
TCHAR szBuf[MAXSTR];
TCHAR szEvent[MAXSTR];
TCHAR szApp[MAXSTR];
HKEY hkApp;
HKEY hkAppList;
LONG cbSize;
int iEvent;
int iApp;
if (hWndC)
{
pszKey = (LPTSTR)ComboBox_GetItemData(hWndC, iIndex);
lstrcpy(szKey, pszKey);
if (ComboBox_DeleteString(hWndC, iIndex) == CB_ERR)
{
DPF("Couldn't delete string %s,\n", (LPTSTR)szKey);
return FALSE;
}
//ComboBox_SetCurSel(hWndC, 0);
AppendRegKeys (szBuf, aszNames, szKey);
if (RegDeleteKey(HKEY_CURRENT_USER, szBuf) != ERROR_SUCCESS)
{
DPF("Failed to delete %s key\n", (LPTSTR)szBuf);
//return FALSE;
}
cbSize = sizeof(szBuf);
if ((RegQueryValue(HKEY_CURRENT_USER, aszDefaultScheme, szBuf, &cbSize)
!= ERROR_SUCCESS) || (cbSize < 2))
{
DPF("Failed to get value of default scheme\n");
RegSetDefault(gszNullScheme);
}
else
if (!lstrcmpi(szBuf, szKey))
{
RegSetDefault(gszNullScheme);
RegDeleteScheme(NULL, 0);
}
}
else
{
lstrcpy(szKey, (LPTSTR)aszCurrent);
}
if (RegOpenKey(HKEY_CURRENT_USER, aszApps, &hkAppList) != ERROR_SUCCESS)
{
DPF("Failed to open that %s key\n", (LPTSTR)aszApps);
return FALSE;
}
for (iApp = 0; RegEnumKey(hkAppList, iApp, szApp, sizeof(szApp)/sizeof(TCHAR))
== ERROR_SUCCESS; iApp++)
{
if (RegOpenKey(hkAppList, szApp, &hkApp) != ERROR_SUCCESS)
{
DPF("Failed to open the %s key\n", (LPTSTR)szApp);
continue;
}
for (iEvent = 0; RegEnumKey(hkApp, iEvent, szEvent, sizeof(szEvent)/sizeof(TCHAR))
== ERROR_SUCCESS; iEvent++)
{
AppendRegKeys (szBuf, szEvent, szKey);
if (RegDeleteKey(hkApp, szBuf) != ERROR_SUCCESS)
DPF("No entry for scheme %s under event %s\n", (LPTSTR)szKey,
(LPTSTR)szEvent);
}
RegCloseKey(hkApp);
}
RegCloseKey(hkAppList);
return TRUE;
}
/*
***************************************************************
* LoadEvents
*
* Description:
* Adds all the events to the CB_EVENTS Combobox, corresponding to
* the selected module.
*
* Parameters:
* HWND hDlg - handle to dialog window.
* int iIndex - The index of the selected module in the Combobox.
*
* Returns: BOOL
* TRUE if all the events for the selected module were read from the reg
* database, else FALSE
***************************************************************
*/
BOOL PASCAL LoadEvents(HWND hwndTree, HTREEITEM htiParent, PMODULE npModule)
{
PEVENT npPtr;
HTREEITEM hti;
TV_INSERTSTRUCT ti;
if (npModule == NULL)
{
DPF("Couldn't find module\n");
return FALSE;
}
npPtr = npModule->npList;
for (; npPtr != NULL; npPtr = npPtr->npNextEvent)
{
if (!gszCmdLineEvent[0])
{
npPtr->iNode = 2;
ti.hParent = htiParent;
ti.hInsertAfter = TVI_SORT;
ti.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
if (npPtr->fHasSound)
ti.item.iImage = ti.item.iSelectedImage = 1;
else
ti.item.iImage = ti.item.iSelectedImage = 2;
ti.item.pszText = npPtr->pszEventLabel;
ti.item.lParam = (LPARAM)npPtr;
hti = TreeView_InsertItem(hwndTree, &ti);
if (!hti)
{
DPF("Couldn't add event Dataitem\n");
return FALSE;
}
}
else
{
// If a command line event was specified, only show this event.
if (!lstrcmpi(npPtr->pszEventLabel, gszCmdLineEvent))
{
npPtr->iNode = 2;
ti.hParent = htiParent;
ti.hInsertAfter = TVI_SORT;
ti.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
if (npPtr->fHasSound)
ti.item.iImage = ti.item.iSelectedImage = 1;
else
ti.item.iImage = ti.item.iSelectedImage = 2;
ti.item.pszText = npPtr->pszEventLabel;
ti.item.lParam = (LPARAM)npPtr;
hti = TreeView_InsertItem(hwndTree, &ti);
if (!hti)
{
DPF("Couldn't add event Dataitem\n");
return FALSE;
}
break;
}
}
}
return TRUE;
}
/*
***************************************************************
* LoadModules
*
* Description: Adds all the strings and event data items to the
* list box for the given scheme
*
* Arguments:
* HWND hDlg - window handle of dialog window
* LPTSTR lpszScheme - The current scheme
*
* Returns: BOOL
* TRUE if the modules for the scheme were read from reg db else FALSE
*
***************************************************************
*/
BOOL PASCAL LoadModules(HWND hDlg, LPTSTR lpszScheme)
{
TCHAR szLabel[MAXSTR];
TCHAR szApp[MAXSTR];
TCHAR szBuf[MAXSTR];
HWND hwndTree;
HKEY hKeyDisplayName;
HKEY hkAppList;
int iApp;
DWORD cbSize;
HTREEITEM hti;
HWND hWndC = GetDlgItem(hDlg, CB_SCHEMES);
hwndTree = GetDlgItem(hDlg, IDC_EVENT_TREE);
ClearModules(hDlg, hwndTree, FALSE);
if (RegOpenKey(HKEY_CURRENT_USER, aszApps, &hkAppList) != ERROR_SUCCESS)
{
DPF("Failed to open %s key\n", (LPTSTR)aszApps);
return FALSE;
}
SendMessage(hwndTree, WM_SETREDRAW, FALSE, 0L);
for (iApp = 0; RegEnumKey(hkAppList, iApp, szApp, sizeof(szApp)/sizeof(TCHAR))
== ERROR_SUCCESS; iApp++)
{
AppendRegKeys (szBuf, aszApps, szApp);
if (RegOpenKey (HKEY_CURRENT_USER, szBuf, &hKeyDisplayName) != ERROR_SUCCESS)
{
DPF("Failed to open key %s for event %s\n", (LPTSTR)szBuf, (LPTSTR)szApp);
// If Key is not found, Display event name
lstrcpy((LPTSTR)szLabel, szApp);
}
else
{
cbSize = sizeof(szLabel)/sizeof(TCHAR);
if (ERROR_SUCCESS != SHLoadRegUIString(hKeyDisplayName, aszDisplayLabels, szLabel, cbSize))
{
// Load Default String if Localized String is not found
if (ERROR_SUCCESS != SHLoadRegUIString(hKeyDisplayName, TEXT(""), szLabel, cbSize))
{
// If Default String is not found, load Event name
DPF("Failed to get Display value for %s key\n", (LPTSTR)szApp);
lstrcpy((LPTSTR)szLabel, szApp);
}
}
RegCloseKey (hKeyDisplayName);
}
if(!lstrcmpi((LPTSTR)szLabel, (LPTSTR)aszMMTask))
continue;
if (!NewModule(hwndTree, lpszScheme, szLabel, szApp, iApp))
{
DPF("failed in new module for %s module\n", (LPTSTR)szApp);
RegCloseKey(hkAppList);
return FALSE;
}
}
hti = NULL;
for (hti = TreeView_GetRoot(hwndTree); hti; hti = TreeView_GetNextSibling(hwndTree, hti))
TreeView_Expand(hwndTree, hti, TVE_EXPAND);
SendMessage(hwndTree, WM_VSCROLL, (WPARAM)SB_TOP, 0L);
SendMessage(hwndTree, WM_SETREDRAW, TRUE, 0L);
// Select the event if one was passed on the command line.
if (gszCmdLineEvent[0])
{
if ((hti = TreeView_GetRoot(hwndTree)) != NULL) {
if ((hti = TreeView_GetChild(hwndTree, hti)) != NULL) {
TreeView_SelectItem(hwndTree, hti);
}
}
}
RegCloseKey(hkAppList);
if (iApp == 0)
return FALSE;
return TRUE;
}
/***************************************************************
* NewModule
*
* Description:
* Adds a data item associated with the module in the CB_MODULE
* Combobox control.
*
* Parameters:
* HWND hDlg - Dialog window handle.
* LPTSTR lpszScheme - the handle to the key of the current scheme
* LPTSTR lpszLabel - the string to be added to the Combobox
* LPTSTR lpszKey - a string to be added as a data item
* int iVal - Combobox index where the data item should go
*
* returns: BOOL
* TRUE if data item is successfully added
*
***************************************************************
*/
BOOL PASCAL NewModule(HWND hwndTree, LPTSTR lpszScheme, LPTSTR lpszLabel,
LPTSTR lpszKey, int iVal)
{
//int iIndex;
int iEvent;
LONG cbSize;
HKEY hkApp;
PMODULE npModule;
PEVENT npPtr = NULL;
PEVENT npNextPtr = NULL;
TCHAR szEvent[MAXSTR];
TCHAR szBuf[MAXSTR];
TCHAR szTemp[MAXSTR];
HTREEITEM hti;
TV_INSERTSTRUCT ti;
DWORD dwType;
HKEY hkEvent;
HKEY hKeyDisplayName;
npModule = (PMODULE)LocalAlloc(LPTR, sizeof(MODULE));
if (npModule == NULL)
{
DPF("Failed Alloc\n");
return FALSE;
}
npModule->pszKey = (LPTSTR)LocalAlloc(LPTR, (lstrlen(lpszKey)*sizeof(TCHAR)) + sizeof(TCHAR));
npModule->pszLabel = (LPTSTR)LocalAlloc(LPTR, (lstrlen(lpszLabel)*sizeof(TCHAR)) + sizeof(TCHAR));
if (npModule->pszKey == NULL)
{
DPF("Failed Alloc\n");
return FALSE;
}
if (npModule->pszLabel == NULL)
{
DPF("Failed Alloc\n");
return FALSE;
}
lstrcpy(npModule->pszKey, lpszKey);
lstrcpy(npModule->pszLabel, lpszLabel);
AppendRegKeys (szBuf, aszApps, lpszKey);
if (RegOpenKey(HKEY_CURRENT_USER, szBuf, &hkApp) != ERROR_SUCCESS)
{
DPF("Failed to open %s key\n", (LPTSTR)szBuf);
return FALSE;
}
for (iEvent = 0; RegEnumKey(hkApp, iEvent, szEvent, sizeof(szEvent)/sizeof(TCHAR))
== ERROR_SUCCESS; iEvent++)
{
npPtr = (PEVENT)LocalAlloc(LPTR, sizeof(EVENT));
if (npPtr == NULL)
{
DPF("Failed Alloc\n");
RegCloseKey(hkApp);
return FALSE;
}
npPtr->npNextEvent = NULL;
npPtr->pszEvent = (LPTSTR)LocalAlloc(LPTR, (lstrlen(szEvent)*sizeof(TCHAR)) + sizeof(TCHAR));
if (npPtr->pszEvent == NULL)
{
DPF("Failed Alloc\n");
RegCloseKey(hkApp);
return FALSE;
}
lstrcpy(npPtr->pszEvent, szEvent);
AppendRegKeys (szBuf, aszLabels, szEvent);
if (RegOpenKey (HKEY_CURRENT_USER, szBuf, &hKeyDisplayName) != ERROR_SUCCESS)
{
DPF("Failed to open key %s for event %s\n", (LPTSTR)szBuf, (LPTSTR)szEvent);
// If Key is not found, Display event name
lstrcpy(szTemp, szEvent);
}
else
{
cbSize = sizeof(szTemp)/sizeof(TCHAR);
if (ERROR_SUCCESS != SHLoadRegUIString(hKeyDisplayName, aszDisplayLabels, szTemp, cbSize))
{
// Load Default String if Localized String is not found
if (ERROR_SUCCESS != SHLoadRegUIString(hKeyDisplayName, TEXT(""), szTemp, cbSize))
{
// If Default String is not found, load Event name
DPF("Failed to get Display value for %s key\n", (LPTSTR)szEvent);
lstrcpy(szTemp, szEvent);
}
}
RegCloseKey (hKeyDisplayName);
}
npPtr->pszEventLabel = (LPTSTR)LocalAlloc(LPTR, (lstrlen(szTemp)*sizeof(TCHAR)) + sizeof(TCHAR));
if (npPtr->pszEventLabel == NULL)
{
DPF("Failed Alloc\n");
RegCloseKey(hkApp);
return FALSE;
}
lstrcpy(npPtr->pszEventLabel, szTemp);
// Query name of file; key is szEvent
AppendRegKeys (szBuf, szEvent, lpszScheme);
cbSize = sizeof(szTemp);
if (ExRegQueryValue(hkApp, szBuf, (LPBYTE)szTemp, &cbSize) != ERROR_SUCCESS)
{
TCHAR szCurrentScheme[MAX_PATH];
AppendRegKeys (szCurrentScheme, szEvent, aszCurrent);
if (lstrcmpi(gszNullScheme, lpszScheme) && !ExRegQueryValue(hkApp, szCurrentScheme, (LPBYTE)szTemp, &cbSize))
{
HKEY hkNew;
if (!RegCreateKey(hkApp, szBuf, &hkNew))
{
if (!RegSetValue(hkNew, NULL, REG_SZ, szTemp, lstrlen(szTemp)+sizeof(TCHAR)) && cbSize >= 5)
npPtr->fHasSound = TRUE;
else
szTemp[0] = TEXT('\0');
RegCloseKey(hkNew);
}
}
else
szTemp[0] = TEXT('\0');
}
else if(cbSize < 5)
szTemp[0] = TEXT('\0');
else
npPtr->fHasSound = TRUE;
npPtr->pszPath = (LPTSTR)LocalAlloc(LPTR, (lstrlen(szTemp)*sizeof(TCHAR)) + sizeof(TCHAR));
if (npPtr->pszPath == NULL)
{
DPF("Failed Alloc\n");
RegCloseKey(hkApp);
return FALSE;
}
lstrcpy(npPtr->pszPath, szTemp);
npPtr->npNextEvent = NULL;
if (!npModule->npList)
{
npModule->npList = npPtr;
npNextPtr = npPtr;
}
else
{
npNextPtr->npNextEvent = npPtr;
npNextPtr = npNextPtr->npNextEvent;
}
}
RegCloseKey(hkApp);
npModule->iNode = 1;
ti.hParent = TVI_ROOT;
if (!gszCmdLineApp[0])
{
if (!lstrcmpi((LPTSTR)npModule->pszLabel, (LPTSTR)gszDefaultApp))
ti.hInsertAfter = TVI_FIRST;
else
ti.hInsertAfter = TVI_LAST;
ti.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
ti.item.iImage = ti.item.iSelectedImage = 0;
ti.item.pszText = npModule->pszLabel;
ti.item.lParam = (LPARAM)npModule;
hti = TreeView_InsertItem(hwndTree, &ti);
if (!hti)
{
DPF("Couldn't add module dataitem\n");
return FALSE;
}
LoadEvents(hwndTree, hti, npModule);
}
else
{
// If a command line app was specified, only show it's events.
if (!lstrcmpi((LPTSTR)npModule->pszLabel, (LPTSTR)gszCmdLineApp))
{
ti.hInsertAfter = TVI_LAST;
ti.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
ti.item.iImage = ti.item.iSelectedImage = 0;
ti.item.pszText = npModule->pszLabel;
ti.item.lParam = (LPARAM)npModule;
hti = TreeView_InsertItem(hwndTree, &ti);
if (!hti)
{
DPF("Couldn't add module dataitem\n");
return FALSE;
}
LoadEvents(hwndTree, hti, npModule);
}
}
return TRUE;
}
/*
***************************************************************
* ClearModules
*
* Description:
* Frees the storage used for mappings, and removes the
* entries in the list box
*
* Parameters:
* HWND hDlg - Dialog window handle.
* BOOL fDisable - If true disable save, remove and browse controls
*
* returns: BOOL
*
***************************************************************
*/
BOOL PASCAL ClearModules(HWND hDlg, HWND hwndTree, BOOL fDisable)
{
PMODULE npModule;
PEVENT npPtr;
PEVENT pEvent;
HTREEITEM hti;
TV_ITEM tvi;
hti = NULL;
for (hti = TreeView_GetRoot(hwndTree); hti; hti = TreeView_GetNextSibling(hwndTree, hti))
{
tvi.mask = TVIF_PARAM;
tvi.hItem = hti;
TreeView_GetItem(hwndTree, &tvi);
npModule = (PMODULE)tvi.lParam;
if (npModule)
{
for (npPtr = npModule->npList; npPtr != NULL;)
{
pEvent = npPtr;
npPtr = npPtr->npNextEvent;
if (pEvent)
{
LocalFree((HLOCAL)pEvent->pszEvent);
LocalFree((HLOCAL)pEvent->pszEventLabel);
if (pEvent->pszPath)
LocalFree((HLOCAL)pEvent->pszPath);
LocalFree((HLOCAL)pEvent);
}
}
LocalFree((HLOCAL)npModule->pszKey);
LocalFree((HLOCAL)npModule->pszLabel);
LocalFree((HLOCAL)npModule);
}
}
gfDeletingTree = TRUE;
SendMessage(hwndTree, WM_SETREDRAW, FALSE, 0L);
TreeView_DeleteAllItems(hwndTree);
SendMessage(hwndTree, WM_SETREDRAW, TRUE, 0L);
gfDeletingTree = FALSE;
//if (hti)
// LocalFree((HLOCAL)szScheme);
return TRUE;
}
/*
***************************************************************
* AddScheme
*
* Description:
* Adds a scheme to the CB_SCHEME combobox
*
* Parameters:
* HWND hDlg - Dialog window handle.
* LPTSTR szLabel -- Printable name of scheme
* LPTSTR szScheme -- registry key for scheme
* BOOL fInsert -- Insert or add
* int iInsert -- position to insert if finsert is set
*
* returns: BOOL
*
***************************************************************
*/
BOOL PASCAL AddScheme(HWND hWndC, LPTSTR szLabel, LPTSTR szScheme,
BOOL fInsert, int iInsert)
{
int iIndex = 0;
LPTSTR pszKey;
pszKey = (LPTSTR)LocalAlloc(LPTR, (lstrlen(szScheme)*sizeof(TCHAR)) + sizeof(TCHAR));
if (pszKey == NULL)
{
DPF("Failed Alloc\n");
return FALSE;
}
lstrcpy(pszKey, szScheme);
if (fInsert)
{
if (ComboBox_InsertString(hWndC, iInsert, szLabel) != CB_ERR)
{
if (ComboBox_SetItemData(hWndC, iInsert,(LPVOID)pszKey) == CB_ERR)
{
DPF("couldn't set itemdata %s\n", (LPTSTR)pszKey);
return FALSE;
}
}
else
{
DPF("couldn't insert %s\n", (LPTSTR)szLabel);
return FALSE;
}
}
else
{
if ((iIndex = ComboBox_AddString(hWndC, szLabel)) != CB_ERR)
{
if (ComboBox_SetItemData(hWndC, iIndex, (LPVOID)pszKey) == CB_ERR)
{
DPF("couldn't set itemdata %s\n", (LPTSTR)pszKey);
return FALSE;
}
}
else
{
DPF("couldn't add %s\n", (LPTSTR)szLabel);
return FALSE;
}
}
return TRUE;
}
/*
***************************************************************
* GetMediaPath
*
* Description:
* Fills in a buffer with the current setting for MediaPath,
* with a trailing backslash (usually "c:\windows\media\" etc).
* If there's no setting (very unlikely), the return buffer
* will be given "".
*
***************************************************************
*/
void PASCAL GetMediaPath (LPTSTR pszMediaPath, size_t cchMax)
{
static TCHAR szMediaPath[ MAX_PATH ] = TEXT("");
if (szMediaPath[0] == TEXT('\0'))
{
HKEY hk;
if (RegOpenKey (HKEY_LOCAL_MACHINE, REGSTR_PATH_SETUP, &hk) == 0)
{
DWORD dwType;
DWORD cb = sizeof(szMediaPath);
if (RegQueryValueEx (hk, REGSTR_VAL_MEDIA, NULL,
&dwType, (LPBYTE)szMediaPath, &cb) != 0)
{
szMediaPath[0] = TEXT('\0');
}
if ( (szMediaPath[0] != TEXT('\0')) &&
(szMediaPath[ lstrlen(szMediaPath)-1 ] != TEXT('\\')) )
{
lstrcat (szMediaPath, TEXT("\\"));
}
RegCloseKey (hk);
}
}
lstrcpyn (pszMediaPath, szMediaPath, cchMax-1);
}
/*
***************************************************************
* RemoveMediaPath
*
* Description:
* Checks to see if a given filename resides within MediaPath;
* if so, yanks its parent path ("c:\win\media\ding.wav" becomes
* just "ding.wav", etc)
*
***************************************************************
*/
void PASCAL RemoveMediaPath (LPTSTR pszTarget, LPTSTR pszSource)
{
TCHAR szMediaPath[ MAX_PATH ] = TEXT("");
GetMediaPath (szMediaPath, MAX_PATH);
if (szMediaPath[0] == TEXT('\0'))
{
lstrcpy (pszTarget, pszSource);
}
else
{
size_t cch = lstrlen (szMediaPath);
if (!lstrnicmp (pszSource, szMediaPath, cch))
{
lstrcpy (pszTarget, &pszSource[ cch ]);
}
else
{
lstrcpy (pszTarget, pszSource);
}
}
}
/*
***************************************************************
* AddMediaPath
*
* Description:
* If the given filename doesn't have a path, prepends the
* current setting of MediaPath to it ("ding.wav"->"c:\win\media\ding.wav")
*
***************************************************************
*/
void PASCAL AddMediaPath (LPTSTR pszTarget, LPTSTR pszSource)
{
if (lstrchr (pszSource, TEXT('\\')) != NULL)
{
lstrcpy (pszTarget, pszSource);
}
else
{
TCHAR szMediaPath[ MAX_PATH ] = TEXT("");
GetMediaPath (szMediaPath, MAX_PATH);
if (szMediaPath[0] == TEXT('\0'))
{
lstrcpy (pszTarget, pszSource);
}
else
{
lstrcpy (pszTarget, szMediaPath);
lstrcat (pszTarget, pszSource);
}
}
}
/*
***************************************************************
* ExRegQueryValue
*
* Description:
* Just a wrapper for RegQueryValue(); this one doesn't choke
* on REG_EXPAND_SZ's.
*
***************************************************************
*/
int ExRegQueryValue (HKEY hkParent, LPTSTR szSubKey, LPBYTE pszBuffer, DWORD *pdwSize)
{
HKEY hkSubKey;
int rc;
if ((rc = RegOpenKey (hkParent, szSubKey, &hkSubKey)) == ERROR_SUCCESS)
{
DWORD dwType;
rc = RegQueryValueEx (hkSubKey, NULL, NULL, &dwType, pszBuffer, pdwSize);
RegCloseKey (hkSubKey);
}
return rc;
}