⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dbgport.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
This routine is called for every parallel port in the system.  It
will create a class device upon connecting to the port device
corresponding to it.
****************************************************************************/
VOID ParInitializeDeviceObject(
    IN  PDRIVER_OBJECT  DriverObject,
    IN  ULONG           ParallelPortNumber)
{
    UNICODE_STRING      portName, className, linkName;
    NTSTATUS            status;
    PDEVICE_OBJECT      deviceObject;
    PDEVICE_EXTENSION   ext;
    PFILE_OBJECT        fileObject;
    
    // Cobble together the port and class device names.
    if (!ParMakeNames(ParallelPortNumber, &portName, &className, &linkName))
        return;
    
    // Create the device object.
    status = IoCreateDevice(DriverObject, sizeof(DEVICE_EXTENSION),
        &className, FILE_DEVICE_PARALLEL_PORT, 0, TRUE,
        &deviceObject);
    if (!NT_SUCCESS(status)) {
        ExFreePool(linkName.Buffer);
        goto Cleanup;
    }
    
    // Now that the device has been created,
    // set up the device extension.
    ext = deviceObject->DeviceExtension;
    RtlZeroMemory(ext, sizeof(DEVICE_EXTENSION));
    ext->DeviceObject = deviceObject;
    deviceObject->Flags |= DO_BUFFERED_IO;
    status = IoGetDeviceObjectPointer(&portName, FILE_READ_ATTRIBUTES,
        &fileObject,
        &ext->PortDeviceObject);
    if (!NT_SUCCESS(status)) {
        IoDeleteDevice(deviceObject);
        ExFreePool(linkName.Buffer);
        goto Cleanup;
    }
    ObDereferenceObject(fileObject);
    ext->DeviceObject->StackSize = ext->PortDeviceObject->StackSize + 1;
    
    // Get the port information from the port device object.
    status = ParGetPortInfoFromPortDevice(ext);
    if (!NT_SUCCESS(status)) {
        IoDeleteDevice(deviceObject);
        ExFreePool(linkName.Buffer);
        goto Cleanup;
    }
    
    // Set up the symbolic link for windows apps.
    status = IoCreateSymbolicLink(&linkName, &className);
    if (!NT_SUCCESS(status)) {
        ext->CreatedSymbolicLink = FALSE;
        ExFreePool(linkName.Buffer);
        goto Cleanup;
    }
    
    // We were able to create the symbolic link, so record this
    // value in the extension for cleanup at unload time.
    ext->CreatedSymbolicLink = TRUE;
    ext->SymbolicLinkName = linkName;
    
Cleanup:
    ExFreePool(portName.Buffer);
    ExFreePool(className.Buffer);
}

/****************************************************************************
REMARKS:
Set the IOPM (I/O permission map) of the calling process so that it
is given full I/O access.  Our IOPM_local[] array is all zeros, so
the IOPM will be all zeros.  If OnFlag is 1, the process is given I/O
access.  If it is 0, access is removed.
****************************************************************************/
VOID SetIOPermissionMap( int OnFlag )
{
    if (OnFlag) {
        /* Enable I/O for the process */
        Ke386QueryIoAccessMap(1,IOPM_saved);
        Ke386IoSetAccessProcess(PsGetCurrentProcess(), 1);
        Ke386SetIoAccessMap(1, IOPM_local);
    } else {
        /* Disable I/O for the process, restoring old IOPM table */
        Ke386IoSetAccessProcess(PsGetCurrentProcess(), 0);
        Ke386SetIoAccessMap(1, IOPM_saved);
    }
}

