|
|
/*++
Copyright (c) 1998 Microsoft Corporation
Module Name:
common9x.c
Abstract:
Common functionality between various parts of Win9x-side processing. The routines in this library are shared only by other LIBs in the w95upg tree.
Author:
Jim Schmidt (jimschm) 18-Aug-1998
Revision History:
Name (alias) Date Description
--*/
#include "pch.h"
static PMAPSTRUCT g_EnvVars9x;
typedef struct { UINT MapSize; UINT Icons; BYTE Map[]; } ICONMAP, *PICONMAP;
static HASHTABLE g_IconMaps; static POOLHANDLE g_IconMapPool; static BYTE g_Bits[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
BOOL WINAPI Common9x_Entry ( IN HINSTANCE Instance, IN DWORD Reason, IN PVOID lpv )
/*++
Routine Description:
Common9x_Entry is a DllMain-like init funciton, called by w95upg\dll. This function is called at process attach and detach.
Arguments:
Instance - (OS-supplied) instance handle for the DLL Reason - (OS-supplied) indicates attach or detatch from process or thread lpv - unused
Return Value:
Return value is always TRUE (indicating successful init).
--*/
{ switch (Reason) {
case DLL_PROCESS_ATTACH: //
// used by userenum.c
//
if(!pSetupInitializeUtils()) { return FALSE; } break;
case DLL_PROCESS_DETACH: pSetupUninitializeUtils(); break; }
return TRUE; }
BOOL EnumFirstJoystick ( OUT PJOYSTICK_ENUM EnumPtr ) { ZeroMemory (EnumPtr, sizeof (JOYSTICK_ENUM));
EnumPtr->Root = OpenRegKeyStr (TEXT("HKLM\\System\\CurrentControlSet\\Control\\MediaResources\\joystick\\<FixedKey>\\CurrentJoystickSettings"));
if (!EnumPtr->Root) { return FALSE; }
return EnumNextJoystick (EnumPtr); }
BOOL EnumNextJoystick ( IN OUT PJOYSTICK_ENUM EnumPtr ) { TCHAR ValueName[MAX_REGISTRY_VALUE_NAME]; PCTSTR Data;
//
// Ping the root key for Joystick<n>OEMName and Joystick<n>OEMCallout
//
EnumPtr->JoyId++;
wsprintf (ValueName, TEXT("Joystick%uOEMName"), EnumPtr->JoyId); Data = GetRegValueString (EnumPtr->Root, ValueName);
if (!Data) { AbortJoystickEnum (EnumPtr); return FALSE; }
StringCopy (EnumPtr->JoystickName, Data); MemFree (g_hHeap, 0, Data);
wsprintf (ValueName, TEXT("Joystick%uOEMCallout"), EnumPtr->JoyId); Data = GetRegValueString (EnumPtr->Root, ValueName);
if (!Data) { AbortJoystickEnum (EnumPtr); return FALSE; }
StringCopy (EnumPtr->JoystickDriver, Data); MemFree (g_hHeap, 0, Data);
return TRUE; }
VOID AbortJoystickEnum ( IN PJOYSTICK_ENUM EnumPtr ) { if (EnumPtr->Root) { CloseRegKey (EnumPtr->Root); }
ZeroMemory (EnumPtr, sizeof (JOYSTICK_ENUM)); }
typedef struct {
PCTSTR Text; PCTSTR Button1; PCTSTR Button2;
} TWOBUTTONBOXPARAMS, *PTWOBUTTONBOXPARAMS;
BOOL CALLBACK TwoButtonProc ( HWND hdlg, UINT uMsg, WPARAM wParam, LPARAM lParam ) { PTWOBUTTONBOXPARAMS params;
switch (uMsg) { case WM_INITDIALOG:
params = (PTWOBUTTONBOXPARAMS) lParam; SetWindowText (GetDlgItem (hdlg, IDC_TWOBUTTON_TEXT), params->Text); SetWindowText (GetDlgItem (hdlg, IDBUTTON1), params->Button1); SetWindowText (GetDlgItem (hdlg, IDBUTTON2), params->Button2);
CenterWindow (hdlg, GetDesktopWindow());
return FALSE;
case WM_COMMAND:
EndDialog (hdlg, LOWORD (wParam)); break; }
return FALSE;
}
LRESULT TwoButtonBox ( IN HWND Window, IN PCTSTR Text, IN PCTSTR Button1, IN PCTSTR Button2 ) { TWOBUTTONBOXPARAMS params;
params.Text = Text; params.Button1 = Button1; params.Button2 = Button2;
return DialogBoxParam ( g_hInst, MAKEINTRESOURCE(IDD_TWOBUTTON_DLG), Window, TwoButtonProc, (LPARAM) ¶ms ); }
BOOL DontTouchThisFile ( IN PCTSTR FileName ) { TCHAR key[MEMDB_MAX];
RemoveOperationsFromPath (FileName, ALL_CHANGE_OPERATIONS);
MemDbBuildKey (key, MEMDB_CATEGORY_DEFERREDANNOUNCE, FileName, NULL, NULL); MemDbDeleteTree (key);
return TRUE; }
VOID ReplaceOneEnvVar ( IN OUT PCTSTR *NewString, IN PCTSTR Base, IN PCTSTR Variable, IN PCTSTR Value ) { PCTSTR FreeMe;
//
// The Base string cannot be freed, but a previous NewString
// value must be freed.
//
FreeMe = *NewString; // FreeMe will be NULL if no replacement string
// has been generated yet
if (FreeMe) { Base = FreeMe; // Previously generated replacement string is now the source
}
*NewString = StringSearchAndReplace (Base, Variable, Value);
if (*NewString == NULL) { // Keep previously generated replacement string
*NewString = FreeMe; } else if (FreeMe) { // Free previously generated replacmenet string
FreePathString (FreeMe); }
//
// *NewString is either:
//
// 1. It's original value (which may be NULL)
// 2. A new string that will need to be freed with FreePathString
//
}
VOID Init9xEnvironmentVariables ( VOID ) {
DestroyStringMapping (g_EnvVars9x); g_EnvVars9x = CreateStringMapping();
AddStringMappingPair (g_EnvVars9x, S_WINDIR_ENV, g_WinDir); AddStringMappingPair (g_EnvVars9x, S_SYSTEMDIR_ENV, g_SystemDir); AddStringMappingPair (g_EnvVars9x, S_SYSTEM32DIR_ENV, g_System32Dir); AddStringMappingPair (g_EnvVars9x, S_SYSTEMDRIVE_ENV, g_WinDrive); AddStringMappingPair (g_EnvVars9x, S_BOOTDRIVE_ENV, g_BootDrivePath); AddStringMappingPair (g_EnvVars9x, S_PROGRAMFILES_ENV, g_ProgramFilesDir); AddStringMappingPair (g_EnvVars9x, S_COMMONPROGRAMFILES_ENV, g_ProgramFilesCommonDir); }
BOOL Expand9xEnvironmentVariables ( IN PCSTR SourceString, OUT PSTR DestinationString, // can be the same as SourceString
IN INT DestSizeInBytes ) { BOOL Changed;
Changed = MappingSearchAndReplaceEx ( g_EnvVars9x, SourceString, DestinationString, 0, NULL, DestSizeInBytes, STRMAP_ANY_MATCH, NULL, NULL );
return Changed; }
VOID CleanUp9xEnvironmentVariables ( VOID ) { DestroyStringMapping (g_EnvVars9x); }
BOOL pIsGuid ( PCTSTR Key )
/*++
Routine Description:
pIsGuid examines the string specified by Key and determines if it is the correct length and has dashes at the correct locations.
Arguments:
Key - The string that may or may not be a GUID
Return Value:
TRUE if Key is a GUID (and only a GUID), or FALSE if not.
--*/
{ PCTSTR p; int i; DWORD DashesFound = 0;
if (CharCount (Key) != 38) { return FALSE; }
for (i = 0, p = Key ; *p ; p = _tcsinc (p), i++) { if (_tcsnextc (p) == TEXT('-')) { if (i != 9 && i != 14 && i != 19 && i != 24) { DEBUGMSG ((DBG_NAUSEA, "%s is not a GUID", Key)); return FALSE; } } else if (i == 9 || i == 14 || i == 19 || i == 24) { DEBUGMSG ((DBG_NAUSEA, "%s is not a GUID", Key)); return FALSE; } }
return TRUE; }
BOOL FixGuid ( IN PCTSTR Guid, OUT PTSTR NewGuid // can be the same as Guid
) { TCHAR NewData[MAX_GUID];
if (pIsGuid (Guid)) { if (NewGuid != Guid) { StringCopy (NewGuid, Guid); }
return TRUE; }
//
// Try fixing GUID -- sometimes the braces are missing
//
wsprintf (NewData, TEXT("{%s}"), Guid); if (pIsGuid (NewData)) { StringCopy (NewGuid, NewData); return TRUE; }
return FALSE; }
BOOL IsGuid ( IN PCTSTR Guid, IN BOOL MustHaveBraces ) { TCHAR NewData[MAX_GUID];
if (pIsGuid (Guid)) { return TRUE; }
if (MustHaveBraces) { return FALSE; }
//
// Try fixing GUID -- sometimes the braces are missing
//
wsprintf (NewData, TEXT("{%s}"), Guid); if (pIsGuid (NewData)) { return TRUE; }
return FALSE; }
VOID pParseMapRanges ( IN PCTSTR List, OUT PGROWBUFFER Ranges, OPTIONAL OUT PINT HighestNumber OPTIONAL ) { MULTISZ_ENUM e; PTSTR ParsePos; INT From; INT To; INT Max = 0; PINT Ptr;
if (EnumFirstMultiSz (&e, List)) { do { //
// The INF has either a single resource ID, or
// a range, separated by a dash.
//
if (_tcschr (e.CurrentString, TEXT('-'))) {
From = (INT) _tcstoul (e.CurrentString, &ParsePos, 10);
ParsePos = (PTSTR) SkipSpace (ParsePos); if (_tcsnextc (ParsePos) != TEXT('-')) { DEBUGMSG ((DBG_WHOOPS, "Ignoring invalid resource ID %s", e.CurrentString)); continue; }
ParsePos = (PTSTR) SkipSpace (_tcsinc (ParsePos));
To = (INT) _tcstoul (ParsePos, &ParsePos, 10);
if (*ParsePos) { DEBUGMSG ((DBG_WHOOPS, "Ignoring garbage resource ID %s", e.CurrentString)); continue; }
if (From > To) { DEBUGMSG ((DBG_WHOOPS, "Ignoring invalid resource ID range %s", e.CurrentString)); continue; }
Max = max (Max, To);
} else { From = To = (INT) _tcstoul (e.CurrentString, &ParsePos, 10);
if (*ParsePos) { DEBUGMSG ((DBG_WHOOPS, "Ignoring garbage resource %s", e.CurrentString)); continue; }
Max = max (Max, From); }
if (Ranges) {
Ptr = (PINT) GrowBuffer (Ranges, sizeof (INT)); *Ptr = From;
Ptr = (PINT) GrowBuffer (Ranges, sizeof (INT)); *Ptr = To;
} } while (EnumNextMultiSz (&e)); }
if (HighestNumber) { *HighestNumber = Max; } }
VOID InitializeKnownGoodIconMap ( VOID ) { PICONMAP Map; INT Highest; INT From; INT To; INFSTRUCT is = INITINFSTRUCT_GROWBUFFER; PCTSTR Module; PCTSTR List; PCTSTR IconsInModule; GROWBUFFER Ranges = GROWBUF_INIT; PINT Ptr; PINT End; UINT MapDataSize; PBYTE Byte; BYTE Bit;
if (g_IconMaps) { return; }
if (g_Win95UpgInf == INVALID_HANDLE_VALUE) { MYASSERT (g_ToolMode); return; }
g_IconMaps = HtAllocWithData (sizeof (PICONMAP)); g_IconMapPool = PoolMemInitNamedPool ("IconMap");
//
// Enumerate the lines in win95upg.inf and build a map table for each
//
if (InfFindFirstLine (g_Win95UpgInf, S_KNOWN_GOOD_ICON_MODULES, NULL, &is)) { do {
//
// Parse the INF format into a binary struct
//
List = InfGetMultiSzField (&is, 2);
pParseMapRanges (List, &Ranges, &Highest);
if (!Ranges.End) { continue; }
//
// Allocate a map struct
//
MapDataSize = (Highest / 8) + 1; Map = PoolMemGetMemory (g_IconMapPool, sizeof (ICONMAP) + MapDataSize);
//
// Fill in the map
//
Map->MapSize = Highest; ZeroMemory (Map->Map, MapDataSize);
Ptr = (PINT) Ranges.Buf; End = (PINT) (Ranges.Buf + Ranges.End);
while (Ptr < End) { From = *Ptr++; To = *Ptr++;
while (From <= To) { Byte = Map->Map + (From / 8); Bit = g_Bits[From & 7];
*Byte |= Bit; From++; } }
FreeGrowBuffer (&Ranges);
IconsInModule = InfGetStringField (&is, 1); if (IconsInModule) { Map->Icons = _tcstoul (IconsInModule, NULL, 10); } else { continue; }
//
// Cross-reference the map with the module name via a hash table
//
Module = InfGetStringField (&is, 0); if (!Module || !*Module) { continue; }
HtAddStringAndData (g_IconMaps, Module, &Map);
} while (InfFindNextLine (&is)); }
InfCleanUpInfStruct (&is); }
VOID CleanUpKnownGoodIconMap ( VOID ) { if (g_IconMaps) { HtFree (g_IconMaps); g_IconMaps = NULL; }
if (g_IconMapPool) { PoolMemDestroyPool (g_IconMapPool); g_IconMapPool = NULL; } }
BOOL IsIconKnownGood ( IN PCTSTR FileSpec, IN INT Index ) { PCTSTR Module; PICONMAP Map; PBYTE Byte; BYTE Bit; TCHAR node[MEMDB_MAX];
Module = GetFileNameFromPath (FileSpec); MYASSERT (Module);
//
// Check icon against moved icons
//
wsprintf (node, MEMDB_CATEGORY_ICONS_MOVED TEXT("\\%s\\%i"), FileSpec, Index); if (MemDbGetValue (node, NULL)) { return TRUE; }
//
// If a path is specified, make sure it is in either %windir% or %windir%\system.
//
if (Module > (FileSpec + 2)) {
if (!StringIMatchCharCount (FileSpec, g_WinDirWack, g_WinDirWackChars) && !StringIMatchCharCount (FileSpec, g_SystemDirWack, g_SystemDirWackChars) ) { return FALSE; } }
//
// Test if there is an icon map for this module, then check the map
//
if (!HtFindStringAndData (g_IconMaps, Module, &Map)) { return FALSE; }
//
// If the icon index is a positive number, then it is a sequential
// ID. If it is a negative number, then it is a resource ID.
//
if (Index >= 0) { return (UINT) Index <= Map->Icons; }
Index = -Index;
if ((UINT) Index > Map->MapSize) { return FALSE; }
Byte = Map->Map + (Index / 8); Bit = g_Bits[Index & 7];
return *Byte & Bit; }
BOOL TreatAsGood ( IN PCTSTR FullPath )
/*++
Routine Description:
TreatAsGood checks the registry to see if a file is listed as good. If this is the case, then setup processing is skipped. This is currently used for TWAIN data sources, run keys and CPLs.
Arguments:
FullPath - Specifies the full path of the file.
Return Value:
TRUE if the file should be treated as known good, FALSE otherwise.
--*/
{ HKEY Key; REGVALUE_ENUM e; BOOL b = FALSE; PCTSTR str;
Key = OpenRegKeyStr (TEXT("HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Setup\\KnownGood"));
if (Key) {
if (EnumFirstRegValue (&e, Key)) { do {
str = GetRegValueString (Key, e.ValueName);
if (str) { b = StringIMatch (FullPath, str); MemFree (g_hHeap, 0, str);
DEBUGMSG_IF ((b, DBG_VERBOSE, "File %s is known-good", FullPath)); }
} while (!b && EnumNextRegValue (&e)); }
CloseRegKey (Key); }
return b; }
|