📄 driver.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 + -