|About memory leaks. VB allocation\dellocation mechanisms are the same with COM.
p->vt = VT_BSTR | VT_BYREF;
BSTR *pBSTR = new BSTR;
*pBSTR = SysAllocString( L"abc" );
p->pbstrVal = pBSTR;
There are 2 memory allocations in statements "= new BSTR" and "= SysAllocString".
The VARIANT with VT_BYREF|VT_BSTR isn't an owner of its values, so freeing of the VARIANT doesn't free neither pbstrVal nor *pbstrVal. And finally you have memory leaks.
The VARIANT with VT_BSTR (without VT_BYREF) is an owner of its values, so freeing of the VARIANT frees bstrVal.
p->vt = VT_BSTR;
p->bstrVal = SysAllocString( L"abc" );
And there are no memory leaks.
With best wishes,