/****************************************************************************
PARAMETERS:
DeviceObject    - Supplies the device object.
Irp             - Supplies the I/O request packet.

RETURNS:
STATUS_SUCCESS          - Success.
STATUS_NOT_A_DIRECTORY  - This device is not a directory.

REMARKS:
This routine is the dispatch for create requests.
****************************************************************************/
NTSTATUS PORTSTDCALL ParCreate(
    IN  PDEVICE_OBJECT  DeviceObject,
    IN  PIRP            Irp)
{
    PIO_STACK_LOCATION  irpSp;
    NTSTATUS            status;
    PDEVICE_EXTENSION   ext;
    
    // Give the debugger process full I/O port access. Ideally we should
    // restrict this to the actual I/O ports in use, and this can be done
    // in the future if desired.
    SetIOPermissionMap(1);
    
    // Now create the parallel port extension device
    ext = DeviceObject->DeviceExtension;
    irpSp = IoGetCurrentIrpStackLocation(Irp);
    if (irpSp->Parameters.Create.Options & FILE_DIRECTORY_FILE)
        status = STATUS_NOT_A_DIRECTORY;
    else if (!ext->TryAllocatePort(ext->AllocFreePortContext))
        status = STATUS_DEVICE_BUSY;
    else
        status = STATUS_SUCCESS;
    Irp->IoStatus.Status = status;
    Irp->IoStatus.Information = 0;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    return status;
}

/****************************************************************************
PARAMETERS:
DeviceObject    - Supplies the device object.
Irp             - Supplies the I/O request packet.

REMARKS:
This is the cancel routine for this driver.
****************************************************************************/
VOID ParCancel(
    IN  PDEVICE_OBJECT  DeviceObject,
    IN  PIRP            Irp)
{
}

/****************************************************************************
PARAMETERS:
DeviceObject    - Supplies the device object.
Irp             - Supplies the I/O request packet.

REMARKS:
This is the IOCtl routine for this driver.
****************************************************************************/
NTSTATUS PORTSTDCALL ParIOCTL(
    IN  PDEVICE_OBJECT  DeviceObject,
    IN  PIRP            Irp)
{
    PIO_STACK_LOCATION  irpSp;
    NTSTATUS            status;
    PDEVICE_EXTENSION   ext;
    DBGPORT_IO                      *IOBuffer;
    
    status = STATUS_SUCCESS;
    Irp->IoStatus.Information = sizeof( *IOBuffer );
    ext = DeviceObject->DeviceExtension;
    irpSp = IoGetCurrentIrpStackLocation(Irp);
    IOBuffer = (DBGPORT_IO *)Irp->AssociatedIrp.SystemBuffer;
    
    // NT copies inbuf here before entry and copies this to outbuf after
    // return, for METHOD_BUFFERED IOCTL's.
    switch (irpSp->Parameters.DeviceIoControl.IoControlCode) {
    case IOCTL_DBG_READ_PORT_U8:
        IOBuffer->data.u8 = _inp(IOBuffer->port);
        break;
    case IOCTL_DBG_READ_PORT_U16:
        IOBuffer->data.u16 = READ_PORT_USHORT((PUSHORT)(ext->Controller + IOBuffer->port));
        break;
    case IOCTL_DBG_READ_PORT_U32:
        IOBuffer->data.u32 = READ_PORT_ULONG((PULONG)(ext->Controller + IOBuffer->port));
        break;
    case IOCTL_DBG_WRITE_PORT_U8:
        _outp(IOBuffer->port,IOBuffer->data.u8);
        break;
    case IOCTL_DBG_WRITE_PORT_U16:
        WRITE_PORT_USHORT((PUSHORT)(ext->Controller + IOBuffer->port), IOBuffer->data.u16);
        break;
    case IOCTL_DBG_WRITE_PORT_U32:
        WRITE_PORT_ULONG((PULONG)(ext->Controller + IOBuffer->port), IOBuffer->data.u32);
        break;
    case IOCTL_DBG_REMOTE_GET:
        IOBuffer->status = RemoteGet(ext,IOBuffer->buffer,IOBuffer->len);
        break;
    case IOCTL_DBG_REMOTE_PUT:
        IOBuffer->status = RemotePut(ext,IOBuffer->buffer,IOBuffer->len);
        break;
    case IOCTL_DBG_REMOTE_CONNECT_SERV:
        IOBuffer->status = RemoteConnectServer(ext);
        break;
    case IOCTL_DBG_REMOTE_CONNECT_CLIENT:
        IOBuffer->status = RemoteConnectClient(ext);
        break;
    case IOCTL_DBG_REMOTE_DISCO:
        RemoteDisco(ext);
        break;
    case IOCTL_DBG_REMOTE_LINK:
        RemoteLink(ext);
        break;
    default:
        Irp->IoStatus.Information = 0;
        status = STATUS_NOT_IMPLEMENTED;
        break;
    }
    Irp->IoStatus.Status = status;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    return status;
}

