DATACONV.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:14k
源码类别:

Windows编程

开发平台:

Visual C++

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4.     dataconv.c
  5. Abstract:
  6.     This source file implements data conversion routines that know
  7.     the format of Windows 95 screen saver settings and can convert
  8.     them to the Windows NT format.
  9. Author:
  10.     Jim Schmidt (jimschm) 14-Apr-1997
  11. Revision History:
  12. --*/
  13. #include "pch.h"
  14. static CHAR g_Data[MAX_PATH];
  15. BOOL
  16. pHasSpecialProcessing (
  17.     IN      LPCSTR ScreenSaverName
  18.     );
  19. BOOL
  20. pTranslateBezier (
  21.     IN      HKEY RegRoot
  22.     );
  23. BOOL
  24. pTranslateMarquee (
  25.     IN      HKEY RegRoot
  26.     );
  27. HKEY
  28. pCreateControlPanelKey (
  29.     IN      HKEY RootKey,
  30.     IN      LPCSTR SubKeyName,
  31.     IN      BOOL CreateEmptyKey
  32.     )
  33. {
  34.     CHAR FullRegKey[MAX_PATH];
  35.     wsprintf (FullRegKey, S_CONTROL_PANEL_MASK, SubKeyName);
  36.     if (CreateEmptyKey) {
  37.         RegDeleteKey (RootKey, FullRegKey);
  38.     }
  39.     return CreateRegKey (RootKey, FullRegKey);
  40. }
  41. HKEY
  42. pCreateScreenSaverKey (
  43.     IN      HKEY RegRoot, 
  44.     IN      LPCSTR ScreenSaverName
  45.     )
  46. {
  47.     CHAR FullScreenSaverName[MAX_PATH];
  48.     wsprintf (FullScreenSaverName, S_SCRNSAVE_MASK, ScreenSaverName);
  49.     return pCreateControlPanelKey (RegRoot, FullScreenSaverName, FALSE);
  50. }
  51. BOOL
  52. pCopyValuesFromSettingsFileToRegistry (
  53.     IN      HKEY RegKeyRoot,
  54.     IN      LPCSTR RegKeyName,
  55.     IN      LPCSTR ScreenSaverName,
  56.     IN      LPCSTR ValueArray[]
  57.     )
  58. {
  59.     INT i;
  60.     CHAR IniKeyName[MAX_PATH];
  61.     HKEY RegKey;
  62.     BOOL b = TRUE;
  63.     //
  64.     // This function takes the values stored in our settings file and
  65.     // copies them to a brand new key in the NT registry.
  66.     //
  67.     // In the settings file, we store screen saver parameters in the
  68.     // format of <screen saver name len>/<screen saver name>/<parameter>=<value>.
  69.     //
  70.     //
  71.     // Create new registry key
  72.     //
  73.     RegKey = pCreateControlPanelKey (RegKeyRoot, RegKeyName, TRUE);
  74.     if (!RegKey) {
  75.         return FALSE;
  76.     }
  77.     //
  78.     // Copy values to reg key
  79.     //
  80.     for (i = 0 ; ValueArray[i] ; i++) {
  81.         if (!CreateScreenSaverParamKey (ScreenSaverName, ValueArray[i], IniKeyName)) {
  82.             // fail if screen saver name is huge for some unknown reason
  83.             SetupLogError (S_HUGEDATA_ERROR, LogSevWarning);
  84.             b = FALSE;
  85.             break;
  86.         }
  87.         GetSettingsFileVal (IniKeyName);
  88.         if (!SetRegValueString (RegKey, ValueArray[i], g_Data)) {
  89.             b = FALSE;
  90.             break;
  91.         }
  92.     }
  93.     CloseRegKey (RegKey);
  94.     return b;
  95. }
  96. BOOL
  97. TranslateGeneralSetting (
  98.     IN      HKEY RegKey,
  99.     IN      LPCSTR Win9xSetting,
  100.     IN      LPCSTR WinNTSetting
  101.     )
  102. {
  103.     BOOL b = TRUE;
  104.     if (!WinNTSetting) {
  105.         WinNTSetting = Win9xSetting;
  106.     } else {
  107.         //
  108.         // Delete the Win9x setting that was copied to NT, ignore
  109.         // any failures.
  110.         //
  111.         RegDeleteValue (RegKey, Win9xSetting);
  112.     }
  113.     //
  114.     // Obtain setting from data file
  115.     //
  116.     if (GetSettingsFileVal (Win9xSetting)) {
  117.         //
  118.         // Save settings to registry
  119.         //
  120.         b = SetRegValueString (RegKey, WinNTSetting, g_Data);
  121.     }
  122.     return b;
  123. }
  124. typedef struct {
  125.     LPCSTR Win9xName;
  126.     LPCSTR WinNtName;
  127. } FILE_TRANS, *PFILE_TRANS;
  128. FILE_TRANS g_FileNameTranslation[] = {
  129.     // Win9x name                   // WinNT name (NULL=no change)
  130.     "black16.scr",                  NULL,
  131.     "Blank Screen.scr",             "black16.scr",
  132.     "ssbezier.scr",                 NULL,
  133.     "Curves and Colors.scr",        "ssbezier.scr",
  134.     "ssstars.scr",                  NULL,
  135.     "Flying Through Space.scr",     "ssstars.scr",
  136.     "ssmarque.scr",                 NULL,
  137.     "Scrolling Marquee.scr",        "ssmarque.scr",
  138.     "ssmyst.scr",                   NULL,
  139.     "Mystify Your Mind.scr",        "ssmyst.scr",
  140.     NULL, NULL
  141. };
  142. LPCSTR
  143. GetSettingsFileVal (
  144.     IN      LPCSTR Key
  145.     )
  146. {
  147.     GetPrivateProfileString (
  148.         g_User, 
  149.         Key, 
  150.         S_EMPTY, 
  151.         g_Data, 
  152.         MAX_PATH, 
  153.         g_SettingsFile
  154.         );
  155.     return g_Data[0] ? g_Data : NULL;
  156. }
  157. BOOL
  158. pTranslateScrName (
  159.     IN OUT  LPSTR KeyName,
  160.     OUT     LPSTR FullPath      OPTIONAL
  161.     )
  162. {
  163.     int i;
  164.     //
  165.     // Compare against translation list
  166.     //
  167.     for (i = 0 ; g_FileNameTranslation[i].Win9xName ; i++) {
  168.         if (!_mbsicmp (KeyName, g_FileNameTranslation[i].Win9xName)) {
  169.             break;
  170.         }
  171.     }
  172.     //
  173.     // Translate filename only if a match was found in our list
  174.     //
  175.     if (g_FileNameTranslation[i].Win9xName) {
  176.         //
  177.         // If WinNtName is NULL, there is no renaming necessary.  Otherwise,
  178.         // use the NT name, which is always a file in system32.
  179.         //
  180.         if (g_FileNameTranslation[i].WinNtName && FullPath) {
  181.             // Rebuild path
  182.             GetSystemDirectory (FullPath, MAX_PATH);
  183.             _mbscat (FullPath, "\");
  184.             _mbscat (FullPath, g_FileNameTranslation[i].WinNtName);
  185.         }
  186.         _mbscpy (KeyName, g_FileNameTranslation[i].WinNtName);
  187.     }
  188.     else if (FullPath) {
  189.         FullPath[0] = 0;
  190.     }
  191.     return TRUE;
  192. }
  193. BOOL
  194. SaveScrName (
  195.     IN      HKEY RegKey, 
  196.     IN      LPCSTR KeyName
  197.     )
  198. {
  199.     LPSTR p;
  200.     CHAR FullPath[MAX_PATH];
  201.     CHAR ShortName[MAX_PATH];
  202.     //
  203.     // The Windows 95 screen saver names are different than
  204.     // Windows NT.
  205.     //
  206.     if (!GetSettingsFileVal (KeyName)) {
  207.         // Unexpected: .SCR name does not exist in our file
  208.         return TRUE;
  209.     }
  210.     //
  211.     // Locate the screen saver name within the full path
  212.     //
  213.     p = _mbsrchr (g_Data, '\');
  214.     if (!p) {
  215.         p = g_Data;
  216.     } else {
  217.         p = _mbsinc (p);
  218.     }
  219.     //
  220.     // Translate it if necessary
  221.     //
  222.     if (!pTranslateScrName (p, FullPath)) {
  223.         return FALSE;
  224.     }
  225.     if (!FullPath[0]) {
  226.         //
  227.         // No change was made, so copy original path to FullPath
  228.         //
  229.         
  230.         _mbscpy (FullPath, g_Data);
  231.     }
  232.     //
  233.     // Screen savers are always stored in short filename format
  234.     //
  235.     GetShortPathName (FullPath, ShortName, MAX_PATH);
  236.     return SetRegValueString (RegKey, KeyName, ShortName);
  237. }
  238. INT
  239. GetHexDigit (
  240.     IN      CHAR c
  241.     )
  242. {
  243.     if (c >= '0' && c <= '9') {
  244.         return c - '0';
  245.     }
  246.     c = tolower (c);
  247.     if (c >= 'a' && c <= 'f') {
  248.         return c - 'a' + 10;
  249.     }
  250.     return -1;
  251. }
  252. BYTE
  253. GetNextHexByte (
  254.     IN      LPCSTR HexString,
  255.     OUT     LPCSTR *HexStringReturn
  256.     )
  257. {
  258.     INT a, b;
  259.     a = GetHexDigit (HexString[0]);
  260.     b = GetHexDigit (HexString[1]);
  261.     if (a == -1 || b == -1) {
  262.         *HexStringReturn = NULL;
  263.         return 0;
  264.     }
  265.     *HexStringReturn = &(HexString[2]);
  266.     return a * 16 + b;
  267. }
  268. BOOL
  269. GetNextDword (
  270.     IN      LPCSTR HexString,
  271.     OUT     LPCSTR *HexStringReturn,
  272.     OUT     PDWORD ValuePtr
  273.     )
  274. {
  275.     INT i;
  276.     BYTE NextByte;
  277.     *ValuePtr = 0;
  278.     for (i = 0 ; i < 4 ; i++) {
  279.         NextByte = GetNextHexByte (HexString, &HexString);
  280.         if (!HexString) {
  281.             return FALSE;
  282.         }
  283.         *ValuePtr = ((*ValuePtr) << 8) | NextByte;
  284.     }
  285.     return TRUE;
  286. }
  287. BOOL
  288. VerifyBezierChecksum (
  289.     IN      LPCSTR HexString
  290.     )
  291. {
  292.     BYTE Checksum = 0;
  293.     INT Len;
  294.     Len = _mbslen (HexString);
  295.     Len -= 2;
  296.     if (Len < 1) {
  297.         return FALSE;
  298.     }
  299.     while (Len > 0) {
  300.         Checksum += GetNextHexByte (HexString, &HexString);
  301.         if (!HexString) {
  302.             return FALSE;
  303.         }
  304.     }
  305.     if (Checksum != GetNextHexByte (HexString, &HexString)) {
  306.         return FALSE;
  307.     }
  308.     return TRUE;
  309. }
  310. BOOL
  311. CopyUntranslatedSettings (
  312.     IN      HKEY RegRoot
  313.     )
  314. {
  315.     LPSTR KeyBuffer;
  316.     DWORD KeyBufferSize;
  317.     LPSTR p;
  318.     CHAR ScreenSaverName[MAX_PATH];
  319.     CHAR ValueName[MAX_PATH];
  320.     HKEY Key;
  321.     //
  322.     // Enumerate each entry in our private settings file for the user
  323.     //
  324.     KeyBufferSize = 32768;
  325.     KeyBuffer = (LPSTR) HeapAlloc (g_hHeap, 0, KeyBufferSize);
  326.     if (!KeyBuffer) {
  327.         return FALSE;
  328.     }
  329.     //
  330.     // Get all keys in the user's section
  331.     //
  332.     GetPrivateProfileString (
  333.         g_User,
  334.         NULL,
  335.         S_DOUBLE_EMPTY,
  336.         KeyBuffer,
  337.         KeyBufferSize,
  338.         g_SettingsFile
  339.         );
  340.     for (p = KeyBuffer ; *p ; p = _mbschr (p, 0) + 1) {
  341.         //
  342.         // Process only if key is encoded
  343.         //
  344.         if (!DecodeScreenSaverParamKey (p, ScreenSaverName, ValueName)) {
  345.             continue;
  346.         }
  347.         //
  348.         // Key is encoded, so perform migration!
  349.         //
  350.         pTranslateScrName (ScreenSaverName, NULL);
  351.         //
  352.         // Skip screen savers that have special processing
  353.         //
  354.         if (pHasSpecialProcessing (ScreenSaverName)) {
  355.             continue;
  356.         }
  357.         //
  358.         // Save the value to the registry
  359.         //
  360.         GetSettingsFileVal (p);
  361.         Key = pCreateScreenSaverKey (RegRoot, ScreenSaverName);
  362.         if (Key) {
  363.             if (SetRegValueString (Key, ValueName, g_Data))
  364.             {
  365.                 CHAR DebugMsg[MAX_PATH*2];
  366.                 wsprintf (DebugMsg, "Saved %s=%srn", ValueName, g_Data);
  367.                 SetupLogError (DebugMsg, LogSevInformation);
  368.             } else {
  369.                 CHAR DebugMsg[MAX_PATH*2];
  370.                 wsprintf (DebugMsg, "Could not save %s=%srn", ValueName, g_Data);
  371.                 SetupLogError (DebugMsg, LogSevError);
  372.             }
  373.             CloseRegKey (Key);
  374.         }
  375.     }
  376.     HeapFree (g_hHeap, 0, KeyBuffer);
  377.     return TRUE;
  378. }
  379. BOOL
  380. pHasSpecialProcessing (
  381.     IN      LPCSTR ScreenSaverName
  382.     )
  383. {
  384.     //
  385.     // Return TRUE if we are doing something special for the
  386.     // named screen saver.
  387.     //
  388.     if (!_mbsicmp (ScreenSaverName, S_BEZIER) ||
  389.         !_mbsicmp (ScreenSaverName, S_MARQUEE)
  390.         ) {
  391.         return TRUE;
  392.     }
  393.     return FALSE;
  394. }
  395. BOOL
  396. TranslateScreenSavers (
  397.     IN      HKEY RegRoot
  398.     )
  399. {
  400.     BOOL b = TRUE;
  401.     b &= pTranslateBezier (RegRoot);
  402.     b &= pTranslateMarquee (RegRoot);
  403.     return b;
  404. }
  405. BOOL
  406. pTranslateBezier (
  407.     IN      HKEY RegRoot
  408.     )
  409. {
  410.     DWORD Value;
  411.     CHAR StrValue[32];
  412.     LPCSTR p;
  413.     HKEY RegKey;
  414.     BOOL b;
  415.     //
  416.     // NT's Bezier has three settings:
  417.     //
  418.     // Length (REG_SZ)      = Curve Count on Win9x
  419.     // LineSpeed (REG_SZ)   = Speed on Win9x
  420.     // Width (REG_SZ)       = Density on Win9x
  421.     //
  422.     // Win9x's Bezier has a big string of hex in the following format:
  423.     // 
  424.     // Clear Screen Flag (DWORD)
  425.     // Random Colors Flag (DWORD)
  426.     // Curve Count (DWORD)
  427.     // Line Count (DWORD)
  428.     // Density (DWORD)
  429.     // Speed (DWORD)
  430.     // Current Color (DWORD RGB)
  431.     // Checksum (BYTE)
  432.     //
  433.     //
  434.     // Verify structure
  435.     //
  436.     GetSettingsFileVal (S_BEZIER_SETTINGS);
  437.     if (!VerifyBezierChecksum (g_Data)) {
  438.         return TRUE;
  439.     }
  440.     //
  441.     // Open reg key
  442.     //
  443.     RegKey = pCreateControlPanelKey (RegRoot, S_BEZIER_SETTINGS, TRUE);
  444.     if (!RegKey) {
  445.         return FALSE;
  446.     }
  447.     p = g_Data;
  448.     // Get clear screen flag (but ignore it)
  449.     b = GetNextDword (p, &p, &Value);
  450.     // Get random colors flag (but ignore it)
  451.     if (b) {
  452.         b = GetNextDword (p, &p, &Value);
  453.     }
  454.     //
  455.     // Get curve count
  456.     //
  457.     if (b) {
  458.         b = GetNextDword (p, &p, &Value);
  459.     }
  460.     if (b) {
  461.         wsprintf (StrValue, "%u", Value);
  462.         b = SetRegValueString (RegKey, S_LENGTH, StrValue);
  463.     }
  464.     // Get line count (but ignore it)
  465.     if (b) {
  466.         b = GetNextDword (p, &p, &Value);
  467.     }
  468.     //
  469.     // Get density
  470.     //
  471.     if (b) {
  472.         b = GetNextDword (p, &p, &Value);
  473.     }
  474.     if (b) {
  475.         wsprintf (StrValue, "%u", Value);
  476.         b = SetRegValueString (RegKey, S_WIDTH, StrValue);
  477.     }
  478.     //
  479.     // Get speed
  480.     //
  481.     if (b) {
  482.         b = GetNextDword (p, &p, &Value);
  483.     }
  484.     if (b) {
  485.         wsprintf (StrValue, "%u", Value);
  486.         b = SetRegValueString (RegKey, S_LINESPEED, StrValue);
  487.     }
  488.     CloseRegKey (RegKey);
  489.     if (!b) {
  490.         SetupLogError (S_BEZIER_DATA_ERROR, LogSevError);
  491.     }
  492.     return TRUE;
  493. }
  494. LPCSTR g_MarqueeValues[] = {
  495.     S_BACKGROUND_COLOR,
  496.     S_CHARSET,
  497.     S_FONT,
  498.     S_MODE,
  499.     S_SIZE,
  500.     S_SPEED,
  501.     S_TEXT,
  502.     S_TEXTCOLOR,
  503.     NULL
  504. };
  505. BOOL
  506. pTranslateMarquee (
  507.     IN      HKEY RegRoot
  508.     )
  509. {
  510.     BOOL b;
  511.     //
  512.     // Marquee has the same settings on Win9x and NT.  They just need
  513.     // to be copied from the control.ini file to the NT registry.
  514.     //
  515.     b = pCopyValuesFromSettingsFileToRegistry (
  516.                 RegRoot,
  517.                 S_MARQUEE_SETTINGS, 
  518.                 S_MARQUEE,
  519.                 g_MarqueeValues
  520.                 );
  521.     //
  522.     // We need to divide the speed by two to be compatible
  523.     //
  524.     if (b) {
  525.         HKEY MarqueeKey;
  526.         LPCSTR Value;
  527.         CHAR NewValue[32];
  528.         // Read the setting we just wrote in the registry
  529.         MarqueeKey = pCreateControlPanelKey (RegRoot, S_MARQUEE_SETTINGS, FALSE);
  530.         if (MarqueeKey) {
  531.             Value = GetRegValueString (MarqueeKey, S_SPEED);
  532.             if (Value) {
  533.                 // Write speed divided by two
  534.                 wsprintf (NewValue, "%i", atoi (Value) / 2);
  535.                 SetRegValueString (MarqueeKey, S_SPEED, NewValue);
  536.             }
  537.             CloseRegKey (MarqueeKey);
  538.         }
  539.     }
  540.     return b;
  541. }