定时关机重启注销源码
第一个ASM程序,终于写了一个比Hello Word稍微复杂一点的程序了。这个程序断断续续的写了很长的时间,其间在一边学习ASM,一边写这个小程序。利用这个程序学到不少汇编方面的知识。今天 终于将这个程序给写结束了,Win32 ASM算是入门了,下面就是找个新的主意进行练手了。
下面贴上代码:
;**********************************************************************
;功能:定时关闭/重启/注销计算机
;描述:这是本人第一个Win32 ASM程序,习作请多多指教.
;作者:Lonkil
;网站:http://www.vcfans.com
;邮箱:lonkil_AT_gmail.com
;**********************************************************************
.386
.model flat,stdcall
option casemap:none
include windows.inc
include user32.inc
include kernel32.inc
include gdi32.inc
include advapi32.inc
include shell32.inc
includelib user32.lib
includelib gdi32.lib
includelib kernel32.lib
includelib advapi32.lib
includelib shell32.lib
DlgProc proto :DWORD,:DWORD,:DWORD,:DWORD;申明窗口回调函数
ShutdownMachine proto :DWORD;如果是1:关机,2:重启,3:注销
RunAction proto :Byte
InitDlg proto :HWND;初始化对话框
ChangTaskIcon proto :HWND,:DWORD
ShowCurTime proto :HWND;实时显示当前计算机时间
SetApplyButtonText proto:HWND;设置应用按钮标题
.const
IDD_MAIN equ 102;对话框资源ID
IDI_START equ 129;对话框图标ID
IDI_NOTSTART equ 131;未设置时任务栏图标ID
IDC_ACTION equ 1004;选择的列表框图标ID
IDC_BTN_APPLY equ 1005;应用按钮
IDC_SYSTIME equ 1008;Group Box’ID
WM_TASKICON equ WM_USER+12
IDC_DATE equ 1001
IDC_TIME equ 1002
.data
ShutDownParam db “SeShutdownPrivilege”,0
g_szActShutDown db “关机”,0
g_szActSignOut db “注销”,0
g_szActRestart db “重启”,0
g_szTips db “欢迎使用本关机程序”,0
g_szCurTimeFormat db “%d-%02d-%02d %02d:%02d:%02d”,0
g_szActBTNText db “应用%s设置”,0
g_szNoActBTNText db “取消%s设置”,0
.data?
hInstance dd ?;对话框实例
hIconNormal dd ?;对话框图标句柄
hAction dd ?;列表框句柄
g_szCurTime db 32 dup (?)
g_szApplyBtnText db 256 dup(?)
tnid NOTIFYICONDATA <?>
g_bIsHasAction db ?;是否已执行操作0:未执行,1:已执行
g_bActionType db ?
g_targetDateTime SYSTEMTIME <?>;目标的日期
.code
;设置应用按钮标题
SetApplyButtonText proc hwnd:HWND
local hAct:HWND
local hApply:HWND
local szTemp[256]:BYTE
invoke RtlZeroMemory,addr szTemp,256
.if g_bIsHasAction == 0
;未执行动作
invoke lstrcpy,addr szTemp, addr g_szActBTNText
.else
;已执行
invoke lstrcpy,addr szTemp, addr g_szNoActBTNText
.endif
invoke GetDlgItem, hwnd, IDC_BTN_APPLY
mov hApply,eax
invoke GetDlgItem, hwnd, IDC_ACTION
mov hAct,eax
invoke SendMessage,hAct,CB_GETCURSEL,0,0
.if eax == 0
;关机
mov g_bActionType,0
invoke wsprintf,offset g_szApplyBtnText,addr szTemp,offset g_szActShutDown
.elseif eax == 1
;重启
mov g_bActionType,1
invoke wsprintf,offset g_szApplyBtnText,addr szTemp,offset g_szActRestart
.elseif eax == 2
;注销
mov g_bActionType,2
invoke wsprintf,offset g_szApplyBtnText,addr szTemp,offset g_szActSignOut
.endif
invoke SetWindowText,hApply,offset g_szApplyBtnText
ret
SetApplyButtonText endp
;实时显示当前计算机时间
ShowCurTime proc hwnd:HWND
local stCur:SYSTEMTIME
local ctrlCurTime:HWND
pushad
invoke GetLocalTime,addr stCur
movzx eax, stCur.wYear
movzx ebx, stCur.wMonth
movzx ecx, stCur.wDay
movzx edx, stCur.wHour
movzx esi, stCur.wMinute
movzx edi, stCur.wSecond
invoke wsprintf, offset g_szCurTime, offset g_szCurTimeFormat, eax, ebx, ecx, edx, esi, edi
invoke GetDlgItem,hwnd,IDC_SYSTIME
mov ctrlCurTime,eax
invoke SetWindowText,ctrlCurTime,offset g_szCurTime
popad
ret
ShowCurTime endp
;改变任务栏图标和提示信息
ChangTaskIcon proc hwnd:HWND,nType:DWORD
pushad
mov tnid.cbSize,sizeof NOTIFYICONDATA
push hwnd
pop tnid.hwnd
mov tnid.uID, 0
mov tnid.uFlags,NIF_MESSAGE+NIF_ICON+NIF_TIP
mov tnid.uCallbackMessage,WM_TASKICON
push hIconNormal
pop tnid.hIcon
invoke lstrcpy, addr tnid.szTip, addr g_szTips
invoke Shell_NotifyIcon, NIM_ADD, addr tnid
popad
ret
ChangTaskIcon endp
;设置时期控件是否有效,日期和时间控件,有效变无效,无效变有效。
SetDateCtrlState proc hwnd:HWND
local hDate:HWND;日期控件句柄
local hTime:HWND;时间控件句柄
pushad
invoke GetDlgItem,hwnd,IDC_DATE
test eax,eax
je @F
mov hDate,eax
invoke IsWindowEnabled,hDate
mov edx,1
sub edx,eax
invoke EnableWindow, hDate,edx
@@:
invoke GetDlgItem,hwnd,IDC_TIME
test eax,eax
je @F
mov hTime,eax
invoke IsWindowEnabled,hTime
mov edx,1
sub edx,eax
invoke EnableWindow, hTime,edx
@@:
popad
ret
SetDateCtrlState endp
;初始化窗口函数
InitDlg proc hwnd:HWND
local nScreenW :DWORD;屏幕宽
local nScreenH :DWORD;屏幕高
local rtWindow :RECT;窗口大小
local nX:DWORD
local nY:DWORD
pushad
invoke ShowCurTime,hwnd;更新当前时间
invoke LoadIcon,hInstance,IDI_START
mov hIconNormal,eax
invoke SendMessage, hwnd, WM_SETICON, ICON_SMALL, eax
invoke GetDlgItem, hwnd, IDC_ACTION
mov hAction,eax
invoke SendMessage, hAction, CB_ADDSTRING, 0, offset g_szActSignOut
invoke SendMessage, hAction, CB_ADDSTRING, 0, offset g_szActRestart
invoke SendMessage, hAction, CB_ADDSTRING, 0, offset g_szActShutDown
invoke PostMessage, hAction, CB_SETCURSEL, 0, 0
;初始化列表框
invoke GetSystemMetrics, SM_CXSCREEN
mov nScreenW,eax
invoke GetSystemMetrics, SM_CYSCREEN
mov nScreenH,eax
invoke GetWindowRect,hwnd,addr rtWindow
mov ebx,nScreenW
mov ecx,rtWindow.right
sub ecx,rtWindow.left
sub ebx,ecx;x坐标
mov nX,ebx
push ecx;将宽压栈
mov eax,nScreenH
mov edx,rtWindow.bottom
sub edx,rtWindow.top
sub eax,edx;y坐标
mov nY,eax
push edx;将高压栈
mov ecx,2
xor edx,edx
mov eax,nX
div ecx
mov nX, eax
xor edx,edx
mov eax,nY
div ecx
mov nY,eax
pop edx;高
pop ecx;宽
invoke MoveWindow, hwnd,nX,nY,ecx,edx,TRUE
;将对框移动屏幕中央
mov g_bActionType,0;默认关机操作
mov g_bIsHasAction,0
invoke SetTimer,hwnd,1,1000,NULL;一秒更新一次时间
popad
ret
InitDlg endp
;关机主程序
ShutDownMachine proc nType:Byte
local hToken:HANDLE
local Version:DWORD
local tp:TOKEN_PRIVILEGES
pushad
invoke GetVersion
mov Version,eax;得到版本号
.if Version < 80000000h;Windows NT
invoke RtlZeroMemory, addr tp, sizeof TOKEN_PRIVILEGES
invoke GetCurrentProcess
mov ebx,eax
invoke OpenProcessToken,ebx, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY,addr hToken;得到令牌
invoke LookupPrivilegeValue,NULL,addr ShutDownParam,addr tp.Privileges.Luid;根据特权名得到全局标识
mov tp.PrivilegeCount , 1
mov tp.Privileges.Attributes , SE_PRIVILEGE_ENABLED
invoke AdjustTokenPrivileges, hToken,FALSE, addr tp,0,NULL,0;提权
invoke RunAction, nType
mov tp.Privileges.Attributes , 0
invoke AdjustTokenPrivileges, hToken,FALSE, addr tp,0,NULL,0;还原权限
invoke CloseHandle,hToken
.elseif;win32s,such as win98,win95
invoke RunAction, nType
.endif
popad
ret
ShutDownMachine endP
;执行实际动作
RunAction proc nT:Byte
.if nT == 0
;关机并关闭电源
invoke ExitWindowsEx,EWX_SHUTDOWN+EWX_FORCE+EWX_POWEROFF,0
.elseif nT == 1
;重启
invoke ExitWindowsEx,EWX_REBOOT+EWX_FORCE,0
.elseif nT == 2
;注销
invoke ExitWindowsEx,EWX_LOGOFF+EWX_FORCE,0
.endif
ret
RunAction endp
GetTargetDate proc hWnd:HWND
local dateCtrl:HWND
local timeCtrl:HWND
local TempTime:SYSTEMTIME
local CurTime:SYSTEMTIME
local TempFileTime: FILETIME
local CurFileTime: FILETIME
pushad
invoke GetDlgItem,hWnd,IDC_DATE
mov dateCtrl,eax
invoke GetDlgItem,hWnd,IDC_TIME
mov timeCtrl,eax
invoke SendMessage,dateCtrl,DTM_GETSYSTEMTIME, NULL, offset g_targetDateTime
invoke SendMessage,timeCtrl,DTM_GETSYSTEMTIME, NULL, addr TempTime
mov ax,TempTime.wHour
mov g_targetDateTime.wHour,ax
mov ax,TempTime.wMinute
mov g_targetDateTime.wMinute,ax
mov ax,TempTime.wSecond
mov g_targetDateTime.wSecond,ax
popad
ret
GetTargetDate endp
;检测设定时间是否到达如到达则执行相关的操作
CheckTime proc hWnd:HWND
local stCur:SYSTEMTIME
pushad
invoke GetLocalTime,addr stCur
movzx eax, stCur.wYear
movzx ebx, stCur.wMonth
movzx ecx, stCur.wDay
movzx edx, stCur.wHour
movzx esi, stCur.wMinute
movzx edi, stCur.wSecond
.if ax == g_targetDateTime.wYear && bx == g_targetDateTime.wMonth && cx == g_targetDateTime.wDay && dx == g_targetDateTime.wHour && g_targetDateTime.wMinute == si && di == g_targetDateTime.wSecond
dec g_bIsHasAction
invoke SetDateCtrlState,hWnd
invoke ShutDownMachine, g_bActionType
.endif
popad
ret
CheckTime endp
DlgProc proc hWnd,Umsg,wParam,lParam;窗口回调函数程序实现
.if Umsg == WM_INITDIALOG;窗口初始化
invoke InitDlg,hWnd
.elseif Umsg == WM_TASKICON;任务栏响应的消息
mov eax, lParam
.if eax == WM_LBUTTONDOWN || eax == WM_RBUTTONDOWN
invoke Shell_NotifyIcon, NIM_DELETE, addr tnid
invoke ShowWindow,hWnd,SW_SHOW
.endif
.elseif Umsg == WM_SYSCOMMAND
mov eax,wParam
.if eax == SC_MINIMIZE && g_bIsHasAction == 1
invoke Shell_NotifyIcon, NIM_ADD, addr tnid
invoke ShowWindow,hWnd,SW_HIDE
mov eax,TRUE;如果不返回TRUE任务栏将还会看到程序
.else
mov eax,FALSE;让系统处理其他消息
.endif
ret
.elseif Umsg == WM_COMMAND
mov eax,wParam
and eax,0ffffh
.if eax == IDCANCEL
invoke PostMessage,hWnd,WM_CLOSE,wParam,lParam
.elseif eax == IDC_BTN_APPLY;执行应用
invoke SetDateCtrlState,hWnd
invoke ChangTaskIcon,hWnd,0
.if g_bIsHasAction == 0
invoke GetTargetDate,hWnd;应用设置日期
invoke Shell_NotifyIcon, NIM_ADD, addr tnid
invoke ShowWindow,hWnd,SW_HIDE
inc g_bIsHasAction
.else
dec g_bIsHasAction
.endif
invoke SetApplyButtonText,hWnd
.elseif eax == IDC_ACTION
mov eax,wParam
SHR eax,16;取wParam高16位
.if eax == CBN_SELCHANGE;动作列表被选择
invoke SetApplyButtonText,hWnd
.endif
.endif
.elseif Umsg == WM_CLOSE
invoke KillTimer,hWnd,1
invoke Shell_NotifyIcon, NIM_DELETE, addr tnid
invoke EndDialog,hWnd,wParam
.elseif Umsg == WM_TIMER
invoke ShowCurTime,hWnd;更新当前时间
.if g_bIsHasAction == 1
invoke CheckTime,hWnd
.endif
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
DlgProc EndP
start:
invoke GetModuleHandle,NULL
mov hInstance,eax;得到应用程序模块句柄
invoke DialogBoxParam,hInstance,IDD_MAIN,NULL,offset DlgProc,0
invoke ExitProcess,NULL
end start
