home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / sysmgmt / setup / win9xmig / scrnsave / dataconv.c next >
Encoding:
C/C++ Source or Header  |  1997-08-13  |  13.7 KB  |  700 lines

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