From 5448041616a0ac6b4069c1abaac88f8cc5cf111c Mon Sep 17 00:00:00 2001 From: Vinseti Date: Tue, 8 Aug 2023 16:50:06 +0530 Subject: [PATCH] Aggregation --- SampleInterfaces/TestIPCFactoryBuffer.cpp | 13 +- SampleInterfaces/TestProxyBuffer.cpp | 274 +++++++++++++++++----- SampleInterfaces/TestProxyBuffer.h | 72 ++++-- 3 files changed, 276 insertions(+), 83 deletions(-) diff --git a/SampleInterfaces/TestIPCFactoryBuffer.cpp b/SampleInterfaces/TestIPCFactoryBuffer.cpp index 99c815b..4af69e6 100644 --- a/SampleInterfaces/TestIPCFactoryBuffer.cpp +++ b/SampleInterfaces/TestIPCFactoryBuffer.cpp @@ -40,20 +40,25 @@ HRESULT __stdcall ComputerIPSFactoryBuffer::CreateProxy( void** ppv //We must give this a value. the actual interface specified by IID returned to the client ) { + IUnknown* mainObject = NULL; + + HRESULT hr; if (riid == IID_IMOUSE) - *ppProxy = new MouseProxyBuffer(pUnkOuter); + hr = MouseProxyBufferNonDelegate::Create(pUnkOuter, IID_IUnknown, (void**)&mainObject); else if (riid == IID_IKEYBOARD) - *ppProxy = new KeyboardProxyBuffer(pUnkOuter); + hr = KeyboardProxyBufferNonDelegate::Create(pUnkOuter, IID_IUnknown, (void**)&mainObject); else { *ppv = NULL; *ppProxy = NULL; return E_NOINTERFACE; } + if (FAILED(hr)) + return E_UNEXPECTED; - ((IUnknown*)*ppProxy)->QueryInterface(riid, (void**)ppv); + ((IUnknown*)mainObject)->QueryInterface(riid, (void**)ppv); - return ((IUnknown*)*ppProxy)->QueryInterface(IID_IRpcProxyBuffer, (void**)ppProxy); + return ((IUnknown*)mainObject)->QueryInterface(IID_IRpcProxyBuffer, (void**)ppProxy); } //Server side diff --git a/SampleInterfaces/TestProxyBuffer.cpp b/SampleInterfaces/TestProxyBuffer.cpp index 1986025..a82f0ad 100644 --- a/SampleInterfaces/TestProxyBuffer.cpp +++ b/SampleInterfaces/TestProxyBuffer.cpp @@ -1,33 +1,54 @@ #include "TestProxyBuffer.h" -MouseProxyBuffer::MouseProxyBuffer(IUnknown* proxy):refCount(0),proxyBuffer(NULL),proxyManager(NULL) +MouseProxyBufferNonDelegate::MouseProxyBufferNonDelegate(IUnknown* ptr_outer):refCount(0) { - proxyManager = proxy; - proxyManager->AddRef(); + outerObject = ptr_outer; + innerObject.outerObject = ptr_outer; } -HRESULT __stdcall MouseProxyBuffer::QueryInterface(REFIID riid, void** ppvObject) + +HRESULT MouseProxyBufferNonDelegate::Create(IUnknown* outer, REFIID riid, void** ppvObject) { - if (riid == IID_IRpcProxyBuffer) + if (outer != NULL && riid != IID_IUnknown) + return CLASS_E_NOAGGREGATION; + + MouseProxyBufferNonDelegate* mainObject = new MouseProxyBufferNonDelegate(outer); + if(mainObject == NULL) + return E_OUTOFMEMORY; + + if (mainObject->outerObject == NULL) { - *ppvObject = (IRpcProxyBuffer*)this; - ((IUnknown*)*ppvObject)->AddRef(); - return S_OK; + mainObject->outerObject = mainObject; + mainObject->innerObject.outerObject = mainObject; } + + HRESULT hr = mainObject->QueryInterface(riid, (void**)ppvObject); + if (FAILED(hr)) + delete mainObject; + return hr; +} +HRESULT __stdcall MouseProxyBufferNonDelegate::QueryInterface(REFIID riid, void** ppvObject) +{ + if (riid == IID_IUnknown) + *ppvObject = (IUnknown*)this; else if (riid == IID_IMOUSE) + *ppvObject = (IMouse*)&innerObject; + else if (riid == IID_IRpcProxyBuffer) + *ppvObject = (IRpcProxyBuffer*)this; + else { - *ppvObject = (IMouse*)this; - ((IUnknown*)*ppvObject)->AddRef(); - return S_OK; + *ppvObject = NULL; + return E_NOINTERFACE; } - else - return proxyManager->QueryInterface(riid, ppvObject); + + ((IUnknown*)*ppvObject)->AddRef(); + return S_OK; } -ULONG __stdcall MouseProxyBuffer::AddRef(void) +ULONG __stdcall MouseProxyBufferNonDelegate::AddRef(void) { refCount++; return refCount; } -ULONG __stdcall MouseProxyBuffer::Release(void) +ULONG __stdcall MouseProxyBufferNonDelegate::Release(void) { refCount--; if (refCount > 0) @@ -36,25 +57,41 @@ ULONG __stdcall MouseProxyBuffer::Release(void) delete this; return 0; } -HRESULT __stdcall MouseProxyBuffer::Connect(IRpcChannelBuffer* pRpcChannelBuffer) +HRESULT __stdcall MouseProxyBufferNonDelegate::MouseProxyBufferDelegate::QueryInterface(REFIID riid, void** ppvObject) { return outerObject->QueryInterface(riid, ppvObject); } +ULONG __stdcall MouseProxyBufferNonDelegate::MouseProxyBufferDelegate::AddRef(void) { return outerObject->AddRef(); } +ULONG __stdcall MouseProxyBufferNonDelegate::MouseProxyBufferDelegate::Release(void) { return outerObject->Release(); } +HRESULT __stdcall MouseProxyBufferNonDelegate::Connect(IRpcChannelBuffer* pRpcChannelBuffer) { - proxyBuffer = pRpcChannelBuffer; - proxyBuffer->AddRef(); + innerObject.proxyBuffer = pRpcChannelBuffer; + innerObject.proxyBuffer->AddRef(); return S_OK; } -void __stdcall MouseProxyBuffer::Disconnect(void) +void __stdcall MouseProxyBufferNonDelegate::Disconnect(void) { - proxyBuffer->Release(); - proxyBuffer = NULL; + innerObject.proxyBuffer->Release(); + innerObject.proxyBuffer = NULL; } -HRESULT MouseProxyBuffer::click(int button) +HRESULT MouseProxyBufferNonDelegate::MouseProxyBufferDelegate::click(int button) { RPCOLEMESSAGE message = {}; ZeroMemory(&message, sizeof(RPCOLEMESSAGE)); message.cbBuffer = sizeof(int); HRESULT hr = proxyBuffer->GetBuffer(&message, IID_IMOUSE); - if (FAILED(hr)) { + if (FAILED(hr)) + { + std::string errorMsg; + switch (hr) + { + case E_INVALIDARG:errorMsg = "Invalid Arguments"; + break; + case E_OUTOFMEMORY:errorMsg = "No Memory"; + break; + case E_UNEXPECTED:errorMsg = "Catostrophic Failure"; + break; + case E_FAIL:errorMsg = "Fail"; + } + std::cout << errorMsg << std::endl; return E_UNEXPECTED; } @@ -63,21 +100,47 @@ HRESULT MouseProxyBuffer::click(int button) ULONG status = 0; hr = proxyBuffer->SendReceive(&message, &status); - if (SUCCEEDED(hr)){ - std::cout << std::string((char*)message.Buffer); + if (SUCCEEDED(hr)){std::cout << std::string((char*)message.Buffer);} + else + { + std::string errorMsg; + switch (hr) + { + case E_INVALIDARG:errorMsg = "Invalid Arguments"; + break; + case E_OUTOFMEMORY:errorMsg = "No Memory"; + break; + case E_UNEXPECTED:errorMsg = "Catostrophic Failure"; + break; + case E_FAIL:errorMsg = "Fail"; + } + std::cout << errorMsg << std::endl; } proxyBuffer->FreeBuffer(&message); return S_OK; } -HRESULT MouseProxyBuffer::scroll(int amount) +HRESULT MouseProxyBufferNonDelegate::MouseProxyBufferDelegate::scroll(int amount) { RPCOLEMESSAGE message = {}; ZeroMemory(&message, sizeof(RPCOLEMESSAGE)); message.cbBuffer = sizeof(int); HRESULT hr = proxyBuffer->GetBuffer(&message, IID_IMOUSE); - if (FAILED(hr)) { + if (FAILED(hr)) + { + std::string errorMsg; + switch (hr) + { + case E_INVALIDARG:errorMsg = "Invalid Arguments"; + break; + case E_OUTOFMEMORY:errorMsg = "No Memory"; + break; + case E_UNEXPECTED:errorMsg = "Catostrophic Failure"; + break; + case E_FAIL:errorMsg = "Fail"; + } + std::cout << errorMsg << std::endl; return E_UNEXPECTED; } @@ -86,41 +149,59 @@ HRESULT MouseProxyBuffer::scroll(int amount) ULONG status = 0; hr = proxyBuffer->SendReceive(&message, &status); - if (SUCCEEDED(hr)) { - std::cout << std::string((char*)message.Buffer); + if (SUCCEEDED(hr)) {std::cout << std::string((char*)message.Buffer);} + else + { + std::string errorMsg; + switch (hr) + { + case E_INVALIDARG:errorMsg = "Invalid Arguments"; + break; + case E_OUTOFMEMORY:errorMsg = "No Memory"; + break; + case E_UNEXPECTED:errorMsg = "Catostrophic Failure"; + break; + case E_FAIL:errorMsg = "Fail"; + } + std::cout << errorMsg << std::endl; } proxyBuffer->FreeBuffer(&message); return S_OK; } -KeyboardProxyBuffer::KeyboardProxyBuffer(IUnknown* proxy):refCount(0),proxyBuffer(NULL),proxyManager(NULL) + + + + +KeyboardProxyBufferNonDelegate::KeyboardProxyBufferNonDelegate(IUnknown* ptr_outer):refCount(0) { - proxyManager = proxy; + outerObject = ptr_outer; + innerObject.outerObject = outerObject; } -HRESULT __stdcall KeyboardProxyBuffer::QueryInterface(REFIID riid, void** ppvObject) +HRESULT __stdcall KeyboardProxyBufferNonDelegate::QueryInterface(REFIID riid, void** ppvObject) { - if (riid == IID_IRpcProxyBuffer) - { - *ppvObject = (IRpcProxyBuffer*)this; - ((IUnknown*)*ppvObject)->AddRef(); - return S_OK; - } + if (riid == IID_IUnknown) + *ppvObject = (IUnknown*)this; else if (riid == IID_IKEYBOARD) + *ppvObject = (IKeyboard*)&innerObject; + else if (riid == IID_IRpcProxyBuffer) + *ppvObject = (IRpcProxyBuffer*)this; + else { - *ppvObject = (IKeyboard*)this; - ((IUnknown*)*ppvObject)->AddRef(); - return S_OK; + *ppvObject = NULL; + return E_NOINTERFACE; } - else - return proxyManager->QueryInterface(riid, ppvObject); + + ((IUnknown*)*ppvObject)->AddRef(); + return S_OK; } -ULONG __stdcall KeyboardProxyBuffer::AddRef(void) +ULONG __stdcall KeyboardProxyBufferNonDelegate::AddRef(void) { refCount++; return refCount; } -ULONG __stdcall KeyboardProxyBuffer::Release(void) +ULONG __stdcall KeyboardProxyBufferNonDelegate::Release(void) { refCount--; if (refCount > 0) @@ -129,25 +210,61 @@ ULONG __stdcall KeyboardProxyBuffer::Release(void) delete this; return 0; } -HRESULT __stdcall KeyboardProxyBuffer::Connect(IRpcChannelBuffer* pRpcChannelBuffer) +HRESULT KeyboardProxyBufferNonDelegate::Create(IUnknown* outer, REFIID riid, void** ppvObject) { - proxyBuffer = pRpcChannelBuffer; - proxyBuffer->AddRef(); + if (outer != NULL && riid != IID_IUnknown) + return CLASS_E_NOAGGREGATION; + + KeyboardProxyBufferNonDelegate* mainObject = new KeyboardProxyBufferNonDelegate(outer); + if (mainObject == NULL) + return E_OUTOFMEMORY; + + if (mainObject->outerObject == NULL) + { + mainObject->outerObject = mainObject; + mainObject->innerObject.outerObject = mainObject; + } + + HRESULT hr = mainObject->QueryInterface(riid, (void**)ppvObject); + if (FAILED(hr)) + delete mainObject; + return hr; +} +HRESULT __stdcall KeyboardProxyBufferNonDelegate::KeyboardProxyBufferDelegate::QueryInterface(REFIID riid, void** ppvObject) { return outerObject->QueryInterface(riid, ppvObject); } +ULONG __stdcall KeyboardProxyBufferNonDelegate::KeyboardProxyBufferDelegate::AddRef(void) { return outerObject->AddRef(); } +ULONG __stdcall KeyboardProxyBufferNonDelegate::KeyboardProxyBufferDelegate::Release(void) { return outerObject->Release(); } +HRESULT __stdcall KeyboardProxyBufferNonDelegate::Connect(IRpcChannelBuffer* pRpcChannelBuffer) +{ + innerObject.proxyBuffer = pRpcChannelBuffer; + innerObject.proxyBuffer->AddRef(); return S_OK; } -void __stdcall KeyboardProxyBuffer::Disconnect(void) +void __stdcall KeyboardProxyBufferNonDelegate::Disconnect(void) { - proxyBuffer->Release(); - proxyBuffer = NULL; + innerObject.proxyBuffer->Release(); + innerObject.proxyBuffer = NULL; } -HRESULT KeyboardProxyBuffer::pressKey(int key) +HRESULT KeyboardProxyBufferNonDelegate::KeyboardProxyBufferDelegate::pressKey(int key) { RPCOLEMESSAGE message = {}; ZeroMemory(&message, sizeof(RPCOLEMESSAGE)); message.cbBuffer = sizeof(int); HRESULT hr = proxyBuffer->GetBuffer(&message, IID_IKEYBOARD); - if (FAILED(hr)) { + if (FAILED(hr)) + { + std::string errorMsg; + switch (hr) + { + case E_INVALIDARG:errorMsg = "Invalid Arguments"; + break; + case E_OUTOFMEMORY:errorMsg = "No Memory"; + break; + case E_UNEXPECTED:errorMsg = "Catostrophic Failure"; + break; + case E_FAIL:errorMsg = "Fail"; + } + std::cout << errorMsg << std::endl; return E_UNEXPECTED; } @@ -156,21 +273,47 @@ HRESULT KeyboardProxyBuffer::pressKey(int key) ULONG status = 0; hr = proxyBuffer->SendReceive(&message, &status); - if (SUCCEEDED(hr)) { - std::cout << std::string((char*)message.Buffer); + if (SUCCEEDED(hr)) {std::cout << std::string((char*)message.Buffer);} + else + { + std::string errorMsg; + switch (hr) + { + case E_INVALIDARG:errorMsg = "Invalid Arguments"; + break; + case E_OUTOFMEMORY:errorMsg = "No Memory"; + break; + case E_UNEXPECTED:errorMsg = "Catostrophic Failure"; + break; + case E_FAIL:errorMsg = "Fail"; + } + std::cout << errorMsg << std::endl; } proxyBuffer->FreeBuffer(&message); return S_OK; } -HRESULT KeyboardProxyBuffer::releaseKey(int key) +HRESULT KeyboardProxyBufferNonDelegate::KeyboardProxyBufferDelegate::releaseKey(int key) { RPCOLEMESSAGE message = {}; ZeroMemory(&message, sizeof(RPCOLEMESSAGE)); message.cbBuffer = sizeof(int); HRESULT hr = proxyBuffer->GetBuffer(&message, IID_IKEYBOARD); - if (FAILED(hr)) { + if (FAILED(hr)) + { + std::string errorMsg; + switch (hr) + { + case E_INVALIDARG:errorMsg = "Invalid Arguments"; + break; + case E_OUTOFMEMORY:errorMsg = "No Memory"; + break; + case E_UNEXPECTED:errorMsg = "Catostrophic Failure"; + break; + case E_FAIL:errorMsg = "Fail"; + } + std::cout << errorMsg << std::endl; return E_UNEXPECTED; } @@ -179,8 +322,21 @@ HRESULT KeyboardProxyBuffer::releaseKey(int key) ULONG status = 0; hr = proxyBuffer->SendReceive(&message, &status); - if (SUCCEEDED(hr)) { - std::cout << std::string((char*)message.Buffer); + if (SUCCEEDED(hr)) {std::cout << std::string((char*)message.Buffer);} + else + { + std::string errorMsg; + switch (hr) + { + case E_INVALIDARG:errorMsg = "Invalid Arguments"; + break; + case E_OUTOFMEMORY:errorMsg = "No Memory"; + break; + case E_UNEXPECTED:errorMsg = "Catostrophic Failure"; + break; + case E_FAIL:errorMsg = "Fail"; + } + std::cout << errorMsg << std::endl; } proxyBuffer->FreeBuffer(&message); diff --git a/SampleInterfaces/TestProxyBuffer.h b/SampleInterfaces/TestProxyBuffer.h index 029de26..9f96494 100644 --- a/SampleInterfaces/TestProxyBuffer.h +++ b/SampleInterfaces/TestProxyBuffer.h @@ -3,14 +3,34 @@ #include "TestInterfaces.h" #include -class MouseProxyBuffer : public IRpcProxyBuffer, public IMouse +class MouseProxyBufferNonDelegate : public IRpcProxyBuffer { ULONG refCount; - IRpcChannelBuffer* proxyBuffer; - IUnknown* proxyManager; + IUnknown* outerObject; + + MouseProxyBufferNonDelegate(IUnknown*); + +private: + class MouseProxyBufferDelegate : public IMouse + { + friend class MouseProxyBufferNonDelegate; + IRpcChannelBuffer* proxyBuffer; + IUnknown* outerObject; + + public: + // Inherited via IUnknown + virtual HRESULT __stdcall QueryInterface(REFIID riid, void** ppvObject) override; + virtual ULONG __stdcall AddRef(void) override; + virtual ULONG __stdcall Release(void) override; + + // Inherited via IMouse + virtual HRESULT click(int button) override; + virtual HRESULT scroll(int amount) override; + }; + MouseProxyBufferDelegate innerObject; public: - MouseProxyBuffer(IUnknown*); + static HRESULT Create(IUnknown*, REFIID, void**); // Inherited via IUnknown virtual HRESULT __stdcall QueryInterface(REFIID riid, void** ppvObject) override; @@ -20,32 +40,44 @@ class MouseProxyBuffer : public IRpcProxyBuffer, public IMouse // Inherited via IRpcProxyBuffer virtual HRESULT __stdcall Connect(IRpcChannelBuffer* pRpcChannelBuffer) override; virtual void __stdcall Disconnect(void) override; - - // Inherited via IMouse - virtual HRESULT click(int button) override; - virtual HRESULT scroll(int amount) override; }; -class KeyboardProxyBuffer : public IRpcProxyBuffer, public IKeyboard + +class KeyboardProxyBufferNonDelegate : public IRpcProxyBuffer { ULONG refCount; - IRpcChannelBuffer* proxyBuffer; - IUnknown* proxyManager; + IUnknown* outerObject; -public: - KeyboardProxyBuffer(IUnknown*); + KeyboardProxyBufferNonDelegate(IUnknown*); - // Inherited via IUnknown - virtual HRESULT __stdcall QueryInterface(REFIID riid, void** ppvObject) override; - virtual ULONG __stdcall AddRef(void) override; - virtual ULONG __stdcall Release(void) override; + class KeyboardProxyBufferDelegate : public IKeyboard + { + friend class KeyboardProxyBufferNonDelegate; + IRpcChannelBuffer* proxyBuffer; + IUnknown* outerObject; + + public: + // Inherited via IUnknown + virtual HRESULT __stdcall QueryInterface(REFIID riid, void** ppvObject) override; + virtual ULONG __stdcall AddRef(void) override; + virtual ULONG __stdcall Release(void) override; + + // Inherited via IKeyboard + virtual HRESULT pressKey(int key) override; + virtual HRESULT releaseKey(int key) override; + }; + KeyboardProxyBufferDelegate innerObject; + +public: + static HRESULT Create(IUnknown*, REFIID, void**); // Inherited via IRpcProxyBuffer virtual HRESULT __stdcall Connect(IRpcChannelBuffer* pRpcChannelBuffer) override; virtual void __stdcall Disconnect(void) override; - // Inherited via IKeyboard - virtual HRESULT pressKey(int key) override; - virtual HRESULT releaseKey(int key) override; + // Inherited via IUnknown + virtual HRESULT __stdcall QueryInterface(REFIID riid, void** ppvObject) override; + virtual ULONG __stdcall AddRef(void) override; + virtual ULONG __stdcall Release(void) override; };