summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--plugins/AssocMgr/src/assoclist.cpp426
-rw-r--r--plugins/AssocMgr/src/assoclist.h24
-rw-r--r--plugins/AssocMgr/src/reg.cpp73
-rw-r--r--plugins/AssocMgr/src/reg.h2
-rw-r--r--plugins/AssocMgr/src/version.h2
5 files changed, 237 insertions, 290 deletions
diff --git a/plugins/AssocMgr/src/assoclist.cpp b/plugins/AssocMgr/src/assoclist.cpp
index 9b2db86cbd..1604ea27ca 100644
--- a/plugins/AssocMgr/src/assoclist.cpp
+++ b/plugins/AssocMgr/src/assoclist.cpp
@@ -21,26 +21,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "stdafx.h"
-// Options
-static HANDLE hHookOptInit;
-
/************************* Assoc List *****************************/
-typedef struct
-{
- char *pszClassName; // class name as used in registry and db
- wchar_t *pszDescription;
- HINSTANCE hInstance; // allowed to be NULL for miranda32.exe
- WORD nIconResID;
- char *pszService;
- WORD flags; // set of FTDF_* and UTDF_* flags
- char *pszFileExt; // file type: NULL for url type
- char *pszMimeType; // file type: allowed to be NULL
- wchar_t *pszVerbDesc; // file type: allowed to be NULL
-} ASSOCDATA;
-
-static ASSOCDATA *pAssocList; // protected by csAssocList
-static int nAssocListCount; // protected by csAssocList
+static OBJLIST<ASSOCDATA> arAssocList(10, PtrKeySortT);
static mir_cs csAssocList;
/************************* Assoc Enabled **************************/
@@ -135,19 +118,22 @@ static __inline BOOL WasMimeTypeAdded(const char *pszMimeType)
void CleanupMimeTypeAddedSettings(void)
{
int nSettingsCount;
- char **ppszSettings, *pszSuffix;
- DBVARIANT dbv;
- int i, j;
+ char **ppszSettings;
// delete old mime_* settings and unregister the associated mime type
if (EnumDbPrefixSettings(MODULENAME, "mime_", &ppszSettings, &nSettingsCount)) {
mir_cslock lck(csAssocList);
- for (i = 0; i < nSettingsCount; ++i) {
- pszSuffix = &ppszSettings[i][5];
- for (j = 0; j < nAssocListCount; ++j)
- if (!mir_strcmp(pszSuffix, pAssocList[j].pszMimeType))
+ for (int i = 0; i < nSettingsCount; ++i) {
+ char *pszSuffix = &ppszSettings[i][5];
+ ASSOCDATA *p = nullptr;
+ for (auto &it : arAssocList)
+ if (!mir_strcmp(pszSuffix, it->pszMimeType)) {
+ p = it;
break; // mime type in current list
- if (j == nAssocListCount) { // mime type not in current list
+ }
+
+ if (p == nullptr) { // mime type not in current list
+ DBVARIANT dbv;
if (!db_get(NULL, MODULENAME, ppszSettings[i], &dbv)) {
if (dbv.type == DBVT_ASCIIZ)
RemoveRegMimeType(pszSuffix, dbv.pszVal);
@@ -190,71 +176,39 @@ static void NotifyAssocChange(BOOL fNow)
/************************* Assoc List Utils ***********************/
// this function assumes it has got the csAssocList mutex
-static int FindAssocItem(const char *pszClassName)
+static ASSOCDATA* FindAssocItem(const char *pszClassName)
{
- int i;
- for (i = 0; i < nAssocListCount; ++i)
- if (!mir_strcmp(pszClassName, pAssocList[i].pszClassName))
- return i;
- return -1;
+ for (auto &it : arAssocList)
+ if (!mir_strcmp(pszClassName, it->pszClassName))
+ return it;
+
+ return nullptr;
}
BOOL IsRegisteredAssocItem(const char *pszClassName)
{
- int index;
mir_cslock lck(csAssocList);
- index = FindAssocItem(pszClassName);
- return index != -1;
-}
-
-
-// this function assumes it has got the csAssocList mutex
-static ASSOCDATA* CopyAssocItem(const ASSOCDATA *assoc)
-{
- ASSOCDATA *assoc2;
- assoc2 = (ASSOCDATA*)mir_alloc(sizeof(ASSOCDATA));
- if (assoc2 == nullptr) return nullptr;
- assoc2->pszClassName = mir_strdup(assoc->pszClassName);
- assoc2->pszDescription = mir_wstrdup(assoc->pszDescription);
- assoc2->hInstance = assoc->hInstance;
- assoc2->nIconResID = assoc->nIconResID;
- assoc2->pszService = mir_strdup(assoc->pszService);
- assoc2->flags = assoc->flags;
- assoc2->pszFileExt = mir_strdup(assoc->pszFileExt);
- assoc2->pszMimeType = mir_strdup(assoc->pszMimeType);
- assoc2->pszVerbDesc = mir_wstrdup(assoc->pszVerbDesc);
- if (assoc2->pszClassName == nullptr || assoc2->pszDescription == nullptr ||
- (assoc2->pszFileExt == nullptr && assoc->pszFileExt != nullptr)) {
- mir_free(assoc2->pszClassName); // does NULL check
- mir_free(assoc2->pszDescription); // does NULL check
- mir_free(assoc2->pszService); // does NULL check
- mir_free(assoc2->pszFileExt); // does NULL check
- mir_free(assoc2->pszMimeType); // does NULL check
- mir_free(assoc2->pszVerbDesc); // does NULL check
- mir_free(assoc2);
- return nullptr;
- }
- return assoc2;
+ return FindAssocItem(pszClassName) != nullptr;
}
// this function assumes it has got the csAssocList mutex
// this function assumes CoInitialize() has been called before
-static int ReplaceImageListAssocIcon(HIMAGELIST himl, const ASSOCDATA *assoc, int iPrevIndex)
+static int ReplaceImageListAssocIcon(HIMAGELIST himl, ASSOCDATA *assoc, int iPrevIndex)
{
- HICON hIcon = nullptr;
- int index;
- if (himl == nullptr) return -1;
+ if (himl == nullptr)
+ return -1;
// load icon
- hIcon = LoadRegClassSmallIcon(assoc->pszClassName);
+ HICON hIcon = LoadRegClassSmallIcon(assoc);
if (hIcon == nullptr) {
SHFILEINFOA sfi;
if (SHGetFileInfoA((assoc->pszFileExt != nullptr) ? assoc->pszFileExt : "", FILE_ATTRIBUTE_NORMAL, &sfi, sizeof(sfi), SHGFI_ICON | SHGFI_SMALLICON | SHGFI_USEFILEATTRIBUTES))
hIcon = sfi.hIcon; // WinXP: this icon is not updated until the process exits
}
// add icon
- if (hIcon == nullptr) return -1;
- index = ImageList_ReplaceIcon(himl, iPrevIndex, hIcon);
+ if (hIcon == nullptr)
+ return -1;
+ int index = ImageList_ReplaceIcon(himl, iPrevIndex, hIcon);
DestroyIcon(hIcon);
return index;
}
@@ -390,23 +344,15 @@ typedef struct
// ownership of pszClassName, pszFileExt, pszVerbDesc and pszMimeType is transfered
// to the storage list on success
-static BOOL AddNewAssocItem_Worker(char *pszClassName, const TYPEDESCHEAD *tdh, char *pszFileExt, wchar_t *pszVerbDesc, char *pszMimeType)
+static bool AddNewAssocItem_Worker(char *pszClassName, const TYPEDESCHEAD *tdh, char *pszFileExt, wchar_t *pszVerbDesc, char *pszMimeType)
{
- ASSOCDATA *pAssocListBuf, *assoc;
-
// is already in list?
mir_cslock lck(csAssocList);
- int index = FindAssocItem(pszClassName);
- if (index != -1) return FALSE;
-
- // resize storage array
- pAssocListBuf = (ASSOCDATA*)mir_realloc(pAssocList, (nAssocListCount + 1) * sizeof(ASSOCDATA));
- if (pAssocListBuf == nullptr)
- return FALSE;
- pAssocList = pAssocListBuf;
+ if (FindAssocItem(pszClassName) != nullptr)
+ return false;
// init new item
- assoc = &pAssocList[nAssocListCount];
+ ASSOCDATA *assoc = new ASSOCDATA();
assoc->pszClassName = pszClassName; // no dup here
assoc->pszDescription = s2t(tdh->pszDescription, tdh->flags & FTDF_UNICODE, TRUE); // does NULL check
assoc->hInstance = tdh->hInstance; // hInstance is allowed to be NULL for miranda32.exe
@@ -419,31 +365,27 @@ static BOOL AddNewAssocItem_Worker(char *pszClassName, const TYPEDESCHEAD *tdh,
// error check
if (assoc->pszDescription == nullptr || (assoc->pszService == nullptr && tdh->pszService != nullptr)) {
- mir_free(assoc->pszService); // does NULL check
- mir_free(assoc->pszDescription); // does NULL check
- return FALSE;
+ delete assoc;
+ return false;
}
// add registry keys
if (IsAssocEnabled(assoc))
EnsureAssocRegistered(assoc);
- ++nAssocListCount;
- NotifyAssocChange(FALSE);
- return TRUE;
+ arAssocList.insert(assoc);
+ NotifyAssocChange(false);
+ return true;
}
// ownership of pszClassName is *not* transferd to storage list
-static BOOL RemoveAssocItem_Worker(const char *pszClassName)
+static bool RemoveAssocItem_Worker(const char *pszClassName)
{
- ASSOCDATA *pAssocListBuf, *assoc;
-
// find index
mir_cslock lck(csAssocList);
- int index = FindAssocItem(pszClassName);
- if (index == -1)
- return FALSE;
- assoc = &pAssocList[index];
+ ASSOCDATA *assoc = FindAssocItem(pszClassName);
+ if (assoc == nullptr)
+ return false;
// delete registry keys and db setting
UnregisterAssoc(assoc);
@@ -451,20 +393,8 @@ static BOOL RemoveAssocItem_Worker(const char *pszClassName)
RememberMimeTypeAdded(assoc->pszMimeType, assoc->pszFileExt, FALSE);
DeleteAssocEnabledSetting(assoc);
- // free memory
- mir_free(assoc->pszClassName);
- mir_free(assoc->pszDescription);
- mir_free(assoc->pszService);
- mir_free(assoc->pszFileExt); // does NULL check
- mir_free(assoc->pszVerbDesc); // does NULL check
- mir_free(assoc->pszMimeType); // does NULL check
-
// resize storage array
- if ((index + 1) < nAssocListCount)
- memmove(assoc, &pAssocList[index + 1], ((nAssocListCount - index - 1) * sizeof(ASSOCDATA)));
- pAssocListBuf = (ASSOCDATA*)mir_realloc(pAssocList, (nAssocListCount - 1) * sizeof(ASSOCDATA));
- if (pAssocListBuf != nullptr) pAssocList = pAssocListBuf;
- --nAssocListCount;
+ arAssocList.remove(assoc);
NotifyAssocChange(FALSE);
return TRUE;
@@ -545,15 +475,12 @@ static INT_PTR ServiceRemoveUrlType(WPARAM, LPARAM lParam)
static BOOL InvokeHandler_Worker(const char *pszClassName, const wchar_t *pszParam, INT_PTR *res)
{
- void *pvParam;
- char *pszService;
-
// find it in list
mir_cslock lck(csAssocList);
- int index = FindAssocItem(pszClassName);
- if (index == -1)
- return FALSE;
- ASSOCDATA *assoc = &pAssocList[index];
+ ASSOCDATA *assoc = FindAssocItem(pszClassName);
+ if (assoc == nullptr)
+ return false;
+
// no service specified? correct registry to use main commandline
if (assoc->pszService == nullptr) {
EnsureAssocRegistered(assoc);
@@ -563,9 +490,10 @@ static BOOL InvokeHandler_Worker(const char *pszClassName, const wchar_t *pszPar
*res = 0; // success
return TRUE;
}
+
// get params
- pszService = mir_strdup(assoc->pszService);
- pvParam = t2s(pszParam, assoc->flags & FTDF_UNICODE, FALSE);
+ char *pszService = mir_strdup(assoc->pszService);
+ void *pvParam = t2s(pszParam, assoc->flags & FTDF_UNICODE, FALSE);
// call service
if (pszService != nullptr && pvParam != nullptr)
@@ -629,7 +557,7 @@ static int CALLBACK ListViewSortDesc(LPARAM lParam1, LPARAM lParam2, LPARAM lPar
int cmp;
if (((ASSOCDATA*)lParam1)->pszFileExt != nullptr && ((ASSOCDATA*)lParam2)->pszFileExt != nullptr)
cmp = CompareStringA((LCID)lParamSort, 0, ((ASSOCDATA*)lParam1)->pszFileExt, -1, ((ASSOCDATA*)lParam2)->pszFileExt, -1);
- else if (((ASSOCDATA*)lParam1)->pszFileExt == ((ASSOCDATA*)lParam2)->pszFileExt) // both NULL
+ else if (((ASSOCDATA*)lParam1)->pszFileExt.get() == ((ASSOCDATA*)lParam2)->pszFileExt.get()) // both NULL
cmp = CompareStringA((LCID)lParamSort, 0, ((ASSOCDATA*)lParam1)->pszClassName, -1, ((ASSOCDATA*)lParam2)->pszClassName, -1);
else // different types, incomparable
cmp = (((ASSOCDATA*)lParam1)->pszFileExt == nullptr) ? CSTR_LESS_THAN : CSTR_GREATER_THAN;
@@ -643,129 +571,129 @@ static int CALLBACK ListViewSortDesc(LPARAM lParam1, LPARAM lParam2, LPARAM lPar
static INT_PTR CALLBACK AssocListOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
LVITEM lvi;
- ASSOCDATA *assoc;
switch (msg) {
case WM_INITDIALOG:
- {
TranslateDialogDefault(hwndDlg);
CoInitialize(nullptr);
- HWND hwndList = GetDlgItem(hwndDlg, IDC_ASSOCLIST);
-
- ListView_SetUnicodeFormat(hwndList, TRUE);
-
- SendDlgItemMessage(hwndDlg, IDC_HEADERTEXT, WM_SETFONT, SendMessage(GetParent(hwndDlg), PSM_GETBOLDFONT, 0, 0), 0);
- // checkboxes won't show up on Win95 without IE3+ or 4.70 (plugin opts uses the same)
- ListView_SetExtendedListViewStyle(hwndList, LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT | LVS_EX_LABELTIP);
- // columns
- {
- LVCOLUMN lvc;
- lvc.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
- lvc.pszText = TranslateT("Type");
- lvc.cx = 170;
- ListView_InsertColumn(hwndList, lvc.iSubItem = 0, &lvc);
- lvc.pszText = TranslateT("Description");
- ListView_InsertColumn(hwndList, lvc.iSubItem = 1, &lvc);
- }
- // create image storage
- HIMAGELIST himl;
- mir_cslock lck(csAssocList);
{
- HDC hdc = GetDC(hwndList);
- if (hdc != nullptr) { // BITSPIXEL is compatible with ILC_COLOR flags
- himl = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), GetDeviceCaps(hdc, BITSPIXEL) | ILC_MASK, nAssocListCount, 0);
- ReleaseDC(hwndList, hdc);
+ HWND hwndList = GetDlgItem(hwndDlg, IDC_ASSOCLIST);
+
+ ListView_SetUnicodeFormat(hwndList, TRUE);
+
+ SendDlgItemMessage(hwndDlg, IDC_HEADERTEXT, WM_SETFONT, SendMessage(GetParent(hwndDlg), PSM_GETBOLDFONT, 0, 0), 0);
+ // checkboxes won't show up on Win95 without IE3+ or 4.70 (plugin opts uses the same)
+ ListView_SetExtendedListViewStyle(hwndList, LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT | LVS_EX_LABELTIP);
+ // columns
+ {
+ LVCOLUMN lvc;
+ lvc.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
+ lvc.pszText = TranslateT("Type");
+ lvc.cx = 170;
+ ListView_InsertColumn(hwndList, lvc.iSubItem = 0, &lvc);
+ lvc.pszText = TranslateT("Description");
+ ListView_InsertColumn(hwndList, lvc.iSubItem = 1, &lvc);
}
- else himl = nullptr;
- }
- ListView_SetImageList(hwndList, himl, LVSIL_SMALL); // autodestroyed
- // enum assoc list
- lvi.iSubItem = 0;
- lvi.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
- for (int i = 0; i < nAssocListCount; ++i) {
- assoc = &pAssocList[i];
- lvi.iItem = 0;
- lvi.lParam = (LPARAM)CopyAssocItem(assoc);
- lvi.pszText = GetAssocTypeDesc(assoc);
- lvi.iImage = ReplaceImageListAssocIcon(himl, assoc, -1);
- lvi.iItem = ListView_InsertItem(hwndList, &lvi);
- if (lvi.iItem != -1) {
- ListView_SetItemText(hwndList, lvi.iItem, 1, assoc->pszDescription);
- ListView_SetCheckState(hwndList, lvi.iItem, IsAssocEnabled(assoc) && IsAssocRegistered(assoc));
+ // create image storage
+ HIMAGELIST himl;
+ mir_cslock lck(csAssocList);
+ {
+ HDC hdc = GetDC(hwndList);
+ if (hdc != nullptr) { // BITSPIXEL is compatible with ILC_COLOR flags
+ himl = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), GetDeviceCaps(hdc, BITSPIXEL) | ILC_MASK, arAssocList.getCount(), 0);
+ ReleaseDC(hwndList, hdc);
+ }
+ else himl = nullptr;
}
- }
- // sort items (before moving to groups)
- ListView_SortItems(hwndList, ListViewSortDesc, Langpack_GetDefaultLocale());
- // groups
- if (ListView_EnableGroupView(hwndList, TRUE) == 1) { // returns 0 on pre WinXP or if commctls6 are disabled
- LVGROUP lvg;
- int iItem;
- // dummy item for group
- lvi.iItem = ListView_GetItemCount(hwndList) - 1;
+ ListView_SetImageList(hwndList, himl, LVSIL_SMALL); // autodestroyed
+ // enum assoc list
lvi.iSubItem = 0;
- lvi.mask = LVIF_PARAM | LVIF_IMAGE;
- lvi.iImage = -1;
- lvi.lParam = 0;
- // insert groups
- lvg.cbSize = sizeof(lvg);
- lvg.mask = LVGF_HEADER | LVGF_GROUPID;
- lvg.iGroupId = 2;
- lvg.pszHeader = TranslateT("URLs on websites");
- lvi.iItem = ListView_InsertItem(hwndList, &lvi);
- if (lvi.iItem != -1) {
- ListView_InsertGroup(hwndList, lvi.iItem, &lvg);
- lvg.iGroupId = 1;
- lvg.pszHeader = TranslateT("File types");
- iItem = lvi.iItem = ListView_InsertItem(hwndList, &lvi);
- if (lvi.iItem != -1)
+ lvi.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
+ for (auto &it : arAssocList) {
+ lvi.iItem = 0;
+ lvi.lParam = (LPARAM)new ASSOCDATA(*it);
+ lvi.pszText = GetAssocTypeDesc(it);
+ lvi.iImage = ReplaceImageListAssocIcon(himl, it, -1);
+ lvi.iItem = ListView_InsertItem(hwndList, &lvi);
+ if (lvi.iItem != -1) {
+ ListView_SetItemText(hwndList, lvi.iItem, 1, it->pszDescription);
+ ListView_SetCheckState(hwndList, lvi.iItem, IsAssocEnabled(it) && IsAssocRegistered(it));
+ }
+ }
+ // sort items (before moving to groups)
+ ListView_SortItems(hwndList, ListViewSortDesc, Langpack_GetDefaultLocale());
+ // groups
+ if (ListView_EnableGroupView(hwndList, TRUE) == 1) { // returns 0 on pre WinXP or if commctls6 are disabled
+ LVGROUP lvg;
+ int iItem;
+ // dummy item for group
+ lvi.iItem = ListView_GetItemCount(hwndList) - 1;
+ lvi.iSubItem = 0;
+ lvi.mask = LVIF_PARAM | LVIF_IMAGE;
+ lvi.iImage = -1;
+ lvi.lParam = 0;
+ // insert groups
+ lvg.cbSize = sizeof(lvg);
+ lvg.mask = LVGF_HEADER | LVGF_GROUPID;
+ lvg.iGroupId = 2;
+ lvg.pszHeader = TranslateT("URLs on websites");
+ lvi.iItem = ListView_InsertItem(hwndList, &lvi);
+ if (lvi.iItem != -1) {
ListView_InsertGroup(hwndList, lvi.iItem, &lvg);
- else ListView_DeleteItem(hwndList, iItem);
+ lvg.iGroupId = 1;
+ lvg.pszHeader = TranslateT("File types");
+ iItem = lvi.iItem = ListView_InsertItem(hwndList, &lvi);
+ if (lvi.iItem != -1)
+ ListView_InsertGroup(hwndList, lvi.iItem, &lvg);
+ else ListView_DeleteItem(hwndList, iItem);
+ }
+ // move to group
+ lvi.iSubItem = 0;
+ lvi.mask = LVIF_PARAM | LVIF_GROUPID;
+ for (lvi.iItem = 0; ListView_GetItem(hwndList, &lvi); ++lvi.iItem) {
+ ASSOCDATA *assoc = (ASSOCDATA*)lvi.lParam;
+ if (assoc == nullptr)
+ continue; // groups
+ lvi.iGroupId = (assoc->pszFileExt == nullptr) + 1;
+ ListView_SetItem(hwndList, &lvi);
+ }
}
- // move to group
- lvi.iSubItem = 0;
- lvi.mask = LVIF_PARAM | LVIF_GROUPID;
- for (lvi.iItem = 0; ListView_GetItem(hwndList, &lvi); ++lvi.iItem) {
- assoc = (ASSOCDATA*)lvi.lParam;
- if (assoc == nullptr) continue; // groups
- lvi.iGroupId = (assoc->pszFileExt == nullptr) + 1;
- ListView_SetItem(hwndList, &lvi);
+ lvi.iItem = ListView_GetTopIndex(hwndList);
+ ListView_SetItemState(hwndList, lvi.iItem, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
+ ListView_SetColumnWidth(hwndList, 1, LVSCW_AUTOSIZE_USEHEADER); // size to fit window
+ // only while running
+ CheckDlgButton(hwndDlg, IDC_ONLYWHILERUNNING, (BOOL)db_get_b(NULL, MODULENAME, "OnlyWhileRunning", SETTING_ONLYWHILERUNNING_DEFAULT) ? BST_CHECKED : BST_UNCHECKED);
+
+ // autostart
+ wchar_t *pszRunCmd = MakeRunCommand(TRUE, TRUE);
+ if (pszRunCmd != nullptr) {
+ CheckDlgButton(hwndDlg, IDC_AUTOSTART, IsRegRunEntry(L"MirandaNG", pszRunCmd) ? BST_CHECKED : BST_UNCHECKED);
+ mir_free(pszRunCmd);
}
}
- lvi.iItem = ListView_GetTopIndex(hwndList);
- ListView_SetItemState(hwndList, lvi.iItem, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
- ListView_SetColumnWidth(hwndList, 1, LVSCW_AUTOSIZE_USEHEADER); // size to fit window
- // only while running
- CheckDlgButton(hwndDlg, IDC_ONLYWHILERUNNING, (BOOL)db_get_b(NULL, MODULENAME, "OnlyWhileRunning", SETTING_ONLYWHILERUNNING_DEFAULT) ? BST_CHECKED : BST_UNCHECKED);
-
- // autostart
- wchar_t *pszRunCmd = MakeRunCommand(TRUE, TRUE);
- if (pszRunCmd != nullptr) {
- CheckDlgButton(hwndDlg, IDC_AUTOSTART, IsRegRunEntry(L"MirandaNG", pszRunCmd) ? BST_CHECKED : BST_UNCHECKED);
- mir_free(pszRunCmd);
- }
- }
- return TRUE;
+ return TRUE;
case WM_SETTINGCHANGE:
case M_REFRESH_ICONS:
- {
- HWND hwndList = GetDlgItem(hwndDlg, IDC_ASSOCLIST);
- HIMAGELIST himl = ListView_GetImageList(hwndList, LVSIL_SMALL);
- // enum items
- lvi.iSubItem = 0;
- lvi.mask = LVIF_PARAM | LVIF_IMAGE;
- for (lvi.iItem = 0; ListView_GetItem(hwndList, &lvi); ++lvi.iItem) {
- assoc = (ASSOCDATA*)lvi.lParam;
- if (assoc == nullptr) continue; // groups
- lvi.iImage = ReplaceImageListAssocIcon(himl, assoc, lvi.iImage);
- ListView_SetItem(hwndList, &lvi);
- }
- if (lvi.iItem) { // ListView_Update() blinks
- ListView_RedrawItems(hwndList, 0, lvi.iItem - 1);
- UpdateWindow(hwndList);
+ {
+ HWND hwndList = GetDlgItem(hwndDlg, IDC_ASSOCLIST);
+ HIMAGELIST himl = ListView_GetImageList(hwndList, LVSIL_SMALL);
+ // enum items
+ lvi.iSubItem = 0;
+ lvi.mask = LVIF_PARAM | LVIF_IMAGE;
+ for (lvi.iItem = 0; ListView_GetItem(hwndList, &lvi); ++lvi.iItem) {
+ ASSOCDATA *assoc = (ASSOCDATA*)lvi.lParam;
+ if (assoc == nullptr)
+ continue; // groups
+ lvi.iImage = ReplaceImageListAssocIcon(himl, assoc, lvi.iImage);
+ ListView_SetItem(hwndList, &lvi);
+ }
+ if (lvi.iItem) { // ListView_Update() blinks
+ ListView_RedrawItems(hwndList, 0, lvi.iItem - 1);
+ UpdateWindow(hwndList);
+ }
}
- }
- return TRUE;
+ return TRUE;
case WM_CTLCOLORSTATIC:
// use same text color for header as for group boxes (WinXP+)
@@ -782,6 +710,19 @@ static INT_PTR CALLBACK AssocListOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wPara
}
break;
+ case WM_DESTROY:
+ {
+ HWND hwndList = GetDlgItem(hwndDlg, IDC_ASSOCLIST);
+ lvi.iSubItem = 0;
+ lvi.mask = LVIF_PARAM;
+ mir_cslock lck(csAssocList);
+ for (lvi.iItem = 0; ListView_GetItem(hwndList, &lvi); ++lvi.iItem) {
+ ASSOCDATA *assoc = (ASSOCDATA*)lvi.lParam;
+ delete assoc;
+ }
+ }
+ break;
+
case WM_NCDESTROY:
CoUninitialize();
return TRUE;
@@ -870,8 +811,9 @@ static INT_PTR CALLBACK AssocListOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wPara
lvi.mask = LVIF_PARAM;
mir_cslock lck(csAssocList);
for (lvi.iItem = 0; ListView_GetItem(hwndList, &lvi); ++lvi.iItem) {
- assoc = (ASSOCDATA*)lvi.lParam;
- if (assoc == nullptr) continue; // groups
+ ASSOCDATA *assoc = (ASSOCDATA*)lvi.lParam;
+ if (assoc == nullptr)
+ continue; // groups
fEnabled = ListView_GetCheckState(hwndList, lvi.iItem);
SetAssocEnabled(assoc, fEnabled);
@@ -930,11 +872,7 @@ void InitAssocList(void)
icc.dwSize = sizeof(icc);
icc.dwICC = ICC_LISTVIEW_CLASSES;
InitCommonControlsEx(&icc);
- hHookOptInit = HookEvent(ME_OPT_INITIALISE, AssocListOptInit);
-
- // Assoc List
- pAssocList = nullptr;
- nAssocListCount = 0;
+ HookEvent(ME_OPT_INITIALISE, AssocListOptInit);
// Services
CreateServiceFunction(MS_ASSOCMGR_ADDNEWFILETYPE, ServiceAddNewFileType);
@@ -986,30 +924,16 @@ void InitAssocList(void)
void UninitAssocList(void)
{
- // Options
- UnhookEvent(hHookOptInit);
-
// Assoc List
BYTE fOnlyWhileRunning = db_get_b(NULL, MODULENAME, "OnlyWhileRunning", SETTING_ONLYWHILERUNNING_DEFAULT);
- for (int i = 0; i < nAssocListCount; ++i) {
- ASSOCDATA *assoc = &pAssocList[i];
-
- // remove registry keys
+ for (auto &it : arAssocList)
if (fOnlyWhileRunning)
- UnregisterAssoc(assoc);
-
- mir_free(assoc->pszClassName);
- mir_free(assoc->pszDescription);
- mir_free(assoc->pszService);
- mir_free(assoc->pszFileExt);
- mir_free(assoc->pszVerbDesc);
- mir_free(assoc->pszMimeType);
- }
- mir_free(pAssocList);
+ UnregisterAssoc(it); // remove registry keys
// Notify Shell
- if (fOnlyWhileRunning && nAssocListCount)
+ if (fOnlyWhileRunning && arAssocList.getCount())
NotifyAssocChange(TRUE);
+ arAssocList.destroy();
// unregister open-with app
if (fOnlyWhileRunning) {
diff --git a/plugins/AssocMgr/src/assoclist.h b/plugins/AssocMgr/src/assoclist.h
index 8afaeebe70..08b8d0a34e 100644
--- a/plugins/AssocMgr/src/assoclist.h
+++ b/plugins/AssocMgr/src/assoclist.h
@@ -21,6 +21,30 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#pragma once
+struct ASSOCDATA : public MZeroedObject
+{
+ ASSOCDATA() {}
+
+ ASSOCDATA(const ASSOCDATA &p) :
+ pszClassName(mir_strdup(p.pszClassName)),
+ pszDescription(mir_wstrdup(p.pszDescription)),
+ pszService(mir_strdup(p.pszService)),
+ pszFileExt(mir_strdup(p.pszFileExt)),
+ pszMimeType(mir_strdup(p.pszMimeType)),
+ pszVerbDesc(mir_wstrdup(p.pszVerbDesc))
+ {}
+
+ ptrA pszClassName; // class name as used in registry and db
+ ptrW pszDescription;
+ HINSTANCE hInstance; // allowed to be NULL for miranda32.exe
+ WORD nIconResID;
+ ptrA pszService;
+ WORD flags; // set of FTDF_* and UTDF_* flags
+ ptrA pszFileExt; // file type: NULL for url type
+ ptrA pszMimeType; // file type: allowed to be NULL
+ ptrW pszVerbDesc; // file type: allowed to be NULL
+};
+
/* Assoc Enabled */
void CleanupAssocEnabledSettings(void);
/* Mime Reg */
diff --git a/plugins/AssocMgr/src/reg.cpp b/plugins/AssocMgr/src/reg.cpp
index 5a96d02582..b6ecad1a0b 100644
--- a/plugins/AssocMgr/src/reg.cpp
+++ b/plugins/AssocMgr/src/reg.cpp
@@ -754,21 +754,21 @@ BOOL IsRegClass(const char *pszClassName, const wchar_t *pszRunCmd)
*/
// DestroyIcon() the return value
-HICON LoadRegClassSmallIcon(const char *pszClassName)
+HICON LoadRegClassSmallIcon(ASSOCDATA *assoc)
{
- HICON hIcon = nullptr;
- HKEY hClassKey, hIconKey;
- wchar_t *pszIconLoc, *p;
+ HICON hIcon = LoadIcon(assoc->hInstance, MAKEINTRESOURCE(assoc->nIconResID));
+ if (hIcon != nullptr)
+ return hIcon;
- // using the merged view classes key for reading
- // class
- if (!RegOpenKeyExA(HKEY_CLASSES_ROOT, pszClassName, 0, KEY_QUERY_VALUE, &hClassKey)) {
+ // using the merged view classes key for reading class
+ HKEY hClassKey, hIconKey;
+ if (!RegOpenKeyExA(HKEY_CLASSES_ROOT, assoc->pszClassName, 0, KEY_QUERY_VALUE, &hClassKey)) {
// default icon
if (!RegOpenKeyEx(hClassKey, L"DefaultIcon", 0, KEY_QUERY_VALUE, &hIconKey)) {
// extract icon
- pszIconLoc = GetRegStrValue(hIconKey, nullptr);
+ wchar_t *pszIconLoc = GetRegStrValue(hIconKey, nullptr);
if (pszIconLoc != nullptr) {
- p = wcsrchr(pszIconLoc, ',');
+ wchar_t *p = wcsrchr(pszIconLoc, ',');
if (p != nullptr) {
*(p++) = 0;
ExtractIconEx(pszIconLoc, _wtoi(p), nullptr, &hIcon, 1);
@@ -797,13 +797,13 @@ HICON LoadRegClassSmallIcon(const char *pszClassName)
BOOL AddRegFileExt(const char *pszFileExt, const char *pszClassName, const char *pszMimeType, BOOL fIsText)
{
BOOL fSuccess = FALSE;
- HKEY hRootKey, hExtKey, hOpenWithKey;
// some error checking for disallowed values (to avoid errors in registry)
if (strchr(pszFileExt, '\\') != nullptr || strchr(pszFileExt, ' ') != nullptr)
return FALSE;
// try to open interactive user's classes key
+ HKEY hRootKey, hExtKey, hOpenWithKey;
if (RegOpenKeyEx(HKEY_CURRENT_USER, L"Software\\Classes", 0, KEY_CREATE_SUB_KEY, &hRootKey))
hRootKey = HKEY_CLASSES_ROOT;
@@ -838,18 +838,17 @@ BOOL AddRegFileExt(const char *pszFileExt, const char *pszClassName, const char
void RemoveRegFileExt(const char *pszFileExt, const char *pszClassName)
{
- HKEY hRootKey, hExtKey, hSubKey;
- DWORD nOpenWithCount;
- wchar_t *pszPrevClassName = nullptr;
BOOL fRestored = FALSE;
// try to open interactive user's classes key
+ HKEY hRootKey, hExtKey, hSubKey;
if (RegOpenKeyEx(HKEY_CURRENT_USER, L"Software\\Classes", 0, DELETE, &hRootKey))
hRootKey = HKEY_CLASSES_ROOT;
// file ext
if (!RegOpenKeyExA(hRootKey, pszFileExt, 0, KEY_QUERY_VALUE | KEY_SET_VALUE | DELETE, &hExtKey)) {
// class name (the important part)
+ wchar_t *pszPrevClassName = nullptr;
if (!RestoreRegTree(hRootKey, pszFileExt, "bak_")) {
pszPrevClassName = GetRegStrValue(hExtKey, nullptr);
if (pszPrevClassName != nullptr) {
@@ -863,20 +862,25 @@ void RemoveRegFileExt(const char *pszFileExt, const char *pszClassName)
mir_free(pszPrevClassName);
}
}
- if (pszPrevClassName == nullptr) RegDeleteValue(hExtKey, nullptr);
+
+ if (pszPrevClassName == nullptr)
+ RegDeleteValue(hExtKey, nullptr);
+
// open with progids (remove if empty)
- nOpenWithCount = 0;
+ DWORD nOpenWithCount = 0;
if (!RegOpenKeyEx(hExtKey, L"OpenWithProgids", 0, KEY_SET_VALUE | KEY_QUERY_VALUE, &hSubKey)) {
// remove current class (if set by another app)
RegDeleteValueA(hSubKey, pszClassName);
RegQueryInfoKey(hSubKey, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, &nOpenWithCount, nullptr, nullptr, nullptr);
RegCloseKey(hSubKey);
}
- if (!nOpenWithCount) RegDeleteKey(hExtKey, L"OpenWithProgids"); // delete if no values
+ if (!nOpenWithCount)
+ RegDeleteKey(hExtKey, L"OpenWithProgids"); // delete if no values
RegCloseKey(hExtKey);
}
else DeleteRegTreeBackup(pszFileExt, "bak_");
- if (!fRestored) RegDeleteKeyA(hRootKey, pszFileExt); // try to remove it all
+ if (!fRestored)
+ RegDeleteKeyA(hRootKey, pszFileExt); // try to remove it all
if (hRootKey != HKEY_CLASSES_ROOT)
RegCloseKey(hRootKey);
@@ -891,10 +895,9 @@ void RemoveRegFileExt(const char *pszFileExt, const char *pszClassName)
BOOL IsRegFileExt(const char *pszFileExt, const char *pszClassName)
{
BOOL fSuccess = FALSE;
- HKEY hExtKey;
- // using the merged view classes key for reading
- // file ext
+ // using the merged view classes key for reading file ext
+ HKEY hExtKey;
if (!RegOpenKeyExA(HKEY_CLASSES_ROOT, pszFileExt, 0, KEY_QUERY_VALUE, &hExtKey)) {
// class name
// it is enough to check if the class is right
@@ -915,9 +918,9 @@ BOOL IsRegFileExt(const char *pszFileExt, const char *pszClassName)
BOOL AddRegMimeType(const char *pszMimeType, const char *pszFileExt)
{
BOOL fSuccess = FALSE;
- HKEY hRootKey, hDbKey, hTypeKey;
// some error checking for disallowed values (to avoid errors in registry)
+ HKEY hRootKey, hDbKey, hTypeKey;
if (strchr(pszMimeType, '\\') != nullptr || strchr(pszMimeType, ' ') != nullptr)
return FALSE;
@@ -944,22 +947,23 @@ BOOL AddRegMimeType(const char *pszMimeType, const char *pszFileExt)
void RemoveRegMimeType(const char *pszMimeType, const char *pszFileExt)
{
- HKEY hRootKey, hDbKey, hTypeKey;
- BOOL fDelete = TRUE;
-
// try to open interactive user's classes key
+ HKEY hRootKey, hDbKey, hTypeKey;
if (RegOpenKeyEx(HKEY_CURRENT_USER, L"Software\\Classes", 0, KEY_QUERY_VALUE, &hRootKey))
hRootKey = HKEY_CLASSES_ROOT;
// database
if (!RegOpenKeyEx(hRootKey, L"MIME\\Database\\Content Type", 0, DELETE, &hDbKey)) {
+ BOOL fDelete = TRUE;
+
// mime type
if (!RegOpenKeyExA(hDbKey, pszMimeType, 0, KEY_QUERY_VALUE, &hTypeKey)) {
// file ext
fDelete = IsRegStrValueA(hTypeKey, L"Extension", pszFileExt);
RegCloseKey(hTypeKey);
}
- if (fDelete) RegDeleteKeyA(hDbKey, pszMimeType);
+ if (fDelete)
+ RegDeleteKeyA(hDbKey, pszMimeType);
RegCloseKey(hDbKey);
}
@@ -976,9 +980,8 @@ void RemoveRegMimeType(const char *pszMimeType, const char *pszFileExt)
// pszDdeCmd is allowed to be NULL
void AddRegOpenWith(const wchar_t *pszAppFileName, BOOL fAllowOpenWith, const wchar_t *pszAppName, const wchar_t *pszIconLoc, const wchar_t *pszRunCmd, const wchar_t *pszDdeCmd, const wchar_t *pszDdeApp, const wchar_t *pszDdeTopic)
{
- HKEY hRootKey, hAppsKey, hExeKey, hShellKey, hVerbKey, hDdeKey;
-
// try to open interactive user's classes key
+ HKEY hRootKey, hAppsKey, hExeKey, hShellKey, hVerbKey, hDdeKey;
if (RegOpenKeyEx(HKEY_CURRENT_USER, L"Software\\Classes", 0, KEY_QUERY_VALUE, &hRootKey))
hRootKey = HKEY_CLASSES_ROOT;
@@ -1029,9 +1032,8 @@ void AddRegOpenWith(const wchar_t *pszAppFileName, BOOL fAllowOpenWith, const wc
void RemoveRegOpenWith(const wchar_t *pszAppFileName)
{
- HKEY hRootKey, hAppsKey, hExeKey, hShellKey, hVerbKey, hDdeKey;
-
// try to open interactive user's classes key
+ HKEY hRootKey, hAppsKey, hExeKey, hShellKey, hVerbKey, hDdeKey;
if (RegOpenKeyEx(HKEY_CURRENT_USER, L"Software\\Classes", 0, KEY_QUERY_VALUE, &hRootKey))
hRootKey = HKEY_CLASSES_ROOT;
@@ -1080,9 +1082,8 @@ void RemoveRegOpenWith(const wchar_t *pszAppFileName)
void AddRegOpenWithExtEntry(const wchar_t *pszAppFileName, const char *pszFileExt, const wchar_t *pszFileDesc)
{
- HKEY hRootKey, hAppsKey, hExeKey, hTypesKey;
-
// try to open interactive user's classes key
+ HKEY hRootKey, hAppsKey, hExeKey, hTypesKey;
if (RegOpenKeyEx(HKEY_CURRENT_USER, L"Software\\Classes", 0, KEY_QUERY_VALUE, &hRootKey))
hRootKey = HKEY_CLASSES_ROOT;
@@ -1109,9 +1110,8 @@ void AddRegOpenWithExtEntry(const wchar_t *pszAppFileName, const char *pszFileEx
void RemoveRegOpenWithExtEntry(const wchar_t *pszAppFileName, const char *pszFileExt)
{
- HKEY hRootKey, hAppsKey, hExeKey, hTypesKey;
-
// try to open interactive user's classes key
+ HKEY hRootKey, hAppsKey, hExeKey, hTypesKey;
if (RegOpenKeyEx(HKEY_CURRENT_USER, L"Software\\Classes", 0, KEY_QUERY_VALUE, &hRootKey))
hRootKey = HKEY_CLASSES_ROOT;
@@ -1142,9 +1142,9 @@ void RemoveRegOpenWithExtEntry(const wchar_t *pszAppFileName, const char *pszFil
BOOL AddRegRunEntry(const wchar_t *pszAppName, const wchar_t *pszRunCmd)
{
BOOL fSuccess = FALSE;
- HKEY hRunKey;
// run
+ HKEY hRunKey;
if (!RegCreateKeyEx(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, nullptr, 0, KEY_SET_VALUE, nullptr, &hRunKey, nullptr)) {
// appname
fSuccess = !RegSetValueEx(hRunKey, pszAppName, 0, REG_SZ, (BYTE*)pszRunCmd, (int)(mir_wstrlen(pszRunCmd) + 1) * sizeof(wchar_t));
@@ -1155,9 +1155,8 @@ BOOL AddRegRunEntry(const wchar_t *pszAppName, const wchar_t *pszRunCmd)
BOOL RemoveRegRunEntry(const wchar_t *pszAppName, const wchar_t *pszRunCmd)
{
- HKEY hRunKey;
-
// run
+ HKEY hRunKey;
LONG res = RegOpenKeyEx(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, KEY_QUERY_VALUE | KEY_SET_VALUE, &hRunKey);
if (!res) {
// appname
@@ -1175,9 +1174,9 @@ BOOL RemoveRegRunEntry(const wchar_t *pszAppName, const wchar_t *pszRunCmd)
BOOL IsRegRunEntry(const wchar_t *pszAppName, const wchar_t *pszRunCmd)
{
BOOL fState = FALSE;
- HKEY hRunKey;
// Run
+ HKEY hRunKey;
if (!RegOpenKeyEx(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, KEY_QUERY_VALUE, &hRunKey)) {
// appname
fState = IsRegStrValue(hRunKey, pszAppName, pszRunCmd);
diff --git a/plugins/AssocMgr/src/reg.h b/plugins/AssocMgr/src/reg.h
index 5cd27c7a33..e82b4376ea 100644
--- a/plugins/AssocMgr/src/reg.h
+++ b/plugins/AssocMgr/src/reg.h
@@ -27,7 +27,7 @@ void CleanupRegTreeBackupSettings(void);
BOOL AddRegClass(const char *pszClassName,const wchar_t *pszTypeDescription,const wchar_t *pszIconLoc,const wchar_t *pszAppName,const wchar_t *pszRunCmd,const wchar_t *pszDdeCmd,const wchar_t *pszDdeApp,const wchar_t *pszDdeTopic,const wchar_t *pszVerbDesc,BOOL fBrowserAutoOpen,BOOL fUrlProto,BOOL fIsShortcut);
BOOL RemoveRegClass(const char *pszClassName);
BOOL IsRegClass(const char *pszClassName,const wchar_t *pszRunCmd);
-HICON LoadRegClassSmallIcon(const char *pszClassName);
+HICON LoadRegClassSmallIcon(struct ASSOCDATA *pszClassName);
/* Extension */
BOOL AddRegFileExt(const char *pszFileExt,const char *pszClassName,const char *pszMimeType,BOOL fIsText);
void RemoveRegFileExt(const char *pszFileExt,const char *pszClassName);
diff --git a/plugins/AssocMgr/src/version.h b/plugins/AssocMgr/src/version.h
index 34cd557e93..9aecdd58f2 100644
--- a/plugins/AssocMgr/src/version.h
+++ b/plugins/AssocMgr/src/version.h
@@ -22,7 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define __MAJOR_VERSION 0
#define __MINOR_VERSION 2
#define __RELEASE_NUM 1
-#define __BUILD_NUM 0
+#define __BUILD_NUM 1
#include <stdver.h>