2009-08-04 19:02:56 +00:00
|
|
|
/*
|
|
|
|
* PROJECT: ReactOS Applications Manager
|
|
|
|
* LICENSE: GPL - See COPYING in the top level directory
|
|
|
|
* FILE: base/applications/rapps/installed.c
|
|
|
|
* PURPOSE: Functions for working with installed applications
|
|
|
|
* PROGRAMMERS: Dmitry Chapyshev (dmitry@reactos.org)
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "rapps.h"
|
|
|
|
|
|
|
|
|
|
|
|
BOOL
|
|
|
|
GetApplicationString(HKEY hKey, LPWSTR lpKeyName, LPWSTR lpString)
|
|
|
|
{
|
|
|
|
DWORD dwSize = MAX_PATH;
|
|
|
|
|
|
|
|
if (RegQueryValueExW(hKey,
|
|
|
|
lpKeyName,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
(LPBYTE)lpString,
|
|
|
|
&dwSize) == ERROR_SUCCESS)
|
|
|
|
{
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
wcscpy(lpString, L"---");
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
BOOL
|
2009-08-26 19:03:32 +00:00
|
|
|
IsInstalledApplication(LPWSTR lpRegName, BOOL IsUserKey)
|
2009-08-04 19:02:56 +00:00
|
|
|
{
|
|
|
|
DWORD dwSize = MAX_PATH, dwType;
|
|
|
|
WCHAR szName[MAX_PATH];
|
|
|
|
WCHAR szDisplayName[MAX_PATH];
|
|
|
|
HKEY hKey, hSubKey;
|
|
|
|
INT ItemIndex = 0;
|
|
|
|
|
2009-08-26 19:03:32 +00:00
|
|
|
if (RegOpenKeyW(IsUserKey ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE,
|
2009-08-04 19:02:56 +00:00
|
|
|
L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall",
|
|
|
|
&hKey) != ERROR_SUCCESS)
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (RegEnumKeyExW(hKey, ItemIndex, szName, &dwSize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
|
|
|
|
{
|
|
|
|
if (RegOpenKeyW(hKey, szName, &hSubKey) == ERROR_SUCCESS)
|
|
|
|
{
|
|
|
|
dwType = REG_SZ;
|
|
|
|
dwSize = MAX_PATH;
|
|
|
|
if (RegQueryValueExW(hSubKey,
|
|
|
|
L"DisplayName",
|
|
|
|
NULL,
|
|
|
|
&dwType,
|
|
|
|
(LPBYTE)szDisplayName,
|
|
|
|
&dwSize) == ERROR_SUCCESS)
|
|
|
|
{
|
|
|
|
if (wcscmp(szDisplayName, lpRegName) == 0)
|
|
|
|
{
|
|
|
|
RegCloseKey(hSubKey);
|
|
|
|
RegCloseKey(hKey);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
RegCloseKey(hSubKey);
|
|
|
|
dwSize = MAX_PATH;
|
|
|
|
ItemIndex++;
|
|
|
|
}
|
|
|
|
|
|
|
|
RegCloseKey(hKey);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
BOOL
|
|
|
|
UninstallApplication(INT Index, BOOL bModify)
|
|
|
|
{
|
|
|
|
WCHAR szModify[] = L"ModifyPath";
|
|
|
|
WCHAR szUninstall[] = L"UninstallString";
|
|
|
|
WCHAR szPath[MAX_PATH];
|
2009-09-19 16:04:38 +00:00
|
|
|
WCHAR szAppName[MAX_STR_LEN];
|
2009-08-04 19:02:56 +00:00
|
|
|
DWORD dwType, dwSize;
|
|
|
|
INT ItemIndex;
|
|
|
|
LVITEM Item;
|
|
|
|
HKEY hKey;
|
2009-11-18 14:37:31 +00:00
|
|
|
PINSTALLED_INFO ItemInfo;
|
2009-08-04 19:02:56 +00:00
|
|
|
|
|
|
|
if (!IS_INSTALLED_ENUM(SelectedEnumType))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
if (Index == -1)
|
|
|
|
{
|
|
|
|
ItemIndex = (INT) SendMessageW(hListView, LVM_GETNEXTITEM, -1, LVNI_FOCUSED);
|
|
|
|
if (ItemIndex == -1)
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ItemIndex = Index;
|
|
|
|
}
|
|
|
|
|
2009-09-19 16:04:38 +00:00
|
|
|
ListView_GetItemText(hListView, ItemIndex, 0, szAppName, sizeof(szAppName) / sizeof(WCHAR));
|
|
|
|
WriteLogMessage(EVENTLOG_SUCCESS, MSG_SUCCESS_REMOVE, szAppName);
|
|
|
|
|
2009-08-04 19:02:56 +00:00
|
|
|
ZeroMemory(&Item, sizeof(LVITEM));
|
|
|
|
|
|
|
|
Item.mask = LVIF_PARAM;
|
|
|
|
Item.iItem = ItemIndex;
|
|
|
|
if (!ListView_GetItem(hListView, &Item))
|
|
|
|
return FALSE;
|
|
|
|
|
2009-11-18 14:37:31 +00:00
|
|
|
ItemInfo = (PINSTALLED_INFO)Item.lParam;
|
|
|
|
hKey = ItemInfo->hSubKey;
|
2009-08-04 19:02:56 +00:00
|
|
|
|
|
|
|
dwType = REG_SZ;
|
|
|
|
dwSize = MAX_PATH;
|
|
|
|
if (RegQueryValueExW(hKey,
|
|
|
|
bModify ? szModify : szUninstall,
|
|
|
|
NULL,
|
|
|
|
&dwType,
|
|
|
|
(LPBYTE)szPath,
|
|
|
|
&dwSize) != ERROR_SUCCESS)
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return StartProcess(szPath, TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
BOOL
|
|
|
|
ShowInstalledAppInfo(INT Index)
|
|
|
|
{
|
|
|
|
WCHAR szText[MAX_PATH], szInfo[MAX_PATH];
|
2009-10-03 09:34:19 +00:00
|
|
|
PINSTALLED_INFO Info = ListViewGetlParam(Index);
|
2009-08-04 19:02:56 +00:00
|
|
|
|
2009-10-03 09:34:19 +00:00
|
|
|
if (!Info || !Info->hSubKey) return FALSE;
|
2009-08-04 19:02:56 +00:00
|
|
|
|
2009-10-03 09:34:19 +00:00
|
|
|
GetApplicationString(Info->hSubKey, L"DisplayName", szText);
|
2009-08-04 19:02:56 +00:00
|
|
|
NewRichEditText(szText, CFE_BOLD);
|
|
|
|
|
|
|
|
InsertRichEditText(L"\n", 0);
|
|
|
|
|
|
|
|
#define GET_INFO(a, b, c, d) \
|
2009-10-03 09:34:19 +00:00
|
|
|
if (GetApplicationString(Info->hSubKey, a, szInfo)) \
|
2009-08-04 19:02:56 +00:00
|
|
|
{ \
|
|
|
|
LoadStringW(hInst, b, szText, sizeof(szText) / sizeof(WCHAR)); \
|
|
|
|
InsertRichEditText(szText, c); \
|
|
|
|
InsertRichEditText(szInfo, d); \
|
|
|
|
} \
|
|
|
|
|
|
|
|
GET_INFO(L"DisplayVersion", IDS_INFO_VERSION, CFE_BOLD, 0);
|
|
|
|
GET_INFO(L"Publisher", IDS_INFO_PUBLISHER, CFE_BOLD, 0);
|
|
|
|
GET_INFO(L"RegOwner", IDS_INFO_REGOWNER, CFE_BOLD, 0);
|
|
|
|
GET_INFO(L"ProductID", IDS_INFO_PRODUCTID, CFE_BOLD, 0);
|
|
|
|
GET_INFO(L"HelpLink", IDS_INFO_HELPLINK, CFE_BOLD, CFM_LINK);
|
|
|
|
GET_INFO(L"HelpTelephone", IDS_INFO_HELPPHONE, CFE_BOLD, 0);
|
|
|
|
GET_INFO(L"Readme", IDS_INFO_README, CFE_BOLD, 0);
|
|
|
|
GET_INFO(L"Contact", IDS_INFO_CONTACT, CFE_BOLD, 0);
|
|
|
|
GET_INFO(L"URLUpdateInfo", IDS_INFO_UPDATEINFO, CFE_BOLD, CFM_LINK);
|
|
|
|
GET_INFO(L"URLInfoAbout", IDS_INFO_INFOABOUT, CFE_BOLD, CFM_LINK);
|
|
|
|
GET_INFO(L"Comments", IDS_INFO_COMMENTS, CFE_BOLD, 0);
|
|
|
|
GET_INFO(L"InstallDate", IDS_INFO_INSTALLDATE, CFE_BOLD, 0);
|
|
|
|
GET_INFO(L"InstallLocation", IDS_INFO_INSTLOCATION, CFE_BOLD, 0);
|
|
|
|
GET_INFO(L"InstallSource", IDS_INFO_INSTALLSRC, CFE_BOLD, 0);
|
|
|
|
GET_INFO(L"UninstallString", IDS_INFO_UNINSTALLSTR, CFE_BOLD, 0);
|
|
|
|
GET_INFO(L"InstallSource", IDS_INFO_INSTALLSRC, CFE_BOLD, 0);
|
|
|
|
GET_INFO(L"ModifyPath", IDS_INFO_MODIFYPATH, CFE_BOLD, 0);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-10-03 09:34:19 +00:00
|
|
|
VOID
|
|
|
|
RemoveAppFromRegistry(INT Index)
|
|
|
|
{
|
|
|
|
PINSTALLED_INFO Info;
|
|
|
|
WCHAR szFullName[MAX_PATH] = L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\";
|
|
|
|
WCHAR szMsgText[MAX_STR_LEN], szMsgTitle[MAX_STR_LEN];
|
|
|
|
INT ItemIndex = SendMessage(hListView, LVM_GETNEXTITEM, -1, LVNI_FOCUSED);
|
|
|
|
|
|
|
|
if (!IS_INSTALLED_ENUM(SelectedEnumType))
|
|
|
|
return;
|
|
|
|
|
|
|
|
Info = ListViewGetlParam(Index);
|
|
|
|
if (!Info || !Info->hSubKey || (ItemIndex == -1)) return;
|
|
|
|
|
|
|
|
if (!LoadStringW(hInst, IDS_APP_REG_REMOVE, szMsgText, sizeof(szMsgText) / sizeof(WCHAR)) ||
|
|
|
|
!LoadStringW(hInst, IDS_INFORMATION, szMsgTitle, sizeof(szMsgTitle) / sizeof(WCHAR)))
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (MessageBoxW(hMainWnd, szMsgText, szMsgTitle, MB_YESNO | MB_ICONQUESTION) == IDYES)
|
|
|
|
{
|
|
|
|
wcsncat(szFullName, Info->szKeyName, MAX_PATH - wcslen(szFullName));
|
|
|
|
|
|
|
|
if (RegDeleteKeyW(Info->hRootKey, szFullName) == ERROR_SUCCESS)
|
|
|
|
{
|
|
|
|
(VOID) ListView_DeleteItem(hListView, ItemIndex);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!LoadStringW(hInst, IDS_UNABLE_TO_REMOVE, szMsgText, sizeof(szMsgText) / sizeof(WCHAR)))
|
|
|
|
return;
|
|
|
|
|
|
|
|
MessageBoxW(hMainWnd, szMsgText, NULL, MB_OK | MB_ICONERROR);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-08-04 19:02:56 +00:00
|
|
|
BOOL
|
2009-08-23 07:40:23 +00:00
|
|
|
EnumInstalledApplications(INT EnumType, BOOL IsUserKey, APPENUMPROC lpEnumProc)
|
2009-08-04 19:02:56 +00:00
|
|
|
{
|
|
|
|
DWORD dwSize = MAX_PATH, dwType, dwValue;
|
|
|
|
BOOL bIsSystemComponent, bIsUpdate;
|
|
|
|
WCHAR pszParentKeyName[MAX_PATH];
|
|
|
|
WCHAR pszDisplayName[MAX_PATH];
|
2009-10-03 09:34:19 +00:00
|
|
|
INSTALLED_INFO Info;
|
|
|
|
HKEY hKey;
|
2009-08-04 19:02:56 +00:00
|
|
|
LONG ItemIndex = 0;
|
|
|
|
|
2009-10-03 09:34:19 +00:00
|
|
|
Info.hRootKey = IsUserKey ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE;
|
|
|
|
|
|
|
|
if (RegOpenKeyW(Info.hRootKey,
|
2009-08-04 19:02:56 +00:00
|
|
|
L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall",
|
|
|
|
&hKey) != ERROR_SUCCESS)
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2009-10-03 09:34:19 +00:00
|
|
|
while (RegEnumKeyExW(hKey, ItemIndex, Info.szKeyName, &dwSize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
|
2009-08-04 19:02:56 +00:00
|
|
|
{
|
2009-10-03 09:34:19 +00:00
|
|
|
if (RegOpenKeyW(hKey, Info.szKeyName, &Info.hSubKey) == ERROR_SUCCESS)
|
2009-08-04 19:02:56 +00:00
|
|
|
{
|
|
|
|
dwType = REG_DWORD;
|
|
|
|
dwSize = sizeof(DWORD);
|
|
|
|
|
2009-10-03 09:34:19 +00:00
|
|
|
if (RegQueryValueExW(Info.hSubKey,
|
2009-08-04 19:02:56 +00:00
|
|
|
L"SystemComponent",
|
|
|
|
NULL,
|
|
|
|
&dwType,
|
|
|
|
(LPBYTE)&dwValue,
|
|
|
|
&dwSize) == ERROR_SUCCESS)
|
|
|
|
{
|
|
|
|
bIsSystemComponent = (dwValue == 0x1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
bIsSystemComponent = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
dwType = REG_SZ;
|
|
|
|
dwSize = MAX_PATH;
|
2009-10-03 09:34:19 +00:00
|
|
|
bIsUpdate = (RegQueryValueExW(Info.hSubKey,
|
2009-08-04 19:02:56 +00:00
|
|
|
L"ParentKeyName",
|
|
|
|
NULL,
|
|
|
|
&dwType,
|
|
|
|
(LPBYTE)pszParentKeyName,
|
|
|
|
&dwSize) == ERROR_SUCCESS);
|
|
|
|
|
|
|
|
dwSize = MAX_PATH;
|
2009-10-03 09:34:19 +00:00
|
|
|
if (RegQueryValueExW(Info.hSubKey,
|
2009-08-04 19:02:56 +00:00
|
|
|
L"DisplayName",
|
|
|
|
NULL,
|
|
|
|
&dwType,
|
|
|
|
(LPBYTE)pszDisplayName,
|
|
|
|
&dwSize) == ERROR_SUCCESS)
|
|
|
|
{
|
|
|
|
if (EnumType < ENUM_ALL_COMPONENTS || EnumType > ENUM_UPDATES)
|
|
|
|
EnumType = ENUM_ALL_COMPONENTS;
|
|
|
|
|
|
|
|
if (!bIsSystemComponent)
|
|
|
|
{
|
|
|
|
if ((EnumType == ENUM_ALL_COMPONENTS) || /* All components */
|
|
|
|
((EnumType == ENUM_APPLICATIONS) && (!bIsUpdate)) || /* Applications only */
|
|
|
|
((EnumType == ENUM_UPDATES) && (bIsUpdate))) /* Updates only */
|
|
|
|
{
|
2009-10-03 09:34:19 +00:00
|
|
|
if (!lpEnumProc(ItemIndex, pszDisplayName, Info))
|
2009-08-04 19:02:56 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
dwSize = MAX_PATH;
|
|
|
|
ItemIndex++;
|
|
|
|
}
|
|
|
|
|
|
|
|
RegCloseKey(hKey);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|