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 / utils.c < prev   
Encoding:
C/C++ Source or Header  |  1997-08-13  |  12.7 KB  |  671 lines

  1. /*++
  2.  
  3. Copyright (c) 1997 Microsoft Corporation
  4.  
  5. Module Name:
  6.  
  7.     utils.c
  8.  
  9. Abstract:
  10.  
  11.     This source file implements utility functions used by scrnsave.c.
  12.  
  13. Author:
  14.  
  15.     Jim Schmidt (jimschm) 11-Apr-1997
  16.  
  17. Revision History:
  18.  
  19.  
  20. --*/
  21.  
  22. #include "pch.h"
  23.  
  24. #ifdef UNICODE
  25. #error UNICODE cannot be defined
  26. #endif
  27.  
  28. //
  29. // Declare strings
  30. //
  31.  
  32. #define DEFMAC(var,str) CHAR var[] = str;
  33. DEFINE_STRINGS
  34. #undef DEFMAC
  35.  
  36. //
  37. // Temporary buffer
  38. //
  39.  
  40. static CHAR g_Data[MAX_PATH];
  41.  
  42. //
  43. // Buffer for string representation of registry keys (for error logging)
  44. //
  45.  
  46. typedef struct _tagKEYTOSTR {
  47.     struct _tagKEYTOSTR *Prev, *Next;
  48.     HKEY Key;
  49.     CHAR RegKey[];
  50. } KEYTOSTR, *PKEYTOSTR;
  51.  
  52. static PKEYTOSTR g_Head = NULL;
  53.  
  54. VOID
  55. pAddKeyToStrMapping (
  56.     IN      HKEY Key,
  57.     IN      LPCSTR RootStr,
  58.     IN      LPCSTR KeyStr
  59.     )
  60. {
  61.     PKEYTOSTR Node;
  62.     DWORD Size;
  63.     CHAR FullKeyStr[MAX_PATH];
  64.  
  65.     // We control RootStr and KeyStr, so we know it is less than MAX_PATH in length
  66.     wsprintf (FullKeyStr, "%s\\%s", RootStr, KeyStr);
  67.  
  68.     Size = sizeof (KEYTOSTR) + CountStringBytes (FullKeyStr);
  69.  
  70.     Node = (PKEYTOSTR) HeapAlloc (g_hHeap, 0, Size);
  71.     if (Node) {
  72.         Node->Prev = NULL;
  73.         Node->Next = g_Head;
  74.         Node->Key = Key;
  75.         _mbscpy (Node->RegKey, FullKeyStr);
  76.  
  77.         if (g_Head) {
  78.             g_Head->Prev = Node;
  79.         }
  80.         g_Head = Node;
  81.     }
  82. }
  83.  
  84. PKEYTOSTR
  85. pFindKeyToStrMapping (
  86.     IN      HKEY Key
  87.     )
  88. {
  89.     PKEYTOSTR Node;
  90.  
  91.     Node = g_Head;
  92.     while (Node) {
  93.         if (Node->Key == Key) {
  94.             return Node;
  95.         }
  96.         Node = Node->Next;
  97.     }
  98.  
  99.     return NULL;
  100. }
  101.  
  102. VOID
  103. pRemoveKeyToStrMapping (
  104.     IN      HKEY Key
  105.     )
  106. {
  107.     PKEYTOSTR Node;
  108.  
  109.     Node = pFindKeyToStrMapping (Key);
  110.     if (!Node) {
  111.         return;
  112.     }
  113.  
  114.     if (Node->Prev) {
  115.         Node->Prev->Next = Node->Next;
  116.     } else {
  117.         g_Head = Node->Next;
  118.     }
  119.  
  120.     if (Node->Next) {
  121.         Node->Next->Prev = Node->Prev;
  122.     }
  123.  
  124.     HeapFree (g_hHeap, 0, Node);
  125. }
  126.     
  127.  
  128. VOID
  129. LogRegistryError (
  130.     IN      HKEY Key,
  131.     IN      LPCSTR ValueName
  132.     )
  133. {
  134.     DWORD rc = GetLastError();
  135.     CHAR Msg[512];
  136.     LPCSTR FullKeyStr;
  137.     PKEYTOSTR Node;
  138.  
  139.     Node = pFindKeyToStrMapping (Key);
  140.     if (Node) {
  141.         FullKeyStr = Node->RegKey;
  142.     } else {
  143.         FullKeyStr = S_DEFAULT_KEYSTR;
  144.     }
  145.  
  146.     wsprintf (Msg, S_REGISTRY_ERROR, g_User, rc, FullKeyStr, ValueName);
  147.     SetupLogError (Msg, LogSevError);
  148. }
  149.  
  150.  
  151. VOID
  152. GenerateFilePaths (
  153.     VOID
  154.     )
  155. {
  156.     INT Len;
  157.  
  158.     // Safety (unexpected condition)
  159.     if (!g_WorkingDirectory) {
  160.         return;
  161.     }
  162.  
  163.     Len = CountStringBytes (g_WorkingDirectory) + sizeof(S_SETTINGS_MASK);
  164.     g_SettingsFile = (LPSTR) HeapAlloc (g_hHeap, 0, Len);
  165.     if (!g_SettingsFile) {
  166.         return;
  167.     }
  168.     wsprintf (g_SettingsFile, S_SETTINGS_MASK, g_WorkingDirectory);
  169.  
  170.     Len = CountStringBytes (g_WorkingDirectory) + sizeof(S_MIGINF_MASK);
  171.     g_MigrateDotInf = (LPSTR) HeapAlloc (g_hHeap, 0, Len);
  172.     if (!g_MigrateDotInf) {
  173.         return;
  174.     }
  175.     wsprintf (g_MigrateDotInf, S_MIGINF_MASK, g_WorkingDirectory);
  176. }
  177.  
  178.  
  179. HKEY
  180. OpenRegKey (
  181.     IN      HKEY RootKey,
  182.     IN      LPCSTR KeyStr
  183.     )
  184. {
  185.     HKEY Key;
  186.     LONG rc;
  187.  
  188.     rc = RegOpenKeyEx (RootKey, KeyStr, 0, KEY_ALL_ACCESS, &Key);
  189.     if (rc != ERROR_SUCCESS) {
  190.         SetLastError (rc);
  191.         return NULL;
  192.     }
  193.  
  194.     pAddKeyToStrMapping (Key, S_HKR, KeyStr);
  195.  
  196.     return Key;
  197. }
  198.  
  199.  
  200. HKEY
  201. CreateRegKey (
  202.     IN      HKEY RootKey,
  203.     IN      LPCSTR KeyStr
  204.     )
  205. {
  206.     HKEY Key;
  207.     LONG rc;
  208.     DWORD DontCare;
  209.  
  210.     pAddKeyToStrMapping (NULL, S_HKR, KeyStr);
  211.  
  212.     rc = RegCreateKeyEx (RootKey, KeyStr, 0, S_EMPTY, 0, 
  213.                          KEY_ALL_ACCESS, NULL, &Key, &DontCare);
  214.     if (rc != ERROR_SUCCESS) {
  215.         SetLastError (rc);
  216.         LogRegistryError (NULL, S_EMPTY);
  217.         pRemoveKeyToStrMapping (NULL);
  218.         return NULL;
  219.     }
  220.  
  221.     pRemoveKeyToStrMapping (NULL);
  222.     pAddKeyToStrMapping (Key, S_HKR, KeyStr);
  223.  
  224.     return Key;
  225. }
  226.  
  227. VOID
  228. CloseRegKey (
  229.     IN      HKEY Key
  230.     )
  231. {
  232.     pRemoveKeyToStrMapping (Key);
  233.     RegCloseKey (Key);
  234. }
  235.  
  236.  
  237. LPCSTR
  238. GetRegValueString (
  239.     IN      HKEY Key,
  240.     IN      LPCSTR ValueName
  241.     )
  242. {
  243.     static CHAR DataBuf[MAX_PATH];
  244.     DWORD Size;
  245.     LONG rc;
  246.     DWORD Type;
  247.     DWORD d;
  248.  
  249.     Size = MAX_PATH;
  250.     rc = RegQueryValueEx (Key, ValueName, NULL, &Type, DataBuf, &Size);
  251.     SetLastError (rc);
  252.  
  253.     if (rc != ERROR_SUCCESS) {
  254.         return NULL;
  255.     }
  256.  
  257.     if (Type == REG_DWORD) {
  258.         d = *((PDWORD) DataBuf);
  259.         wsprintf (DataBuf, "%u", d);
  260.     }
  261.     else if (Type != REG_SZ) {
  262.         return NULL;
  263.     }
  264.  
  265.     return DataBuf;
  266. }
  267.  
  268. BOOL
  269. SetRegValueString (
  270.     HKEY Key,
  271.     LPCSTR ValueName,
  272.     LPCSTR ValueStr
  273.     )
  274. {
  275.     LONG rc;
  276.     LPCSTR p;
  277.  
  278.     p = _mbschr (ValueStr, 0);
  279.     p++;
  280.  
  281.     rc = RegSetValueEx (Key, ValueName, 0, REG_SZ, ValueStr, p - ValueStr);
  282.     SetLastError (rc);
  283.  
  284.     if (rc != ERROR_SUCCESS) {
  285.         LogRegistryError (Key, ValueName);
  286.     }
  287.  
  288.     return rc == ERROR_SUCCESS;
  289. }
  290.  
  291.  
  292. LPCSTR
  293. GetScrnSaveExe (
  294.     VOID
  295.     )
  296. {
  297.     CHAR IniFileSetting[MAX_PATH];
  298.  
  299.     GetPrivateProfileString (
  300.             S_BOOT, 
  301.             S_SCRNSAVE_EXE, 
  302.             S_EMPTY, 
  303.             IniFileSetting, 
  304.             MAX_PATH, 
  305.             S_SYSTEM_INI
  306.             );
  307.  
  308.     if (!IniFileSetting[0]) {
  309.         return NULL;
  310.     }
  311.  
  312.     if (!OurGetLongPathName (IniFileSetting, g_Data)) {
  313.         // File does not exist
  314.         return NULL;
  315.     }
  316.  
  317.     return g_Data[0] ? g_Data : NULL;
  318. }
  319.  
  320. INT
  321. _mbsbytes (
  322.     IN      LPCSTR str
  323.     )
  324. {
  325.     LPCSTR p;
  326.  
  327.     // Find the nul terminator and return the number of bytes
  328.     // occupied by the characters in the string, but don't
  329.     // include the nul.
  330.  
  331.     p = _mbschr (str, 0);
  332.     return (p - str);
  333. }
  334.  
  335.  
  336. DWORD
  337. CountStringBytes (
  338.     IN      LPCSTR str
  339.     )
  340. {
  341.     // Return bytes in string, plus 1 for the nul
  342.     return _mbsbytes (str) + 1;
  343. }
  344.  
  345. DWORD
  346. CountMultiStringBytes (
  347.     IN      LPCSTR str
  348.     )
  349. {
  350.     LPCSTR p;
  351.     INT Total = 0;
  352.     INT Bytes;
  353.  
  354.     p = str;
  355.  
  356.     do {
  357.         Bytes = CountStringBytes (p);
  358.         p += Bytes;
  359.         Total += Bytes;
  360.     } while (Bytes > 1);
  361.  
  362.     return Total;
  363. }
  364.  
  365.  
  366. LPSTR
  367. CopyStringAtoB (
  368.     OUT     LPSTR mbstrDest, 
  369.     IN      LPCSTR mbstrStart, 
  370.     IN      LPCSTR mbstrEnd     // first char NOT to copy
  371.     )
  372. {
  373.     LPSTR mbstrOrg;
  374.  
  375.     mbstrOrg = mbstrDest;
  376.  
  377.     // Assume mbstrEnd is on a lead byte
  378.  
  379.     while (mbstrStart < mbstrEnd) {
  380.         if (isleadbyte (*mbstrStart)) {
  381.             *mbstrDest = *mbstrStart;
  382.             mbstrDest++;
  383.             mbstrStart++;
  384.         }
  385.  
  386.         *mbstrDest = *mbstrStart;
  387.         mbstrDest++;
  388.         mbstrStart++;
  389.     }
  390.  
  391.     *mbstrDest = 0;
  392.  
  393.     return mbstrOrg;
  394. }
  395.  
  396. LPSTR 
  397. AppendStr (
  398.     OUT     LPSTR mbstrDest, 
  399.     IN      LPCSTR mbstrSrc
  400.     )
  401.  
  402. {
  403.     // Advance mbstrDest to end of string
  404.     mbstrDest = _mbschr (mbstrDest, 0);
  405.  
  406.     // Copy string
  407.     while (*mbstrSrc) {
  408.         *mbstrDest = *mbstrSrc++;
  409.         if (isleadbyte (*mbstrDest)) {
  410.             mbstrDest++;
  411.             *mbstrDest = *mbstrSrc++;
  412.         }
  413.         mbstrDest++;
  414.     }
  415.  
  416.     *mbstrDest = 0;
  417.  
  418.     return mbstrDest;
  419. }
  420.  
  421.  
  422. BOOL
  423. pFindShortName (
  424.     IN      LPCTSTR WhatToFind,
  425.     OUT     LPTSTR Buffer
  426.     )
  427. {
  428.     WIN32_FIND_DATA fd;
  429.     HANDLE hFind;
  430.  
  431.     hFind = FindFirstFile (WhatToFind, &fd);
  432.     if (!hFind) {
  433.         return FALSE;
  434.     }
  435.  
  436.     FindClose (hFind);
  437.     _mbscpy (Buffer, fd.cFileName);
  438.  
  439.     return TRUE;
  440. }
  441.  
  442.  
  443. BOOL
  444. OurGetLongPathName (
  445.     IN      LPCSTR ShortPath,
  446.     OUT     LPSTR Buffer
  447.     )
  448. {
  449.     CHAR FullPath[MAX_PATH];
  450.     LPSTR FilePart;
  451.     LPSTR BufferEnd;
  452.     LPSTR p, p2;
  453.     CHAR c;
  454.  
  455.     //
  456.     // Convert ShortPath into complete path name
  457.     //
  458.  
  459.     if (!_mbschr (ShortPath, TEXT('\\'))) {
  460.         if (!SearchPath (NULL, ShortPath, NULL, MAX_PATH, FullPath, &FilePart)) {
  461.             return FALSE;
  462.         }
  463.     } else {
  464.         GetFullPathName (ShortPath, MAX_PATH, FullPath, &FilePart);
  465.     }
  466.  
  467.     //
  468.     // Convert short path to long path
  469.     //
  470.  
  471.     p = FullPath;
  472.  
  473.     // Don't process non-local paths
  474.     if (!(*p) || _mbsnextc (_mbsinc (p)) != TEXT(':')) {
  475.         _mbscpy (Buffer, FullPath);
  476.         return TRUE;
  477.     }
  478.  
  479.     p = _mbsinc (p);
  480.     p = _mbsinc (p);
  481.     if (_mbsnextc (p) != TEXT('\\')) {
  482.         _mbscpy (Buffer, FullPath);
  483.         return TRUE;
  484.     }
  485.     
  486.     // Copy drive letter to buffer
  487.     p = _mbsinc (p);
  488.     CopyStringAtoB (Buffer, FullPath, p);
  489.     BufferEnd = _mbschr (Buffer, 0);
  490.  
  491.     // Convert each portion of the path
  492.     do {
  493.         // Locate end of this file or dir
  494.         p2 = _mbschr (p, TEXT('\\'));
  495.         if (!p2) {
  496.             p = _mbschr (p, 0);
  497.         } else {
  498.             p = p2;
  499.         }
  500.  
  501.         // Look up file
  502.         c = *p;
  503.         *p = 0;
  504.         if (!pFindShortName (FullPath, BufferEnd)) {
  505.             return FALSE;
  506.         }
  507.         *p = c;
  508.  
  509.         // Move on to next part of path
  510.         BufferEnd = _mbschr (BufferEnd, 0);
  511.         if (*p) {
  512.             p = _mbsinc (p);
  513.             BufferEnd = AppendStr (BufferEnd, TEXT("\\"));
  514.         }
  515.     } while (*p);
  516.  
  517.     return TRUE;
  518. }
  519.  
  520.  
  521. BOOL
  522. CreateScreenSaverParamKey (
  523.     IN      LPCSTR ScreenSaverName,
  524.     IN      LPCSTR ValueName,
  525.     OUT     LPSTR Buffer
  526.     )
  527. {
  528.     //
  529.     // Make sure we cannot create a string bigger than MAX_PATH
  530.     //
  531.  
  532.     if (_mbslen (ScreenSaverName) + 4 + _mbslen (ValueName) > MAX_PATH) {
  533.         return FALSE;
  534.     }
  535.  
  536.     //
  537.     // Format the string with length of screen saver name, screen saver name,
  538.     // and value name.
  539.     //
  540.  
  541.     wsprintf (Buffer, "%03u/%s/%s", _mbslen (ScreenSaverName), ScreenSaverName, ValueName);
  542.  
  543.     return TRUE;
  544. }
  545.  
  546. BOOL
  547. DecodeScreenSaverParamKey (
  548.     IN      LPCSTR EncodedString,
  549.     OUT     LPSTR ScreenSaverName,
  550.     OUT     LPSTR ValueName
  551.     )
  552. {
  553.     INT Len;
  554.  
  555.     //
  556.     // Validate encoded string.  It is in the form of ###/screen saver name/value name.
  557.     //
  558.  
  559.     Len = atoi (EncodedString);
  560.     if (Len < 0 || Len >= MAX_PATH || (Len - 5) > (INT) _mbslen (EncodedString)) {
  561.         return FALSE;
  562.     }
  563.  
  564.     if (EncodedString[3] != '/' || EncodedString[4 + Len] != '/') {
  565.         return FALSE;
  566.     }
  567.  
  568.     if (_mbslen (EncodedString + 5 + Len) >= MAX_PATH) {
  569.         return FALSE;
  570.     }
  571.  
  572.     //
  573.     // Extract screen saver name and value name
  574.     //
  575.  
  576.     _mbsncpy (ScreenSaverName, EncodedString + 4, Len);
  577.     ScreenSaverName[Len] = 0;
  578.  
  579.     _mbscpy (ValueName, EncodedString + 5 + Len);
  580.     return TRUE;
  581. }
  582.  
  583. LPSTR
  584. _mbsistr (
  585.     IN      LPCSTR mbstrStr, 
  586.     IN      LPCSTR mbstrSubStr
  587.     )
  588. {
  589.     LPCSTR mbstrStart, mbstrStrPos, mbstrSubStrPos;
  590.     LPCSTR mbstrEnd;
  591.  
  592.     mbstrEnd = (LPSTR) ((LPBYTE) mbstrStr + _mbsbytes (mbstrStr) - _mbsbytes (mbstrSubStr));
  593.  
  594.     for (mbstrStart = mbstrStr ; mbstrStart <= mbstrEnd ; mbstrStart = _mbsinc (mbstrStart)) {
  595.         mbstrStrPos = mbstrStart;
  596.         mbstrSubStrPos = mbstrSubStr;
  597.  
  598.         while (*mbstrSubStrPos && 
  599.                _mbctolower ((INT) _mbsnextc (mbstrSubStrPos)) == _mbctolower ((INT) _mbsnextc (mbstrStrPos))) 
  600.         {
  601.             mbstrStrPos = _mbsinc (mbstrStrPos);
  602.             mbstrSubStrPos = _mbsinc (mbstrSubStrPos);
  603.         }
  604.  
  605.         if (!(*mbstrSubStrPos))
  606.             return (LPSTR) mbstrStart;
  607.     }
  608.  
  609.     return NULL;    
  610. }
  611.  
  612. VOID
  613. DeletePartOfString (
  614.     IN      LPSTR Buffer,
  615.     IN      DWORD CharsToDelete
  616.     )
  617. {
  618.     LPSTR p;
  619.     DWORD d;
  620.  
  621.     p = Buffer;
  622.     for (d = 0 ; *p && d < CharsToDelete ; d++) {
  623.         p = _mbsinc (p);
  624.     }
  625.  
  626.     if (!(*p)) {
  627.         *Buffer = 0;
  628.     } else {
  629.         MoveMemory (Buffer, p, CountStringBytes(p));
  630.     }
  631. }
  632.  
  633. VOID
  634. InsertStringInString (
  635.     IN      LPSTR Buffer,
  636.     IN      LPCSTR StringToInsert
  637.     )
  638. {
  639.     DWORD BytesToMove;
  640.     DWORD BytesOfInsertedString;
  641.  
  642.     BytesToMove = CountStringBytes (Buffer);
  643.     BytesOfInsertedString = _mbsbytes(StringToInsert);
  644.     MoveMemory (Buffer + BytesOfInsertedString, 
  645.                 Buffer,
  646.                 BytesToMove
  647.                 );
  648.     _mbsncpy (Buffer, StringToInsert, _mbslen (StringToInsert));
  649. }
  650.  
  651.  
  652. VOID
  653. ConvertSystemToSystem32 (
  654.     IN OUT  LPSTR FileName
  655.     )
  656. {
  657.     LPSTR p;
  658.  
  659.     // look for \system\ in the path somewhere
  660.     p = _mbsistr (FileName, S_SYSTEM_DIR);
  661.     if (p) {
  662.         // Remove "\system\" and replace with "\system32\"
  663.         DeletePartOfString (p, _mbslen (S_SYSTEM_DIR));
  664.         InsertStringInString (p, S_SYSTEM32_DIR);
  665.     }
  666. }
  667.  
  668.  
  669.  
  670.  
  671.