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

📄 fancontrolor.cpp

📁 dell服务器的风扇控制器,带驱动源码,实现风扇转速的监测和控制.
💻 CPP
字号:
#include<windows.h>
#include<commctrl.h>
#include "resource.h"
//<-----------全局变量声明----->
//全局变量
HINSTANCE	hInst;//实例变量
HBRUSH bk_brush,fr_brush;//背景画刷
RECT Rt;//窗口RECT
HRGN DlgRgn,frRgn,tmpRgn;//窗口RGN
HDC hdc;
PAINTSTRUCT ps;
SC_HANDLE hSCObject;
HANDLE hFan;
char strSpeed[16],strSpeedRate[16];
int iSpeedRate=255;
UINT_PTR hGetSpeedTimer=NULL,hSetSpeedTimer=NULL;

//<--------------函数声明----------->

//主对话框过程函数
INT_PTR CALLBACK MainDlgProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
//风扇控制函数
int GetFanSpeed(HANDLE hFan);
void SetFanSpeedAuto(HANDLE hFan);
void SetFanSpeed(HANDLE hFan,int SpeedRate);//调节风扇速度,only for dell
//Opcode函数
int SendOpcode(HANDLE hFan,byte op1,byte op2,byte op3);
//<----------------------------驱动相关函数----------------------->
//装载风扇设备
DWORD LoadFanDevice();
////创建服务
	BOOL CreateFanService(SC_HANDLE hSCManager,LPCSTR lpDisplayName,LPCSTR lpBinaryPathName);
////启动服务
	BOOL StartFanService(SC_HANDLE hSCManager,LPCSTR lpServiceName);
//卸载风扇驱动
void UnLoadFanService();
///停止服务
	void StopFanService(SC_HANDLE hSCManager,LPCSTR lpServiceName);
////删除服务
	void DeleteFanService(SC_HANDLE hSCManager,LPCSTR lpServiceName);
//<------------------辅助函数-------------->
//警告框
void AlarmBox(LPSTR msg);
//绘制渐变背景
void OnEraseBkGnd(HWND hwnd);


