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.

631 lines
14 KiB

  1. /*++
  2. Copyright (c) 1999-2000 Microsoft Corporation
  3. Module Name:
  4. Iocltdispatch.c
  5. Abstract:
  6. This module contains functions for handling supported IOCTL codes.
  7. Author:
  8. Nicholas Owens (Nichow) - 1999
  9. Revision History:
  10. --*/
  11. #include "pch.h"
  12. NTSTATUS
  13. SoftPCIOpenDeviceControl(
  14. IN PDEVICE_OBJECT DeviceObject,
  15. IN PIRP Irp
  16. )
  17. /*++
  18. Routine Description:
  19. Handles all CREATES' we receive
  20. Arguments:
  21. DeviceObject - Pointer to the device object.
  22. Irp - PnP Irp to be dispatched.
  23. Return Value:
  24. NTSTATUS.
  25. --*/
  26. {
  27. NTSTATUS status = STATUS_SUCCESS;
  28. //
  29. // Set Irp Status and Information
  30. //
  31. Irp->IoStatus.Status = STATUS_SUCCESS;
  32. Irp->IoStatus.Information = 0;
  33. //
  34. // Increment Reference Count
  35. //
  36. ObReferenceObject(
  37. DeviceObject
  38. );
  39. //
  40. // Complete the Irp
  41. //
  42. IoCompleteRequest(
  43. Irp,
  44. IO_NO_INCREMENT
  45. );
  46. return status;
  47. }
  48. NTSTATUS
  49. SoftPCICloseDeviceControl(
  50. IN PDEVICE_OBJECT DeviceObject,
  51. IN PIRP Irp
  52. )
  53. /*++
  54. Routine Description:
  55. Handles all CLOSES' we receive
  56. Arguments:
  57. DeviceObject - Pointer to the device object.
  58. Irp - PnP Irp to be dispatched.
  59. Return Value:
  60. NTSTATUS.
  61. --*/
  62. {
  63. NTSTATUS status = STATUS_SUCCESS;
  64. //
  65. // Set Irp Status and Information
  66. //
  67. Irp->IoStatus.Status = STATUS_SUCCESS;
  68. Irp->IoStatus.Information = 0;
  69. //
  70. // Decrement Reference Count
  71. //
  72. ObDereferenceObject(
  73. DeviceObject
  74. );
  75. //
  76. // Complete the Irp
  77. //
  78. IoCompleteRequest(
  79. Irp,
  80. IO_NO_INCREMENT
  81. );
  82. return status;
  83. }
  84. NTSTATUS
  85. SoftPCIIoctlAddDevice(
  86. IN PDEVICE_OBJECT DeviceObject,
  87. IN PIRP Irp
  88. )
  89. /*++
  90. Routine Description:
  91. Handles all SOFTPCI_IOCTL_CREATE_DEVICE IOCLTS we receive. Here we attempt to create a
  92. new SoftPCI device.
  93. Arguments:
  94. DeviceObject - Pointer to the device object.
  95. Irp - PnP Irp to be dispatched.
  96. Return Value:
  97. NTSTATUS.
  98. --*/
  99. {
  100. NTSTATUS status = STATUS_UNSUCCESSFUL;
  101. PIO_STACK_LOCATION irpSl;
  102. PVOID inputBuffer;
  103. PBOOLEAN outputBuffer;
  104. ULONG inputBufferLength;
  105. ULONG outputBufferLength;
  106. KIRQL irql;
  107. PSOFTPCI_DEVICE newSoftPciDevice;
  108. PSOFTPCI_DEVICE previousDevice;
  109. PSOFTPCI_DEVICE existingDevice;
  110. PSOFTPCI_SCRIPT_DEVICE scriptDevice;
  111. UNREFERENCED_PARAMETER(DeviceObject);
  112. //
  113. // Get Current Stack Location
  114. //
  115. irpSl = IoGetCurrentIrpStackLocation(Irp);
  116. //
  117. // Initialize input and output buffers to Irp->AssociatedIrp.SystemBuffer
  118. //
  119. inputBuffer = Irp->AssociatedIrp.SystemBuffer;
  120. outputBuffer = Irp->AssociatedIrp.SystemBuffer;
  121. //
  122. // Initialize input and output lengths.
  123. //
  124. inputBufferLength = irpSl->Parameters.DeviceIoControl.InputBufferLength;
  125. outputBufferLength = irpSl->Parameters.DeviceIoControl.OutputBufferLength;
  126. if (inputBufferLength == sizeof (SOFTPCI_DEVICE)) {
  127. newSoftPciDevice = (PSOFTPCI_DEVICE) inputBuffer;
  128. SoftPCIDbgPrint(
  129. SOFTPCI_INFO,
  130. "SOFTPCI: AddDeviceIoctl - BUS_%02x&DEV_%02x&FUN_%02x (0x%x)\n",
  131. newSoftPciDevice->Bus,
  132. newSoftPciDevice->Slot.Device,
  133. newSoftPciDevice->Slot.Function,
  134. &newSoftPciDevice->Config
  135. );
  136. previousDevice = NULL;
  137. SoftPCILockDeviceTree(&irql);
  138. existingDevice = SoftPCIFindDevice(
  139. newSoftPciDevice->Bus,
  140. newSoftPciDevice->Slot.AsUSHORT,
  141. &previousDevice,
  142. FALSE
  143. );
  144. SoftPCIUnlockDeviceTree(irql);
  145. if (!existingDevice) {
  146. if (!SoftPCIRealHardwarePresent(newSoftPciDevice)) {
  147. #if DBG
  148. if (IS_BRIDGE(newSoftPciDevice)){
  149. ASSERT((newSoftPciDevice->Config.Mask.u.type1.PrimaryBus != 0) &&
  150. (newSoftPciDevice->Config.Mask.u.type1.SecondaryBus != 0) &&
  151. (newSoftPciDevice->Config.Mask.u.type1.SubordinateBus != 0));
  152. }
  153. #endif
  154. //
  155. // Doesnt look like real hardware is here so lets allow a fake one.
  156. //
  157. status = SoftPCIAddNewDevice(newSoftPciDevice);
  158. }else{
  159. //
  160. // We dont allow fake devices to be placed on real ones!
  161. //
  162. SoftPCIDbgPrint(
  163. SOFTPCI_ERROR,
  164. "SOFTPCI: AddDeviceIoctl - Physical Hardware exists at BUS_%02x&DEV_%02x&FUN_%02x\n",
  165. newSoftPciDevice->Bus,
  166. newSoftPciDevice->Slot.Device,
  167. newSoftPciDevice->Slot.Function
  168. );
  169. status = STATUS_ACCESS_DENIED;
  170. }
  171. }
  172. }else{
  173. //
  174. // We must be installing a path based device
  175. //
  176. ASSERT(inputBufferLength > sizeof(SOFTPCI_DEVICE));
  177. scriptDevice = (PSOFTPCI_SCRIPT_DEVICE) inputBuffer;
  178. ASSERT(scriptDevice->ParentPathLength > 0 );
  179. ASSERT(scriptDevice->ParentPath != NULL);
  180. status = SoftPCIAddNewDeviceByPath(scriptDevice);
  181. }
  182. //
  183. // Set outputBuffer to True
  184. //
  185. if (outputBufferLength >= sizeof(BOOLEAN)) {
  186. if (NT_SUCCESS(status)) {
  187. *outputBuffer = TRUE;
  188. } else {
  189. *outputBuffer = FALSE;
  190. }
  191. //
  192. // Set IoStatus.Information to the size of a Boolean or to outputBufferLength, whichever is lesser.
  193. //
  194. Irp->IoStatus.Information = (sizeof(BOOLEAN)<outputBufferLength?sizeof(BOOLEAN):outputBufferLength);
  195. } else {
  196. status = STATUS_INSUFFICIENT_RESOURCES;
  197. }
  198. return status;
  199. }
  200. NTSTATUS
  201. SoftPCIIoctlRemoveDevice(
  202. IN PDEVICE_OBJECT DeviceObject,
  203. IN PIRP Irp
  204. )
  205. /*++
  206. Routine Description:
  207. Handles all SOFTPCI_IOCTL_WRITE_DELETE_DEVICE IOCLTS we receive. Here we will try and remove a specified
  208. SoftPCI device.
  209. Arguments:
  210. DeviceObject - Pointer to the device object.
  211. Irp - PnP Irp to be dispatched.
  212. Return Value:
  213. NTSTATUS.
  214. --*/
  215. {
  216. NTSTATUS status = STATUS_SUCCESS;
  217. PIO_STACK_LOCATION irpSl;
  218. PSOFTPCI_DEVICE inputBuffer;
  219. PBOOLEAN outputBuffer;
  220. ULONG inputBufferLength;
  221. ULONG outputBufferLength;
  222. UNREFERENCED_PARAMETER(DeviceObject);
  223. //
  224. // Get Current Stack Location
  225. //
  226. irpSl = IoGetCurrentIrpStackLocation(Irp);
  227. //
  228. // Initialize input and output buffers to Irp->AssociatedIrp.SystemBuffer
  229. //
  230. inputBuffer = Irp->AssociatedIrp.SystemBuffer;
  231. outputBuffer = Irp->AssociatedIrp.SystemBuffer;
  232. //
  233. // Initialize input and output lengths.
  234. //
  235. inputBufferLength = irpSl->Parameters.DeviceIoControl.InputBufferLength;
  236. outputBufferLength = irpSl->Parameters.DeviceIoControl.OutputBufferLength;
  237. Irp->IoStatus.Information = 0;
  238. if (inputBufferLength == sizeof(SOFTPCI_DEVICE)) {
  239. SoftPCIDbgPrint(
  240. SOFTPCI_INFO,
  241. "SOFTPCI: RemoveDeviceIoctl - BUS_%02x&DEV_%02x&FUN_%02x\n",
  242. inputBuffer->Bus,
  243. inputBuffer->Slot.Device,
  244. inputBuffer->Slot.Function
  245. );
  246. status = SoftPCIRemoveDevice(inputBuffer);
  247. }
  248. //
  249. // Set outputBuffer to True
  250. //
  251. if (outputBufferLength >= sizeof(BOOLEAN)) {
  252. if (NT_SUCCESS(status)) {
  253. *outputBuffer = TRUE;
  254. } else {
  255. *outputBuffer = FALSE;
  256. }
  257. //
  258. // Set IoStatus.Information to the size of a Boolean
  259. //
  260. Irp->IoStatus.Information = sizeof(BOOLEAN);
  261. } else {
  262. status = STATUS_INSUFFICIENT_RESOURCES;
  263. }
  264. SoftPCIDbgPrint(
  265. SOFTPCI_IOCTL_LEVEL,
  266. "SOFTPCI: RemoveDeviceIoctl - BUS_%02x&DEV_%02x&FUN_%02x status=0x%x\n",
  267. inputBuffer->Bus,
  268. inputBuffer->Slot.Device,
  269. inputBuffer->Slot.Function,
  270. status
  271. );
  272. return status;
  273. }
  274. NTSTATUS
  275. SoftPCIIoctlGetDeviceCount(
  276. IN PDEVICE_OBJECT DeviceObject,
  277. IN PIRP Irp
  278. )
  279. /*++
  280. Routine Description:
  281. Handles all SOFTPCI_IOCTL_GET_NUMBER_OF_DEVICES IOCLTS we receive.
  282. Arguments:
  283. DeviceObject - Pointer to the device object.
  284. Irp - PnP Irp to be dispatched.
  285. Return Value:
  286. NTSTATUS.
  287. --*/
  288. {
  289. NTSTATUS status = STATUS_SUCCESS;
  290. PIO_STACK_LOCATION irpSl;
  291. PULONG outputBuffer;
  292. ULONG outputBufferLength;
  293. UNREFERENCED_PARAMETER(DeviceObject);
  294. //
  295. // Get Current Stack Location
  296. //
  297. irpSl = IoGetCurrentIrpStackLocation(Irp);
  298. //
  299. // Initialize input and output buffers to Irp->AssociatedIrp.SystemBuffer
  300. //
  301. outputBuffer = Irp->AssociatedIrp.SystemBuffer;
  302. //
  303. // Initialize input and output lengths.
  304. //
  305. outputBufferLength = irpSl->Parameters.DeviceIoControl.OutputBufferLength;
  306. //
  307. // Set outputBuffer to True
  308. //
  309. if (outputBufferLength >= sizeof(ULONG)) {
  310. *outputBuffer = SoftPciTree.DeviceCount;
  311. //
  312. // Set IoStatus.Information to the size of a Boolean or to outputBufferLength, whichever is lesser.
  313. //
  314. Irp->IoStatus.Information = (sizeof(ULONG)<outputBufferLength?sizeof(ULONG):outputBufferLength);
  315. } else {
  316. status = STATUS_INSUFFICIENT_RESOURCES;
  317. }
  318. return status;
  319. }
  320. NTSTATUS
  321. SoftPCIIoctlGetDevice(
  322. IN PDEVICE_OBJECT DeviceObject,
  323. IN PIRP Irp
  324. )
  325. /*++
  326. Routine Description:
  327. Handles all SOFTPCI_IOCTL_GET_DEVICE IOCLTS we receive.
  328. Arguments:
  329. DeviceObject - Pointer to the device object.
  330. Irp - PnP Irp to be dispatched.
  331. Return Value:
  332. NTSTATUS.
  333. --*/
  334. {
  335. NTSTATUS status = STATUS_UNSUCCESSFUL;
  336. PIO_STACK_LOCATION irpSp;
  337. PSOFTPCI_DEVICE device;
  338. PSOFTPCI_DEVICE inputBuffer, outputBuffer;
  339. ULONG inputBufferLength, outputBufferLength;
  340. KIRQL irql;
  341. UNREFERENCED_PARAMETER(DeviceObject);
  342. //
  343. // Get Current Stack Location
  344. //
  345. irpSp = IoGetCurrentIrpStackLocation(Irp);
  346. SoftPCILockDeviceTree(&irql);
  347. //
  348. // Initialize input and output buffers to Irp->AssociatedIrp.SystemBuffer
  349. //
  350. inputBuffer = (PSOFTPCI_DEVICE)Irp->AssociatedIrp.SystemBuffer;
  351. outputBuffer = (PSOFTPCI_DEVICE)Irp->AssociatedIrp.SystemBuffer;
  352. //
  353. // Initialize input and output lengths.
  354. //
  355. inputBufferLength = irpSp->Parameters.DeviceIoControl.InputBufferLength;
  356. outputBufferLength = irpSp->Parameters.DeviceIoControl.OutputBufferLength;
  357. device = NULL;
  358. if (inputBufferLength == sizeof(SOFTPCI_DEVICE)) {
  359. device = SoftPCIFindDevice(
  360. inputBuffer->Bus,
  361. inputBuffer->Slot.AsUSHORT,
  362. NULL,
  363. TRUE
  364. );
  365. }
  366. //
  367. // Set outputBuffer to True
  368. //
  369. if (outputBufferLength >= sizeof(SOFTPCI_DEVICE)) {
  370. if (device) {
  371. RtlCopyMemory(outputBuffer, device, sizeof(SOFTPCI_DEVICE));
  372. outputBufferLength = sizeof(SOFTPCI_DEVICE);
  373. status = STATUS_SUCCESS;
  374. } else {
  375. outputBufferLength = 0;
  376. }
  377. //
  378. // Set IoStatus.Information to number of bytes returned
  379. //
  380. Irp->IoStatus.Information = outputBufferLength;
  381. } else {
  382. status = STATUS_INSUFFICIENT_RESOURCES;
  383. }
  384. SoftPCIUnlockDeviceTree(irql);
  385. return status;
  386. }
  387. NTSTATUS
  388. SoftPCIIocltReadWriteConfig(
  389. IN PDEVICE_OBJECT DeviceObject,
  390. IN PIRP Irp
  391. )
  392. /*++
  393. Routine Description:
  394. Handles all SOFTPCI_IOCTL_RW_CONFIG we receive.
  395. Arguments:
  396. DeviceObject - Pointer to the device object.
  397. Irp - PnP Irp to be dispatched.
  398. Return Value:
  399. NTSTATUS.
  400. --*/
  401. {
  402. PIO_STACK_LOCATION irpSl;
  403. PUCHAR outputBuffer;
  404. ULONG outputBufferLength;
  405. ULONG bytes;
  406. PSOFTPCI_RW_CONTEXT context;
  407. PCI_SLOT_NUMBER slot;
  408. UNREFERENCED_PARAMETER(DeviceObject);
  409. irpSl = IoGetCurrentIrpStackLocation(Irp);
  410. //
  411. // Initialize input and output buffers
  412. //
  413. context = (PSOFTPCI_RW_CONTEXT) Irp->AssociatedIrp.SystemBuffer;
  414. outputBuffer = (PUCHAR)Irp->AssociatedIrp.SystemBuffer;
  415. //
  416. // Initialize input and output lengths.
  417. //
  418. outputBufferLength = irpSl->Parameters.DeviceIoControl.OutputBufferLength;
  419. slot.u.AsULONG = 0;
  420. slot.u.bits.DeviceNumber = context->Slot.Device;
  421. slot.u.bits.FunctionNumber = context->Slot.Function;
  422. Irp->IoStatus.Information = 0;
  423. bytes = 0;
  424. switch (context->WriteConfig) {
  425. case SoftPciWriteConfig:
  426. bytes = SoftPCIWriteConfigSpace(
  427. SoftPciTree.BusInterface,
  428. (UCHAR)context->Bus,
  429. slot.u.AsULONG,
  430. context->Data,
  431. context->Offset,
  432. outputBufferLength
  433. );
  434. break;
  435. case SoftPciReadConfig:
  436. bytes = SoftPCIReadConfigSpace(
  437. SoftPciTree.BusInterface,
  438. (UCHAR)context->Bus,
  439. slot.u.AsULONG,
  440. outputBuffer,
  441. context->Offset,
  442. outputBufferLength
  443. );
  444. break;
  445. default:
  446. return STATUS_UNSUCCESSFUL;
  447. }
  448. if (bytes != outputBufferLength) {
  449. //
  450. // We failed to get all the data we wanted.
  451. //
  452. return STATUS_UNSUCCESSFUL;
  453. }
  454. //
  455. // Set IoStatus.Information to the number of bytes returned
  456. //
  457. Irp->IoStatus.Information = bytes;
  458. return STATUS_SUCCESS;
  459. }