Merge pull request #6473 from fufesou/feat/format_idd_error_message
Feat/format idd error message
This commit is contained in:
commit
3a6f56ebbc
@ -139,9 +139,9 @@ impl MagInterface {
|
|||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
ErrorKind::Other,
|
ErrorKind::Other,
|
||||||
format!(
|
format!(
|
||||||
"Failed to LoadLibraryExA {}, error: {}",
|
"Failed to LoadLibraryExA {}, error {}",
|
||||||
lib_file_name,
|
lib_file_name,
|
||||||
GetLastError()
|
Error::last_os_error()
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
};
|
};
|
||||||
@ -173,7 +173,7 @@ impl MagInterface {
|
|||||||
if FALSE == init_func() {
|
if FALSE == init_func() {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
ErrorKind::Other,
|
ErrorKind::Other,
|
||||||
format!("Failed to MagInitialize, error: {}", GetLastError()),
|
format!("Failed to MagInitialize, error {}", Error::last_os_error()),
|
||||||
));
|
));
|
||||||
} else {
|
} else {
|
||||||
s.init_succeeded = true;
|
s.init_succeeded = true;
|
||||||
@ -195,9 +195,9 @@ impl MagInterface {
|
|||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
ErrorKind::Other,
|
ErrorKind::Other,
|
||||||
format!(
|
format!(
|
||||||
"Failed to GetProcAddress {}, error: {}",
|
"Failed to GetProcAddress {}, error {}",
|
||||||
func_name,
|
func_name,
|
||||||
GetLastError()
|
Error::last_os_error()
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -209,14 +209,14 @@ impl MagInterface {
|
|||||||
if let Some(uninit_func) = self.mag_uninitialize_func {
|
if let Some(uninit_func) = self.mag_uninitialize_func {
|
||||||
unsafe {
|
unsafe {
|
||||||
if FALSE == uninit_func() {
|
if FALSE == uninit_func() {
|
||||||
println!("Failed MagUninitialize {}", GetLastError())
|
println!("Failed MagUninitialize, error {}", Error::last_os_error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !self.lib_handle.is_null() {
|
if !self.lib_handle.is_null() {
|
||||||
unsafe {
|
unsafe {
|
||||||
if FALSE == FreeLibrary(self.lib_handle) {
|
if FALSE == FreeLibrary(self.lib_handle) {
|
||||||
println!("Failed FreeLibrary {}", GetLastError())
|
println!("Failed FreeLibrary, error {}", Error::last_os_error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.lib_handle = NULL as _;
|
self.lib_handle = NULL as _;
|
||||||
@ -315,7 +315,10 @@ impl CapturerMag {
|
|||||||
) {
|
) {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
ErrorKind::Other,
|
ErrorKind::Other,
|
||||||
format!("Failed to GetModuleHandleExA, error: {}", GetLastError()),
|
format!(
|
||||||
|
"Failed to GetModuleHandleExA, error {}",
|
||||||
|
Error::last_os_error()
|
||||||
|
),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -342,7 +345,10 @@ impl CapturerMag {
|
|||||||
if code != ERROR_CLASS_ALREADY_EXISTS {
|
if code != ERROR_CLASS_ALREADY_EXISTS {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
ErrorKind::Other,
|
ErrorKind::Other,
|
||||||
format!("Failed to RegisterClassExA, error: {}", code),
|
format!(
|
||||||
|
"Failed to RegisterClassExA, error {}",
|
||||||
|
Error::from_raw_os_error(code as _)
|
||||||
|
),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -366,8 +372,8 @@ impl CapturerMag {
|
|||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
ErrorKind::Other,
|
ErrorKind::Other,
|
||||||
format!(
|
format!(
|
||||||
"Failed to CreateWindowExA host_window, error: {}",
|
"Failed to CreateWindowExA host_window, error {}",
|
||||||
GetLastError()
|
Error::last_os_error()
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -391,8 +397,8 @@ impl CapturerMag {
|
|||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
ErrorKind::Other,
|
ErrorKind::Other,
|
||||||
format!(
|
format!(
|
||||||
"Failed CreateWindowA magnifier_window, error: {}",
|
"Failed CreateWindowA magnifier_window, error {}",
|
||||||
GetLastError()
|
Error::last_os_error()
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -411,8 +417,8 @@ impl CapturerMag {
|
|||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
ErrorKind::Other,
|
ErrorKind::Other,
|
||||||
format!(
|
format!(
|
||||||
"Failed to MagSetImageScalingCallback, error: {}",
|
"Failed to MagSetImageScalingCallback, error {}",
|
||||||
GetLastError()
|
Error::last_os_error()
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -455,10 +461,10 @@ impl CapturerMag {
|
|||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
ErrorKind::Other,
|
ErrorKind::Other,
|
||||||
format!(
|
format!(
|
||||||
"Failed MagSetWindowFilterList for cls {} name {}, err: {}",
|
"Failed MagSetWindowFilterList for cls {} name {}, error {}",
|
||||||
cls,
|
cls,
|
||||||
name,
|
name,
|
||||||
GetLastError()
|
Error::last_os_error()
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -535,7 +541,7 @@ impl CapturerMag {
|
|||||||
self.rect.top,
|
self.rect.top,
|
||||||
self.rect.right - self.rect.left,
|
self.rect.right - self.rect.left,
|
||||||
self.rect.bottom - self.rect.top,
|
self.rect.bottom - self.rect.top,
|
||||||
GetLastError()
|
Error::last_os_error()
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -546,7 +552,10 @@ impl CapturerMag {
|
|||||||
if FALSE == set_window_source_func(self.magnifier_window, self.rect) {
|
if FALSE == set_window_source_func(self.magnifier_window, self.rect) {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
ErrorKind::Other,
|
ErrorKind::Other,
|
||||||
format!("Failed to MagSetWindowSource, error: {}", GetLastError()),
|
format!(
|
||||||
|
"Failed to MagSetWindowSource, error {}",
|
||||||
|
Error::last_os_error()
|
||||||
|
),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -578,7 +587,10 @@ impl CapturerMag {
|
|||||||
unsafe {
|
unsafe {
|
||||||
if FALSE == DestroyWindow(self.magnifier_window) {
|
if FALSE == DestroyWindow(self.magnifier_window) {
|
||||||
//
|
//
|
||||||
println!("Failed DestroyWindow magnifier window {}", GetLastError())
|
println!(
|
||||||
|
"Failed DestroyWindow magnifier window, error {}",
|
||||||
|
Error::last_os_error()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -588,7 +600,10 @@ impl CapturerMag {
|
|||||||
unsafe {
|
unsafe {
|
||||||
if FALSE == DestroyWindow(self.host_window) {
|
if FALSE == DestroyWindow(self.host_window) {
|
||||||
//
|
//
|
||||||
println!("Failed DestroyWindow host window {}", GetLastError())
|
println!(
|
||||||
|
"Failed DestroyWindow host window, error {}",
|
||||||
|
Error::last_os_error()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,12 @@
|
|||||||
|
|
||||||
#include "./Public.h"
|
#include "./Public.h"
|
||||||
|
|
||||||
|
typedef struct DeviceCreateCallbackContext
|
||||||
|
{
|
||||||
|
HANDLE hEvent;
|
||||||
|
SW_DEVICE_LIFETIME* lifetime;
|
||||||
|
HRESULT hrCreateResult;
|
||||||
|
} DeviceCreateCallbackContext;
|
||||||
|
|
||||||
const GUID GUID_DEVINTERFACE_IDD_DRIVER_DEVICE = \
|
const GUID GUID_DEVINTERFACE_IDD_DRIVER_DEVICE = \
|
||||||
{ 0x781EF630, 0x72B2, 0x11d2, { 0xB8, 0x52, 0x00, 0xC0, 0x4E, 0xAF, 0x52, 0x72 } };
|
{ 0x781EF630, 0x72B2, 0x11d2, { 0xB8, 0x52, 0x00, 0xC0, 0x4E, 0xAF, 0x52, 0x72 } };
|
||||||
@ -43,6 +49,8 @@ BOOLEAN GetDevicePath2(
|
|||||||
HANDLE DeviceOpenHandle();
|
HANDLE DeviceOpenHandle();
|
||||||
VOID DeviceCloseHandle(HANDLE handle);
|
VOID DeviceCloseHandle(HANDLE handle);
|
||||||
|
|
||||||
|
LPSTR formatErrorString(DWORD error);
|
||||||
|
|
||||||
void SetLastMsg(const char* format, ...)
|
void SetLastMsg(const char* format, ...)
|
||||||
{
|
{
|
||||||
memset(g_lastMsg, 0, sizeof(g_lastMsg));
|
memset(g_lastMsg, 0, sizeof(g_lastMsg));
|
||||||
@ -82,7 +90,23 @@ BOOL InstallUpdate(LPCWSTR fullInfPath, PBOOL rebootRequired)
|
|||||||
DWORD error = GetLastError();
|
DWORD error = GetLastError();
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
{
|
{
|
||||||
SetLastMsg("Failed InstallUpdate UpdateDriverForPlugAndPlayDevicesW, last error 0x%x\n", error);
|
LPSTR errorString = formatErrorString(error);
|
||||||
|
switch (error)
|
||||||
|
{
|
||||||
|
case 0x109:
|
||||||
|
SetLastMsg("Failed InstallUpdate UpdateDriverForPlugAndPlayDevicesW, error: 0x%x, %s Please try: Reinstall RustDesk with the cert option.\n", error, errorString == NULL ? "(NULL)\n" : errorString);
|
||||||
|
break;
|
||||||
|
case 0xe0000247:
|
||||||
|
SetLastMsg("Failed InstallUpdate UpdateDriverForPlugAndPlayDevicesW, error: 0x%x, %s Please try: \n1. Check the device manager and event viewer.\n2. Uninstall \"RustDeskIddDriver Device\" in device manager, then reinstall RustDesk with the cert option.\n", error, errorString == NULL ? "(NULL)\n" : errorString);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
SetLastMsg("Failed InstallUpdate UpdateDriverForPlugAndPlayDevicesW, error: 0x%x, %s Please try: Check the device manager and event viewer.\n", error, errorString == NULL ? "(NULL)\n" : errorString);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (errorString != NULL)
|
||||||
|
{
|
||||||
|
LocalFree(errorString);
|
||||||
|
}
|
||||||
if (g_printMsg)
|
if (g_printMsg)
|
||||||
{
|
{
|
||||||
printf(g_lastMsg);
|
printf(g_lastMsg);
|
||||||
@ -108,7 +132,12 @@ BOOL Uninstall(LPCWSTR fullInfPath, PBOOL rebootRequired)
|
|||||||
DWORD error = GetLastError();
|
DWORD error = GetLastError();
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
{
|
{
|
||||||
SetLastMsg("Failed Uninstall DiUninstallDriverW, last error 0x%x\n", error);
|
LPSTR errorString = formatErrorString(error);
|
||||||
|
SetLastMsg("Failed Uninstall DiUninstallDriverW, error: 0x%x, %s", error, errorString == NULL ? "(NULL)\n" : errorString);
|
||||||
|
if (errorString != NULL)
|
||||||
|
{
|
||||||
|
LocalFree(errorString);
|
||||||
|
}
|
||||||
if (g_printMsg)
|
if (g_printMsg)
|
||||||
{
|
{
|
||||||
printf(g_lastMsg);
|
printf(g_lastMsg);
|
||||||
@ -132,7 +161,13 @@ BOOL IsDeviceCreated(PBOOL created)
|
|||||||
DIGCF_DEVICEINTERFACE)); // Function class devices.
|
DIGCF_DEVICEINTERFACE)); // Function class devices.
|
||||||
if (INVALID_HANDLE_VALUE == hardwareDeviceInfo)
|
if (INVALID_HANDLE_VALUE == hardwareDeviceInfo)
|
||||||
{
|
{
|
||||||
SetLastMsg("Idd device: Failed IsDeviceCreated SetupDiGetClassDevs, last error 0x%x\n", GetLastError());
|
DWORD error = GetLastError();
|
||||||
|
LPSTR errorString = formatErrorString(error);
|
||||||
|
SetLastMsg("Idd device: Failed IsDeviceCreated SetupDiGetClassDevs, error 0x%x (%s)\n", error, errorString == NULL ? "(NULL)\n" : errorString);
|
||||||
|
if (errorString != NULL)
|
||||||
|
{
|
||||||
|
LocalFree(errorString);
|
||||||
|
}
|
||||||
if (g_printMsg)
|
if (g_printMsg)
|
||||||
{
|
{
|
||||||
printf(g_lastMsg);
|
printf(g_lastMsg);
|
||||||
@ -165,7 +200,12 @@ BOOL IsDeviceCreated(PBOOL created)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetLastMsg("Idd device: Failed IsDeviceCreated SetupDiEnumDeviceInterfaces, last error 0x%x\n", error);
|
LPSTR errorString = formatErrorString(error);
|
||||||
|
SetLastMsg("Idd device: Failed IsDeviceCreated SetupDiEnumDeviceInterfaces, error: 0x%x, %s", error, errorString == NULL ? "(NULL)\n" : errorString);
|
||||||
|
if (errorString != NULL)
|
||||||
|
{
|
||||||
|
LocalFree(errorString);
|
||||||
|
}
|
||||||
if (g_printMsg)
|
if (g_printMsg)
|
||||||
{
|
{
|
||||||
printf(g_lastMsg);
|
printf(g_lastMsg);
|
||||||
@ -180,36 +220,40 @@ BOOL IsDeviceCreated(PBOOL created)
|
|||||||
}
|
}
|
||||||
|
|
||||||
BOOL DeviceCreate(PHSWDEVICE hSwDevice)
|
BOOL DeviceCreate(PHSWDEVICE hSwDevice)
|
||||||
|
{
|
||||||
|
SW_DEVICE_LIFETIME lifetime = SWDeviceLifetimeHandle;
|
||||||
|
return DeviceCreateWithLifetime(&lifetime, hSwDevice);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL DeviceCreateWithLifetime(SW_DEVICE_LIFETIME *lifetime, PHSWDEVICE hSwDevice)
|
||||||
{
|
{
|
||||||
SetLastMsg("Success");
|
SetLastMsg("Success");
|
||||||
|
|
||||||
if (*hSwDevice != NULL)
|
if (*hSwDevice != NULL)
|
||||||
{
|
{
|
||||||
SetLastMsg("Device handler is not NULL\n");
|
SetLastMsg("Device handle is not NULL\n");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL created = TRUE;
|
// No need to check if the device is previous created.
|
||||||
if (FALSE == IsDeviceCreated(&created))
|
// https://learn.microsoft.com/en-us/windows/win32/api/swdevice/nf-swdevice-swdevicesetlifetime
|
||||||
{
|
// When a client app calls SwDeviceCreate for a software device that was previously marked for
|
||||||
return FALSE;
|
// SwDeviceLifetimeParentPresent, SwDeviceCreate succeeds if there are no open software device handles for the device
|
||||||
}
|
// (only one handle can be open for a device). A client app can then regain control over a persistent software device
|
||||||
if (created == TRUE)
|
// for the purposes of updating properties and interfaces or changing the lifetime.
|
||||||
{
|
//
|
||||||
SetLastMsg("Device is already created, please destroy it first\n");
|
|
||||||
if (g_printMsg)
|
|
||||||
{
|
|
||||||
printf(g_lastMsg);
|
|
||||||
}
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// create device
|
// create device
|
||||||
HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||||
if (hEvent == INVALID_HANDLE_VALUE || hEvent == NULL)
|
if (hEvent == INVALID_HANDLE_VALUE || hEvent == NULL)
|
||||||
{
|
{
|
||||||
DWORD error = GetLastError();
|
DWORD error = GetLastError();
|
||||||
SetLastMsg("Failed DeviceCreate CreateEvent 0x%lx\n", error);
|
LPSTR errorString = formatErrorString(error);
|
||||||
|
SetLastMsg("Failed DeviceCreate CreateEvent, error: 0x%x, %s", error, errorString == NULL ? "(NULL)\n" : errorString);
|
||||||
|
if (errorString != NULL)
|
||||||
|
{
|
||||||
|
LocalFree(errorString);
|
||||||
|
}
|
||||||
if (g_printMsg)
|
if (g_printMsg)
|
||||||
{
|
{
|
||||||
printf(g_lastMsg);
|
printf(g_lastMsg);
|
||||||
@ -218,6 +262,8 @@ BOOL DeviceCreate(PHSWDEVICE hSwDevice)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DeviceCreateCallbackContext callbackContext = { hEvent, lifetime, E_FAIL, };
|
||||||
|
|
||||||
SW_DEVICE_CREATE_INFO createInfo = { 0 };
|
SW_DEVICE_CREATE_INFO createInfo = { 0 };
|
||||||
PCWSTR description = L"RustDesk Idd Driver";
|
PCWSTR description = L"RustDesk Idd Driver";
|
||||||
|
|
||||||
@ -243,11 +289,16 @@ BOOL DeviceCreate(PHSWDEVICE hSwDevice)
|
|||||||
0,
|
0,
|
||||||
NULL,
|
NULL,
|
||||||
CreationCallback,
|
CreationCallback,
|
||||||
&hEvent,
|
&callbackContext,
|
||||||
hSwDevice);
|
hSwDevice);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
SetLastMsg("Failed DeviceCreate SwDeviceCreate 0x%lx\n", hr);
|
LPSTR errorString = formatErrorString((DWORD)hr);
|
||||||
|
SetLastMsg("Failed DeviceCreate SwDeviceCreate, hresult 0x%lx, %s", hr, errorString == NULL ? "(NULL)\n" : errorString);
|
||||||
|
if (errorString != NULL)
|
||||||
|
{
|
||||||
|
LocalFree(errorString);
|
||||||
|
}
|
||||||
if (g_printMsg)
|
if (g_printMsg)
|
||||||
{
|
{
|
||||||
printf(g_lastMsg);
|
printf(g_lastMsg);
|
||||||
@ -259,17 +310,54 @@ BOOL DeviceCreate(PHSWDEVICE hSwDevice)
|
|||||||
// Wait for callback to signal that the device has been created
|
// Wait for callback to signal that the device has been created
|
||||||
printf("Waiting for device to be created....\n");
|
printf("Waiting for device to be created....\n");
|
||||||
DWORD waitResult = WaitForSingleObject(hEvent, 10 * 1000);
|
DWORD waitResult = WaitForSingleObject(hEvent, 10 * 1000);
|
||||||
|
CloseHandle(hEvent);
|
||||||
if (waitResult != WAIT_OBJECT_0)
|
if (waitResult != WAIT_OBJECT_0)
|
||||||
{
|
{
|
||||||
SetLastMsg("Failed DeviceCreate wait for device creation 0x%d\n", waitResult);
|
DWORD error = 0;
|
||||||
|
LPSTR errorString = NULL;
|
||||||
|
switch (waitResult)
|
||||||
|
{
|
||||||
|
case WAIT_ABANDONED:
|
||||||
|
SetLastMsg("Failed DeviceCreate wait for device creation 0x%d, WAIT_ABANDONED\n", waitResult);
|
||||||
|
break;
|
||||||
|
case WAIT_TIMEOUT:
|
||||||
|
SetLastMsg("Failed DeviceCreate wait for device creation 0x%d, WAIT_TIMEOUT\n", waitResult);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
error = GetLastError();
|
||||||
|
if (error != 0)
|
||||||
|
{
|
||||||
|
errorString = formatErrorString(error);
|
||||||
|
SetLastMsg("Failed DeviceCreate wait for device creation, error: 0x%x, %s", error, errorString == NULL ? "(NULL)\n" : errorString);
|
||||||
|
if (errorString != NULL)
|
||||||
|
{
|
||||||
|
LocalFree(errorString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (g_printMsg)
|
if (g_printMsg)
|
||||||
{
|
{
|
||||||
printf(g_lastMsg);
|
printf(g_lastMsg);
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
// printf("Device created\n\n");
|
|
||||||
return TRUE;
|
if (SUCCEEDED(callbackContext.hrCreateResult))
|
||||||
|
{
|
||||||
|
// printf("Device created\n\n");
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LPSTR errorString = formatErrorString((DWORD)callbackContext.hrCreateResult);
|
||||||
|
SetLastMsg("Failed DeviceCreate SwDeviceCreate, hrCreateResult 0x%lx, %s", callbackContext.hrCreateResult, errorString == NULL ? "(NULL)\n" : errorString);
|
||||||
|
if (errorString != NULL)
|
||||||
|
{
|
||||||
|
LocalFree(errorString);
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID DeviceClose(HSWDEVICE hSwDevice)
|
VOID DeviceClose(HSWDEVICE hSwDevice)
|
||||||
@ -278,8 +366,38 @@ VOID DeviceClose(HSWDEVICE hSwDevice)
|
|||||||
|
|
||||||
if (hSwDevice != INVALID_HANDLE_VALUE && hSwDevice != NULL)
|
if (hSwDevice != INVALID_HANDLE_VALUE && hSwDevice != NULL)
|
||||||
{
|
{
|
||||||
|
HRESULT result = SwDeviceSetLifetime(hSwDevice, SWDeviceLifetimeHandle);
|
||||||
SwDeviceClose(hSwDevice);
|
SwDeviceClose(hSwDevice);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BOOL created = TRUE;
|
||||||
|
if (TRUE == IsDeviceCreated(&created))
|
||||||
|
{
|
||||||
|
if (created == FALSE)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Try crete sw device, and close
|
||||||
|
}
|
||||||
|
|
||||||
|
HSWDEVICE hSwDevice2 = NULL;
|
||||||
|
if (DeviceCreateWithLifetime(NULL, &hSwDevice2))
|
||||||
|
{
|
||||||
|
if (hSwDevice2 != NULL)
|
||||||
|
{
|
||||||
|
HRESULT result = SwDeviceSetLifetime(hSwDevice2, SWDeviceLifetimeHandle);
|
||||||
|
SwDeviceClose(hSwDevice2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL MonitorPlugIn(UINT index, UINT edid, INT retries)
|
BOOL MonitorPlugIn(UINT index, UINT edid, INT retries)
|
||||||
@ -319,7 +437,12 @@ BOOL MonitorPlugIn(UINT index, UINT edid, INT retries)
|
|||||||
HRESULT hr = CoCreateGuid(&plugIn.ContainerId);
|
HRESULT hr = CoCreateGuid(&plugIn.ContainerId);
|
||||||
if (!SUCCEEDED(hr))
|
if (!SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
SetLastMsg("Failed MonitorPlugIn CoCreateGuid %d\n", hr);
|
LPSTR errorString = formatErrorString((DWORD)hr);
|
||||||
|
SetLastMsg("Failed MonitorPlugIn CoCreateGuid, hresult 0x%lx, %s", hr, errorString == NULL ? "(NULL)\n" : errorString);
|
||||||
|
if (errorString != NULL)
|
||||||
|
{
|
||||||
|
LocalFree(errorString);
|
||||||
|
}
|
||||||
if (g_printMsg)
|
if (g_printMsg)
|
||||||
{
|
{
|
||||||
printf(g_lastMsg);
|
printf(g_lastMsg);
|
||||||
@ -348,8 +471,16 @@ BOOL MonitorPlugIn(UINT index, UINT edid, INT retries)
|
|||||||
if (ret == FALSE)
|
if (ret == FALSE)
|
||||||
{
|
{
|
||||||
DWORD error = GetLastError();
|
DWORD error = GetLastError();
|
||||||
SetLastMsg("Failed MonitorPlugIn DeviceIoControl 0x%lx\n", error);
|
LPSTR errorString = formatErrorString(error);
|
||||||
printf(g_lastMsg);
|
SetLastMsg("Failed MonitorPlugIn DeviceIoControl, error: 0x%x, %s", error, errorString == NULL ? "(NULL)\n" : errorString);
|
||||||
|
if (errorString != NULL)
|
||||||
|
{
|
||||||
|
LocalFree(errorString);
|
||||||
|
}
|
||||||
|
if (g_printMsg)
|
||||||
|
{
|
||||||
|
printf(g_lastMsg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -382,7 +513,12 @@ BOOL MonitorPlugOut(UINT index)
|
|||||||
0)) // Ptr to Overlapped structure
|
0)) // Ptr to Overlapped structure
|
||||||
{
|
{
|
||||||
DWORD error = GetLastError();
|
DWORD error = GetLastError();
|
||||||
SetLastMsg("Failed MonitorPlugOut DeviceIoControl 0x%lx\n", error);
|
LPSTR errorString = formatErrorString(error);
|
||||||
|
SetLastMsg("Failed MonitorPlugOut DeviceIoControl, error: 0x%x, %s", error, errorString == NULL ? "(NULL)\n" : errorString);
|
||||||
|
if (errorString != NULL)
|
||||||
|
{
|
||||||
|
LocalFree(errorString);
|
||||||
|
}
|
||||||
if (g_printMsg)
|
if (g_printMsg)
|
||||||
{
|
{
|
||||||
printf(g_lastMsg);
|
printf(g_lastMsg);
|
||||||
@ -414,7 +550,7 @@ BOOL MonitorModesUpdate(UINT index, UINT modeCount, PMonitorMode modes)
|
|||||||
PCtlMonitorModes pMonitorModes = (PCtlMonitorModes)malloc(buflen);
|
PCtlMonitorModes pMonitorModes = (PCtlMonitorModes)malloc(buflen);
|
||||||
if (pMonitorModes == NULL)
|
if (pMonitorModes == NULL)
|
||||||
{
|
{
|
||||||
SetLastMsg("Failed MonitorModesUpdate CtlMonitorModes malloc 0x%lx\n");
|
SetLastMsg("Failed MonitorModesUpdate CtlMonitorModes malloc\n");
|
||||||
if (g_printMsg)
|
if (g_printMsg)
|
||||||
{
|
{
|
||||||
printf(g_lastMsg);
|
printf(g_lastMsg);
|
||||||
@ -441,7 +577,12 @@ BOOL MonitorModesUpdate(UINT index, UINT modeCount, PMonitorMode modes)
|
|||||||
0)) // Ptr to Overlapped structure
|
0)) // Ptr to Overlapped structure
|
||||||
{
|
{
|
||||||
DWORD error = GetLastError();
|
DWORD error = GetLastError();
|
||||||
SetLastMsg("Failed MonitorModesUpdate DeviceIoControl 0x%lx\n", error);
|
LPSTR errorString = formatErrorString(error);
|
||||||
|
SetLastMsg("Failed MonitorModesUpdate DeviceIoControl, error: 0x%x, %s", error, errorString == NULL ? "(NULL)\n" : errorString);
|
||||||
|
if (errorString != NULL)
|
||||||
|
{
|
||||||
|
LocalFree(errorString);
|
||||||
|
}
|
||||||
if (g_printMsg)
|
if (g_printMsg)
|
||||||
{
|
{
|
||||||
printf(g_lastMsg);
|
printf(g_lastMsg);
|
||||||
@ -466,11 +607,30 @@ CreationCallback(
|
|||||||
_In_opt_ PCWSTR pszDeviceInstanceId
|
_In_opt_ PCWSTR pszDeviceInstanceId
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
HANDLE hEvent = *(HANDLE*)pContext;
|
DeviceCreateCallbackContext* callbackContext = NULL;
|
||||||
|
|
||||||
|
if (pContext != NULL)
|
||||||
|
{
|
||||||
|
callbackContext = (DeviceCreateCallbackContext*)pContext;
|
||||||
|
callbackContext->hrCreateResult = hrCreateResult;
|
||||||
|
if (SUCCEEDED(hrCreateResult))
|
||||||
|
{
|
||||||
|
if (callbackContext->lifetime)
|
||||||
|
{
|
||||||
|
HRESULT result = SwDeviceSetLifetime(hSwDevice, *callbackContext->lifetime);
|
||||||
|
if (FAILED(result))
|
||||||
|
{
|
||||||
|
// TODO: debug log error here
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (callbackContext->hEvent != NULL)
|
||||||
|
{
|
||||||
|
SetEvent(callbackContext->hEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SetEvent(hEvent);
|
|
||||||
UNREFERENCED_PARAMETER(hSwDevice);
|
|
||||||
UNREFERENCED_PARAMETER(hrCreateResult);
|
|
||||||
// printf("Idd device %ls created\n", pszDeviceInstanceId);
|
// printf("Idd device %ls created\n", pszDeviceInstanceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -495,7 +655,7 @@ GetDevicePath(
|
|||||||
CM_GET_DEVICE_INTERFACE_LIST_ALL_DEVICES);
|
CM_GET_DEVICE_INTERFACE_LIST_ALL_DEVICES);
|
||||||
if (cr != CR_SUCCESS)
|
if (cr != CR_SUCCESS)
|
||||||
{
|
{
|
||||||
SetLastMsg("Failed GetDevicePath 0x%x retrieving device interface list size.\n", cr);
|
SetLastMsg("Failed GetDevicePath 0x%x, retrieving device interface list size.\n", cr);
|
||||||
if (g_printMsg)
|
if (g_printMsg)
|
||||||
{
|
{
|
||||||
printf(g_lastMsg);
|
printf(g_lastMsg);
|
||||||
@ -565,7 +725,12 @@ GetDevicePath(
|
|||||||
hr = StringCchCopy(DevicePath, BufLen, deviceInterfaceList);
|
hr = StringCchCopy(DevicePath, BufLen, deviceInterfaceList);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
SetLastMsg("Error: GetDevicePath StringCchCopy failed with HRESULT 0x%x", hr);
|
LPSTR errorString = formatErrorString((DWORD)hr);
|
||||||
|
SetLastMsg("Failed GetDevicePath StringCchCopy, hresult 0x%lx, %s", hr, errorString == NULL ? "(NULL)\n" : errorString);
|
||||||
|
if (errorString != NULL)
|
||||||
|
{
|
||||||
|
LocalFree(errorString);
|
||||||
|
}
|
||||||
if (g_printMsg)
|
if (g_printMsg)
|
||||||
{
|
{
|
||||||
printf(g_lastMsg);
|
printf(g_lastMsg);
|
||||||
@ -611,7 +776,13 @@ BOOLEAN GetDevicePath2(
|
|||||||
DIGCF_DEVICEINTERFACE)); // Function class devices.
|
DIGCF_DEVICEINTERFACE)); // Function class devices.
|
||||||
if (INVALID_HANDLE_VALUE == hardwareDeviceInfo)
|
if (INVALID_HANDLE_VALUE == hardwareDeviceInfo)
|
||||||
{
|
{
|
||||||
SetLastMsg("Idd device: GetDevicePath2 SetupDiGetClassDevs failed, last error 0x%x\n", GetLastError());
|
DWORD error = GetLastError();
|
||||||
|
LPSTR errorString = formatErrorString(error);
|
||||||
|
SetLastMsg("Failed GetDevicePath2 SetupDiGetClassDevs, error: 0x%x, %s", error, errorString == NULL ? "(NULL)\n" : errorString);
|
||||||
|
if (errorString != NULL)
|
||||||
|
{
|
||||||
|
LocalFree(errorString);
|
||||||
|
}
|
||||||
if (g_printMsg)
|
if (g_printMsg)
|
||||||
{
|
{
|
||||||
printf(g_lastMsg);
|
printf(g_lastMsg);
|
||||||
@ -627,7 +798,13 @@ BOOLEAN GetDevicePath2(
|
|||||||
0, //
|
0, //
|
||||||
&deviceInterfaceData))
|
&deviceInterfaceData))
|
||||||
{
|
{
|
||||||
SetLastMsg("Idd device: GetDevicePath2 SetupDiEnumDeviceInterfaces failed, last error 0x%x\n", GetLastError());
|
DWORD error = GetLastError();
|
||||||
|
LPSTR errorString = formatErrorString(error);
|
||||||
|
SetLastMsg("Failed GetDevicePath2 SetupDiEnumDeviceInterfaces, error: 0x%x, %s", error, errorString == NULL ? "(NULL)\n" : errorString);
|
||||||
|
if (errorString != NULL)
|
||||||
|
{
|
||||||
|
LocalFree(errorString);
|
||||||
|
}
|
||||||
if (g_printMsg)
|
if (g_printMsg)
|
||||||
{
|
{
|
||||||
printf(g_lastMsg);
|
printf(g_lastMsg);
|
||||||
@ -647,9 +824,15 @@ BOOLEAN GetDevicePath2(
|
|||||||
&requiredLength,
|
&requiredLength,
|
||||||
NULL);//not interested in the specific dev-node
|
NULL);//not interested in the specific dev-node
|
||||||
|
|
||||||
if (ERROR_INSUFFICIENT_BUFFER != GetLastError())
|
DWORD error = GetLastError();
|
||||||
|
if (ERROR_INSUFFICIENT_BUFFER != error)
|
||||||
{
|
{
|
||||||
SetLastMsg("Idd device: GetDevicePath2 SetupDiGetDeviceInterfaceDetail failed, last error 0x%x\n", GetLastError());
|
LPSTR errorString = formatErrorString(error);
|
||||||
|
SetLastMsg("GetDevicePath2 SetupDiGetDeviceInterfaceDetail failed, error: 0x%x, %s", error, errorString == NULL ? "(NULL)\n" : errorString);
|
||||||
|
if (errorString != NULL)
|
||||||
|
{
|
||||||
|
LocalFree(errorString);
|
||||||
|
}
|
||||||
if (g_printMsg)
|
if (g_printMsg)
|
||||||
{
|
{
|
||||||
printf(g_lastMsg);
|
printf(g_lastMsg);
|
||||||
@ -671,7 +854,13 @@ BOOLEAN GetDevicePath2(
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SetLastMsg("Idd device: Failed GetDevicePath2 HeapAlloc, last error 0x%x\n", GetLastError());
|
DWORD error = GetLastError();
|
||||||
|
LPSTR errorString = formatErrorString(error);
|
||||||
|
SetLastMsg("Failed GetDevicePath2 HeapAlloc, error: 0x%x, %s", error, errorString == NULL ? "(NULL)\n" : errorString);
|
||||||
|
if (errorString != NULL)
|
||||||
|
{
|
||||||
|
LocalFree(errorString);
|
||||||
|
}
|
||||||
if (g_printMsg)
|
if (g_printMsg)
|
||||||
{
|
{
|
||||||
printf(g_lastMsg);
|
printf(g_lastMsg);
|
||||||
@ -687,7 +876,13 @@ BOOLEAN GetDevicePath2(
|
|||||||
&requiredLength,
|
&requiredLength,
|
||||||
NULL))
|
NULL))
|
||||||
{
|
{
|
||||||
SetLastMsg("Idd device: Failed GetDevicePath2 SetupDiGetDeviceInterfaceDetail, last error 0x%x\n", GetLastError());
|
DWORD error = GetLastError();
|
||||||
|
LPSTR errorString = formatErrorString(error);
|
||||||
|
SetLastMsg("Failed GetDevicePath2 SetupDiGetDeviceInterfaceDetail, error: 0x%x, %s", error, errorString == NULL ? "(NULL)\n" : errorString);
|
||||||
|
if (errorString != NULL)
|
||||||
|
{
|
||||||
|
LocalFree(errorString);
|
||||||
|
}
|
||||||
if (g_printMsg)
|
if (g_printMsg)
|
||||||
{
|
{
|
||||||
printf(g_lastMsg);
|
printf(g_lastMsg);
|
||||||
@ -698,7 +893,12 @@ BOOLEAN GetDevicePath2(
|
|||||||
hr = StringCchCopy(DevicePath, BufLen, deviceInterfaceDetailData->DevicePath);
|
hr = StringCchCopy(DevicePath, BufLen, deviceInterfaceDetailData->DevicePath);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
SetLastMsg("Error: Failed GetDevicePath2 StringCchCopy HRESULT 0x%x", hr);
|
LPSTR errorString = formatErrorString((DWORD)hr);
|
||||||
|
SetLastMsg("Failed GetDevicePath2 StringCchCopy, hresult 0x%lx, %s", hr, errorString == NULL ? "(NULL)\n" : errorString);
|
||||||
|
if (errorString != NULL)
|
||||||
|
{
|
||||||
|
LocalFree(errorString);
|
||||||
|
}
|
||||||
if (g_printMsg)
|
if (g_printMsg)
|
||||||
{
|
{
|
||||||
printf(g_lastMsg);
|
printf(g_lastMsg);
|
||||||
@ -759,7 +959,12 @@ HANDLE DeviceOpenHandle()
|
|||||||
if (hDevice == INVALID_HANDLE_VALUE || hDevice == NULL)
|
if (hDevice == INVALID_HANDLE_VALUE || hDevice == NULL)
|
||||||
{
|
{
|
||||||
DWORD error = GetLastError();
|
DWORD error = GetLastError();
|
||||||
SetLastMsg("Failed DeviceOpenHandle CreateFile 0x%lx\n", error);
|
LPSTR errorString = formatErrorString(error);
|
||||||
|
SetLastMsg("Failed DeviceOpenHandle CreateFile, error: 0x%x, %s", error, errorString == NULL ? "(NULL)\n" : errorString);
|
||||||
|
if (errorString != NULL)
|
||||||
|
{
|
||||||
|
LocalFree(errorString);
|
||||||
|
}
|
||||||
if (g_printMsg)
|
if (g_printMsg)
|
||||||
{
|
{
|
||||||
printf(g_lastMsg);
|
printf(g_lastMsg);
|
||||||
@ -782,3 +987,20 @@ VOID SetPrintErrMsg(BOOL b)
|
|||||||
{
|
{
|
||||||
g_printMsg = (b == TRUE);
|
g_printMsg = (b == TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use en-us for simple, or we may need to handle wide string.
|
||||||
|
LPSTR formatErrorString(DWORD error)
|
||||||
|
{
|
||||||
|
LPSTR errorString = NULL;
|
||||||
|
FormatMessageA(
|
||||||
|
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||||
|
NULL,
|
||||||
|
error,
|
||||||
|
MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
|
||||||
|
(LPSTR)&errorString,
|
||||||
|
0,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
return errorString;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -58,10 +58,27 @@ BOOL IsDeviceCreated(PBOOL created);
|
|||||||
*/
|
*/
|
||||||
BOOL DeviceCreate(PHSWDEVICE hSwDevice);
|
BOOL DeviceCreate(PHSWDEVICE hSwDevice);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Create device and set the lifetime.
|
||||||
|
* Only one device should be created.
|
||||||
|
* If device is installed ealier, this function returns FALSE.
|
||||||
|
*
|
||||||
|
* @param lifetime [in] The lifetime to set after creating the device. NULL means do not set the lifetime.
|
||||||
|
* https://learn.microsoft.com/en-us/windows/win32/api/swdevice/nf-swdevice-swdevicesetlifetime
|
||||||
|
* @param hSwDevice [out] Handler of software device, used by DeviceCreate(). Should be **NULL**.
|
||||||
|
*
|
||||||
|
* @return TRUE/FALSE. If FALSE returned, error message can be retrieved by GetLastMsg()
|
||||||
|
*
|
||||||
|
* @see GetLastMsg#GetLastMsg
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
BOOL DeviceCreateWithLifetime(SW_DEVICE_LIFETIME * lifetime, PHSWDEVICE hSwDevice);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Close device.
|
* @brief Close device.
|
||||||
*
|
*
|
||||||
* @param hSwDevice Handler of software device, used by SwDeviceClose().
|
* @param hSwDevice Handler of software device, used by SwDeviceClose().
|
||||||
|
* If hSwDevice is INVALID_HANDLE_VALUE or NULL, try find and close the device.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
VOID DeviceClose(HSWDEVICE hSwDevice);
|
VOID DeviceClose(HSWDEVICE hSwDevice);
|
||||||
|
@ -319,7 +319,7 @@ fn get_rich_cursor_data(
|
|||||||
let dc = DC::new()?;
|
let dc = DC::new()?;
|
||||||
let bitmap_dc = BitmapDC::new(dc.0, hbm_color)?;
|
let bitmap_dc = BitmapDC::new(dc.0, hbm_color)?;
|
||||||
if get_di_bits(out.as_mut_ptr(), bitmap_dc.dc(), hbm_color, width, height) > 0 {
|
if get_di_bits(out.as_mut_ptr(), bitmap_dc.dc(), hbm_color, width, height) > 0 {
|
||||||
bail!("Failed to get di bits: {}", get_error());
|
bail!("Failed to get di bits: {}", io::Error::last_os_error());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -603,7 +603,7 @@ async fn launch_server(session_id: DWORD, close_first: bool) -> ResultType<HANDL
|
|||||||
let wstr = wstr.as_ptr();
|
let wstr = wstr.as_ptr();
|
||||||
let h = unsafe { LaunchProcessWin(wstr, session_id, FALSE) };
|
let h = unsafe { LaunchProcessWin(wstr, session_id, FALSE) };
|
||||||
if h.is_null() {
|
if h.is_null() {
|
||||||
log::error!("Failed to launch server: {}", get_error());
|
log::error!("Failed to launch server: {}", io::Error::last_os_error());
|
||||||
}
|
}
|
||||||
Ok(h)
|
Ok(h)
|
||||||
}
|
}
|
||||||
@ -627,7 +627,7 @@ pub fn run_as_user(arg: Vec<&str>) -> ResultType<Option<std::process::Child>> {
|
|||||||
"Failed to launch {:?} with session id {}: {}",
|
"Failed to launch {:?} with session id {}: {}",
|
||||||
arg,
|
arg,
|
||||||
session_id,
|
session_id,
|
||||||
get_error()
|
io::Error::last_os_error()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Ok(None)
|
Ok(None)
|
||||||
@ -676,7 +676,7 @@ pub fn try_change_desktop() -> bool {
|
|||||||
if !res {
|
if !res {
|
||||||
let mut s = SUPPRESS.lock().unwrap();
|
let mut s = SUPPRESS.lock().unwrap();
|
||||||
if s.elapsed() > std::time::Duration::from_secs(3) {
|
if s.elapsed() > std::time::Duration::from_secs(3) {
|
||||||
log::error!("Failed to switch desktop: {}", get_error());
|
log::error!("Failed to switch desktop: {}", io::Error::last_os_error());
|
||||||
*s = Instant::now();
|
*s = Instant::now();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -688,41 +688,6 @@ pub fn try_change_desktop() -> bool {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_error() -> String {
|
|
||||||
unsafe {
|
|
||||||
let buff_size = 256;
|
|
||||||
let mut buff: Vec<u16> = Vec::with_capacity(buff_size);
|
|
||||||
buff.resize(buff_size, 0);
|
|
||||||
let errno = GetLastError();
|
|
||||||
let chars_copied = FormatMessageW(
|
|
||||||
FORMAT_MESSAGE_IGNORE_INSERTS
|
|
||||||
| FORMAT_MESSAGE_FROM_SYSTEM
|
|
||||||
| FORMAT_MESSAGE_ARGUMENT_ARRAY,
|
|
||||||
std::ptr::null(),
|
|
||||||
errno,
|
|
||||||
0,
|
|
||||||
buff.as_mut_ptr(),
|
|
||||||
(buff_size + 1) as u32,
|
|
||||||
std::ptr::null_mut(),
|
|
||||||
);
|
|
||||||
if chars_copied == 0 {
|
|
||||||
return "".to_owned();
|
|
||||||
}
|
|
||||||
let mut curr_char: usize = chars_copied as usize;
|
|
||||||
while curr_char > 0 {
|
|
||||||
let ch = buff[curr_char];
|
|
||||||
|
|
||||||
if ch >= ' ' as u16 {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
curr_char -= 1;
|
|
||||||
}
|
|
||||||
let sl = std::slice::from_raw_parts(buff.as_ptr(), curr_char);
|
|
||||||
let err_msg = String::from_utf16(sl);
|
|
||||||
return err_msg.unwrap_or("".to_owned());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn share_rdp() -> BOOL {
|
fn share_rdp() -> BOOL {
|
||||||
if get_reg("share_rdp") != "true" {
|
if get_reg("share_rdp") != "true" {
|
||||||
FALSE
|
FALSE
|
||||||
@ -1285,7 +1250,7 @@ pub fn block_input(v: bool) -> (bool, String) {
|
|||||||
if BlockInput(v) == TRUE {
|
if BlockInput(v) == TRUE {
|
||||||
(true, "".to_owned())
|
(true, "".to_owned())
|
||||||
} else {
|
} else {
|
||||||
(false, format!("Error code: {}", GetLastError()))
|
(false, format!("Error: {}", io::Error::last_os_error()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1559,9 +1524,10 @@ pub fn elevate_or_run_as_system(is_setup: bool, is_elevate: bool, is_run_as_syst
|
|||||||
if run_as_system(arg_run_as_system).is_ok() {
|
if run_as_system(arg_run_as_system).is_ok() {
|
||||||
std::process::exit(0);
|
std::process::exit(0);
|
||||||
} else {
|
} else {
|
||||||
unsafe {
|
log::error!(
|
||||||
log::error!("Failed to run as system, errno = {}", GetLastError());
|
"Failed to run as system, error {}",
|
||||||
}
|
io::Error::last_os_error()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -1569,16 +1535,15 @@ pub fn elevate_or_run_as_system(is_setup: bool, is_elevate: bool, is_run_as_syst
|
|||||||
if let Ok(true) = elevate(arg_elevate) {
|
if let Ok(true) = elevate(arg_elevate) {
|
||||||
std::process::exit(0);
|
std::process::exit(0);
|
||||||
} else {
|
} else {
|
||||||
unsafe {
|
log::error!("Failed to elevate, error {}", io::Error::last_os_error());
|
||||||
log::error!("Failed to elevate, errno = {}", GetLastError());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(_) => unsafe {
|
Err(_) => log::error!(
|
||||||
log::error!("Failed to get elevation status, errno = {}", GetLastError());
|
"Failed to get elevation status, error {}",
|
||||||
},
|
io::Error::last_os_error()
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1591,12 +1556,18 @@ pub fn is_elevated(process_id: Option<DWORD>) -> ResultType<bool> {
|
|||||||
None => GetCurrentProcess(),
|
None => GetCurrentProcess(),
|
||||||
};
|
};
|
||||||
if handle == NULL {
|
if handle == NULL {
|
||||||
bail!("Failed to open process, errno {}", GetLastError())
|
bail!(
|
||||||
|
"Failed to open process, error {}",
|
||||||
|
io::Error::last_os_error()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
let _handle = RAIIHandle(handle);
|
let _handle = RAIIHandle(handle);
|
||||||
let mut token: HANDLE = mem::zeroed();
|
let mut token: HANDLE = mem::zeroed();
|
||||||
if OpenProcessToken(handle, TOKEN_QUERY, &mut token) == FALSE {
|
if OpenProcessToken(handle, TOKEN_QUERY, &mut token) == FALSE {
|
||||||
bail!("Failed to open process token, errno {}", GetLastError())
|
bail!(
|
||||||
|
"Failed to open process token, error {}",
|
||||||
|
io::Error::last_os_error()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
let _token = RAIIHandle(token);
|
let _token = RAIIHandle(token);
|
||||||
let mut token_elevation: TOKEN_ELEVATION = mem::zeroed();
|
let mut token_elevation: TOKEN_ELEVATION = mem::zeroed();
|
||||||
@ -1609,7 +1580,10 @@ pub fn is_elevated(process_id: Option<DWORD>) -> ResultType<bool> {
|
|||||||
&mut size,
|
&mut size,
|
||||||
) == FALSE
|
) == FALSE
|
||||||
{
|
{
|
||||||
bail!("Failed to get token information, errno {}", GetLastError())
|
bail!(
|
||||||
|
"Failed to get token information, error {}",
|
||||||
|
io::Error::last_os_error()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(token_elevation.TokenIsElevated != 0)
|
Ok(token_elevation.TokenIsElevated != 0)
|
||||||
@ -1621,7 +1595,10 @@ pub fn is_foreground_window_elevated() -> ResultType<bool> {
|
|||||||
let mut process_id: DWORD = 0;
|
let mut process_id: DWORD = 0;
|
||||||
GetWindowThreadProcessId(GetForegroundWindow(), &mut process_id);
|
GetWindowThreadProcessId(GetForegroundWindow(), &mut process_id);
|
||||||
if process_id == 0 {
|
if process_id == 0 {
|
||||||
bail!("Failed to get processId, errno {}", GetLastError())
|
bail!(
|
||||||
|
"Failed to get processId, error {}",
|
||||||
|
io::Error::last_os_error()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
is_elevated(Some(process_id))
|
is_elevated(Some(process_id))
|
||||||
}
|
}
|
||||||
@ -1723,11 +1700,11 @@ pub fn create_process_with_logon(user: &str, pwd: &str, exe: &str, arg: &str) ->
|
|||||||
{
|
{
|
||||||
let last_error = GetLastError();
|
let last_error = GetLastError();
|
||||||
bail!(
|
bail!(
|
||||||
"CreateProcessWithLogonW failed : \"{}\", errno={}",
|
"CreateProcessWithLogonW failed : \"{}\", error {}",
|
||||||
last_error_table
|
last_error_table
|
||||||
.get(&last_error)
|
.get(&last_error)
|
||||||
.unwrap_or(&"Unknown error"),
|
.unwrap_or(&"Unknown error"),
|
||||||
last_error
|
io::Error::from_raw_os_error(last_error as _)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1786,8 +1763,8 @@ pub fn current_resolution(name: &str) -> ResultType<Resolution> {
|
|||||||
dm.dmSize = std::mem::size_of::<DEVMODEW>() as _;
|
dm.dmSize = std::mem::size_of::<DEVMODEW>() as _;
|
||||||
if EnumDisplaySettingsW(device_name.as_ptr(), ENUM_CURRENT_SETTINGS, &mut dm) == 0 {
|
if EnumDisplaySettingsW(device_name.as_ptr(), ENUM_CURRENT_SETTINGS, &mut dm) == 0 {
|
||||||
bail!(
|
bail!(
|
||||||
"failed to get currrent resolution, errno={}",
|
"failed to get currrent resolution, error {}",
|
||||||
GetLastError()
|
io::Error::last_os_error()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
let r = Resolution {
|
let r = Resolution {
|
||||||
@ -1820,9 +1797,9 @@ pub(super) fn change_resolution_directly(
|
|||||||
);
|
);
|
||||||
if res != DISP_CHANGE_SUCCESSFUL {
|
if res != DISP_CHANGE_SUCCESSFUL {
|
||||||
bail!(
|
bail!(
|
||||||
"ChangeDisplaySettingsExW failed, res={}, errno={}",
|
"ChangeDisplaySettingsExW failed, res={}, error {}",
|
||||||
res,
|
res,
|
||||||
GetLastError()
|
io::Error::last_os_error()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
use hbb_common::{allow_err, bail, lazy_static, log, ResultType};
|
use hbb_common::{allow_err, bail, lazy_static, log, ResultType};
|
||||||
use std::sync::{
|
use std::{
|
||||||
mpsc::{channel, Sender},
|
io::Error,
|
||||||
Mutex,
|
sync::{
|
||||||
|
mpsc::{channel, Sender},
|
||||||
|
Mutex,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
use winapi::{
|
use winapi::{
|
||||||
ctypes::c_int,
|
ctypes::c_int,
|
||||||
@ -10,10 +13,7 @@ use winapi::{
|
|||||||
ntdef::NULL,
|
ntdef::NULL,
|
||||||
windef::{HHOOK, POINT},
|
windef::{HHOOK, POINT},
|
||||||
},
|
},
|
||||||
um::{
|
um::{libloaderapi::GetModuleHandleExA, processthreadsapi::GetCurrentThreadId, winuser::*},
|
||||||
errhandlingapi::GetLastError, libloaderapi::GetModuleHandleExA,
|
|
||||||
processthreadsapi::GetCurrentThreadId, winuser::*,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT: u32 = 2;
|
const GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT: u32 = 2;
|
||||||
@ -44,7 +44,7 @@ fn do_hook(tx: Sender<String>) -> ResultType<(HHOOK, HHOOK)> {
|
|||||||
) {
|
) {
|
||||||
tx.send(format!(
|
tx.send(format!(
|
||||||
"Failed to GetModuleHandleExA, error: {}",
|
"Failed to GetModuleHandleExA, error: {}",
|
||||||
GetLastError()
|
Error::last_os_error()
|
||||||
))?;
|
))?;
|
||||||
return Ok(invalid_ret);
|
return Ok(invalid_ret);
|
||||||
}
|
}
|
||||||
@ -56,7 +56,7 @@ fn do_hook(tx: Sender<String>) -> ResultType<(HHOOK, HHOOK)> {
|
|||||||
) {
|
) {
|
||||||
tx.send(format!(
|
tx.send(format!(
|
||||||
"Failed to GetModuleHandleExA, error: {}",
|
"Failed to GetModuleHandleExA, error: {}",
|
||||||
GetLastError()
|
Error::last_os_error()
|
||||||
))?;
|
))?;
|
||||||
return Ok(invalid_ret);
|
return Ok(invalid_ret);
|
||||||
}
|
}
|
||||||
@ -68,7 +68,10 @@ fn do_hook(tx: Sender<String>) -> ResultType<(HHOOK, HHOOK)> {
|
|||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
if hook_keyboard.is_null() {
|
if hook_keyboard.is_null() {
|
||||||
tx.send(format!(" SetWindowsHookExA keyboard {}", GetLastError()))?;
|
tx.send(format!(
|
||||||
|
" SetWindowsHookExA keyboard, error {}",
|
||||||
|
Error::last_os_error()
|
||||||
|
))?;
|
||||||
return Ok(invalid_ret);
|
return Ok(invalid_ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,9 +79,15 @@ fn do_hook(tx: Sender<String>) -> ResultType<(HHOOK, HHOOK)> {
|
|||||||
if hook_mouse.is_null() {
|
if hook_mouse.is_null() {
|
||||||
if FALSE == UnhookWindowsHookEx(hook_keyboard) {
|
if FALSE == UnhookWindowsHookEx(hook_keyboard) {
|
||||||
// Fatal error
|
// Fatal error
|
||||||
log::error!(" UnhookWindowsHookEx keyboard {}", GetLastError());
|
log::error!(
|
||||||
|
" UnhookWindowsHookEx keyboard, error {}",
|
||||||
|
Error::last_os_error()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
tx.send(format!(" SetWindowsHookExA mouse {}", GetLastError()))?;
|
tx.send(format!(
|
||||||
|
" SetWindowsHookExA mouse, error {}",
|
||||||
|
Error::last_os_error()
|
||||||
|
))?;
|
||||||
return Ok(invalid_ret);
|
return Ok(invalid_ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,12 +140,18 @@ pub fn hook() -> ResultType<()> {
|
|||||||
|
|
||||||
if FALSE == UnhookWindowsHookEx(hook_keyboard as _) {
|
if FALSE == UnhookWindowsHookEx(hook_keyboard as _) {
|
||||||
// Fatal error
|
// Fatal error
|
||||||
log::error!("Failed UnhookWindowsHookEx keyboard {}", GetLastError());
|
log::error!(
|
||||||
|
"Failed UnhookWindowsHookEx keyboard, error {}",
|
||||||
|
Error::last_os_error()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if FALSE == UnhookWindowsHookEx(hook_mouse as _) {
|
if FALSE == UnhookWindowsHookEx(hook_mouse as _) {
|
||||||
// Fatal error
|
// Fatal error
|
||||||
log::error!("Failed UnhookWindowsHookEx mouse {}", GetLastError());
|
log::error!(
|
||||||
|
"Failed UnhookWindowsHookEx mouse, error {}",
|
||||||
|
Error::last_os_error()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
*CUR_HOOK_THREAD_ID.lock().unwrap() = 0;
|
*CUR_HOOK_THREAD_ID.lock().unwrap() = 0;
|
||||||
@ -162,7 +177,10 @@ pub fn unhook() -> ResultType<()> {
|
|||||||
let cur_hook_thread_id = CUR_HOOK_THREAD_ID.lock().unwrap();
|
let cur_hook_thread_id = CUR_HOOK_THREAD_ID.lock().unwrap();
|
||||||
if *cur_hook_thread_id != 0 {
|
if *cur_hook_thread_id != 0 {
|
||||||
if FALSE == PostThreadMessageA(*cur_hook_thread_id, WM_USER_EXIT_HOOK, 0, 0) {
|
if FALSE == PostThreadMessageA(*cur_hook_thread_id, WM_USER_EXIT_HOOK, 0, 0) {
|
||||||
bail!("Failed to post message to exit hook, {}", GetLastError());
|
bail!(
|
||||||
|
"Failed to post message to exit hook, error {}",
|
||||||
|
Error::last_os_error()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ use crate::{platform::windows::get_user_token, privacy_mode::PrivacyModeState};
|
|||||||
use hbb_common::{allow_err, bail, log, ResultType};
|
use hbb_common::{allow_err, bail, log, ResultType};
|
||||||
use std::{
|
use std::{
|
||||||
ffi::CString,
|
ffi::CString,
|
||||||
|
io::Error,
|
||||||
time::{Duration, Instant},
|
time::{Duration, Instant},
|
||||||
};
|
};
|
||||||
use winapi::{
|
use winapi::{
|
||||||
@ -12,7 +13,6 @@ use winapi::{
|
|||||||
windef::HWND,
|
windef::HWND,
|
||||||
},
|
},
|
||||||
um::{
|
um::{
|
||||||
errhandlingapi::GetLastError,
|
|
||||||
handleapi::CloseHandle,
|
handleapi::CloseHandle,
|
||||||
libloaderapi::{GetModuleHandleA, GetProcAddress},
|
libloaderapi::{GetModuleHandleA, GetProcAddress},
|
||||||
memoryapi::{VirtualAllocEx, WriteProcessMemory},
|
memoryapi::{VirtualAllocEx, WriteProcessMemory},
|
||||||
@ -266,9 +266,9 @@ impl PrivacyModeImpl {
|
|||||||
CloseHandle(token);
|
CloseHandle(token);
|
||||||
if 0 == create_res {
|
if 0 == create_res {
|
||||||
bail!(
|
bail!(
|
||||||
"Failed to create privacy window process {}, code {}",
|
"Failed to create privacy window process {}, error {}",
|
||||||
cmdline,
|
cmdline,
|
||||||
GetLastError()
|
Error::last_os_error()
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -284,8 +284,8 @@ impl PrivacyModeImpl {
|
|||||||
CloseHandle(proc_info.hProcess);
|
CloseHandle(proc_info.hProcess);
|
||||||
|
|
||||||
bail!(
|
bail!(
|
||||||
"Failed to create privacy window process, {}",
|
"Failed to create privacy window process, error {}",
|
||||||
GetLastError()
|
Error::last_os_error()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
use super::{PrivacyMode, PrivacyModeState, INVALID_PRIVACY_MODE_CONN_ID, NO_DISPLAYS};
|
use super::{PrivacyMode, PrivacyModeState, INVALID_PRIVACY_MODE_CONN_ID, NO_DISPLAYS};
|
||||||
use crate::virtual_display_manager;
|
use crate::virtual_display_manager;
|
||||||
use hbb_common::{allow_err, bail, config::Config, log, ResultType};
|
use hbb_common::{allow_err, bail, config::Config, log, ResultType};
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::{
|
||||||
|
io::Error,
|
||||||
|
ops::{Deref, DerefMut},
|
||||||
|
};
|
||||||
use virtual_display::MonitorMode;
|
use virtual_display::MonitorMode;
|
||||||
use winapi::{
|
use winapi::{
|
||||||
shared::{
|
shared::{
|
||||||
@ -9,7 +12,6 @@ use winapi::{
|
|||||||
ntdef::{NULL, WCHAR},
|
ntdef::{NULL, WCHAR},
|
||||||
},
|
},
|
||||||
um::{
|
um::{
|
||||||
errhandlingapi::GetLastError,
|
|
||||||
wingdi::{
|
wingdi::{
|
||||||
DEVMODEW, DISPLAY_DEVICEW, DISPLAY_DEVICE_ACTIVE, DISPLAY_DEVICE_ATTACHED_TO_DESKTOP,
|
DEVMODEW, DISPLAY_DEVICEW, DISPLAY_DEVICE_ACTIVE, DISPLAY_DEVICE_ATTACHED_TO_DESKTOP,
|
||||||
DISPLAY_DEVICE_MIRRORING_DRIVER, DISPLAY_DEVICE_PRIMARY_DEVICE, DM_POSITION,
|
DISPLAY_DEVICE_MIRRORING_DRIVER, DISPLAY_DEVICE_PRIMARY_DEVICE, DM_POSITION,
|
||||||
@ -193,9 +195,9 @@ impl PrivacyModeImpl {
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
bail!(
|
bail!(
|
||||||
"Failed EnumDisplaySettingsW, device name: {:?}, error code: {}",
|
"Failed EnumDisplaySettingsW, device name: {:?}, error: {}",
|
||||||
std::string::String::from_utf16(&display.name),
|
std::string::String::from_utf16(&display.name),
|
||||||
GetLastError()
|
Error::last_os_error()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -227,9 +229,9 @@ impl PrivacyModeImpl {
|
|||||||
== EnumDisplaySettingsW(dd.DeviceName.as_ptr(), ENUM_CURRENT_SETTINGS, &mut dm)
|
== EnumDisplaySettingsW(dd.DeviceName.as_ptr(), ENUM_CURRENT_SETTINGS, &mut dm)
|
||||||
{
|
{
|
||||||
bail!(
|
bail!(
|
||||||
"Failed EnumDisplaySettingsW, device name: {:?}, error code: {}",
|
"Failed EnumDisplaySettingsW, device name: {:?}, error: {}",
|
||||||
std::string::String::from_utf16(&dd.DeviceName),
|
std::string::String::from_utf16(&dd.DeviceName),
|
||||||
GetLastError()
|
Error::last_os_error()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2357,10 +2357,28 @@ impl Connection {
|
|||||||
|
|
||||||
#[cfg(all(windows, feature = "virtual_display_driver"))]
|
#[cfg(all(windows, feature = "virtual_display_driver"))]
|
||||||
async fn toggle_virtual_display(&mut self, t: ToggleVirtualDisplay) {
|
async fn toggle_virtual_display(&mut self, t: ToggleVirtualDisplay) {
|
||||||
|
let make_msg = |text: String| {
|
||||||
|
let mut msg_out = Message::new();
|
||||||
|
let res = MessageBox {
|
||||||
|
msgtype: "nook-nocancel-hasclose".to_owned(),
|
||||||
|
title: "Virtual display".to_owned(),
|
||||||
|
text,
|
||||||
|
link: "".to_owned(),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
msg_out.set_message_box(res);
|
||||||
|
msg_out
|
||||||
|
};
|
||||||
|
|
||||||
if t.on {
|
if t.on {
|
||||||
if let Err(e) = virtual_display_manager::plug_in_index_modes(t.display as _, Vec::new())
|
if let Err(e) = virtual_display_manager::plug_in_index_modes(t.display as _, Vec::new())
|
||||||
{
|
{
|
||||||
log::error!("Failed to plug in virtual display: {}", e);
|
log::error!("Failed to plug in virtual display: {}", e);
|
||||||
|
self.send(make_msg(format!(
|
||||||
|
"Failed to plug in virtual display: {}",
|
||||||
|
e
|
||||||
|
)))
|
||||||
|
.await;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let indices = if t.display == -1 {
|
let indices = if t.display == -1 {
|
||||||
@ -2370,6 +2388,11 @@ impl Connection {
|
|||||||
};
|
};
|
||||||
if let Err(e) = virtual_display_manager::plug_out_peer_request(&indices) {
|
if let Err(e) = virtual_display_manager::plug_out_peer_request(&indices) {
|
||||||
log::error!("Failed to plug out virtual display {:?}: {}", &indices, e);
|
log::error!("Failed to plug out virtual display {:?}: {}", &indices, e);
|
||||||
|
self.send(make_msg(format!(
|
||||||
|
"Failed to plug out virtual displays: {}",
|
||||||
|
e
|
||||||
|
)))
|
||||||
|
.await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user