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

/*++
Copyright (c) 1999-2000 Microsoft Corporation
Module Name:
Iocltdispatch.c
Abstract:
This module contains functions for handling supported IOCTL codes.
Author:
Nicholas Owens (Nichow) - 1999
Revision History:
--*/
#include "pch.h"
NTSTATUS
SoftPCIOpenDeviceControl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
Handles all CREATES' we receive
Arguments:
DeviceObject - Pointer to the device object.
Irp - PnP Irp to be dispatched.
Return Value:
NTSTATUS.
--*/
{
NTSTATUS status = STATUS_SUCCESS;
//
// Set Irp Status and Information
//
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
//
// Increment Reference Count
//
ObReferenceObject(
DeviceObject
);
//
// Complete the Irp
//
IoCompleteRequest(
Irp,
IO_NO_INCREMENT
);
return status;
}
NTSTATUS
SoftPCICloseDeviceControl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
Handles all CLOSES' we receive
Arguments:
DeviceObject - Pointer to the device object.
Irp - PnP Irp to be dispatched.
Return Value:
NTSTATUS.
--*/
{
NTSTATUS status = STATUS_SUCCESS;
//
// Set Irp Status and Information
//
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
//
// Decrement Reference Count
//
ObDereferenceObject(
DeviceObject
);
//
// Complete the Irp
//
IoCompleteRequest(
Irp,
IO_NO_INCREMENT
);
return status;
}
NTSTATUS
SoftPCIIoctlAddDevice(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
Handles all SOFTPCI_IOCTL_CREATE_DEVICE IOCLTS we receive. Here we attempt to create a
new SoftPCI device.
Arguments:
DeviceObject - Pointer to the device object.
Irp - PnP Irp to be dispatched.
Return Value:
NTSTATUS.
--*/
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
PIO_STACK_LOCATION irpSl;
PVOID inputBuffer;
PBOOLEAN outputBuffer;
ULONG inputBufferLength;
ULONG outputBufferLength;
KIRQL irql;
PSOFTPCI_DEVICE newSoftPciDevice;
PSOFTPCI_DEVICE previousDevice;
PSOFTPCI_DEVICE existingDevice;
PSOFTPCI_SCRIPT_DEVICE scriptDevice;
UNREFERENCED_PARAMETER(DeviceObject);
//
// Get Current Stack Location
//
irpSl = IoGetCurrentIrpStackLocation(Irp);
//
// Initialize input and output buffers to Irp->AssociatedIrp.SystemBuffer
//
inputBuffer = Irp->AssociatedIrp.SystemBuffer;
outputBuffer = Irp->AssociatedIrp.SystemBuffer;
//
// Initialize input and output lengths.
//
inputBufferLength = irpSl->Parameters.DeviceIoControl.InputBufferLength;
outputBufferLength = irpSl->Parameters.DeviceIoControl.OutputBufferLength;
if (inputBufferLength == sizeof (SOFTPCI_DEVICE)) {
newSoftPciDevice = (PSOFTPCI_DEVICE) inputBuffer;
SoftPCIDbgPrint(
SOFTPCI_INFO,
"SOFTPCI: AddDeviceIoctl - BUS_%02x&DEV_%02x&FUN_%02x (0x%x)\n",
newSoftPciDevice->Bus,
newSoftPciDevice->Slot.Device,
newSoftPciDevice->Slot.Function,
&newSoftPciDevice->Config
);
previousDevice = NULL;
SoftPCILockDeviceTree(&irql);
existingDevice = SoftPCIFindDevice(
newSoftPciDevice->Bus,
newSoftPciDevice->Slot.AsUSHORT,
&previousDevice,
FALSE
);
SoftPCIUnlockDeviceTree(irql);
if (!existingDevice) {
if (!SoftPCIRealHardwarePresent(newSoftPciDevice)) {
#if DBG
if (IS_BRIDGE(newSoftPciDevice)){
ASSERT((newSoftPciDevice->Config.Mask.u.type1.PrimaryBus != 0) &&
(newSoftPciDevice->Config.Mask.u.type1.SecondaryBus != 0) &&
(newSoftPciDevice->Config.Mask.u.type1.SubordinateBus != 0));
}
#endif
//
// Doesnt look like real hardware is here so lets allow a fake one.
//
status = SoftPCIAddNewDevice(newSoftPciDevice);
}else{
//
// We dont allow fake devices to be placed on real ones!
//
SoftPCIDbgPrint(
SOFTPCI_ERROR,
"SOFTPCI: AddDeviceIoctl - Physical Hardware exists at BUS_%02x&DEV_%02x&FUN_%02x\n",
newSoftPciDevice->Bus,
newSoftPciDevice->Slot.Device,
newSoftPciDevice->Slot.Function
);
status = STATUS_ACCESS_DENIED;
}
}
}else{
//
// We must be installing a path based device
//
ASSERT(inputBufferLength > sizeof(SOFTPCI_DEVICE));
scriptDevice = (PSOFTPCI_SCRIPT_DEVICE) inputBuffer;
ASSERT(scriptDevice->ParentPathLength > 0 );
ASSERT(scriptDevice->ParentPath != NULL);
status = SoftPCIAddNewDeviceByPath(scriptDevice);
}
//
// Set outputBuffer to True
//
if (outputBufferLength >= sizeof(BOOLEAN)) {
if (NT_SUCCESS(status)) {
*outputBuffer = TRUE;
} else {
*outputBuffer = FALSE;
}
//
// Set IoStatus.Information to the size of a Boolean or to outputBufferLength, whichever is lesser.
//
Irp->IoStatus.Information = (sizeof(BOOLEAN)<outputBufferLength?sizeof(BOOLEAN):outputBufferLength);
} else {
status = STATUS_INSUFFICIENT_RESOURCES;
}
return status;
}
NTSTATUS
SoftPCIIoctlRemoveDevice(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
Handles all SOFTPCI_IOCTL_WRITE_DELETE_DEVICE IOCLTS we receive. Here we will try and remove a specified
SoftPCI device.
Arguments:
DeviceObject - Pointer to the device object.
Irp - PnP Irp to be dispatched.
Return Value:
NTSTATUS.
--*/
{
NTSTATUS status = STATUS_SUCCESS;
PIO_STACK_LOCATION irpSl;
PSOFTPCI_DEVICE inputBuffer;
PBOOLEAN outputBuffer;
ULONG inputBufferLength;
ULONG outputBufferLength;
UNREFERENCED_PARAMETER(DeviceObject);
//
// Get Current Stack Location
//
irpSl = IoGetCurrentIrpStackLocation(Irp);
//
// Initialize input and output buffers to Irp->AssociatedIrp.SystemBuffer
//
inputBuffer = Irp->AssociatedIrp.SystemBuffer;
outputBuffer = Irp->AssociatedIrp.SystemBuffer;
//
// Initialize input and output lengths.
//
inputBufferLength = irpSl->Parameters.DeviceIoControl.InputBufferLength;
outputBufferLength = irpSl->Parameters.DeviceIoControl.OutputBufferLength;
Irp->IoStatus.Information = 0;
if (inputBufferLength == sizeof(SOFTPCI_DEVICE)) {
SoftPCIDbgPrint(
SOFTPCI_INFO,
"SOFTPCI: RemoveDeviceIoctl - BUS_%02x&DEV_%02x&FUN_%02x\n",
inputBuffer->Bus,
inputBuffer->Slot.Device,
inputBuffer->Slot.Function
);
status = SoftPCIRemoveDevice(inputBuffer);
}
//
// Set outputBuffer to True
//
if (outputBufferLength >= sizeof(BOOLEAN)) {
if (NT_SUCCESS(status)) {
*outputBuffer = TRUE;
} else {
*outputBuffer = FALSE;
}
//
// Set IoStatus.Information to the size of a Boolean
//
Irp->IoStatus.Information = sizeof(BOOLEAN);
} else {
status = STATUS_INSUFFICIENT_RESOURCES;
}
SoftPCIDbgPrint(
SOFTPCI_IOCTL_LEVEL,
"SOFTPCI: RemoveDeviceIoctl - BUS_%02x&DEV_%02x&FUN_%02x status=0x%x\n",
inputBuffer->Bus,
inputBuffer->Slot.Device,
inputBuffer->Slot.Function,
status
);
return status;
}
NTSTATUS
SoftPCIIoctlGetDeviceCount(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
Handles all SOFTPCI_IOCTL_GET_NUMBER_OF_DEVICES IOCLTS we receive.
Arguments:
DeviceObject - Pointer to the device object.
Irp - PnP Irp to be dispatched.
Return Value:
NTSTATUS.
--*/
{
NTSTATUS status = STATUS_SUCCESS;
PIO_STACK_LOCATION irpSl;
PULONG outputBuffer;
ULONG outputBufferLength;
UNREFERENCED_PARAMETER(DeviceObject);
//
// Get Current Stack Location
//
irpSl = IoGetCurrentIrpStackLocation(Irp);
//
// Initialize input and output buffers to Irp->AssociatedIrp.SystemBuffer
//
outputBuffer = Irp->AssociatedIrp.SystemBuffer;
//
// Initialize input and output lengths.
//
outputBufferLength = irpSl->Parameters.DeviceIoControl.OutputBufferLength;
//
// Set outputBuffer to True
//
if (outputBufferLength >= sizeof(ULONG)) {
*outputBuffer = SoftPciTree.DeviceCount;
//
// Set IoStatus.Information to the size of a Boolean or to outputBufferLength, whichever is lesser.
//
Irp->IoStatus.Information = (sizeof(ULONG)<outputBufferLength?sizeof(ULONG):outputBufferLength);
} else {
status = STATUS_INSUFFICIENT_RESOURCES;
}
return status;
}
NTSTATUS
SoftPCIIoctlGetDevice(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
Handles all SOFTPCI_IOCTL_GET_DEVICE IOCLTS we receive.
Arguments:
DeviceObject - Pointer to the device object.
Irp - PnP Irp to be dispatched.
Return Value:
NTSTATUS.
--*/
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
PIO_STACK_LOCATION irpSp;
PSOFTPCI_DEVICE device;
PSOFTPCI_DEVICE inputBuffer, outputBuffer;
ULONG inputBufferLength, outputBufferLength;
KIRQL irql;
UNREFERENCED_PARAMETER(DeviceObject);
//
// Get Current Stack Location
//
irpSp = IoGetCurrentIrpStackLocation(Irp);
SoftPCILockDeviceTree(&irql);
//
// Initialize input and output buffers to Irp->AssociatedIrp.SystemBuffer
//
inputBuffer = (PSOFTPCI_DEVICE)Irp->AssociatedIrp.SystemBuffer;
outputBuffer = (PSOFTPCI_DEVICE)Irp->AssociatedIrp.SystemBuffer;
//
// Initialize input and output lengths.
//
inputBufferLength = irpSp->Parameters.DeviceIoControl.InputBufferLength;
outputBufferLength = irpSp->Parameters.DeviceIoControl.OutputBufferLength;
device = NULL;
if (inputBufferLength == sizeof(SOFTPCI_DEVICE)) {
device = SoftPCIFindDevice(
inputBuffer->Bus,
inputBuffer->Slot.AsUSHORT,
NULL,
TRUE
);
}
//
// Set outputBuffer to True
//
if (outputBufferLength >= sizeof(SOFTPCI_DEVICE)) {
if (device) {
RtlCopyMemory(outputBuffer, device, sizeof(SOFTPCI_DEVICE));
outputBufferLength = sizeof(SOFTPCI_DEVICE);
status = STATUS_SUCCESS;
} else {
outputBufferLength = 0;
}
//
// Set IoStatus.Information to number of bytes returned
//
Irp->IoStatus.Information = outputBufferLength;
} else {
status = STATUS_INSUFFICIENT_RESOURCES;
}
SoftPCIUnlockDeviceTree(irql);
return status;
}
NTSTATUS
SoftPCIIocltReadWriteConfig(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
Handles all SOFTPCI_IOCTL_RW_CONFIG we receive.
Arguments:
DeviceObject - Pointer to the device object.
Irp - PnP Irp to be dispatched.
Return Value:
NTSTATUS.
--*/
{
PIO_STACK_LOCATION irpSl;
PUCHAR outputBuffer;
ULONG outputBufferLength;
ULONG bytes;
PSOFTPCI_RW_CONTEXT context;
PCI_SLOT_NUMBER slot;
UNREFERENCED_PARAMETER(DeviceObject);
irpSl = IoGetCurrentIrpStackLocation(Irp);
//
// Initialize input and output buffers
//
context = (PSOFTPCI_RW_CONTEXT) Irp->AssociatedIrp.SystemBuffer;
outputBuffer = (PUCHAR)Irp->AssociatedIrp.SystemBuffer;
//
// Initialize input and output lengths.
//
outputBufferLength = irpSl->Parameters.DeviceIoControl.OutputBufferLength;
slot.u.AsULONG = 0;
slot.u.bits.DeviceNumber = context->Slot.Device;
slot.u.bits.FunctionNumber = context->Slot.Function;
Irp->IoStatus.Information = 0;
bytes = 0;
switch (context->WriteConfig) {
case SoftPciWriteConfig:
bytes = SoftPCIWriteConfigSpace(
SoftPciTree.BusInterface,
(UCHAR)context->Bus,
slot.u.AsULONG,
context->Data,
context->Offset,
outputBufferLength
);
break;
case SoftPciReadConfig:
bytes = SoftPCIReadConfigSpace(
SoftPciTree.BusInterface,
(UCHAR)context->Bus,
slot.u.AsULONG,
outputBuffer,
context->Offset,
outputBufferLength
);
break;
default:
return STATUS_UNSUCCESSFUL;
}
if (bytes != outputBufferLength) {
//
// We failed to get all the data we wanted.
//
return STATUS_UNSUCCESSFUL;
}
//
// Set IoStatus.Information to the number of bytes returned
//
Irp->IoStatus.Information = bytes;
return STATUS_SUCCESS;
}