windows-nt/Source/XPSP1/NT/shell/cpls/appwzdui/confopt.c
2020-09-26 16:20:57 +08:00

1259 lines
32 KiB
C

//
// ConfOpt.C
//
// Copyright (C) Microsoft, 1994,1995 All Rights Reserved.
//
// History:
// ral 5/23/94 - First pass
// 3/20/95 [stevecat] - NT port & real clean up, unicode, etc.
//
//
#include "priv.h"
#include "appwiz.h"
#define MAX_CFG_FILE_SIZE 20000
#define MAX_DESC_SIZE 100
//
// Return codes for OptSelected
//
#define OPTSEL_YES 0
#define OPTSEL_NO 1
#define OPTSEL_NOTSUPP 2
//
// Define checkbox states for listview
//
#define LVIS_GCNOCHECK 0x1000
#define LVIS_GCCHECK 0x2000
//
// Character definitions
//
#define CR 13
#define LF 10
TCHAR const c_szCRLF[] = {CR, LF, 0};
TCHAR const c_szRegValAutoexec[] = REGSTR_VAL_AUTOEXEC;
TCHAR const c_szRegValConfigSys[] = REGSTR_VAL_CONFIGSYS;
TCHAR const c_szRegDosOptFlags[] = REGSTR_VAL_DOSOPTFLAGS;
TCHAR const c_szRegStandardOpt[] = REGSTR_VAL_STDDOSOPTION;
TCHAR const c_szRegDosOptTip[] = REGSTR_VAL_DOSOPTTIP;
TCHAR const c_szRegDosOptsPath[] = REGSTR_PATH_MSDOSOPTS;
TCHAR const c_szRegGlobalFlags[] = REGSTR_VAL_DOSOPTGLOBALFLAGS;
TCHAR const c_szRegShutdownKey[] = REGSTR_PATH_SHUTDOWN;
TCHAR const c_szForceRebootVal[] = REGSTR_VAL_FORCEREBOOT;
BOOL MustRebootSystem(void)
{
HKEY hk;
BOOL bMustReboot = FALSE;
if (RegOpenKey(HKEY_LOCAL_MACHINE, c_szRegShutdownKey, &hk) == ERROR_SUCCESS)
{
bMustReboot = (RegQueryValueEx(hk, c_szForceRebootVal, NULL,
NULL, NULL, NULL) == ERROR_SUCCESS);
RegCloseKey(hk);
}
return(bMustReboot);
}
DWORD GetMSDOSOptGlobalFlags(LPWIZDATA lpwd)
{
if ((lpwd->dwFlags & WDFLAG_READOPTFLAGS) == 0)
{
HKEY hk;
lpwd->dwFlags |= WDFLAG_READOPTFLAGS;
if (RegOpenKey(HKEY_LOCAL_MACHINE, c_szRegDosOptsPath, &hk)
== ERROR_SUCCESS)
{
UINT cb = sizeof(lpwd->dwDosOptGlobalFlags);
if (RegQueryValueEx(hk, c_szRegGlobalFlags, NULL, NULL,
(LPVOID)(&(lpwd->dwDosOptGlobalFlags)), &cb)
!= ERROR_SUCCESS)
{
lpwd->dwDosOptGlobalFlags = 0;
}
RegCloseKey(hk);
}
if (MustRebootSystem())
{
lpwd->dwDosOptGlobalFlags |= DOSOPTGF_DEFCLEAN;
}
}
return(lpwd->dwDosOptGlobalFlags);
}
//
// Structure used to store text for Autoexec.Bat and Config.Sys
//
typedef struct _TEXTDATA {
UINT cb;
LPTSTR lpszData;
} TEXTDATA, FAR * LPTEXTDATA;
//
// Gets a single value from the specified option index. If no data is
// found for the specified value name then a 0 DWORD is stored.
//
void GetOptVal(LPWIZDATA lpwd, int i, LPCTSTR lpszValName, LPVOID lpData, UINT cb)
{
if (RegQueryValueEx(lpwd->DosOpt[i].hk, lpszValName, NULL, NULL, lpData, &cb) != ERROR_SUCCESS)
{
*(LPDWORD)lpData = (DWORD)0;
}
}
BOOL FindDriver(int idFiles, int idLoadHigh, HKEY hk, LPCTSTR lpszRegVal,
LPCTSTR FAR dirs[])
{
TCHAR szFiles[MAX_PATH];
LPTSTR lpszCur, lpszFileName;
TCHAR szCommand[MAX_PATH+20];
LoadAndStrip(idFiles, szFiles, ARRAYSIZE(szFiles));
LoadString(g_hinst, idLoadHigh, szCommand, ARRAYSIZE(szCommand));
lpszFileName = &szCommand[lstrlen(szCommand)];
lpszCur = szFiles;
while (*lpszCur)
{
lstrcpy(lpszFileName, lpszCur);
if (PathResolve(lpszFileName, dirs, PRF_VERIFYEXISTS))
{
PathGetShortPath(lpszFileName);
RegSetValueEx(hk, lpszRegVal, 0, REG_SZ, (LPBYTE) szCommand,
(lstrlen(szCommand)+1)*sizeof(TCHAR));
return(TRUE);
}
lpszCur = SkipStr(lpszCur);
}
return(FALSE);
}
BOOL SetUpMouse(LPWIZDATA lpwd, int i)
{
#define MOpt lpwd->DosOpt[i]
TCHAR szMouseEnv[64];
TCHAR szMouseDir[64];
LPCTSTR FAR dirs[] = {szMouseDir, NULL};
BOOL fRetVal;
if (!LoadString(g_hinst, IDS_MOUSEENV, szMouseEnv, ARRAYSIZE(szMouseEnv)))
{
fRetVal = FALSE;
}
else
{
lstrcpy(szMouseDir, szMouseEnv);
DoEnvironmentSubst(szMouseDir, ARRAYSIZE(szMouseDir));
if (lstrcmp(szMouseDir, szMouseEnv) == 0)
{
dirs[0] = NULL;
}
if (FindDriver(IDS_MOUSETSRS, IDS_LOADHIGH,MOpt.hk, c_szRegValAutoexec, dirs) ||
FindDriver(IDS_MOUSEDRVS, IDS_DEVHIGH, MOpt.hk, c_szRegValConfigSys, dirs))
{
MOpt.dwFlags |= DOSOPTF_SUPPORTED;
TraceMsg(TF_ERROR, "%s", "Found real mode mouse driver");
}
MOpt.dwFlags &= ~DOSOPTF_NEEDSETUP;
RegSetValueEx(MOpt.hk, c_szRegDosOptFlags, 0, REG_DWORD,
(LPBYTE)&(MOpt.dwFlags), sizeof(MOpt.dwFlags));
fRetVal = TRUE;
}
return fRetVal;
#undef MOpt
}
//
// The option is not configured. Here's where to add code to set up any
// standard option. Currently, we only set up the mouse.
//
BOOL SetupOption(LPWIZDATA lpwd, int i)
{
BOOL fRetVal;
if (RMOPT_MOUSE == lpwd->DosOpt[i].dwStdOpt)
{
TraceMsg(TF_ERROR, "%s", "About to search for real mode mouse driver");
fRetVal = SetUpMouse(lpwd, i);
}
else
{
fRetVal = TRUE;
}
return fRetVal;
}
//
// Closes all open hkeys and frees the memory. NOTE: This function can
// be called any time, even if ReadRegInfo has not been called previously.
//
void FreeRegInfo(LPWIZDATA lpwd)
{
int i;
if (!lpwd->DosOpt)
{
return;
}
for (i = 0; i < lpwd->NumOpts; i++)
{
RegCloseKey(lpwd->DosOpt[i].hk);
}
LocalFree(lpwd->DosOpt);
lpwd->DosOpt = NULL;
lpwd->NumOpts = 0;
}
//
// Initializes the option table in the wizard data header.
//
BOOL ReadRegInfo(LPWIZDATA lpwd)
{
HKEY hk;
BOOL bSuccess = FALSE;
int i;
if (lpwd->DosOpt)
{
return(TRUE);
}
if (RegOpenKey(HKEY_LOCAL_MACHINE, c_szRegDosOptsPath, &hk) !=
ERROR_SUCCESS)
{
goto Exit;
}
if (RegQueryInfoKey(hk, NULL, NULL, NULL, &(lpwd->NumOpts),
NULL, NULL, NULL, NULL, NULL, NULL, NULL) !=
ERROR_SUCCESS)
{
goto ExitCloseKey;
}
lpwd->DosOpt = LocalAlloc(LPTR, lpwd->NumOpts * sizeof(DOSOPT));
if (!lpwd->DosOpt)
{
goto ExitCloseKey;
}
for (i = 0; i < lpwd->NumOpts; i++)
{
UINT cb;
TCHAR szOptKey[80];
HKEY hkOpt;
UINT uOrder = 0;
int InsPos;
cb = ARRAYSIZE(szOptKey);
if ((RegEnumKeyEx(hk, i, szOptKey, &cb, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) ||
(RegOpenKey(hk, szOptKey, &hkOpt) != ERROR_SUCCESS))
{
lpwd->NumOpts = i - 1;
FreeRegInfo(lpwd); // This frees the DosOpt memory
goto ExitCloseKey;
}
cb = sizeof(uOrder);
RegQueryValueEx(hkOpt, REGSTR_VAL_OPTORDER, NULL, NULL, (LPVOID)&uOrder, &cb);
for (InsPos = i;
(InsPos > 0) && (lpwd->DosOpt[InsPos-1].uOrder > uOrder);
InsPos--);
if (InsPos < i)
{
MoveMemory(&(lpwd->DosOpt[InsPos+1]), &(lpwd->DosOpt[InsPos]),
(i - InsPos) * sizeof(DOSOPT));
}
lpwd->DosOpt[InsPos].hk = hkOpt;
lpwd->DosOpt[InsPos].uOrder = uOrder;
GetOptVal(lpwd, InsPos, c_szRegDosOptFlags, &(lpwd->DosOpt[InsPos].dwFlags), sizeof(DWORD));
GetOptVal(lpwd, InsPos, c_szRegStandardOpt, &(lpwd->DosOpt[InsPos].dwStdOpt), sizeof(DWORD));
if (lpwd->DosOpt[InsPos].dwFlags & DOSOPTF_NEEDSETUP)
{
if (!SetupOption(lpwd, InsPos))
{
goto ExitCloseKey;
}
}
}
bSuccess = TRUE;
ExitCloseKey:
RegCloseKey(hk);
Exit:
return(bSuccess);
}
//
// Inserts a single column into the specified ListView.
//
void InitSingleColListView(HWND hLV)
{
LV_COLUMN col = {LVCF_FMT | LVCF_WIDTH, LVCFMT_LEFT};
RECT rc;
GetClientRect(hLV, &rc);
col.cx = rc.right - GetSystemMetrics(SM_CXVSCROLL)
- GetSystemMetrics(SM_CXSMICON)
- 2 * GetSystemMetrics(SM_CXEDGE);
ListView_InsertColumn(hLV, 0, &col);
}
//
// Initializes the listview with all available options
//
void ConfOptInit(HWND hDlg, LPPROPSHEETPAGE lpp)
{
HIMAGELIST himlState;
HWND hwndOptions = GetDlgItem(hDlg, IDC_OPTIONLIST);
LPWIZDATA lpwd = InitWizSheet(hDlg, (LPARAM)lpp, 0);
InitSingleColListView(hwndOptions);
//
// Lets load our bitmap as an imagelist
//
himlState = ImageList_LoadImage(g_hinst, MAKEINTRESOURCE(IDB_CHECKSTATES), 0, 2,
CLR_NONE, IMAGE_BITMAP, LR_LOADTRANSPARENT);
ListView_SetImageList(hwndOptions, himlState, LVSIL_STATE);
//
// Find all options for MS-DOS configs and set their approropriate state
// information
//
if (ReadRegInfo(lpwd))
{
int i;
for (i = 0; i < lpwd->NumOpts; i++)
{
DWORD dwFlags = lpwd->DosOpt[i].dwFlags;
if ((dwFlags & DOSOPTF_SUPPORTED) &&
((dwFlags & DOSOPTF_ALWAYSUSE) == 0) &&
((dwFlags & DOSOPTF_USESPMODE) == 0 ||
(lpwd->dwFlags & WDFLAG_REALMODEONLY) == 0) &&
(lpwd->DosOpt[i].uOrder > 0))
{
TCHAR szDesc[MAX_DESC_SIZE];
LV_ITEM lvi;
GetOptVal(lpwd, i, NULL, szDesc, sizeof(szDesc));
lvi.mask = LVIF_TEXT | LVIF_STATE | LVIF_PARAM;
lvi.iItem = 0x7FFF;
lvi.iSubItem = 0;
//
///// REARCHITECT If program properties contains real mode flags, use them for defaults!
//
lvi.state = (dwFlags & DOSOPTF_DEFAULT) ? LVIS_GCCHECK : LVIS_GCNOCHECK;
lvi.stateMask = LVIS_ALL;
lvi.pszText = szDesc;
lvi.lParam = (LPARAM)i;
lvi.cchTextMax = 0;
ListView_InsertItem(hwndOptions, &lvi);
}
}
}
}
//
// Toggles the state of the specified item in the list view.
//
void ToggleState(HWND hwndLV, int i)
{
UINT state = ListView_GetItemState(hwndLV, i, LVIS_STATEIMAGEMASK);
state = (state == LVIS_GCNOCHECK) ? LVIS_GCCHECK : LVIS_GCNOCHECK;
ListView_SetItemState(hwndLV, i, state, LVIS_STATEIMAGEMASK);
}
//
// Returns the path to the boot directory. If we can't find it in the
// registry then this function returns the default (drive that windows
// directory is on)
//
void GetBootDir(LPTSTR lpszBootDir, int cchBootDir)
{
HKEY hkSetup;
*lpszBootDir = 0;
if (RegOpenKey(HKEY_LOCAL_MACHINE, REGSTR_PATH_SETUP REGSTR_KEY_SETUP,
&hkSetup) == ERROR_SUCCESS)
{
UINT cb = cchBootDir * SIZEOF(TCHAR);
RegQueryValueEx(hkSetup, REGSTR_VAL_BOOTDIR, NULL,
NULL, (LPBYTE) lpszBootDir, &cb);
RegCloseKey(hkSetup);
}
if (*lpszBootDir == 0)
{
if (0 != GetWindowsDirectory(lpszBootDir, cchBootDir)
&& lpszBootDir[0] != TEXT('\0')
&& lpszBootDir[1] == TEXT(':')
&& lpszBootDir[2] == TEXT('\\'))
{
lpszBootDir[3] = TEXT('\0');
}
else
{
LoadString(g_hinst, IDS_DEFBOOTDIR, lpszBootDir, cchBootDir);
}
}
}
//
// Process the clicks on the listview. do a hittest to see where the user
// clicked. If on one of the state bitmaps, toggle it.
//
void ConfOptClick(HWND hDlg, LPNMHDR pnmhdr)
{
//
// The user clicked on one the listview see where...
//
DWORD dwpos;
LV_HITTESTINFO lvhti;
dwpos = GetMessagePos();
lvhti.pt.x = GET_X_LPARAM(dwpos);
lvhti.pt.y = GET_Y_LPARAM(dwpos);
MapWindowPoints(HWND_DESKTOP, pnmhdr->hwndFrom, &lvhti.pt, 1);
ListView_HitTest(pnmhdr->hwndFrom, &lvhti);
if (lvhti.flags & LVHT_ONITEMSTATEICON)
{
ToggleState(pnmhdr->hwndFrom, lvhti.iItem);
}
}
//
// When the user hits the space bar, toggle the state of the selected item.
//
BOOL ConfOptKeyDown(HWND hDlg, LV_KEYDOWN *plvkd)
{
int iCursor;
if (plvkd->wVKey == VK_SPACE && !(GetAsyncKeyState(VK_MENU) < 0))
{
//
// Lets toggle the cursored item.
//
iCursor = ListView_GetNextItem(plvkd->hdr.hwndFrom, -1, LVNI_FOCUSED);
if (iCursor != -1)
{
ToggleState(plvkd->hdr.hwndFrom, iCursor);
}
return TRUE;
}
return FALSE;
}
//
// Item selection changed. Update tip.
//
void ItemChanged(LPWIZDATA lpwd, LPNM_LISTVIEW lpnmlv)
{
LV_ITEM lvi;
TCHAR szTip[200]; ///???
if ((lpnmlv->uNewState & LVIS_FOCUSED) &&
(!(lpnmlv->uOldState & LVIS_FOCUSED)))
{
lvi.iItem = lpnmlv->iItem;
lvi.iSubItem = 0;
lvi.mask = LVIF_PARAM;
ListView_GetItem(lpnmlv->hdr.hwndFrom, &lvi);
GetOptVal(lpwd, (int)lvi.lParam, c_szRegDosOptTip, szTip, sizeof(szTip));
Static_SetText(GetDlgItem(lpwd->hwnd, IDC_OPTIONTIP), szTip);
}
}
void _inline NoSupportMsg(LPWIZDATA lpwd, int iOpt)
{
LPTSTR lpszDesc = (LPTSTR)LocalAlloc(LMEM_FIXED, MAX_DESC_SIZE*sizeof(TCHAR));
if (lpszDesc)
{
LPTSTR lpszMsg = (LPTSTR)LocalAlloc(LMEM_FIXED, 512*sizeof(TCHAR)); // Max 2 resource size
if (lpszMsg)
{
GetOptVal(lpwd, iOpt, NULL, lpszDesc, MAX_DESC_SIZE*sizeof(TCHAR));
LoadString(g_hinst, IDS_NOSUPPORT1, lpszMsg, 512);
LoadString(g_hinst, IDS_NOSUPPORT2, lpszMsg+lstrlen(lpszMsg), 256);
ShellMessageBox(g_hinst, lpwd->hwnd,
lpszMsg, 0,
MB_OK | MB_ICONEXCLAMATION,
lpszDesc);
LocalFree(lpszMsg);
}
LocalFree(lpszDesc);
}
}
//
// Returns OPTSEL_YES if the option indicated by i is selected in the list
// box, or, if hwndLV is NULL then OPTSEL_YES if option should be added,
// OPTSEL_NO if should not be added, and OPTSEL_NOTSUPP if the option is
// required but can't be added.
//
int OptSelected(LPWIZDATA lpwd, int i, HWND hwndLV)
{
BOOL bSelected = FALSE;
if (lpwd->DosOpt[i].dwFlags & DOSOPTF_ALWAYSUSE)
{
bSelected = TRUE;
}
else
{
if (hwndLV)
{
LV_ITEM lvi;
int NumItems = ListView_GetItemCount(hwndLV);
for (lvi.iItem = 0; lvi.iItem < NumItems; lvi.iItem++)
{
lvi.iSubItem = 0;
lvi.mask = LVIF_PARAM | LVIF_STATE;
lvi.stateMask = LVIS_STATEIMAGEMASK;
ListView_GetItem(hwndLV, &lvi);
if ((int)lvi.lParam == i)
{
bSelected = ((lvi.state & LVIS_STATEIMAGEMASK) == LVIS_GCCHECK);
}
}
}
else
{
BOOL bSupported = lpwd->DosOpt[i].dwFlags & DOSOPTF_SUPPORTED;
if (lpwd->PropPrg.dwRealModeFlags & lpwd->DosOpt[i].dwStdOpt)
{
bSelected = TRUE;
if (!bSupported)
{
NoSupportMsg(lpwd, i);
return(OPTSEL_NOTSUPP);
}
}
else
{
if (bSupported)
{
bSelected = (lpwd->PropPrg.dwRealModeFlags & (lpwd->DosOpt[i].dwStdOpt >> 16));
}
}
}
}
if (bSelected)
{
return(OPTSEL_YES);
}
else
{
return(OPTSEL_NO);
}
}
void AppendStr(LPTEXTDATA lpTD, LPTSTR lpStr)
{
int cb = lstrlen(lpStr)*sizeof(TCHAR);
if ((lpTD->cb + cb + 2) <= MAX_CFG_FILE_SIZE*sizeof(TCHAR))
{
memcpy(lpTD->lpszData+lpTD->cb, lpStr, cb);
lpTD->cb += cb;
}
}
//
// Appends the string+cr/lf to the TextData structure.
//
void AppendLine(LPTEXTDATA lpTD, LPTSTR lpStr)
{
AppendStr(lpTD, lpStr);
AppendStr(lpTD, (LPTSTR)c_szCRLF);
}
//
// Returns NULL if none of the strings in szKeys matches the first entry
// in the specified string.
//
LPTSTR MatchesKey(LPTSTR lpszStr, LPTSTR lpszKeys)
{
UINT cch = lstrlen(lpszStr);
TCHAR szUpLine[20];
LPTSTR lpszCurKey;
if (cch >= ARRAYSIZE(szUpLine))
{
cch = ARRAYSIZE(szUpLine)-1;
}
memcpy(szUpLine, lpszStr, cch*sizeof(TCHAR));
szUpLine[cch] = 0;
CharUpper(szUpLine);
for (lpszCurKey = lpszKeys; *lpszCurKey; lpszCurKey = SkipStr(lpszCurKey))
{
UINT cchKey = lstrlen(lpszCurKey);
if ((cchKey < cch) &&
((szUpLine[cchKey] == TEXT(' ')) || (szUpLine[cchKey] == TEXT('='))) &&
(memcmp(lpszCurKey, szUpLine, cchKey*sizeof(TCHAR)) == 0))
{
return(lpszCurKey);
}
}
return(NULL);
}
//
// Copy the current environment into Autoexec.Bat
//
void CopyEnvironment(LPTEXTDATA lpAE)
{
TCHAR szKeys[MAX_PATH]; // SIZE?
TCHAR szSetCmd[20];
LPTSTR lpszCur = (LPTSTR)GetEnvironmentStrings();
LoadString(g_hinst, IDS_SETCMD, szSetCmd, ARRAYSIZE(szSetCmd));
LoadAndStrip(IDS_NOCOPYENV, szKeys, ARRAYSIZE(szKeys));
while (*lpszCur)
{
if (!MatchesKey(lpszCur, szKeys))
{
AppendStr(lpAE, szSetCmd);
AppendLine(lpAE, lpszCur);
}
lpszCur = SkipStr(lpszCur);
}
}
//
// Add keyboard type option for JKEYB.SYS
//
void SetJkeybOpt(LPTSTR lpszStr)
{
UINT cb, cbKey;
TCHAR szUpLine[64];
TCHAR lpszKey[] = TEXT("JKEYB.SYS");
TCHAR *lpszOpts[] = {TEXT(" /101"), TEXT(" /AX"), TEXT(" /106"), TEXT(" /J31DT"), TEXT(" /J31NB"), TEXT(" /J31LT")};
int KeybOpt;
int i;
ASSERT(lpszStr);
cb = lstrlen(lpszStr);
cbKey = lstrlen(lpszKey);
if (cb >= ARRAYSIZE(szUpLine))
{
cb = ARRAYSIZE(szUpLine)-1;
}
memcpy(szUpLine, lpszStr, cb*sizeof(TCHAR));
szUpLine[cb] = 0;
// AnsiUpper(szUpLine);
CharUpper(szUpLine);
for (i = 0; cbKey <= cb; i++, cb--)
{
if (memcmp(lpszKey, &szUpLine[i], cbKey*sizeof(TCHAR)) == 0)
{
// if (GetKeyboardType(0) == 7){
// switch(GetKeyboardType(1)) {
if (GetPrivateProfileInt(TEXT("keyboard"), TEXT("type"), 0, TEXT("SYSTEM.INI")) == 7)
{
switch(GetPrivateProfileInt(TEXT("keyboard"), TEXT("subtype"), 0, TEXT("SYSTEM.INI")))
{
case 0:
KeybOpt = 0;
break;
case 1:
KeybOpt = 1;
break;
case 2:
case 3:
case 4:
KeybOpt = 2;
break;
case 13:
KeybOpt = 3;
break;
case 14:
KeybOpt = 4;
break;
case 15:
KeybOpt = 5;
break;
default:
KeybOpt = 0;
break;
}
}
else
KeybOpt = 0;
lstrcat(lpszStr, lpszOpts[KeybOpt]);
break;
}
}
}
//
// Adds an option line from the specified value name to the TEXTDATA structure
//
BOOL AddOption(HKEY hk, LPCTSTR lpszValName, LPTEXTDATA lpTD,
LPTSTR lpszHighCmds, LPTSTR lpszLowCmd, BOOL bCanLoadHigh)
{
TCHAR szOptData[256];
UINT cb = sizeof(szOptData);
DWORD dwType;
LCID lcid = GetThreadLocale();
if (RegQueryValueEx(hk, lpszValName, NULL,
&dwType, (LPBYTE) szOptData, &cb) == ERROR_SUCCESS)
{
LPTSTR lpszAddData = szOptData;
DoEnvironmentSubst(szOptData, ARRAYSIZE(szOptData));
//
// Now remove LH or LoadHigh or DeviceHigh and replace with the
// appropriate string if EMM386 has not loaded yet.
//
if (!bCanLoadHigh)
{
LPTSTR lpszMatch = MatchesKey(szOptData, lpszHighCmds);
if (lpszMatch)
{
int cbHigh = lstrlen(lpszMatch);
if (lpszLowCmd)
{
int cbLow = lstrlen(lpszLowCmd);
lpszAddData += cbHigh - cbLow;
memcpy(lpszAddData, lpszLowCmd, cbLow*sizeof(TCHAR));
}
else
{
lpszAddData += cbHigh + 1;
}
}
}
if (PRIMARYLANGID(LANGIDFROMLCID(lcid))==LANG_JAPANESE)
{
SetJkeybOpt(lpszAddData);
}
AppendLine(lpTD, lpszAddData);
return(TRUE);
}
return(FALSE);
}
//
// Sets the appropriate configuration options in the PIF proprties
// If fForceCleanCfg is TRUE then a clean configuration is created. Otherwise
// the autoexec and config fields are nuked to force the app to use the current
// configuration.
//
PIFWIZERR SetConfOptions(LPWIZDATA lpwd, HWND hwndOptions, BOOL fForceCleanCfg)
{
TEXTDATA AE;
TEXTDATA CS;
int i;
PIFWIZERR err = PIFWIZERR_SUCCESS;
TCHAR szCSHighCmds[100];
TCHAR szCSLowCmd[20];
TCHAR szAEHighCmds[100];
BOOL bCanLoadHigh = FALSE;
//
// Make sure the real mode flag is set in the program properties.
//
PifMgr_GetProperties(lpwd->hProps, (LPSTR)GROUP_PRG, &(lpwd->PropPrg),
sizeof(lpwd->PropPrg), GETPROPS_NONE);
lpwd->PropPrg.flPrgInit |= PRGINIT_REALMODE;
PifMgr_SetProperties(lpwd->hProps, (LPSTR)GROUP_PRG, &(lpwd->PropPrg),
sizeof(lpwd->PropPrg), SETPROPS_NONE);
if (!fForceCleanCfg)
{
TCHAR NullStr = 0;
PifMgr_SetProperties(lpwd->hProps, AUTOEXECHDRSIG40, &NullStr, 0, SETPROPS_NONE);
PifMgr_SetProperties(lpwd->hProps, CONFIGHDRSIG40, &NullStr, 0, SETPROPS_NONE);
return(err);
}
//
// Load strings used to force drivers to load low if no EMM386.
//
LoadString(g_hinst, IDS_CSLOWSTR, szCSLowCmd, ARRAYSIZE(szCSLowCmd));
LoadAndStrip(IDS_CSHIGHSTRS, szCSHighCmds, ARRAYSIZE(szCSHighCmds));
LoadAndStrip(IDS_AEHIGHSTRS, szAEHighCmds, ARRAYSIZE(szAEHighCmds));
//
// Allocate memory for autoexec/config.sys buffers.
//
AE.lpszData = (LPTSTR)LocalAlloc(LPTR, MAX_CFG_FILE_SIZE*sizeof(TCHAR));
if (AE.lpszData == NULL)
{
return(PIFWIZERR_OUTOFMEM);
}
CS.lpszData = (LPTSTR)LocalAlloc(LPTR, MAX_CFG_FILE_SIZE*sizeof(TCHAR));
if (CS.lpszData == NULL)
{
LocalFree(AE.lpszData);
return(PIFWIZERR_OUTOFMEM);
}
AE.cb = CS.cb = 0;
//
// Copy the appropriate goop out of config.sys and autoexec.bat
//
CopyEnvironment(&AE);
for (i = 0; i < lpwd->NumOpts; i++)
{
int OptSel = OptSelected(lpwd, i, hwndOptions);
if (OptSel == OPTSEL_YES)
{
bCanLoadHigh |= (lpwd->DosOpt[i].dwFlags & DOSOPTF_PROVIDESUMB);
AddOption(lpwd->DosOpt[i].hk, c_szRegValAutoexec, &AE,
szAEHighCmds, NULL, bCanLoadHigh);
AddOption(lpwd->DosOpt[i].hk, c_szRegValConfigSys, &CS,
szCSHighCmds, szCSLowCmd, bCanLoadHigh);
//
// DOSOPTF_MULTIPLE will load multiple configuration from
// Config.Sys1 - Config.Sys9 and Autoexec.Bat1 - Autoexec.Bat9
//
if (lpwd->DosOpt[i].dwFlags & DOSOPTF_MULTIPLE)
{
BOOL ret;
TCHAR multicount[2];
TCHAR multiAutoexec[64];
TCHAR multiConfig[64];
lstrcpy(multicount,TEXT("1"));
while (1)
{
lstrcpy(multiAutoexec, c_szRegValAutoexec);
lstrcat(multiAutoexec, multicount);
lstrcpy(multiConfig, c_szRegValConfigSys);
lstrcat(multiConfig, multicount);
ret = AddOption(lpwd->DosOpt[i].hk, multiAutoexec, &AE,
szAEHighCmds, NULL, bCanLoadHigh);
ret |= AddOption(lpwd->DosOpt[i].hk, multiConfig, &CS,
szCSHighCmds, szCSLowCmd, bCanLoadHigh);
if (!ret)
break;
multicount[0] += 1;
if (multicount[0] > TEXT('9'))
break;
}
}
}
else
{
if (OptSel == OPTSEL_NOTSUPP)
{
err = PIFWIZERR_UNSUPPORTEDOPT;
}
}
}
//
// Set the properties in the PIF file
//
PifMgr_SetProperties(lpwd->hProps, AUTOEXECHDRSIG40, AE.lpszData, AE.cb, SETPROPS_NONE);
PifMgr_SetProperties(lpwd->hProps, CONFIGHDRSIG40, CS.lpszData, CS.cb, SETPROPS_NONE);
//
// Clean up allocated memory
//
LocalFree(AE.lpszData);
LocalFree(CS.lpszData);
return(err);
}
//
// The user hit the finish button. Set the proper configuration.
//
PIFWIZERR ConfigRealModeOptions(LPWIZDATA lpwd, HWND hwndOptList,
UINT uAction)
{
PIFWIZERR err = PIFWIZERR_GENERALFAILURE;
BOOL fCleanCfg;
switch(uAction)
{
case CRMOACTION_DEFAULT:
fCleanCfg = GetMSDOSOptGlobalFlags(lpwd) & DOSOPTGF_DEFCLEAN;
break;
case CRMOACTION_CLEAN:
fCleanCfg = TRUE;
break;
case CRMOACTION_CURRENT:
fCleanCfg = FALSE;
break;
}
//
// OK to call twice -- Returns true
//
if (ReadRegInfo(lpwd))
{
if (lpwd->hProps == 0)
{
if (CreateLink(lpwd))
{
TCHAR szLinkName[MAX_PATH];
GetLinkName(szLinkName, lpwd);
lpwd->hProps = PifMgr_OpenProperties(szLinkName, NULL, 0, OPENPROPS_NONE);
if (lpwd->hProps)
{
err = SetConfOptions(lpwd, hwndOptList, fCleanCfg);
PifMgr_CloseProperties(lpwd->hProps, CLOSEPROPS_NONE);
lpwd->hProps = 0;
}
}
}
else
{
err = SetConfOptions(lpwd, hwndOptList, fCleanCfg);
}
FreeRegInfo(lpwd);
}
return(err);
}
BOOL_PTR CALLBACK ConfigOptionsDlgProc(HWND hDlg, UINT message , WPARAM wParam, LPARAM lParam)
{
LPNMHDR lpnm = NULL;
LPPROPSHEETPAGE lpp = (LPPROPSHEETPAGE)(GetWindowLongPtr(hDlg, DWLP_USER));
LPWIZDATA lpwd = lpp ? (LPWIZDATA)lpp->lParam : NULL;
switch(message)
{
case WM_NOTIFY:
lpnm = (LPNMHDR)lParam;
if(lpnm)
{
switch(lpnm->code)
{
case LVN_ITEMCHANGED:
if(lpwd)
{
ItemChanged(lpwd, (LPNM_LISTVIEW)lParam);
}
break;
case NM_CLICK:
case NM_DBLCLK:
ConfOptClick(hDlg, lpnm);
break;
case LVN_KEYDOWN:
SetDlgMsgResult(hDlg, WM_NOTIFY,
ConfOptKeyDown(hDlg, (LV_KEYDOWN *)lParam));
break;
case PSN_SETACTIVE:
if(lpwd)
{
lpwd->hwnd = hDlg;
if (lpwd->dwFlags & WDFLAG_PIFPROP)
{
TCHAR szOK[20];
LoadString(g_hinst, IDS_OK, szOK, ARRAYSIZE(szOK));
PropSheet_SetFinishText(GetParent(hDlg), szOK);
}
else
{
PropSheet_SetWizButtons(GetParent(hDlg),
PSWIZB_FINISH | PSWIZB_BACK);
}
}
break;
case PSN_WIZFINISH:
if(lpwd)
{
ConfigRealModeOptions(lpwd, GetDlgItem(hDlg, IDC_OPTIONLIST),
CRMOACTION_CLEAN);
}
break;
case PSN_RESET:
if(lpwd)
{
CleanUpWizData(lpwd);
}
break;
default:
return FALSE;
}
}
break;
case WM_INITDIALOG:
ConfOptInit(hDlg, (LPPROPSHEETPAGE)lParam);
break;
default:
return FALSE;
} // end of switch on message
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////
void WhichConfInit(HWND hDlg, LPPROPSHEETPAGE lpp)
{
LPWIZDATA lpwd = InitWizSheet(hDlg, (LPARAM)lpp, 0);
CheckRadioButton(hDlg, IDB_CURCFG, IDB_CLEANCFG,
GetMSDOSOptGlobalFlags(lpwd) & DOSOPTGF_DEFCLEAN ?
IDB_CLEANCFG : IDB_CURCFG);
}
void SetChoiceWizBtns(LPWIZDATA lpwd)
{
PropSheet_SetWizButtons(GetParent(lpwd->hwnd),
IsDlgButtonChecked(lpwd->hwnd, IDB_CLEANCFG) ?
PSWIZB_NEXT | PSWIZB_BACK :
PSWIZB_FINISH | PSWIZB_BACK);
}
BOOL_PTR CALLBACK PickConfigDlgProc(HWND hDlg, UINT message , WPARAM wParam, LPARAM lParam)
{
LPNMHDR lpnm = NULL;
LPPROPSHEETPAGE lpp = (LPPROPSHEETPAGE)(GetWindowLongPtr(hDlg, DWLP_USER));
LPWIZDATA lpwd = lpp ? (LPWIZDATA)lpp->lParam : NULL;
switch(message)
{
case WM_NOTIFY:
lpnm = (LPNMHDR)lParam;
if(lpnm)
{
switch(lpnm->code)
{
case PSN_SETACTIVE:
if(lpwd)
{
lpwd->hwnd = hDlg;
if (MustRebootSystem())
{
SetDlgMsgResult(hDlg, WM_NOTIFY, -1);
}
else
{
SetChoiceWizBtns(lpwd);
}
}
break;
case PSN_WIZFINISH:
if(lpwd)
{
ConfigRealModeOptions(lpwd, GetDlgItem(hDlg, IDC_OPTIONLIST),
CRMOACTION_CURRENT);
}
break;
case PSN_RESET:
if(lpwd)
{
CleanUpWizData(lpwd);
}
break;
default:
return FALSE;
}
}
break;
case WM_COMMAND:
switch (GET_WM_COMMAND_ID(wParam, lParam))
{
case IDB_CURCFG:
case IDB_CLEANCFG:
if(lpwd)
{
SetChoiceWizBtns(lpwd);
}
}
break;
case WM_INITDIALOG:
WhichConfInit(hDlg, (LPPROPSHEETPAGE)lParam);
break;
default:
return FALSE;
} // end of switch on message
return TRUE;
}