#include "pch.hpp"
//===========================================================================//
// File:	 Machine Details.cpp											 //
// Project:  GameOS					                                         //
// Contents: Gets information about devices in the machine					 // 
//---------------------------------------------------------------------------//
// Date      Who    Modification                                             //
// 04/01/98  AG     Created
//																			 //
//---------------------------------------------------------------------------//
// Copyright (C) 1999 Microsoft Corp.						                 //
// All Rights reserved worldwide                                             //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL               //
//===========================================================================//
#include "Registry.hpp"
#include "Windows.hpp"

extern bool InternalDoesFileExist( const char* FileName );



typedef struct
{
	char*	RegistryEntry;
	char*	ReadableName;
	int		Flags;

} CHIPSET;

CHIPSET chipArray[]={
{ "VEN_8086&DEV_7190", "Intel BX1"		,0 },
{ "VEN_8086&DEV_7192", "Intel BX2"		,0 },
{ "VEN_8086&DEV_71a0", "Intel GX"		,0 },
{ "VEN_8086&DEV_7180", "Intel LX/EX"	,0 },
{ "VEN_1179&DEV_0601", "Toshiba"		,0 },
{ "VEN_1106&DEV_0501", "VIA Tech1"		,1 },
{ "VEN_1106&DEV_0691", "VIA Tech2"		,1 },
{ "VEN_1106&DEV_0305", "VIA Tech3"		,1 },
{ "VEN_10b9&DEV_1521", "Ali"			,0 },
{ "VEN_8086&DEV_1250", "Intel HX"		,0 },
{ "VEN_8086&DEV_7100", "Intel TX"		,0 },
{ "VEN_8086&DEV_1237", "Intel FX"		,0 },
{ "VEN_8086&DEV_7122", "Intel 810"		,0 },
{ "VEN_8086&DEV_1131", "Intel 815"		,0 },
{ "VEN_8086&DEV_250F", "Intel 820"		,0 },
{ "VEN_1039&DEV_0001", "SIS"			,0 },
{ "VEN_1022&DEV_7007", "AMD 750"		,0 }};






