Forum Stats

  • 3,770,104 Users
  • 2,253,066 Discussions
  • 7,875,315 Comments

Discussions

Unhandled exception in Oracle Smart View

User_U4MW0
User_U4MW0 Member Posts: 1 Red Ribbon
edited Nov 22, 2021 6:56PM in Essbase On-Premise

Dear Oracle,

we found a problem with Oracle Smart View that is frequent, and we believe should be addressed.

HSADDIN.DLL calls Excel::Window::PointsToScreenPixelsX inside a WM_TIMER callback, and this call fails fairly often with VBA_E_IGNORE. The HRESULT is wrapped into an _com_error exception by the COM call wrapper, but not handled and falls through into the Windows WM_TIMER dispatch mechanism. There, it usually gets caught by a catch-all __try __except block, and thus does not become visible.

But Excel contains code that disables this catch-all by calling the Win32 API function SetUserObjectInformationW(…, UOI_TIMERPROC_EXCEPTION_SUPPRESSION, …), which is actually recommended as described here:

https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-settimer#remarks

We do not know under which circumstances Excel disables UOI_TIMERPROC_EXCEPTION_SUPPRESSION, but our telemetry indicates that the _com_error exception described above falls through the WM_TIMER dispatch quite frequently and then gets accidentally caught by us. It is fairly certain that all this is not intended by Oracle, and you simply forgot to handle VBA_E_IGNORE in your add-in.

Regards,

Arno

CTO think-cell Software

 

P.S.:

 

Here is some pseudo-code that replicates roughly what HSADDIN.DLL is doing:

 

struct SOracleSmartViewSimulator {

      HHOOK m_hhookCallWndProc;

      bool m_bExcelIsBusy;

} g_oraclesmartviewsim;

 

      g_oraclesmartviewsim.m_hhookCallWndProc = APIERR( SetWindowsHookEx(

             WH_CALLWNDPROC,

             (HOOKPROC)[](int nCode, WPARAM wParam, LPARAM lParam) noexcept -> LRESULT {

                     if( HC_ACTION == nCode ) {

                            CWPSTRUCT const* cwpstruct = reinterpret_cast<CWPSTRUCT const*>(lParam);

                            if( WM_SETFOCUS == cwpstruct->message || WM_KILLFOCUS == cwpstruct->message ) {

                                   tc::ui::win::CWindowClass wndclass(cwpstruct->hwnd);

                                   if( wndclass.Is(_T("EXCEL6")) || wndclass.Is(_T("EXCEL<")) ) {

                                         g_oraclesmartviewsim.m_bExcelIsBusy = WM_SETFOCUS == cwpstruct->message;

                                         APIERR( SetTimer(nullptr, /*Oracle uses 1?*/0, 0, [](HWND hWnd, UINT uElapse, UINT_PTR nIDEvent, DWORD dwReserved) {

                                                if( !g_oraclesmartviewsim.m_bExcelIsBusy ) {

                                                       if( auto_cref(activeWindow, NOEXCEPT(XlApplication()->m_iApplication->GetActiveWindow())) ) {

                                                               activeWindow->PointsToScreenPixelsX(530); // throws VBA_E_IGNORE

                                                         }

                                                 }

                                                APIERR( KillTimer( nullptr, nIDEvent ) );

                                                 // SmartView kills timer here

                                          }) );

                                   }

                            }

                     }

                     return CallNextHookEx(g_oraclesmartviewsim.m_hhookCallWndProc, nCode, wParam, lParam);

             },

             /*hmod*/nullptr,

             VERIFYEQUAL(g_threadidMain, tc::this_thread::get_id())

      ) );

 

Tagged:

Answers