每一个软件都是有个进程,一般我们直接使用关机命令是无法对系统操作的,是需要获得一定的权限的。跟具权限的不同对系统的操作和控制也不同。
在软件操作系统进行关机、注销、重启等操作需要用到的函数和结构体如下:
- ExitWindowsEx(EWX_LOGOFF,0) 关闭计算机
- ExitWindowsEx(EWX_SHUTDOWN,0) 注销计算机
- ExitWindowsEx(EWX_REBOOT,0) 重启计算机
- TOKEN_PRIVILEGES:是关于提升权限的结构体,包含了关于设置一个访问令牌的信息。
typedef struct _TOKEN_PRIVILEGES {
ULONG PrivilegeCount;
LUID_AND_ATTRIBUTES Privileges[ANYSIZE_ARRAY];
} TOKEN_PRIVILEGES, *PTOKEN_PRIVILEGES;
- 参数
PrivilegeCount数组元素的个数
Privileges一个LUID_AND_ATTRIBUTES结构体. 每个结构体包括LUID和特权的属性. 特权的属性可以是下列值的组合:
属性 | 描述 |
---|---|
SE_PRIVILEGE_ENABLED_BY_DEFAULT | 特权默认启用 |
SE_PRIVILEGE_ENABLED | 特权启用. |
SE_PRIVILEGE_ENABLED_BY_DEFAULT | 特权默认启用 |
SE_PRIVILEGE_USED_FOR_ACCESS | 特权被用来访问一个对象或服务。这个标志 被用于 标识有关特权,因为通过一组客户端应用程序,可能包含不必要的特权 |
- OpenProcessToken:函数用来打开与进程相关联的访问令牌。我们要修改一个进程的访问令牌,首先要获得进程访问令牌的句柄,这可以通过OpenProcessToken得到,函数的原型如下:
BOOL OpenProcessToken(
__in HANDLE ProcessHandle, //要修改访问权限的进程句柄
__in DWORD DesiredAccess, //指定你要进行的操作类型
__out PHANDLE TokenHandle //返回的访问令牌指针
);
- AdjustTokenPrivileges:是一种可以修改用户权限的函数,用于启用或禁止,指定访问令牌的特权。启用或禁用特权一个有TOKEN_ADJUST_PRIVILEGES访问的访问令牌.
BOOL AdjustTokenPrivileges(
HANDLE TokenHandle, //包含特权的句柄
BOOL DisableAllPrivileges,//禁用所有权限标志,如果开启权限,为FALSE
PTOKEN_PRIVILEGES NewState,//新特权信息的指针(结构体)
DWORD BufferLength, //缓冲数据大小,以字节为单位的PreviousState的缓存区(sizeof)
TOKEN_PRIVILEGES PreviousState,//接收被改变特权当前状态的Buffer
PDWORD ReturnLength //接收PreviousState缓存区要求的大小
);
- LookupPrivilegeValue:函数查看系统权限的特权值,返回信息到一个LUID结构体里。
BOOL LookupPrivilegeValue(LPCTSTR lpSystemName,LPCTSTR lpName,PLUID lpLuid);
参数
- lpSystemName表示所要查看的系统,本地系统直接用NULL
- lpName指向一个以零结尾的字符串,指定特权的名称,如在WinNT h头文件定义。例如,此参数可指定数,se_security_name,或其对应的字符串,“sesecurityprivilege ";
- lpLuid用来接收所返回的制定特权名称的信息。 函数调用成功后,信息存入第三个类型为LUID的结构体中,并且函数返回非0。
1、关闭计算机
void C注销_关机_重启Dlg::OnBnClickedGuan()
{
// TODO: 在此添加控件通知处理程序代码
//提示是不是需要注销电脑
if (IDNO == MessageBox(_T("确定要关机吗"),_T("Demo"),MB_YESNO))
{
return;
}
//打开令牌
HANDLE hToken;//创建令牌句柄
if (!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,&hToken))//打开令牌句柄,设置令牌权限
{
AfxMessageBox(_T("OpenProcessToken Error."));
return;
}
TOKEN_PRIVILEGES tkp;//结构体包括LUID和特权的属性
LookupPrivilegeValue(NULL,SE_SHUTDOWN_NAME,&tkp.Privileges[0].Luid);//查看令牌权限
tkp.PrivilegeCount = 1;//设置元素的个数
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;//设置元素的权限
AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);//修改用户权限的函数
if (GetLastError() != ERROR_SUCCESS)
{
AfxMessageBox(_T("AdjustTokenPrivileges Error"));
return;
}
AfxMessageBox(_T("电脑已关机"));
//if (!ExitWindowsEx(EWX_LOGOFF,0))
//{
// AfxMessageBox(_T("ExitWindowsEx Error"));
//}
}
2、注销计算机
void C注销_关机_重启Dlg::OnBnClickedZhu()
{
// TODO: 在此添加控件通知处理程序代码
//提示是不是需要注销电脑
if (IDNO == MessageBox(_T("确定要注销吗"), _T("Demo"), MB_YESNO))
{
return;
}
//打开令牌
HANDLE hToken;//创建令牌句柄
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))//打开令牌句柄,设置令牌权限
{
AfxMessageBox(_T("OpenProcessToken Error."));
return;
}
TOKEN_PRIVILEGES tkp;
LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid);//查看令牌权限
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
if (GetLastError() != ERROR_SUCCESS)
{
AfxMessageBox(_T("AdjustTokenPrivileges Error"));
return;
}
AfxMessageBox(_T("电脑已注销"));
//if (!ExitWindowsEx(EWX_SHUTDOWN,0))
//{
// AfxMessageBox(_T("ExitWindowsEx Error"));
//}
}
3、重启计算机
void C注销_关机_重启Dlg::OnBnClickedChong()
{
// TODO: 在此添加控件通知处理程序代码
//提示是不是需要注销电脑
if (IDNO == MessageBox(_T("确定要重启吗"), _T("Demo"), MB_YESNO))
{
return;
}
//打开令牌
HANDLE hToken;//创建令牌句柄
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))//打开令牌句柄,设置令牌权限
{
AfxMessageBox(_T("OpenProcessToken Error."));
return;
}
TOKEN_PRIVILEGES tkp;//一个LUID_AND_ATTRIBUTES结构体. 每个结构体包括LUID和特权的属性。
LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid);//查看令牌权限
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
if (GetLastError() != ERROR_SUCCESS)
{
AfxMessageBox(_T("AdjustTokenPrivileges Error"));
return;
}
AfxMessageBox(_T("电脑已重启"));
//if (!ExitWindowsEx(EWX_REBOOT,0))
//{
// AfxMessageBox(_T("ExitWindowsEx Error"));
//}
}