291 lines
7.8 KiB
C
291 lines
7.8 KiB
C
|
//
|
|||
|
// MSDOS.C Wizard started by SHELL.VxD
|
|||
|
//
|
|||
|
// Copyright (C) Microsoft, 1994,1995 All Rights Reserved.
|
|||
|
//
|
|||
|
// History:
|
|||
|
// 3/20/95 [stevecat] - NT port & real clean up, unicode, etc.
|
|||
|
//
|
|||
|
//
|
|||
|
#include "priv.h"
|
|||
|
#include "appwiz.h"
|
|||
|
#include <wshioctl.h>
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// This exported entry point is called by RUNDLL32 when a VxD calls the
|
|||
|
// Shell_SuggestSingleMSDOSMode service.
|
|||
|
//
|
|||
|
|
|||
|
void WINAPI SingleMSDOSWizard(HWND hwnd, HINSTANCE hAppInstance, LPTSTR lpszCmdLine, int nCmdShow)
|
|||
|
{
|
|||
|
WIZDATA wd;
|
|||
|
|
|||
|
memset(&wd, 0, sizeof(wd));
|
|||
|
|
|||
|
wd.hwnd = hwnd;
|
|||
|
|
|||
|
if (GetSingleAppInfo(&wd))
|
|||
|
{
|
|||
|
if (wd.hProps != 0)
|
|||
|
{
|
|||
|
MSDOSPropOnlyWizard(&wd);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
wd.dwFlags |= WDFLAG_SINGLEAPP;
|
|||
|
LinkWizard(&wd);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Note, we close properties here in case GetSingleAppInfo returned false,
|
|||
|
// but still had opened the hProps.
|
|||
|
//
|
|||
|
|
|||
|
if (wd.hProps != 0)
|
|||
|
{
|
|||
|
PifMgr_CloseProperties(wd.hProps, CLOSEPROPS_NONE);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Inline helper function. If the name ends with the extension .EXE, .BAT,
|
|||
|
// or .COM then we'll accept it. Otherwise, try to take the given name and
|
|||
|
// convert it to a program name we can execute. This fixes the case where
|
|||
|
// Flight Simulator's setup program runs FS5.OVL. The user should really
|
|||
|
// run FS5.BAT.
|
|||
|
//
|
|||
|
|
|||
|
HRESULT _inline CleanUpName(LPWIZDATA lpwd)
|
|||
|
{
|
|||
|
LPCTSTR PathDirs[2];
|
|||
|
LPTSTR pszExt;
|
|||
|
LPTSTR pszCurExt;
|
|||
|
TCHAR szValidExt[100];
|
|||
|
|
|||
|
ASSERT(lpwd);
|
|||
|
pszExt = PathFindExtension(lpwd->szExeName);
|
|||
|
if (!pszExt)
|
|||
|
{
|
|||
|
return E_FAIL;
|
|||
|
}
|
|||
|
PathDirs[0] = lpwd->szWorkingDir;
|
|||
|
PathDirs[1] = NULL;
|
|||
|
|
|||
|
if (*pszExt)
|
|||
|
pszExt++; // NSL: *pszExt == '.' so this should be fine
|
|||
|
|
|||
|
//
|
|||
|
// Make sure that the extension is a real progarm extension (not .OVL
|
|||
|
// for example. If it is, search for the matching name.
|
|||
|
//
|
|||
|
szValidExt[0] = TEXT('\0');
|
|||
|
if (!LoadAndStrip(IDS_EXTENSIONS, szValidExt, ARRAYSIZE(szValidExt)))
|
|||
|
{
|
|||
|
return E_FAIL;
|
|||
|
}
|
|||
|
|
|||
|
pszCurExt = szValidExt;
|
|||
|
|
|||
|
while (*pszCurExt)
|
|||
|
{
|
|||
|
if (lstrcmpi(pszExt, pszCurExt) == 0)
|
|||
|
{
|
|||
|
if (PathResolve(lpwd->szExeName, PathDirs, PRF_VERIFYEXISTS | PRF_TRYPROGRAMEXTENSIONS))
|
|||
|
{
|
|||
|
return S_OK;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
return S_FALSE;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
pszCurExt = SkipStr(pszCurExt);
|
|||
|
}
|
|||
|
|
|||
|
pszCurExt = szValidExt;
|
|||
|
|
|||
|
while (*pszCurExt)
|
|||
|
{
|
|||
|
lstrcpy(pszExt, pszCurExt);
|
|||
|
|
|||
|
if (PathResolve(lpwd->szExeName, PathDirs, PRF_VERIFYEXISTS | PRF_TRYPROGRAMEXTENSIONS))
|
|||
|
{
|
|||
|
return S_OK;
|
|||
|
}
|
|||
|
|
|||
|
pszCurExt = SkipStr(pszCurExt);
|
|||
|
}
|
|||
|
return S_FALSE;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
BOOL GetSingleAppInfo(LPWIZDATA lpwd)
|
|||
|
{
|
|||
|
HANDLE hDevice;
|
|||
|
BOOL bMakeLink = FALSE;
|
|||
|
SINGLEAPPSTRUC SAS;
|
|||
|
DWORD dwRetSize;
|
|||
|
LPDWORD lpResult;
|
|||
|
HRESULT hr;
|
|||
|
|
|||
|
hDevice = CreateFile(SHELLFILENAME, GENERIC_WRITE, FILE_SHARE_WRITE, NULL,
|
|||
|
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
|||
|
|
|||
|
if (hDevice == INVALID_HANDLE_VALUE)
|
|||
|
{
|
|||
|
return(FALSE);
|
|||
|
}
|
|||
|
|
|||
|
if (DeviceIoControl(hDevice, WSHIOCTL_GET1APPINFO, NULL, 0,
|
|||
|
&SAS, sizeof(SAS), &dwRetSize, NULL))
|
|||
|
{
|
|||
|
|
|||
|
#define fVMDead ((BOOL)(SAS.SSA_dwFlags & SSAMFLAG_KILLVM))
|
|||
|
|
|||
|
int idString = fVMDead ? IDS_VMCLOSED : IDS_VMSTILLALIVE;
|
|||
|
|
|||
|
TraceMsg(TF_ERROR, "%s", "Got info on a single MS-DOS mode app. Now will show Exe, Command line params, directory, and PIF.");
|
|||
|
TraceMsg(TF_ERROR, "%s", SAS.SSA_ProgName);
|
|||
|
TraceMsg(TF_ERROR, "%s", SAS.SSA_CommandLine);
|
|||
|
TraceMsg(TF_ERROR, "%s", SAS.SSA_CurDir);
|
|||
|
TraceMsg(TF_ERROR, "%s", SAS.SSA_PIFPath);
|
|||
|
|
|||
|
if (SAS.SSA_dwFlags & SSAMFLAG_FROMREGLIST)
|
|||
|
{
|
|||
|
SHELLEXECUTEINFO ei;
|
|||
|
|
|||
|
lpResult = (LPVOID)SAS.SSA_ResultPtr;
|
|||
|
*lpResult = SSR_KILLAPP;
|
|||
|
|
|||
|
DeviceIoControl(hDevice, WSHIOCTL_SIGNALSEM, &SAS, sizeof(SAS),
|
|||
|
NULL, 0, NULL, NULL);
|
|||
|
|
|||
|
ei.cbSize = sizeof(ei);
|
|||
|
ei.hwnd = lpwd->hwnd;
|
|||
|
ei.lpVerb = NULL;
|
|||
|
ei.fMask = 0;
|
|||
|
ei.lpFile = SAS.SSA_ProgName;
|
|||
|
|
|||
|
if (SAS.SSA_CommandLine[0] == 0)
|
|||
|
{
|
|||
|
ei.lpParameters = NULL;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
ei.lpParameters = SAS.SSA_CommandLine;
|
|||
|
}
|
|||
|
|
|||
|
if (SAS.SSA_CurDir == TEXT('\0'))
|
|||
|
{
|
|||
|
ei.lpDirectory = NULL;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
ei.lpDirectory = SAS.SSA_CurDir;
|
|||
|
}
|
|||
|
|
|||
|
ei.lpClass = NULL;
|
|||
|
ei.nShow = SW_SHOWDEFAULT;
|
|||
|
ei.hInstApp = g_hinst;
|
|||
|
|
|||
|
ShellExecuteEx(&ei);
|
|||
|
goto CloseHandleExit;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
if (SAS.SSA_dwFlags & SSAMFLAG_REQREALMODE)
|
|||
|
{
|
|||
|
lpwd->dwFlags |= WDFLAG_REALMODEONLY;
|
|||
|
}
|
|||
|
|
|||
|
lstrcpyn(lpwd->szExeName, SAS.SSA_ProgName, ARRAYSIZE(lpwd->szExeName));
|
|||
|
lstrcpyn(lpwd->szParams, SAS.SSA_CommandLine, ARRAYSIZE(lpwd->szParams));
|
|||
|
lstrcpyn(lpwd->szWorkingDir, SAS.SSA_CurDir, ARRAYSIZE(lpwd->szWorkingDir));
|
|||
|
|
|||
|
|
|||
|
hr = CleanUpName(lpwd);
|
|||
|
if (FAILED(hr))
|
|||
|
{
|
|||
|
bMakeLink = FALSE;
|
|||
|
goto CloseHandleExit;
|
|||
|
}
|
|||
|
else if (hr == S_OK)
|
|||
|
{
|
|||
|
DetermineExeType(lpwd);
|
|||
|
lpwd->dwFlags |= WDFLAG_NOBROWSEPAGE;
|
|||
|
|
|||
|
//
|
|||
|
// There are three different possibilities with SSA_PIFPath:
|
|||
|
// Empty string indicates program run from command line.
|
|||
|
// " " indicates exe run from shell, but no PIF exists
|
|||
|
// Name of PIF that was run.
|
|||
|
// If the program was run from command.com then we will force
|
|||
|
// the user to create a shortcut. If not started from a specific
|
|||
|
// PIF then we'll set the default properties for the program. If
|
|||
|
// started from a specific PIF then we'll set the properties for
|
|||
|
// that PIF.
|
|||
|
//
|
|||
|
|
|||
|
if (SAS.SSA_PIFPath[0] != 0)
|
|||
|
{
|
|||
|
lpwd->hProps = PifMgr_OpenProperties((SAS.SSA_PIFPath[0] == TEXT(' ')) ?
|
|||
|
lpwd->szExeName : SAS.SSA_PIFPath,
|
|||
|
NULL, 0, OPENPROPS_NONE);
|
|||
|
|
|||
|
if (lpwd->hProps != 0)
|
|||
|
{
|
|||
|
idString = fVMDead ? IDS_CHGPROPCLOSED
|
|||
|
: IDS_CHGPROPSTILLALIVE;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
LPTSTR pszStartName = PathFindFileName(lpwd->szExeName);
|
|||
|
|
|||
|
*pszStartName = 0;
|
|||
|
|
|||
|
LoadStringA(g_hinst, IDS_GENERICNAME,
|
|||
|
lpwd->PropPrg.achTitle, ARRAYSIZE(lpwd->PropPrg.achTitle));
|
|||
|
}
|
|||
|
|
|||
|
bMakeLink = (IDYES == ShellMessageBox(g_hinst,
|
|||
|
lpwd->hwnd,
|
|||
|
MAKEINTRESOURCE(idString),
|
|||
|
MAKEINTRESOURCE(IDS_1APPWARNTITLE),
|
|||
|
MB_YESNO | MB_DEFBUTTON1 | MB_ICONEXCLAMATION,
|
|||
|
lpwd->PropPrg.achTitle));
|
|||
|
|
|||
|
lpResult = (LPVOID)SAS.SSA_ResultPtr;
|
|||
|
|
|||
|
if (!fVMDead && lpResult != NULL)
|
|||
|
{
|
|||
|
if (bMakeLink)
|
|||
|
{
|
|||
|
*lpResult = (SAS.SSA_dwFlags & SSAMFLAG_FROMREGLIST) ?
|
|||
|
SSR_KILLAPP : SSR_CLOSEVM;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
*lpResult = SSR_CONTINUE;
|
|||
|
}
|
|||
|
|
|||
|
DeviceIoControl(hDevice, WSHIOCTL_SIGNALSEM, &SAS, sizeof(SAS),
|
|||
|
NULL, 0, NULL, NULL);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
CloseHandleExit:
|
|||
|
|
|||
|
CloseHandle(hDevice);
|
|||
|
|
|||
|
return(bMakeLink);
|
|||
|
|
|||
|
#undef fVMDead
|
|||
|
}
|
|||
|
|