MSTSCLib :: MsRdpClient неверное поведение

Я пытаюсь использовать MsRdpClient для подключения к серверу rdp и получения некоторых основных уведомлений. Теперь у меня та же проблема, что и у людей около 8 лет, я не нашел ответа, поэтому я снова поднимаю эту тему. У меня есть такой код, собранный из различных примеров использования rdp с winapi:

#include <Windows.h>
#include <CommCtrl.h>
#include <tchar.h>
#include "resource.h"#include <atlbase.h>
#include <exdisp.h>

#include "mstscax.tlh"#include "mstscax.tli"using namespace MSTSCLib;class CTscEventSink : public IMsTscAxEvents
{
public:
CTscEventSink()
{
_ulRefs = 1;
m_dwEvtCookie = 0;
}
~CTscEventSink()
{
}
BOOL Attach(IMsTscAx* pTscAx)
{
CComPtr<IConnectionPointContainer> cpCPCont;
HRESULT hr;
hr = pTscAx->QueryInterface(IID_IConnectionPointContainer, (LPVOID *)&cpCPCont);
if (FAILED(hr))
return FALSE;
hr = cpCPCont->FindConnectionPoint(__uuidof(IMsTscAxEvents), &m_cpConnect);
if (FAILED(hr))
{
return FALSE;
}
hr = m_cpConnect->Advise(this, &m_dwEvtCookie);
if (FAILED(hr))
{
m_dwEvtCookie = 0;
return FALSE;
}
return TRUE;
}
void Detach()
{
if ((m_dwEvtCookie) && (m_cpConnect))
m_cpConnect->Unadvise(m_dwEvtCookie);
if (m_cpConnect)
m_cpConnect = NULL;
}
//IUnknown Methods
STDMETHOD(QueryInterface) (REFIID riid, LPVOID * ppv)
{
if (riid == __uuidof(IMsTscAxEvents))
{
*ppv = (IMsTscAxEvents *)this;
}
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
AddRef();
return S_OK;
}
STDMETHOD_(ULONG, AddRef) (void)
{
InterlockedIncrement((LONG*)&_ulRefs);
return _ulRefs;
}
STDMETHOD_(ULONG, Release) (void)
{
ULONG ulRefs = _ulRefs;
if (InterlockedDecrement((LONG*)&_ulRefs) == 0)
{
delete this;
return 0;
}
return _ulRefs;
}
HRESULT OnConnecting()
{
DebugBreak();
::MessageBoxA(NULL, "Connecting", "", 0);
}
HRESULT OnConnected()
{
DebugBreak();
::MessageBoxA(NULL, "Connected", "", 0);
}
HRESULT OnFatalError()
{
DebugBreak();
::MessageBoxA(NULL, "Fatal Error", "", 0);
}
HRESULT OnLoginComplete()
{
DebugBreak();
::MessageBoxA(NULL, "Login complete", "", 0);
}
HRESULT OnLogonError(
long lError)
{
DebugBreak();
::MessageBoxA(NULL, "OnLogonError", "", 0);
}
HRESULT OnDisconnected(
long discReason)
{
DebugBreak();
::MessageBoxA(NULL, "OnDisconnected", "", 0);
}
//IDispatch Methods
STDMETHOD(GetTypeInfoCount)(UINT FAR* pctinfo)
{
return E_NOTIMPL;
}
STDMETHOD(GetTypeInfo)(UINT itinfo, LCID lcid, ITypeInfo FAR* FAR* pptinfo)
{
return E_NOTIMPL;
}
STDMETHOD(GetIDsOfNames)(REFIID riid, OLECHAR FAR* FAR* rgszNames, UINT cNames,
LCID lcid, DISPID FAR* rgdispid)
{
return E_NOTIMPL;
}
STDMETHOD(Invoke)(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags,
DISPPARAMS FAR* pdispparams, VARIANT FAR* pvarResult,
EXCEPINFO FAR* pexcepinfo, UINT FAR* puArgErr)
{

return S_OK;
}
protected:
ULONG _ulRefs;
DWORD m_dwEvtCookie;
CComPtr<IConnectionPoint> m_cpConnect;
};CTscEventSink * pCTscEventSink;
MSTSCLib::IMsRdpClient2* pInterface = NULL;LRESULT CALLBACK WindowProc(HWND hWnd, UINT messg, WPARAM wParam, LPARAM lParam)
{
switch (messg)
{
case WM_SIZE:

break;
case WM_CLOSE:

DestroyWindow(hWnd);
break;
case WM_DESTROY:

PostQuitMessage(0);
break;
default:

return(DefWindowProc(hWnd, messg, wParam, lParam));
}
return 0;
}

