1. #define INC_OLE2
2. #define STRICT
3. #include <stdio.h>
4. #include <windows.h>
5. #include <initguid.h>
6.
7. DEFINE_GUID(CLSID_SimpleObject, 0x5e9ddec7, 0x5767, 0x11cf, 0xbe, 0xab, 0x0, 0xaa, 0x0, 0x6c, 0x36, 0x6);
8.
9. HANDLE hevtDone;
10.
11. class CClassFactory : public IClassFactory {
12. public:
13. STDMETHODIMP QueryInterface (REFIID riid, void** ppv);
14. STDMETHODIMP_(ULONG) AddRef(void) { return 1; };
15. STDMETHODIMP_(ULONG) Release(void) { return 1; }
16.
17. STDMETHODIMP CreateInstance (LPUNKNOWN punkOuter, REFIID iid, void **ppv);
18. STDMETHODIMP LockServer (BOOL fLock) { return E_FAIL; };
19. };
20.
21. class CSimpleObject : public IStream {
22. public:
23. STDMETHODIMP QueryInterface (REFIID iid, void **ppv);
24. STDMETHODIMP_(ULONG) AddRef(void) { return InterlockedIncrement(&m_cRef); };
25. STDMETHODIMP_(ULONG) Release(void) { if (InterlockedDecrement(&m_cRef) == 0) { delete this; return 0; } return 1; }
26.
27. STDMETHODIMP Read(void *pv, ULONG cb, ULONG *pcbRead);
28. STDMETHODIMP Write(VOID const *pv, ULONG cb, ULONG *pcbWritten);
29. STDMETHODIMP Seek(LARGE_INTEGER dbMove, DWORD dwOrigin, ULARGE_INTEGER *pbNewPosition)
30. { return E_FAIL; }
31. STDMETHODIMP SetSize(ULARGE_INTEGER cbNewSize)
32. { return E_FAIL; }
33. STDMETHODIMP CopyTo(IStream *pstm, ULARGE_INTEGER cb, ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten)
34. { return E_FAIL; }
35. STDMETHODIMP Commit(DWORD grfCommitFlags)
36. { return E_FAIL; }
37. STDMETHODIMP Revert(void)
38. { return E_FAIL; }
39. STDMETHODIMP LockRegion(ULARGE_INTEGER bOffset, ULARGE_INTEGER cb, DWORD dwLockType)
40. { return E_FAIL; }
41. STDMETHODIMP UnlockRegion(ULARGE_INTEGER bOffset, ULARGE_INTEGER cb, DWORD dwLockType)
42. { return E_FAIL; }
43. STDMETHODIMP Stat(STATSTG *pstatstg, DWORD grfStatFlag)
44. { return E_FAIL; }
45. STDMETHODIMP Clone(IStream **ppstm)
46. { return E_FAIL; }
47.
48. CSimpleObject() { m_cRef = 1; }
49. ~CSimpleObject() { SetEvent(hevtDone); }
50.
51. private:
52. LONG m_cRef;
53. };
54.
55. CClassFactory g_ClassFactory;
56.
57. void
58. Message(LPTSTR szPrefix, HRESULT hr)
59. {
60. LPTSTR szMessage;
61.
62. if (hr == S_OK)
63. {
64. wprintf(szPrefix);
65. wprintf(TEXT("\n"));
66. return;
67. }
68.
69. if (HRESULT_FACILITY(hr) == FACILITY_WINDOWS)
70. hr = HRESULT_CODE(hr);
71.
72. FormatMessage(
73. FORMAT_MESSAGE_ALLOCATE_BUFFER |
74. FORMAT_MESSAGE_FROM_SYSTEM |
75. FORMAT_MESSAGE_IGNORE_INSERTS,
76. NULL,
77. hr,
78. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), //The user default language
79. (LPTSTR)&szMessage,
80. 0,
81. NULL );
82.
83. wprintf(TEXT("%s: %s(%lx)\n"), szPrefix, szMessage, hr);
84.
85. LocalFree(szMessage);
86. } // Message
87.
88. STDMETHODIMP
89. CSimpleObject::QueryInterface(REFIID riid, void** ppv)
90. {
91. if (ppv == NULL)
92. return E_INVALIDARG;
93. if (riid == IID_IUnknown || riid == IID_IStream)
94. {
95. *ppv = (IUnknown *) this;
96. AddRef();
97. return S_OK;
98. }
99. *ppv = NULL;
100. return E_NOINTERFACE;
101. } // CSimpleObject::QueryInterface
102.
103. STDMETHODIMP
104. CSimpleObject::Read(void *pv, ULONG cb, ULONG *pcbRead)
105. {
106. Message(TEXT("Server: IStream:Read"), S_OK);
107. if (!pv && cb != 0)
108. return E_INVALIDARG;
109.
110. // 对于读取操作,只是简单地把数组的内容设置为0xFF
111. if (cb != 0)
112. memset(pv, 0xFF, cb);
113.
114. if (pcbRead)
115. *pcbRead = cb;
116. return S_OK;
117. } // CSimpleObject::Read
118.
119. STDMETHODIMP
120. CSimpleObject::Write(VOID const *pv, ULONG cb, ULONG *pcbWritten)
121. {
122. Message(TEXT("Server: IStream:Write"), S_OK);
123. if (!pv && cb != 0)
124. return E_INVALIDARG;
125.
126. // 不执行任何写操作,只是简单地更新pcbWritten,
127. // 这样客户端就会误认为写操作已经成功。
128. if (pcbWritten)
129. *pcbWritten = cb;
130. return S_OK;
131. } // CSimpleObject::Write
132.
133. STDMETHODIMP
134. CClassFactory::QueryInterface(REFIID riid, void** ppv)
135. {
136. if (ppv == NULL)
137. return E_INVALIDARG;
138. if (riid == IID_IClassFactory || riid == IID_IUnknown)
139. {
140. *ppv = (IClassFactory *) this;
141. AddRef();
142. return S_OK;
143. }
144. *ppv = NULL;
145. return E_NOINTERFACE;
146. } // CClassFactory::QueryInterface
147.
148. STDMETHODIMP
149. CClassFactory::CreateInstance(LPUNKNOWN punkOuter, REFIID riid, void** ppv)
150. {
151. LPUNKNOWN punk;
152. HRESULT hr;
153.
154. *ppv = NULL;
155.
156. if (punkOuter != NULL)
157. return CLASS_E_NOAGGREGATION;
158.
159. Message(TEXT("Server: IClassFactory:CreateInstance"), S_OK);
160.
161. punk = new CSimpleObject;
162.
163. if (punk == NULL)
164. return E_OUTOFMEMORY;
165.
166. hr = punk->QueryInterface(riid, ppv);
167. punk->Release();
168. return hr;
169. } // CClassFactory::CreateInstance
170.
171. void __cdecl
172. main()
173. {
174. HRESULT hr;
175. DWORD dwRegister;
176.
177. // 创建一个Windows事件,等待客户端来创建
178. // CSimpleObject对象,模拟一个一直在线的DCOM服务器
179. hevtDone = CreateEvent(NULL, FALSE, FALSE, NULL);
180. if (hevtDone == NULL)
181. {
182. hr = HRESULT_FROM_WIN32(GetLastError());
183. Message(TEXT("Server: CreateEvent"), hr);
184. exit(hr);
185. }
186.
187. hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
188. if (FAILED(hr))
189. {
190. Message(TEXT("Server: CoInitializeEx"), hr);
191. exit(hr);
192. }
193.
194. // 注册类厂
195. hr = CoRegisterClassObject(CLSID_SimpleObject, &g_ClassFactory,
196. CLSCTX_SERVER, REGCLS_SINGLEUSE, &dwRegister);
197. if (FAILED(hr))
198. {
199. Message(TEXT("Server: CoRegisterClassObject"), hr);
200. exit(hr);
201. }
202.
203. Message(TEXT("Server: Waiting"), S_OK);
204.
205. // 等待DCOM客户的请求
206. WaitForSingleObject(hevtDone, INFINITE);
207.
208. CloseHandle(hevtDone);
209.
210. CoUninitialize();
211. Message(TEXT("Server: Done"), S_OK);
212. } // main
|
请发表评论