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

📄 ioctl.c

📁 WinBond W83627 看门狗驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
/*++

Copyright (c) 2006 EVOC, All Rights Reserved
 
Module Name:

    Ioctl.c  

Abstract:   WDT ioctl control code dispatch.


Environment:

    Kernel mode


Author:    mz.yang  may, 2006


Revision History:

--*/

//#include <ntddk.h>

#include "Driver.h"

NTSTATUS
WDTIoctlReadPort(
    IN PDEVICE_EXTENSION pde,
    IN PIRP Irp,
    IN PIO_STACK_LOCATION IrpStack,
    IN ULONG IoctlCode  );


NTSTATUS
WDTIoctlWritePort(
    IN PDEVICE_EXTENSION pde, 
    IN PIRP Irp, 
    IN PIO_STACK_LOCATION IrpStack,
    IN ULONG IoctlCode
    );


NTSTATUS
WDTIoctlGetHardwareID(
	IN PDEVICE_EXTENSION pde,
	IN PIRP Irp,
	IN PIO_STACK_LOCATION IrpStack
	);


NTSTATUS
WDTIoctlGetPortIndex(
	IN PDEVICE_EXTENSION pde,
	IN PIRP Irp,
	IN PIO_STACK_LOCATION IrpStack
	);


NTSTATUS
WDTIoctlGetPortData(
	IN PDEVICE_EXTENSION pde,
	IN PIRP Irp,
	IN PIO_STACK_LOCATION IrpStack
	);


NTSTATUS
IRQSearchAuto(
	IN PDEVICE_OBJECT fdo,
	IN PIRP Irp,
	IN PIO_STACK_LOCATION IrpStack
	);


NTSTATUS
IRQUserSet(
	IN PDEVICE_OBJECT fdo,
	IN PIRP Irp,
	IN PIO_STACK_LOCATION IrpStack
	);


NTSTATUS 
ClaimResources( IN PDEVICE_OBJECT fdo );


NTSTATUS 
TranslateAndMapResources( IN PDEVICE_OBJECT fdo);


NTSTATUS
DRV_Open(IN PDEVICE_OBJECT fdo,IN PIRP Irp)
/*++

Routine Description:

    When application called api "CreateFile",system will called this routine.

Arguments:

    fdo - pointer to a function device object.
	Irp - pointer to an I/O Request Packet.

Return Value:

    TRUE  :called succeed.
    FALSE :called failed.
--*/
{
	
	NTSTATUS status=STATUS_SUCCESS;
	PDEVICE_EXTENSION pde=fdo->DeviceExtension;
	
	if(pde->opencount > 0)
	{
		DebugPrint (("device already opened by other user..\n"));
		return STATUS_UNSUCCESSFUL;
	}
	else
	{
		pde->opencount++;
	
		status=STATUS_SUCCESS;

		DebugPrint (("device opened..\n"));
	}

	// create kernel mode event,shared with application use the same event name.
	if(!pde->EventCreated)
	{
		RtlInitUnicodeString(&pde->EventName,L"\\BaseNamedObjects\\WDTInterruptEvent");
		pde->pEvent = IoCreateNotificationEvent(&pde->EventName,&pde->hEvent);
		if(!pde->pEvent)
		{
			DebugPrint(("creat event error!\n"));
			return STATUS_UNSUCCESSFUL;
		}
		KeClearEvent(pde->pEvent);
		pde->EventCreated = TRUE;
		DebugPrint(("create event ok!\n"));
	}

	return CompleteIoReq(Irp,status,0);
}


NTSTATUS
DRV_Close(IN PDEVICE_OBJECT fdo,IN PIRP Irp)
/*++

Routine Description:

    When application called api "CloseHandle",system will called this routine.

Arguments:

    fdo - pointer to a function device object.
	Irp - pointer to an I/O Request Packet.

Return Value:

    TRUE  :called succeed.
    FALSE :called failed.

--*/
{
	
	PIO_STACK_LOCATION stack;
	PDEVICE_EXTENSION pde=fdo->DeviceExtension;

	if(pde->opencount>0)
		pde->opencount--;

	if(pde->EventCreated)
	{
		ZwClose(pde->hEvent);
		pde->EventCreated = FALSE;
	}

	DebugPrint (("device closed..\n"));
	
	return CompleteIoReq(Irp,STATUS_SUCCESS,0);
}