int CALLBACK wWinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPWSTR lpCmdLine,
int nCmdShow)
{

WNDCLASS wndclass;
wndclass.style = CS_VREDRAW | CS_HREDRAW;
wndclass.lpfnWndProc = &WindowProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = NULL;
wndclass.hCursor = NULL;
wndclass.hbrBackground = reinterpret_cast <HBRUSH> (COLOR_BTNFACE + 1);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = L"RdpTest1";
::RegisterClass(&wndclass);

HWND mainWindow = ::CreateWindow(
L"RdpTest1",
L"Rdp!",
0,
CW_USEDEFAULT,
CW_USEDEFAULT,
800,
800,
NULL,
NULL,
hInstance,
0);
::ShowWindow(mainWindow, nCmdShow);
::UpdateWindow(mainWindow);

//ocx

typedef HRESULT(WINAPI *PFonc)(IUnknown*, HWND, IUnknown**);
HINSTANCE hDLL2 = ::LoadLibrary(TEXT("atl.dll"));
if (!hDLL2)
return 1;

PFonc AtlAxAttachControl = (PFonc) ::GetProcAddress(hDLL2, "AtlAxAttachControl");

HRESULT hr = ::CoInitialize(0);

HRESULT hrInit = CoInitialize(NULL);
if (FAILED(hrInit)) return 0;
CLSID clsid = __uuidof(MSTSCLib::MsRdpClient2);
IID iid = __uuidof(MSTSCLib::IMsRdpClient2);
HRESULT hrInterface = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, iid, (void**)&pInterface);
if (SUCCEEDED(hrInterface))
{

pCTscEventSink = new CTscEventSink();

BOOL b = pCTscEventSink->Attach(pInterface);
pInterface->PutServer(L"non_existing_server.lol");
pInterface->PutFullScreen(VARIANT_TRUE);
pInterface->PutDesktopWidth(GetSystemMetrics(SM_CXSCREEN));
pInterface->PutDesktopHeight(GetSystemMetrics(SM_CYSCREEN));
pInterface->PutUserName(L"some_incorrect_user");
pInterface->AdvancedSettings2->PutClearTextPassword(L"some_incorrect_pass");

pInterface->AdvancedSettings2->PutRDPPort(3389);

IMsRdpExtendedSettings *pExtendedSetting = NULL;
IID interface_MsRdpClient8NotSafeForScripting = __uuidof(MSTSCLib::MsRdpClient2NotSafeForScripting);
HRESULT hr = pInterface->QueryInterface(interface_MsRdpClient8NotSafeForScripting, (void**)&pExtendedSetting);
if (hr == S_OK)
{
VARIANT index;
VariantInit(&index);
V_VT(&index) = VT_BOOL;
index.boolVal = VARIANT_TRUE;
pExtendedSetting->put_Property((BSTR)L"DisableCredentialsDelegation", &index);
}
hr = AtlAxAttachControl(pInterface, mainWindow, 0);
if (FAILED(hr)) {
MessageBox(0, L"FAILED(AtlAxAttachControl(pitd, container, NULL))", L"Error", MB_ICONERROR | MB_OK);
}
HRESULT hrConnect = pInterface->Connect();
if (FAILED(hrConnect))
{
MessageBoxW(NULL, L"pInterface->Connect()", L"Error", 0);
}
else MessageBoxW(NULL, L"pInterface->Connect() Success!!!", L"Success", 0);
}
else
{
wchar_t buf[16] = { 0 };
_ltow(hrInterface, buf, 16);
MessageBoxW(NULL, buf, L"CoCreateInstance failed", 0);
}

::MSG message;
while (::GetMessageA(&message, 0, 0, 0)) {
switch (message.message) {
case WM_QUIT:
break;
default:
::TranslateMessage(&message);
::DispatchMessage(&message);
break;
}
}
CoUninitialize();
FreeLibrary(hDLL2);
return 0;
}

Итак, что я делаю в этом коде. Я создаю окно, создаю MSTSCLib::IMsRdpClient2* pInterface объект, прикрепить класс приемника событий, чтобы перехватывать события, к этому объекту, и я передаю ему неверные данные Но никакие события не запускаются, OnFatalError, OnConnecting и т. Д. Никогда не вызывались, и HRESULT hrConnect = pInterface->Connect(); всегда возвращается S_OKнезависимо от того, что сервер / пользователь / пароль. Из того, что я понял, это поведение связано с Invoke реализация в CTscEventSink Мне нужно сделать что-то внутри здесь:

STDMETHOD(Invoke)(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags,
DISPPARAMS FAR* pdispparams, VARIANT FAR* pvarResult,
EXCEPINFO FAR* pexcepinfo, UINT FAR* puArgErr)
{

return S_OK;
}

Скорее просто возвращаясь S_OKМне нужно что-то сделать, чтобы на самом деле передать команду подключения дальше. Может кто-нибудь помочь, что мне здесь делать ?? Как то, что позвонить из Invoke ?? Это загадка, и я не знаю примеров, и ни одна страница MSDN не говорит об этом.

0

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]