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.

403 lines
11 KiB

  1. /*++
  2. Copyright (c) 1991, 1992, 1993 Microsoft Corporation
  3. Module Name:
  4. registry.c
  5. Abstract:
  6. This module contains the code that is used to get values from the
  7. registry and to manipulate entries in the registry.
  8. Author:
  9. Anthony V. Ercolano 26-Sep-1991
  10. Environment:
  11. Kernel mode
  12. Revision History :
  13. --*/
  14. #include "precomp.h"
  15. #ifdef ALLOC_PRAGMA
  16. #pragma alloc_text(INIT,SerialGetConfigDefaults)
  17. #pragma alloc_text(PAGESRP0,SerialGetRegistryKeyValue)
  18. #pragma alloc_text(PAGESRP0,SerialPutRegistryKeyValue)
  19. #endif // ALLOC_PRAGMA
  20. NTSTATUS
  21. SerialGetConfigDefaults(
  22. IN PSERIAL_FIRMWARE_DATA DriverDefaultsPtr,
  23. IN PUNICODE_STRING RegistryPath
  24. )
  25. /*++
  26. Routine Description:
  27. This routine reads the default configuration data from the
  28. registry for the serial driver.
  29. It also builds fields in the registry for several configuration
  30. options if they don't exist.
  31. Arguments:
  32. DriverDefaultsPtr - Pointer to a structure that will contain
  33. the default configuration values.
  34. RegistryPath - points to the entry for this driver in the
  35. current control set of the registry.
  36. Return Value:
  37. STATUS_SUCCESS if we got the defaults, otherwise we failed.
  38. The only way to fail this call is if the STATUS_INSUFFICIENT_RESOURCES.
  39. --*/
  40. {
  41. NTSTATUS Status = STATUS_SUCCESS; // return value
  42. //
  43. // We use this to query into the registry for defaults
  44. //
  45. RTL_QUERY_REGISTRY_TABLE paramTable[8];
  46. PWCHAR path;
  47. ULONG zero = 0;
  48. ULONG DbgDefault = 0;//SER_DBG_DEFAULT;
  49. ULONG notThereDefault = SERIAL_UNINITIALIZED_DEFAULT;
  50. PAGED_CODE();
  51. //
  52. // Since the registry path parameter is a "counted" UNICODE string, it
  53. // might not be zero terminated. For a very short time allocate memory
  54. // to hold the registry path zero terminated so that we can use it to
  55. // delve into the registry.
  56. //
  57. // NOTE NOTE!!!! This is not an architected way of breaking into
  58. // a driver. It happens to work for this driver because the author
  59. // likes to do things this way.
  60. //
  61. path = ExAllocatePool (PagedPool, RegistryPath->Length+sizeof(WCHAR));
  62. if (!path) {
  63. Status = STATUS_INSUFFICIENT_RESOURCES;
  64. return (Status);
  65. }
  66. RtlZeroMemory (DriverDefaultsPtr, sizeof(SERIAL_FIRMWARE_DATA));
  67. RtlZeroMemory (&paramTable[0], sizeof(paramTable));
  68. RtlZeroMemory (path, RegistryPath->Length+sizeof(WCHAR));
  69. RtlMoveMemory (path, RegistryPath->Buffer, RegistryPath->Length);
  70. paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
  71. paramTable[0].Name = L"BreakOnEntry";
  72. paramTable[0].EntryContext = &DriverDefaultsPtr->ShouldBreakOnEntry;
  73. paramTable[0].DefaultType = REG_DWORD;
  74. paramTable[0].DefaultData = &zero;
  75. paramTable[0].DefaultLength = sizeof(ULONG);
  76. paramTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT;
  77. paramTable[1].Name = L"DebugLevel";
  78. paramTable[1].EntryContext = &DriverDefaultsPtr->DebugLevel;
  79. paramTable[1].DefaultType = REG_DWORD;
  80. paramTable[1].DefaultData = &DbgDefault;
  81. paramTable[1].DefaultLength = sizeof(ULONG);
  82. paramTable[2].Flags = RTL_QUERY_REGISTRY_DIRECT;
  83. paramTable[2].Name = L"ForceFifoEnable";
  84. paramTable[2].EntryContext = &DriverDefaultsPtr->ForceFifoEnableDefault;
  85. paramTable[2].DefaultType = REG_DWORD;
  86. paramTable[2].DefaultData = &notThereDefault;
  87. paramTable[2].DefaultLength = sizeof(ULONG);
  88. paramTable[3].Flags = RTL_QUERY_REGISTRY_DIRECT;
  89. paramTable[3].Name = L"RxFIFO";
  90. paramTable[3].EntryContext = &DriverDefaultsPtr->RxFIFODefault;
  91. paramTable[3].DefaultType = REG_DWORD;
  92. paramTable[3].DefaultData = &notThereDefault;
  93. paramTable[3].DefaultLength = sizeof(ULONG);
  94. paramTable[4].Flags = RTL_QUERY_REGISTRY_DIRECT;
  95. paramTable[4].Name = L"TxFIFO";
  96. paramTable[4].EntryContext = &DriverDefaultsPtr->TxFIFODefault;
  97. paramTable[4].DefaultType = REG_DWORD;
  98. paramTable[4].DefaultData = &notThereDefault;
  99. paramTable[4].DefaultLength = sizeof(ULONG);
  100. paramTable[5].Flags = RTL_QUERY_REGISTRY_DIRECT;
  101. paramTable[5].Name = L"PermitShare";
  102. paramTable[5].EntryContext = &DriverDefaultsPtr->PermitShareDefault;
  103. paramTable[5].DefaultType = REG_DWORD;
  104. paramTable[5].DefaultData = &notThereDefault;
  105. paramTable[5].DefaultLength = sizeof(ULONG);
  106. paramTable[6].Flags = RTL_QUERY_REGISTRY_DIRECT;
  107. paramTable[6].Name = L"LogFifo";
  108. paramTable[6].EntryContext = &DriverDefaultsPtr->LogFifoDefault;
  109. paramTable[6].DefaultType = REG_DWORD;
  110. paramTable[6].DefaultData = &notThereDefault;
  111. paramTable[6].DefaultLength = sizeof(ULONG);
  112. Status = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
  113. path,
  114. &paramTable[0],
  115. NULL,
  116. NULL);
  117. if (!NT_SUCCESS(Status)) {
  118. DriverDefaultsPtr->ShouldBreakOnEntry = 0;
  119. DriverDefaultsPtr->DebugLevel = 0;
  120. }
  121. //
  122. // Check to see if there was a forcefifo or an rxfifo size.
  123. // If there isn't then write out values so that they could
  124. // be adjusted later.
  125. //
  126. if (DriverDefaultsPtr->ForceFifoEnableDefault == notThereDefault) {
  127. DriverDefaultsPtr->ForceFifoEnableDefault = SERIAL_FORCE_FIFO_DEFAULT;
  128. RtlWriteRegistryValue(
  129. RTL_REGISTRY_ABSOLUTE,
  130. path,
  131. L"ForceFifoEnable",
  132. REG_DWORD,
  133. &DriverDefaultsPtr->ForceFifoEnableDefault,
  134. sizeof(ULONG)
  135. );
  136. }
  137. if (DriverDefaultsPtr->RxFIFODefault == notThereDefault) {
  138. DriverDefaultsPtr->RxFIFODefault = SERIAL_RX_FIFO_DEFAULT;
  139. RtlWriteRegistryValue(
  140. RTL_REGISTRY_ABSOLUTE,
  141. path,
  142. L"RxFIFO",
  143. REG_DWORD,
  144. &DriverDefaultsPtr->RxFIFODefault,
  145. sizeof(ULONG)
  146. );
  147. }
  148. if (DriverDefaultsPtr->TxFIFODefault == notThereDefault) {
  149. DriverDefaultsPtr->TxFIFODefault = SERIAL_TX_FIFO_DEFAULT;
  150. RtlWriteRegistryValue(
  151. RTL_REGISTRY_ABSOLUTE,
  152. path,
  153. L"TxFIFO",
  154. REG_DWORD,
  155. &DriverDefaultsPtr->TxFIFODefault,
  156. sizeof(ULONG)
  157. );
  158. }
  159. if (DriverDefaultsPtr->PermitShareDefault == notThereDefault) {
  160. DriverDefaultsPtr->PermitShareDefault = SERIAL_PERMIT_SHARE_DEFAULT;
  161. //
  162. // Only share if the user actual changes switch.
  163. //
  164. RtlWriteRegistryValue(
  165. RTL_REGISTRY_ABSOLUTE,
  166. path,
  167. L"PermitShare",
  168. REG_DWORD,
  169. &DriverDefaultsPtr->PermitShareDefault,
  170. sizeof(ULONG)
  171. );
  172. }
  173. if (DriverDefaultsPtr->LogFifoDefault == notThereDefault) {
  174. //
  175. // Wasn't there. After this load don't log
  176. // the message anymore. However this first
  177. // time log the message.
  178. //
  179. DriverDefaultsPtr->LogFifoDefault = SERIAL_LOG_FIFO_DEFAULT;
  180. RtlWriteRegistryValue(
  181. RTL_REGISTRY_ABSOLUTE,
  182. path,
  183. L"LogFifo",
  184. REG_DWORD,
  185. &DriverDefaultsPtr->LogFifoDefault,
  186. sizeof(ULONG)
  187. );
  188. DriverDefaultsPtr->LogFifoDefault = 1;
  189. }
  190. //
  191. // We don't need that path anymore.
  192. //
  193. if (path) {
  194. ExFreePool(path);
  195. }
  196. //
  197. // Set the defaults for other values
  198. //
  199. DriverDefaultsPtr->PermitSystemWideShare = FALSE;
  200. return (Status);
  201. }
  202. NTSTATUS
  203. SerialGetRegistryKeyValue (
  204. IN HANDLE Handle,
  205. IN PWCHAR KeyNameString,
  206. IN ULONG KeyNameStringLength,
  207. IN PVOID Data,
  208. IN ULONG DataLength
  209. )
  210. /*++
  211. Routine Description:
  212. Reads a registry key value from an already opened registry key.
  213. Arguments:
  214. Handle Handle to the opened registry key
  215. KeyNameString ANSI string to the desired key
  216. KeyNameStringLength Length of the KeyNameString
  217. Data Buffer to place the key value in
  218. DataLength Length of the data buffer
  219. Return Value:
  220. STATUS_SUCCESS if all works, otherwise status of system call that
  221. went wrong.
  222. --*/
  223. {
  224. UNICODE_STRING keyName;
  225. ULONG length;
  226. PKEY_VALUE_FULL_INFORMATION fullInfo;
  227. NTSTATUS ntStatus = STATUS_INSUFFICIENT_RESOURCES;
  228. PAGED_CODE();
  229. SerialDump(SERTRACECALLS, ("SERIAL: Enter SerialGetRegistryKeyValue\n"));
  230. RtlInitUnicodeString (&keyName, KeyNameString);
  231. length = sizeof(KEY_VALUE_FULL_INFORMATION) + KeyNameStringLength
  232. + DataLength;
  233. fullInfo = ExAllocatePool(PagedPool, length);
  234. if (fullInfo) {
  235. ntStatus = ZwQueryValueKey (Handle,
  236. &keyName,
  237. KeyValueFullInformation,
  238. fullInfo,
  239. length,
  240. &length);
  241. if (NT_SUCCESS(ntStatus)) {
  242. //
  243. // If there is enough room in the data buffer, copy the output
  244. //
  245. if (DataLength >= fullInfo->DataLength) {
  246. RtlCopyMemory (Data,
  247. ((PUCHAR) fullInfo) + fullInfo->DataOffset,
  248. fullInfo->DataLength);
  249. }
  250. }
  251. ExFreePool(fullInfo);
  252. }
  253. return ntStatus;
  254. }
  255. NTSTATUS
  256. SerialPutRegistryKeyValue(IN HANDLE Handle, IN PWCHAR PKeyNameString,
  257. IN ULONG KeyNameStringLength, IN ULONG Dtype,
  258. IN PVOID PData, IN ULONG DataLength)
  259. /*++
  260. Routine Description:
  261. Writes a registry key value to an already opened registry key.
  262. Arguments:
  263. Handle Handle to the opened registry key
  264. PKeyNameString ANSI string to the desired key
  265. KeyNameStringLength Length of the KeyNameString
  266. Dtype REG_XYZ value type
  267. PData Buffer to place the key value in
  268. DataLength Length of the data buffer
  269. Return Value:
  270. STATUS_SUCCESS if all works, otherwise status of system call that
  271. went wrong.
  272. --*/
  273. {
  274. NTSTATUS status;
  275. UNICODE_STRING keyname;
  276. PAGED_CODE();
  277. SerialDump(SERTRACECALLS,("SERIAL: Enter SerialPutRegistryKeyValue\n"));
  278. RtlInitUnicodeString(&keyname, NULL);
  279. keyname.MaximumLength = (USHORT)(KeyNameStringLength + sizeof(WCHAR));
  280. keyname.Buffer = ExAllocatePool(PagedPool, keyname.MaximumLength);
  281. if (keyname.Buffer == NULL) {
  282. return STATUS_INSUFFICIENT_RESOURCES;
  283. }
  284. RtlAppendUnicodeToString(&keyname, PKeyNameString);
  285. status = ZwSetValueKey(Handle, &keyname, 0, Dtype, PData, DataLength);
  286. ExFreePool(keyname.Buffer);
  287. return status;
  288. }