|
|
/*++
Copyright (c) 1997 Microsoft Corporation
Module Name:
hwwiz.c
Abstract:
Implements a upgwiz wizard for obtaining hardware information.
Author:
Jim Schmidt (jimschm) 05-Oct-1998
Revision History:
<alias> <date> <comments>
--*/
#include "pch.h"
#include "..\inc\dgdll.h"
DATATYPE g_DataTypes[] = { {UPGWIZ_VERSION, "PNP Device Should Be Compatible", "You specify the PNP device or devices that were incorrectly reported as incompatible.", 0 },
{UPGWIZ_VERSION, "PNP Device Should Be Incompatible", "You specify the PNP device or devices that need to be reported as incompatible.", 0 },
{UPGWIZ_VERSION, "PNP Device Has Loss of Functionality", "A device is compatible, but some functionality is lost.", 0, DTF_REQUIRE_TEXT|DTF_ONE_SELECTION, 1024, NULL, "&Text For Incompatibility:" },
{UPGWIZ_VERSION, "Compatible Windows 3.1 Driver", "Use this to completely suppress the generic Win3.1 driver warning for a .386 file.", 0, DTF_REQUIRE_DESCRIPTION|DTF_ONE_SELECTION, 1024, "&Name of Device that Driver Controls:" },
{UPGWIZ_VERSION, "Incompatible Windows 3.1 Driver", "Use this to give a better problem description to a driver that causes the generic Win3.1 driver warning.", 0, DTF_REQUIRE_TEXT|DTF_REQUIRE_DESCRIPTION|DTF_ONE_SELECTION, 1024, "&Name of Device that Driver Controls:", "&Describe The Problem:" },
{UPGWIZ_VERSION, "Compatible TWAIN Data Sources", "Removes the incompatible warning caused by an unknown TWAIN data source." },
{UPGWIZ_VERSION, "Compatible Joysticks", "Removes the incompatible warning caused by an unknown joysticks." }
};
GROWBUFFER g_DataObjects = GROWBUF_INIT; POOLHANDLE g_DataObjectPool;
typedef struct { PCSTR Description; PCSTR FullPath; } TWAINPARAM, *PTWAINPARAM;
BOOL pGeneratePnpOutput ( IN POUTPUTARGS Args, IN HANDLE File );
BOOL pGenerateWin31DriverOutput ( IN POUTPUTARGS Args, IN HANDLE File );
BOOL pGenerateTwainOutput ( IN POUTPUTARGS Args, IN HANDLE File );
BOOL pGenerateJoystickOutput ( IN POUTPUTARGS Args, IN HANDLE File );
HINSTANCE g_OurInst;
BOOL Init ( VOID ) { #ifndef UPGWIZ4FLOPPY
return InitToolMode (g_OurInst); #else
return TRUE; #endif
}
VOID Terminate ( VOID ) { //
// Local cleanup
//
FreeGrowBuffer (&g_DataObjects);
if (g_DataObjectPool) { PoolMemDestroyPool (g_DataObjectPool); }
#ifndef UPGWIZ4FLOPPY
TerminateToolMode (g_OurInst); #endif
}
BOOL WINAPI DllMain ( IN HINSTANCE hInstance, IN DWORD dwReason, IN LPVOID lpReserved ) { if (dwReason == DLL_PROCESS_DETACH) { MYASSERT (g_OurInst == hInstance); Terminate(); }
g_OurInst = hInstance;
return TRUE; }
UINT GiveVersion ( VOID ) { Init();
return UPGWIZ_VERSION; }
PDATATYPE GiveDataTypeList ( OUT PUINT Count ) { UINT u;
*Count = sizeof (g_DataTypes) / sizeof (g_DataTypes[0]);
for (u = 0 ; u < *Count ; u++) { g_DataTypes[u].DataTypeId = u; }
return g_DataTypes; }
PDATAOBJECT GiveDataObjectList ( IN UINT DataTypeId, OUT PUINT Count ) { HARDWARE_ENUM e; PDATAOBJECT Data; HINF Inf; TCHAR Path[MAX_TCHAR_PATH]; TCHAR FullPath[MAX_TCHAR_PATH]; INFSTRUCT is = INITINFSTRUCT_GROWBUFFER; PCTSTR DriverPath; PCTSTR DriverFile; TWAINDATASOURCE_ENUM te; JOYSTICK_ENUM je; TWAINPARAM TwainParam;
g_DataObjectPool = PoolMemInitNamedPool ("Data Objects");
if (DataTypeId < 3) { //
// Enumerate the PNP devices
//
if (EnumFirstHardware (&e, ENUM_ALL_DEVICES, ENUM_WANT_DEV_FIELDS)) { do { if (!e.Driver || !e.DeviceDesc || !e.InstanceId) { continue; }
Data = (PDATAOBJECT) GrowBuffer (&g_DataObjects, sizeof (DATAOBJECT));
Data->Version = UPGWIZ_VERSION; Data->NameOrPath = PoolMemDuplicateString (g_DataObjectPool, e.DeviceDesc); Data->Flags = 0; Data->DllParam = PoolMemDuplicateString (g_DataObjectPool, e.FullKey);
} while (EnumNextHardware (&e)); }
} else if (DataTypeId >= 3 && DataTypeId < 5) { //
// Enumerate the .386 candidates
//
wsprintf (Path, TEXT("%s\\system.ini"), g_WinDir);
Inf = InfOpenInfFile (Path); if (Inf != INVALID_HANDLE_VALUE) { if (InfFindFirstLine (Inf, TEXT("386Enh"), NULL, &is)) { do { DriverPath = InfGetStringField (&is, 1); if (DriverPath) { //
// Determine if device driver is known
//
if (_tcsnextc (DriverPath) != TEXT('*')) { DriverFile = GetFileNameFromPath (DriverPath);
if (!_tcschr (DriverPath, TEXT(':'))) { if (!SearchPath ( NULL, DriverFile, NULL, MAX_TCHAR_PATH, FullPath, NULL )) { _tcssafecpy (FullPath, DriverPath, MAX_TCHAR_PATH); } } else { _tcssafecpy (FullPath, DriverPath, MAX_TCHAR_PATH); }
if (!_tcschr (FullPath, TEXT(':'))) { continue; }
Data = (PDATAOBJECT) GrowBuffer (&g_DataObjects, sizeof (DATAOBJECT));
Data->Version = UPGWIZ_VERSION; Data->NameOrPath = PoolMemDuplicateString (g_DataObjectPool, DriverFile); Data->Flags = 0; Data->DllParam = PoolMemDuplicateString (g_DataObjectPool, FullPath); } }
} while (InfFindNextLine (&is)); }
InfCloseInfFile (Inf); InfCleanUpInfStruct (&is); }
} else if (DataTypeId == 5) { //
// Enumerate the TWAIN devices
//
if (EnumFirstTwainDataSource (&te)) { do { Data = (PDATAOBJECT) GrowBuffer (&g_DataObjects, sizeof (DATAOBJECT));
Data->Version = UPGWIZ_VERSION; Data->NameOrPath = PoolMemDuplicateString (g_DataObjectPool, te.DisplayName); Data->Flags = 0;
TwainParam.Description = PoolMemDuplicateString (g_DataObjectPool, te.DisplayName); TwainParam.FullPath = PoolMemDuplicateString (g_DataObjectPool, te.DataSourceModule);
Data->DllParam = PoolMemGetAlignedMemory (g_DataObjectPool, sizeof (TWAINPARAM));
CopyMemory (Data->DllParam, &TwainParam, sizeof (TWAINPARAM));
} while (EnumNextTwainDataSource (&te)); }
} else if (DataTypeId == 6) { //
// Enumerate the Joystick
//
if (EnumFirstJoystick (&je)) { do {
if (!_mbschr (je.JoystickDriver, ':')) { if (!SearchPath ( NULL, je.JoystickDriver, NULL, MAX_TCHAR_PATH, Path, NULL )) { continue; } } else { StringCopy (Path, je.JoystickDriver); }
Data = (PDATAOBJECT) GrowBuffer (&g_DataObjects, sizeof (DATAOBJECT));
Data->Version = UPGWIZ_VERSION; Data->NameOrPath = PoolMemDuplicateString (g_DataObjectPool, je.JoystickName); Data->Flags = 0;
TwainParam.Description = PoolMemDuplicateString (g_DataObjectPool, je.JoystickName); TwainParam.FullPath = PoolMemDuplicateString (g_DataObjectPool, Path);
Data->DllParam = PoolMemGetAlignedMemory (g_DataObjectPool, sizeof (TWAINPARAM));
CopyMemory (Data->DllParam, &TwainParam, sizeof (TWAINPARAM));
} while (EnumNextJoystick (&je)); } }
*Count = g_DataObjects.End / sizeof (DATAOBJECT);
return (PDATAOBJECT) g_DataObjects.Buf; }
BOOL OldGenerateOutput ( IN POUTPUTARGS Args ) { return TRUE; }
//#if 0
BOOL pWritePnpIdRule ( IN HANDLE File, IN PHARDWARE_ENUM EnumPtr, IN PCSTR Description OPTIONAL ) { CHAR Path[MAX_MBCHAR_PATH]; CHAR DriverKey[MAX_REGISTRY_KEY]; HKEY Key = NULL; BOOL b = FALSE; PCSTR InfPath = NULL; WIN32_FIND_DATA fd; HANDLE Find = INVALID_HANDLE_VALUE; CHAR Buf[2048]; CHAR WinDir[MAX_MBCHAR_PATH]; CHAR StringSectKey[256];
GetWindowsDirectory (WinDir, MAX_MBCHAR_PATH);
if (Description && *Description == 0) { Description = NULL; }
//
// Get the driver
//
__try { if (!EnumPtr->Driver || !EnumPtr->DeviceDesc || !EnumPtr->InstanceId) { DEBUGMSG ((DBG_WHOOPS, "Enum field missing; should have been screened out of object list")); __leave; }
wsprintf (DriverKey, "HKLM\\System\\CurrentControlSet\\Services\\Class\\%s", EnumPtr->Driver);
Key = OpenRegKeyStr (DriverKey); if (!Key) { DEBUGMSG ((DBG_WHOOPS, "Can't open %s", DriverKey)); __leave; }
InfPath = GetRegValueString (Key, "InfPath"); if (!InfPath || *InfPath == 0) { DEBUGMSG ((DBG_WHOOPS, "No InfPath in %s", DriverKey)); MessageBox (NULL, "Selected device does not have an INF path. The INF path is required.", NULL, MB_OK); __leave; }
if (!_mbschr (InfPath, '\\')) { wsprintf (Path, "%s\\inf\\%s", WinDir, InfPath); } else { StringCopy (Path, InfPath); }
Find = FindFirstFile (Path, &fd); if (Find == INVALID_HANDLE_VALUE) { DEBUGMSG ((DBG_WHOOPS, "Can't find %s", Path)); __leave; }
if (!Description) { wsprintf (Buf, "%s,,", EnumPtr->DeviceDesc); } else { GenerateUniqueStringSectKey ("DV", StringSectKey); wsprintf (Buf, "%s, %%%s%%,", EnumPtr->DeviceDesc, StringSectKey); }
if (!WizardWriteColumn (File, Buf, 45)) { __leave; }
wsprintf (Buf, "%s,", fd.cFileName); if (!WizardWriteColumn (File, Buf, 15)) { __leave; }
wsprintf (Buf, "FILESIZE(%u),", fd.nFileSizeLow); if (!WizardWriteRealString (File, Buf)) { __leave; }
if (!WizardWriteRealString (File, " PNPID(")) { __leave; }
if (!WizardWriteQuotedString (File, EnumPtr->InstanceId)) { __leave; }
if (!WizardWriteRealString (File, ")\r\n")) { __leave; }
if (Description) { if (!WizardWriteRealString (File, "[Strings]\r\n")) { __leave; }
WriteStringSectKey (File, StringSectKey, Description); }
b = TRUE; } __finally { if (Key) { CloseRegKey (Key); }
if (InfPath) { MemFree (g_hHeap, 0, InfPath); }
if (Find != INVALID_HANDLE_VALUE) { FindClose (Find); } }
return b; }
BOOL GenerateOutput ( IN POUTPUTARGS Args ) { BOOL b = FALSE; HANDLE File; CHAR Path[MAX_MBCHAR_PATH];
switch (Args->DataTypeId) {
case 0: wsprintf (Path, "%s\\comphw.txt", Args->OutboundDir); break;
case 1: wsprintf (Path, "%s\\incomphw.txt", Args->OutboundDir); break;
case 2: wsprintf (Path, "%s\\hwfnloss.inx", Args->OutboundDir); break;
case 3: case 4: wsprintf (Path, "%s\\win31drv.inx", Args->OutboundDir); break;
case 5: wsprintf (Path, "%s\\twain.inx", Args->OutboundDir); break;
case 6: wsprintf (Path, "%s\\joystick.inx", Args->OutboundDir); break;
default: wsprintf (Path, "%s\\unknown.txt", Args->OutboundDir); break; }
printf ("Saving data to %s\n\n", Path);
File = CreateFile ( Path, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
if (File == INVALID_HANDLE_VALUE) { printf ("Can't open file for output.\n"); return FALSE; }
__try { SetFilePointer (File, 0, NULL, FILE_END);
//
// Write [Identification] for all .inx files
//
switch (Args->DataTypeId) {
case 0: case 1: break;
default: if (!WizardWriteRealString (File, "[Identification]\r\n")) { __leave; } break; }
//
// Write user name and date/time
//
if (!WriteHeader (File)) { __leave; }
//
// Generate output depending on the type
//
switch (Args->DataTypeId) {
case 0: case 1: case 2: b = pGeneratePnpOutput (Args, File); break;
case 3: case 4: b = pGenerateWin31DriverOutput (Args, File); break;
case 5: b = pGenerateTwainOutput (Args, File); break;
case 6: b = pGenerateJoystickOutput (Args, File); break; }
//
// Write a final blank line
//
b = b & WizardWriteRealString (File, "\r\n"); } __finally { CloseHandle (File); }
return b; }
BOOL pGeneratePnpOutput ( IN POUTPUTARGS Args, IN HANDLE File ) { PDATAOBJECT Data; UINT Count; UINT Pos; HARDWARE_ENUM e; BOOL b = FALSE;
__try { Count = g_DataObjects.End / sizeof (DATAOBJECT);
if (EnumFirstHardware (&e, ENUM_ALL_DEVICES, ENUM_WANT_DEV_FIELDS)) { do { Data = (PDATAOBJECT) g_DataObjects.Buf;
for (Pos = 0 ; Pos < Count ; Pos++) {
if (StringIMatch ((PCSTR) Data->DllParam, e.FullKey)) {
if (Data->Flags & DOF_SELECTED) {
if (Args->DataTypeId == 2) { if (!WizardWriteRealString (File, "[MinorProblems]\r\n")) { __leave; }
if (!pWritePnpIdRule (File, &e, Args->OptionalText)) { __leave; }
} else {
if (!pWritePnpIdRule (File, &e, NULL)) { __leave; } } }
break; }
Data++; }
} while (EnumNextHardware (&e)); }
b = TRUE; } __finally { if (!b) { AbortHardwareEnum (&e); } }
return b; }
BOOL pGenerateWin31DriverOutput ( IN POUTPUTARGS Args, IN HANDLE File ) { PDATAOBJECT Data; UINT Pos; UINT Count; BOOL b = FALSE;
Data = (PDATAOBJECT) g_DataObjects.Buf; Count = g_DataObjects.End / sizeof (DATAOBJECT);
for (Pos = 0 ; Pos < Count ; Pos++) {
if (Data->Flags & DOF_SELECTED) {
b = WriteFileAttributes ( Args, NULL, File, (PCSTR) Data->DllParam, Args->OptionalText ? "[NonPnpDrivers]" : "[NonPnpDrivers_NoMessage]" );
break; }
Data++; }
return b; }
BOOL pGenerateTwainOutput ( IN POUTPUTARGS Args, IN HANDLE File ) { PDATAOBJECT Data; UINT Pos; UINT Count; BOOL b = FALSE; PTWAINPARAM TwainParam;
Data = (PDATAOBJECT) g_DataObjects.Buf; Count = g_DataObjects.End / sizeof (DATAOBJECT);
for (Pos = 0 ; Pos < Count ; Pos++) {
if (Data->Flags & DOF_SELECTED) {
TwainParam = (PTWAINPARAM) Data->DllParam;
b = WriteFileAttributes ( Args, TwainParam->Description, File, TwainParam->FullPath, "[CompatibleFiles]" );
break; }
Data++; }
return b; }
BOOL pGenerateJoystickOutput ( IN POUTPUTARGS Args, IN HANDLE File ) { PDATAOBJECT Data; UINT Pos; UINT Count; BOOL b = FALSE; PTWAINPARAM TwainParam;
Data = (PDATAOBJECT) g_DataObjects.Buf; Count = g_DataObjects.End / sizeof (DATAOBJECT);
for (Pos = 0 ; Pos < Count ; Pos++) {
if (Data->Flags & DOF_SELECTED) {
TwainParam = (PTWAINPARAM) Data->DllParam;
b = WriteFileAttributes ( Args, TwainParam->Description, File, TwainParam->FullPath, "[CompatibleFiles]" );
break; }
Data++; }
return b; }
//#endif
|