////////////////////////////////////////////////////////////////
// Code excerpt from who.cpp showing how the object discovers
// the Base COM caller, and the COM+/MTS caller SIDs and maps
// them to names.
//
// Download project at: http://www.develop.com/securitybriefs
//
void _getErrMsg(wchar_t* psz, const wchar_t* pszFcn,
DWORD hr = GetLastError())
{
wchar_t sz[256];
if (!FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, 0, hr, 0,
sz, sizeof sz / sizeof *sz, 0))
lstrcpyW(sz, L"???");
wsprintfW( psz, L"%s failed: %s", pszFcn, sz);
}
HRESULT _err(BSTR* pval, const wchar_t* pszFcn,
DWORD hr = GetLastError())
{
wchar_t szMsg[512];
_getErrMsg(szMsg, pszFcn, hr);
*pval = SysAllocString(szMsg);
return S_OK;
}
void _lookupAccount(void* psid, wchar_t* psz)
{
wchar_t szName[256];
DWORD cchName = sizeof szName / sizeof *szName;
wchar_t szDom[256];
DWORD cchDom = sizeof szDom / sizeof *szDom;
SID_NAME_USE snu;
if (LookupAccountSidW(0, psid, szName,
&cchName, szDom,
&cchDom, &snu))
wsprintfW(psz, L"%s\\%s", szDom, szName);
else _getErrMsg(psz, L"LookupAccountSid");
}
STDMETHODIMP CWho::WhoIsCaller(BSTR *pval)
{
// see who COM thinks the caller is
wchar_t* pszCOMCaller;
HRESULT hr = CoQueryClientBlanket(0, 0, 0, 0, 0,
(void**)&pszCOMCaller, 0);
if (FAILED(hr))
return _err(pval, L"CoQueryClientBlanket", hr);
IObjectContext* poc;
hr = GetObjectContext(&poc);
if (FAILED(hr))
return _err(pval, L"GetObjectContext", hr);
ISecurityProperty* psp;
poc->QueryInterface(&psp);
poc->Release();
poc = 0;
// see who COM+/MTS thinks the caller is
void* psid;
hr = psp->GetDirectCallerSID(&psid);
if (FAILED(hr))
return _err(pval, L"GetDirectCallerSID", hr);
wchar_t szMTSDirectCaller[256];
_lookupAccount(psid, szMTSDirectCaller);
psp->ReleaseSID(psid);
// who started this chain of calls into COM+/MTS
hr = psp->GetOriginalCallerSID(&psid);
if (FAILED(hr))
return _err(pval, L"GetOriginalCallerSID", hr);
wchar_t szMTSOriginalCaller[256];
_lookupAccount(psid, szMTSOriginalCaller);
psp->ReleaseSID(psid);
psp->Release();
psp = 0;
// send back a pretty table showing results
const wchar_t* const pszFmt =
L"<table cellpadding=3 border=1>\r\n"
L"<tr><td>Base COM Caller</td><td>%s</td></tr>\r\n"
L"<tr><td>COM+/MTS Direct Caller</td><td>%s</td></tr>\r\n"
L"<tr><td>COM+/MTS Original Caller</td><td>%s</td></tr>\r\n"
L"</table>\n";
wchar_t sz[512];
wsprintfW(sz, pszFmt, pszCOMCaller,
szMTSDirectCaller,
szMTSOriginalCaller);
*pval = SysAllocString(sz);
return S_OK;
}