我创建了一个从远程计算机控制鼠标和键盘的应用程序(如InputDirector)。现在我遇到的问题是无法控制安全桌面(锁屏、UAC)。
我在其他帖子中读到,我必须使用
SetThreadDesktop()
。但对我来说这不起作用。以下是我如何更新桌面的代码片段(我使用 SetCursorPos
检查 UAC 中是否有效):
if(flag_start_desk)
{
flag_start_desk = 0;
POINT pt = { 0 };
if(!GetCursorPos(&pt)) erz_output(red, LOCAL_FUNCTION_NAME, "Something went wrong to get mouse position\r\n");
else SetCursorPos(pt.x-20, pt.y-20);
if( (desk = OpenInputDesktop(0, 0, WRITE_OWNER) ) == NULL)
{
erz_output(red, LOCAL_FUNCTION_NAME, "OID Error: %lu\r\n", GetLastError());
Beep(530, 500);
}
else
{
erz_output(green, LOCAL_FUNCTION_NAME, "New Desktop: %llu\r\n", desk);
if( SetThreadDesktop(desk) == 0 )
{
erz_output(red, LOCAL_FUNCTION_NAME, "STD Error: %lu\r\n", GetLastError());
Beep(530, 500);
}
//CloseDesktop(desk);
//desk = NULL;
}
}
OID Error: 5
(ERROR_ACCESS_DENIED)。STD Error: 170
(ERROR_BUSY)。当我启动 UAC 时,我收到消息 OID Error: 5
。OpenInputDesktop(0, 0, WRITE_OWNER)
更改为 OpenInputDesktop(DF_ALLOWOTHERACCOUNTHOOK, 1, WRITE_OWNER)
,结果相同。uiAccess="true"
创建应用程序清单,并向应用程序添加数字证书。结果与上面相同,只是我不需要以管理员身份启动。SetCursorPos
。CreateProcessAsUser()
启动一个控制安全桌面的子进程。结果与上面相同。但我也会分享我的剪裁。给孩子打电话:
int loadp(void)
{
DWORD sessionID = WTSGetActiveConsoleSessionId();
HANDLE hToken;
WTSQueryUserToken(sessionID, &hToken);
// userdata for CreateProcessAsUser
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;
// get secure desktop
si.lpDesktop = ("winsta0\\default"); // default-Desktop
// child app to start
CHAR appPath[1024];
memcpy(appPath, ("C:\\MinGW64\\bin\\proj\\TESTS\\client.exe"), 37);
// start process witch can access secure desktop
if (CreateProcessAsUser(hToken, appPath, NULL, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
} else {
printf(("Cannot start process: %d\n"), GetLastError());
}
CloseHandle(hToken);
return 0;
}
感觉我在兜圈子,也许你可以帮助我。
我的目标是中止或接受 UAC 弹出窗口并在锁屏上登录。
我在 Windows 10 上工作。
在前一个示例中,
GetThreadDesktop
来获取默认活动桌面设置
该线程的系统。SetThreadDesktop
设置与此关联的桌面
线程到我们创建的桌面 CreateDeskTop
.我们可以在windows station中切换和关闭桌面。现在,
#define DESTOP_NAME L"MY_DESTOP"
hDDesk = CreateDesktop(
DESTOP_NAME,
0, 0, 0,
GENERIC_ALL,
NULL
);
STARTUPINFO sti =
{
sizeof(sti)
};
sti.lpDesktop =(LPWSTR)DESTOP_NAME;
请参阅与桌面的线程连接。需要注意的是,本次连接过程中分配的桌面无法通过调用CloseDesktop函数来关闭。
typedef BOOL(__stdcall* P_IsWow64Process)(HANDLE, BOOL*);
HMODULE _Kernel32 = GetModuleHandle(L"kernel32.dll");
if (_Kernel32 == 0)
{
return FALSE;
}
P_IsWow64Process iswow64process = (P_IsWow64Process)GetProcAddress(_Kernel32, "IsWow64Process");
int bwow64 = 0;
iswow64process(GetCurrentProcess(), &bwow64);
温馨提示:
CreateDesktop
.CloseDeskTop
之前,您必须切换回当前桌面。
不然你就再也回不来了。这是代码:
#include <iostream>
#include<windows.h>
TCHAR szAppName[] = L"TEST";
#define DESTOP_NAME L"MY_DESTOP"
ATOM m_HotKeyId1;
ATOM m_HotKeyId2;
ATOM m_HotKeyId3;
HDESK hDDesk;
HDESK hOld;
//HWINSTA hWinStaThisProcess = GetProcessWindowStation();
//HDESK hDeskOriignInput = OpenInputDesktop(0, FALSE, GENERIC_ALL);
void OnHotKey(WPARAM wParam, LPARAM lParam)
{
static LRESULT lRes = 0;
if (wParam == m_HotKeyId1)
{
SwitchDesktop(hOld);
}
else if (wParam == m_HotKeyId2)
{
SwitchDesktop(hDDesk);
}
else if (wParam == m_HotKeyId3)
{
MessageBox(0, L"quit", L"caution", 0);
PostQuitMessage(0);
SwitchDesktop(hOld);
BOOL res=CloseDesktop(hDDesk);
MessageBox(0, L"failed", L"closed", 0);
}
return ;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
RECT rect;
GetClientRect(hwnd, &rect);
POINT p;
ClientToScreen(hwnd, &p);
RECT winrect;
GetWindowRect(hwnd, &winrect);
//hotkey
switch (message)
{
case WM_HOTKEY:
OnHotKey(wParam, lParam);
return 0;
}
//cursor
HCURSOR hCurs1, hCurs2; // cursor handles
POINT pt; // cursor location
RECT rc; // client area coordinates
static int repeat = 100; // repeat key counter
//
// Other declarations and initialization.
//
switch (message)
{
//
// Process other messages.
//
case WM_KEYDOWN:
if (wParam != VK_LEFT && wParam != VK_RIGHT &&
wParam != VK_UP && wParam != VK_DOWN)
{
break;
}
GetCursorPos(&pt);
// Convert screen coordinates to client coordinates.
ScreenToClient(hwnd, &pt);
switch (wParam)
{
// Move the cursor to reflect which
// arrow keys are pressed.
case VK_LEFT: // left arrow
pt.x -= repeat;
break;
case VK_RIGHT: // right arrow
pt.x += repeat;
break;
case VK_UP: // up arrow
pt.y -= repeat;
break;
case VK_DOWN: // down arrow
pt.y += repeat;
break;
default:
return 0;
}
repeat++; // Increment repeat count.
// Keep the cursor in the client area.
GetClientRect(hwnd, &rc);
if (pt.x >= rc.right)
{
pt.x = rc.right - 100;
}
else
{
if (pt.x < rc.left)
{
pt.x = rc.left;
}
}
if (pt.y >= rc.bottom)
pt.y = rc.bottom - 100;
else
if (pt.y < rc.top)
pt.y = rc.top;
// Convert client coordinates to screen coordinates.
ClientToScreen(hwnd, &pt);
SetCursorPos(pt.x, pt.y);
return 0;
case WM_KEYUP:
repeat = 10; // Clear repeat count.
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow)
{
hOld = GetThreadDesktop(GetCurrentThreadId());
int result = 0;
typedef BOOL(__stdcall* P_IsWow64Process)(HANDLE, BOOL*);
HMODULE _Kernel32 = GetModuleHandle(L"kernel32.dll");
if (_Kernel32 == 0)
{
return FALSE;
}
P_IsWow64Process iswow64process = (P_IsWow64Process)GetProcAddress(_Kernel32, "IsWow64Process");
HWND hwnd;
HWND hwnd2;
MSG msg;
WNDCLASS wndclass;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szAppName;
if (!RegisterClass(&wndclass))
{
MessageBox(NULL, L"RegisterClass failed!", NULL, 0);
return 0;
}
hwnd = CreateWindow(
szAppName, szAppName,
WS_OVERLAPPEDWINDOW,
0, 0,
800, 600,
NULL, NULL, hInstance, NULL
);
ShowWindow(hwnd, SW_SHOW);
hDDesk = CreateDesktop(
DESTOP_NAME,
0, 0, 0,
GENERIC_ALL,
NULL
);
result = SetThreadDesktop(hDDesk);
STARTUPINFO sti = {
sizeof(sti)
};
sti.lpDesktop =(LPWSTR)DESTOP_NAME;
PROCESS_INFORMATION pi = { 0 };
int bwow64 = 0;
iswow64process(GetCurrentProcess(), &bwow64);
if (bwow64)
{
result = CreateProcess(L"C:\\Windows\\SysWOW64\\explorer.exe", NULL, NULL, NULL, TRUE, 0, NULL, NULL, &sti, &pi);
}
else {
result = CreateProcess(L"C:\\Windows\\explorer.exe", NULL, NULL, NULL, TRUE, 0, NULL, NULL, &sti, &pi);
}
if (result)
{
CloseHandle(pi.hProcess);
}
m_HotKeyId1 = GlobalAddAtomW(L"HotKey1") - 0xc000;
RegisterHotKey(hwnd, m_HotKeyId1, 0, VK_F6);
m_HotKeyId2 = GlobalAddAtomW(L"HotKey2") - 0xc000;
RegisterHotKey(hwnd, m_HotKeyId2, 0, VK_F7);
m_HotKeyId3 = GlobalAddAtomW(L"HotKey3") - 0xc000;
RegisterHotKey(hwnd, m_HotKeyId3, MOD_CONTROL | MOD_SHIFT, VK_F8);
RegisterHotKey(hwnd, m_HotKeyId3, 0, VK_F8);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
UnregisterHotKey(hwnd, m_HotKeyId1);
GlobalDeleteAtom(m_HotKeyId1);
UnregisterHotKey(hwnd, m_HotKeyId2);
GlobalDeleteAtom(m_HotKeyId2);
UnregisterHotKey(hwnd, m_HotKeyId3);
GlobalDeleteAtom(m_HotKeyId3);
return msg.wParam;
}