From 6f0fbd1088ff9db5b0c499e27776c2c47bc1732b Mon Sep 17 00:00:00 2001 From: fufesou Date: Mon, 20 Nov 2023 15:30:56 +0800 Subject: [PATCH 01/10] feat, format idd error message Signed-off-by: fufesou --- .../dylib/src/win10/IddController.c | 253 +++++++++++++++--- .../dylib/src/win10/IddController.h | 17 ++ 2 files changed, 231 insertions(+), 39 deletions(-) diff --git a/libs/virtual_display/dylib/src/win10/IddController.c b/libs/virtual_display/dylib/src/win10/IddController.c index 1b177d47b..43322edf2 100644 --- a/libs/virtual_display/dylib/src/win10/IddController.c +++ b/libs/virtual_display/dylib/src/win10/IddController.c @@ -9,6 +9,12 @@ #include "./Public.h" +typedef struct DeviceCreateCallbackContext +{ + HANDLE hEvent; + SW_DEVICE_LIFETIME* lifetime; + HRESULT hrCreateResult; +} DeviceCreateCallbackContext; const GUID GUID_DEVINTERFACE_IDD_DRIVER_DEVICE = \ { 0x781EF630, 0x72B2, 0x11d2, { 0xB8, 0x52, 0x00, 0xC0, 0x4E, 0xAF, 0x52, 0x72 } }; @@ -43,6 +49,8 @@ BOOLEAN GetDevicePath2( HANDLE DeviceOpenHandle(); VOID DeviceCloseHandle(HANDLE handle); +LPSTR formatErrorString(DWORD error); + void SetLastMsg(const char* format, ...) { memset(g_lastMsg, 0, sizeof(g_lastMsg)); @@ -82,7 +90,23 @@ BOOL InstallUpdate(LPCWSTR fullInfPath, PBOOL rebootRequired) DWORD error = GetLastError(); 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: Install the cert.\n", error, errorString == NULL ? "(NULL)\n" : errorString); + break; + case 0xe0000247: + SetLastMsg("Failed InstallUpdate UpdateDriverForPlugAndPlayDevicesW, error: 0x%x, %s Please try: \n1. Uninstall the driver first.\n2. Install the cert.\n3. Check the device manager and event viewer.\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) { printf(g_lastMsg); @@ -108,7 +132,12 @@ BOOL Uninstall(LPCWSTR fullInfPath, PBOOL rebootRequired) DWORD error = GetLastError(); 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) { printf(g_lastMsg); @@ -132,7 +161,13 @@ BOOL IsDeviceCreated(PBOOL created) DIGCF_DEVICEINTERFACE)); // Function class devices. 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) { printf(g_lastMsg); @@ -165,7 +200,12 @@ BOOL IsDeviceCreated(PBOOL created) 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) { printf(g_lastMsg); @@ -180,36 +220,40 @@ BOOL IsDeviceCreated(PBOOL created) } BOOL DeviceCreate(PHSWDEVICE hSwDevice) +{ + SW_DEVICE_LIFETIME lifetime = SWDeviceLifetimeHandle; + return DeviceCreateWithLifetime(&lifetime, hSwDevice); +} + +BOOL DeviceCreateWithLifetime(SW_DEVICE_LIFETIME *lifetime, PHSWDEVICE hSwDevice) { SetLastMsg("Success"); if (*hSwDevice != NULL) { - SetLastMsg("Device handler is not NULL\n"); + SetLastMsg("Device handle is not NULL\n"); return FALSE; } - BOOL created = TRUE; - if (FALSE == IsDeviceCreated(&created)) - { - return FALSE; - } - if (created == TRUE) - { - SetLastMsg("Device is already created, please destroy it first\n"); - if (g_printMsg) - { - printf(g_lastMsg); - } - return FALSE; - } + // No need to check if the device is previous 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 + // 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 + // for the purposes of updating properties and interfaces or changing the lifetime. + // // create device HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); if (hEvent == INVALID_HANDLE_VALUE || hEvent == NULL) { 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) { printf(g_lastMsg); @@ -218,6 +262,8 @@ BOOL DeviceCreate(PHSWDEVICE hSwDevice) return FALSE; } + DeviceCreateCallbackContext callbackContext = { hEvent, lifetime, E_FAIL, }; + SW_DEVICE_CREATE_INFO createInfo = { 0 }; PCWSTR description = L"RustDesk Idd Driver"; @@ -243,7 +289,7 @@ BOOL DeviceCreate(PHSWDEVICE hSwDevice) 0, NULL, CreationCallback, - &hEvent, + &callbackContext, hSwDevice); if (FAILED(hr)) { @@ -259,6 +305,7 @@ BOOL DeviceCreate(PHSWDEVICE hSwDevice) // Wait for callback to signal that the device has been created printf("Waiting for device to be created....\n"); DWORD waitResult = WaitForSingleObject(hEvent, 10 * 1000); + CloseHandle(hEvent); if (waitResult != WAIT_OBJECT_0) { SetLastMsg("Failed DeviceCreate wait for device creation 0x%d\n", waitResult); @@ -268,8 +315,17 @@ BOOL DeviceCreate(PHSWDEVICE hSwDevice) } return FALSE; } - // printf("Device created\n\n"); - return TRUE; + + if (SUCCEEDED(callbackContext.hrCreateResult)) + { + // printf("Device created\n\n"); + return TRUE; + } + else + { + SetLastMsg("Failed DeviceCreate SwDeviceCreate, hrCreateResult 0x%lx\n", callbackContext.hrCreateResult); + return FALSE; + } } VOID DeviceClose(HSWDEVICE hSwDevice) @@ -278,8 +334,38 @@ VOID DeviceClose(HSWDEVICE hSwDevice) if (hSwDevice != INVALID_HANDLE_VALUE && hSwDevice != NULL) { + HRESULT result = SwDeviceSetLifetime(hSwDevice, SWDeviceLifetimeHandle); 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) @@ -348,8 +434,16 @@ BOOL MonitorPlugIn(UINT index, UINT edid, INT retries) if (ret == FALSE) { DWORD error = GetLastError(); - SetLastMsg("Failed MonitorPlugIn DeviceIoControl 0x%lx\n", error); - printf(g_lastMsg); + LPSTR errorString = formatErrorString(error); + 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 +476,12 @@ BOOL MonitorPlugOut(UINT index) 0)) // Ptr to Overlapped structure { 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) { printf(g_lastMsg); @@ -441,7 +540,12 @@ BOOL MonitorModesUpdate(UINT index, UINT modeCount, PMonitorMode modes) 0)) // Ptr to Overlapped structure { 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) { printf(g_lastMsg); @@ -466,11 +570,30 @@ CreationCallback( _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); } @@ -611,7 +734,13 @@ BOOLEAN GetDevicePath2( DIGCF_DEVICEINTERFACE)); // Function class devices. 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) { printf(g_lastMsg); @@ -627,7 +756,13 @@ BOOLEAN GetDevicePath2( 0, // &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) { printf(g_lastMsg); @@ -647,9 +782,15 @@ BOOLEAN GetDevicePath2( &requiredLength, 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) { printf(g_lastMsg); @@ -671,7 +812,13 @@ BOOLEAN GetDevicePath2( } 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) { printf(g_lastMsg); @@ -687,7 +834,13 @@ BOOLEAN GetDevicePath2( &requiredLength, 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) { printf(g_lastMsg); @@ -698,7 +851,7 @@ BOOLEAN GetDevicePath2( hr = StringCchCopy(DevicePath, BufLen, deviceInterfaceDetailData->DevicePath); if (FAILED(hr)) { - SetLastMsg("Error: Failed GetDevicePath2 StringCchCopy HRESULT 0x%x", hr); + SetLastMsg("Failed GetDevicePath2 StringCchCopy, HRESULT 0x%x", hr); if (g_printMsg) { printf(g_lastMsg); @@ -759,7 +912,12 @@ HANDLE DeviceOpenHandle() if (hDevice == INVALID_HANDLE_VALUE || hDevice == NULL) { 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) { printf(g_lastMsg); @@ -782,3 +940,20 @@ VOID SetPrintErrMsg(BOOL b) { 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; +} + diff --git a/libs/virtual_display/dylib/src/win10/IddController.h b/libs/virtual_display/dylib/src/win10/IddController.h index 909f17423..6e87a78df 100644 --- a/libs/virtual_display/dylib/src/win10/IddController.h +++ b/libs/virtual_display/dylib/src/win10/IddController.h @@ -58,10 +58,27 @@ BOOL IsDeviceCreated(PBOOL created); */ 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. * * @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); From 5064696480cf2d68c6c7af2e7b68cbe1cce3a54c Mon Sep 17 00:00:00 2001 From: fufesou Date: Mon, 20 Nov 2023 15:46:22 +0800 Subject: [PATCH 02/10] send msgbox when plugging in/out virtual displays Signed-off-by: fufesou --- src/server/connection.rs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/server/connection.rs b/src/server/connection.rs index 12e52afba..464edfb37 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -2357,10 +2357,28 @@ impl Connection { #[cfg(all(windows, feature = "virtual_display_driver"))] 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 let Err(e) = virtual_display_manager::plug_in_index_modes(t.display as _, Vec::new()) { log::error!("Failed to plug in virtual display: {}", e); + self.send(make_msg(format!( + "Failed to plug in virtual display: {}", + e + ))) + .await; } } else { let indices = if t.display == -1 { @@ -2370,6 +2388,11 @@ impl Connection { }; if let Err(e) = virtual_display_manager::plug_out_peer_request(&indices) { log::error!("Failed to plug out virtual display {:?}: {}", &indices, e); + self.send(make_msg(format!( + "Failed to plug out virtual displays: {}", + e + ))) + .await; } } } From 3fd97f7e6040a6daf967b85836842035ba51eaac Mon Sep 17 00:00:00 2001 From: fufesou Date: Mon, 20 Nov 2023 15:54:21 +0800 Subject: [PATCH 03/10] modify error message Signed-off-by: fufesou --- libs/virtual_display/dylib/src/win10/IddController.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/virtual_display/dylib/src/win10/IddController.c b/libs/virtual_display/dylib/src/win10/IddController.c index 43322edf2..1f8bbf950 100644 --- a/libs/virtual_display/dylib/src/win10/IddController.c +++ b/libs/virtual_display/dylib/src/win10/IddController.c @@ -97,7 +97,7 @@ BOOL InstallUpdate(LPCWSTR fullInfPath, PBOOL rebootRequired) SetLastMsg("Failed InstallUpdate UpdateDriverForPlugAndPlayDevicesW, error: 0x%x, %s Please try: Install the cert.\n", error, errorString == NULL ? "(NULL)\n" : errorString); break; case 0xe0000247: - SetLastMsg("Failed InstallUpdate UpdateDriverForPlugAndPlayDevicesW, error: 0x%x, %s Please try: \n1. Uninstall the driver first.\n2. Install the cert.\n3. Check the device manager and event viewer.\n", error, errorString == NULL ? "(NULL)\n" : errorString); + SetLastMsg("Failed InstallUpdate UpdateDriverForPlugAndPlayDevicesW, error: 0x%x, %s Please try: \n1. Check the device manager and event viewer.\n2. Uninstall the driver, install the cert, then try again.\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); From 0c8643837fec1e8694fa45470a30257ae6dbcab8 Mon Sep 17 00:00:00 2001 From: fufesou Date: Mon, 20 Nov 2023 16:11:59 +0800 Subject: [PATCH 04/10] Modify the error message Signed-off-by: fufesou --- libs/virtual_display/dylib/src/win10/IddController.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/virtual_display/dylib/src/win10/IddController.c b/libs/virtual_display/dylib/src/win10/IddController.c index 1f8bbf950..25c30729c 100644 --- a/libs/virtual_display/dylib/src/win10/IddController.c +++ b/libs/virtual_display/dylib/src/win10/IddController.c @@ -94,10 +94,10 @@ BOOL InstallUpdate(LPCWSTR fullInfPath, PBOOL rebootRequired) switch (error) { case 0x109: - SetLastMsg("Failed InstallUpdate UpdateDriverForPlugAndPlayDevicesW, error: 0x%x, %s Please try: Install the cert.\n", error, errorString == NULL ? "(NULL)\n" : errorString); + 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 the driver, install the cert, then try again.\n", error, errorString == NULL ? "(NULL)\n" : errorString); + 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); From 2c432dbf4d97e09e6d2fb2a9dc9c7524df37f29e Mon Sep 17 00:00:00 2001 From: fufesou Date: Mon, 20 Nov 2023 16:41:02 +0800 Subject: [PATCH 05/10] format idd error message Signed-off-by: fufesou --- .../dylib/src/win10/IddController.c | 63 ++++++++++++++++--- 1 file changed, 55 insertions(+), 8 deletions(-) diff --git a/libs/virtual_display/dylib/src/win10/IddController.c b/libs/virtual_display/dylib/src/win10/IddController.c index 25c30729c..eb3a6238a 100644 --- a/libs/virtual_display/dylib/src/win10/IddController.c +++ b/libs/virtual_display/dylib/src/win10/IddController.c @@ -293,7 +293,12 @@ BOOL DeviceCreateWithLifetime(SW_DEVICE_LIFETIME *lifetime, PHSWDEVICE hSwDevice hSwDevice); if (FAILED(hr)) { - SetLastMsg("Failed DeviceCreate SwDeviceCreate 0x%lx\n", hr); + LPSTR errorString = formatErrorString((DWORD)hr); + SetLastMsg("Failed DeviceCreate SwDeviceCreate, hresult 0x%lx, %s\n", hr, errorString == NULL ? "(NULL)\n" : errorString); + if (errorString != NULL) + { + LocalFree(errorString); + } if (g_printMsg) { printf(g_lastMsg); @@ -308,7 +313,29 @@ BOOL DeviceCreateWithLifetime(SW_DEVICE_LIFETIME *lifetime, PHSWDEVICE hSwDevice CloseHandle(hEvent); 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) { printf(g_lastMsg); @@ -323,7 +350,12 @@ BOOL DeviceCreateWithLifetime(SW_DEVICE_LIFETIME *lifetime, PHSWDEVICE hSwDevice } else { - SetLastMsg("Failed DeviceCreate SwDeviceCreate, hrCreateResult 0x%lx\n", callbackContext.hrCreateResult); + 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; } } @@ -405,7 +437,12 @@ BOOL MonitorPlugIn(UINT index, UINT edid, INT retries) HRESULT hr = CoCreateGuid(&plugIn.ContainerId); if (!SUCCEEDED(hr)) { - SetLastMsg("Failed MonitorPlugIn CoCreateGuid %d\n", hr); + LPSTR errorString = formatErrorString((DWORD)hr); + SetLastMsg("Failed MonitorPlugIn CoCreateGuid, hresult 0x%lx, %s\n", hr, errorString == NULL ? "(NULL)\n" : errorString); + if (errorString != NULL) + { + LocalFree(errorString); + } if (g_printMsg) { printf(g_lastMsg); @@ -513,7 +550,7 @@ BOOL MonitorModesUpdate(UINT index, UINT modeCount, PMonitorMode modes) PCtlMonitorModes pMonitorModes = (PCtlMonitorModes)malloc(buflen); if (pMonitorModes == NULL) { - SetLastMsg("Failed MonitorModesUpdate CtlMonitorModes malloc 0x%lx\n"); + SetLastMsg("Failed MonitorModesUpdate CtlMonitorModes malloc\n"); if (g_printMsg) { printf(g_lastMsg); @@ -618,7 +655,7 @@ GetDevicePath( CM_GET_DEVICE_INTERFACE_LIST_ALL_DEVICES); 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) { printf(g_lastMsg); @@ -688,7 +725,12 @@ GetDevicePath( hr = StringCchCopy(DevicePath, BufLen, deviceInterfaceList); 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\n", hr, errorString == NULL ? "(NULL)\n" : errorString); + if (errorString != NULL) + { + LocalFree(errorString); + } if (g_printMsg) { printf(g_lastMsg); @@ -851,7 +893,12 @@ BOOLEAN GetDevicePath2( hr = StringCchCopy(DevicePath, BufLen, deviceInterfaceDetailData->DevicePath); if (FAILED(hr)) { - SetLastMsg("Failed GetDevicePath2 StringCchCopy, HRESULT 0x%x", hr); + LPSTR errorString = formatErrorString((DWORD)hr); + SetLastMsg("Failed GetDevicePath2 StringCchCopy, hresult 0x%lx, %s\n", hr, errorString == NULL ? "(NULL)\n" : errorString); + if (errorString != NULL) + { + LocalFree(errorString); + } if (g_printMsg) { printf(g_lastMsg); From 9c12c3ee4e478ea0519c1c4143c3b0c9847e9954 Mon Sep 17 00:00:00 2001 From: fufesou Date: Mon, 20 Nov 2023 16:48:05 +0800 Subject: [PATCH 06/10] remove useless \n Signed-off-by: fufesou --- libs/virtual_display/dylib/src/win10/IddController.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libs/virtual_display/dylib/src/win10/IddController.c b/libs/virtual_display/dylib/src/win10/IddController.c index eb3a6238a..0c6d06799 100644 --- a/libs/virtual_display/dylib/src/win10/IddController.c +++ b/libs/virtual_display/dylib/src/win10/IddController.c @@ -294,7 +294,7 @@ BOOL DeviceCreateWithLifetime(SW_DEVICE_LIFETIME *lifetime, PHSWDEVICE hSwDevice if (FAILED(hr)) { LPSTR errorString = formatErrorString((DWORD)hr); - SetLastMsg("Failed DeviceCreate SwDeviceCreate, hresult 0x%lx, %s\n", hr, errorString == NULL ? "(NULL)\n" : errorString); + SetLastMsg("Failed DeviceCreate SwDeviceCreate, hresult 0x%lx, %s", hr, errorString == NULL ? "(NULL)\n" : errorString); if (errorString != NULL) { LocalFree(errorString); @@ -438,7 +438,7 @@ BOOL MonitorPlugIn(UINT index, UINT edid, INT retries) if (!SUCCEEDED(hr)) { LPSTR errorString = formatErrorString((DWORD)hr); - SetLastMsg("Failed MonitorPlugIn CoCreateGuid, hresult 0x%lx, %s\n", hr, errorString == NULL ? "(NULL)\n" : errorString); + SetLastMsg("Failed MonitorPlugIn CoCreateGuid, hresult 0x%lx, %s", hr, errorString == NULL ? "(NULL)\n" : errorString); if (errorString != NULL) { LocalFree(errorString); @@ -726,7 +726,7 @@ GetDevicePath( if (FAILED(hr)) { LPSTR errorString = formatErrorString((DWORD)hr); - SetLastMsg("Failed GetDevicePath StringCchCopy, hresult 0x%lx, %s\n", hr, errorString == NULL ? "(NULL)\n" : errorString); + SetLastMsg("Failed GetDevicePath StringCchCopy, hresult 0x%lx, %s", hr, errorString == NULL ? "(NULL)\n" : errorString); if (errorString != NULL) { LocalFree(errorString); @@ -894,7 +894,7 @@ BOOLEAN GetDevicePath2( if (FAILED(hr)) { LPSTR errorString = formatErrorString((DWORD)hr); - SetLastMsg("Failed GetDevicePath2 StringCchCopy, hresult 0x%lx, %s\n", hr, errorString == NULL ? "(NULL)\n" : errorString); + SetLastMsg("Failed GetDevicePath2 StringCchCopy, hresult 0x%lx, %s", hr, errorString == NULL ? "(NULL)\n" : errorString); if (errorString != NULL) { LocalFree(errorString); From c85682de8d21bf8dd904ca72ba6f1b0c45f88082 Mon Sep 17 00:00:00 2001 From: fufesou Date: Mon, 20 Nov 2023 17:15:15 +0800 Subject: [PATCH 07/10] Refact, replace GetLastError() by std::io::Error::last_os_error() Signed-off-by: fufesou --- libs/scrap/src/dxgi/mag.rs | 42 ++++++++++---------- src/platform/windows.rs | 51 +++++++++++++++--------- src/privacy_mode/win_input.rs | 52 +++++++++++++++++-------- src/privacy_mode/win_topmost_window.rs | 10 ++--- src/privacy_mode/win_virtual_display.rs | 14 ++++--- 5 files changed, 102 insertions(+), 67 deletions(-) diff --git a/libs/scrap/src/dxgi/mag.rs b/libs/scrap/src/dxgi/mag.rs index 188cf2c9c..52404b3af 100644 --- a/libs/scrap/src/dxgi/mag.rs +++ b/libs/scrap/src/dxgi/mag.rs @@ -139,9 +139,9 @@ impl MagInterface { return Err(Error::new( ErrorKind::Other, format!( - "Failed to LoadLibraryExA {}, error: {}", + "Failed to LoadLibraryExA {}, error: {:?}", lib_file_name, - GetLastError() + Error::last_os_error() ), )); }; @@ -173,7 +173,7 @@ impl MagInterface { if FALSE == init_func() { return Err(Error::new( ErrorKind::Other, - format!("Failed to MagInitialize, error: {}", GetLastError()), + format!("Failed to MagInitialize, error: {:?}", Error::last_os_error()), )); } else { s.init_succeeded = true; @@ -195,9 +195,9 @@ impl MagInterface { return Err(Error::new( ErrorKind::Other, format!( - "Failed to GetProcAddress {}, error: {}", + "Failed to GetProcAddress {}, error {:?}", func_name, - GetLastError() + Error::last_os_error() ), )); } @@ -209,14 +209,14 @@ impl MagInterface { if let Some(uninit_func) = self.mag_uninitialize_func { unsafe { if FALSE == uninit_func() { - println!("Failed MagUninitialize {}", GetLastError()) + println!("Failed MagUninitialize, error {:?}", Error::last_os_error()) } } } if !self.lib_handle.is_null() { unsafe { if FALSE == FreeLibrary(self.lib_handle) { - println!("Failed FreeLibrary {}", GetLastError()) + println!("Failed FreeLibrary, error {:?}", Error::last_os_error()) } } self.lib_handle = NULL as _; @@ -315,7 +315,7 @@ impl CapturerMag { ) { return Err(Error::new( ErrorKind::Other, - format!("Failed to GetModuleHandleExA, error: {}", GetLastError()), + format!("Failed to GetModuleHandleExA, error {:?}", Error::last_os_error()), )); } @@ -366,8 +366,8 @@ impl CapturerMag { return Err(Error::new( ErrorKind::Other, format!( - "Failed to CreateWindowExA host_window, error: {}", - GetLastError() + "Failed to CreateWindowExA host_window, error {:?}", + Error::last_os_error() ), )); } @@ -391,8 +391,8 @@ impl CapturerMag { return Err(Error::new( ErrorKind::Other, format!( - "Failed CreateWindowA magnifier_window, error: {}", - GetLastError() + "Failed CreateWindowA magnifier_window, error {:?}", + Error::last_os_error() ), )); } @@ -411,8 +411,8 @@ impl CapturerMag { return Err(Error::new( ErrorKind::Other, format!( - "Failed to MagSetImageScalingCallback, error: {}", - GetLastError() + "Failed to MagSetImageScalingCallback, error {:?}", + Error::last_os_error() ), )); } @@ -455,10 +455,10 @@ impl CapturerMag { return Err(Error::new( ErrorKind::Other, format!( - "Failed MagSetWindowFilterList for cls {} name {}, err: {}", + "Failed MagSetWindowFilterList for cls {} name {}, error {:?}", cls, name, - GetLastError() + Error::last_os_error() ), )); } @@ -530,12 +530,12 @@ impl CapturerMag { return Err(Error::new( ErrorKind::Other, format!( - "Failed SetWindowPos (x, y, w , h) - ({}, {}, {}, {}), error {}", + "Failed SetWindowPos (x, y, w , h) - ({}, {}, {}, {}), error {:?}", self.rect.left, self.rect.top, self.rect.right - self.rect.left, self.rect.bottom - self.rect.top, - GetLastError() + Error::last_os_error() ), )); } @@ -546,7 +546,7 @@ impl CapturerMag { if FALSE == set_window_source_func(self.magnifier_window, self.rect) { return Err(Error::new( ErrorKind::Other, - format!("Failed to MagSetWindowSource, error: {}", GetLastError()), + format!("Failed to MagSetWindowSource, error {:?}", Error::last_os_error()), )); } } else { @@ -578,7 +578,7 @@ impl CapturerMag { unsafe { if FALSE == DestroyWindow(self.magnifier_window) { // - println!("Failed DestroyWindow magnifier window {}", GetLastError()) + println!("Failed DestroyWindow magnifier window, error {:?}", Error::last_os_error()) } } } @@ -588,7 +588,7 @@ impl CapturerMag { unsafe { if FALSE == DestroyWindow(self.host_window) { // - println!("Failed DestroyWindow host window {}", GetLastError()) + println!("Failed DestroyWindow host window, error {:?}", Error::last_os_error()) } } } diff --git a/src/platform/windows.rs b/src/platform/windows.rs index 4e88ea99c..34d85a6cd 100644 --- a/src/platform/windows.rs +++ b/src/platform/windows.rs @@ -1285,7 +1285,7 @@ pub fn block_input(v: bool) -> (bool, String) { if BlockInput(v) == TRUE { (true, "".to_owned()) } else { - (false, format!("Error code: {}", GetLastError())) + (false, format!("Error: {:?}", io::Error::last_os_error())) } } } @@ -1559,9 +1559,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() { std::process::exit(0); } else { - unsafe { - log::error!("Failed to run as system, errno = {}", GetLastError()); - } + log::error!( + "Failed to run as system, error {:?}", + io::Error::last_os_error() + ); } } } else { @@ -1569,16 +1570,18 @@ pub fn elevate_or_run_as_system(is_setup: bool, is_elevate: bool, is_run_as_syst if let Ok(true) = elevate(arg_elevate) { std::process::exit(0); } else { - unsafe { - log::error!("Failed to elevate, errno = {}", GetLastError()); - } + log::error!( + "Failed to elevate, error {:?}", + io::Error::last_os_error() + ); } } } } - Err(_) => unsafe { - log::error!("Failed to get elevation status, errno = {}", GetLastError()); - }, + Err(_) => log::error!( + "Failed to get elevation status, error {:?}", + io::Error::last_os_error() + ), } } } @@ -1591,12 +1594,18 @@ pub fn is_elevated(process_id: Option) -> ResultType { None => GetCurrentProcess(), }; 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 mut token: HANDLE = mem::zeroed(); 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 mut token_elevation: TOKEN_ELEVATION = mem::zeroed(); @@ -1609,7 +1618,10 @@ pub fn is_elevated(process_id: Option) -> ResultType { &mut size, ) == 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) @@ -1621,7 +1633,10 @@ pub fn is_foreground_window_elevated() -> ResultType { let mut process_id: DWORD = 0; GetWindowThreadProcessId(GetForegroundWindow(), &mut process_id); 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)) } @@ -1786,8 +1801,8 @@ pub fn current_resolution(name: &str) -> ResultType { dm.dmSize = std::mem::size_of::() as _; if EnumDisplaySettingsW(device_name.as_ptr(), ENUM_CURRENT_SETTINGS, &mut dm) == 0 { bail!( - "failed to get currrent resolution, errno={}", - GetLastError() + "failed to get currrent resolution, error {:?}", + io::Error::last_os_error() ); } let r = Resolution { @@ -1820,9 +1835,9 @@ pub(super) fn change_resolution_directly( ); if res != DISP_CHANGE_SUCCESSFUL { bail!( - "ChangeDisplaySettingsExW failed, res={}, errno={}", + "ChangeDisplaySettingsExW failed, res={}, error {:?}", res, - GetLastError() + io::Error::last_os_error() ); } Ok(()) diff --git a/src/privacy_mode/win_input.rs b/src/privacy_mode/win_input.rs index 486f3b5e4..df6ee0143 100644 --- a/src/privacy_mode/win_input.rs +++ b/src/privacy_mode/win_input.rs @@ -1,7 +1,10 @@ use hbb_common::{allow_err, bail, lazy_static, log, ResultType}; -use std::sync::{ - mpsc::{channel, Sender}, - Mutex, +use std::{ + io::Error, + sync::{ + mpsc::{channel, Sender}, + Mutex, + }, }; use winapi::{ ctypes::c_int, @@ -10,10 +13,7 @@ use winapi::{ ntdef::NULL, windef::{HHOOK, POINT}, }, - um::{ - errhandlingapi::GetLastError, libloaderapi::GetModuleHandleExA, - processthreadsapi::GetCurrentThreadId, winuser::*, - }, + um::{libloaderapi::GetModuleHandleExA, processthreadsapi::GetCurrentThreadId, winuser::*}, }; const GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT: u32 = 2; @@ -43,8 +43,8 @@ fn do_hook(tx: Sender) -> ResultType<(HHOOK, HHOOK)> { &mut hm_keyboard as _, ) { tx.send(format!( - "Failed to GetModuleHandleExA, error: {}", - GetLastError() + "Failed to GetModuleHandleExA, error: {:?}", + Error::last_os_error() ))?; return Ok(invalid_ret); } @@ -55,8 +55,8 @@ fn do_hook(tx: Sender) -> ResultType<(HHOOK, HHOOK)> { &mut hm_mouse as _, ) { tx.send(format!( - "Failed to GetModuleHandleExA, error: {}", - GetLastError() + "Failed to GetModuleHandleExA, error: {:?}", + Error::last_os_error() ))?; return Ok(invalid_ret); } @@ -68,7 +68,10 @@ fn do_hook(tx: Sender) -> ResultType<(HHOOK, HHOOK)> { 0, ); 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); } @@ -76,9 +79,15 @@ fn do_hook(tx: Sender) -> ResultType<(HHOOK, HHOOK)> { if hook_mouse.is_null() { if FALSE == UnhookWindowsHookEx(hook_keyboard) { // 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); } @@ -131,12 +140,18 @@ pub fn hook() -> ResultType<()> { if FALSE == UnhookWindowsHookEx(hook_keyboard as _) { // Fatal error - log::error!("Failed UnhookWindowsHookEx keyboard {}", GetLastError()); + log::error!( + "Failed UnhookWindowsHookEx keyboard, error {:?}", + Error::last_os_error() + ); } if FALSE == UnhookWindowsHookEx(hook_mouse as _) { // 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; @@ -162,7 +177,10 @@ pub fn unhook() -> ResultType<()> { let cur_hook_thread_id = CUR_HOOK_THREAD_ID.lock().unwrap(); if *cur_hook_thread_id != 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() + ); } } } diff --git a/src/privacy_mode/win_topmost_window.rs b/src/privacy_mode/win_topmost_window.rs index 687f59155..0b54f9a71 100644 --- a/src/privacy_mode/win_topmost_window.rs +++ b/src/privacy_mode/win_topmost_window.rs @@ -3,6 +3,7 @@ use crate::{platform::windows::get_user_token, privacy_mode::PrivacyModeState}; use hbb_common::{allow_err, bail, log, ResultType}; use std::{ ffi::CString, + io::Error, time::{Duration, Instant}, }; use winapi::{ @@ -12,7 +13,6 @@ use winapi::{ windef::HWND, }, um::{ - errhandlingapi::GetLastError, handleapi::CloseHandle, libloaderapi::{GetModuleHandleA, GetProcAddress}, memoryapi::{VirtualAllocEx, WriteProcessMemory}, @@ -266,9 +266,9 @@ impl PrivacyModeImpl { CloseHandle(token); if 0 == create_res { bail!( - "Failed to create privacy window process {}, code {}", + "Failed to create privacy window process {}, error {:?}", cmdline, - GetLastError() + Error::last_os_error() ); }; @@ -284,8 +284,8 @@ impl PrivacyModeImpl { CloseHandle(proc_info.hProcess); bail!( - "Failed to create privacy window process, {}", - GetLastError() + "Failed to create privacy window process, error {:?}", + Error::last_os_error() ); } diff --git a/src/privacy_mode/win_virtual_display.rs b/src/privacy_mode/win_virtual_display.rs index 8183d3275..9b25b6361 100644 --- a/src/privacy_mode/win_virtual_display.rs +++ b/src/privacy_mode/win_virtual_display.rs @@ -1,7 +1,10 @@ use super::{PrivacyMode, PrivacyModeState, INVALID_PRIVACY_MODE_CONN_ID, NO_DISPLAYS}; use crate::virtual_display_manager; 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 winapi::{ shared::{ @@ -9,7 +12,6 @@ use winapi::{ ntdef::{NULL, WCHAR}, }, um::{ - errhandlingapi::GetLastError, wingdi::{ DEVMODEW, DISPLAY_DEVICEW, DISPLAY_DEVICE_ACTIVE, DISPLAY_DEVICE_ATTACHED_TO_DESKTOP, DISPLAY_DEVICE_MIRRORING_DRIVER, DISPLAY_DEVICE_PRIMARY_DEVICE, DM_POSITION, @@ -193,9 +195,9 @@ impl PrivacyModeImpl { ) { bail!( - "Failed EnumDisplaySettingsW, device name: {:?}, error code: {}", + "Failed EnumDisplaySettingsW, device name: {:?}, error: {:?}", 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) { bail!( - "Failed EnumDisplaySettingsW, device name: {:?}, error code: {}", + "Failed EnumDisplaySettingsW, device name: {:?}, error: {:?}", std::string::String::from_utf16(&dd.DeviceName), - GetLastError() + Error::last_os_error() ); } From c6d587f0c7019e5730af9517da84ff56ade01a3f Mon Sep 17 00:00:00 2001 From: fufesou Date: Mon, 20 Nov 2023 17:22:14 +0800 Subject: [PATCH 08/10] Refact, use std::io::Error::from_raw_os_error() to format message Signed-off-by: fufesou --- libs/scrap/src/dxgi/mag.rs | 30 ++++++++++++++++++++++++------ src/platform/windows.rs | 4 ++-- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/libs/scrap/src/dxgi/mag.rs b/libs/scrap/src/dxgi/mag.rs index 52404b3af..89ed44b9f 100644 --- a/libs/scrap/src/dxgi/mag.rs +++ b/libs/scrap/src/dxgi/mag.rs @@ -173,7 +173,10 @@ impl MagInterface { if FALSE == init_func() { return Err(Error::new( ErrorKind::Other, - format!("Failed to MagInitialize, error: {:?}", Error::last_os_error()), + format!( + "Failed to MagInitialize, error: {:?}", + Error::last_os_error() + ), )); } else { s.init_succeeded = true; @@ -315,7 +318,10 @@ impl CapturerMag { ) { return Err(Error::new( ErrorKind::Other, - format!("Failed to GetModuleHandleExA, error {:?}", Error::last_os_error()), + format!( + "Failed to GetModuleHandleExA, error {:?}", + Error::last_os_error() + ), )); } @@ -342,7 +348,10 @@ impl CapturerMag { if code != ERROR_CLASS_ALREADY_EXISTS { return Err(Error::new( ErrorKind::Other, - format!("Failed to RegisterClassExA, error: {}", code), + format!( + "Failed to RegisterClassExA, error {:?}", + Error::from_raw_os_error(code as _) + ), )); } } @@ -546,7 +555,10 @@ impl CapturerMag { if FALSE == set_window_source_func(self.magnifier_window, self.rect) { return Err(Error::new( ErrorKind::Other, - format!("Failed to MagSetWindowSource, error {:?}", Error::last_os_error()), + format!( + "Failed to MagSetWindowSource, error {:?}", + Error::last_os_error() + ), )); } } else { @@ -578,7 +590,10 @@ impl CapturerMag { unsafe { if FALSE == DestroyWindow(self.magnifier_window) { // - println!("Failed DestroyWindow magnifier window, error {:?}", Error::last_os_error()) + println!( + "Failed DestroyWindow magnifier window, error {:?}", + Error::last_os_error() + ) } } } @@ -588,7 +603,10 @@ impl CapturerMag { unsafe { if FALSE == DestroyWindow(self.host_window) { // - println!("Failed DestroyWindow host window, error {:?}", Error::last_os_error()) + println!( + "Failed DestroyWindow host window, error {:?}", + Error::last_os_error() + ) } } } diff --git a/src/platform/windows.rs b/src/platform/windows.rs index 34d85a6cd..c85c39d34 100644 --- a/src/platform/windows.rs +++ b/src/platform/windows.rs @@ -1738,11 +1738,11 @@ pub fn create_process_with_logon(user: &str, pwd: &str, exe: &str, arg: &str) -> { let last_error = GetLastError(); bail!( - "CreateProcessWithLogonW failed : \"{}\", errno={}", + "CreateProcessWithLogonW failed : \"{}\", error {:?}", last_error_table .get(&last_error) .unwrap_or(&"Unknown error"), - last_error + io::Error::from_raw_os_error(last_error as _) ); } } From 2aaca0c54a32decdf29fa9b50392ff1f6ffd1c9f Mon Sep 17 00:00:00 2001 From: fufesou Date: Mon, 20 Nov 2023 17:38:53 +0800 Subject: [PATCH 09/10] Remove get_error() in windows.rs Signed-off-by: fufesou --- libs/scrap/src/dxgi/mag.rs | 31 ++++++------ src/platform/windows.rs | 64 +++++-------------------- src/privacy_mode/win_input.rs | 16 +++---- src/privacy_mode/win_topmost_window.rs | 4 +- src/privacy_mode/win_virtual_display.rs | 4 +- 5 files changed, 39 insertions(+), 80 deletions(-) diff --git a/libs/scrap/src/dxgi/mag.rs b/libs/scrap/src/dxgi/mag.rs index 89ed44b9f..f759ecbeb 100644 --- a/libs/scrap/src/dxgi/mag.rs +++ b/libs/scrap/src/dxgi/mag.rs @@ -139,7 +139,7 @@ impl MagInterface { return Err(Error::new( ErrorKind::Other, format!( - "Failed to LoadLibraryExA {}, error: {:?}", + "Failed to LoadLibraryExA {}, error: {}", lib_file_name, Error::last_os_error() ), @@ -173,10 +173,7 @@ impl MagInterface { if FALSE == init_func() { return Err(Error::new( ErrorKind::Other, - format!( - "Failed to MagInitialize, error: {:?}", - Error::last_os_error() - ), + format!("Failed to MagInitialize, error: {}", Error::last_os_error()), )); } else { s.init_succeeded = true; @@ -198,7 +195,7 @@ impl MagInterface { return Err(Error::new( ErrorKind::Other, format!( - "Failed to GetProcAddress {}, error {:?}", + "Failed to GetProcAddress {}, error {}", func_name, Error::last_os_error() ), @@ -212,14 +209,14 @@ impl MagInterface { if let Some(uninit_func) = self.mag_uninitialize_func { unsafe { if FALSE == uninit_func() { - println!("Failed MagUninitialize, error {:?}", Error::last_os_error()) + println!("Failed MagUninitialize, error {}", Error::last_os_error()) } } } if !self.lib_handle.is_null() { unsafe { if FALSE == FreeLibrary(self.lib_handle) { - println!("Failed FreeLibrary, error {:?}", Error::last_os_error()) + println!("Failed FreeLibrary, error {}", Error::last_os_error()) } } self.lib_handle = NULL as _; @@ -319,7 +316,7 @@ impl CapturerMag { return Err(Error::new( ErrorKind::Other, format!( - "Failed to GetModuleHandleExA, error {:?}", + "Failed to GetModuleHandleExA, error {}", Error::last_os_error() ), )); @@ -375,7 +372,7 @@ impl CapturerMag { return Err(Error::new( ErrorKind::Other, format!( - "Failed to CreateWindowExA host_window, error {:?}", + "Failed to CreateWindowExA host_window, error {}", Error::last_os_error() ), )); @@ -400,7 +397,7 @@ impl CapturerMag { return Err(Error::new( ErrorKind::Other, format!( - "Failed CreateWindowA magnifier_window, error {:?}", + "Failed CreateWindowA magnifier_window, error {}", Error::last_os_error() ), )); @@ -420,7 +417,7 @@ impl CapturerMag { return Err(Error::new( ErrorKind::Other, format!( - "Failed to MagSetImageScalingCallback, error {:?}", + "Failed to MagSetImageScalingCallback, error {}", Error::last_os_error() ), )); @@ -464,7 +461,7 @@ impl CapturerMag { return Err(Error::new( ErrorKind::Other, format!( - "Failed MagSetWindowFilterList for cls {} name {}, error {:?}", + "Failed MagSetWindowFilterList for cls {} name {}, error {}", cls, name, Error::last_os_error() @@ -539,7 +536,7 @@ impl CapturerMag { return Err(Error::new( ErrorKind::Other, format!( - "Failed SetWindowPos (x, y, w , h) - ({}, {}, {}, {}), error {:?}", + "Failed SetWindowPos (x, y, w , h) - ({}, {}, {}, {}), error {}", self.rect.left, self.rect.top, self.rect.right - self.rect.left, @@ -556,7 +553,7 @@ impl CapturerMag { return Err(Error::new( ErrorKind::Other, format!( - "Failed to MagSetWindowSource, error {:?}", + "Failed to MagSetWindowSource, error {}", Error::last_os_error() ), )); @@ -591,7 +588,7 @@ impl CapturerMag { if FALSE == DestroyWindow(self.magnifier_window) { // println!( - "Failed DestroyWindow magnifier window, error {:?}", + "Failed DestroyWindow magnifier window, error {}", Error::last_os_error() ) } @@ -604,7 +601,7 @@ impl CapturerMag { if FALSE == DestroyWindow(self.host_window) { // println!( - "Failed DestroyWindow host window, error {:?}", + "Failed DestroyWindow host window, error {}", Error::last_os_error() ) } diff --git a/src/platform/windows.rs b/src/platform/windows.rs index c85c39d34..f005d3720 100644 --- a/src/platform/windows.rs +++ b/src/platform/windows.rs @@ -319,7 +319,7 @@ fn get_rich_cursor_data( let dc = DC::new()?; 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 { - bail!("Failed to get di bits: {}", get_error()); + bail!("Failed to get di bits: {}", io::Error::last_os_error()); } } Ok(()) @@ -603,7 +603,7 @@ async fn launch_server(session_id: DWORD, close_first: bool) -> ResultType) -> ResultType> { "Failed to launch {:?} with session id {}: {}", arg, session_id, - get_error() + io::Error::last_os_error() ); } Ok(None) @@ -676,7 +676,7 @@ pub fn try_change_desktop() -> bool { if !res { let mut s = SUPPRESS.lock().unwrap(); 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(); } } else { @@ -688,41 +688,6 @@ pub fn try_change_desktop() -> bool { return false; } -fn get_error() -> String { - unsafe { - let buff_size = 256; - let mut buff: Vec = 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 { if get_reg("share_rdp") != "true" { FALSE @@ -1285,7 +1250,7 @@ pub fn block_input(v: bool) -> (bool, String) { if BlockInput(v) == TRUE { (true, "".to_owned()) } else { - (false, format!("Error: {:?}", io::Error::last_os_error())) + (false, format!("Error: {}", io::Error::last_os_error())) } } } @@ -1560,7 +1525,7 @@ pub fn elevate_or_run_as_system(is_setup: bool, is_elevate: bool, is_run_as_syst std::process::exit(0); } else { log::error!( - "Failed to run as system, error {:?}", + "Failed to run as system, error {}", io::Error::last_os_error() ); } @@ -1570,16 +1535,13 @@ pub fn elevate_or_run_as_system(is_setup: bool, is_elevate: bool, is_run_as_syst if let Ok(true) = elevate(arg_elevate) { std::process::exit(0); } else { - log::error!( - "Failed to elevate, error {:?}", - io::Error::last_os_error() - ); + log::error!("Failed to elevate, error {}", io::Error::last_os_error()); } } } } Err(_) => log::error!( - "Failed to get elevation status, error {:?}", + "Failed to get elevation status, error {}", io::Error::last_os_error() ), } @@ -1595,7 +1557,7 @@ pub fn is_elevated(process_id: Option) -> ResultType { }; if handle == NULL { bail!( - "Failed to open process, error {:?}", + "Failed to open process, error {}", io::Error::last_os_error() ) } @@ -1603,7 +1565,7 @@ pub fn is_elevated(process_id: Option) -> ResultType { let mut token: HANDLE = mem::zeroed(); if OpenProcessToken(handle, TOKEN_QUERY, &mut token) == FALSE { bail!( - "Failed to open process token, error {:?}", + "Failed to open process token, error {}", io::Error::last_os_error() ) } @@ -1619,7 +1581,7 @@ pub fn is_elevated(process_id: Option) -> ResultType { ) == FALSE { bail!( - "Failed to get token information, error {:?}", + "Failed to get token information, error {}", io::Error::last_os_error() ) } @@ -1801,7 +1763,7 @@ pub fn current_resolution(name: &str) -> ResultType { dm.dmSize = std::mem::size_of::() as _; if EnumDisplaySettingsW(device_name.as_ptr(), ENUM_CURRENT_SETTINGS, &mut dm) == 0 { bail!( - "failed to get currrent resolution, error {:?}", + "failed to get currrent resolution, error {}", io::Error::last_os_error() ); } @@ -1835,7 +1797,7 @@ pub(super) fn change_resolution_directly( ); if res != DISP_CHANGE_SUCCESSFUL { bail!( - "ChangeDisplaySettingsExW failed, res={}, error {:?}", + "ChangeDisplaySettingsExW failed, res={}, error {}", res, io::Error::last_os_error() ); diff --git a/src/privacy_mode/win_input.rs b/src/privacy_mode/win_input.rs index df6ee0143..29c87dc18 100644 --- a/src/privacy_mode/win_input.rs +++ b/src/privacy_mode/win_input.rs @@ -43,7 +43,7 @@ fn do_hook(tx: Sender) -> ResultType<(HHOOK, HHOOK)> { &mut hm_keyboard as _, ) { tx.send(format!( - "Failed to GetModuleHandleExA, error: {:?}", + "Failed to GetModuleHandleExA, error: {}", Error::last_os_error() ))?; return Ok(invalid_ret); @@ -55,7 +55,7 @@ fn do_hook(tx: Sender) -> ResultType<(HHOOK, HHOOK)> { &mut hm_mouse as _, ) { tx.send(format!( - "Failed to GetModuleHandleExA, error: {:?}", + "Failed to GetModuleHandleExA, error: {}", Error::last_os_error() ))?; return Ok(invalid_ret); @@ -69,7 +69,7 @@ fn do_hook(tx: Sender) -> ResultType<(HHOOK, HHOOK)> { ); if hook_keyboard.is_null() { tx.send(format!( - " SetWindowsHookExA keyboard, error {:?}", + " SetWindowsHookExA keyboard, error {}", Error::last_os_error() ))?; return Ok(invalid_ret); @@ -80,12 +80,12 @@ fn do_hook(tx: Sender) -> ResultType<(HHOOK, HHOOK)> { if FALSE == UnhookWindowsHookEx(hook_keyboard) { // Fatal error log::error!( - " UnhookWindowsHookEx keyboard, error {:?}", + " UnhookWindowsHookEx keyboard, error {}", Error::last_os_error() ); } tx.send(format!( - " SetWindowsHookExA mouse, error {:?}", + " SetWindowsHookExA mouse, error {}", Error::last_os_error() ))?; return Ok(invalid_ret); @@ -141,7 +141,7 @@ pub fn hook() -> ResultType<()> { if FALSE == UnhookWindowsHookEx(hook_keyboard as _) { // Fatal error log::error!( - "Failed UnhookWindowsHookEx keyboard, error {:?}", + "Failed UnhookWindowsHookEx keyboard, error {}", Error::last_os_error() ); } @@ -149,7 +149,7 @@ pub fn hook() -> ResultType<()> { if FALSE == UnhookWindowsHookEx(hook_mouse as _) { // Fatal error log::error!( - "Failed UnhookWindowsHookEx mouse, error {:?}", + "Failed UnhookWindowsHookEx mouse, error {}", Error::last_os_error() ); } @@ -178,7 +178,7 @@ pub fn unhook() -> ResultType<()> { if *cur_hook_thread_id != 0 { if FALSE == PostThreadMessageA(*cur_hook_thread_id, WM_USER_EXIT_HOOK, 0, 0) { bail!( - "Failed to post message to exit hook, error {:?}", + "Failed to post message to exit hook, error {}", Error::last_os_error() ); } diff --git a/src/privacy_mode/win_topmost_window.rs b/src/privacy_mode/win_topmost_window.rs index 0b54f9a71..7fd27b60b 100644 --- a/src/privacy_mode/win_topmost_window.rs +++ b/src/privacy_mode/win_topmost_window.rs @@ -266,7 +266,7 @@ impl PrivacyModeImpl { CloseHandle(token); if 0 == create_res { bail!( - "Failed to create privacy window process {}, error {:?}", + "Failed to create privacy window process {}, error {}", cmdline, Error::last_os_error() ); @@ -284,7 +284,7 @@ impl PrivacyModeImpl { CloseHandle(proc_info.hProcess); bail!( - "Failed to create privacy window process, error {:?}", + "Failed to create privacy window process, error {}", Error::last_os_error() ); } diff --git a/src/privacy_mode/win_virtual_display.rs b/src/privacy_mode/win_virtual_display.rs index 9b25b6361..372479b5d 100644 --- a/src/privacy_mode/win_virtual_display.rs +++ b/src/privacy_mode/win_virtual_display.rs @@ -195,7 +195,7 @@ impl PrivacyModeImpl { ) { bail!( - "Failed EnumDisplaySettingsW, device name: {:?}, error: {:?}", + "Failed EnumDisplaySettingsW, device name: {:?}, error: {}", std::string::String::from_utf16(&display.name), Error::last_os_error() ); @@ -229,7 +229,7 @@ impl PrivacyModeImpl { == EnumDisplaySettingsW(dd.DeviceName.as_ptr(), ENUM_CURRENT_SETTINGS, &mut dm) { bail!( - "Failed EnumDisplaySettingsW, device name: {:?}, error: {:?}", + "Failed EnumDisplaySettingsW, device name: {:?}, error: {}", std::string::String::from_utf16(&dd.DeviceName), Error::last_os_error() ); From 3e8c5d3b79ac545014dac40f5549bbbe6aa389f5 Mon Sep 17 00:00:00 2001 From: fufesou Date: Mon, 20 Nov 2023 17:42:34 +0800 Subject: [PATCH 10/10] trivial changes Signed-off-by: fufesou --- libs/scrap/src/dxgi/mag.rs | 6 +++--- src/platform/windows.rs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libs/scrap/src/dxgi/mag.rs b/libs/scrap/src/dxgi/mag.rs index f759ecbeb..923606a82 100644 --- a/libs/scrap/src/dxgi/mag.rs +++ b/libs/scrap/src/dxgi/mag.rs @@ -139,7 +139,7 @@ impl MagInterface { return Err(Error::new( ErrorKind::Other, format!( - "Failed to LoadLibraryExA {}, error: {}", + "Failed to LoadLibraryExA {}, error {}", lib_file_name, Error::last_os_error() ), @@ -173,7 +173,7 @@ impl MagInterface { if FALSE == init_func() { return Err(Error::new( ErrorKind::Other, - format!("Failed to MagInitialize, error: {}", Error::last_os_error()), + format!("Failed to MagInitialize, error {}", Error::last_os_error()), )); } else { s.init_succeeded = true; @@ -346,7 +346,7 @@ impl CapturerMag { return Err(Error::new( ErrorKind::Other, format!( - "Failed to RegisterClassExA, error {:?}", + "Failed to RegisterClassExA, error {}", Error::from_raw_os_error(code as _) ), )); diff --git a/src/platform/windows.rs b/src/platform/windows.rs index f005d3720..3a726c2a1 100644 --- a/src/platform/windows.rs +++ b/src/platform/windows.rs @@ -1700,7 +1700,7 @@ pub fn create_process_with_logon(user: &str, pwd: &str, exe: &str, arg: &str) -> { let last_error = GetLastError(); bail!( - "CreateProcessWithLogonW failed : \"{}\", error {:?}", + "CreateProcessWithLogonW failed : \"{}\", error {}", last_error_table .get(&last_error) .unwrap_or(&"Unknown error"),