NTSTATUS 
DRV_IoCtrl(IN PDEVICE_OBJECT fdo, IN PIRP Irp)
/*++

Routine Description:
    This routine is the dispatch handler for the user IOCTL.  It is responsible
    for processing the IRPs.

Arguments:
    
    fdo - Pointer to device object.

    Irp - Pointer to the current IRP.

Return Value:

    STATUS_SUCCESS if the IRP was processed successfully, otherwise an error
    indicating the reason for failure.

--*/
{
	NTSTATUS			status;
	PIO_STACK_LOCATION	IrpStack;
	PDEVICE_EXTENSION	pde	= fdo->DeviceExtension;
	ULONG				IoctlCode;

	DebugPrint(("Enter IOCTRL process\n"));

	if(!pde->started)
		return CompleteIoReq( Irp, STATUS_DEVICE_NOT_CONNECTED, 0);
	status = IoAcquireRemoveLock(&pde->RemoveLock, Irp);
    if (!NT_SUCCESS(status)) 
	{
        DebugPrint(("Acquire RemoveLock failed\n" ));
        CompleteIoReq( Irp, status, 0 );
        return status;
    }
	
	IrpStack=IoGetCurrentIrpStackLocation(Irp);
	IoctlCode=IrpStack->Parameters.DeviceIoControl.IoControlCode;

	switch(IoctlCode)
	{
	case IOCTL_WDT_READ_PORT_UCHAR:
	case IOCTL_WDT_READ_PORT_USHORT:
    case IOCTL_WDT_READ_PORT_ULONG:

		status = WDTIoctlReadPort(
                            pde,
                            Irp,
                            IrpStack,
                            IoctlCode
                            );
        break;

    case IOCTL_WDT_WRITE_PORT_UCHAR:
	case IOCTL_WDT_WRITE_PORT_USHORT:
    case IOCTL_WDT_WRITE_PORT_ULONG:

        status = WDTIoctlWritePort(
                            pde,
                            Irp,
                            IrpStack,
                            IoctlCode
                            );
         break;

	case IOCTL_WDT_GET_HARDWARE_ID:
		status = WDTIoctlGetHardwareID(pde,
									   Irp,
									   IrpStack);
		break;

	case IOCTL_WDT_GET_PORT_INDEX:
		status = WDTIoctlGetPortIndex(pde,
									  Irp,
									  IrpStack);
		break;

	case IOCTL_WDT_GET_PORT_DATA:
		status = WDTIoctlGetPortData(pde,
									 Irp,
									 IrpStack);
		break;

	case IOCTL_WDT_IRQ_SEARCH_AUTO:
		status = IRQSearchAuto( fdo,
								Irp,
								IrpStack
								);
		break;

	case IOCTL_WDT_IRQ_USER_SET:
		status = IRQUserSet(fdo,
							Irp,
							IrpStack
							);
		break;

    default:      
        status = STATUS_INVALID_PARAMETER;
		CompleteIoReq( Irp, status, 0 );
		break;
	}
	
	IoReleaseRemoveLock(&pde->RemoveLock, Irp);
	return STATUS_SUCCESS;
	
}

NTSTATUS
WDTIoctlReadPort(
    IN PDEVICE_EXTENSION pde,
    IN PIRP Irp,
    IN PIO_STACK_LOCATION IrpStack,
    IN ULONG IoctlCode  )


/*++

Routine Description:
    This routine processes the IOCTLs which read from the ports.

Arguments:
    
    pde         - our device extention
    Irp         - IO request packet
    IrpStack    - The current stack location
    IoctlCode   - The ioctl code from the IRP

Return Value:
    STATUS_SUCCESS           -- OK

    STATUS_INVALID_PARAMETER -- The buffer sent to the driver
                                was too small to contain the
                                port, or the buffer which
                                would be sent back to the driver
                                was not a multiple of the data size.

    STATUS_ACCESS_VIOLATION  -- An illegal port number was given.

--*/

