Environment
Harbour 3.2.0dev (r2006301601), BCC 7.3, FiveWin 17.05, Excel automation (out-of-process server), Windows Server with Terminal Services.
Symptom
Sometimes the value returned by a function or method that has just worked with OLE reaches the caller as a 2-element array {0, NNNNNNN} (second element is a large number, looks like a pointer) instead of the real value. It happens rarely and at random, and the same code usually works. Example:
A workaround that avoids it: don't return the value with RETURN. The function stores it in a by-reference parameter and returns NIL.
Analysis
Harbour already protects this case in other places: hb_objDestructorCall() and hb_oleDispatchToItem() use hb_vmRequestReenter() / hb_vmRequestRestore(), and olecore.c has the comment "pItem actually can be stack's return item!". The GC destructors in olecore.c call Release() without that protection.
I could not check whether FiveWin's window procedure saves the return item (its C source is not public). But since Release() can dispatch messages to any GUI library, it seems safer to protect it in olecore.c.
Proposed patch (contrib/hbwin/olecore.c)
The same change goes in hb_oleenum_destructor() (around pEnum->Release()) and hb_olevariant_destructor() (around VariantClear()).
Status
The analysis is based on reading the Harbour sources (estack.c, garbage.c, itemapi.c, classes.c, olecore.c) and the Microsoft COM/DCOM documentation. The patch has not been tested in production yet. I will report the results.