//程序入口点
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{

	hInst = hInstance;
	LoadIcon(hInst,MAKEINTRESOURCE(IDI_LOGO));
	//<------------------装载风扇驱动------------------------------------->
	if(0xFFFFFFFF == (DWORD)(hFan=(HANDLE)LoadFanDevice()))
	{
		UnLoadFanService();
	}
	DialogBoxA(hInstance, MAKEINTRESOURCE(DLG_MAIN), 0, MainDlgProc);
	//<-------------卸载风扇驱动------------->
	UnLoadFanService();
	return 0;
}
//主对话框过程函数定义
INT_PTR CALLBACK MainDlgProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	int wmId, wmEvent;

	switch (message)
	{
		case WM_INITDIALOG :
		//<-------------------初始化界面--------------------------------------->
			GetWindowRect(hDlg, &Rt);
			DlgRgn = CreateRectRgn(0,0,0,0);
			frRgn = CreateRectRgn(0,0,0,0);
			tmpRgn = CreateRectRgn(0,0,0,0);
			CombineRgn(	DlgRgn,																		//保存创建的RGN---------创建窗口非标准RGN
				CreateEllipticRgn(0,0,Rt.bottom-Rt.top,Rt.bottom-Rt.top),							//圆形RGN
				CreateRectRgn((Rt.bottom-Rt.top)/2,0,Rt.right-Rt.left,Rt.bottom-Rt.top),			//矩形RGN
				RGN_OR);																			//叠加方式 
			CombineRgn(	tmpRgn,																		
				CreateEllipticRgn(1,1,Rt.bottom-Rt.top-1,Rt.bottom-Rt.top-1),						
				CreateRectRgn((Rt.bottom-Rt.top-1)/2,1,Rt.right-Rt.left-1,Rt.bottom-Rt.top-1),		
				RGN_OR);
			CombineRgn(frRgn,tmpRgn,DlgRgn,RGN_XOR);
			SetWindowRgn(hDlg, DlgRgn, TRUE);														//应用创建好的RGN 
			//<-----------------初始化控件-------------------------------------->
			CheckDlgButton(hDlg,IDC_AUTOCHECK,BST_CHECKED);
			SetDlgItemText(hDlg,IDC_FanSpeed,"侦测中");
			//限制输入长度
			SendMessage(GetDlgItem(hDlg,IDC_SPEEDRATE),(UINT)EM_SETLIMITTEXT,(WPARAM)0x3,NULL );  
				//----------加载GDI Object----------
			bk_brush=CreateSolidBrush(RGB(255,255,255));
			fr_brush=CreateSolidBrush(RGB(0,0,0));
			//<--------------------设置测速时间消息------------------------------->
			hGetSpeedTimer=SetTimer(hDlg,0x1,2000,NULL);
			return TRUE;
			break;
		//<------------画界面--------------------->
		case WM_PAINT:
			InvalidateRect(hDlg,NULL,TRUE);
			hdc=BeginPaint(hDlg,&ps);
			FillRgn(hdc,frRgn,fr_brush);
			EndPaint(hDlg,&ps);
			return FALSE;
			break;

		//<----------------------添加无标题栏拖动功能----------------------->
		case WM_LBUTTONDOWN:	
			SendMessage(hDlg,WM_NCLBUTTONDOWN,HTCAPTION, wParam);
			return TRUE;
			break;
	/*	//<---------------------添加无标题栏Alt+F4关闭功能------------------>
		case WM_SYSKEYUP:
			switch(wParam)
			{
			case VK_F4:
				if( (lParam & 0x20000000)!=0)
				{
					EndDialog(hDlg,0);
					return TRUE;
				}
				break;
			}
			return FALSE;
			break;
	*/
		//<-----------------处理时间消息-更新转速-设置转速-------->
		case WM_TIMER:
			switch(wParam)
			{
			case 0x1:
				wsprintf(strSpeed,"%d",GetFanSpeed(hFan));
				SetDlgItemText(hDlg,IDC_FanSpeed,strSpeed);
				return TRUE;
				break;
			case 0x2:
				memset(strSpeedRate,0,16);
				GetDlgItemText(hDlg,IDC_SPEEDRATE,strSpeedRate,4);
				if(strlen(strSpeedRate) == 3 &&  (iSpeedRate=atoi(strSpeedRate))<=255)
				{
					SetFanSpeed(hFan,iSpeedRate);
				}
				KillTimer(hDlg,hSetSpeedTimer);
				return TRUE;
				break;
			}
			return FALSE;
			break;
	
	//<----------------------------------改变颜色-------------------------->
		case WM_CTLCOLORDLG:
			return (INT_PTR)bk_brush;
			break;
	
		case WM_ERASEBKGND:
			OnEraseBkGnd(hDlg);
			return TRUE;
			break;
	
			
	//<----------------------------------关闭对话框------------------------>
		case WM_CLOSE:
			//----------卸载GDI Object-----------
			DeleteObject(bk_brush);DeleteObject(fr_brush);
			//---kill timer--------
			KillTimer(hDlg, hGetSpeedTimer);
			EndDialog(hDlg,0);
			return TRUE;
			break;
		case WM_COMMAND :
			wmId    = LOWORD(wParam); 
			wmEvent = HIWORD(wParam); 
			switch(wmId)
			{
			case IDC_AUTOCHECK:
				 if (IsDlgButtonChecked(hDlg,IDC_AUTOCHECK) == BST_CHECKED)
				 {
					 EnableWindow(GetDlgItem(hDlg,IDC_SPEEDRATE),FALSE);
					 SetFanSpeedAuto(hFan);
				 }
				 else
				 {
					 EnableWindow(GetDlgItem(hDlg,IDC_SPEEDRATE),TRUE);
				 }
				 return TRUE;
				 break;
			case IDC_SPEEDRATE:
				if(wmEvent == EN_CHANGE)
				{
					memset(strSpeedRate,0,16);
					GetDlgItemText(hDlg,IDC_SPEEDRATE,strSpeedRate,4);
					if(strlen(strSpeedRate) == 3 && (iSpeedRate=atoi(strSpeedRate))<=255 )
					{
						hSetSpeedTimer=SetTimer(hDlg,0x2,3000,NULL);
					}
				}
				return TRUE;
				break;
			default:
				return FALSE;
			}
			break;
		default: 
			return FALSE;
	}
	return FALSE;
}

