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.

899 lines
23 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. access.c
  5. Abstract:
  6. Implements Win9x accessiblity conversion by hooking the physical registry type
  7. and emulating the NT registry format.
  8. Author:
  9. Jim Schmidt (jimschm) 29-Aug-2000
  10. Revision History:
  11. <alias> <date> <comments>
  12. --*/
  13. //
  14. // Includes
  15. //
  16. #include "pch.h"
  17. #include "logmsg.h"
  18. #define DBG_ACCESS "Accessibility"
  19. //
  20. // Strings
  21. //
  22. #define S_ACCESSIBILITY_ROOT TEXT("HKCU\\Control Panel\\Accessibility")
  23. //
  24. // Constants
  25. //
  26. #define SPECIAL_INVERT_OPTION 0x80000000
  27. //
  28. // Macros
  29. //
  30. // none
  31. //
  32. // Types
  33. //
  34. typedef struct {
  35. PCTSTR ValueName;
  36. DWORD FlagVal;
  37. } ACCESS_OPTION, *PACCESS_OPTION;
  38. typedef struct {
  39. PACCESS_OPTION AccessibilityMap;
  40. PCTSTR Win9xSubKey;
  41. PCTSTR NtSubKey;
  42. } ACCESSIBILITY_MAPPINGS, *PACCESSIBILITY_MAPPINGS;
  43. typedef struct {
  44. MEMDB_ENUM EnumStruct;
  45. DWORD RegType;
  46. } ACCESSIBILITY_ENUM_STATE, *PACCESSIBILITY_ENUM_STATE;
  47. //
  48. // Globals
  49. //
  50. MIG_OBJECTTYPEID g_RegistryTypeId;
  51. HASHTABLE g_ProhibitTable;
  52. ACCESS_OPTION g_FilterKeys[] = {
  53. TEXT("On"), FKF_FILTERKEYSON,
  54. TEXT("Available"), FKF_AVAILABLE,
  55. TEXT("HotKeyActive"), FKF_HOTKEYACTIVE,
  56. TEXT("ConfirmHotKey"), FKF_CONFIRMHOTKEY,
  57. TEXT("HotKeySound"), FKF_HOTKEYSOUND,
  58. TEXT("ShowStatusIndicator"), FKF_INDICATOR,
  59. TEXT("ClickOn"), FKF_CLICKON,
  60. TEXT("OnOffFeedback"), 0,
  61. NULL
  62. };
  63. ACCESS_OPTION g_MouseKeys[] = {
  64. TEXT("On"), MKF_MOUSEKEYSON,
  65. TEXT("Available"), MKF_AVAILABLE,
  66. TEXT("HotKeyActive"), MKF_HOTKEYACTIVE,
  67. TEXT("ConfirmHotKey"), MKF_CONFIRMHOTKEY,
  68. TEXT("HotKeySound"), MKF_HOTKEYSOUND,
  69. TEXT("ShowStatusIndicator"), MKF_INDICATOR,
  70. TEXT("Modifiers"), MKF_MODIFIERS|SPECIAL_INVERT_OPTION,
  71. TEXT("ReplaceNumbers"), MKF_REPLACENUMBERS,
  72. TEXT("OnOffFeedback"), 0,
  73. NULL
  74. };
  75. ACCESS_OPTION g_StickyKeys[] = {
  76. TEXT("On"), SKF_STICKYKEYSON,
  77. TEXT("Available"), SKF_AVAILABLE,
  78. TEXT("HotKeyActive"), SKF_HOTKEYACTIVE,
  79. TEXT("ConfirmHotKey"), SKF_CONFIRMHOTKEY,
  80. TEXT("HotKeySound"), SKF_HOTKEYSOUND,
  81. TEXT("ShowStatusIndicator"), SKF_INDICATOR,
  82. TEXT("AudibleFeedback"), SKF_AUDIBLEFEEDBACK,
  83. TEXT("TriState"), SKF_TRISTATE,
  84. TEXT("TwoKeysOff"), SKF_TWOKEYSOFF,
  85. TEXT("OnOffFeedback"), 0,
  86. NULL
  87. };
  88. ACCESS_OPTION g_SoundSentry[] = {
  89. TEXT("On"), SSF_SOUNDSENTRYON,
  90. TEXT("Available"), SSF_AVAILABLE,
  91. TEXT("ShowStatusIndicator"), SSF_INDICATOR,
  92. NULL
  93. };
  94. ACCESS_OPTION g_TimeOut[] = {
  95. TEXT("On"), ATF_TIMEOUTON,
  96. TEXT("OnOffFeedback"), ATF_ONOFFFEEDBACK,
  97. NULL
  98. };
  99. ACCESS_OPTION g_ToggleKeys[] = {
  100. TEXT("On"), TKF_TOGGLEKEYSON,
  101. TEXT("Available"), TKF_AVAILABLE,
  102. TEXT("HotKeyActive"), TKF_HOTKEYACTIVE,
  103. TEXT("ConfirmHotKey"), TKF_CONFIRMHOTKEY,
  104. TEXT("HotKeySound"), TKF_HOTKEYSOUND,
  105. TEXT("ShowStatusIndicator"), TKF_INDICATOR,
  106. TEXT("OnOffFeedback"), 0,
  107. NULL
  108. };
  109. ACCESS_OPTION g_HighContrast[] = {
  110. TEXT("On"), HCF_HIGHCONTRASTON,
  111. TEXT("Available"), HCF_AVAILABLE,
  112. TEXT("HotKeyActive"), HCF_HOTKEYACTIVE,
  113. TEXT("ConfirmHotKey"), HCF_CONFIRMHOTKEY,
  114. TEXT("HotKeySound"), HCF_HOTKEYSOUND,
  115. TEXT("ShowStatusIndicator"), HCF_INDICATOR,
  116. TEXT("HotKeyAvailable"), HCF_HOTKEYAVAILABLE,
  117. TEXT("OnOffFeedback"), 0,
  118. NULL
  119. };
  120. ACCESSIBILITY_MAPPINGS g_AccessibilityMappings[] = {
  121. {g_FilterKeys, TEXT("KeyboardResponse"), TEXT("Keyboard Response")},
  122. {g_MouseKeys, TEXT("MouseKeys")},
  123. {g_StickyKeys, TEXT("StickyKeys")},
  124. {g_SoundSentry, TEXT("SoundSentry")},
  125. {g_TimeOut, TEXT("TimeOut")},
  126. {g_ToggleKeys, TEXT("ToggleKeys")},
  127. {g_HighContrast, TEXT("HighContrast")},
  128. {NULL}
  129. };
  130. //
  131. // Macro expansion list
  132. //
  133. // none
  134. //
  135. // Private function prototypes
  136. //
  137. // none
  138. //
  139. // Macro expansion definition
  140. //
  141. // none
  142. //
  143. // Private prototypes
  144. //
  145. ETMINITIALIZE AccessibilityEtmInitialize;
  146. MIG_PHYSICALENUMADD EmulatedEnumCallback;
  147. MIG_PHYSICALACQUIREHOOK AcquireAccessibilityFlags;
  148. MIG_PHYSICALACQUIREFREE ReleaseAccessibilityFlags;
  149. //
  150. // Code
  151. //
  152. VOID
  153. pProhibit9xSetting (
  154. IN PCTSTR Key,
  155. IN PCTSTR ValueName OPTIONAL
  156. )
  157. {
  158. MIG_OBJECTSTRINGHANDLE handle;
  159. handle = IsmCreateObjectHandle (Key, ValueName);
  160. MYASSERT (handle);
  161. IsmProhibitPhysicalEnum (g_RegistryTypeId, handle, NULL, 0, NULL);
  162. HtAddString (g_ProhibitTable, handle);
  163. IsmDestroyObjectHandle (handle);
  164. }
  165. BOOL
  166. pStoreEmulatedSetting (
  167. IN PCTSTR Key,
  168. IN PCTSTR ValueName, OPTIONAL
  169. IN DWORD Type,
  170. IN PBYTE ValueData,
  171. IN UINT ValueDataSize
  172. )
  173. {
  174. MIG_OBJECTSTRINGHANDLE handle;
  175. PCTSTR memdbNode;
  176. BOOL stored = FALSE;
  177. handle = IsmCreateObjectHandle (Key, ValueName);
  178. memdbNode = JoinPaths (TEXT("~Accessibility"), handle);
  179. IsmDestroyObjectHandle (handle);
  180. if (MemDbAddKey (memdbNode)) {
  181. if (ValueData) {
  182. stored = (MemDbSetValue (memdbNode, Type) != 0);
  183. stored &= (MemDbSetUnorderedBlob (memdbNode, 0, ValueData, ValueDataSize) != 0);
  184. } else {
  185. stored = TRUE;
  186. }
  187. }
  188. FreePathString (memdbNode);
  189. return stored;
  190. }
  191. VOID
  192. pMoveAccessibilityValue (
  193. IN PCTSTR Win9xKey,
  194. IN PCTSTR Win9xValue,
  195. IN PCTSTR NtKey,
  196. IN PCTSTR NtValue,
  197. IN BOOL ForceDword
  198. )
  199. {
  200. HKEY key;
  201. PBYTE data = NULL;
  202. PBYTE storeData;
  203. DWORD conversionDword;
  204. DWORD valueType;
  205. DWORD valueSize;
  206. MIG_OBJECTSTRINGHANDLE handle;
  207. BOOL prohibited;
  208. handle = IsmCreateObjectHandle (Win9xKey, Win9xValue);
  209. prohibited = (HtFindString (g_ProhibitTable, handle) != NULL);
  210. IsmDestroyObjectHandle (handle);
  211. if (prohibited) {
  212. return;
  213. }
  214. key = OpenRegKeyStr (Win9xKey);
  215. if (!key) {
  216. return;
  217. }
  218. __try {
  219. if (!GetRegValueTypeAndSize (key, Win9xValue, &valueType, &valueSize)) {
  220. __leave;
  221. }
  222. if (valueType != REG_SZ && valueType != REG_DWORD) {
  223. __leave;
  224. }
  225. data = GetRegValueData (key, Win9xValue);
  226. if (!data) {
  227. __leave;
  228. }
  229. if (ForceDword && valueType == REG_SZ) {
  230. storeData = (PBYTE) &conversionDword;
  231. conversionDword = _ttoi ((PCTSTR) data);
  232. valueType = REG_DWORD;
  233. valueSize = sizeof (DWORD);
  234. } else {
  235. storeData = data;
  236. }
  237. if (pStoreEmulatedSetting (NtKey, NtValue, valueType, storeData, valueSize)) {
  238. pProhibit9xSetting (Win9xKey, Win9xValue);
  239. }
  240. }
  241. __finally {
  242. CloseRegKey (key);
  243. if (data) {
  244. FreeAlloc (data);
  245. }
  246. }
  247. }
  248. VOID
  249. pMoveAccessibilityKey (
  250. IN PCTSTR Win9xKey,
  251. IN PCTSTR NtKey
  252. )
  253. {
  254. HKEY key;
  255. PBYTE data = NULL;
  256. DWORD valueType;
  257. DWORD valueSize;
  258. LONG rc;
  259. DWORD index = 0;
  260. TCHAR valueName[MAX_REGISTRY_KEY];
  261. DWORD valueNameSize;
  262. GROWBUFFER value = INIT_GROWBUFFER;
  263. MIG_OBJECTSTRINGHANDLE handle;
  264. BOOL prohibited;
  265. key = OpenRegKeyStr (Win9xKey);
  266. if (!key) {
  267. return;
  268. }
  269. __try {
  270. for (;;) {
  271. valueNameSize = ARRAYSIZE(valueName);
  272. valueSize = 0;
  273. rc = RegEnumValue (key, index, valueName, &valueNameSize, NULL, &valueType, NULL, &valueSize);
  274. if (rc != ERROR_SUCCESS) {
  275. break;
  276. }
  277. handle = IsmCreateObjectHandle (Win9xKey, valueName);
  278. prohibited = (HtFindString (g_ProhibitTable, handle) != NULL);
  279. IsmDestroyObjectHandle (handle);
  280. if (!prohibited) {
  281. value.End = 0;
  282. data = GbGrow (&value, valueSize);
  283. valueNameSize = ARRAYSIZE(valueName);
  284. rc = RegEnumValue (key, index, valueName, &valueNameSize, NULL, &valueType, value.Buf, &valueSize);
  285. if (rc != ERROR_SUCCESS) {
  286. break;
  287. }
  288. if (pStoreEmulatedSetting (NtKey, valueName, valueType, data, valueSize)) {
  289. pProhibit9xSetting (Win9xKey, valueName);
  290. }
  291. }
  292. index++;
  293. }
  294. if (pStoreEmulatedSetting (NtKey, NULL, 0, NULL, 0)) {
  295. pProhibit9xSetting (Win9xKey, NULL);
  296. }
  297. }
  298. __finally {
  299. CloseRegKey (key);
  300. GbFree (&value);
  301. }
  302. }
  303. VOID
  304. pTranslateAccessibilityKey (
  305. IN PCTSTR Win9xSubKey,
  306. IN PCTSTR NtSubKey,
  307. IN PACCESS_OPTION AccessibilityMap
  308. )
  309. {
  310. TCHAR full9xKey[MAX_REGISTRY_KEY];
  311. TCHAR fullNtKey[MAX_REGISTRY_KEY];
  312. MIG_OBJECTSTRINGHANDLE handle = NULL;
  313. HKEY key = NULL;
  314. PCTSTR data;
  315. DWORD flags = 0;
  316. DWORD thisFlag;
  317. BOOL enabled;
  318. TCHAR buffer[32];
  319. __try {
  320. StringCopy (full9xKey, S_ACCESSIBILITY_ROOT TEXT("\\"));
  321. StringCopy (fullNtKey, full9xKey);
  322. StringCat (full9xKey, Win9xSubKey);
  323. StringCat (fullNtKey, NtSubKey);
  324. key = OpenRegKeyStr (full9xKey);
  325. if (!key) {
  326. __leave;
  327. }
  328. while (AccessibilityMap->ValueName) {
  329. //
  330. // Prohibit enum of this value
  331. //
  332. handle = IsmCreateObjectHandle (full9xKey, AccessibilityMap->ValueName);
  333. MYASSERT (handle);
  334. IsmProhibitPhysicalEnum (g_RegistryTypeId, handle, NULL, 0, NULL);
  335. HtAddString (g_ProhibitTable, handle);
  336. IsmDestroyObjectHandle (handle);
  337. handle = NULL;
  338. //
  339. // Update the emulated flags
  340. //
  341. data = GetRegValueString (key, AccessibilityMap->ValueName);
  342. if (data) {
  343. enabled = (_ttoi (data) != 0);
  344. thisFlag = (AccessibilityMap->FlagVal & (~SPECIAL_INVERT_OPTION));
  345. if (AccessibilityMap->FlagVal & SPECIAL_INVERT_OPTION) {
  346. enabled = !enabled;
  347. }
  348. if (enabled) {
  349. flags |= thisFlag;
  350. }
  351. FreeAlloc (data);
  352. }
  353. AccessibilityMap++;
  354. }
  355. //
  356. // Put the emulated value in the hash table
  357. //
  358. wsprintf (buffer, TEXT("%u"), flags);
  359. pStoreEmulatedSetting (fullNtKey, TEXT("Flags"), REG_SZ, (PBYTE) buffer, SizeOfString (buffer));
  360. }
  361. __finally {
  362. if (key) {
  363. CloseRegKey (key);
  364. }
  365. }
  366. }
  367. VOID
  368. pFillTranslationTable (
  369. VOID
  370. )
  371. {
  372. PACCESSIBILITY_MAPPINGS mappings;
  373. //
  374. // Loop through all flags that need translation. Disable enumeration of
  375. // the Win9x physical values and enable enumeration of the translated values
  376. // via population of the hash table.
  377. //
  378. mappings = g_AccessibilityMappings;
  379. while (mappings->AccessibilityMap) {
  380. pTranslateAccessibilityKey (
  381. mappings->Win9xSubKey,
  382. mappings->NtSubKey ? mappings->NtSubKey : mappings->Win9xSubKey,
  383. mappings->AccessibilityMap
  384. );
  385. mappings++;
  386. }
  387. //
  388. // Add all keys that have moved, ordered from most specific to least specific
  389. //
  390. // AutoRepeat values are transposed
  391. pMoveAccessibilityValue (
  392. S_ACCESSIBILITY_ROOT TEXT("\\KeyboardResponse"), TEXT("AutoRepeatDelay"),
  393. S_ACCESSIBILITY_ROOT TEXT("\\Keyboard Response"), TEXT("AutoRepeatRate"),
  394. FALSE
  395. );
  396. pMoveAccessibilityValue (
  397. S_ACCESSIBILITY_ROOT TEXT("\\KeyboardResponse"), TEXT("AutoRepeatRate"),
  398. S_ACCESSIBILITY_ROOT TEXT("\\Keyboard Response"), TEXT("AutoRepeatDelay"),
  399. FALSE
  400. );
  401. // double c in DelayBeforeAcceptance value name
  402. pMoveAccessibilityValue (
  403. S_ACCESSIBILITY_ROOT TEXT("\\KeyboardResponse"), TEXT("DelayBeforeAcceptancce"),
  404. S_ACCESSIBILITY_ROOT TEXT("\\Keyboard Response"), TEXT("DelayBeforeAcceptance"),
  405. FALSE
  406. );
  407. // add a space to the key name for the rest of the values
  408. pMoveAccessibilityKey (
  409. S_ACCESSIBILITY_ROOT TEXT("\\KeyboardResponse"),
  410. S_ACCESSIBILITY_ROOT TEXT("\\Keyboard Response")
  411. );
  412. // change BaudRate to Baud & convert to DWORD
  413. pMoveAccessibilityValue (
  414. S_ACCESSIBILITY_ROOT TEXT("\\SerialKeys"), TEXT("BaudRate"),
  415. S_ACCESSIBILITY_ROOT TEXT("\\SerialKeys"), TEXT("Baud"),
  416. TRUE
  417. );
  418. // convert Flags to DWORD
  419. pMoveAccessibilityValue (
  420. S_ACCESSIBILITY_ROOT TEXT("\\SerialKeys"), TEXT("Flags"),
  421. S_ACCESSIBILITY_ROOT TEXT("\\SerialKeys"), TEXT("Flags"),
  422. TRUE
  423. );
  424. // add space between high and contrast
  425. pMoveAccessibilityValue (
  426. S_ACCESSIBILITY_ROOT TEXT("\\HighContrast"), TEXT("Pre-HighContrast Scheme"),
  427. S_ACCESSIBILITY_ROOT TEXT("\\HighContrast"), TEXT("Pre-High Contrast Scheme"),
  428. FALSE
  429. );
  430. // move two values from the root into their own subkeys
  431. pMoveAccessibilityValue (
  432. S_ACCESSIBILITY_ROOT, TEXT("Blind Access"),
  433. S_ACCESSIBILITY_ROOT TEXT("\\Blind Access"), TEXT("On"),
  434. FALSE
  435. );
  436. pStoreEmulatedSetting (S_ACCESSIBILITY_ROOT TEXT("\\Blind Access"), NULL, 0, NULL, 0);
  437. pMoveAccessibilityValue (
  438. S_ACCESSIBILITY_ROOT, TEXT("Keyboard Preference"),
  439. S_ACCESSIBILITY_ROOT TEXT("\\Keyboard Preference"), TEXT("On"),
  440. FALSE
  441. );
  442. pStoreEmulatedSetting (S_ACCESSIBILITY_ROOT TEXT("\\Keyboard Preference"), NULL, 0, NULL, 0);
  443. }
  444. BOOL
  445. WINAPI
  446. AccessibilityEtmInitialize (
  447. IN MIG_PLATFORMTYPEID Platform,
  448. IN PMIG_LOGCALLBACK LogCallback,
  449. IN PVOID Reserved
  450. )
  451. {
  452. MIG_OBJECTSTRINGHANDLE objectName;
  453. BOOL b = TRUE;
  454. LogReInit (NULL, NULL, NULL, (PLOGCALLBACK) LogCallback);
  455. if (ISWIN9X()) {
  456. g_RegistryTypeId = IsmGetObjectTypeId (S_REGISTRYTYPE);
  457. MYASSERT (g_RegistryTypeId);
  458. g_ProhibitTable = HtAlloc();
  459. MYASSERT (g_ProhibitTable);
  460. if (g_RegistryTypeId) {
  461. //
  462. // Add a callback for additional enumeration. If we are unable to do so, then
  463. // someone else is already doing something different for this key.
  464. //
  465. objectName = IsmCreateObjectHandle (S_ACCESSIBILITY_ROOT, NULL);
  466. b = IsmAddToPhysicalEnum (g_RegistryTypeId, objectName, EmulatedEnumCallback, 0);
  467. IsmDestroyObjectHandle (objectName);
  468. if (b) {
  469. //
  470. // Add a callback to acquire the data of the new physical objects
  471. //
  472. objectName = IsmCreateSimpleObjectPattern (
  473. S_ACCESSIBILITY_ROOT,
  474. TRUE,
  475. NULL,
  476. TRUE
  477. );
  478. b = IsmRegisterPhysicalAcquireHook (
  479. g_RegistryTypeId,
  480. objectName,
  481. AcquireAccessibilityFlags,
  482. ReleaseAccessibilityFlags,
  483. 0,
  484. NULL
  485. );
  486. IsmDestroyObjectHandle (objectName);
  487. }
  488. if (b) {
  489. //
  490. // Now load memdb with the current registry values and
  491. // prohibit the enumeration of Win9x values.
  492. //
  493. pFillTranslationTable ();
  494. }
  495. ELSE_DEBUGMSG ((DBG_WARNING, "Not allowed to translate accessibility key"));
  496. }
  497. HtFree (g_ProhibitTable);
  498. g_ProhibitTable = NULL;
  499. }
  500. return b;
  501. }
  502. BOOL
  503. WINAPI
  504. EmulatedEnumCallback (
  505. IN OUT PMIG_TYPEOBJECTENUM ObjectEnum,
  506. IN MIG_OBJECTSTRINGHANDLE Pattern,
  507. IN MIG_PARSEDPATTERN ParsedPattern,
  508. IN ULONG_PTR Arg,
  509. IN BOOL Abort
  510. )
  511. {
  512. PACCESSIBILITY_ENUM_STATE state = (PACCESSIBILITY_ENUM_STATE) ObjectEnum->EtmHandle;
  513. BOOL result = FALSE;
  514. BOOL cleanUpMemdb = TRUE;
  515. PCTSTR p;
  516. for (;;) {
  517. if (!Abort) {
  518. //
  519. // Begin or continue? If the EtmHandle is NULL, begin. Otherwise, continue.
  520. //
  521. if (!state) {
  522. state = (PACCESSIBILITY_ENUM_STATE) MemAllocUninit (sizeof (ACCESSIBILITY_ENUM_STATE));
  523. if (!state) {
  524. MYASSERT (FALSE);
  525. return FALSE;
  526. }
  527. ObjectEnum->EtmHandle = (LONG_PTR) state;
  528. result = MemDbEnumFirst (
  529. &state->EnumStruct,
  530. TEXT("~Accessibility\\*"),
  531. ENUMFLAG_NORMAL,
  532. 1,
  533. MEMDB_LAST_LEVEL
  534. );
  535. } else {
  536. result = MemDbEnumNext (&state->EnumStruct);
  537. }
  538. //
  539. // If an item was found, populate the enum struct. Otherwise, set
  540. // Abort to TRUE to clean up.
  541. //
  542. if (result) {
  543. //
  544. // Test against pattern
  545. //
  546. if (!IsmParsedPatternMatch (ParsedPattern, 0, state->EnumStruct.KeyName)) {
  547. continue;
  548. }
  549. MYASSERT ((ObjectEnum->ObjectTypeId & (~PLATFORM_MASK)) == g_RegistryTypeId);
  550. ObjectEnum->ObjectName = state->EnumStruct.KeyName;
  551. state->RegType = state->EnumStruct.Value;
  552. //
  553. // Fill in node, leaf and details
  554. //
  555. IsmDestroyObjectString (ObjectEnum->ObjectNode);
  556. IsmDestroyObjectString (ObjectEnum->ObjectLeaf);
  557. IsmReleaseMemory (ObjectEnum->NativeObjectName);
  558. IsmCreateObjectStringsFromHandle (
  559. ObjectEnum->ObjectName,
  560. &ObjectEnum->ObjectNode,
  561. &ObjectEnum->ObjectLeaf
  562. );
  563. MYASSERT (ObjectEnum->ObjectNode);
  564. ObjectEnum->Level = 0;
  565. p = _tcschr (ObjectEnum->ObjectNode, TEXT('\\'));
  566. while (p) {
  567. ObjectEnum->Level++;
  568. p = _tcschr (p + 1, TEXT('\\'));
  569. }
  570. ObjectEnum->SubLevel = 0;
  571. if (ObjectEnum->ObjectLeaf) {
  572. ObjectEnum->IsNode = FALSE;
  573. ObjectEnum->IsLeaf = TRUE;
  574. } else {
  575. ObjectEnum->IsNode = TRUE;
  576. ObjectEnum->IsLeaf = FALSE;
  577. }
  578. if (state->RegType) {
  579. ObjectEnum->Details.DetailsSize = sizeof (state->RegType);
  580. ObjectEnum->Details.DetailsData = &state->RegType;
  581. } else {
  582. ObjectEnum->Details.DetailsSize = 0;
  583. ObjectEnum->Details.DetailsData = NULL;
  584. }
  585. //
  586. // Rely on base type to get the native object name
  587. //
  588. ObjectEnum->NativeObjectName = IsmGetNativeObjectName (
  589. ObjectEnum->ObjectTypeId,
  590. ObjectEnum->ObjectName
  591. );
  592. } else {
  593. Abort = TRUE;
  594. cleanUpMemdb = FALSE;
  595. }
  596. }
  597. if (Abort) {
  598. //
  599. // Clean up our enum struct
  600. //
  601. if (state) {
  602. if (cleanUpMemdb) {
  603. MemDbAbortEnum (&state->EnumStruct);
  604. }
  605. IsmDestroyObjectString (ObjectEnum->ObjectNode);
  606. ObjectEnum->ObjectNode = NULL;
  607. IsmDestroyObjectString (ObjectEnum->ObjectLeaf);
  608. ObjectEnum->ObjectLeaf = NULL;
  609. IsmReleaseMemory (ObjectEnum->NativeObjectName);
  610. ObjectEnum->NativeObjectName = NULL;
  611. FreeAlloc (state);
  612. }
  613. // return value ignored in Abort case, and ObjectEnum is zeroed by the ISM
  614. }
  615. break;
  616. }
  617. return result;
  618. }
  619. BOOL
  620. WINAPI
  621. AcquireAccessibilityFlags(
  622. IN MIG_OBJECTSTRINGHANDLE ObjectName,
  623. IN PMIG_CONTENT ObjectContent,
  624. IN MIG_CONTENTTYPE ContentType,
  625. IN UINT MemoryContentLimit,
  626. OUT PMIG_CONTENT *NewObjectContent, CALLER_INITIALIZED OPTIONAL
  627. IN BOOL ReleaseContent,
  628. IN ULONG_PTR Arg
  629. )
  630. {
  631. BOOL result = TRUE;
  632. PDWORD details;
  633. PMIG_CONTENT ourContent;
  634. PCTSTR memdbNode;
  635. //
  636. // Is this object in our hash table?
  637. //
  638. if (ContentType == CONTENTTYPE_FILE) {
  639. DEBUGMSG ((DBG_ERROR, "Accessibility content cannot be saved to a file"));
  640. result = FALSE;
  641. } else {
  642. memdbNode = JoinPaths (TEXT("~Accessibility"), ObjectName);
  643. if (MemDbTestKey (memdbNode)) {
  644. //
  645. // Alloc updated content struct
  646. //
  647. ourContent = MemAllocZeroed (sizeof (MIG_CONTENT) + sizeof (DWORD));
  648. ourContent->EtmHandle = ourContent;
  649. details = (PDWORD) (ourContent + 1);
  650. //
  651. // Get the content from memdb
  652. //
  653. ourContent->MemoryContent.ContentBytes = MemDbGetUnorderedBlob (
  654. memdbNode,
  655. 0,
  656. &ourContent->MemoryContent.ContentSize
  657. );
  658. if (ourContent->MemoryContent.ContentBytes) {
  659. MemDbGetValue (memdbNode, details);
  660. ourContent->Details.DetailsSize = sizeof (DWORD);
  661. ourContent->Details.DetailsData = details;
  662. } else {
  663. ourContent->MemoryContent.ContentSize = 0;
  664. ourContent->Details.DetailsSize = 0;
  665. ourContent->Details.DetailsData = NULL;
  666. }
  667. ourContent->ContentInFile = FALSE;
  668. //
  669. // Pass it to ISM
  670. //
  671. *NewObjectContent = ourContent;
  672. }
  673. FreePathString (memdbNode);
  674. }
  675. return result; // always TRUE unless an error occurred
  676. }
  677. VOID
  678. WINAPI
  679. ReleaseAccessibilityFlags(
  680. IN PMIG_CONTENT ObjectContent
  681. )
  682. {
  683. //
  684. // This callback is called to free the content we allocated above.
  685. //
  686. if (ObjectContent->MemoryContent.ContentBytes) {
  687. MemDbReleaseMemory (ObjectContent->MemoryContent.ContentBytes);
  688. }
  689. FreeAlloc ((PMIG_CONTENT) ObjectContent->EtmHandle);
  690. }
  691. BOOL
  692. WINAPI
  693. AccessibilitySourceInitialize (
  694. IN PMIG_LOGCALLBACK LogCallback,
  695. IN PVOID Reserved
  696. )
  697. {
  698. LogReInit (NULL, NULL, NULL, (PLOGCALLBACK) LogCallback);
  699. if (!g_RegistryTypeId) {
  700. g_RegistryTypeId = IsmGetObjectTypeId (S_REGISTRYTYPE);
  701. }
  702. return TRUE;
  703. }