|
|
#include "precomp.h"
#pragma hdrstop
/*++
Copyright (c) 1990 Microsoft Corporation
Module Name:
detect1.c
Abstract:
Detect module for Win32 PDK Setup. This module has no external dependencies and is not statically linked to any part of Setup.
Author:
Ted Miller (tedm) June 1991
--*/
#define PROCESSOR_NONE ""
#define PROCESSOR_I386 "I386"
#define PROCESSOR_I486 "I486"
#define PROCESSOR_I586 "I586"
#define PROCESSOR_R4000 "R4000"
#define PROCESSOR_ALPHA "Alpha_AXP"
#define PROCESSOR_PPC601 "PPC601"
#define PROCESSOR_PPC603 "PPC603"
#define PROCESSOR_PPC604 "PPC604"
#define PROCESSOR_PPC620 "PPC620"
#define PLATFORM_NONE ""
#define PLATFORM_I386 "I386"
#define PLATFORM_MIPS "Mips"
#define PLATFORM_ALPHA "Alpha"
#define PLATFORM_PPC "ppc"
//
// Local prototypes
//
BOOL MatchNtPathToDosPath( PUNICODE_STRING, PUNICODE_STRING, SZ, SZ, CB ); VOID ConvertUnicodeToAnsi( PUNICODE_STRING, SZ );
/*
oemcp as a string */ CB GetOemCodepage( IN RGSZ Args, IN USHORT cArgs, OUT SZ ReturnBuffer, IN CB cbReturnBuffer ) { UINT cp;
Unused(Args); Unused(cArgs); Unused(cbReturnBuffer);
cp = GetOEMCP();
wsprintf(ReturnBuffer,"%u",cp); return(lstrlen(ReturnBuffer)+1); }
/*
ansicp as a string */ CB GetAnsiCodepage( IN RGSZ Args, IN USHORT cArgs, OUT SZ ReturnBuffer, IN CB cbReturnBuffer ) { UINT cp;
Unused(Args); Unused(cArgs); Unused(cbReturnBuffer);
cp = GetACP();
wsprintf(ReturnBuffer,"%u",cp); return(lstrlen(ReturnBuffer)+1); }
/*
langauge type as a string */ CB GetLanguage( IN RGSZ Args, IN USHORT cArgs, OUT SZ ReturnBuffer, IN CB cbReturnBuffer ) { //
// bugbug ramonsa - enable when GetQualifiedLocale returns something
// meaningful
#ifdef LOCALE_STUFF
LCID LcId = {0,0,0}; LCSTRINGS LcStrings;
Unused(Args); Unused(cArgs); Unused(cbReturnBuffer);
ReturnBuffer[0] = '\0';
if ( GetQualifiedLocale( QF_LCID, &LcId, NULL, &LcStrings ) ) {
lstrcpy(ReturnBuffer,LcStrings.szLanguage); return(lstrlen(ReturnBuffer)+1); }
return 0; #else
#define TEMP_LANGUAGE "ENG"
Unused(Args); Unused(cArgs); Unused(cbReturnBuffer);
lstrcpy(ReturnBuffer,TEMP_LANGUAGE); return(lstrlen(ReturnBuffer)+1);
#endif
}
/*
* GetSystemDate - returns a list of date information in the following * order: * sec after 1-1-1970, year, month, day, hour, minute, second, millisecond * */
CB GetSystemDate( IN RGSZ Args, IN USHORT cArgs, OUT SZ ReturnBuffer, IN CB cbReturnBuffer ) { SYSTEMTIME systime; time_t timet;
Unused( Args ); Unused( cArgs ); Unused( cbReturnBuffer );
GetSystemTime( &systime ); time( &timet );
wsprintf(ReturnBuffer, "{\"%d\",\"%d\",\"%d\",\"%d\",\"%d\",\"%d\",\"%d\",\"%d\"}", timet, systime.wYear, systime.wMonth, systime.wDay, systime.wHour, systime.wMinute, systime.wSecond, systime.wMilliseconds );
return(lstrlen(ReturnBuffer)+1); }
/*
Country type as a string */ CB GetCountry( IN RGSZ Args, IN USHORT cArgs, OUT SZ ReturnBuffer, IN CB cbReturnBuffer ) { //
// bugbug ramonsa - enable when GetQualifiedLocale returns something
// meaningful
#ifdef LOCALE_STUFF
LCID LcId = {0,0,0}; LCSTRINGS LcStrings;
Unused(Args); Unused(cArgs); Unused(cbReturnBuffer);
ReturnBuffer[0] = '\0';
if ( GetQualifiedLocale( QF_LCID, &LcId, NULL, &LcStrings ) ) {
lstrcpy(ReturnBuffer,LcStrings.szCountry); return(lstrlen(ReturnBuffer)+1); }
return 0;
#else
#define TEMP_COUNTRY "US"
Unused(Args); Unused(cArgs); Unused(cbReturnBuffer);
lstrcpy(ReturnBuffer,TEMP_COUNTRY); return(lstrlen(ReturnBuffer)+1);
#endif
}
CB GetProcessor( IN RGSZ Args, IN USHORT cArgs, OUT SZ ReturnBuffer, IN CB cbReturnBuffer ) { SYSTEM_INFO SystemInfo; SZ szProcessor;
Unused(Args); Unused(cArgs); Unused(cbReturnBuffer);
GetSystemInfo( &SystemInfo );
switch ( SystemInfo.wProcessorArchitecture ) {
case PROCESSOR_ARCHITECTURE_INTEL: if (SystemInfo.wProcessorLevel == 3) { szProcessor = PROCESSOR_I386; } else if (SystemInfo.wProcessorLevel == 4) { szProcessor = PROCESSOR_I486; } else { szProcessor = PROCESSOR_I586; } break;
case PROCESSOR_ARCHITECTURE_MIPS: szProcessor = PROCESSOR_R4000; break;
case PROCESSOR_ARCHITECTURE_ALPHA: szProcessor = PROCESSOR_ALPHA; break;
case PROCESSOR_ARCHITECTURE_PPC: if (SystemInfo.wProcessorLevel == 1) { szProcessor = PROCESSOR_PPC601; } else if (SystemInfo.wProcessorLevel == 3) { szProcessor = PROCESSOR_PPC603; } else if (SystemInfo.wProcessorLevel == 4) { szProcessor = PROCESSOR_PPC604; } else if (SystemInfo.wProcessorLevel == 6) { szProcessor = PROCESSOR_PPC603; } else if (SystemInfo.wProcessorLevel == 7) { szProcessor = PROCESSOR_PPC603; } else if (SystemInfo.wProcessorLevel == 9) { szProcessor = PROCESSOR_PPC604; } else if (SystemInfo.wProcessorLevel == 20) { szProcessor = PROCESSOR_PPC620; } else { szProcessor = PROCESSOR_PPC601; } break;
default: //
// There could be processors we don't know about.
// Try to make sure we'll at least set up on them
// by defaulting to a known processor. This also eliminates
// the need to keep updating the INFs to know about all the
// processors we support.
//
szProcessor = PROCESSOR_NONE; #ifdef _X86_
//
// Probably a P6 or greater.
//
szProcessor = PROCESSOR_I586; #endif
#ifdef _MIPS_
//
// Probably something that came after the R4000.
// Assume R4000 to be safe.
//
szProcessor = PROCESSOR_R4000; #endif
#ifdef _ALPHA_
//
// Just recognize that it's an Alpha.
//
szProcessor = PROCESSOR_ALPHA; #endif
#ifdef _PPC_
//
// Just call it a 601, which is assumed to be
// the lowest common denominator.
//
szProcessor = PROCESSOR_PPC601; #endif
break; }
lstrcpy( ReturnBuffer, szProcessor ); return lstrlen( ReturnBuffer)+1; }
CB GetPlatform( IN RGSZ Args, IN USHORT cArgs, OUT SZ ReturnBuffer, IN CB cbReturnBuffer ) { SYSTEM_INFO SystemInfo; SZ szPlatform;
Unused(Args); Unused(cArgs); Unused(cbReturnBuffer);
GetSystemInfo( &SystemInfo );
switch ( SystemInfo.wProcessorArchitecture ) {
case PROCESSOR_ARCHITECTURE_INTEL: szPlatform = PLATFORM_I386; break;
case PROCESSOR_ARCHITECTURE_MIPS: szPlatform = PLATFORM_MIPS; break;
case PROCESSOR_ARCHITECTURE_ALPHA: szPlatform = PLATFORM_ALPHA; break;
case PROCESSOR_ARCHITECTURE_PPC: szPlatform = PLATFORM_PPC; break;
default: szPlatform = PLATFORM_NONE;
//
// Try really hard to return a reasonable value by
// assuming that the code is running on a machine of the
// platform for which the it was compiled.
// This lets us run on processors we haven't invented yet
// and whose ids are thus not accounted for in the aboce
// cases.
//
#ifdef _X86_
szPlatform = PLATFORM_I386; #endif
#ifdef _MIPS_
szPlatform = PLATFORM_MIPS; #endif
#ifdef _ALPHA_
szPlatform = PLATFORM_ALPHA; #endif
#ifdef _PPC_
szPlatform = PLATFORM_PPC; #endif
break; }
lstrcpy( ReturnBuffer, szPlatform ); return lstrlen( ReturnBuffer)+1; }
/*
Memory size as an ASCII string (Kb) */ CB GetMemorySize( IN RGSZ Args, IN USHORT cArgs, OUT SZ ReturnBuffer, IN CB cbReturnBuffer ) { MEMORYSTATUS MemoryStatus;
Unused(Args); Unused(cArgs); Unused(cbReturnBuffer);
GlobalMemoryStatus(&MemoryStatus); _ultoa((ULONG)(MemoryStatus.dwTotalPhys/1024),ReturnBuffer,10); return(lstrlen(ReturnBuffer)+1); }
/*
Minimum pagefile size necessary for crash dump support (MB) */ CB GetCrashDumpSize( IN RGSZ Args, IN USHORT cArgs, OUT SZ ReturnBuffer, IN CB cbReturnBuffer ) { MEMORYSTATUS ms; SYSTEM_INFO si;
Unused(Args); Unused(cArgs); Unused(cbReturnBuffer);
GlobalMemoryStatus(&ms); GetSystemInfo(&si); //
// We need a pagefile as large as physical memory + 1 page.
//
_ultoa( (ULONG)((ms.dwTotalPhys + si.dwPageSize + 0xFFFFF) >> 20), ReturnBuffer, 10); return(lstrlen(ReturnBuffer)+1); }
/*
list of paths on which a given file appears. */
CB FindFileInstances( IN RGSZ Args, IN USHORT cArgs, OUT SZ ReturnBuffer, IN CB cbReturnBuffer ) { CB rc = 0; SZ sz; RGSZ rgszFiles; HANDLE hff; WIN32_FIND_DATA FindFileData;
Unused(cbReturnBuffer);
//
// If no file specified then return 0
//
if (cArgs != 1) { return rc; }
//
// If invalid filename then return 0
if ((lstrlen(Args[0]) + 1) > MAX_PATH) { return rc; }
//
// Allocate just the NULL terminator for the rgsz structure
//
rgszFiles = RgszAlloc(1); if (!rgszFiles) { return rc; }
//
// Do find first, find next adding files found to the rgsz structure
//
if ((hff = FindFirstFile( Args[0], &FindFileData )) != (HANDLE)-1) {
do { if (!RgszAdd( &rgszFiles, SzDup( (SZ)FindFileData.cFileName ) )) { FindClose( hff ); return rc; } } while (FindNextFile(hff, &FindFileData));
FindClose( hff ); }
//
// Convert the rgsz structure to a sz list value and copy this over
// to the return buffer.
//
sz = SzListValueFromRgsz( rgszFiles );
if ( sz ) {
lstrcpy( ReturnBuffer, sz ); rc = lstrlen(sz) + 1; SFree( sz );
}
RgszFree( rgszFiles );
return ( rc ); }
//
// Get Windows version
//
CB GetWindowsNtVersion( IN RGSZ Args, IN USHORT cArgs, OUT SZ ReturnBuffer, IN CB cbReturnBuffer ) {
DWORD Version; DWORD WinMaj; DWORD WinMin; DWORD OsMaj; DWORD OsMin;
Unused(Args); Unused(cArgs); Unused(cbReturnBuffer);
Version = GetVersion();
WinMaj = FIRSTBYTE(Version); WinMin = SECONDBYTE(Version); OsMin = THIRDBYTE(Version); OsMaj = FOURTHBYTE(Version);
sprintf(ReturnBuffer, "{%lu,%lu,%lu,%lu}", WinMaj, WinMin, OsMaj, OsMin ); return(lstrlen(ReturnBuffer)+1);
}
//
// Get Windows directory
//
CB GetWindowsNtDir( IN RGSZ Args, IN USHORT cArgs, OUT SZ ReturnBuffer, IN CB cbReturnBuffer ) { DWORD cbRet;
Unused(Args); Unused(cArgs);
cbRet = GetWindowsDirectory( ReturnBuffer, cbReturnBuffer );
if ( (cbRet == 0) || (cbRet > cbReturnBuffer) ) { ReturnBuffer[0] = '\0'; return 0; }
return cbRet + 1;
}
//
// Get Windows system directory
//
CB GetWindowsNtSysDir( IN RGSZ Args, IN USHORT cArgs, OUT SZ ReturnBuffer, IN CB cbReturnBuffer ) { DWORD cbRet;
Unused(Args); Unused(cArgs);
cbRet = GetSystemDirectory( ReturnBuffer, cbReturnBuffer );
if ( (cbRet == 0) || (cbRet > cbReturnBuffer) ) { ReturnBuffer[0] = '\0'; return 0; }
return cbRet + 1;
}
//
// Get NT directory
//
CB GetNtDir( IN RGSZ Args, IN USHORT cArgs, OUT SZ ReturnBuffer, IN CB cbReturnBuffer ) {
#define SYSTEMROOT "\\SystemRoot"
#define DRIVEROOT "\\DosDevices\\?:"
#define LINKBUFFERSIZE (MAXIMUM_FILENAME_LENGTH * sizeof(WCHAR))
ANSI_STRING SystemRoot; ANSI_STRING DriveRoot; WCHAR SysLinkBuffer[LINKBUFFERSIZE]; WCHAR DrvLinkBuffer[LINKBUFFERSIZE]; WCHAR DriveLetter; CHAR DriveBuffer[] = DRIVEROOT; NTSTATUS Status;
UNICODE_STRING SystemRootU; UNICODE_STRING SystemRootLinkU; UNICODE_STRING DriveRootU; UNICODE_STRING DriveRootLinkU;
Unused(Args); Unused(cArgs); Unused(cbReturnBuffer); ReturnBuffer[0] = '\0';
SystemRootLinkU.Length = 0; SystemRootLinkU.MaximumLength = LINKBUFFERSIZE; SystemRootLinkU.Buffer = SysLinkBuffer;
DriveRootLinkU.Length = 0; DriveRootLinkU.MaximumLength = LINKBUFFERSIZE; DriveRootLinkU.Buffer = DrvLinkBuffer;
RtlInitAnsiString(&SystemRoot, SYSTEMROOT);
Status = RtlAnsiStringToUnicodeString( &SystemRootU, &SystemRoot, TRUE );
//
// Get the value of the "SystemRoot" symbolic link.
//
if ( GetSymbolicLinkTarget( &SystemRootU, &SystemRootLinkU ) ) {
for ( DriveLetter = (WCHAR)'A'; DriveLetter <= (WCHAR)'Z'; DriveLetter++ ) {
DriveBuffer[12] = (CHAR)DriveLetter;
RtlInitAnsiString(&DriveRoot, DriveBuffer);
Status = RtlAnsiStringToUnicodeString( &DriveRootU, &DriveRoot, TRUE );
//
// If there is a symbolic link for the drive, see if it
// matches the symbolic link of "SystemRoot"
//
if ( GetSymbolicLinkTarget( &DriveRootU, &DriveRootLinkU ) ) {
if ( MatchNtPathToDosPath( &SystemRootLinkU, &DriveRootLinkU, &DriveBuffer[12], ReturnBuffer, cbReturnBuffer ) ) {
return lstrlen(ReturnBuffer)+1; } }
RtlFreeUnicodeString(&DriveRootU); } }
RtlFreeUnicodeString(&SystemRootU);
return 0; }
//
// Convert an NT path to a DOS path
//
BOOL MatchNtPathToDosPath( IN PUNICODE_STRING NtPathU, IN PUNICODE_STRING DosLinkU, IN SZ DosPath, OUT SZ ReturnBuffer, IN CB cbBuffer ) {
CHAR NtPath[MAX_PATH]; CHAR DosLink[MAX_PATH]; SZ p;
Unused( cbBuffer );
ConvertUnicodeToAnsi( NtPathU, NtPath ); ConvertUnicodeToAnsi( DosLinkU, DosLink );
//
// If DosLink is a substring of NtPath, then subsitute that substring by
// the given DosPath.
//
p = strstr( NtPath, DosLink );
if ( p == NtPath ) {
strcpy( ReturnBuffer, DosPath ); p = NtPath + strlen(DosLink); strcat( ReturnBuffer, p );
return fTrue;
}
return fFalse; }
//
// Convert Unicode string to ansi string
//
VOID ConvertUnicodeToAnsi( IN PUNICODE_STRING UnicodeString, OUT SZ AnsiString ) { WCHAR *pw; SZ pa;
pw = UnicodeString->Buffer; pa = AnsiString;
while ( *pw != (WCHAR)0 ) { *pa++ = (CHAR)(*pw++); }
*pa = '\0'; }
//
// Get NT drive
//
CB GetNtDrive( IN RGSZ Args, IN USHORT cArgs, OUT SZ ReturnBuffer, IN CB cbReturnBuffer ) {
if ( GetNtDir( Args, cArgs, ReturnBuffer, cbReturnBuffer ) > 0 ) {
ReturnBuffer[2] = '\0'; return 3;
}
return 0; }
#if i386
//
// Get NT Boot Info - I386 version
//
CB GetNtBootInfo( IN RGSZ Args, IN USHORT cArgs, OUT SZ ReturnBuffer, IN CB cbReturnBuffer ) {
#define BOOT_INI "C:\\BOOT.INI"
#define MULTIBOOT_SCT "multiboot"
#define FLEXBOOT_SCT "flexboot"
#define OS_SCT "operating systems"
#define TIMEOUT "timeout"
#define DEFAULT "default"
PTAGGEDFILE pBootTxt; PTFSECTION pSection; PTFKEYWORD pTimeout; PTFKEYWORD pDefault; PTFKEYWORD pKey; BOOL fOkay = fFalse; RGSZ rgszInfo; RGSZ rgszTmp; SZ sz; INT cCount = 3;
Unused( Args ); Unused( cArgs ); Unused( cbReturnBuffer );
rgszInfo = RgszAlloc(cCount); rgszTmp = RgszAlloc(3);
if ( rgszInfo && rgszTmp ) { //
// Get Boot.txt
//
if ( pBootTxt = GetTaggedFile( BOOT_INI ) ) {
//
// Get multiboot section
//
if ( ( pSection = GetSection( pBootTxt, MULTIBOOT_SCT )) || ( pSection = GetSection( pBootTxt, FLEXBOOT_SCT )) ) {
//
// Get timeout and default
//
pTimeout = GetKeyword( pSection, TIMEOUT ); pDefault = GetKeyword( pSection, DEFAULT );
if ( pTimeout && pDefault ) {
//
// Get Operating systems section
//
if ( pSection = GetSection( pBootTxt, OS_SCT ) ) {
rgszInfo[0] = SzDup( pTimeout->szValue ); rgszInfo[1] = SzDup( pDefault->szValue ); rgszInfo[2] = NULL;
if ( rgszInfo[0] && rgszInfo[1] ) {
fOkay = fTrue; pKey = NULL;
while ( pKey = GetNextKeyword( pSection, pKey )) {
rgszTmp[0] = pKey->szName; rgszTmp[1] = pKey->szValue; rgszTmp[2] = NULL;
sz = SzListValueFromRgsz( rgszTmp );
if ( !sz || !RgszAdd( &rgszInfo, sz ) ) {
fOkay = fFalse; if ( sz ) { SFree( sz ); } break; } } }
} } }
CloseTaggedFile( pBootTxt ); } }
if ( fOkay ) {
sz = SzListValueFromRgsz( rgszInfo );
if ( sz ) {
strcpy( ReturnBuffer, sz );
SFree( sz );
} else {
fOkay = fFalse; } }
if ( rgszTmp ) { rgszTmp[0] = NULL; RgszFree( rgszTmp ); }
if ( rgszInfo ) { RgszFreeCount( rgszInfo, cCount ); }
if ( fOkay ) { return lstrlen(ReturnBuffer)+1; } else { return 0; }
}
#else // if i386
//
// Get NT Boot Info - MIPS version
//
CB GetNtBootInfo( IN RGSZ Args, IN USHORT cArgs, OUT SZ ReturnBuffer, IN CB cbReturnBuffer ) {
//
// BUGBUG ramonsa - For MIPS currently we fail
//
Unused( Args ); Unused( cArgs ); Unused( ReturnBuffer ); Unused( cbReturnBuffer );
return 0;
}
#endif // if i386
//
// Get value of an environment variable. Returns the value in list form. If the
// value is a path (semicolon-separated components) each component is an element
// of the list.
//
CB GetLoadedEnvVar( IN RGSZ Args, IN USHORT cArgs, OUT SZ ReturnBuffer, IN CB cbReturnBuffer ) {
CHAR EnvValue[ MAX_PATH ]; SZ sz;
Unused( cbReturnBuffer );
ReturnBuffer[0] = '\0';
if (cArgs > 0) {
if ( GetEnvironmentVariable( Args[0], EnvValue, MAX_PATH ) == 0 ) {
//
// Env. Variable not defined, return empty list
//
#define UNDEF_VAR_VALUE "{}"
lstrcpy( ReturnBuffer, UNDEF_VAR_VALUE ); return lstrlen( ReturnBuffer )+1;
} else if ( sz = SzListValueFromPath( EnvValue ) ) {
lstrcpy( ReturnBuffer, sz ); SFree( sz ); return lstrlen( ReturnBuffer)+1; } }
return 0; }
CB IsUniprocessorSystem( IN RGSZ Args, IN USHORT cArgs, OUT SZ ReturnBuffer, IN CB cbReturnBuffer ) { CHAR Value[256]; HKEY hkey; LONG l; DWORD size; BOOL IsUp; SYSTEM_INFO SysInfo;
Unused(Args); Unused(cArgs); Unused(cbReturnBuffer);
ReturnBuffer[0] = 0;
//
// Look in the registry.
//
l = RegOpenKeyEx( HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows NT\\CurrentVersion", 0, KEY_QUERY_VALUE, &hkey );
if(l == NO_ERROR) {
size = sizeof(Value);
l = RegQueryValueEx( hkey, "CurrentType", NULL, NULL, Value, &size );
RegCloseKey(hkey); }
if(l == NO_ERROR) {
//
// It's UP if the string starts with Uni
// and not Multi
//
IsUp = (Value[0] == 'U');
} else {
//
// Registry didn't tell us for some reason; fall back on
// the # of processors.
//
GetSystemInfo(&SysInfo);
IsUp = (SysInfo.dwNumberOfProcessors == 1); }
lstrcpy(ReturnBuffer,IsUp ? "YES" : "NO");
return lstrlen(ReturnBuffer)+1; }
|