Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

314 lines
8.7 KiB

// Copyright Microsoft Corp 1995
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ver.h>
#include <io.h>
#include "resource.h"
// Directory Path parts For Non x86 also the
// Environment string match
const LPSTR pi386 = {"i386"}; // Environment = x86
const LPSTR px86 = {"x86"};
const LPSTR pMIPS = {"MIPS"};
const LPSTR pALPHA = {"ALPHA"};
const LPSTR pPPC = {"PPC"};
const LPSTR pClientsDir = {"clients\\"};
const LPSTR pWinNTDir = {"WinNT\\"};
const LPSTR pWIN95 = {"WIN95"};
const LPSTR pWin31x = {"win31x"};
LPSTR pSetup = {"install.exe"};
const LPSTR pWin95Setup = {"install.bat"};
// Item for looking ut what the setup "subtype" is
// Filename, Section and Key for GetPrivateProfileString()
const LPSTR pSETUPINF = { "INsetup.inf" };
const LPSTR pSection = { "Internet Services"};
const LPSTR pEntry = {"setup"};
const LPSTR pDefault = {"master"};
enum eSubDirSetup {
eMasterSetup,
eClientSetup,
eAdminSetup,
eUnKnowsSetup
};
// For SubType setup
struct {
const LPSTR pszKey;
enum eSubDirSetup eSetupType;
} SetupType[] = {
{ "master" , eMasterSetup },
{ "client" , eClientSetup },
{ "admin" , eAdminSetup },
{ NULL, 0 } // End of the list
};
/* **************************************************************** */
void
ErrorMsgBox(HANDLE hInstance, int MessageID)
{
int Rtn;
char szTitle[255];
char szMessage[255];
Rtn = LoadString( hInstance, IDS_EMSGTITLE, szTitle, sizeof szTitle );
Rtn = LoadString( hInstance, MessageID, szMessage, sizeof szMessage );
// if no string found then just give up..
if (Rtn)
MessageBox(NULL, szMessage, szTitle, MB_ICONSTOP);
}
/* **************************************************************** */
// Return an Index that Indicates the Setup mode, one of the following
// master, client, admin
//
// Open a INsetup.ini file in the local dir where this setup was run from,
// in there is a key that tell us what setup mode we are running in.
// Another way might have been to use the path or the contents of dir, For
// example clients has a WinNt dir, but admin does not, master has cleints
// and admin dirs, etc. This seems contrived, inflexable, and subjet to errors
// if someone changes the directory structure.
//
// Using the INI file allow admin to copy the Sub-dirs, clients,and admin to
// any place in the file system and setup will still work.correctly,
enum eSubDirSetup
CheckSetupType( LPSTR pPath )
{
char szBuffer[_MAX_PATH];
char szValue[_MAX_PATH];
int Rtn, i;
_fstrcpy(szBuffer,pPath);
_fstrcat(szBuffer,pSETUPINF);
Rtn = GetPrivateProfileString(
pSection, // lpszSection,
pEntry, // lpszEntry,
pDefault, // lpszDefault,
szValue, // lpszReturnBuffer,
sizeof szValue, // cbReturnBuffer,
szBuffer); // lpszFilename)
if( Rtn )
for( i = 0; SetupType[i].pszKey != NULL; i++ )
if ( !_fstricmp( (LPSTR) szValue,(LPSTR) SetupType[i].pszKey) ) // Equal to
return SetupType[i].eSetupType;
return eUnKnowsSetup; // Should never happend because of default value....
}
/* **************************************************************** */
int PASCAL WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
HANDLE hInstance; /* current instance */
HANDLE hPrevInstance; /* previous instance */
LPSTR lpCmdLine; /* command line */
int nCmdShow; /* show-window type (open/icon) */
{
char szPath[_MAX_PATH], szExeStr[_MAX_PATH];
char szTemp[_MAX_PATH], szWin95Setup[_MAX_PATH];
int Rtn;
LPSTR pDir, pCpu;
enum eSubDirSetup eSetupType;
int Show = SW_SHOW;
// Get the current Windows Versiop
// Win 95 = 3.95
// NT = 3.10
// NT SUR = ??
DWORD Version=GetVersion();
#ifdef VERBOSE
{
char szBuf[200];
wsprintf(szBuf, "Windows version %d.%d\n",
LOBYTE(LOWORD(Version)),
HIBYTE(LOWORD(Version)));
MessageBox(NULL, szBuf, "Windows Version", MB_OK);
}
#endif
GetModuleFileName(hInstance, szPath, _MAX_PATH);
*(_fstrrchr(szPath, '\\')+1) = '\0'; // Strip setup.exe off path
// ** WILL BREAK FOR MULTIBYTE **
// Check what Setup mode we are running in
// Master, Client, or Admin
eSetupType = CheckSetupType( szPath );
// None of the above, this should never happen
// because the default is master, but check never the less
if ( eSetupType == eUnKnowsSetup ) {
ErrorMsgBox(hInstance, IDS_CANTRUN);
exit(1);
}
// Get the Processor Architecture, Return value should be one of
// x86, MIPS, ALPHA, PPC, anything else is not supported.
pCpu = getenv("PROCESSOR_ARCHITECTURE");
if (pCpu != NULL ) // This little trick is necessary
if( *pCpu == 0) // because NT and Win95 work differently
pCpu = NULL; // with Unknown Evironment variables
// if no value returned, see if this is an NT System by checking
// the OS environment variable, should be WindowsNT if it exists..
// if neither OS or PROCESSOR_ARCHITECTURE, we are either on a
// Win95/Win3.x system or a badly mananged NT, IF OS is set
// but not PROCESSOR_ARCHITECTURE, we are more than likly on a
// NT system, but can't figure our what processor we are running
// so refuse to install until this condition is corrected.
// turns out the trying to delete PROCESSOR_ARCHITECTURE is can only
// be accomplished in small windows of time, because it seems to be self reparing
// to a degree. The Kernel replaces Environment variable if you delete
// from the system control pannel, How every you seem be able to spawn
// a limited number of processes or NTVDM's until the problem is corrected.
if (pCpu == NULL ) {
LPSTR pOS = getenv("OS");
if (pOS != NULL )
if( *pOS == 0)
pOS = NULL;
if (pOS != NULL ) {
// if OS is what we expect
if (!lstrcmp(pOS, "Windows_NT")){ // Equal to
// Egads, We have OS set but not PROCESSOR_ARCHITECTURE
// It could be NT but we don't what Kind of processor it is
ErrorMsgBox(hInstance, IDS_BADENV);
exit(1);
}
}
// Else we fall through and assume is Win3.X or Win95
// PROCESSOR_ARCHITECTURE Not defined, Assume it's NOT NT
// HiByte of LowWord is Windows Minor Version
if (HIBYTE(LOWORD(Version)) > 11){ // Check if Win95
pDir = pWIN95;
if ( eSetupType == eMasterSetup ) {
_fstrcpy(szTemp, pClientsDir);
_fstrcat(szTemp, pDir );
}else
_fstrcpy(szTemp, pDir );
// for Win95 Arg1 is the path to where the batch file is
if( _fstrlen(pWin95Setup)+_fstrlen(szPath)+_fstrlen(szTemp) > sizeof szWin95Setup ) {
ErrorMsgBox(hInstance, IDS_PATHTOLONG);
exit(1);
}
wsprintf(szWin95Setup,"%ls %ls%ls",(LPSTR)pWin95Setup,(LPSTR)szPath, (LPSTR)szTemp );
pSetup = szWin95Setup;
Show = SW_HIDE; // Win95 is a batch file hide it...
}
else // Assume it's Win3.1x
pDir = pWin31x;
// If we are at the Master Level we need to add a
// Clients dir to the path
// Admin setup is not supported from NON NT systems.
if ( eSetupType == eMasterSetup ) {
_fstrcpy(szTemp, pClientsDir);
_fstrcat(szTemp, pDir );
pDir = szTemp;
} else if ( eSetupType == eAdminSetup ) {
ErrorMsgBox(hInstance, IDS_NOTSUPPORTADMIN);
exit (1);
}
} else {
// ok we have a "valid" Cpu string lets match it to one of the ones we know
if (!lstrcmp(pCpu, px86)) // Equal to
pDir = pi386;
else if (!lstrcmp(pCpu, pMIPS)) // Equal to
pDir = pMIPS;
else if (!lstrcmp(pCpu, pALPHA)) // Equal to
pDir = pALPHA;
else if (!lstrcmp(pCpu, pPPC)) // Equal to
pDir = pPPC;
else {
// Opps not a supported string...
ErrorMsgBox(hInstance, IDS_NOTSUPPORT);
exit(1);
}
// if we are running from the Client dir we must add a WinNT
// to processor pathname
if ( eSetupType == eClientSetup ) {
_fstrcpy(szTemp, pWinNTDir);
_fstrcat(szTemp, pDir );
pDir = szTemp;
}
}
//chect the path lengths to see if we will overrun szExeStr
if( strlen(szPath) + _fstrlen(szExeStr),
+ _fstrlen(pSetup) + _fstrlen(lpCmdLine) + 4> sizeof szExeStr ) {
ErrorMsgBox(hInstance, IDS_PATHTOLONG);
exit(1);
}
// build the path to the exe
wsprintf(szExeStr, "%ls%ls\\%ls ", (LPSTR)szPath, pDir, pSetup );
if (*lpCmdLine != 0) {
lstrcat(szExeStr, lpCmdLine);
}
// #define VERBOSE
#ifdef VERBOSE
MessageBox(NULL, szExeStr, "WinExec()", MB_OK);
#endif // VERBOSE
// Execute the proper setup
Rtn = WinExec(szExeStr, Show);
if (Rtn < 32) {
ErrorMsgBox(hInstance, IDS_CANTRUN);
exit(1);
}
return 0;
}