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.

413 lines
11 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. DevCtrl.c
  5. Abstract:
  6. This module implements the File System Device Control routines for Rx
  7. called by the dispatch driver.
  8. Author:
  9. Revision History:
  10. Balan Sethu Raman [19-July-95] -- Hook it up to the mini rdr call down.
  11. --*/
  12. #include "precomp.h"
  13. #pragma hdrstop
  14. #include "ntddmup.h"
  15. //
  16. // The local debug trace level
  17. //
  18. #define Dbg (DEBUG_TRACE_DEVCTRL)
  19. NTSTATUS
  20. RxLowIoIoCtlShellCompletion( RXCOMMON_SIGNATURE );
  21. #ifdef ALLOC_PRAGMA
  22. #pragma alloc_text(PAGE, RxCommonDeviceControl)
  23. #pragma alloc_text(PAGE, RxLowIoIoCtlShellCompletion)
  24. #endif
  25. NTSTATUS
  26. RxCommonDeviceControl ( RXCOMMON_SIGNATURE )
  27. /*++
  28. Routine Description:
  29. This is the common routine for doing Device control operations called
  30. by both the fsd and fsp threads
  31. Arguments:
  32. Irp - Supplies the Irp to process
  33. InFsp - Indicates if this is the fsp thread or someother thread
  34. Return Value:
  35. RXSTATUS - The return status for the operation
  36. --*/
  37. {
  38. NTSTATUS Status;
  39. RxCaptureRequestPacket;
  40. //RxCaptureFcb;
  41. //RxCaptureFobx;
  42. RxCaptureParamBlock;
  43. //RxCaptureFileObject;
  44. //NODE_TYPE_CODE TypeOfOpen = NodeType(capFcb);
  45. BOOLEAN SubmitLowIoRequest = TRUE;
  46. ULONG IoControlCode = capPARAMS->Parameters.DeviceIoControl.IoControlCode;
  47. PAGED_CODE();
  48. RxDbgTrace(+1, Dbg, ("RxCommonDeviceControl\n", 0));
  49. RxDbgTrace( 0, Dbg, ("Irp = %08lx\n", capReqPacket));
  50. RxDbgTrace( 0, Dbg, ("MinorFunction = %08lx\n", capPARAMS->MinorFunction));
  51. //
  52. //
  53. if (IoControlCode == IOCTL_REDIR_QUERY_PATH) {
  54. Status = (STATUS_INVALID_DEVICE_REQUEST);
  55. SubmitLowIoRequest = FALSE;
  56. }
  57. if (SubmitLowIoRequest) {
  58. RxInitializeLowIoContext(&RxContext->LowIoContext,LOWIO_OP_IOCTL);
  59. Status = RxLowIoSubmit(RxContext,RxLowIoIoCtlShellCompletion);
  60. }
  61. RxDbgTrace(-1, Dbg, ("RxCommonDeviceControl -> %08lx\n", Status));
  62. return Status;
  63. }
  64. NTSTATUS
  65. RxLowIoIoCtlShellCompletion( RXCOMMON_SIGNATURE )
  66. /*++
  67. Routine Description:
  68. This is the completion routine for IoCtl requests passed down to the mini rdr
  69. Arguments:
  70. Irp - Supplies the Irp being processed
  71. Return Value:
  72. RXSTATUS - The return status for the operation
  73. --*/
  74. {
  75. RxCaptureRequestPacket;
  76. //RxCaptureFcb;
  77. //RxCaptureFobx;
  78. //RxCaptureParamBlock;
  79. //RxCaptureFileObject;
  80. NTSTATUS Status = STATUS_SUCCESS;
  81. //NODE_TYPE_CODE TypeOfOpen = NodeType(capFcb);
  82. PLOWIO_CONTEXT pLowIoContext = &RxContext->LowIoContext;
  83. //ULONG FsControlCode = capPARAMS->Parameters.FileSystemControl.FsControlCode;
  84. PAGED_CODE();
  85. Status = RxContext->StoredStatus;
  86. RxDbgTrace(+1, Dbg, ("RxLowIoIoCtlShellCompletion entry Status = %08lx\n", Status));
  87. switch (Status) { //maybe success vs warning vs error
  88. case STATUS_SUCCESS:
  89. case STATUS_BUFFER_OVERFLOW:
  90. //capReqPacket->IoStatus.Information = pLowIoContext->ParamsFor.IoCtl.OutputBufferLength;
  91. capReqPacket->IoStatus.Information = RxContext->InformationToReturn;
  92. break;
  93. //case STATUS(CONNECTION_INVALID:
  94. default:
  95. break;
  96. }
  97. capReqPacket->IoStatus.Status = Status;
  98. RxDbgTrace(-1, Dbg, ("RxLowIoIoCtlShellCompletion exit Status = %08lx\n", Status));
  99. return Status;
  100. }
  101. #if 0
  102. THIS CODE IS NOT USED CURRENTLY....IT'S BEING SAVED HERE TO MAP OVER TO HAVING RDBSS LOAD/UNLOAD EACH MINIRDR UNDER IOCTL
  103. NTSTATUS
  104. RxLoadMiniRdrs(
  105. IN PUNICODE_STRING RegistryPath
  106. );
  107. VOID
  108. RxUnloadMiniRdrs(
  109. void
  110. );
  111. NTSYSAPI
  112. NTSTATUS
  113. NTAPI
  114. ZwLoadDriver(
  115. IN PUNICODE_STRING DriverServiceName
  116. );
  117. NTSYSAPI
  118. NTSTATUS
  119. NTAPI
  120. ZwUnloadDriver(
  121. IN PUNICODE_STRING DriverServiceName
  122. );
  123. PWCHAR RxMiniRdrInfo = NULL;
  124. ULONG RxMiniRdrsLoaded = 0;
  125. //CODE.IMPROVEMENT this should be allocated dynamically
  126. #define MAXIMUM_NUMBER_OF_MINIRDRS 16
  127. UNICODE_STRING RxLoadedDrivers[MAXIMUM_NUMBER_OF_MINIRDRS];
  128. PWCHAR RxLoadedDriversNameBuffer = NULL;
  129. ULONG RxNextDriverLoaded = 0;
  130. NTSTATUS
  131. RxFabricateRegistryStringZZ(
  132. IN OUT PUNICODE_STRING RegistryNameString,
  133. IN PUNICODE_STRING DriverName,
  134. IN OUT PVOID Buffer,
  135. IN ULONG BufferLength
  136. )
  137. {
  138. UNICODE_STRING RegistryServicePrefix;
  139. NTSTATUS Status;
  140. RegistryNameString->Buffer = (PWCHAR)Buffer;
  141. RegistryNameString->MaximumLength = (USHORT)BufferLength;
  142. RtlInitUnicodeString(&RegistryServicePrefix, SERVICE_REGISTRY_KEY);
  143. RtlCopyUnicodeString(RegistryNameString,&RegistryServicePrefix);
  144. Status = RtlAppendUnicodeStringToString(RegistryNameString,DriverName);
  145. return(Status);
  146. }
  147. NTSTATUS
  148. RxLoadMiniRdrs(
  149. IN PUNICODE_STRING RegistryPath
  150. )
  151. /*++
  152. Routine Description:
  153. This routine does an enumeration from the registry to load the minirdrs. It saves what it finds so it
  154. can unload them later. It also initializes the structures that are used to scan over minirdrs.......
  155. Arguments:
  156. None.
  157. Return Value:
  158. STATUS_SUCCESS if at least one minirdr was loaded
  159. STATUS_INSUFFICIENT_RESOURCES if the buffer to save the names could not be allocated
  160. STATUS_UNSUCCESSFUL if no minirdrs were loaded
  161. --*/
  162. {
  163. ULONG Storage[256];
  164. WCHAR ServiceNameRegistryStringBuffer[256]; //bugbug allocate this!
  165. UNICODE_STRING UnicodeString;
  166. PCHAR NextNameBufferPosition;
  167. HANDLE RdbssHandle = INVALID_HANDLE_VALUE;
  168. HANDLE MiniRdrsHandle = INVALID_HANDLE_VALUE;
  169. NTSTATUS Status;
  170. KEY_FULL_INFORMATION KeyInformation;
  171. PKEY_VALUE_BASIC_INFORMATION ValueInformation;
  172. ULONG DummyLength,Index;
  173. //ULONG BytesRead;
  174. OBJECT_ATTRIBUTES ObjectAttributes;
  175. //PKEY_VALUE_FULL_INFORMATION Value = (PKEY_VALUE_FULL_INFORMATION)Storage;
  176. DbgPrint("here we go\n");
  177. InitializeObjectAttributes(
  178. &ObjectAttributes,
  179. RegistryPath, // name
  180. OBJ_CASE_INSENSITIVE, // attributes
  181. NULL, // root
  182. NULL // security descriptor
  183. );
  184. Status = ZwOpenKey (&RdbssHandle, KEY_READ, &ObjectAttributes);
  185. if (!NT_SUCCESS(Status)) {
  186. DbgPrint("FirstOpenFailed: %08lx %wZ\n",Status,RegistryPath);
  187. RxLogFailure (
  188. RxFileSystemDeviceObject,
  189. NULL,
  190. EVENT_RDR_CANT_READ_REGISTRY,
  191. Status);
  192. goto FINALLY;
  193. }
  194. RtlInitUnicodeString(&UnicodeString, L"MiniRdrs");
  195. InitializeObjectAttributes(
  196. &ObjectAttributes,
  197. &UnicodeString,
  198. OBJ_CASE_INSENSITIVE,
  199. RdbssHandle,
  200. NULL
  201. );
  202. Status = ZwOpenKey (&MiniRdrsHandle, KEY_READ, &ObjectAttributes);
  203. if (!NT_SUCCESS(Status)) {
  204. DbgPrint("2ndOpenFailed: %08lx %wZ\n",Status,&UnicodeString);
  205. RxLogFailure (
  206. RxFileSystemDeviceObject,
  207. NULL,
  208. EVENT_RDR_CANT_READ_REGISTRY,
  209. Status);
  210. goto FINALLY;
  211. }
  212. Status = ZwQueryKey (MiniRdrsHandle, KeyFullInformation, &KeyInformation,sizeof(KeyInformation),&DummyLength);
  213. if (!NT_SUCCESS(Status)) {
  214. DbgPrint("QueryFailed: %08lx %wZ\n",Status,&UnicodeString);
  215. RxLogFailure (
  216. RxFileSystemDeviceObject,
  217. NULL,
  218. EVENT_RDR_CANT_READ_REGISTRY,
  219. Status);
  220. goto FINALLY;
  221. }
  222. DbgPrint("HandleInfo %08lx %08lx %08lx\n",
  223. KeyInformation.Values,
  224. KeyInformation.MaxValueNameLen,
  225. KeyInformation.MaxValueDataLen);
  226. RxLoadedDriversNameBuffer = RxAllocatePoolWithTag(PagedPool,
  227. KeyInformation.Values*KeyInformation.MaxValueNameLen,
  228. 'xMxR');
  229. if (RxLoadedDriversNameBuffer==NULL) {
  230. DbgPrint("NameBufferAllocFailed: %08lx %wZ\n",Status,&UnicodeString);
  231. RxLogFailure (
  232. RxFileSystemDeviceObject,
  233. NULL,
  234. EVENT_RDR_CANT_READ_REGISTRY,
  235. Status);
  236. goto FINALLY;
  237. }
  238. NextNameBufferPosition = (PCHAR)RxLoadedDriversNameBuffer;
  239. ValueInformation = (PKEY_VALUE_BASIC_INFORMATION)(&Storage[0]); //this restricts the name length..we'll just skip long ones
  240. for (Index=0;Index<KeyInformation.Values;Index++) {
  241. UNICODE_STRING DriverName,RegistryNameString;
  242. NTSTATUS LoadStatus;
  243. ULONG ThisDriver;
  244. LoadStatus = ZwEnumerateValueKey(MiniRdrsHandle,
  245. Index,
  246. KeyValueBasicInformation,
  247. ValueInformation,
  248. sizeof(Storage),
  249. &DummyLength);
  250. if (!NT_SUCCESS(LoadStatus)) {
  251. continue;
  252. }
  253. DriverName.Length = DriverName.MaximumLength = (USHORT)(ValueInformation->NameLength);
  254. DriverName.Buffer = &(ValueInformation->Name[0]);
  255. LoadStatus = RxFabricateRegistryStringZZ(&RegistryNameString,
  256. &DriverName,
  257. &ServiceNameRegistryStringBuffer[0],
  258. sizeof(ServiceNameRegistryStringBuffer));
  259. if (!NT_SUCCESS(LoadStatus)) {
  260. continue;
  261. }
  262. DbgPrint(">>LOADING %wZ:%wZ\n",&DriverName,&RegistryNameString);
  263. LoadStatus = ZwLoadDriver(&RegistryNameString);
  264. if (!NT_SUCCESS(LoadStatus)) {
  265. continue;
  266. }
  267. ThisDriver = RxNextDriverLoaded;
  268. RxNextDriverLoaded++;
  269. RxLoadedDrivers[ThisDriver].Buffer = (PWCHAR)NextNameBufferPosition;
  270. RxLoadedDrivers[ThisDriver].Length = DriverName.MaximumLength;
  271. RxLoadedDrivers[ThisDriver].MaximumLength = DriverName.MaximumLength;
  272. RtlCopyMemory(NextNameBufferPosition,DriverName.Buffer,DriverName.MaximumLength);
  273. NextNameBufferPosition+=DriverName.MaximumLength;
  274. DbgPrint(">>SAVEDNAME %wZ:%wZ\n",&DriverName,&RxLoadedDrivers[ThisDriver]);
  275. }
  276. FINALLY:
  277. if (MiniRdrsHandle!=INVALID_HANDLE_VALUE) ZwClose(MiniRdrsHandle);
  278. if (MiniRdrsHandle!=INVALID_HANDLE_VALUE) ZwClose(RdbssHandle);
  279. if (!NT_SUCCESS(Status)) {
  280. RxUnloadMiniRdrs();
  281. }
  282. return Status;
  283. }
  284. VOID
  285. RxUnloadMiniRdrs(
  286. void
  287. )
  288. {
  289. ULONG ThisDriver;
  290. WCHAR ServiceNameRegistryStringBuffer[256]; //bugbug allocate this!
  291. PAGED_CODE(); //not actually in use
  292. DbgPrint("here we ungo, drivertounload=%08lx\n",RxNextDriverLoaded);
  293. for (ThisDriver=0;ThisDriver<RxNextDriverLoaded;ThisDriver++) {
  294. NTSTATUS LoadStatus;
  295. UNICODE_STRING RegistryNameString;
  296. DbgPrint(">>Unloading %wZ\n",&RxLoadedDrivers[ThisDriver]);
  297. LoadStatus = RxFabricateRegistryStringZZ(&RegistryNameString,
  298. &RxLoadedDrivers[ThisDriver],
  299. &ServiceNameRegistryStringBuffer[0],
  300. sizeof(ServiceNameRegistryStringBuffer));
  301. LoadStatus = ZwUnloadDriver(&RegistryNameString);
  302. DbgPrint(">>Unloaded %wZ, status =%08lx\n",&RxLoadedDrivers[ThisDriver],LoadStatus);
  303. //no status check.....can't do anything anyway!
  304. }
  305. if (RxLoadedDriversNameBuffer!=NULL) RxFreePool(RxLoadedDriversNameBuffer);
  306. return;
  307. }
  308. #endif
  309.