-
Notifications
You must be signed in to change notification settings - Fork 19
Expand file tree
/
Copy pathIDynamicWrapperEx.cpp
More file actions
166 lines (149 loc) · 5.65 KB
/
Copy pathIDynamicWrapperEx.cpp
File metadata and controls
166 lines (149 loc) · 5.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
/**
* @file IDynamicWrapperEx.cpp
* @date 01-10-2020
* @author Paul Laine (@am0nsec)
* @version 1.0
* @brief DynamicWrapperEx Automation definition.
* @details
* @link https://github.com/am0nsec/DynamicWrapperEx
* @copyright This project has been released under the GNU Public License v3 license.
*/
#include <windows.h>
#include <unknwn.h>
#include <memory>
#include "IDynamicWrapperEx.hpp"
#include "AutomationFactory.hpp"
#include "Util.hpp"
/**
* @brief Constructor.
*/
IDynamicWrapperEx::IDynamicWrapperEx() {
this->m_pAutomationFactory->m_aDispatchTable.push_back({ 0, L"DwRegister"});
this->m_pAutomationFactory->m_aDispatchTable.push_back({ 1, L"WriteByte" });
this->m_pAutomationFactory->m_dwInternalMethods = this->m_pAutomationFactory->m_aDispatchTable.size();
}
/**
* @brief Destructor.
*/
IDynamicWrapperEx::~IDynamicWrapperEx() { }
/**
*@brief Queries a COM object for a pointer to one of its interface.
* @param riid A reference to the interface identifier(IID) of the interface being queried for.
* @param ppvObject The address of a pointer to an interface with the IID specified in the riid parameter.
* @return Whether an interface has been found.
*/
HRESULT STDMETHODCALLTYPE IDynamicWrapperEx::QueryInterface(
_In_ REFIID riid,
_Out_ LPVOID* ppvObject
) {
if (IsEqualGUID(riid, IID_IDynamicWrapperEx) || IsEqualGUID(riid, IID_IDispatch) || IsEqualGUID(riid, IID_IUnknown)) {
*ppvObject = this;
this->AddRef();
return S_OK;
}
*ppvObject = NULL;
return E_NOINTERFACE;
}
/**
* @brief Increment the number of references.
* @return Number of remaining references.
*/
ULONG STDMETHODCALLTYPE IDynamicWrapperEx::AddRef(VOID) {
return InterlockedIncrement(&this->m_dwReference);
}
/**
* @brief Decrement the number of references.
* @return Number of remaining references.
*/
ULONG STDMETHODCALLTYPE IDynamicWrapperEx::Release(VOID) {
ULONG ulReference = InterlockedDecrement(&this->m_dwReference);
return ulReference;
}
/**
* @brief Retrieves the number of type information interfaces that an object provides (either 0 or 1).
* @param pctinfo The number of type information interfaces provided by the object.
* @return Method not implemented.
*/
HRESULT STDMETHODCALLTYPE IDynamicWrapperEx::GetTypeInfoCount(
_Out_ UINT* pctinfo
) {
*pctinfo = 1;
return E_NOTIMPL;
}
/**
* @brief Retrieves the type information for an object, which can then be used to get the type information for an interface.
* @param iTInfo The type information to return. Pass 0 to retrieve type information for the IDispatch implementation.
* @param lcid The locale identifier for the type information.
* @param ppTInfo The requested type information object.
* @return Whether the function executed successfully.
*/
HRESULT STDMETHODCALLTYPE IDynamicWrapperEx::GetTypeInfo(
_In_ UINT iTInfo,
_In_ LCID lcid,
_Out_ ITypeInfo** ppTInfo
) {
*ppTInfo = NULL;
return E_NOTIMPL;
}
/**
* @brief Maps a single member and an optional set of argument names to a corresponding set of integer DISPIDs, which can be used on subsequent calls to Invoke.
* @param riid Reserved for future use. Must be IID_NULL.
* @param rgszNames The array of names to be mapped.
* @param cNames The count of the names to be mapped.
* @param lcid The locale context in which to interpret the names.
* @param rgDispId Caller-allocated array, each element of which contains an identifier (ID) corresponding to one of the names passed in the rgszNames array.
* @return Whether the function executed successfully.
*/
HRESULT STDMETHODCALLTYPE IDynamicWrapperEx::GetIDsOfNames(
_In_ REFIID riid,
_In_ LPOLESTR* rgszNames,
_In_ UINT cNames,
_In_ LCID lcid,
_Out_ DISPID* rgDispId
) {
if (riid != IID_NULL)
return DISP_E_UNKNOWNINTERFACE;
for (auto& elem : this->m_pAutomationFactory->m_aDispatchTable) {
if (::wcscmp(elem.wszName, *rgszNames) == 0) {
*rgDispId = elem.lDispId;
return S_OK;
}
}
*rgDispId = 0;
return E_FAIL;
}
/**
* @brief Provides access to properties and methods exposed by an object.
* @param dispIdMember Identifies the member.
* @param riid Reserved for future use. Must be IID_NULL.
* @param lcid The locale context in which to interpret arguments.
* @param wFlags Flags describing the context of the Invoke call.
* @param pDispParams Pointer to a DISPPARAMS structure containing an array of arguments, an array of argument DISPIDs for named arguments, and counts for the number of elements in the arrays.
* @param pVarResult Pointer to the location where the result is to be stored, or NULL if the caller expects no result.
* @param pExcepInfo Pointer to a structure that contains exception information.
* @param puArgErr The index within rgvarg of the first argument that has an error.
* @return Whether the function executed successfully.
*/
HRESULT STDMETHODCALLTYPE IDynamicWrapperEx::Invoke(
_In_ DISPID dispIdMember,
_In_ REFIID riid,
_In_ LCID lcid,
_In_ WORD wFlags,
_In_ DISPPARAMS* pDispParams,
_Out_ VARIANT* pVarResult,
_Out_ EXCEPINFO* pExcepInfo,
_Out_ UINT* puArgErr
) {
if (riid != IID_NULL)
return DISP_E_UNKNOWNINTERFACE;
if ((wFlags & DISPATCH_METHOD) != DISPATCH_METHOD)
return E_FAIL;
// Non-dynamic methods
if (dispIdMember == 0)
return this->m_pAutomationFactory->Register(pDispParams, pVarResult);
else if (dispIdMember == 1)
return Util::WriteByte(pDispParams, pVarResult);
// Execute dynamic method
HRESULT hr = this->m_pAutomationFactory->m_aDynamicMethods[dispIdMember - this->m_pAutomationFactory->m_dwInternalMethods]->Invoke(pDispParams, pVarResult);
return hr;
}