Leaked source code of windows server 2003
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.

644 lines
16 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. cpls.c
  5. Abstract:
  6. Control Panel applet converters
  7. This source file implements functions needed to convert
  8. Win95 control panel settings into NT format. The most
  9. complex of the structures are the accessibility flag
  10. conversions.
  11. Author:
  12. Jim Schmidt (jimschm) 9-Aug-1996
  13. Revision History:
  14. Jim Schmidt (jimschm) 27-Jul-1998 Added ValFn_AntiAlias
  15. --*/
  16. #include "pch.h"
  17. #include "rulehlprp.h"
  18. #include <wingdip.h>
  19. extern PVOID g_NtFontFiles; // in rulehlpr.c
  20. #define BASICS_ON 0x00000001
  21. #define BASICS_AVAILABLE 0x00000002
  22. #define BASICS_HOTKEYACTIVE 0x00000004
  23. #define BASICS_CONFIRMHOTKEY 0x00000008
  24. #define BASICS_HOTKEYSOUND 0x00000010
  25. #define BASICS_INDICATOR 0x00000020
  26. #define SPECIAL_INVERT_OPTION 0x80000000
  27. typedef struct {
  28. LPCTSTR ValueName;
  29. DWORD FlagVal;
  30. } ACCESS_OPTION, *PACCESS_OPTION;
  31. ACCESS_OPTION g_FilterKeys[] = {
  32. S_ACCESS_ON, BASICS_ON,
  33. S_ACCESS_AVAILABLE, BASICS_AVAILABLE,
  34. S_ACCESS_HOTKEYACTIVE, BASICS_HOTKEYACTIVE,
  35. S_ACCESS_CONFIRMHOTKEY, BASICS_CONFIRMHOTKEY,
  36. S_ACCESS_HOTKEYSOUND, BASICS_HOTKEYSOUND,
  37. S_ACCESS_SHOWSTATUSINDICATOR, BASICS_INDICATOR,
  38. S_ACCESS_CLICKON, FKF_CLICKON,
  39. NULL, 0
  40. };
  41. ACCESS_OPTION g_MouseKeys[] = {
  42. S_ACCESS_ON, BASICS_ON,
  43. S_ACCESS_AVAILABLE, BASICS_AVAILABLE,
  44. S_ACCESS_HOTKEYACTIVE, BASICS_HOTKEYACTIVE,
  45. S_ACCESS_CONFIRMHOTKEY, BASICS_CONFIRMHOTKEY,
  46. S_ACCESS_HOTKEYSOUND, BASICS_HOTKEYSOUND,
  47. S_ACCESS_SHOWSTATUSINDICATOR, BASICS_INDICATOR,
  48. S_ACCESS_MODIFIERS, MKF_MODIFIERS|SPECIAL_INVERT_OPTION,
  49. S_ACCESS_REPLACENUMBERS, MKF_REPLACENUMBERS,
  50. NULL, 0
  51. };
  52. ACCESS_OPTION g_StickyKeys[] = {
  53. S_ACCESS_ON, BASICS_ON,
  54. S_ACCESS_AVAILABLE, BASICS_AVAILABLE,
  55. S_ACCESS_HOTKEYACTIVE, BASICS_HOTKEYACTIVE,
  56. S_ACCESS_CONFIRMHOTKEY, BASICS_CONFIRMHOTKEY,
  57. S_ACCESS_HOTKEYSOUND, BASICS_HOTKEYSOUND,
  58. S_ACCESS_SHOWSTATUSINDICATOR, BASICS_INDICATOR,
  59. S_ACCESS_AUDIBLEFEEDBACK, SKF_AUDIBLEFEEDBACK,
  60. S_ACCESS_TRISTATE, SKF_TRISTATE,
  61. S_ACCESS_TWOKEYSOFF, SKF_TWOKEYSOFF,
  62. NULL, 0
  63. };
  64. ACCESS_OPTION g_SoundSentry[] = {
  65. S_ACCESS_ON, BASICS_ON,
  66. S_ACCESS_AVAILABLE, BASICS_AVAILABLE,
  67. S_ACCESS_SHOWSTATUSINDICATOR, BASICS_INDICATOR,
  68. NULL, 0
  69. };
  70. ACCESS_OPTION g_TimeOut[] = {
  71. S_ACCESS_ON, BASICS_ON,
  72. S_ACCESS_ONOFFFEEDBACK, ATF_ONOFFFEEDBACK,
  73. NULL, 0
  74. };
  75. ACCESS_OPTION g_ToggleKeys[] = {
  76. S_ACCESS_ON, BASICS_ON,
  77. S_ACCESS_AVAILABLE, BASICS_AVAILABLE,
  78. S_ACCESS_HOTKEYACTIVE, BASICS_HOTKEYACTIVE,
  79. S_ACCESS_CONFIRMHOTKEY, BASICS_CONFIRMHOTKEY,
  80. S_ACCESS_HOTKEYSOUND, BASICS_HOTKEYSOUND,
  81. S_ACCESS_SHOWSTATUSINDICATOR, BASICS_INDICATOR,
  82. NULL, 0
  83. };
  84. ACCESS_OPTION g_HighContrast[] = {
  85. S_ACCESS_ON, BASICS_ON,
  86. S_ACCESS_AVAILABLE, BASICS_AVAILABLE,
  87. S_ACCESS_HOTKEYACTIVE, BASICS_HOTKEYACTIVE,
  88. S_ACCESS_CONFIRMHOTKEY, BASICS_CONFIRMHOTKEY,
  89. S_ACCESS_HOTKEYSOUND, BASICS_HOTKEYSOUND,
  90. S_ACCESS_SHOWSTATUSINDICATOR, BASICS_INDICATOR,
  91. S_ACCESS_HOTKEYAVAILABLE, HCF_HOTKEYAVAILABLE,
  92. NULL, 0
  93. };
  94. DWORD
  95. ConvertFlags (
  96. IN LPCTSTR Object,
  97. IN PACCESS_OPTION OptionArray
  98. )
  99. {
  100. DATAOBJECT Ob;
  101. DWORD Flags;
  102. DWORD d;
  103. if (!CreateObjectStruct (Object, &Ob, WIN95OBJECT)) {
  104. LOG ((LOG_ERROR, "%s is not a valid object", Object));
  105. return 0;
  106. }
  107. if (!OpenObject (&Ob)) {
  108. DEBUGMSG ((DBG_WARNING, "%s does not exist", Object));
  109. return 0;
  110. }
  111. //
  112. // Get flag settings from Win95 registry and convert them to Flags
  113. //
  114. Flags = 0;
  115. while (OptionArray->ValueName) {
  116. SetRegistryValueName (&Ob, OptionArray->ValueName);
  117. if (GetDwordFromObject (&Ob, &d)) {
  118. //
  119. // Most flags are identical on Win9x and NT, but there's one
  120. // MouseKey flag that needs to be inverted.
  121. //
  122. if (OptionArray->FlagVal & SPECIAL_INVERT_OPTION) {
  123. if (!d) {
  124. Flags |= (OptionArray->FlagVal & (~SPECIAL_INVERT_OPTION));
  125. }
  126. } else if (d) {
  127. Flags |= OptionArray->FlagVal;
  128. }
  129. }
  130. OptionArray++;
  131. FreeObjectVal (&Ob);
  132. }
  133. FreeObjectStruct (&Ob);
  134. return Flags;
  135. }
  136. BOOL
  137. SaveAccessibilityFlags (
  138. IN LPCTSTR ObjectStr,
  139. IN DWORD dw
  140. )
  141. {
  142. DATAOBJECT Ob;
  143. BOOL b = FALSE;
  144. TCHAR FlagBuf[32];
  145. SetLastError (ERROR_SUCCESS);
  146. if (!CreateObjectStruct (ObjectStr, &Ob, WINNTOBJECT)) {
  147. LOG ((LOG_ERROR, "Save Accessibility Flags: can't create object %s", ObjectStr));
  148. return FALSE;
  149. }
  150. if (!(Ob.ValueName)) {
  151. if (!SetRegistryValueName (&Ob, TEXT("Flags"))) {
  152. return FALSE;
  153. }
  154. } else {
  155. DEBUGMSG ((DBG_WARNING, "SaveAccessibilityFlags: Name already exists"));
  156. }
  157. wsprintf (FlagBuf, TEXT("%u"), dw);
  158. SetRegistryType (&Ob, REG_SZ);
  159. ReplaceValue (&Ob, (LPBYTE) FlagBuf, SizeOfString (FlagBuf));
  160. b = WriteObject (&Ob);
  161. FreeObjectStruct (&Ob);
  162. return b;
  163. }
  164. BOOL
  165. pConvertFlagsAndSave (
  166. IN LPCTSTR SrcObject,
  167. IN LPCTSTR DestObject,
  168. IN PACCESS_OPTION OptionArray,
  169. IN DWORD ForceValues
  170. )
  171. {
  172. DWORD d;
  173. d = ConvertFlags (SrcObject, OptionArray);
  174. if (!d) {
  175. return TRUE;
  176. }
  177. DEBUGMSG ((DBG_VERBOSE, "Setting %x and forcing %x for %s", d, ForceValues, DestObject));
  178. return SaveAccessibilityFlags (DestObject, d | ForceValues);
  179. }
  180. //
  181. // Exported helper functions
  182. //
  183. BOOL
  184. RuleHlpr_ConvertFilterKeys (
  185. IN LPCTSTR SrcObjectStr,
  186. IN LPCTSTR DestObjectStr,
  187. IN LPCTSTR User,
  188. IN LPVOID Data
  189. )
  190. {
  191. return pConvertFlagsAndSave (
  192. SrcObjectStr,
  193. DestObjectStr,
  194. g_FilterKeys,
  195. BASICS_HOTKEYSOUND | BASICS_CONFIRMHOTKEY | BASICS_AVAILABLE
  196. );
  197. }
  198. BOOL
  199. RuleHlpr_ConvertOldDisabled (
  200. IN LPCTSTR SrcObjectStr,
  201. IN LPCTSTR DestObjectStr,
  202. IN LPCTSTR User,
  203. IN LPVOID Data
  204. )
  205. {
  206. DATAOBJECT Ob;
  207. DWORD Val;
  208. BOOL b = FALSE;
  209. if (!ReadWin95ObjectString (SrcObjectStr, &Ob)) {
  210. DEBUGMSG ((DBG_WARNING, "RuleHlpr_ConvertOldDisabled failed because ReadWin95ObjectString failed"));
  211. goto c0;
  212. }
  213. //
  214. // Obtain Val from DWORD or string
  215. //
  216. if (!GetDwordFromObject (&Ob, &Val)) {
  217. goto c1;
  218. }
  219. // Our little fixup
  220. if (Val == 32760) {
  221. Val = 0;
  222. } else {
  223. b = TRUE;
  224. goto c1;
  225. }
  226. //
  227. // Regenerate registry value
  228. //
  229. if (Ob.Type == REG_DWORD) {
  230. *((PDWORD) Ob.Value.Buffer) = Val;
  231. } else {
  232. TCHAR NumStr[32];
  233. wsprintf (NumStr, TEXT("%u"), Val);
  234. if (!ReplaceValueWithString (&Ob, NumStr)) {
  235. goto c1;
  236. }
  237. }
  238. if (!WriteWinNTObjectString (DestObjectStr, &Ob)) {
  239. DEBUGMSG ((DBG_WARNING, "RuleHlpr_ConvertOldDisabled failed because WriteWinNTObjectString failed"));
  240. goto c1;
  241. }
  242. b = TRUE;
  243. c1:
  244. FreeObjectStruct (&Ob);
  245. c0:
  246. return b;
  247. }
  248. BOOL
  249. RuleHlpr_ConvertMouseKeys (
  250. IN LPCTSTR SrcObjectStr,
  251. IN LPCTSTR DestObjectStr,
  252. IN LPCTSTR User,
  253. IN LPVOID Data
  254. )
  255. {
  256. return pConvertFlagsAndSave (
  257. SrcObjectStr,
  258. DestObjectStr,
  259. g_MouseKeys,
  260. BASICS_HOTKEYSOUND | BASICS_CONFIRMHOTKEY | BASICS_AVAILABLE
  261. );
  262. }
  263. BOOL
  264. RuleHlpr_ConvertStickyKeys (
  265. IN LPCTSTR SrcObjectStr,
  266. IN LPCTSTR DestObjectStr,
  267. IN LPCTSTR User,
  268. IN LPVOID Data
  269. )
  270. {
  271. return pConvertFlagsAndSave (
  272. SrcObjectStr,
  273. DestObjectStr,
  274. g_StickyKeys,
  275. BASICS_HOTKEYSOUND | BASICS_CONFIRMHOTKEY | BASICS_AVAILABLE
  276. );
  277. }
  278. BOOL
  279. RuleHlpr_ConvertSoundSentry (
  280. IN LPCTSTR SrcObjectStr,
  281. IN LPCTSTR DestObjectStr,
  282. IN LPCTSTR User,
  283. IN LPVOID Data
  284. )
  285. {
  286. return pConvertFlagsAndSave (
  287. SrcObjectStr,
  288. DestObjectStr,
  289. g_SoundSentry,
  290. BASICS_AVAILABLE
  291. );
  292. }
  293. BOOL
  294. RuleHlpr_ConvertTimeOut (
  295. IN LPCTSTR SrcObjectStr,
  296. IN LPCTSTR DestObjectStr,
  297. IN LPCTSTR User,
  298. IN LPVOID Data
  299. )
  300. {
  301. return pConvertFlagsAndSave (
  302. SrcObjectStr,
  303. DestObjectStr,
  304. g_TimeOut,
  305. 0
  306. );
  307. }
  308. BOOL
  309. RuleHlpr_ConvertToggleKeys (
  310. IN LPCTSTR SrcObjectStr,
  311. IN LPCTSTR DestObjectStr,
  312. IN LPCTSTR User,
  313. IN LPVOID Data
  314. )
  315. {
  316. return pConvertFlagsAndSave (
  317. SrcObjectStr,
  318. DestObjectStr,
  319. g_ToggleKeys,
  320. BASICS_HOTKEYSOUND | BASICS_CONFIRMHOTKEY | BASICS_AVAILABLE
  321. );
  322. }
  323. BOOL
  324. RuleHlpr_ConvertHighContrast (
  325. IN LPCTSTR SrcObjectStr,
  326. IN LPCTSTR DestObjectStr,
  327. IN LPCTSTR User,
  328. IN LPVOID Data
  329. )
  330. {
  331. return pConvertFlagsAndSave (
  332. SrcObjectStr,
  333. DestObjectStr,
  334. g_HighContrast,
  335. BASICS_AVAILABLE | BASICS_CONFIRMHOTKEY |
  336. BASICS_INDICATOR | HCF_HOTKEYAVAILABLE |
  337. BASICS_HOTKEYSOUND
  338. );
  339. }
  340. BOOL
  341. ValFn_Fonts (
  342. IN OUT PDATAOBJECT ObPtr
  343. )
  344. /*++
  345. Routine Description:
  346. This routine uses the RuleHlpr_ConvertRegVal simplification routine. See
  347. rulehlpr.c for details. The simplification routine does almost all the work
  348. for us; all we need to do is update the value.
  349. ValFn_Fonts compares the value data against the string table g_NtFontFiles
  350. to suppress copy of font names of files that NT installs. This allows the
  351. font names to change.
  352. Arguments:
  353. ObPtr - Specifies the Win95 data object as specified in wkstamig.inf,
  354. [Win9x Data Conversion] section. The object value is then modified.
  355. After returning, the merge code then copies the data to the NT
  356. destination, which has a new location (specified in wkstamig.inf,
  357. [Map Win9x to WinNT] section).
  358. Return Value:
  359. Tri-state:
  360. TRUE to allow merge code to continue processing (it writes the value)
  361. FALSE and last error == ERROR_SUCCESS to continue, but skip the write
  362. FALSE and last error != ERROR_SUCCESS if an error occurred
  363. --*/
  364. {
  365. LONG rc;
  366. TCHAR FontName[MAX_TCHAR_PATH];
  367. PTSTR p;
  368. BOOL Check;
  369. DATAOBJECT NtObject;
  370. BOOL AlreadyExists;
  371. //
  372. // Require non-empty value data
  373. //
  374. if (!IsObjectRegistryKeyAndVal (ObPtr) ||
  375. !IsRegistryTypeSpecified (ObPtr) ||
  376. !ObPtr->Value.Size ||
  377. !g_NtFontFiles
  378. ) {
  379. SetLastError (ERROR_SUCCESS);
  380. return FALSE;
  381. }
  382. //
  383. // Ignore Win9x font entry if same value name exists on NT
  384. //
  385. if (!DuplicateObjectStruct (&NtObject, ObPtr)) {
  386. return FALSE;
  387. }
  388. DEBUGMSG ((DBG_VERBOSE, "Working on %s [%s]", ObPtr->KeyPtr->KeyString, ObPtr->ValueName));
  389. SetPlatformType (&NtObject, WINNTOBJECT);
  390. SetRegistryKey (&NtObject, TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts"));
  391. FreeObjectVal (&NtObject);
  392. DEBUGMSG ((DBG_VERBOSE, "Reading %s [%s]", NtObject.KeyPtr->KeyString, NtObject.ValueName));
  393. AlreadyExists = ReadObject (&NtObject);
  394. FreeObjectStruct (&NtObject);
  395. if (AlreadyExists) {
  396. DEBUGMSG ((DBG_VERBOSE, "[%s] Already exists", ObPtr->ValueName));
  397. SetLastError (ERROR_SUCCESS);
  398. return FALSE;
  399. }
  400. //
  401. // Look in string table for file name
  402. //
  403. rc = pSetupStringTableLookUpString (
  404. g_NtFontFiles,
  405. (PTSTR) ObPtr->Value.Buffer,
  406. STRTAB_CASE_INSENSITIVE
  407. );
  408. if (rc == -1) {
  409. //
  410. // Check for TTF/TTC match
  411. //
  412. _tcssafecpy (FontName, (PCTSTR) ObPtr->Value.Buffer, MAX_TCHAR_PATH);
  413. p = _tcschr (FontName, TEXT('.'));
  414. if (p) {
  415. p = _tcsinc (p);
  416. if (StringIMatch (p, TEXT("TTF"))) {
  417. StringCopy (p, TEXT("TTC"));
  418. Check = TRUE;
  419. } else if (StringIMatch (p, TEXT("TTC"))) {
  420. StringCopy (p, TEXT("TTF"));
  421. Check = TRUE;
  422. } else {
  423. Check = FALSE;
  424. }
  425. if (Check) {
  426. rc = pSetupStringTableLookUpString (
  427. g_NtFontFiles,
  428. FontName,
  429. STRTAB_CASE_INSENSITIVE
  430. );
  431. }
  432. }
  433. }
  434. if (rc == -1) {
  435. //
  436. // Check for an NT font named FONTU.TTF or FONTU.TTC
  437. //
  438. _tcssafecpy (FontName, (PCTSTR) ObPtr->Value.Buffer, MAX_TCHAR_PATH);
  439. p = _tcschr (FontName, TEXT('.'));
  440. if (p) {
  441. StringCopy (p, TEXT("U.TTF"));
  442. rc = pSetupStringTableLookUpString (
  443. g_NtFontFiles,
  444. FontName,
  445. STRTAB_CASE_INSENSITIVE
  446. );
  447. if (rc == -1) {
  448. StringCopy (p, TEXT("U.TTC"));
  449. rc = pSetupStringTableLookUpString (
  450. g_NtFontFiles,
  451. FontName,
  452. STRTAB_CASE_INSENSITIVE
  453. );
  454. }
  455. }
  456. }
  457. if (rc != -1) {
  458. //
  459. // Font name was in the table, so don't add it twice
  460. //
  461. DEBUGMSG ((DBG_NAUSEA, "Suppressing Win9x font registration for %s", ObPtr->Value.Buffer));
  462. SetLastError (ERROR_SUCCESS);
  463. return FALSE;
  464. } else {
  465. DEBUGMSG ((DBG_VERBOSE, "[%s] Preserving Win9x font info: %s", ObPtr->ValueName, (PCTSTR) ObPtr->Value.Buffer));
  466. }
  467. return TRUE;
  468. }
  469. BOOL
  470. ValFn_AntiAlias (
  471. IN OUT PDATAOBJECT ObPtr
  472. )
  473. /*++
  474. Routine Description:
  475. This routine uses the RuleHlpr_ConvertRegVal simplification routine. See
  476. rulehlpr.c for details. The simplification routine does almost all the work
  477. for us; all we need to do is update the value.
  478. ValFn_AntiAlias changes a 1 to a 2. Win9x uses 1, but NT uses FE_AA_ON,
  479. which is currently 2.
  480. Return Value:
  481. Tri-state:
  482. TRUE to allow merge code to continue processing (it writes the value)
  483. FALSE and last error == ERROR_SUCCESS to continue, but skip the write
  484. FALSE and last error != ERROR_SUCCESS if an error occurred
  485. --*/
  486. {
  487. TCHAR Number[8];
  488. //
  489. // Require non-empty REG_SZ
  490. //
  491. if (!IsObjectRegistryKeyAndVal (ObPtr) ||
  492. !IsRegistryTypeSpecified (ObPtr) ||
  493. !ObPtr->Value.Size ||
  494. !g_NtFontFiles ||
  495. ObPtr->Type != REG_SZ
  496. ) {
  497. DEBUGMSG ((DBG_WARNING, "ValFn_AntiAlias: Data is not valid"));
  498. ReplaceValueWithString (ObPtr, TEXT("0"));
  499. }
  500. else if (_ttoi ((PCTSTR) ObPtr->Value.Buffer)) {
  501. DEBUGMSG ((DBG_NAUSEA, "Switching anti-alias value from 1 to %u", FE_AA_ON));
  502. wsprintf (Number, TEXT("%u"), FE_AA_ON);
  503. ReplaceValueWithString (ObPtr, Number);
  504. }
  505. return TRUE;
  506. }