//
// Windows 2000
//
char* FindChipset()
{
	HKEY hKey;
	int found;
	DWORD Index=0;
	FILETIME FileTime;
	DWORD Flags=0;
	static char ChipSet[256]="";
	static char hardware[256];			// Static so not to take as much stack space
	static char Subkey[256];
	static char card[256];
	static char keyClass[256];

	if( WindowsNT )
	{
		int result=RegOpenKey( HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Enum\\PCI", &hKey );
		if( ERROR_SUCCESS==result )
		{
			do
			{
				DWORD SubKeySize;
				SubKeySize=sizeof(Subkey);
				found=RegEnumKeyEx( hKey, Index++, Subkey, &SubKeySize, 0, 0, 0, &FileTime );	// Enum through all devices
				if( ERROR_SUCCESS==found )
				{
					for( int t0=0; t0<sizeof(chipArray)/sizeof(CHIPSET); t0++ )
					{
						if( 0==strnicmp( Subkey, chipArray[t0].RegistryEntry, strlen(chipArray[t0].RegistryEntry) ) )
						{
							strcpy( ChipSet, chipArray[t0].ReadableName );
							Flags=chipArray[t0].Flags;
							break;
						}
					}
				}

			} while( ERROR_SUCCESS==found );

			RegCloseKey( hKey );
		}

		if( Flags==1 )
		{
			char Buffer[MAX_PATH];
			GetWindowsDirectory( Buffer, MAX_PATH );
			strcat( Buffer, "\\System32\\drivers\\viaagp1.sys" );
						
			if( !InternalDoesFileExist(Buffer) )
			{
				strcat( ChipSet, " - No AGP miniport driver" );
			}
			else
			{
				strcat( ChipSet, " - AGP miniport driver" );
			}
		}

		return ChipSet;
	}
//
// Windows 9x
//
	int result=RegOpenKey( HKEY_LOCAL_MACHINE, "Enum\\PCI", &hKey );
	if( ERROR_SUCCESS==result )
	{
		do
		{
			DWORD SubKeySize;
			SubKeySize=sizeof(Subkey);
			found=RegEnumKeyEx( hKey, Index++, Subkey, &SubKeySize, 0, 0, 0, &FileTime );	// Enum through all devices
			if( ERROR_SUCCESS==found )
			{
				for( int t0=0; t0<sizeof(chipArray)/sizeof(CHIPSET); t0++ )
				{
					if( 0==strnicmp( Subkey, chipArray[t0].RegistryEntry, strlen(chipArray[t0].RegistryEntry) ) )
					{
						strcpy( ChipSet, chipArray[t0].ReadableName );
						Flags=chipArray[t0].Flags;
						break;
					}
				}
			}

		} while( ERROR_SUCCESS==found );

		RegCloseKey( hKey );

		if( Flags==1 )
		{
			char Buffer[MAX_PATH];
			GetWindowsDirectory( Buffer, MAX_PATH );
			strcat( Buffer, "\\System\\viagart.vxd" );
			
			if( !InternalDoesFileExist(Buffer) )
			{
				strcat( ChipSet, " - No AGP miniport driver" );
			}
			else
			{
				char* Turbo=ReadRegistry( "System\\CurrentControlSet\\Services\\VxD\\VIAGART", "Turbo", 1 );
				if( !Turbo )
				{
					strcat( ChipSet, " - AGP miniport driver, unknown setting" );
				}
				else
				{
					if( 0==*Turbo )
					{
						strcat( ChipSet, " - AGP miniport driver in NORMAL mode" );
					}
					else
					{
						strcat( ChipSet, " - AGP miniport driver in TURBO mode" );
					}
				}
			}
		}
	}
	return ChipSet;
}






//
// Scan for all cards found on a particular bus (PCI,ISA,BIOS and ROOT)
//
void ExamineBus( FixedLengthString& Buffer, char* BusName, char* Key )
{
	static char ChipSet[256]="";
	static char Subkey[256];
	static char card[256];
	static char keyClass[256];
	static char hardware[256];			// Static so not to take as much stack space
	static char ClassName[256];
	static char DeviceName[256];
	static char Revision[256];
	static char Mfg[256];
	static char Driver[256];
	static char DriverKey[256];
	static char DriverDate[256];
	int found;
	HKEY hKey;
	FILETIME FileTime;
	DWORD Index=0;
	int BusFound=0;

	int result=RegOpenKey( HKEY_DYN_DATA, "Config Manager\\Enum", &hKey );
	if( ERROR_SUCCESS==result )
	{
		do
		{
			DWORD SubKeySize;
			SubKeySize=sizeof(Subkey);
			found=RegEnumKeyEx( hKey, Index++, Subkey, &SubKeySize, 0, 0, 0, &FileTime );	// Enum through all devices
			if( ERROR_SUCCESS==found )
			{
				strcpy( card, "Config Manager\\Enum\\" );
				strcat( card, Subkey );				
				
				HKEY cardkey;
				int result=RegOpenKey( HKEY_DYN_DATA, card, &cardkey );						// Open the device
				if( ERROR_SUCCESS==result )
				{
					DWORD keyClassSize=256;
					RegQueryValueEx( cardkey, "HardWareKey", NULL, NULL, (LPBYTE)&keyClass, &keyClassSize );

					if( 0!=_strnicmp( "PCI\\IRQHOLDER", keyClass, 13 ) &&
						0!=_strnicmp( "ISAPNP\\READDATAPORT", keyClass, 19 ) &&
						0==_strnicmp( Key, keyClass, strlen(Key) ))							// Ignore System, USB and hdc devices
					{
						strcpy( hardware, "Enum\\" );
						strcat( hardware, keyClass );
						HKEY hardwarekey;

						int result=RegOpenKey( HKEY_LOCAL_MACHINE, hardware, &hardwarekey );
						if( ERROR_SUCCESS==result )
						{
							*ClassName=0;
							DWORD ClassSize=256;
							RegQueryValueEx( hardwarekey, "Class", NULL, NULL, (LPBYTE)&ClassName, &ClassSize );

							if( 0==stricmp( "System", ClassName ) && *ChipSet==0 )
							{
								*DeviceName=0;
								DWORD DeviceNameSize=256;									// Look for Intel nnnnnXX chipset
								RegQueryValueEx( hardwarekey, "DeviceDesc", NULL, NULL, (LPBYTE)&DeviceName, &DeviceNameSize );

								if( 0==_strnicmp( DeviceName,"Intel 82",8) )
									strncpy( ChipSet, DeviceName, 13 );
							}

							if( 0!=stricmp( "System", ClassName ) &&
								0!=stricmp( "hdc", ClassName ) &&							// Ignore System, USB and hdc devices etc..
								0!=stricmp( "fdc", ClassName ) &&
								0!=stricmp( "Keyboard", ClassName ) &&
								0!=stricmp( "Printer", ClassName ) &&
								0!=stricmp( "Mouse", ClassName ) &&
								0!=stricmp( "Infrared", ClassName ) &&
								0!=stricmp( "Ports", ClassName ) &&
								0!=stricmp( "PCMCIA", ClassName ) &&
								0!=stricmp( "Unknown", ClassName ) &&
								0!=stricmp( "USB", ClassName ))
							{
								*DeviceName=0;
								*Revision=0;
								*Mfg=0;
								*Driver=0;
								DWORD DeviceNameSize=256;									// Read card information
								DWORD RevisionSize=256;
								DWORD MfgSize=256;
								DWORD DriverSize=256;

								RegQueryValueEx( hardwarekey, "DeviceDesc", NULL, NULL, (LPBYTE)&DeviceName, &DeviceNameSize );
								RegQueryValueEx( hardwarekey, "HWRevision", NULL, NULL, (LPBYTE)&Revision, &RevisionSize );
								RegQueryValueEx( hardwarekey, "Mfg", NULL, NULL, (LPBYTE)&Mfg, &MfgSize );
								RegQueryValueEx( hardwarekey, "Driver", NULL, NULL, (LPBYTE)&Driver, &DriverSize );

//								if( 0!=stricmp( "Dial-Up Adapter", DeviceName ) &&
								if( 0!=stricmp( "Gameport Joystick", DeviceName ) &&
									!( 0==stricmp( "ROOT\\",Key) && 0==stricmp( Mfg,"(Standard Modem Types)") ))
								{
									if( !BusFound )
									{
										Buffer << BusName;
										BusFound=1;
									}

									if( *Revision )
										Buffer << DeviceName << " (Version " << Revision << ") by " << Mfg;
									else
										Buffer << DeviceName << " by " << Mfg;
								
									strcpy( DriverKey, "System\\CurrentControlSet\\Services\\Class\\" );
									strcat( DriverKey, Driver );
									*DriverDate=0;
									DWORD DriverDateSize=256;									// Get Driver date from Class key
									HKEY hDriverKey;

									int result=RegOpenKey( HKEY_LOCAL_MACHINE, DriverKey, &hDriverKey );
									if( ERROR_SUCCESS==result )
									{
										if( ERROR_SUCCESS==RegQueryValueEx( hDriverKey, "DriverDate", NULL, NULL, (LPBYTE)&DriverDate, &DriverDateSize ))
											Buffer << ", Dated " << DriverDate;
										RegCloseKey( hDriverKey );
									}
									Buffer << "\n";
								}
							}
						}
						RegCloseKey( hardwarekey );
					}
					RegCloseKey( cardkey );
				}
			}
		} while( ERROR_SUCCESS==found );
	RegCloseKey( hKey );
	}
//
// On motherboard - display chipset
//
	if( 0==stricmp( Key, "BIOS\\" ) && *ChipSet )
	{
		if( !BusFound )
			Buffer << BusName;
		Buffer << "ChipSet is " << ChipSet << "\n";
	}
}


// 
//
// Read registry looking for PCI and ISA cards
//
//
void ScanCards( FixedLengthString& Buffer )
{
	ExamineBus( Buffer, "\nPCI bus\n=======\n", "PCI\\" );
	ExamineBus( Buffer, "\nISA bus\n=======\n", "ISAPNP\\" );
	ExamineBus( Buffer, "\nACPI bus\n========\n", "ACPI\\" );
	ExamineBus( Buffer, "\nOther Devices\n============\n", "ROOT\\" );
	ExamineBus( Buffer, "\nMotherboard\n===========\n", "BIOS\\" );
}

