|
|
#include "nt.h"
#include "ntrtl.h"
#include "nturtl.h"
#include <windows.h>
#include <lm.h>
#include <stdio.h>
#include <time.h>
#include <winuserp.h>
#include <shlobj.h>
#include <shlwapi.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 "tchar.h"
#include "string.h"
#include "setuplog.h"
#include "setuplib.h"
#include "pnpstuff.h"
char * Days[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; char * Months[] = { "", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
extern DEV_INFO *g_pdiDevList; // Head of device list
char OutputBuffer[ 8192 ]; #define MAX_WAVEOUT_DEVICES 2
struct { // Sound Card
int nNumWaveOutDevices; // Number of WaveOut Devices (~ number of sound cards)
char szWaveOutDesc[MAX_WAVEOUT_DEVICES][128];// WaveOut description
char szWaveDriverName[MAX_WAVEOUT_DEVICES][128]; // Wave Driver name
} m;
#define SHORTCUT "IDW Logging Tool.lnk"
char szValidHandle[] = "\r\nValid Handle\r\n"; char szInvalidHandle[] = "\r\nInvalid handle. Err: %d\r\n"; char szBadWrite[] = "WriteFile failed. Err: %d\r\n"; char szGoodWrite[] = "WriteFile succeeded\r\n";
// From warndoc.cpp:
VOID GetNTSoundInfo() { HKEY hKey; DWORD cbData; ULONG ulType; LPTSTR sSubKey=TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\Drivers32"); INT i; TCHAR szSubKeyName[256]; TCHAR szTempString[256];
// Get Sound Card Info
hKey = 0; if (!RegOpenKeyEx(HKEY_LOCAL_MACHINE, sSubKey, 0, KEY_READ, &hKey)){ m.nNumWaveOutDevices = 0; // Loop through the key to see how many wave devices we have, but skip mmdrv.dll.
for (i = 0; i <= 1; i++){ if (i) _stprintf(szSubKeyName, TEXT("wave%d"),i); else _tcscpy(szSubKeyName, TEXT("wave"));
cbData = sizeof szTempString; if (RegQueryValueEx(hKey, szSubKeyName, 0, &ulType, (LPBYTE)szTempString, &cbData)) break; else{ if (szTempString[0] // We want to skip mmdrv.dll - not relevant.
&& _tcscmp(szTempString, TEXT("mmdrv.dll"))){ strcpy(&m.szWaveDriverName[m.nNumWaveOutDevices][0], szTempString); m.nNumWaveOutDevices++; } } } }
if (hKey){ RegCloseKey(hKey); hKey = 0; }
sSubKey = (LPTSTR)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 < m.nNumWaveOutDevices; i++){ cbData = sizeof szTempString; if (RegQueryValueEx(hKey, m.szWaveDriverName[i], 0, &ulType, (LPBYTE)szTempString, &cbData)) _tcscpy(m.szWaveOutDesc[i], TEXT("Unknown")); else _tcscpy(m.szWaveOutDesc[i], szTempString); } }
if (hKey){ RegCloseKey(hKey); hKey = 0; } return; }
//
// GetVidInfo reads registry information about the installed
// video cards and produces one string
//
#define HWKEY TEXT("SYSTEM\\CurrentControlSet\\Hardware Profiles\\Current\\System\\CurrentControlSet\\Services")
#define SERVICEKEY TEXT("SYSTEM\\CurrentControlSet\\Services")
#define DESCVAL TEXT("Device Description")
#define TYPEVAL TEXT("HardwareInformation.ChipType")
#define DACVAL TEXT("HardwareInformation.DacType")
#define MEMVAL TEXT("HardwareInformation.MemorySize")
VOID GetVidInfo (LPTSTR vidinfo) {
HKEY hkHardware; HKEY hkCard; DWORD dwSize; TCHAR szBuf[256]; WCHAR szWideBuf[128]; TCHAR szSubKey[128]; DWORD dwIndex=0; DWORD dwMem;
*vidinfo = '\0'; //
// Look in HWKEY to find out what services are used.
//
if (ERROR_SUCCESS != RegOpenKeyEx (HKEY_LOCAL_MACHINE, HWKEY, 0, KEY_READ, &hkHardware)) 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 (szBuf, ("%s\\%s\\Device0"), SERVICEKEY, szSubKey); RegOpenKeyEx (HKEY_LOCAL_MACHINE, szBuf, 0, KEY_READ, &hkCard); //
// First get the description
//
dwSize=256; if (ERROR_SUCCESS == RegQueryValueEx (hkCard, DESCVAL, NULL, NULL, szBuf, &dwSize)){ if (_tcsclen(vidinfo)+dwSize < 254){ _tcscat (vidinfo, szBuf); _tcscat (vidinfo, 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,TYPEVAL,NULL, NULL, (LPBYTE)(szWideBuf+9), &dwSize)){ if ((dwSize=lstrlen(vidinfo))+lstrlenW(szWideBuf)<254) { WideCharToMultiByte (CP_ACP, 0, szWideBuf, -1, vidinfo+dwSize, 256-dwSize, NULL,NULL); lstrcat (vidinfo, " "); } }
//
// Read the DAC. Another UNICODE string
//
dwSize=256; lstrcpyW (szWideBuf, L"DACType:"); if (ERROR_SUCCESS == RegQueryValueEx (hkCard,DACVAL,NULL, NULL, (LPBYTE)(szWideBuf+8), &dwSize)){ if ((dwSize=lstrlen(vidinfo))+lstrlenW(szWideBuf)<254){ WideCharToMultiByte (CP_ACP, 0, szWideBuf, -1, vidinfo+dwSize, 256-dwSize, NULL,NULL); lstrcat (vidinfo, " "); } } //
// Read the memory size. This is a binary value.
//
dwSize=sizeof(DWORD); if (ERROR_SUCCESS == RegQueryValueEx (hkCard, MEMVAL, NULL,NULL,(LPBYTE)&dwMem, &dwSize)){ _stprintf (szBuf, TEXT("Memory:0x%x ;"), dwMem); if (_tcsclen(vidinfo)+lstrlen(szBuf)<255) _tcscat (vidinfo, szBuf); } RegCloseKey (hkCard); dwSize=128; } RegCloseKey (hkHardware); }
//
// Hydra is denoted by "Terminal Server" in the ProductOptions key
//
BOOL IsHydra () { BOOL rVal = FALSE; LONG Rslt; HKEY hKey = NULL; DWORD Type = 0; DWORD Size = 0; LPTSTR ProductSuite = NULL; LPTSTR p;
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 );
return rVal; }
VOID GetBuildNumber( LPTSTR BuildNumber ) {
OSVERSIONINFO osVer;
osVer.dwOSVersionInfoSize= sizeof( osVer );
if (GetVersionEx( &osVer )&&osVer.dwMajorVersion >= 5) { wsprintf( BuildNumber, TEXT("%d"), osVer.dwBuildNumber ); } else { lstrcpy( BuildNumber, TEXT("") ); // return 0 if unknown
}
} // GetBuildNumber
/*
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); } */
VOID ConnectAndWrite(LPTSTR MachineName, LPTSTR Buffer ) { NETRESOURCE NetResource ; TCHAR szLogFile[ MAX_PATH ]; TCHAR szBinPath[MAX_PATH]; TCHAR szExePath[MAX_PATH]; TCHAR szErr[100];
HANDLE hWrite = INVALID_HANDLE_VALUE; HANDLE hDebug = INVALID_HANDLE_VALUE; BOOL bRet; DWORD dwError; DWORD Size, Actual ;
//
// Blow through the list of servers.
// and change the g_szServerShare to match.
//
if (TRUE == IsServerOnline(MachineName, NULL)){ //
// Set the server name now as we now have it
// into the outputbuffer
//
_stprintf (Buffer+_tcsclen(Buffer), TEXT("IdwlogServer:%s\r\n"), g_szServerShare); ZeroMemory( &NetResource, sizeof( NetResource ) ); NetResource.dwType = RESOURCETYPE_DISK ; NetResource.lpLocalName = "" ; NetResource.lpRemoteName = g_szServerShare; NetResource.lpProvider = "" ;
GetModuleFileName (NULL, szExePath, MAX_PATH); // First, try to connect with the current user ID
dwError = WNetAddConnection2( &NetResource,NULL,NULL,0 ); if (dwError) dwError = WNetAddConnection2( &NetResource,LOGSHARE_PW,LOGSHARE_USER,0 ); dwError = 0; // Hard reset.
if ( dwError == 0 ){ _stprintf (szLogFile, TEXT("%s\\%s"),g_szServerShare, MachineName ); hDebug = CreateFile(TEXT("C:\\setuplog.dbg"), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL|FILE_ATTRIBUTE_HIDDEN | FILE_FLAG_WRITE_THROUGH, NULL); if (hDebug != INVALID_HANDLE_VALUE) WriteFile (hDebug, szExePath, _tcsclen(szExePath), &Actual, NULL); hWrite = CreateFile( szLogFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH, NULL );
if ( hWrite != INVALID_HANDLE_VALUE ){ SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION; SECURITY_DESCRIPTOR sd; if (hDebug != INVALID_HANDLE_VALUE) WriteFile (hDebug, szValidHandle, sizeof(szValidHandle), &Actual, NULL);
Size = _tcsclen( Buffer ); bRet = WriteFile( hWrite, Buffer, Size, &Actual, NULL );
if (!bRet){ if (hDebug != INVALID_HANDLE_VALUE){ _stprintf (szErr, szBadWrite, GetLastError()); WriteFile (hDebug, szErr, lstrlen(szErr), &Actual, NULL); } } else{ if (hDebug != INVALID_HANDLE_VALUE) WriteFile (hDebug, szGoodWrite, sizeof(szGoodWrite), &Actual, NULL); } CloseHandle( hWrite ); //
// We should delete the shortcut to idwlog from startup group.
//
SHGetFolderPath (NULL, CSIDL_COMMON_STARTUP, NULL,0,szBinPath); PathAppend (szBinPath, SHORTCUT); DeleteFile (szBinPath);
//
// If this is idwlog.exe, delete the program.
// We only need to write once.
//
if (strstr (CharLower(szExePath), "idwlog.exe")) MoveFileEx ((LPCTSTR)szExePath, NULL, MOVEFILE_DELAY_UNTIL_REBOOT); } else{ if (hDebug != INVALID_HANDLE_VALUE){ _stprintf (szErr, szInvalidHandle, GetLastError()); WriteFile (hDebug, szErr, _tcsclen(szErr), &Actual, NULL); } } WNetCancelConnection2( g_szServerShare, 0, TRUE ); if (hDebug != INVALID_HANDLE_VALUE) CloseHandle (hDebug); } } }
VOID WriteDataToFile (IN LPTSTR szFileName, IN LPTSTR szFrom, IN LPNT32_CMD_PARAMS lpCmdL) {
TCHAR username[MY_MAX_UNLEN + 1]; TCHAR userdomain[ DNLEN+2 ]; TCHAR architecture[ 16 ]; SYSTEM_INFO SysInfo ;
TCHAR build_number[256]; TCHAR time[ 32 ]; DWORD Size; DISPLAY_DEVICE displayDevice; DWORD iLoop; DEVMODE dmCurrent; TCHAR displayname[MY_MAX_UNLEN + 1];
LPTSTR pch; TCHAR localename[4]; // locale abbreviation
TCHAR netcards[256] = "\0"; TCHAR vidinfo[256] = "\0"; TCHAR modem[256] = "\0"; TCHAR scsi[256] = "\0"; BOOL bUSB = FALSE; BOOL bPCCard = FALSE; BOOL bACPI = FALSE; BOOL bIR = FALSE; BOOL bHydra = FALSE; INT iNumDisplays = GetSystemMetrics(SM_CMONITORS);
MEMORYSTATUS msRAM;
DEV_INFO *pdi; strcpy(username, UNKNOWN); strcpy(displayname, UNKNOWN);
if (!GetEnvironmentVariable (USERNAME, username, MY_MAX_UNLEN)) lstrcpy (username, "Unknown");
// Get the build number
if (!szFrom) GetBuildNumber (build_number); else _tcscpy (build_number, szFrom);
GetSystemInfo( &SysInfo );
if ( !GetEnvironmentVariable( "USERDOMAIN", userdomain, sizeof( userdomain) ) ) _tcscpy (userdomain, "Unknown"); if ( !GetEnvironmentVariable( "PROCESSOR_ARCHITECTURE", architecture, sizeof( architecture ) ) ) _tcscpy (architecture, "Unknown");
// Video Information for ChrisW
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) *displayname = 0; else _tcscat( displayname, TEXT(",") ); _tcscat( displayname, dmCurrent.dmDeviceName ); } iLoop++; }
// replace spaces so we don't break the perl script the build lab is using
pch = displayname; while (*pch) { if (*pch == ' ') *pch = '.'; pch++; }
GetVidInfo (vidinfo);
// Get locale abbreviation so we know about language pack usage
if( GetLocaleInfo( LOCALE_SYSTEM_DEFAULT, LOCALE_SABBREVLANGNAME, localename, sizeof( localename)) == 0 ) _tcscpy(localename,"unk");
msRAM.dwLength = sizeof (msRAM); GlobalMemoryStatus (&msRAM); //
// Get PNP net card info
//
*netcards='\0'; *scsi='\0'; CollectDevData (); pdi=g_pdiDevList; while (pdi){ if (!lstrcmpi (pdi->szClass, "Net")){ if (_tcsclen(netcards) + lstrlen(pdi->szDescription) + lstrlen(pdi->szService) < 250){ _tcscat (netcards, pdi->szDescription); _tcscat (netcards, "("); _tcscat (netcards, pdi->szService); _tcscat (netcards, TEXT(") ")); } } else if (!lstrcmpi (pdi->szClass, "SCSIAdapter")){ if (_tcsclen(scsi) + lstrlen(pdi->szService) < 250){ _tcscat (scsi, pdi->szService); _tcscat (scsi, TEXT(",")); } } else if (!lstrcmpi (pdi->szClass, "Modem")){ if (_tcsclen(modem) + lstrlen(pdi->szDescription) < 250){ _tcscat (modem, pdi->szDescription); _tcscat (modem, TEXT(",")); } } else if (!lstrcmpi (pdi->szClass, "USB")) bUSB = TRUE; else if (!lstrcmpi (pdi->szClass, "Infrared")) bIR = TRUE; else if (!lstrcmpi (pdi->szClass, "PCMCIA") || !lstrcmpi (pdi->szService, "PCMCIA")) bPCCard = TRUE; else if (strstr (pdi->szClass, "ACPI") || strstr (pdi->szService, "ACPI")) bACPI = TRUE; pdi=pdi->Next; }
Cleanup(); //free all the pnp data and restore configuration
if (!(*netcards)) _tcscpy (netcards, TEXT("Unknown")); //
// Get Sound info
GetNTSoundInfo (); // format all our data
bHydra= IsHydra ();
// fix the number of displays for non Windows 2000 systems
if (!iNumDisplays) iNumDisplays = 1;
//wsprintf only accepts 1k buffers.
// Break these up into more calls to
// wsprintf to eliminate chance of overflow
_stprintf (OutputBuffer, TEXT("MachineID:%lu\r\n") TEXT("Source Media:%s\r\n") TEXT("Type:%s\r\nUsername:%s\r\n") TEXT("RAM:%d\r\n") TEXT("FromBld:%s\r\n") TEXT("Arch:%s\r\nNumProcs:%d\r\n") TEXT("Vidinfo:%s\r\n"), lpCmdL->dwRandomID, lpCmdL->b_CDrom? TEXT("C"): TEXT("N"), lpCmdL->b_Upgrade?TEXT("U"):TEXT("I"), username, msRAM.dwTotalPhys/(1024*1024), szFrom?szFrom:build_number, architecture, SysInfo.dwNumberOfProcessors, vidinfo );
_stprintf (OutputBuffer+_tcsclen(OutputBuffer), TEXT("VidDriver:%s\r\n") TEXT("Locale:%s\r\nSound:%s\r\nNetCards:%s\r\n") TEXT("ACPI:%d\r\n") TEXT("PCMCIA:%d\r\n") TEXT("CPU:%d\r\n") TEXT("SCSI:%s\r\n") TEXT("USB:%d\r\n") TEXT("Infrared:%d\r\n"), displayname, localename, m.nNumWaveOutDevices?m.szWaveDriverName[0]:TEXT("None"), netcards, bACPI, bPCCard, (DWORD)SysInfo.wProcessorLevel, scsi, bUSB, bIR ); _stprintf (OutputBuffer+_tcsclen(OutputBuffer), TEXT("Modem:%s\r\n") TEXT("Hydra:%d\r\n") TEXT("Displays:%d\r\n") TEXT("MSI:%s\r\n"), modem, bHydra, iNumDisplays, lpCmdL->b_MsiInstall? TEXT("Y"):TEXT("N") );
ConnectAndWrite( szFileName, OutputBuffer ); }
BOOL IsServerOnline(IN LPTSTR szMachineName, IN LPTSTR szSpecifyShare) /*++
Routine Description: This will go through the list of servers specified in setuplogEXE.h It will return the first in it sees and reset the global server share name.
Arguments: The machineName (Filename with build etc) so the test file will get overwritten. Manual Server Name: NULL will give default behaviour.
Return Value: TRUE for success. FALSE for no name. --*/
{ DWORD dw; HANDLE hThrd; INT i; TCHAR szServerFile[ MAX_PATH ]; DWORD dwTimeOutInterval; i = 0;
//
// This should allow for a
// manually specified server.
//
if (NULL != szSpecifyShare){ _tcscpy(g_szServerShare,szSpecifyShare); return TRUE;
} //
// Initialize the Server.
// Variable. Since we are using a single thread
// to do a time out we don't care about mutexes and
// sychronization.
//
g_bServerOnline = FALSE;
while ( i < NUM_SERVERS){
_stprintf (szServerFile, TEXT("%s\\%s"),s[i].szSvr,szMachineName ); //
// Spawn the thread
//
hThrd = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) ServerOnlineThread, (LPTSTR) szServerFile, 0, &dw); //
// This is in milli seconds so the time out is secs.
//
dwTimeOutInterval = TIME_TIMEOUT * 1000;
s[i].dwTimeOut = WaitForSingleObject (hThrd, dwTimeOutInterval); CloseHandle (hThrd);
//
// This means the server passed the timeout.
//
if (s[i].dwTimeOut != WAIT_TIMEOUT && g_bServerOnline == TRUE){ //
// Copy the Share to the glowbal var.
//
_tcscpy(g_szServerShare,s[i].szSvr); return TRUE; } i++; } return FALSE; }
BOOL ServerOnlineThread(IN LPTSTR szServerFile) /*++
Routine Description: This create a thread and then time it out to see if we can get to a server faster.
Arguments: The machineName so the test file will get overwritten. Return Value:
--*/ {
BOOL bCopy = FALSE; TCHAR szFileSrc [MAX_PATH]; TCHAR szServerTestFile [MAX_PATH]; //
// Use this to get the location
// setuplog.exe is run from. this tool
//
GetModuleFileName (NULL, szFileSrc, MAX_PATH); //
// Make a unique test file.
//
_stprintf(szServerTestFile,TEXT("%s.SERVERTEST"),szServerFile); bCopy = CopyFile( szFileSrc,szServerTestFile, FALSE); if (bCopy != FALSE){ //
// If Succeeded Delete the test file.
//
DeleteFile(szServerTestFile); g_bServerOnline = TRUE; return TRUE; } else{ g_bServerOnline = FALSE; return FALSE; } }
|