VC驿站

 找回密码
 加入驿站

QQ登录

只需一步,快速开始

有编程疑问吗?还请到提问专区发帖提问!
搜索
查看: 559|回复: 1

[交流] C语言黑客教程第三课 带界面的开关机、注销(日常打卡)

[复制链接]
31_avatar_middle
在线会员 Eirik 发表于 2018-5-1 12:32:48 | 显示全部楼层 |阅读模式
#include <windows.h>
#include "resource.h"

BOOL ReSetPrivilege(DWORD dwFlags,BOOL bForce);//根据版本,判断是否要提升权限
BOOL SystemShutdown();//给与权限
BOOL CALLBACK DlgProc(HWND hDlg,UINT uMsg,WPARAM wParam,LPARAM lParam);


int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR CmdLine,int nCmdShow)//GUI程序  入口函数 WinMain
{
        //创建非模态dialog
        HWND hDlg = CreateDialog(GetModuleHandle(NULL),MAKEINTRESOURCE(IDD_DLG),NULL,DlgProc);
        ShowWindow(hDlg,nCmdShow);
        //系统不会为非模态对话框提供消息环,使用应用程序本身消息
        //系统会为模态对话框提供消息环
        MSG msg;
        while (GetMessage(&msg,NULL,0,0))
        {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
        }

        return 0;

}

BOOL ReSetPrivilege(DWORD dwFlags, BOOL bForce)
{
        //check the param 检测参数
        if (dwFlags != EWX_LOGOFF && dwFlags != EWX_REBOOT && dwFlags != EWX_SHUTDOWN)
        {//既不是注销 又不是重启、关机 则返回FALSE
                return FALSE;
        }
        //get the current os version获得当前系统的版本号
        OSVERSIONINFO osvi = {0};
        //将该结构体中的所有值初始化为0,OSVERSIONINFO为GetVersionEx()函数中的结构体
        osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
        //获取结构体大小,用于判断新旧版本OSVERSIONINFO和OSVERSIONINFOEX
        if (!GetVersionEx(&osvi))
        {//判断GetVersion()是否运行成功
                return FALSE;
        }
        if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT)
        {
                SystemShutdown();//提升当前进程的权限
        }
        dwFlags |= (bForce == TRUE)? EWX_FORCE:EWX_FORCEIFHUNG;
        //(1)&分离 (2)|组合            三目条件运算符

        return ExitWindowsEx(dwFlags,0);
}

BOOL SystemShutdown()
{
        HANDLE hToken = NULL;
        TOKEN_PRIVILEGES tkp = {0};
        //OpenProcessToken() 这个函数的作用是打开一个进程的访问令牌
        //GetCurrentProcess() 函数的作用是得到当前进程的句柄
        if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
        {
                return FALSE;
        }
        // LookupPrivilegeValue() 的作用是修改进程的权限
        LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,&tkp.Privileges[0].Luid);
        tkp.PrivilegeCount = 1; // one privilege to set 赋给本进程特权
        tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
        // AdjustTokenPrivileges()的作用是通知Windows NT修改本进程的权利
        AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,(PTOKEN_PRIVILEGES)NULL, 0);
        if (GetLastError() != ERROR_SUCCESS) //失败
        {
                return FALSE;
        }
        if (!ExitWindowsEx(EWX_POWEROFF | EWX_FORCE, 0)) //参数在这里设置。强行退出WINDOWS(EWX_FORCE)。
        {
                return FALSE;
        }

        return TRUE;
}
BOOL CALLBACK DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
        switch (uMsg)
        {
                case WM_INITDIALOG:
                {
                        RECT rtDlg;
                        GetWindowRect(hDlg,&rtDlg);//GetWindowRect获取对话框窗口大小
                        int nX = GetSystemMetrics(SM_CXSCREEN)/2 - (rtDlg.right - rtDlg.left)/2;//GetSystemMetrics(SM_CXSCREEN)获取屏幕大小
                        int nY = GetSystemMetrics(SM_CYSCREEN)/2 - (rtDlg.bottom - rtDlg.top)/2;
                        MoveWindow(hDlg,nX,nY, rtDlg.right - rtDlg.left, rtDlg.bottom - rtDlg.top,TRUE);//移动窗口
                }
                        break;
                case WM_COMMAND:
                {
                        if (ID_BT_SHUTDOWN == LOWORD(wParam))
                        {
                                int nRes = MessageBox(NULL,"你确定要关机吗?","HINT",MB_OKCANCEL);
                                if (nRes == IDOK)
                                {
                                        ReSetPrivilege(EWX_SHUTDOWN, FALSE);
                                }

                        }
                        else if (ID_BT_REBOOT == LOWORD(wParam))
                        {
                                int nRes = MessageBox(NULL, "你确定要重启吗?", "HINT", MB_OKCANCEL);
                                if (nRes == IDOK)
                                {
                                        ReSetPrivilege(EWX_REBOOT, FALSE);
                                }

                        }

                        else if (ID_BT_LOGOFF == LOWORD(wParam))
                        {
                                int nRes = MessageBox(NULL, "你确定要注销吗?", "HINT", MB_OKCANCEL);
                                if (nRes == IDOK)
                                {
                                        ReSetPrivilege(EWX_LOGOFF, FALSE);
                                }
                        }
                        else if (NULL == LOWORD(wParam))
                        {
                                MessageBox(NULL, "CmdNull", "Error", MB_OK);
                        }
                        else
                        {
                                MessageBox(NULL, "CmdError", "Error", MB_OK);
                        }
                }
                        break;
                case WM_CLOSE:
                        DestroyWindow(hDlg);//非模态为DestroyWindow(hDlg),模态为EndDialog(hDlg)
                        break;
                case WM_DESTROY:
                        PostQuitMessage(0);
                        break;
                default:
                        return FALSE;//返回false 系统处理
        }
        return TRUE;
}




上一篇:C语言实现简单的Printf
下一篇:为什么C语言会有头文件

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你已经在论坛发帖求助,并且从坛友或者管理的回复中解决了问题,请编辑帖子并把分类改成【已解决】

如何回报帮助你解决问题的坛友?可以给对方加【热心】【驿站币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

21_avatar_middle
在线会员 mqcake10 发表于 2018-5-3 15:28:19 | 显示全部楼层
值得学习学习,点赞。

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你已经在论坛发帖求助,并且从坛友或者管理的回复中解决了问题,请编辑帖子并把分类改成【已解决】

如何回报帮助你解决问题的坛友?可以给对方加【热心】【驿站币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 加入驿站 qq_login

本版积分规则

关闭

站长提醒上一条 /1 下一条

QQ
QQ在线咨询
联系电话
13591366679
手机扫一扫 关注本站精彩内容
wxqrcode

QQ|小黑屋|手机版|VC驿站 ( 辽ICP备09019393号tongdun|网站地图wx_jqr

GMT+8, 2018-10-20 13:39

Powered by Discuz! X3.4

© 2009-2018 cctry.com

快速回复 返回顶部 返回列表