Основан, на маршалинге указателя на интерфейс в стрим и считывании значений по определённым смещениям структуры ObjRef. Получаем Host, User, ProcessID. Можно что то ещё, но пока не вижу необходимости.
Тестировал на w2k sp4.
Код:
HRESULT GetPtrIdentity(
IUnknown* pUnk,
BSTR* pUser,
BSTR* pHost,
DWORD* pProcessID)
{
if (pUnk == 0)
return E_POINTER;
//
// CoGetMarshalSizeMax sould be used here but I'm really lazy ;)
//
HRESULT hr;
CComPtr<IStream> pStream;
HGLOBAL hMem = GlobalAlloc(GMEM_FIXED, 65535);
if (FAILED(hr = CreateStreamOnHGlobal(
hMem,
TRUE,
&pStream)))
return hr;
if (FAILED(hr = CoMarshalInterface(
pStream,
IID_IUnknown,
pUnk,
MSHCTX_DIFFERENTMACHINE,
0,
MSHLFLAGS_NORMAL)))
return hr;
//
// Read the characrers count
//
LARGE_INTEGER Pos;
Pos.QuadPart = 0x42;
if (FAILED(hr = pStream->Seek(Pos, STREAM_SEEK_SET, 0)))
return hr;
WORD charsCount = 0;
if (FAILED(hr = pStream->Read(&charsCount, sizeof(charsCount), 0)))
return hr;
if (charsCount == 0)
return E_UNEXPECTED;
//
// Read the characters
//
if ((pUser) || (pHost))
{
Pos.QuadPart = 0x46;
if (FAILED(hr = pStream->Seek(Pos, STREAM_SEEK_SET, 0)))
return hr;
int buffSize = charsCount * sizeof(wchar_t);
wchar_t* hostInfo = new wchar_t[buffSize];
if (FAILED(hr = pStream->Read(hostInfo, buffSize, 0)))
return hr;
if (pUser)
CComBSTR(hostInfo).CopyTo(pUser);
if (pHost)
CComBSTR(hostInfo + wcslen(hostInfo) + 2).CopyTo(pHost);
delete [] hostInfo;
}
//
// Read the process ID
//
if(pProcessID)
{
long l;
Pos.QuadPart = 0x32;
if (FAILED(hr = pStream->Seek(Pos, STREAM_SEEK_SET, 0)))
return hr;
if (FAILED(hr = pStream->Read(&l, 4, 0)))
return hr;
__asm ROR l, 16;
*pProcessID = l;
}
//
// Release marshal data
//
Pos.QuadPart = 0;
if (FAILED(hr = pStream->Seek(Pos, STREAM_SEEK_SET, 0)))
return hr;
if (FAILED(hr = CoReleaseMarshalData(pStream)))
return hr;
return S_OK;
}
Пример:
int _tmain(int argc, _TCHAR* argv[])
{
CoInitialize(0);
{
COSERVERINFO csInfo = {0};
COAUTHINFO caInfo = {0};
COAUTHIDENTITY caId = {0};
csInfo.pwszName = L"RemoteHostName";
csInfo.pAuthInfo = &caInfo;
caInfo.dwAuthnLevel = RPC_C_AUTHN_LEVEL_CONNECT;
caInfo.dwAuthnSvc = RPC_C_AUTHN_WINNT;
caInfo.dwAuthzSvc = RPC_C_AUTHZ_NONE;
caInfo.dwCapabilities = EOAC_NONE;
caInfo.dwImpersonationLevel = RPC_C_IMP_LEVEL_IMPERSONATE;
caInfo.pAuthIdentityData = &caId;
caId.User = L"UserName";
caId.UserLength = wcslen(caId.User);
caId.Password = L"UserPassword";
caId.PasswordLength = wcslen(caId.Password);
caId.Domain = L"DomainName";
caId.DomainLength = wcslen(caId.Domain);
caId.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
MULTI_QI mqi = {0};
mqi.pIID = &IID_IUnknown;
HRESULT hr;
hr = CoCreateInstanceEx(
CLSID_InternetExplorer,
0,
CLSCTX_REMOTE_SERVER,
&csInfo,
1,
&mqi);
if ((hr == S_OK) && (mqi.hr == S_OK))
{
CComBSTR User;
CComBSTR Host;
DWORD dwProcessID = 0;
hr = GetPtrIdentity(mqi.pItf, &User, &Host, &dwProcessID);
}
}
CoUninitialize();
return 0;
}