附件下载
-----------------------------------------------
1.C源代码中有一处遗漏, 会导致驱动向应用程序返回结果错误, 在DellFanDriver.c中
2.逆向分析的IDB文件中, INIT:00010818处有个笔误, 这一行中的IRP_DEVICE_CONTROL应该是IRP_MJ_DEVICE_CONTROL, 中间丢了"MJ"
3.DispatchIoControl函数中一处数据结构分析有误, 已修正
刚开学天天赋闲, 无聊中翻起老帖, 无意中看到Isaiah兄写的控制Dell风扇的程序, 可惜的是没有驱动源码, 于是心血来潮, 搞了三个小时, 终于把Dell风扇控制驱动的源码搞定了, 附件里有全部C源码和IDA分析生成的IDB文件(需要IDA4.9或者看雪论坛的5.0版本方可正常打开), 另外工程中附带了Isaiah兄写的程序(没有修改)供大家参考, 在此对Isaiah兄表示感谢
Isaiah兄的帖子
http://bbs.pediy.com/showthread.php?s=&threadid=27805&highlight=dell
限于本人水平, 加之驱动没有测试过, 程序中错误和疏漏一定不少, 明天我会到学校机房找一台dell机器测试一下, 如果有错误还请各位多多指教.
由于懒得写驱动程序中那一堆令人厌烦的例行公事式的代码, 程序的框架是用DriverWorks生成的(没有用Driver C++ FrameWork). 所以源代码中基本上是框架代码, 控制风扇的核心在于DispatchIoControl函数中(C源码中对应的函数名是DellFanDriverDeviceIoControlDispatch, DriverWorks生成的函数名),大家也只需要看这个函数就可以了, 如果想看全部代码请看打开IDB文件看, 那儿的代码要简洁明了很多.
另外还有一点要说明的,驱动源码中更改了设备名称和符号链接名, 因为我觉得原来的太丑了
原设备名为\Device\#!#!
原符号链接名为\DosDevices\#!#!
源代码中设备名为\Device\DellFanDriver
符号链接名为\??\DellFanDriver
打开驱动的时候, CreateFile指定的文件名也要做相应修改
代码中, 直接操作风扇的是这两句
out 0B2h, al;Interrupt Controller #2, 8259A
out 84h, al;
------------------------------------------------------------------------------------------------
以下就是驱动控制风扇的代码(只列出最核心的函数, 其他不是很重要的可以去看附件中的代码和IDB文件)
两个"//*************"之间的是核心
代码:
///////////////////////////////////////////////////////////////////////////////////////////////////
// DellFanDriverDeviceIoControlDispatch
// Dispatch routine for IRP_MJ_DEVICE_CONTROL requests.
//
// Arguments:
// IN DeviceObject
// pointer to the device object for our device
//
// IN Irp
// the device i/o control IRP
//
// Return Value:
// NT status code.
//
NTSTATUS DellFanDriverDeviceIoControlDispatch(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PIO_STACK_LOCATION irpStack;
NTSTATUS status;
PDELLFANDRIVER_DEVICE_EXTENSION deviceExtension;
PVOID inputBuffer;
ULONG inputLength;
PVOID outputBuffer;
ULONG outputLength;
ULONG minBufferLen;
PVOID sysBuffer;
ULONG var1, var2, var3;
USHORT result;
DellFanDriverDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__"++. IRP %p", Irp);
deviceExtension = (PDELLFANDRIVER_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
// Get our IRP stack location
irpStack = IoGetCurrentIrpStackLocation(Irp);
// Get the buffer lengths
inputLength = irpStack->Parameters.DeviceIoControl.InputBufferLength;
outputLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
switch (irpStack->Parameters.DeviceIoControl.IoControlCode)
{
case CTL_CODE(0x8001, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS):
//minimal buffer size requirement
minBufferLen = 6;
//check buffer length
if (inputLength < minBufferLen || outputLength < minBufferLen)
{
DellFanDriverDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__":I/O Bufferlength %X | %X is too small\n",inputLength, outputLength);
status = STATUS_BUFFER_TOO_SMALL;
}
else
{
//bytes transfered
Irp->IoStatus.Information = minBufferLen;
//************************************************************************************
//get buffer
sysBuffer = Irp->AssociatedIrp.SystemBuffer;
var1 = ((ULONG)((PUCHAR)sysBuffer)[0] << 8) | 0xA3;
var2 = (ULONG)((PUCHAR)sysBuffer)[1] << 8;
var3 = (ULONG)((PUCHAR)sysBuffer)[2];
__asm
{
pushad;
mov ebx, var2;
mov ecx, var3;
mov eax, var1;
out 0B2h, al;Interrupt Controller #2, 8259A
out 84h, al;
mov result, ax;
popad;
}
((PUSHORT)sysBuffer)[4/sizeof(USHORT)] = result;
status = STATUS_SUCCESS;
//************************************************************************************
DellFanDriverDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__"Fan control result:%4X", (ULONG)result);
}
Irp->IoStatus.Status = status;
IoCompleteRequest (Irp, IO_NO_INCREMENT);
break;
default:
status = STATUS_INVALID_DEVICE_REQUEST;
Irp->IoStatus.Status = status;
IoCompleteRequest (Irp, IO_NO_INCREMENT);
break;
}
DellFanDriverDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__"--. IRP %p STATUS %x", Irp, status);
return status;
}