/*++ Copyright (c) 1997 Microsoft Corporation Module Name: dataconv.c Abstract: This source file implements data conversion routines that know the format of Windows 95 screen saver settings and can convert them to the Windows NT format. Author: Jim Schmidt (jimschm) 14-Apr-1997 Revision History: --*/ #include "pch.h" static CHAR g_Data[MAX_PATH]; BOOL pHasSpecialProcessing ( IN LPCSTR ScreenSaverName ); BOOL pTranslateBezier ( IN HKEY RegRoot ); BOOL pTranslateMarquee ( IN HKEY RegRoot ); HKEY pCreateControlPanelKey ( IN HKEY RootKey, IN LPCSTR SubKeyName, IN BOOL CreateEmptyKey ) { CHAR FullRegKey[MAX_PATH]; wsprintf (FullRegKey, S_CONTROL_PANEL_MASK, SubKeyName); if (CreateEmptyKey) { RegDeleteKey (RootKey, FullRegKey); } return CreateRegKey (RootKey, FullRegKey); } HKEY pCreateScreenSaverKey ( IN HKEY RegRoot, IN LPCSTR ScreenSaverName ) { CHAR FullScreenSaverName[MAX_PATH]; wsprintf (FullScreenSaverName, S_SCRNSAVE_MASK, ScreenSaverName); return pCreateControlPanelKey (RegRoot, FullScreenSaverName, FALSE); } BOOL pCopyValuesFromSettingsFileToRegistry ( IN HKEY RegKeyRoot, IN LPCSTR RegKeyName, IN LPCSTR ScreenSaverName, IN LPCSTR ValueArray[] ) { INT i; CHAR IniKeyName[MAX_PATH]; HKEY RegKey; BOOL b = TRUE; // // This function takes the values stored in our settings file and // copies them to a brand new key in the NT registry. // // In the settings file, we store screen saver parameters in the // format of //=. // // // Create new registry key // RegKey = pCreateControlPanelKey (RegKeyRoot, RegKeyName, TRUE); if (!RegKey) { return FALSE; } // // Copy values to reg key // for (i = 0 ; ValueArray[i] ; i++) { if (!CreateScreenSaverParamKey (ScreenSaverName, ValueArray[i], IniKeyName)) { // fail if screen saver name is huge for some unknown reason LOG ((LOG_WARNING, MSG_HUGEDATA_ERROR)); b = FALSE; break; } GetSettingsFileVal (IniKeyName); if (!SetRegValueString (RegKey, ValueArray[i], g_Data)) { b = FALSE; break; } } CloseRegKey (RegKey); return b; } BOOL TranslateGeneralSetting ( IN HKEY RegKey, IN LPCSTR Win9xSetting, IN LPCSTR WinNTSetting ) { BOOL b = TRUE; if (!WinNTSetting) { WinNTSetting = Win9xSetting; } else { // // Delete the Win9x setting that was copied to NT, ignore // any failures. // RegDeleteValue (RegKey, Win9xSetting); } // // Obtain setting from data file // if (GetSettingsFileVal (Win9xSetting)) { // // Save settings to registry // b = SetRegValueString (RegKey, WinNTSetting, g_Data); } return b; } typedef struct { LPCSTR Win9xName; LPCSTR WinNtName; } FILE_TRANS, *PFILE_TRANS; FILE_TRANS g_FileNameTranslation[] = { // Win9x name // WinNT name (NULL=no change) "black16.scr", NULL, "Blank Screen.scr", "black16.scr", "ssbezier.scr", NULL, "Curves and Colors.scr", "ssbezier.scr", "ssstars.scr", NULL, "Flying Through Space.scr", "ssstars.scr", "ssmarque.scr", NULL, "Scrolling Marquee.scr", "ssmarque.scr", "ssmyst.scr", NULL, "Mystify Your Mind.scr", "ssmyst.scr", NULL, NULL }; LPCSTR GetSettingsFileVal ( IN LPCSTR Key ) { GetPrivateProfileString ( g_User, Key, S_EMPTY, g_Data, MAX_PATH, g_SettingsFile ); return g_Data[0] ? g_Data : NULL; } BOOL pTranslateScrName ( IN OUT LPSTR KeyName, OUT LPSTR FullPath OPTIONAL ) { int i; // // Compare against translation list // for (i = 0 ; g_FileNameTranslation[i].Win9xName ; i++) { if (!_mbsicmp (KeyName, g_FileNameTranslation[i].Win9xName)) { break; } } // // Translate filename only if a match was found in our list // if (g_FileNameTranslation[i].Win9xName) { // // If WinNtName is NULL, there is no renaming necessary. Otherwise, // use the NT name, which is always a file in system32. // if (g_FileNameTranslation[i].WinNtName && FullPath) { // Rebuild path GetSystemDirectory (FullPath, MAX_PATH); _mbscat (FullPath, "\\"); _mbscat (FullPath, g_FileNameTranslation[i].WinNtName); } _mbscpy (KeyName, g_FileNameTranslation[i].WinNtName); } else if (FullPath) { FullPath[0] = 0; } return TRUE; } BOOL SaveScrName ( IN HKEY RegKey, IN LPCSTR KeyName ) { LPSTR p; CHAR FullPath[MAX_PATH]; CHAR ShortName[MAX_PATH]; // // The Windows 95 screen saver names are different than // Windows NT. // if (!GetSettingsFileVal (KeyName)) { // Unexpected: .SCR name does not exist in our file return TRUE; } // // Locate the screen saver name within the full path // p = _mbsrchr (g_Data, '\\'); if (!p) { p = g_Data; } else { p = _mbsinc (p); } // // Translate it if necessary // if (!pTranslateScrName (p, FullPath)) { return FALSE; } if (!FullPath[0]) { // // No change was made, so copy original path to FullPath // _mbscpy (FullPath, g_Data); } // // Screen savers are always stored in short filename format // GetShortPathName (FullPath, ShortName, MAX_PATH); return SetRegValueString (RegKey, KeyName, ShortName); } INT GetHexDigit ( IN CHAR c ) { if (c >= '0' && c <= '9') { return c - '0'; } c = tolower (c); if (c >= 'a' && c <= 'f') { return c - 'a' + 10; } return -1; } BYTE GetNextHexByte ( IN LPCSTR HexString, OUT LPCSTR *HexStringReturn ) { INT a, b; a = GetHexDigit (HexString[0]); b = GetHexDigit (HexString[1]); if (a == -1 || b == -1) { *HexStringReturn = NULL; return 0; } *HexStringReturn = &(HexString[2]); return a * 16 + b; } BOOL GetNextDword ( IN LPCSTR HexString, OUT LPCSTR *HexStringReturn, OUT PDWORD ValuePtr ) { INT i; BYTE NextByte; *ValuePtr = 0; for (i = 0 ; i < 4 ; i++) { NextByte = GetNextHexByte (HexString, &HexString); if (!HexString) { return FALSE; } *ValuePtr = ((*ValuePtr) << 8) | NextByte; } return TRUE; } BOOL VerifyBezierChecksum ( IN LPCSTR HexString ) { BYTE Checksum = 0; INT Len; Len = _mbslen (HexString); Len -= 2; if (Len < 1) { return FALSE; } while (Len > 0) { Checksum += GetNextHexByte (HexString, &HexString); if (!HexString) { return FALSE; } } if (Checksum != GetNextHexByte (HexString, &HexString)) { return FALSE; } return TRUE; } BOOL CopyUntranslatedSettings ( IN HKEY RegRoot ) { LPSTR KeyBuffer; DWORD KeyBufferSize; LPSTR p; CHAR ScreenSaverName[MAX_PATH]; CHAR ValueName[MAX_PATH]; HKEY Key; // // Enumerate each entry in our private settings file for the user // KeyBufferSize = 32768; KeyBuffer = (LPSTR) HeapAlloc (g_hHeap, 0, KeyBufferSize); if (!KeyBuffer) { return FALSE; } // // Get all keys in the user's section // GetPrivateProfileString ( g_User, NULL, S_DOUBLE_EMPTY, KeyBuffer, KeyBufferSize, g_SettingsFile ); for (p = KeyBuffer ; *p ; p = _mbschr (p, 0) + 1) { // // Process only if key is encoded // if (!DecodeScreenSaverParamKey (p, ScreenSaverName, ValueName)) { continue; } // // Key is encoded, so perform migration! // pTranslateScrName (ScreenSaverName, NULL); // // Skip screen savers that have special processing // if (pHasSpecialProcessing (ScreenSaverName)) { continue; } // // Save the value to the registry // GetSettingsFileVal (p); Key = pCreateScreenSaverKey (RegRoot, ScreenSaverName); if (Key) { if (SetRegValueString (Key, ValueName, g_Data)) { CHAR DebugMsg[MAX_PATH*2]; wsprintf (DebugMsg, "Saved %s=%s\r\n", ValueName, g_Data); SetupLogError (DebugMsg, LogSevInformation); } else { CHAR DebugMsg[MAX_PATH*2]; wsprintf (DebugMsg, "Could not save %s=%s\r\n", ValueName, g_Data); SetupLogError (DebugMsg, LogSevError); } CloseRegKey (Key); } } HeapFree (g_hHeap, 0, KeyBuffer); return TRUE; } BOOL pHasSpecialProcessing ( IN LPCSTR ScreenSaverName ) { // // Return TRUE if we are doing something special for the // named screen saver. // if (!_mbsicmp (ScreenSaverName, S_BEZIER) || !_mbsicmp (ScreenSaverName, S_MARQUEE) ) { return TRUE; } return FALSE; } BOOL TranslateScreenSavers ( IN HKEY RegRoot ) { BOOL b = TRUE; b &= pTranslateBezier (RegRoot); b &= pTranslateMarquee (RegRoot); return b; } BOOL pTranslateBezier ( IN HKEY RegRoot ) { DWORD Value; CHAR StrValue[32]; LPCSTR p; HKEY RegKey; BOOL b; // // NT's Bezier has three settings: // // Length (REG_SZ) = Curve Count on Win9x // LineSpeed (REG_SZ) = Speed on Win9x // Width (REG_SZ) = Density on Win9x // // Win9x's Bezier has a big string of hex in the following format: // // Clear Screen Flag (DWORD) // Random Colors Flag (DWORD) // Curve Count (DWORD) // Line Count (DWORD) // Density (DWORD) // Speed (DWORD) // Current Color (DWORD RGB) // Checksum (BYTE) // // // Verify structure // GetSettingsFileVal (S_BEZIER_SETTINGS); if (!VerifyBezierChecksum (g_Data)) { return TRUE; } // // Open reg key // RegKey = pCreateControlPanelKey (RegRoot, S_BEZIER_SETTINGS, TRUE); if (!RegKey) { return FALSE; } p = g_Data; // Get clear screen flag (but ignore it) b = GetNextDword (p, &p, &Value); // Get random colors flag (but ignore it) if (b) { b = GetNextDword (p, &p, &Value); } // // Get curve count // if (b) { b = GetNextDword (p, &p, &Value); } if (b) { wsprintf (StrValue, "%u", Value); b = SetRegValueString (RegKey, S_LENGTH, StrValue); } // Get line count (but ignore it) if (b) { b = GetNextDword (p, &p, &Value); } // // Get density // if (b) { b = GetNextDword (p, &p, &Value); } if (b) { wsprintf (StrValue, "%u", Value); b = SetRegValueString (RegKey, S_WIDTH, StrValue); } // // Get speed // if (b) { b = GetNextDword (p, &p, &Value); } if (b) { wsprintf (StrValue, "%u", Value); b = SetRegValueString (RegKey, S_LINESPEED, StrValue); } CloseRegKey (RegKey); if (!b) { LOG ((LOG_ERROR, MSG_BEZIER_DATA_ERROR)); } return TRUE; } LPCSTR g_MarqueeValues[] = { S_BACKGROUND_COLOR, S_CHARSET, S_FONT, S_MODE, S_SIZE, S_SPEED, S_TEXT, S_TEXTCOLOR, NULL }; BOOL pTranslateMarquee ( IN HKEY RegRoot ) { BOOL b; // // Marquee has the same settings on Win9x and NT. They just need // to be copied from the control.ini file to the NT registry. // b = pCopyValuesFromSettingsFileToRegistry ( RegRoot, S_MARQUEE_SETTINGS, S_MARQUEE, g_MarqueeValues ); // // We need to divide the speed by two to be compatible // if (b) { HKEY MarqueeKey; LPCSTR Value; CHAR NewValue[32]; // Read the setting we just wrote in the registry MarqueeKey = pCreateControlPanelKey (RegRoot, S_MARQUEE_SETTINGS, FALSE); if (MarqueeKey) { Value = GetRegValueString (MarqueeKey, S_SPEED); if (Value) { // Write speed divided by two wsprintf (NewValue, "%i", atoi (Value) / 2); SetRegValueString (MarqueeKey, S_SPEED, NewValue); } CloseRegKey (MarqueeKey); } } return b; }