{
                                // NOTE:  Use METHOD_BUFFERED ioctls.
    PULONG pIOBuffer;           // Pointer to transfer buffer
                                //      (treated as an array of longs).
    ULONG InBufferSize;         // Amount of data avail. from caller.
    ULONG OutBufferSize;        // Max data that caller can accept.
    ULONG DataBufferSize;

    PAGED_CODE();

    // Size of buffer containing data from application
    InBufferSize  = IrpStack->Parameters.DeviceIoControl.InputBufferLength;

    // Size of buffer for data to be sent to application
    OutBufferSize = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;

    // NT copies inbuf here before entry and copies this to outbuf after
    // return, for METHOD_BUFFERED IOCTL's.
    pIOBuffer = (PULONG)Irp->AssociatedIrp.SystemBuffer;

    // Check to ensure input buffer is big enough to hold a port number and
    // the output buffer is at least as big as the port data width.
    //

    switch (IoctlCode)
    {
    case IOCTL_WDT_READ_PORT_UCHAR:
        DataBufferSize = sizeof(UCHAR);
        break;
	
    case IOCTL_WDT_READ_PORT_USHORT:
        DataBufferSize = sizeof(USHORT);
        break;

    case IOCTL_WDT_READ_PORT_ULONG:
        DataBufferSize = sizeof(ULONG);
        break;
	
    default:      
        return STATUS_INVALID_PARAMETER;

    }

    if ( InBufferSize != sizeof(ULONG) || OutBufferSize < DataBufferSize )
    {
        return STATUS_INVALID_PARAMETER;
    }

    // Buffers are big enough.
           
	pde->PortNumber = *pIOBuffer;		// Get the I/O port number from the buffer.

    if (pde->PortMemoryType == 1)
    {
        // Address is in I/O space
        
        switch (IoctlCode)
        {
        case IOCTL_WDT_READ_PORT_UCHAR:
            *(PUCHAR)pIOBuffer = READ_PORT_UCHAR(
                            (PUCHAR)((ULONG_PTR)pde->PortNumber) );
            break;
        case IOCTL_WDT_READ_PORT_USHORT:
            *(PUSHORT)pIOBuffer = READ_PORT_USHORT(
                            (PUSHORT)((ULONG_PTR)pde->PortNumber) );
            break;
        case IOCTL_WDT_READ_PORT_ULONG:
            *(PULONG)pIOBuffer = READ_PORT_ULONG(
                            (PULONG)((ULONG_PTR)pde->PortNumber) );
            break;
        default:      
            return STATUS_INVALID_PARAMETER;

        }
    } 
    else if (pde->PortMemoryType == 0)
    {
        // Address is in Memory space
        
        switch (IoctlCode)
        {
        case IOCTL_WDT_READ_PORT_UCHAR:
            *(PUCHAR)pIOBuffer = READ_REGISTER_UCHAR(
                            (PUCHAR)((ULONG_PTR)pde->PortNumber) );
            break;
        case IOCTL_WDT_READ_PORT_USHORT:
            *(PUSHORT)pIOBuffer = READ_REGISTER_USHORT(
                            (PUSHORT)((ULONG_PTR)pde->PortNumber) );
            break;
        case IOCTL_WDT_READ_PORT_ULONG:
            *(PULONG)pIOBuffer = READ_REGISTER_ULONG(
                            (PULONG)((ULONG_PTR)pde->PortNumber) );
            break;
        default:      
            return STATUS_INVALID_PARAMETER;

        }
    } 
    else
    {
        return STATUS_UNSUCCESSFUL;
    }

    //
    // Indicate # of bytes read,set Irp->IoStatus.Information
    //  
	CompleteIoReq(Irp,STATUS_SUCCESS,DataBufferSize);

    return STATUS_SUCCESS;
}


NTSTATUS
WDTIoctlWritePort(
    IN PDEVICE_EXTENSION pde, 
    IN PIRP Irp, 
    IN PIO_STACK_LOCATION IrpStack,
    IN ULONG IoctlCode
    )

/*++

Routine Description:
    This routine processes the IOCTLs which write to the ports.

Arguments:
    
    pde         - our device extention
    Irp         - IO request packet
    IrpStack    - The current stack location
    IoctlCode   - The ioctl code from the IRP

Return Value:
    STATUS_SUCCESS           -- OK

    STATUS_INVALID_PARAMETER -- The buffer sent to the driver
                                was too small to contain the
                                port, or the buffer which
                                would be sent back to the driver
                                was not a multiple of the data size.

    STATUS_ACCESS_VIOLATION  -- An illegal port number was given.

--*/

{
                                // NOTE:  Use METHOD_BUFFERED ioctls.
    PULONG pIOBuffer;           // Pointer to transfer buffer
                                //      (treated as array of longs).
    ULONG InBufferSize;			// Amount of data avail. from caller.
    ULONG DataBufferSize;

    PAGED_CODE();

    // Size of buffer containing data from application
    InBufferSize  = IrpStack->Parameters.DeviceIoControl.InputBufferLength;

    // NT copies inbuf here before entry and copies this to outbuf after return,
    // for METHOD_BUFFERED IOCTL's.
    pIOBuffer     = (PULONG) Irp->AssociatedIrp.SystemBuffer;
    
    // Check to ensure input buffer is big enough to hold a port number as well
    // as the data to write.
    //
    // The relative port # is a ULONG, and the data is the type appropriate to
    // the IOCTL.
    //

	DebugPrint (("Entered WdgIoctlWritePort\n"));

    switch (IoctlCode)
    {
    case IOCTL_WDT_WRITE_PORT_UCHAR:
        DataBufferSize = sizeof(UCHAR);
        break;
    case IOCTL_WDT_WRITE_PORT_USHORT:
        DataBufferSize = sizeof(USHORT);
        break;
    case IOCTL_WDT_WRITE_PORT_ULONG:
        DataBufferSize = sizeof(ULONG);
        break;

⌨️ 快捷键说明

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