I believe that FACILITY_ITF can be used for your own interface.
Normally, you should be able distinguish your errors from other errors, with the Interface ID (IID).
from https://learn.microsoft.com/en-us/windows/desktop/com/structure-of-com-error-codes:
FACILITY_ITF
4
For most status codes returned from interface methods. The actual meaning of the error is defined by the interface. That is, two HRESULTs with exactly the same 32-bit value returned from two different interfaces might have different meanings.
See also this:
https://learn.microsoft.com/en-us/windows/desktop/com/codes-in-facility-itf
(link already provided in the question, which suggests you really can use FACILITY_ITF for your own interface).
May there's a simpler way, but here is a simple example:
#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \
const type name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}}
// {7D51F88F-76BD-4970-BEC1-E090C032A7F5}
MIDL_DEFINE_GUID(IID, IID_MyInterface,
0x7d51f88f, 0x76bd, 0x4970, 0xbe, 0xc1, 0xe0, 0x90, 0xc0, 0x32, 0xa7, 0xf5);
// {614EBF64-44FF-4615-90DE-09D05AF7F09B}
MIDL_DEFINE_GUID(IID, IID_ISomeoneElseInterface,
0x614ebf64, 0x44ff, 0x4615, 0x90, 0xde, 0x9, 0xd0, 0x5a, 0xf7, 0xf0, 0x9b);
void TestITFFacility();
IErrorInfoPtr CreateErrorInfo(LPCTSTR desc, const CLSID& clsid, LPCWSTR source, DWORD helpContext);
int _main(int argc, TCHAR* argv[], TCHAR* envp[])
{
TestITFFacility();
return 0;
}
void TestITFFacility()
{
IID tab[2] = { IID_MyInterface, IID_ISomeoneElseInterface };
for (int i=0; i<sizeof(tab)/sizeof(IID); i++)
{
try
{
// artificially throw a _com_error.
// note: 0x0200: see https://learn.microsoft.com/en-us/windows/desktop/com/codes-in-facility-itf
// it is recommended that only code values in the range of 0x0200-0xFFFF be used
throw _com_error(MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, (0x7D + 0x0200)),
CreateErrorInfo(_T("something went wrong"),
tab[i],
L"Some Source",
0));
}
catch(_com_error e)
{
auto hr = e.Error();
if (InlineIsEqualGUID(e.GUID(), IID_MyInterface))
_tprintf(_T("My Interface, hr=%08lX, code=%04X\n"), hr, e.WCode());
else
_tprintf(_T("Someone else Interface, hr=%08lX, code=%04X\n"), hr, e.WCode());
}
}
}
// method to create an IErrorInfo
IErrorInfoPtr CreateErrorInfo(LPCTSTR desc, const CLSID& clsid, LPCWSTR source, DWORD helpContext)
{
ICreateErrorInfoPtr pcerrinfo;
IErrorInfoPtr perrinfo;
HRESULT hr = CreateErrorInfo(&pcerrinfo);
assert(SUCCEEDED(hr));
if (S_OK == hr)
{
_bstr_t olestr = _bstr_t(desc);
pcerrinfo->SetDescription(olestr);
pcerrinfo->SetGUID(clsid);
pcerrinfo->SetHelpContext(helpContext);
pcerrinfo->SetSource((LPOLESTR)source);
hr = pcerrinfo->QueryInterface(IID_IErrorInfo, (LPVOID FAR*) &perrinfo);
assert(SUCCEEDED(hr));
}
return perrinfo;
}