384 lines
9.3 KiB
C
384 lines
9.3 KiB
C
//
|
|
// AppList.C
|
|
//
|
|
// Copyright (C) Microsoft, 1994, 1995, All Rights Reserved.
|
|
//
|
|
// History:
|
|
// ral 5/23/94 - First pass
|
|
// ral 9/09/94 - Clean up
|
|
// 3/20/95 [stevecat] - NT port & real clean up, unicode, etc.
|
|
//
|
|
//
|
|
|
|
#include "priv.h"
|
|
#include "appwiz.h"
|
|
#include "regstr.h"
|
|
|
|
#ifdef DOWNLEVEL
|
|
|
|
static const DWORD aApplistHelpIDs[] = {
|
|
IDC_BUTTONSETUPFROMLIST, IDH_APPWIZ_NETINTALLL_BUTTON,
|
|
IDC_APPLIST, IDH_APPWIZ_NETINSTALL_LIST,
|
|
0, 0 };
|
|
|
|
#define INST_SECTION TEXT("AppInstallList") // RESOURCE?
|
|
#define MAX_KEY_SIZE 45000
|
|
|
|
//
|
|
// Fills in the name of the INF file in the wiz data structure. If
|
|
// no INF file is specified then returns FALSE, else TRUE.
|
|
//
|
|
|
|
BOOL AppListGetInfName(LPWIZDATA lpwd)
|
|
{
|
|
HKEY hk;
|
|
LONG RegResult;
|
|
DWORD cbFileName = sizeof(lpwd->szIniFile);
|
|
DWORD dwType;
|
|
BOOL bFileExists = FALSE;
|
|
|
|
if (RegOpenKey(HKEY_LOCAL_MACHINE, REGSTR_PATH_SETUP, &hk) != ERROR_SUCCESS)
|
|
{
|
|
return(FALSE);
|
|
}
|
|
RegResult = RegQueryValueEx(hk, REGSTR_VAL_APPINSTPATH, NULL,
|
|
&dwType, (LPBYTE) lpwd->szIniFile, &cbFileName);
|
|
RegCloseKey(hk);
|
|
|
|
if (RegResult == ERROR_SUCCESS && dwType == REG_SZ)
|
|
{
|
|
bFileExists = PathFileExists(lpwd->szIniFile);
|
|
}
|
|
|
|
if (!bFileExists)
|
|
{
|
|
lpwd->szIniFile[0] = 0;
|
|
}
|
|
|
|
return(bFileExists);
|
|
}
|
|
|
|
|
|
#ifdef DEBUG
|
|
void ValidateINIEntry(LPWIZDATA lpwd, LPTSTR lpszKeyName)
|
|
{
|
|
TCHAR szFileName[MAX_PATH];
|
|
|
|
if (GetPrivateProfileString(INST_SECTION, lpszKeyName, TEXT(""),
|
|
szFileName, ARRAYSIZE(szFileName),
|
|
lpwd->szIniFile))
|
|
{
|
|
LPTSTR lpszRealName = szFileName;
|
|
|
|
if (*lpszRealName == TEXT('*'))
|
|
{
|
|
lpszRealName++;
|
|
}
|
|
|
|
if (!PathFileExists(lpszRealName))
|
|
{
|
|
ShellMessageBox(g_hinst, lpwd->hwnd,
|
|
TEXT("Entry for %1%s points to non-existant setup program: %2%s"),
|
|
0, MB_OK | MB_ICONEXCLAMATION, lpszKeyName, szFileName);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ShellMessageBox(g_hinst, lpwd->hwnd,
|
|
TEXT("Bad INI file format for entry %1%s."),
|
|
0, MB_OK | MB_ICONEXCLAMATION, lpszKeyName);
|
|
}
|
|
}
|
|
#endif // DEBUG
|
|
|
|
|
|
//
|
|
// Initializes the applist property sheet. This function assumes that
|
|
// someone else (appwiz.c) has already called AppListGetInfName and the
|
|
// inf file name has already been filled in in the wizard data structure.
|
|
// If the string is empty, then this function simply returns.
|
|
//
|
|
|
|
void AppList_InitListBox(HWND hDlg, LPPROPSHEETPAGE lpp)
|
|
{
|
|
LPWIZDATA lpwd = (LPWIZDATA)lpp->lParam;
|
|
|
|
SetWindowLongPtr(hDlg, DWLP_USER, (LPARAM)lpp);
|
|
|
|
if (lpwd->szIniFile[0] != 0)
|
|
{
|
|
HWND hLB = GetDlgItem(hDlg, IDC_APPLIST);
|
|
LPTSTR lpszKeys = (LPTSTR)GlobalAllocPtr(GPTR, MAX_KEY_SIZE*sizeof(TCHAR));
|
|
|
|
ListBox_ResetContent(hLB);
|
|
|
|
//
|
|
// If the localalloc failed then we'll just have a
|
|
// empty list.
|
|
//
|
|
|
|
if (lpszKeys)
|
|
{
|
|
HCURSOR hcurOld = SetCursor(LoadCursor(NULL, IDC_WAIT));
|
|
|
|
if (GetPrivateProfileString(INST_SECTION, NULL, NULL, lpszKeys,
|
|
MAX_KEY_SIZE, lpwd->szIniFile))
|
|
{
|
|
LPTSTR lpszCurPos = lpszKeys;
|
|
int iCurLBPos = 0;
|
|
|
|
while (*lpszCurPos)
|
|
{
|
|
ListBox_InsertString(hLB, iCurLBPos++, lpszCurPos);
|
|
#ifdef DEBUG
|
|
ValidateINIEntry(lpwd, lpszCurPos);
|
|
#endif
|
|
while (*lpszCurPos != 0)
|
|
{
|
|
lpszCurPos = CharNext(lpszCurPos);
|
|
}
|
|
lpszCurPos++;
|
|
}
|
|
}
|
|
GlobalFreePtr(lpszKeys);
|
|
SetCursor(hcurOld);
|
|
}
|
|
ListBox_SetCurSel(hLB, 0);
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// Copies the name of the setup program into the wizard data
|
|
//
|
|
|
|
BOOL GetListSel(HWND hLB, int iCurSel, LPWIZDATA lpwd)
|
|
{
|
|
TCHAR szKeyName[MAX_PATH];
|
|
|
|
if ((iCurSel != LB_ERR) &&
|
|
(ListBox_GetTextLen(hLB, iCurSel) <= ARRAYSIZE(szKeyName)))
|
|
{
|
|
ListBox_GetText(hLB, iCurSel, szKeyName);
|
|
|
|
if (GetPrivateProfileString(INST_SECTION, szKeyName, TEXT(""),
|
|
lpwd->szExeName, ARRAYSIZE(lpwd->szExeName),
|
|
lpwd->szIniFile))
|
|
{
|
|
lpwd->szParams[0] = 0; // Make sure this string is empty
|
|
return(TRUE);
|
|
}
|
|
}
|
|
return(FALSE);
|
|
}
|
|
|
|
|
|
//
|
|
// Dismisses the property sheet by pressing the "OK" button.
|
|
//
|
|
|
|
void DismissCPL(LPWIZDATA lpwd)
|
|
{
|
|
PropSheet_PressButton(GetParent(lpwd->hwnd), PSBTN_OK);
|
|
}
|
|
|
|
|
|
//
|
|
// Install property sheet page -- Used only if there is an AppInstallPath
|
|
// specified in the registry. Otherwise, use NoListInstallDlgProc.
|
|
//
|
|
|
|
BOOL_PTR CALLBACK AppListDlgProc(HWND hDlg, UINT message , WPARAM wParam, LPARAM lParam)
|
|
{
|
|
NMHDR FAR *lpnm;
|
|
LPPROPSHEETPAGE lpPropSheet = (LPPROPSHEETPAGE)(GetWindowLongPtr(hDlg, DWLP_USER));
|
|
LPWIZDATA lpwd;
|
|
|
|
|
|
if (lpPropSheet)
|
|
{
|
|
lpwd = (LPWIZDATA)lpPropSheet->lParam;
|
|
}
|
|
switch(message)
|
|
{
|
|
case WM_NOTIFY:
|
|
lpnm = (NMHDR FAR *)lParam;
|
|
|
|
switch(lpnm->code)
|
|
{
|
|
case PSN_SETACTIVE:
|
|
lpwd->hwnd = hDlg;
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
}
|
|
break;
|
|
|
|
case WM_INITDIALOG:
|
|
lpPropSheet = (LPPROPSHEETPAGE)lParam;
|
|
AppList_InitListBox(hDlg, lpPropSheet);
|
|
break;
|
|
|
|
case WM_DESTROY:
|
|
break;
|
|
|
|
case WM_HELP:
|
|
WinHelp((HWND)((LPHELPINFO)lParam)->hItemHandle, NULL,
|
|
HELP_WM_HELP, (DWORD_PTR)aApplistHelpIDs);
|
|
break;
|
|
|
|
case WM_CONTEXTMENU:
|
|
WinHelp((HWND)wParam, NULL, HELP_CONTEXTMENU,
|
|
(DWORD_PTR)aApplistHelpIDs);
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
switch (GET_WM_COMMAND_ID(wParam, lParam))
|
|
{
|
|
case IDC_BUTTONSETUPFROMLIST:
|
|
if (GET_WM_COMMAND_CMD(wParam, lParam) == BN_CLICKED)
|
|
{
|
|
HWND hLB = GetDlgItem(hDlg, IDC_APPLIST);
|
|
int iCurSel = ListBox_GetCurSel(hLB);
|
|
|
|
if (iCurSel != LB_ERR &&
|
|
GetListSel(hLB, iCurSel, lpwd) &&
|
|
ExecSetupProg(lpwd, FALSE, TRUE))
|
|
{
|
|
DismissCPL(lpwd);
|
|
}
|
|
}
|
|
|
|
case IDC_APPLIST:
|
|
if (GET_WM_COMMAND_CMD(wParam, lParam) == LBN_DBLCLK)
|
|
{
|
|
SendMessage(hDlg, WM_COMMAND,
|
|
GET_WM_COMMAND_MPS(IDC_BUTTONSETUPFROMLIST,
|
|
GetDlgItem(hDlg, IDC_BUTTONSETUPFROMLIST),
|
|
BN_CLICKED));
|
|
}
|
|
break;
|
|
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
|
|
} // end of switch on message
|
|
|
|
return TRUE;
|
|
|
|
} // AppListdlgProc
|
|
|
|
#endif // DOWNLEVEL
|
|
|
|
|
|
//
|
|
// Executes the appropriate setup program
|
|
//
|
|
|
|
BOOL ExecSetupProg(LPWIZDATA lpwd, BOOL ForceWx86, BOOL bMinimizeWiz)
|
|
{
|
|
SHELLEXECUTEINFO ei;
|
|
BOOL fWorked= FALSE;
|
|
|
|
#ifdef WX86
|
|
DWORD Len;
|
|
WCHAR ProcArchValue[32];
|
|
#endif
|
|
|
|
HWND hDlgPropSheet = GetParent(lpwd->hwnd);
|
|
LPTSTR lpszTarget = NULL;
|
|
|
|
ei.cbSize = sizeof(ei);
|
|
ei.hwnd = lpwd->hwnd;
|
|
ei.lpVerb = NULL;
|
|
ei.fMask = 0;
|
|
|
|
lpszTarget = (lpwd->dwFlags & WDFLAG_EXPSZ) ? lpwd->szExpExeName : lpwd->szExeName;
|
|
if (lpszTarget[0] == TEXT('*'))
|
|
{
|
|
ei.lpFile = CharNext(lpszTarget);
|
|
ei.fMask |= SEE_MASK_CONNECTNETDRV;
|
|
}
|
|
else
|
|
{
|
|
ei.lpFile = lpszTarget;
|
|
}
|
|
|
|
if (lpwd->szParams[0] == 0)
|
|
{
|
|
ei.lpParameters = NULL;
|
|
}
|
|
else
|
|
{
|
|
ei.lpParameters = lpwd->szParams;
|
|
}
|
|
|
|
if (lpwd->szWorkingDir[0] == TEXT('\0'))
|
|
{
|
|
ei.lpDirectory = NULL;
|
|
}
|
|
else
|
|
{
|
|
ei.lpDirectory = lpwd->szWorkingDir;
|
|
}
|
|
|
|
ei.lpClass = NULL;
|
|
ei.nShow = SW_SHOWDEFAULT;
|
|
ei.hInstApp = g_hinst;
|
|
|
|
if (bMinimizeWiz)
|
|
SetWindowPos(hDlgPropSheet, 0, 0, 0, 0, 0, SWP_HIDEWINDOW|SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER);
|
|
|
|
|
|
#ifdef WX86
|
|
if (ForceWx86) {
|
|
Len = GetEnvironmentVariableW(ProcArchName,
|
|
ProcArchValue,
|
|
sizeof(ProcArchValue)
|
|
);
|
|
|
|
if (!Len || Len >= sizeof(ProcArchValue)) {
|
|
ProcArchValue[0]=L'\0';
|
|
}
|
|
|
|
SetEnvironmentVariableW(ProcArchName, L"x86");
|
|
ei.fMask |= SEE_MASK_FLAG_SEPVDM;
|
|
|
|
}
|
|
#endif
|
|
|
|
|
|
fWorked = ShellExecuteEx(&ei);
|
|
|
|
|
|
#ifdef WX86
|
|
if (ForceWx86) {
|
|
SetEnvironmentVariableW(ProcArchName, ProcArchValue);
|
|
}
|
|
#endif
|
|
|
|
|
|
|
|
if (!fWorked)
|
|
{
|
|
//
|
|
// Something went wrong. Put the dialog back up.
|
|
//
|
|
|
|
SetWindowPos(hDlgPropSheet, 0, 0, 0, 0, 0, SWP_SHOWWINDOW|SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER);
|
|
ShellMessageBox(g_hinst, lpwd->hwnd, MAKEINTRESOURCE(IDS_BADSETUP),
|
|
0, MB_OK | MB_ICONEXCLAMATION);
|
|
}
|
|
|
|
return(fWorked);
|
|
}
|
|
|
|
|
|
|
|
|
|
|