Windows NT 4.0 source code leak
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.

226 lines
5.4 KiB

4 years ago
  1. /****************************************************************************
  2. *
  3. * reslist.c
  4. *
  5. * Copyright (c) 1994 Microsoft Corporation. All Rights Reserved.
  6. *
  7. * This file contains code for querying the registry so that drivers
  8. * can grey invalid resource options prior to loading drivers
  9. *
  10. ****************************************************************************/
  11. #include <windows.h>
  12. #include "reslist.h"
  13. #include <registry.h>
  14. #include <stdio.h>
  15. typedef BOOL ENUMKEYSCALLBACK(PVOID, HKEY, LPTSTR);
  16. typedef BOOL ENUMKEYVALUESCALLBACK(PVOID, LPTSTR, DWORD, PVOID, DWORD);
  17. /*
  18. **
  19. **
  20. **
  21. */
  22. BOOL EnumKeys(HKEY hKey,
  23. LPTSTR KeyName,
  24. ENUMKEYSCALLBACK *Callback,
  25. PVOID Context
  26. )
  27. {
  28. HKEY SubKey;
  29. DWORD Index;
  30. TCHAR SubKeyName[MAX_PATH];
  31. if (ERROR_SUCCESS != RegOpenKey(hKey, KeyName, &SubKey)) {
  32. return FALSE;
  33. }
  34. for (Index = 0; ;Index++) {
  35. DWORD Rc;
  36. Rc = RegEnumKey(SubKey,
  37. Index,
  38. SubKeyName,
  39. MAX_PATH);
  40. if (Rc == ERROR_SUCCESS) {
  41. if (!(*Callback)(Context, SubKey, SubKeyName)) {
  42. RegCloseKey(SubKey);
  43. return FALSE;
  44. }
  45. } else {
  46. RegCloseKey(SubKey);
  47. return Rc == ERROR_NO_MORE_ITEMS;
  48. }
  49. }
  50. }
  51. BOOL EnumKeyValues(HKEY hKey,
  52. LPTSTR KeyName,
  53. ENUMKEYVALUESCALLBACK *Callback,
  54. PVOID Context
  55. )
  56. {
  57. HKEY SubKey;
  58. DWORD Index;
  59. TCHAR ValueName[MAX_PATH];
  60. if (ERROR_SUCCESS != RegOpenKey(hKey, KeyName, &SubKey)) {
  61. return FALSE;
  62. }
  63. for (Index = 0; ;Index++) {
  64. DWORD Rc;
  65. DWORD Type;
  66. DWORD cchName;
  67. DWORD ccbData;
  68. cchName = MAX_PATH;
  69. Rc = RegEnumValue(SubKey,
  70. Index,
  71. ValueName,
  72. &cchName,
  73. NULL,
  74. &Type,
  75. NULL,
  76. &ccbData);
  77. if (Rc == ERROR_SUCCESS) {
  78. PBYTE pData;
  79. pData = (PBYTE)LocalAlloc(LPTR, ccbData);
  80. if (pData == NULL) {
  81. RegCloseKey(SubKey);
  82. return FALSE;
  83. }
  84. Rc = RegQueryValueEx(SubKey,
  85. ValueName,
  86. NULL,
  87. &Type,
  88. pData,
  89. &ccbData);
  90. if (ERROR_SUCCESS != Rc ||
  91. !(*Callback)(Context, ValueName, Type, pData, ccbData)) {
  92. LocalFree((HLOCAL)pData);
  93. RegCloseKey(SubKey);
  94. return FALSE;
  95. }
  96. LocalFree((HLOCAL)pData);
  97. } else {
  98. RegCloseKey(SubKey);
  99. return Rc == ERROR_NO_MORE_ITEMS;
  100. }
  101. }
  102. }
  103. BOOL EnumerateDrivers(PVOID Context, HKEY hKey, LPTSTR SubKeyName)
  104. {
  105. PRESOURCE_INFO ResInfo = (PRESOURCE_INFO)Context;
  106. if (ResInfo->IgnoreDriver != NULL &&
  107. lstrcmpi(SubKeyName, ResInfo->IgnoreDriver) == 0) {
  108. return TRUE;
  109. }
  110. ResInfo->DriverName = SubKeyName;
  111. return EnumKeyValues(hKey, SubKeyName, EnumerateDevices, Context);
  112. }
  113. BOOL EnumerateDriverTypes(PVOID Context, HKEY hKey, LPTSTR SubKeyName)
  114. {
  115. PRESOURCE_INFO ResInfo = (PRESOURCE_INFO)Context;
  116. ResInfo->DriverType = SubKeyName;
  117. return EnumKeys(hKey, SubKeyName, EnumerateDrivers, Context);
  118. }
  119. BOOL EnumResources(ENUMRESOURCECALLBACK Callback, PVOID Context, LPCTSTR IgnoreDriver)
  120. {
  121. HKEY hKey;
  122. RESOURCE_INFO ResInfo;
  123. ResInfo.AppContext = Context;
  124. ResInfo.AppCallback = Callback;
  125. ResInfo.IgnoreDriver = IgnoreDriver;
  126. /*
  127. ** Open the resources registry key then recursively enumerate
  128. ** all resource lists
  129. */
  130. return EnumKeys(HKEY_LOCAL_MACHINE,
  131. TEXT("HARDWARE\\RESOURCEMAP"),
  132. EnumerateDriverTypes,
  133. (PVOID)&ResInfo);
  134. }
  135. /*
  136. ** Build a simple routine to find what interrupts and DMA channels
  137. ** are in use
  138. */
  139. typedef struct {
  140. DD_BUS_TYPE MinBusType;
  141. DWORD Interrupts[DD_NumberOfBusTypes];
  142. DWORD DmaChannels[DD_NumberOfBusTypes];
  143. } INTERRUPTS_AND_DMA, *PINTERRUPTS_AND_DMA;
  144. BOOL GetInterruptsAndDMACallback(
  145. PVOID Context,
  146. DD_BUS_TYPE BusType,
  147. DD_RESOURCE_TYPE ResourceType,
  148. PDD_CONFIG_DATA ConfigData
  149. )
  150. {
  151. PINTERRUPTS_AND_DMA pData;
  152. pData = Context;
  153. if (pData->MinBusType > BusType) {
  154. pData->MinBusType = BusType;
  155. }
  156. switch (ResourceType) {
  157. case DD_Interrupt:
  158. pData->Interrupts[BusType] |= 1 << ConfigData->Interrupt;
  159. break;
  160. case DD_DmaChannel:
  161. pData->DmaChannels[BusType] |= 1 << ConfigData->DmaChannel;
  162. break;
  163. break;
  164. }
  165. return TRUE;
  166. }
  167. BOOL GetInterruptsAndDMA(
  168. LPDWORD InterruptsInUse,
  169. LPDWORD DmaChannelsInUse,
  170. LPCTSTR IgnoreDriver
  171. )
  172. {
  173. INTERRUPTS_AND_DMA Data;
  174. ZeroMemory((PVOID)&Data, sizeof(Data));
  175. Data.MinBusType = DD_NumberOfBusTypes;
  176. EnumResources(GetInterruptsAndDMACallback, &Data, IgnoreDriver);
  177. if (Data.MinBusType == DD_NumberOfBusTypes) {
  178. return FALSE;
  179. }
  180. *InterruptsInUse = Data.Interrupts[Data.MinBusType];
  181. *DmaChannelsInUse = Data.DmaChannels[Data.MinBusType];
  182. return TRUE;
  183. }