windows-nt/Source/XPSP1/NT/sdktools/idwlog/machines.cpp
2020-09-26 16:20:57 +08:00

570 lines
16 KiB
C++

/*++
Filename : Machines.c
Description: This contains the functions that will interrogate the
machine for details.
The GetNTSoundINfo function is directly copied from David Shiftlet's code.
Since we didn't use it, I'm not going to waste debug time figuring out
if the random code he put in actually works.
Created by: Wally Ho
History: Created on 02/01/99.
Contains these functions:
1. DWORD GetCurrentMachinesBuildNumber( VOID );
2. DWORD RandomMachineID(VOID)
3. VOID GetNTSoundInfo(OUT LPMACHINE_DETAILS pMd)
4. VOID GetVidInfo (OUT LPMACHINE_DETAILS pMd)
5. VOID GetPNPDevices (OUT LPMACHINE_DETAILS pMd)
6. BOOL IsHydra ( VOID )
7. BOOL GetPnPDisplayInfo(LPTSTR pOutputData)
--*/
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <time.h>
#include <sys/timeb.h>
#include <tchar.h>
#include <winuser.h>
#include "network.h"
#include "machines.h"
#include "idw_dbg.h"
// For PnP Stuff
#include <devguid.h>
#include <initguid.h>
#include <setupapi.h>
#include <syssetup.h>
#include <regstr.h>
#include <setupbat.h>
#include <cfgmgr32.h>
#include "netinfo.h"
// These aren't used but I think I can use them
// somewhere so I'll leave them here. Wallyho
LPTSTR Days[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
LPTSTR Months[] = { "", "Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
DWORD
GetCurrentMachinesBuildNumber( VOID )
/*++
Author: Wallyho.
Routine Description:
Purpose this should get the current build number of the
running OS.
Arguments:
NONE
Return Value:
The DWORD of the build.
--*/
{
OSVERSIONINFO osVer;
osVer.dwOSVersionInfoSize= sizeof( osVer );
if (GetVersionEx( &osVer )&&osVer.dwMajorVersion >= 5)
return osVer.dwBuildNumber;
else
return FALSE;
}
DWORD
RandomMachineID(VOID)
/*++
Copyright (c) 2000, Microsoft.
Author: Wally W. Ho (wallyho)
Date: 8/18/2000
Routine Description:
Generates DWORD random MachineID for each machine.
There is a very slim chance that duplicates could occur.
Arguments:
NONE
Return Value:
The DWORD random ID.
--*/
{
INT i;
INT iLenCName;
INT iNameTotal = 0;
TCHAR szComputerName[MAX_COMPUTERNAME_LENGTH+1];
DWORD dwSize;
DWORD dwMachineID;
CHAR szRandomID[ 4 ]; // need 4 bytes to contain the DWORD.
struct _timeb tm;
//
// This will get us the milliseconds
_ftime(&tm);
//
// Seed the random number generator.
// We will seed with the seconds + milliseconds at
// at that time. I was getting the same number
// if I pressed the keyboard too fast in testing this.
// The milli seconds should decrease the expectancy of
// duplication.
//
srand( ((UINT)time(NULL)) + tm.millitm);
//
// This will guarantee a mostly random identifier.
// Even with no computer name. We will tally the
// ascii decimal value of the computer name and
// add that to the randomly generated number.
// The possibility of a dup is greatly decreased
// since we switched to a dword system.
// This computername tweak should be unnecessary.
//
dwSize = sizeof(szComputerName);
if (0 == GetComputerName(szComputerName,&dwSize) ){
//
// This algorithm will limit the random number to
// uppercase ascii alphabet.
//
szComputerName[0] = 65 + (rand() % 25);
szComputerName[1] = 65 + (rand() % 25);
szComputerName[2] = 65 + (rand() % 25);
szComputerName[3] = 65 + (rand() % 25);
szComputerName[4] = 65 + (rand() % 25);
szComputerName[5] = 65 + (rand() % 25);
szComputerName[6] = 65 + (rand() % 25);
szComputerName[7] = TEXT('\0');
}
iLenCName = _tcslen (szComputerName);
//
// Tally up the individual elements in the file
//
for (i = 0; i < iLenCName; i++)
iNameTotal += szComputerName[i];
//
// Generate four 8 bit numbers.
// Add the some random number based on the
// computername mod'ed to 0-100.
// Limit the 8 bit number to 0-155 to make room
// for the 100 from the computer name tweak.
// Total per 8 bit is 256.
// Do this tweak to only 2.
// We will then cast and shift to combine it
// into a DWORD.
//
szRandomID[0] = (rand() % 155) + (iNameTotal % 100);
szRandomID[1] = rand() % 255;
szRandomID[2] = (rand() % 155) + (iNameTotal % 100);
szRandomID[3] = rand() % 255;
// This should limit the last digit to 0011 only two binaries so we will
// only get 9 chars in the random id. 10 chars may cause an overflow
// of the dword we are using.
//
// This will combine the 4 8bit CHAR into one DWORD
//
dwMachineID = (DWORD)szRandomID[0] * 0x00000001 +
(DWORD)szRandomID[1] * 0x00000100 +
(DWORD)szRandomID[2] * 0x00010000 +
(DWORD)szRandomID[3] * 0x01000000;
return dwMachineID;
}
VOID
GetNTSoundInfo(OUT LPMACHINE_DETAILS pMd)
{
HKEY hKey;
DWORD dwCbData;
ULONG ulType;
LPTSTR sSubKey=TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\Drivers32");
INT i;
TCHAR szSubKeyName[ MAX_PATH ];
TCHAR szTempString[ MAX_PATH ];
// Get Sound Card Info
pMd->iNumWaveOutDevices = 0;
hKey = 0;
if (!RegOpenKeyEx(HKEY_LOCAL_MACHINE, sSubKey, 0, KEY_READ, &hKey)){
// Loop through the key to see how many wave devices we have, but skip mmdrv.dll.
for (i = 0; i <= 1; i++){
if (i != 0)
_stprintf(szSubKeyName, TEXT("wave%d"),i);
else
_tcscpy(szSubKeyName, TEXT("wave"));
dwCbData = sizeof (szTempString);
if (RegQueryValueEx(hKey, szSubKeyName, 0, &ulType, (LPBYTE)szTempString, &dwCbData))
break;
else{
// We want to skip mmdrv.dll - not relevant.
if (szTempString[0] &&
_tcscmp(szTempString, TEXT("mmdrv.dll"))) {
_tcscpy(&pMd->szWaveDriverName[pMd->iNumWaveOutDevices][0],
szTempString);
pMd->iNumWaveOutDevices++;
}
}
}
}
if (hKey){
RegCloseKey(hKey);
hKey = 0;
}
sSubKey = TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\drivers.desc");
hKey = 0;
if (!RegOpenKeyEx(HKEY_LOCAL_MACHINE, sSubKey, 0, KEY_READ, &hKey)){
// Now grab the sound device string for each wave device
for (i = 0; i < pMd->iNumWaveOutDevices; i++){
dwCbData = sizeof szTempString;
if (RegQueryValueEx(hKey, pMd->szWaveDriverName[i], 0, &ulType, (LPBYTE)szTempString, &dwCbData))
_tcscpy(pMd->szWaveOutDesc[i], TEXT("Unknown"));
else
_tcscpy(pMd->szWaveOutDesc[i], szTempString);
}
}
if (hKey){
RegCloseKey(hKey);
hKey = 0;
}
return;
}
VOID
GetVidInfo (OUT LPMACHINE_DETAILS pMd)
/*++
GetVidInfo reads registry information about the installed
video cards and produces one string
--*/
{
TCHAR szDeviceKey[256];
WCHAR szWideBuf[128];
HKEY hkHardware;
HKEY hkCard;
DWORD dwSize;
TCHAR szSubKey[128];
DWORD dwIndex=0;
DWORD dwMem;
DWORD iLoop;
LPTSTR pch;
DISPLAY_DEVICE displayDevice;
DEVMODE dmCurrent;
// make sure its zeroed even though it should be from ZeroMemory.
pMd->szVideoInfo[0] = TEXT('\0');
szWideBuf[0] = TEXT('\0');
// Look in HWKEY to find out what services are used.
if (ERROR_SUCCESS != RegOpenKeyEx (HKEY_LOCAL_MACHINE, VIDEOKEY, 0, KEY_READ, &hkHardware)){
Idwlog(TEXT("Failed to open the Video hardware Key. Video is NULL."));
return;
}
dwSize=128;
while (ERROR_SUCCESS == RegEnumKeyEx (hkHardware, dwIndex++,szSubKey, &dwSize,NULL,NULL,NULL,NULL)){
// Append the subkey name to SERVICEKEY.
// Look up only Device0 for this card
_stprintf (szDeviceKey, ("%s\\%s\\Device0"), SERVICEKEY, szSubKey);
RegOpenKeyEx (HKEY_LOCAL_MACHINE, szDeviceKey, 0, KEY_READ, &hkCard);
// First get the description
dwSize=256;
if (ERROR_SUCCESS == RegQueryValueEx( hkCard, DEVICE_DESCR, NULL, NULL, (_TUCHAR *)szDeviceKey, &dwSize)){
if (_tcsclen(pMd->szVideoInfo ) + dwSize < 254){
_tcscpy(pMd->szVideoInfo , szDeviceKey);
_tcscat (pMd->szVideoInfo , TEXT(" "));
}
}
// Read the chip type. This is a UNICODE string stored in REG_BINARY format
dwSize=256;
lstrcpyW (szWideBuf, L"ChipType:");
if (ERROR_SUCCESS == RegQueryValueEx (hkCard, CHIP_TYPE,NULL, NULL, (LPBYTE)(szWideBuf+9), &dwSize)){
if ((dwSize=lstrlen(pMd->szVideoInfo))+lstrlenW(szWideBuf)<254) {
WideCharToMultiByte (CP_ACP,
0,
szWideBuf,
-1,
pMd->szVideoInfo + dwSize,
256-dwSize,
NULL,
NULL);
_tcscat (pMd->szVideoInfo, TEXT(" "));
}
}
// Read the DAC. Another UNICODE string
dwSize=256;
lstrcpyW (szWideBuf, L"DACType:");
if (ERROR_SUCCESS == RegQueryValueEx (hkCard, DAC_TYPE, NULL, NULL, (LPBYTE)(szWideBuf+8), &dwSize)){
if ((dwSize=lstrlen(pMd->szVideoInfo))+lstrlenW(szWideBuf)<254){
WideCharToMultiByte (CP_ACP,
0,
szWideBuf,
-1,
pMd->szVideoInfo + dwSize,
256 - dwSize,
NULL,
NULL);
_tcscat (pMd->szVideoInfo, TEXT(" "));
}
}
// Read the memory size. This is a binary value.
dwSize=sizeof(DWORD);
if (ERROR_SUCCESS == RegQueryValueEx (hkCard, MEM_TYPE, NULL,NULL,(LPBYTE)&dwMem, &dwSize)){
_stprintf (szDeviceKey, TEXT("Memory:0x%x ;"), dwMem);
if (_tcsclen(pMd->szVideoInfo)+lstrlen(szDeviceKey)<255)
_tcscat (pMd->szVideoInfo, szDeviceKey);
}
RegCloseKey (hkCard);
dwSize=128;
}
RegCloseKey (hkHardware);
//__________________________________________________________________
// Video Information for ChrisW
// Video display name.
_tcscpy(pMd->szVideoDisplayName,TEXT("Unknown"));
displayDevice.cb = sizeof(DISPLAY_DEVICE);
iLoop = 0;
while(EnumDisplayDevices(NULL, iLoop, &displayDevice, 0)) {
ZeroMemory( &dmCurrent, sizeof(dmCurrent) );
dmCurrent.dmSize= sizeof(dmCurrent);
if( EnumDisplaySettings( displayDevice.DeviceName, ENUM_CURRENT_SETTINGS, &dmCurrent ) ) {
if(iLoop == 0)
pMd->szVideoDisplayName[0] = 0;
else
_tcscat( pMd->szVideoDisplayName, TEXT(",") );
_tcscat( pMd->szVideoDisplayName, (LPCTSTR)dmCurrent.dmDeviceName );
}
iLoop++;
}
// replace spaces so we don't break the perl script the build lab is using
pch = pMd->szVideoDisplayName;
while(*pch) {
if(*pch == TEXT(' '))
*pch = TEXT('.');
pch++;
}
}
extern DEV_INFO *g_pdiDevList;
// in netinfo.c
VOID
GetPNPDevices (OUT LPMACHINE_DETAILS pMd)
/*++
GetPNP Devices like net, scsi, pcmcia etc.
This is a wally created function incorporting the random
placement of this from before.
--*/
{
DEV_INFO *pdi;
// Get PNP net card info
_tcscpy(pMd->szNetcards, TEXT("Unknown"));
_tcscpy(pMd->szScsi, TEXT("Unknown"));
_tcscpy(pMd->szModem , TEXT("Unknown"));
CollectDevData ();
pdi=g_pdiDevList;
while (pdi){
if (0 == _tcscmp(pdi->szClass, TEXT("Net"))){
if (_tcsclen(pMd->szNetcards) + _tcsclen(pdi->szDescription) + _tcsclen(pdi->szService) < 250){
_tcscpy (pMd->szNetcards, pdi->szDescription);
_tcscat (pMd->szNetcards, "(");
_tcscat (pMd->szNetcards, pdi->szService);
_tcscat (pMd->szNetcards, TEXT(")"));
}
}
else if (0 == _tcscmp(pdi->szClass, TEXT("SCSIAdapter"))){
if (_tcsclen(pMd->szScsi) + _tcsclen(pdi->szService) < 250){
_tcscpy (pMd->szScsi, pdi->szService);
_tcscat (pMd->szScsi, TEXT(","));
}
}
else if (0 == _tcscmp(pdi->szClass, TEXT("Modem"))){
if (_tcsclen( pMd->szModem) + _tcsclen(pdi->szDescription) < 250){
_tcscpy ( pMd->szModem, pdi->szDescription);
_tcscat ( pMd->szModem, TEXT(","));
}
}
else if (0 == _tcscmp(pdi->szClass, TEXT("USB")))
pMd->bUSB = TRUE;
else if (0 == _tcscmp(pdi->szClass, TEXT("Infrared")))
pMd->bIR = TRUE;
else if (0 == _tcscmp(pdi->szClass, TEXT("PCMCIA") ) ||
0 == _tcscmp(pdi->szService, TEXT("PCMCIA") ))
pMd->bPCCard = TRUE;
else if (_tcsstr(pdi->szClass, TEXT("ACPI")) ||
_tcsstr(pdi->szService, TEXT("ACPI")))
pMd->bACPI = TRUE;
pdi=pdi->Next;
}
Cleanup(); //free all the pnp data and restore configuration
if (pMd->szNetcards[0] == 0)
_tcscpy (pMd->szNetcards, TEXT("Unknown"));
}
BOOL
IsHydra ( VOID )
// Hydra is denoted by "Terminal Server" in the ProductOptions key
{
BOOL rVal = FALSE;
LONG Rslt;
HKEY hKey = NULL;
DWORD Type = 0;
DWORD Size = 0;
LPTSTR ProductSuite = NULL;
LPTSTR p;
__try{
Rslt = RegOpenKey(
HKEY_LOCAL_MACHINE,
TEXT("System\\CurrentControlSet\\Control\\ProductOptions"),
&hKey
);
if (Rslt != ERROR_SUCCESS)
goto exit;
Rslt = RegQueryValueEx( hKey, TEXT("ProductSuite"), NULL, &Type, NULL, &Size );
if (Rslt != ERROR_SUCCESS || !Size)
goto exit;
ProductSuite = (LPTSTR) LocalAlloc( LPTR, Size );
if (!ProductSuite)
goto exit;
Rslt = RegQueryValueEx( hKey, TEXT("ProductSuite"), NULL, &Type,
(LPBYTE) ProductSuite, &Size );
if (Rslt != ERROR_SUCCESS || Type != REG_MULTI_SZ)
goto exit;
p = ProductSuite;
while (*p) {
if (_tcscmp( p, TEXT("Terminal Server") ) == 0) {
rVal = TRUE;
break;
}
p += (_tcslen( p ) + 1);
}
exit:
if (ProductSuite)
LocalFree( ProductSuite );
if (hKey)
RegCloseKey( hKey );
}__except (EXCEPTION_EXECUTE_HANDLER) {
// This is here as for some reason this faults in NT 4.0.
}
return rVal;
}
/*
BOOL
GetPnPDisplayInfo(
LPTSTR pOutputData
)
{
BOOL bRet = FALSE;
HDEVINFO hDevInfo;
SP_DEVINFO_DATA DeviceInfoData;
DWORD index = 0;
TCHAR RegistryProperty[256];
ULONG BufferSize;
//
// Let's find all the video drivers that are installed in the system
//
hDevInfo = SetupDiGetClassDevs((LPGUID) &GUID_DEVCLASS_DISPLAY,
NULL,
NULL,
0);
while (hDevInfo != INVALID_HANDLE_VALUE){
if (bRet)
strcat(pOutputData, TEXT(",") );
ZeroMemory(&DeviceInfoData, sizeof(SP_DEVINFO_DATA));
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
if (!SetupDiEnumDeviceInfo(hDevInfo,
index++,
&DeviceInfoData))
break;
BufferSize = sizeof(RegistryProperty);
if (CR_SUCCESS ==
CM_Get_Device_ID(DeviceInfoData.DevInst,
RegistryProperty,
sizeof(RegistryProperty),
0)){
bRet = TRUE;
strcat(pOutputData, RegistryProperty);
}
}
return (bRet);
}
*/