/****************************************************************************
PARAMETERS:
DeviceObject    - Supplies the device object.
Irp             - Supplies the I/O request packet.

REMARKS:
This is the cleanup routine for this driver.
****************************************************************************/
NTSTATUS PORTSTDCALL ParCleanup(
    IN  PDEVICE_OBJECT  DeviceObject,
    IN  PIRP            Irp)
{
    Irp->IoStatus.Status = STATUS_CANCELLED;
    Irp->IoStatus.Information = 0;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    return STATUS_CANCELLED;
}

/****************************************************************************
PARAMETERS:
DeviceObject    - Supplies the device object.
Irp             - Supplies the I/O request packet.

REMARKS:
This is the close routine for this driver.
****************************************************************************/
NTSTATUS PORTSTDCALL ParClose(
    IN  PDEVICE_OBJECT  DeviceObject,
    IN  PIRP            Irp)
{
    PDEVICE_EXTENSION   ext;
    
    // Restore the original I/O port mappings
    SetIOPermissionMap(0);
    
    ext = DeviceObject->DeviceExtension;
    ext->FreePort(ext->AllocFreePortContext);
    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    return STATUS_SUCCESS;
}

/****************************************************************************
PARAMETERS:
DriverObject    - Supplies the driver object.

REMARKS:
This routine loops through the device list and cleans up after
each of the devices.
****************************************************************************/
VOID PORTSTDCALL ParUnload(
    IN  PDRIVER_OBJECT  DriverObject)
{
    PDEVICE_OBJECT          currentDevice;
    PDEVICE_EXTENSION   ext;
    
    while (currentDevice = DriverObject->DeviceObject) {
        ext = currentDevice->DeviceExtension;
        if (ext->CreatedSymbolicLink) {
            IoDeleteSymbolicLink(&ext->SymbolicLinkName);
            ExFreePool(ext->SymbolicLinkName.Buffer);
        }
        IoDeleteDevice(currentDevice);
    }
    
    // Free the local IOPM table if allocated
    if (IOPM_local)
        MmFreeNonCachedMemory(IOPM_local, sizeof(IOPM));
    if (IOPM_saved) {
        MmFreeNonCachedMemory(IOPM_saved, sizeof(IOPM));
    }
}

/****************************************************************************
PARAMETERS:
DriverObject    - Supplies the driver object.
RegistryPath    - Supplies the registry path for this driver.

REMARKS:
This routine is called at system initialization time to initialize
this driver.
****************************************************************************/
NTSTATUS PORTSTDCALL DriverEntry(
    IN  PDRIVER_OBJECT  DriverObject,
    IN  PUNICODE_STRING RegistryPath)
{
    ULONG       i;
    
    // TODO: We should be able to re-code this driver to use a call-gate
    //               to give the calling process full IOPL access, without needing
    //               the gross IOPM hack we currently use. This would make it
    //               slightly faster also.
    
    // Allocate a buffer for the local IOPM and zero it.
    IOPM_local = MmAllocateNonCachedMemory(sizeof(IOPM));
    IOPM_saved = MmAllocateNonCachedMemory(sizeof(IOPM));
    if (!IOPM_local || !IOPM_saved)
        return STATUS_INSUFFICIENT_RESOURCES;
    RtlZeroMemory(IOPM_local, sizeof(IOPM));
    Ke386QueryIoAccessMap(1,IOPM_saved);
    
    // Initialise all the device objects
    for (i = 0; i < IoGetConfigurationInformation()->ParallelCount; i++)
        ParInitializeDeviceObject(DriverObject, i);
    if (!DriverObject->DeviceObject)
        return STATUS_NO_SUCH_DEVICE;
    
    // Initialize the Driver Object with driver's entry points
    DriverObject->MajorFunction[IRP_MJ_CREATE] = ParCreate;
    DriverObject->MajorFunction[IRP_MJ_CLOSE] = ParClose;
    DriverObject->MajorFunction[IRP_MJ_CLEANUP] = ParCleanup;
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ParIOCTL;
    DriverObject->DriverUnload = ParUnload;
    return STATUS_SUCCESS;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -