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

📄 driver.c

📁 WinBond W83627 看门狗驱动
💻 C
字号:

/*++

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

    Driver.c  

Abstract:   WDT driver for Windows 2000/Windows XP.
			Driver Entry and Init Device.


Environment:

    Kernel mode


Author:    mz.yang  may, 2006


Revision History:

--*/

#include "Driver.h"
DRV_AddDevice


#pragma code_seg("INIT") // start INIT section

NTSTATUSDRV_Unload
(IN PDRIVER _OBJECT DriverObject,IN PDEVICE_OBJECT pdo);

void (IN PDRIVER_OBJECT DriverObject);

NTSTATUS DriverEntryFindDevice();



NTSTATUS 
(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
/*++

Routine Description:

    Installable driver initialization entry point.
    This entry point is called directly by the I/O system.

Arguments:

    DriverObject - pointer to the driver object

    RegistryPath - pointer to a unicode string representing the path,
                   to driver-specific key in the registry.

Return Value:

    STATUS_SUCCESS

--*/
{
	PDEVICE_OBJECT pdo = NULL;
	NTSTATUS status=STATUS_SUCCESS;

	UNREFERENCED_PARAMETER(RegistryPath);   //消除警告

	DebugPrint (("Entered Driver Entry\n"));

	DriverObject->DriverExtension->AddDevice=DRV_AddDevice;
	DriverObject->DriverUnload=DRV_Unload;
	//DriverObject->DriverStartIo=DRV_StartIo;
	DriverObject->MajorFunction[IRP_MJ_CREATE]= DRV_Open;
	DriverObject->MajorFunction[IRP_MJ_CLOSE]= DRV_Close;
	//DriverObject->MajorFunction[IRP_MJ_READ]=DRV_ReadWrite;
	//DriverObject->MajorFunction[IRP_MJ_WRITE]=DRV_ReadWrite;
	DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]= DRV_IoCtrl;
	DriverObject->MajorFunction[IRP_MJ_PNP]=DRV_PnPDispatch;
	//DriverObject->MajorFunction[IRP_MJ_POWER]=DRV_Power;

	return status;
}

#pragma code_seg() // end INIT section


#pragma code_seg("PAGE") // start PAGE section

VOID DRV_Unload(IN PDRIVER_OBJECT DriverObject)
/*++

Routine Description:

    Free all the allocated resources, etc.

Arguments:

    DriverObject - pointer to a driver object.

Return Value:

    VOID.

--*/
{
	DebugPrint(("Driver Unloading\n"));
}


NTSTATUS
CompleteIoReq(IN PIRP Irp,IN NTSTATUS status,IN ULONG info)
/*++

Routine Description:

    Complete the irps.

Arguments:
 
	Irp - pointer to an I/O Request Packet.

	status - NTSTATUS values.

	info - The transfer data length.

Return Value:

      NT status code

--*/
{
	Irp->IoStatus.Status=status;
	Irp->IoStatus.Information=info;
	IoCompleteRequest(Irp,IO_NO_INCREMENT);
	return status;
}


NTSTATUS
DRV_AddDevice(IN PDRIVER_OBJECT DriverObject,IN PDEVICE_OBJECT pdo)
/*++

Routine Description:

    The Plug & Play subsystem is handing us a brand new PDO, for which we
    (by means of INF registration) have been asked to provide a driver.

    We need to determine if we need to be in the driver stack for the device.
    Create a functional device object to attach to the stack
    Initialize that device object
    Return status success.

    Remember: we can NOT actually send ANY non pnp IRPS to the given driver
    stack, UNTIL we have received an IRP_MN_START_DEVICE.

Arguments:

    DeviceObject - pointer to a device object.

    pdo -  pointer to a device object created by the
                            underlying bus driver.

Return Value:

    NT status code.

--*/
{
	NTSTATUS			status=STATUS_SUCCESS;
	PDEVICE_OBJECT		fdo;
	PDEVICE_EXTENSION	pde;
	UNICODE_STRING		devname;
	POWER_STATE			NewState;
	WCHAR				namebuf[40];
	UNICODE_STRING      DeviceName;

	PAGED_CODE();

	// File system device name.   When you execute a CreateFile call to open the
	// device, use "\\.\WdtDev", or, given C's conversion of \\ to \, use
	// "\\\\.\\WdtDev"
	swprintf(namebuf,L"\\DosDevices\\WDTDev");
	RtlInitUnicodeString(&DeviceName, namebuf);
		
  	status=IoCreateDevice(DriverObject,
						  sizeof(DEVICE_EXTENSION),
						  &DeviceName,
						  FILE_DEVICE_UNKNOWN,
						  0,
						  FALSE,
						  &fdo);
		
	if(!NT_SUCCESS(status))
	{
		DebugPrint(("Create Device Fail\n"));
		return status;
	}

	//Device Object Operate
    pde=(PDEVICE_EXTENSION)fdo->DeviceExtension;

	// Find device.
	status = FindDevice(pde);
	if(!NT_SUCCESS(status))
	{
		DebugPrint(("no device found\n"));
		IoDeleteDevice(fdo);
		return status;
	}

	fdo->Flags |= DO_BUFFERED_IO;
	fdo->Flags &= ~DO_DEVICE_INITIALIZING;
	pde->StackDeviceObject=IoAttachDeviceToDeviceStack(fdo,pdo);

	//
    // This values is based on the hardware design.
    // Let us assume the address is in I/O space. 
    //
	pde->PortMemoryType = 1; 

	pde->started = FALSE;				// StartDevice will be true.
	pde->removing = FALSE;			// StopDevice will be true.
	pde->ConnectedToInterrupt = FALSE;	// connect interrupt will be true.
	pde->opencount = 0;				// create/open will increment.
	pde->EventCreated = FALSE;			// no application shared event create.
	pde->usage = 1;				// locked until StopDevice
	pde->ResourcesClaimed = FALSE;
	IoInitializeRemoveLock ( &pde->RemoveLock, 
                            'WDT', 
                            1, 
                            10);

	//Device Power State Initialize
	/*	
	pde->power=PowerDeviceD0; //Full power  state
	NewState.DeviceState = pde->power;
	PoSetPowerState(fdo,DevicePowerState,NewState);

	pde->idle=PoRegisterDeviceForIdleDetection(pdo,30,60*30,PowerDeviceD3);
	*/
	//Device PNP State Initialize
	
	//Initialize DeviceExtension I/O parameters
	//IoInitializeDpcRequest(fdo,DpcForIsr);

	DebugPrint(("AddDevice: %p to %p->%p \n", fdo, 
                      pde->StackDeviceObject,
                       pdo));
	return status;
}


NTSTATUS FindDevice(PDEVICE_EXTENSION	pde)
/*++

Routine Description:

    WDT is place in IC W83627THF/HF,and it place in mainboard when it made,So we
	must find the device first in AddDevice routine.when the device not find,
	we must return.

Arguments:

	pde - The device object extention.

Return Value:

    NT status code.

--*/
{
	NTSTATUS		status=STATUS_SUCCESS;
	UCHAR			HardwareID;
	UCHAR			Char0,Char1,Char2,Char3;
	BOOLEAN			Found = FALSE;

	PHYSICAL_ADDRESS PhysicalAddress;
	ULONG			Address;
	PULONG			Membase ; 


	PAGED_CODE();

	
	// Find EVOC mainboard flag,a string "EVOC" in memory register "ff500 ~ ff600".
	for(Address=0xff500;Address<=0xff600;Address++)
	{
		PhysicalAddress.QuadPart = Address;
		Membase =  MmMapIoSpace(PhysicalAddress,1, MmNonCached);	// Mapping physical address.
		if (Membase == NULL)
			return STATUS_NO_MEMORY;
		
		Char0 = (UCHAR)READ_REGISTER_ULONG( Membase );
		MmUnmapIoSpace(Membase, 1);

		if(Char0 == 0x45)		// Is "E".
		{	
			Address++;
			PhysicalAddress.QuadPart = Address;
			Membase = (PULONG) MmMapIoSpace(PhysicalAddress,1, MmNonCached);
			if (Membase == NULL)
				return STATUS_NO_MEMORY;
			Char1 = (UCHAR)READ_REGISTER_ULONG( Membase );
			MmUnmapIoSpace(Membase, 1);

			Address++;
			PhysicalAddress.QuadPart = Address;
			Membase = (PULONG) MmMapIoSpace(PhysicalAddress,1, MmNonCached);
			if (Membase == NULL)
				return STATUS_NO_MEMORY;
			Char2 = (UCHAR)READ_REGISTER_ULONG( Membase );
			MmUnmapIoSpace(Membase, 1);

			Address++;
			PhysicalAddress.QuadPart = Address;
			Membase = (PULONG) MmMapIoSpace(PhysicalAddress,1, MmNonCached);
			if (Membase == NULL)
				return STATUS_NO_MEMORY;
			Char3 = (UCHAR)READ_REGISTER_ULONG( Membase );
			MmUnmapIoSpace(Membase, 1);

			Address--;
			Address--;
			Address--;

			if((Char1==0x56) && (Char2==0x4f) && (Char3==0x43))	// Is "V","O","C".
			{
				break;
			}		
		}
	}
	
	if(Address > 0xff600)
	{
		return STATUS_UNSUCCESSFUL;
	}

	if(!Found)
	{
		// W83627,port 2e(index)/2f(data).
		// Start programming watch dog.
		WRITE_PORT_UCHAR( (PVOID)0x2e, 0x87 );
		WRITE_PORT_UCHAR( (PVOID)0x2e, 0x87 );

		//Active watch dog device
		WRITE_PORT_UCHAR( (PVOID)0x2e, 0x07 );
		WRITE_PORT_UCHAR( (PVOID)0x2f, 0x08 );		//logical device 8

		// Active watch dog device
		WRITE_PORT_UCHAR( (PVOID)0x2e, 0x30 );
		WRITE_PORT_UCHAR( (PVOID)0x2f, 0x01 );	

		//read IC is 627HF or 627THF or 627DHG
		WRITE_PORT_UCHAR( (PVOID)0x2e, 0x20 );
		HardwareID = READ_PORT_UCHAR( (PVOID)0x2f );
		WRITE_PORT_UCHAR( (PVOID)0x2e, 0xaa );		//end programming watch dog

		//0x52=HF,0x82=THF,0x88=EF/EHF/EG/EHG,0xA0=DHG
		if( (HardwareID == 0x52) || (HardwareID == 0x82) || 
			(HardwareID == 0x88) || (HardwareID == 0xA0))
		{
			pde->HardwareID = HardwareID;
			pde->PortIndex = 0x2e;
			pde->PortData = 0x2f;
			Found = TRUE;
		}
	}
	if(!Found)
	{	
		// W83627,port 4e(index)/4f(data).

		// Start programming watch dog.
		WRITE_PORT_UCHAR( (PVOID)0x4e, 0x87 );
		WRITE_PORT_UCHAR( (PVOID)0x4e, 0x87 );

		//Active watch dog device.
		WRITE_PORT_UCHAR( (PVOID)0x4e, 0x07 );
		WRITE_PORT_UCHAR( (PVOID)0x4f, 0x08 );		//logical device 8

		// Active watch dog device
		WRITE_PORT_UCHAR( (PVOID)0x4e, 0x30 );
		WRITE_PORT_UCHAR( (PVOID)0x4f, 0x01 );	

		//read IC is 627HF or 627THF or 627DHG.
		WRITE_PORT_UCHAR( (PVOID)0x4e, 0x20 );
		HardwareID = READ_PORT_UCHAR( (PVOID)0x4f );
		WRITE_PORT_UCHAR( (PVOID)0x4e, 0xaa );

		//0x52=HF,0x82=THF,0x88=EF/EHF/EG/EHG,0xA0=DHG.
		if( (HardwareID == 0x52) || (HardwareID == 0x82) || 
			(HardwareID == 0x88) || (HardwareID == 0xA0) )
		{
			pde->HardwareID = HardwareID;
			pde->PortIndex = 0x4e;
			pde->PortData = 0x4f;
			Found = TRUE;
		}	
	}

	if(!Found)
	{	
		// W83977,port 3f0(index)/3f1(data).

		// Start programming watch dog.
		WRITE_PORT_USHORT( (PVOID)0x3f0, 0x87 );
		WRITE_PORT_USHORT( (PVOID)0x3f0, 0x87 );

		//Active watch dog device.
		WRITE_PORT_USHORT( (PVOID)0x3f0, 0x07 );
		WRITE_PORT_USHORT( (PVOID)0x3f0, 0x08 );		//logical device 8

		// Active watch dog device
		WRITE_PORT_USHORT( (PVOID)0x3f0, 0x30 );
		WRITE_PORT_USHORT( (PVOID)0x3f1, 0x01 );	

		//read IC is 627HF or 627THF.
		WRITE_PORT_USHORT( (PVOID)0x3f0, 0x20 );
		HardwareID = (UCHAR)READ_PORT_USHORT( (PVOID)0x3f1 );
		WRITE_PORT_USHORT( (PVOID)0x3f0, 0xaa );

		//0x97=W83977.
		if( HardwareID == 0x97 )
		{
			pde->HardwareID = HardwareID;
			pde->ShortPortIndex = 0x3f0;
			pde->ShortPortData = 0x3f1;
			Found = TRUE;
		}	
	}
	if(!Found)
	{	
		// W83977,port 370(index)/371(data).

		// Start programming watch dog.
		WRITE_PORT_USHORT( (PVOID)0x370, 0x87 );
		WRITE_PORT_USHORT( (PVOID)0x370, 0x87 );

		//Active watch dog device.
		WRITE_PORT_USHORT( (PVOID)0x370, 0x07 );
		WRITE_PORT_USHORT( (PVOID)0x370, 0x08 );		//logical device 8

		// Active watch dog device
		WRITE_PORT_USHORT( (PVOID)0x370, 0x30 );
		WRITE_PORT_USHORT( (PVOID)0x371, 0x01 );	

		//read IC is 627HF or 627THF.
		WRITE_PORT_USHORT( (PVOID)0x370, 0x20 );
		HardwareID = (UCHAR)READ_PORT_USHORT( (PVOID)0x371 );
		WRITE_PORT_USHORT( (PVOID)0x370, 0xaa );

		//0x97=W83977..
		if( HardwareID == 0x97 )
		{
			pde->HardwareID = HardwareID;
			pde->ShortPortIndex = 0x370;
			pde->ShortPortData = 0x371;
			Found = TRUE;
		}	
	}

	if(!Found)
			status = STATUS_UNSUCCESSFUL;
	
	return status;
}
				
#pragma code_seg() // end PAGE section

⌨️ 快捷键说明

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