//警告框定义
void AlarmBox(LPSTR msg)
{
	MessageBox(NULL,msg,"Alarm",MB_OK);
}
//装载风扇设备定义
DWORD LoadFanDevice()
{
	char TempPath[256],FilePath[256];//临时文件名
	DWORD dwNumberOfBytesWritten,dwNumberOfBytesToWrite;
	LPVOID pDriverFile;
	DWORD dwRET=0xFFFFFFFF;
	HRSRC hrsrcDriver;
	HANDLE hDriverFile;

	if( hSCObject = OpenSCManager(NULL,NULL,0x000F003F) )
	{
		if( hrsrcDriver=FindResource(NULL,"FanDriver","SYS"))
		{
			if( (pDriverFile=LockResource(LoadResource(NULL,hrsrcDriver))) && (dwNumberOfBytesToWrite=SizeofResource(NULL,hrsrcDriver)))
			{
				GetTempPath(256,TempPath);
				wsprintf(FilePath,"%sdump%x.tmp",TempPath,GetTickCount());
				if( ( hDriverFile = CreateFile(FilePath,GENERIC_WRITE,NULL,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_TEMPORARY,NULL)) != INVALID_HANDLE_VALUE)
				{
					WriteFile(hDriverFile,pDriverFile,dwNumberOfBytesToWrite,&dwNumberOfBytesWritten,NULL);
					CloseHandle(hDriverFile);
					if ( CreateFanService(hSCObject,"#!#!",FilePath))
					{
						if( StartFanService(hSCObject,"#!#!"))
						{
							dwRET = (DWORD)CreateFile("\\\\.\\#!#!",GENERIC_WRITE|GENERIC_READ,NULL,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
						}
					}
					//<-----------删除文件----------->
					DeleteFile(FilePath);
					return dwRET;
				}
			}
		}
	}
	return dwRET;
}


////创建服务定义
	BOOL CreateFanService(SC_HANDLE hSCManager,LPCSTR lpDisplayName,LPCSTR lpBinaryPathName)
	{
		SC_HANDLE hFanService;
		if( NULL == (hFanService= CreateService(hSCManager,lpDisplayName,lpDisplayName,
												SERVICE_ALL_ACCESS,SERVICE_KERNEL_DRIVER,SERVICE_DEMAND_START,SERVICE_ERROR_NORMAL,lpBinaryPathName,
												NULL,NULL,NULL,NULL,NULL)))
		{
			if(GetLastError() != ERROR_SERVICE_EXISTS)
			{
				AlarmBox("CreateService failed!");
				return FALSE;
			}
		}
		CloseServiceHandle(hFanService);
		return TRUE;
	}
////启动服务定义
	BOOL StartFanService(SC_HANDLE hSCManager,LPCSTR lpServiceName)
	{
		SC_HANDLE hFanService;

		if( hFanService=OpenService(hSCManager,lpServiceName,SERVICE_ALL_ACCESS))
		{
			if(FALSE==StartService(hFanService,NULL,NULL))
			{
				if(GetLastError() != ERROR_SERVICE_ALREADY_RUNNING)
				{
					AlarmBox("StartService failed!");
					return FALSE;
				}
			}
				CloseServiceHandle(hFanService);
				return TRUE;
		}
		AlarmBox("OpenService failed!  Error");
		return FALSE;
	}
//卸载风扇驱动定义
void UnLoadFanService()
{
	if(hSCObject!=NULL)
	{
		StopFanService(hSCObject,"#!#!");
		DeleteFanService(hSCObject,"#!#!");
		CloseServiceHandle(hSCObject);
	}
	return;
}
///停止服务定义
	void StopFanService(SC_HANDLE hSCManager,LPCSTR lpServiceName)
	{
		SERVICE_STATUS ServiceStatus;
		SC_HANDLE hFanService;

		if( !(hFanService=OpenService(hSCManager,lpServiceName,SERVICE_ALL_ACCESS))) 
		{
			AlarmBox("OpenService failed!  Error");
			return;
		}
		if( !(ControlService(hFanService,SERVICE_CONTROL_STOP,&ServiceStatus)))
		{
			AlarmBox("ControlService failed!");
		}
		CloseServiceHandle(hFanService);
		return;

	}
////删除服务定义
	void DeleteFanService(SC_HANDLE hSCManager,LPCSTR lpServiceName)
	{
		SC_HANDLE hFanService;

		if( !(hFanService=OpenService(hSCManager,lpServiceName,SERVICE_ALL_ACCESS))) 
		{
			AlarmBox("OpenService failed!  Error");
			return;
		}
		if(!(DeleteService(hFanService)))
		{
			AlarmBox("DeleteService failed!  Error");
			return;
		}
		CloseServiceHandle(hFanService);
	}

//得到风扇转速定义
int GetFanSpeed(HANDLE hFan)
{
	WORD speed;
	speed=(WORD)SendOpcode(hFan,(byte)2,(byte)0,(byte)0);
	return (DWORD)speed;
}
//自动调节速度
void SetFanSpeedAuto(HANDLE hFan)
{
	SendOpcode(hFan,(byte)1,(byte)3,(byte)0);
}
//设置风扇转速
void SetFanSpeed(HANDLE hFan,int SpeedRate)
{
	SendOpcode(hFan,0x1,0x80,SpeedRate);
}
//Opcode函数定义
int SendOpcode(HANDLE hFan,byte op1,byte op2,byte op3)
{
	DWORD BytesReturned;
	byte buffer[8];
	WORD RetValue;

	memset((LPVOID)buffer,0,8);
	buffer[0]=op1;
	buffer[1]=op2;
	buffer[2]=op3;
	if(DeviceIoControl(hFan,0x80012000,buffer,6,buffer,6,&BytesReturned,NULL))
	{
		RetValue=*((LPWORD)&buffer[4]);
		if(RetValue!=0xFFFF)
			return RetValue;
	}
	return 0xFFFFFFFF;
}
//绘制渐变背景
void OnEraseBkGnd(HWND hwnd)
{
    /* Vars */
    HDC dc; /* Standard Device Context; used to do the painting */

	/* Start color; Change the R,G,B values 
    to the color of your choice */
    int r1 =255, g1 =255, b1 = 255;
    
    /* End Color; Change the R,G,B values 
    to the color of your choice */
    int r2 = 0, g2 = 204, b2 = 255;

	/* Color ref. for the gradient */
    int r,g,b; 

	int i;
    
    /* rect = Client Rect of the window; 
    Temp = Temparary rect tangle for the color bands */
    RECT rect, temp; 
    HBRUSH color; /* A brush to do the painting with */
    
    /* Get the dc for the wnd */
    dc = GetDC(hwnd);
    
    /* Get the client rect */
    GetClientRect(hwnd, &rect);
    

    
    /* loop to create the gradient */
    for(i=0;i<rect.right;i++) 
    { 

        /* Determine the colors */
		if(i<=48)
		{
			r=255;g=255;b=255;
		}
		else
		{
			r = r1 + ((i-48) * (r2-r1) / rect.right); 
			g = g1 + ((i-48) * (g2-g1) / rect.right);
			b = b1 + ((i-48) * (b2-b1) / rect.right);
		}
        
        /* Fill in the rectangle information */
        
        /* The uper left point of the rectangle 
        being painted; uses i as the starting point*/
        temp.left = i;
        /* Upeer Y cord. Always start at the top */ 
        temp.top = 0; 
        /* Okay heres the key part, 
        create a rectangle thats 1 pixel wide */
        temp.right = i + 1; 
        /* Height of the rectangle */
        temp.bottom = rect.bottom; 
        
        /* Create a brush to draw with; 
        these colors are randomized */
        color = CreateSolidBrush(RGB(r, g, b));
        
        /* Finally fill in the rectange */
        FillRect(dc, &temp, color);
    }
}

⌨️ 快捷键说明

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