/*++ 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 #include #include #include #include #include #include #include "network.h" #include "machines.h" #include "idw_dbg.h" // For PnP Stuff #include #include #include #include #include #include #include #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); } */