Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

699 lines
13 KiB

  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. LOG ((LOG_WARNING, MSG_HUGEDATA_ERROR));
  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. _mbscpy (FullPath, g_Data);
  230. }
  231. //
  232. // Screen savers are always stored in short filename format
  233. //
  234. GetShortPathName (FullPath, ShortName, MAX_PATH);
  235. return SetRegValueString (RegKey, KeyName, ShortName);
  236. }
  237. INT
  238. GetHexDigit (
  239. IN CHAR c
  240. )
  241. {
  242. if (c >= '0' && c <= '9') {
  243. return c - '0';
  244. }
  245. c = tolower (c);
  246. if (c >= 'a' && c <= 'f') {
  247. return c - 'a' + 10;
  248. }
  249. return -1;
  250. }
  251. BYTE
  252. GetNextHexByte (
  253. IN LPCSTR HexString,
  254. OUT LPCSTR *HexStringReturn
  255. )
  256. {
  257. INT a, b;
  258. a = GetHexDigit (HexString[0]);
  259. b = GetHexDigit (HexString[1]);
  260. if (a == -1 || b == -1) {
  261. *HexStringReturn = NULL;
  262. return 0;
  263. }
  264. *HexStringReturn = &(HexString[2]);
  265. return a * 16 + b;
  266. }
  267. BOOL
  268. GetNextDword (
  269. IN LPCSTR HexString,
  270. OUT LPCSTR *HexStringReturn,
  271. OUT PDWORD ValuePtr
  272. )
  273. {
  274. INT i;
  275. BYTE NextByte;
  276. *ValuePtr = 0;
  277. for (i = 0 ; i < 4 ; i++) {
  278. NextByte = GetNextHexByte (HexString, &HexString);
  279. if (!HexString) {
  280. return FALSE;
  281. }
  282. *ValuePtr = ((*ValuePtr) << 8) | NextByte;
  283. }
  284. return TRUE;
  285. }
  286. BOOL
  287. VerifyBezierChecksum (
  288. IN LPCSTR HexString
  289. )
  290. {
  291. BYTE Checksum = 0;
  292. INT Len;
  293. Len = _mbslen (HexString);
  294. Len -= 2;
  295. if (Len < 1) {
  296. return FALSE;
  297. }
  298. while (Len > 0) {
  299. Checksum += GetNextHexByte (HexString, &HexString);
  300. if (!HexString) {
  301. return FALSE;
  302. }
  303. }
  304. if (Checksum != GetNextHexByte (HexString, &HexString)) {
  305. return FALSE;
  306. }
  307. return TRUE;
  308. }
  309. BOOL
  310. CopyUntranslatedSettings (
  311. IN HKEY RegRoot
  312. )
  313. {
  314. LPSTR KeyBuffer;
  315. DWORD KeyBufferSize;
  316. LPSTR p;
  317. CHAR ScreenSaverName[MAX_PATH];
  318. CHAR ValueName[MAX_PATH];
  319. HKEY Key;
  320. //
  321. // Enumerate each entry in our private settings file for the user
  322. //
  323. KeyBufferSize = 32768;
  324. KeyBuffer = (LPSTR) HeapAlloc (g_hHeap, 0, KeyBufferSize);
  325. if (!KeyBuffer) {
  326. return FALSE;
  327. }
  328. //
  329. // Get all keys in the user's section
  330. //
  331. GetPrivateProfileString (
  332. g_User,
  333. NULL,
  334. S_DOUBLE_EMPTY,
  335. KeyBuffer,
  336. KeyBufferSize,
  337. g_SettingsFile
  338. );
  339. for (p = KeyBuffer ; *p ; p = _mbschr (p, 0) + 1) {
  340. //
  341. // Process only if key is encoded
  342. //
  343. if (!DecodeScreenSaverParamKey (p, ScreenSaverName, ValueName)) {
  344. continue;
  345. }
  346. //
  347. // Key is encoded, so perform migration!
  348. //
  349. pTranslateScrName (ScreenSaverName, NULL);
  350. //
  351. // Skip screen savers that have special processing
  352. //
  353. if (pHasSpecialProcessing (ScreenSaverName)) {
  354. continue;
  355. }
  356. //
  357. // Save the value to the registry
  358. //
  359. GetSettingsFileVal (p);
  360. Key = pCreateScreenSaverKey (RegRoot, ScreenSaverName);
  361. if (Key) {
  362. if (SetRegValueString (Key, ValueName, g_Data))
  363. {
  364. CHAR DebugMsg[MAX_PATH*2];
  365. wsprintf (DebugMsg, "Saved %s=%s\r\n", ValueName, g_Data);
  366. SetupLogError (DebugMsg, LogSevInformation);
  367. } else {
  368. CHAR DebugMsg[MAX_PATH*2];
  369. wsprintf (DebugMsg, "Could not save %s=%s\r\n", ValueName, g_Data);
  370. SetupLogError (DebugMsg, LogSevError);
  371. }
  372. CloseRegKey (Key);
  373. }
  374. }
  375. HeapFree (g_hHeap, 0, KeyBuffer);
  376. return TRUE;
  377. }
  378. BOOL
  379. pHasSpecialProcessing (
  380. IN LPCSTR ScreenSaverName
  381. )
  382. {
  383. //
  384. // Return TRUE if we are doing something special for the
  385. // named screen saver.
  386. //
  387. if (!_mbsicmp (ScreenSaverName, S_BEZIER) ||
  388. !_mbsicmp (ScreenSaverName, S_MARQUEE)
  389. ) {
  390. return TRUE;
  391. }
  392. return FALSE;
  393. }
  394. BOOL
  395. TranslateScreenSavers (
  396. IN HKEY RegRoot
  397. )
  398. {
  399. BOOL b = TRUE;
  400. b &= pTranslateBezier (RegRoot);
  401. b &= pTranslateMarquee (RegRoot);
  402. return b;
  403. }
  404. BOOL
  405. pTranslateBezier (
  406. IN HKEY RegRoot
  407. )
  408. {
  409. DWORD Value;
  410. CHAR StrValue[32];
  411. LPCSTR p;
  412. HKEY RegKey;
  413. BOOL b;
  414. //
  415. // NT's Bezier has three settings:
  416. //
  417. // Length (REG_SZ) = Curve Count on Win9x
  418. // LineSpeed (REG_SZ) = Speed on Win9x
  419. // Width (REG_SZ) = Density on Win9x
  420. //
  421. // Win9x's Bezier has a big string of hex in the following format:
  422. //
  423. // Clear Screen Flag (DWORD)
  424. // Random Colors Flag (DWORD)
  425. // Curve Count (DWORD)
  426. // Line Count (DWORD)
  427. // Density (DWORD)
  428. // Speed (DWORD)
  429. // Current Color (DWORD RGB)
  430. // Checksum (BYTE)
  431. //
  432. //
  433. // Verify structure
  434. //
  435. GetSettingsFileVal (S_BEZIER_SETTINGS);
  436. if (!VerifyBezierChecksum (g_Data)) {
  437. return TRUE;
  438. }
  439. //
  440. // Open reg key
  441. //
  442. RegKey = pCreateControlPanelKey (RegRoot, S_BEZIER_SETTINGS, TRUE);
  443. if (!RegKey) {
  444. return FALSE;
  445. }
  446. p = g_Data;
  447. // Get clear screen flag (but ignore it)
  448. b = GetNextDword (p, &p, &Value);
  449. // Get random colors flag (but ignore it)
  450. if (b) {
  451. b = GetNextDword (p, &p, &Value);
  452. }
  453. //
  454. // Get curve count
  455. //
  456. if (b) {
  457. b = GetNextDword (p, &p, &Value);
  458. }
  459. if (b) {
  460. wsprintf (StrValue, "%u", Value);
  461. b = SetRegValueString (RegKey, S_LENGTH, StrValue);
  462. }
  463. // Get line count (but ignore it)
  464. if (b) {
  465. b = GetNextDword (p, &p, &Value);
  466. }
  467. //
  468. // Get density
  469. //
  470. if (b) {
  471. b = GetNextDword (p, &p, &Value);
  472. }
  473. if (b) {
  474. wsprintf (StrValue, "%u", Value);
  475. b = SetRegValueString (RegKey, S_WIDTH, StrValue);
  476. }
  477. //
  478. // Get speed
  479. //
  480. if (b) {
  481. b = GetNextDword (p, &p, &Value);
  482. }
  483. if (b) {
  484. wsprintf (StrValue, "%u", Value);
  485. b = SetRegValueString (RegKey, S_LINESPEED, StrValue);
  486. }
  487. CloseRegKey (RegKey);
  488. if (!b) {
  489. LOG ((LOG_ERROR, MSG_BEZIER_DATA_ERROR));
  490. }
  491. return TRUE;
  492. }
  493. LPCSTR g_MarqueeValues[] = {
  494. S_BACKGROUND_COLOR,
  495. S_CHARSET,
  496. S_FONT,
  497. S_MODE,
  498. S_SIZE,
  499. S_SPEED,
  500. S_TEXT,
  501. S_TEXTCOLOR,
  502. NULL
  503. };
  504. BOOL
  505. pTranslateMarquee (
  506. IN HKEY RegRoot
  507. )
  508. {
  509. BOOL b;
  510. //
  511. // Marquee has the same settings on Win9x and NT. They just need
  512. // to be copied from the control.ini file to the NT registry.
  513. //
  514. b = pCopyValuesFromSettingsFileToRegistry (
  515. RegRoot,
  516. S_MARQUEE_SETTINGS,
  517. S_MARQUEE,
  518. g_MarqueeValues
  519. );
  520. //
  521. // We need to divide the speed by two to be compatible
  522. //
  523. if (b) {
  524. HKEY MarqueeKey;
  525. LPCSTR Value;
  526. CHAR NewValue[32];
  527. // Read the setting we just wrote in the registry
  528. MarqueeKey = pCreateControlPanelKey (RegRoot, S_MARQUEE_SETTINGS, FALSE);
  529. if (MarqueeKey) {
  530. Value = GetRegValueString (MarqueeKey, S_SPEED);
  531. if (Value) {
  532. // Write speed divided by two
  533. wsprintf (NewValue, "%i", atoi (Value) / 2);
  534. SetRegValueString (MarqueeKey, S_SPEED, NewValue);
  535. }
  536. CloseRegKey (MarqueeKey);
  537. }
  538. }
  539. return b;
  540. }