appwiz.cpl: Convert the application list to a standard Wine list.
This commit is contained in:
parent
2f9927b8ab
commit
7a041d5209
|
@ -27,8 +27,6 @@
|
|||
|
||||
#include "config.h"
|
||||
#include "wine/port.h"
|
||||
#include "wine/unicode.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -44,6 +42,9 @@
|
|||
#include <commdlg.h>
|
||||
#include <cpl.h>
|
||||
|
||||
#include "wine/unicode.h"
|
||||
#include "wine/list.h"
|
||||
#include "wine/debug.h"
|
||||
#include "appwiz.h"
|
||||
#include "res.h"
|
||||
|
||||
|
@ -52,7 +53,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(appwizcpl);
|
|||
/* define a maximum length for various buffers we use */
|
||||
#define MAX_STRING_LEN 1024
|
||||
|
||||
typedef struct APPINFO {
|
||||
typedef struct APPINFO
|
||||
{
|
||||
struct list entry;
|
||||
int id;
|
||||
|
||||
LPWSTR title;
|
||||
|
@ -67,11 +70,9 @@ typedef struct APPINFO {
|
|||
|
||||
HKEY regroot;
|
||||
WCHAR regkey[MAX_STRING_LEN];
|
||||
|
||||
struct APPINFO *next;
|
||||
} APPINFO;
|
||||
|
||||
static struct APPINFO *AppInfo = NULL;
|
||||
static struct list app_list = LIST_INIT( app_list );
|
||||
HINSTANCE hInst;
|
||||
|
||||
static WCHAR btnRemove[MAX_STRING_LEN];
|
||||
|
@ -131,19 +132,13 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason,
|
|||
*/
|
||||
static void FreeAppInfo(APPINFO *info)
|
||||
{
|
||||
while (info)
|
||||
{
|
||||
APPINFO *next_info = info->next;
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, info->title);
|
||||
HeapFree(GetProcessHeap(), 0, info->path);
|
||||
HeapFree(GetProcessHeap(), 0, info->path_modify);
|
||||
HeapFree(GetProcessHeap(), 0, info->icon);
|
||||
HeapFree(GetProcessHeap(), 0, info->publisher);
|
||||
HeapFree(GetProcessHeap(), 0, info->version);
|
||||
HeapFree(GetProcessHeap(), 0, info);
|
||||
info = next_info;
|
||||
}
|
||||
HeapFree(GetProcessHeap(), 0, info->title);
|
||||
HeapFree(GetProcessHeap(), 0, info->path);
|
||||
HeapFree(GetProcessHeap(), 0, info->path_modify);
|
||||
HeapFree(GetProcessHeap(), 0, info->icon);
|
||||
HeapFree(GetProcessHeap(), 0, info->publisher);
|
||||
HeapFree(GetProcessHeap(), 0, info->version);
|
||||
HeapFree(GetProcessHeap(), 0, info);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
@ -162,7 +157,7 @@ static BOOL ReadApplicationsFromRegistry(HKEY root)
|
|||
WCHAR subKeyName[256];
|
||||
WCHAR key_app[MAX_STRING_LEN];
|
||||
WCHAR *p, *command;
|
||||
APPINFO *iter = AppInfo;
|
||||
APPINFO *info = NULL;
|
||||
LPWSTR iconPtr;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
|
@ -176,12 +171,6 @@ static BOOL ReadApplicationsFromRegistry(HKEY root)
|
|||
|
||||
sizeOfSubKeyName = sizeof(subKeyName) / sizeof(subKeyName[0]);
|
||||
|
||||
if (iter)
|
||||
{
|
||||
/* find the end of the list */
|
||||
for (iter = AppInfo; iter->next; iter = iter->next);
|
||||
}
|
||||
|
||||
for (i = 0; RegEnumKeyExW(hkeyUninst, i, subKeyName, &sizeOfSubKeyName, NULL,
|
||||
NULL, NULL, NULL) != ERROR_NO_MORE_ITEMS; ++i)
|
||||
{
|
||||
|
@ -213,33 +202,15 @@ static BOOL ReadApplicationsFromRegistry(HKEY root)
|
|||
continue;
|
||||
}
|
||||
|
||||
/* if we already have iter, allocate the next entry */
|
||||
if (iter)
|
||||
{
|
||||
iter->next = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||
sizeof(struct APPINFO));
|
||||
info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct APPINFO));
|
||||
if (!info) goto err;
|
||||
|
||||
if (!iter->next)
|
||||
goto err;
|
||||
info->title = HeapAlloc(GetProcessHeap(), 0, displen);
|
||||
|
||||
iter = iter->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* if not, start the list */
|
||||
iter = AppInfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||
sizeof(struct APPINFO));
|
||||
|
||||
if (!iter)
|
||||
goto err;
|
||||
}
|
||||
|
||||
iter->title = HeapAlloc(GetProcessHeap(), 0, displen);
|
||||
|
||||
if (!iter->title)
|
||||
if (!info->title)
|
||||
goto err;
|
||||
|
||||
RegQueryValueExW(hkeyApp, DisplayNameW, 0, 0, (LPBYTE)iter->title,
|
||||
RegQueryValueExW(hkeyApp, DisplayNameW, 0, 0, (LPBYTE)info->title,
|
||||
&displen);
|
||||
|
||||
/* now get DisplayIcon */
|
||||
|
@ -247,24 +218,24 @@ static BOOL ReadApplicationsFromRegistry(HKEY root)
|
|||
RegQueryValueExW(hkeyApp, DisplayIconW, 0, 0, NULL, &displen);
|
||||
|
||||
if (displen == 0)
|
||||
iter->icon = 0;
|
||||
info->icon = 0;
|
||||
else
|
||||
{
|
||||
iter->icon = HeapAlloc(GetProcessHeap(), 0, displen);
|
||||
info->icon = HeapAlloc(GetProcessHeap(), 0, displen);
|
||||
|
||||
if (!iter->icon)
|
||||
if (!info->icon)
|
||||
goto err;
|
||||
|
||||
RegQueryValueExW(hkeyApp, DisplayIconW, 0, 0, (LPBYTE)iter->icon,
|
||||
RegQueryValueExW(hkeyApp, DisplayIconW, 0, 0, (LPBYTE)info->icon,
|
||||
&displen);
|
||||
|
||||
/* separate the index from the icon name, if supplied */
|
||||
iconPtr = strchrW(iter->icon, ',');
|
||||
iconPtr = strchrW(info->icon, ',');
|
||||
|
||||
if (iconPtr)
|
||||
{
|
||||
*iconPtr++ = 0;
|
||||
iter->iconIdx = atoiW(iconPtr);
|
||||
info->iconIdx = atoiW(iconPtr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -272,24 +243,24 @@ static BOOL ReadApplicationsFromRegistry(HKEY root)
|
|||
if (RegQueryValueExW(hkeyApp, PublisherW, 0, 0, NULL, &displen) ==
|
||||
ERROR_SUCCESS)
|
||||
{
|
||||
iter->publisher = HeapAlloc(GetProcessHeap(), 0, displen);
|
||||
info->publisher = HeapAlloc(GetProcessHeap(), 0, displen);
|
||||
|
||||
if (!iter->publisher)
|
||||
if (!info->publisher)
|
||||
goto err;
|
||||
|
||||
RegQueryValueExW(hkeyApp, PublisherW, 0, 0, (LPBYTE)iter->publisher,
|
||||
RegQueryValueExW(hkeyApp, PublisherW, 0, 0, (LPBYTE)info->publisher,
|
||||
&displen);
|
||||
}
|
||||
|
||||
if (RegQueryValueExW(hkeyApp, DisplayVersionW, 0, 0, NULL, &displen) ==
|
||||
ERROR_SUCCESS)
|
||||
{
|
||||
iter->version = HeapAlloc(GetProcessHeap(), 0, displen);
|
||||
info->version = HeapAlloc(GetProcessHeap(), 0, displen);
|
||||
|
||||
if (!iter->version)
|
||||
if (!info->version)
|
||||
goto err;
|
||||
|
||||
RegQueryValueExW(hkeyApp, DisplayVersionW, 0, 0, (LPBYTE)iter->version,
|
||||
RegQueryValueExW(hkeyApp, DisplayVersionW, 0, 0, (LPBYTE)info->version,
|
||||
&displen);
|
||||
}
|
||||
|
||||
|
@ -304,10 +275,9 @@ static BOOL ReadApplicationsFromRegistry(HKEY root)
|
|||
dwNoModify = 0;
|
||||
}
|
||||
|
||||
/* Some installers incorrectly create a REG_SZ instead of a REG_DWORD - check for
|
||||
ASCII 49, which equals 1 */
|
||||
/* Some installers incorrectly create a REG_SZ instead of a REG_DWORD */
|
||||
if (dwType == REG_SZ)
|
||||
dwNoModify = (dwNoModify == 49) ? 1 : 0;
|
||||
dwNoModify = (*(BYTE *)&dwNoModify == '1');
|
||||
|
||||
/* Fetch the modify path */
|
||||
if (!dwNoModify)
|
||||
|
@ -318,22 +288,23 @@ static BOOL ReadApplicationsFromRegistry(HKEY root)
|
|||
static const WCHAR fmtW[] = {'m','s','i','e','x','e','c',' ','/','i','%','s',0};
|
||||
int len = lstrlenW(fmtW) + lstrlenW(subKeyName);
|
||||
|
||||
if (!(iter->path_modify = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)))) goto err;
|
||||
wsprintfW(iter->path_modify, fmtW, subKeyName);
|
||||
if (!(info->path_modify = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)))) goto err;
|
||||
wsprintfW(info->path_modify, fmtW, subKeyName);
|
||||
}
|
||||
else if (!RegQueryValueExW(hkeyApp, ModifyPathW, 0, 0, NULL, &displen))
|
||||
{
|
||||
if (!(iter->path_modify = HeapAlloc(GetProcessHeap(), 0, displen))) goto err;
|
||||
RegQueryValueExW(hkeyApp, ModifyPathW, 0, 0, (LPBYTE)iter->path_modify, &displen);
|
||||
if (!(info->path_modify = HeapAlloc(GetProcessHeap(), 0, displen))) goto err;
|
||||
RegQueryValueExW(hkeyApp, ModifyPathW, 0, 0, (LPBYTE)info->path_modify, &displen);
|
||||
}
|
||||
}
|
||||
|
||||
/* registry key */
|
||||
iter->regroot = root;
|
||||
lstrcpyW(iter->regkey, subKeyName);
|
||||
iter->path = command;
|
||||
info->regroot = root;
|
||||
lstrcpyW(info->regkey, subKeyName);
|
||||
info->path = command;
|
||||
|
||||
iter->id = id++;
|
||||
info->id = id++;
|
||||
list_add_tail( &app_list, &info->entry );
|
||||
}
|
||||
|
||||
RegCloseKey(hkeyApp);
|
||||
|
@ -345,7 +316,7 @@ static BOOL ReadApplicationsFromRegistry(HKEY root)
|
|||
|
||||
err:
|
||||
RegCloseKey(hkeyApp);
|
||||
FreeAppInfo(iter);
|
||||
if (info) FreeAppInfo(info);
|
||||
|
||||
end:
|
||||
RegCloseKey(hkeyUninst);
|
||||
|
@ -365,7 +336,7 @@ static void AddApplicationsToList(HWND hWnd, HIMAGELIST hList)
|
|||
HICON hIcon;
|
||||
int index;
|
||||
|
||||
for (iter = AppInfo; iter; iter = iter->next)
|
||||
LIST_FOR_EACH_ENTRY( iter, &app_list, APPINFO, entry )
|
||||
{
|
||||
if (!iter->title[0]) continue;
|
||||
|
||||
|
@ -412,8 +383,12 @@ static void RemoveItemsFromList(HWND hWnd)
|
|||
*/
|
||||
static inline void EmptyList(void)
|
||||
{
|
||||
FreeAppInfo(AppInfo);
|
||||
AppInfo = NULL;
|
||||
APPINFO *info, *next;
|
||||
LIST_FOR_EACH_ENTRY_SAFE( info, next, &app_list, APPINFO, entry )
|
||||
{
|
||||
list_remove( &info->entry );
|
||||
FreeAppInfo( info );
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
@ -437,7 +412,7 @@ static void UpdateButtons(HWND hWnd)
|
|||
|
||||
if (SendDlgItemMessageW(hWnd, IDL_PROGRAMS, LVM_GETITEMW, 0, (LPARAM) &lvItem))
|
||||
{
|
||||
for (iter = AppInfo; iter; iter = iter->next)
|
||||
LIST_FOR_EACH_ENTRY( iter, &app_list, APPINFO, entry )
|
||||
{
|
||||
if (iter->id == lvItem.lParam)
|
||||
{
|
||||
|
@ -524,7 +499,7 @@ static void UninstallProgram(int id, DWORD button)
|
|||
LoadStringW(hInst, IDS_UNINSTALL_FAILED, sUninstallFailed,
|
||||
sizeof(sUninstallFailed) / sizeof(sUninstallFailed[0]));
|
||||
|
||||
for (iter = AppInfo; iter; iter = iter->next)
|
||||
LIST_FOR_EACH_ENTRY( iter, &app_list, APPINFO, entry )
|
||||
{
|
||||
if (iter->id == id)
|
||||
{
|
||||
|
@ -626,7 +601,7 @@ static BOOL CALLBACK SupportInfoDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPAR
|
|||
switch(msg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
for (iter = AppInfo; iter; iter = iter->next)
|
||||
LIST_FOR_EACH_ENTRY( iter, &app_list, APPINFO, entry )
|
||||
{
|
||||
if (iter->id == (int) lParam)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue