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.

233 lines
6.8 KiB

  1. /****************************** Module Header ******************************\
  2. * Module Name: notify.c
  3. *
  4. * Copyright (c) 1992, Microsoft Corporation
  5. *
  6. * Handles notification of key value changes in the registry that affect
  7. * the Program Manager.
  8. *
  9. * History:
  10. * 04-16-92 JohanneC Created.
  11. \***************************************************************************/
  12. #include "progman.h"
  13. BOOL InHandleProgramGroupsEvent = FALSE;
  14. BOOL bHandleProgramGroupsEvent = TRUE;
  15. //
  16. // 2 watch events: common groups key & personal groups key
  17. //
  18. HANDLE gahEvents[2];
  19. HANDLE hEventCommonGroups;
  20. HANDLE hEventPersGroups;
  21. HANDLE hEventGroupValueSet;
  22. HANDLE hChangeNotifyThread;
  23. /***************************************************************************\
  24. *
  25. *
  26. *
  27. * History:
  28. * 04-16-91 Johannec Created
  29. \***************************************************************************/
  30. BOOL APIENTRY InitializeGroupKeyNotification()
  31. {
  32. hEventCommonGroups = CreateEvent(NULL, FALSE, FALSE, NULL);
  33. hEventPersGroups = CreateEvent(NULL, FALSE, FALSE, NULL);
  34. hEventGroupValueSet = CreateEvent(NULL, FALSE, FALSE,
  35. TEXT(" Progman.GroupValueSet"));
  36. gahEvents[0] = hEventPersGroups;
  37. gahEvents[1] = hEventCommonGroups;
  38. if (hEventPersGroups && hkeyProgramGroups) {
  39. RegNotifyChangeKeyValue(hkeyProgramGroups, TRUE, REG_NOTIFY_CHANGE_NAME,
  40. hEventPersGroups, TRUE);
  41. }
  42. if (hEventCommonGroups && hkeyCommonGroups) {
  43. RegNotifyChangeKeyValue(hkeyCommonGroups, TRUE, REG_NOTIFY_CHANGE_NAME,
  44. hEventCommonGroups, TRUE);
  45. }
  46. if (!hEventCommonGroups && !hEventPersGroups) {
  47. return(FALSE);
  48. }
  49. return(TRUE);
  50. }
  51. VOID APIENTRY ResetProgramGroupsEvent(BOOL bCommonGroup)
  52. {
  53. if (bCommonGroup) {
  54. if (hEventCommonGroups && hkeyCommonGroups) {
  55. ResetEvent(hEventCommonGroups);
  56. RegNotifyChangeKeyValue(hkeyCommonGroups, TRUE, REG_NOTIFY_CHANGE_NAME,
  57. hEventCommonGroups, TRUE);
  58. }
  59. }
  60. else {
  61. if (hEventPersGroups && hkeyProgramGroups) {
  62. ResetEvent(hEventPersGroups);
  63. RegNotifyChangeKeyValue(hkeyProgramGroups, TRUE, REG_NOTIFY_CHANGE_NAME,
  64. hEventPersGroups, TRUE);
  65. }
  66. }
  67. }
  68. /***************************************************************************\
  69. *
  70. *
  71. *
  72. *
  73. * History:
  74. * 04-16-91 Johannec Created
  75. \***************************************************************************/
  76. VOID HandleGroupKeyChange(BOOL bCommonGroup)
  77. {
  78. int i = 0;
  79. DWORD cbGroupKey = MAXKEYLEN;
  80. TCHAR szGroupKey[MAXKEYLEN];
  81. FILETIME ft;
  82. HWND hwndT;
  83. PGROUP pGroup;
  84. PGROUP *ppGroup;
  85. PITEM pItem;
  86. HKEY hkeyGroups;
  87. HKEY hkey;
  88. TCHAR szT[10];
  89. if (InHandleProgramGroupsEvent || !bHandleProgramGroupsEvent) {
  90. goto RegNotify;
  91. }
  92. InHandleProgramGroupsEvent = TRUE;
  93. if (bCommonGroup) {
  94. hkeyGroups = hkeyCommonGroups;
  95. }
  96. else {
  97. hkeyGroups = hkeyProgramGroups;
  98. }
  99. while (!RegEnumKeyEx(hkeyGroups, i, szGroupKey, &cbGroupKey, 0, 0, 0, &ft)) {
  100. if (cbGroupKey) {
  101. /* Search for the group... if it already exists, activate it. */
  102. hwndT = GetWindow(hwndMDIClient, GW_CHILD);
  103. while (hwndT) {
  104. /* Skip icon titles. */
  105. if (!GetWindow(hwndT, GW_OWNER)) {
  106. /* Compare the group title with the request. */
  107. pGroup = (PGROUP)GetWindowLongPtr(hwndT,GWLP_PGROUP);
  108. if (!lstrcmpi(szGroupKey, pGroup->lpKey)) {
  109. if (pGroup->fCommon && bCommonGroup ||
  110. !pGroup->fCommon && !bCommonGroup)
  111. break;
  112. }
  113. }
  114. hwndT = GetWindow(hwndT, GW_HWNDNEXT);
  115. }
  116. /* If we didn't find it, load it. */
  117. if (!hwndT) {
  118. //
  119. // Wait until the value is set before loading the group.
  120. //
  121. WaitForSingleObject(hEventGroupValueSet, 300);
  122. ResetEvent(hEventGroupValueSet);
  123. LoadGroupWindow(szGroupKey, 0, bCommonGroup);
  124. }
  125. }
  126. i++;
  127. cbGroupKey = MAXKEYLEN;
  128. }
  129. //
  130. // Test if any groups were deleted through regedt32.exe.
  131. //
  132. for (hwndT = GetWindow(hwndMDIClient, GW_CHILD);
  133. hwndT;
  134. hwndT = GetWindow(hwndT, GW_HWNDNEXT)) {
  135. /* Skip icon titles. */
  136. if (GetWindow(hwndT, GW_OWNER))
  137. continue;
  138. /* Compare the group title with the request. */
  139. pGroup = (PGROUP)GetWindowLongPtr(hwndT, GWLP_PGROUP);
  140. if ( (pGroup->fCommon && !bCommonGroup) ||
  141. (!pGroup->fCommon && bCommonGroup) ) {
  142. continue;
  143. }
  144. if (RegOpenKey(hkeyGroups, pGroup->lpKey, &hkey) == ERROR_SUCCESS) {
  145. RegCloseKey(hkey);
  146. }
  147. else {
  148. //
  149. // Couldn't find the group in the registry so delete it
  150. // in progman.
  151. //
  152. /* Destroy the window, the global memory block, and the file. */
  153. SendMessage(hwndMDIClient, WM_MDIDESTROY, (WPARAM)hwndT, 0L);
  154. NukeIconBitmap(pGroup);
  155. GlobalFree(pGroup->hGroup);
  156. if (!bCommonGroup) {
  157. //
  158. // Remove the program manager's settings for that personal group.
  159. //
  160. wsprintf(szT,TEXT("Group%d"),pGroup->wIndex);
  161. RegDeleteValue(hkeyPMGroups, szT);
  162. }
  163. /* Unlink the group structure. */
  164. for (ppGroup=&pFirstGroup; *ppGroup && *ppGroup != pGroup; ppGroup = &(*ppGroup)->pNext)
  165. ;
  166. if (*ppGroup)
  167. *ppGroup = pGroup->pNext;
  168. if (pLastGroup == &pGroup->pNext)
  169. pLastGroup = ppGroup;
  170. /* Destroying the window should activate another one, but if it is the
  171. * last one, nothing will get activated, so to make sure punt the
  172. * current group pointer...
  173. */
  174. if (pCurrentGroup == pGroup)
  175. pCurrentGroup = NULL;
  176. /* Lastly, toss out the group and item structures. */
  177. while (pGroup->pItems) {
  178. pItem = pGroup->pItems;
  179. pGroup->pItems = pItem->pNext;
  180. LocalFree((HANDLE)pItem);
  181. }
  182. LocalFree((HANDLE)pGroup->lpKey);
  183. LocalFree((HANDLE)pGroup);
  184. if (!bCommonGroup) {
  185. //
  186. // Change the program manager's settings for that personal group.
  187. //
  188. WriteGroupsSection();
  189. }
  190. }
  191. }
  192. RegNotify:
  193. ResetProgramGroupsEvent(bCommonGroup);
  194. InHandleProgramGroupsEvent = FALSE;
  195. }