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.

417 lines
12 KiB

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