[ATL] Add CComBSTR.Attach
[reactos.git] / sdk / lib / atl / atlcore.h
1 /*
2 * ReactOS ATL
3 *
4 * Copyright 2009 Andrew Hill <ash77@reactos.org>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #pragma once
22
23 #include <malloc.h>
24
25 #define WIN32_NO_STATUS
26 #define _INC_WINDOWS
27 #define COM_NO_WINDOWS_H
28 #include <stdarg.h>
29 #include <windef.h>
30 #include <winbase.h>
31 #include <winreg.h>
32 #include <winnls.h>
33 #include <ole2.h>
34 #include <olectl.h>
35 #include <crtdbg.h>
36
37 #ifndef ATLASSERT
38 #define ATLASSERT(expr) _ASSERTE(expr)
39 #endif // ATLASSERT
40
41 namespace ATL
42 {
43
44 class CComCriticalSection
45 {
46 public:
47 CRITICAL_SECTION m_sec;
48 public:
49 CComCriticalSection()
50 {
51 memset(&m_sec, 0, sizeof(CRITICAL_SECTION));
52 }
53
54 virtual ~CComCriticalSection()
55 {
56 }
57
58 HRESULT Lock()
59 {
60 EnterCriticalSection(&m_sec);
61 return S_OK;
62 }
63
64 HRESULT Unlock()
65 {
66 LeaveCriticalSection(&m_sec);
67 return S_OK;
68 }
69
70 HRESULT Init()
71 {
72 InitializeCriticalSection(&m_sec);
73 return S_OK;
74 }
75
76 HRESULT Term()
77 {
78 DeleteCriticalSection(&m_sec);
79 return S_OK;
80 }
81 };
82
83 class CComFakeCriticalSection
84 {
85 public:
86 HRESULT Lock()
87 {
88 return S_OK;
89 }
90
91 HRESULT Unlock()
92 {
93 return S_OK;
94 }
95
96 HRESULT Init()
97 {
98 return S_OK;
99 }
100
101 HRESULT Term()
102 {
103 return S_OK;
104 }
105 };
106
107 class CComAutoCriticalSection : public CComCriticalSection
108 {
109 public:
110 CComAutoCriticalSection()
111 {
112 HRESULT hResult __MINGW_ATTRIB_UNUSED;
113
114 hResult = CComCriticalSection::Init();
115 ATLASSERT(SUCCEEDED(hResult));
116 }
117 ~CComAutoCriticalSection()
118 {
119 CComCriticalSection::Term();
120 }
121 };
122
123 class CComSafeDeleteCriticalSection : public CComCriticalSection
124 {
125 private:
126 bool m_bInitialized;
127 public:
128 CComSafeDeleteCriticalSection()
129 {
130 m_bInitialized = false;
131 }
132
133 ~CComSafeDeleteCriticalSection()
134 {
135 Term();
136 }
137
138 HRESULT Lock()
139 {
140 ATLASSERT(m_bInitialized);
141 return CComCriticalSection::Lock();
142 }
143
144 HRESULT Init()
145 {
146 HRESULT hResult;
147
148 ATLASSERT(!m_bInitialized);
149 hResult = CComCriticalSection::Init();
150 if (SUCCEEDED(hResult))
151 m_bInitialized = true;
152 return hResult;
153 }
154
155 HRESULT Term()
156 {
157 if (!m_bInitialized)
158 return S_OK;
159 m_bInitialized = false;
160 return CComCriticalSection::Term();
161 }
162 };
163
164 class CComAutoDeleteCriticalSection : public CComSafeDeleteCriticalSection
165 {
166 private:
167 // CComAutoDeleteCriticalSection::Term should never be called
168 HRESULT Term();
169 };
170
171 struct _ATL_BASE_MODULE70
172 {
173 UINT cbSize;
174 HINSTANCE m_hInst;
175 HINSTANCE m_hInstResource;
176 bool m_bNT5orWin98;
177 DWORD dwAtlBuildVer;
178 GUID *pguidVer;
179 CRITICAL_SECTION m_csResource;
180 #ifdef NOTYET
181 CSimpleArray<HINSTANCE> m_rgResourceInstance;
182 #endif
183 };
184 typedef _ATL_BASE_MODULE70 _ATL_BASE_MODULE;
185
186 class CAtlBaseModule : public _ATL_BASE_MODULE
187 {
188 public :
189 static bool m_bInitFailed;
190 public:
191 CAtlBaseModule()
192 {
193 cbSize = sizeof(_ATL_BASE_MODULE);
194 GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCWSTR)this, &m_hInst);
195 m_hInstResource = m_hInst;
196 }
197
198 HINSTANCE GetModuleInstance()
199 {
200 return m_hInst;
201 }
202
203 HINSTANCE GetResourceInstance()
204 {
205 return m_hInstResource;
206 }
207
208 HINSTANCE SetResourceInstance(HINSTANCE hInst)
209 {
210 return static_cast< HINSTANCE >(InterlockedExchangePointer((void**)&m_hInstResource, hInst));
211 }
212
213 HINSTANCE GetHInstanceAt(int i);
214 };
215
216 extern CAtlBaseModule _AtlBaseModule;
217
218
219 ///
220 // String Resource helper functions
221 //
222 #ifdef _MSC_VER
223 #pragma warning(push)
224 #pragma warning(disable:4200)
225 #endif
226 struct ATLSTRINGRESOURCEIMAGE
227 {
228 WORD nLength;
229 WCHAR achString[];
230 };
231 #ifdef _MSC_VER
232 #pragma warning(pop)
233 #endif
234
235 inline const ATLSTRINGRESOURCEIMAGE* _AtlGetStringResourceImage(
236 _In_ HINSTANCE hInstance,
237 _In_ HRSRC hResource,
238 _In_ UINT id)
239 {
240 const ATLSTRINGRESOURCEIMAGE* pImage;
241 const ATLSTRINGRESOURCEIMAGE* pImageEnd;
242 ULONG nResourceSize;
243 HGLOBAL hGlobal;
244 UINT iIndex;
245
246 hGlobal = ::LoadResource(hInstance, hResource);
247 if (hGlobal == NULL) return NULL;
248
249 pImage = (const ATLSTRINGRESOURCEIMAGE*)::LockResource(hGlobal);
250 if (pImage == NULL) return NULL;
251
252 nResourceSize = ::SizeofResource(hInstance, hResource);
253 pImageEnd = (const ATLSTRINGRESOURCEIMAGE*)(LPBYTE(pImage) + nResourceSize);
254 iIndex = id & 0x000f;
255
256 while ((iIndex > 0) && (pImage < pImageEnd))
257 {
258 pImage = (const ATLSTRINGRESOURCEIMAGE*)(LPBYTE(pImage) + (sizeof(ATLSTRINGRESOURCEIMAGE) + (pImage->nLength * sizeof(WCHAR))));
259 iIndex--;
260 }
261
262 if (pImage >= pImageEnd) return NULL;
263 if (pImage->nLength == 0) return NULL;
264
265 return pImage;
266 }
267
268 inline const ATLSTRINGRESOURCEIMAGE* AtlGetStringResourceImage(
269 _In_ HINSTANCE hInstance,
270 _In_ UINT id) throw()
271 {
272 HRSRC hResource;
273 hResource = ::FindResourceW(hInstance, MAKEINTRESOURCEW((((id >> 4) + 1) & static_cast<WORD>(~0))), (LPWSTR)RT_STRING);
274 if (hResource == NULL) return NULL;
275 return _AtlGetStringResourceImage(hInstance, hResource, id);
276 }
277
278 inline const ATLSTRINGRESOURCEIMAGE* AtlGetStringResourceImage(
279 _In_ HINSTANCE hInstance,
280 _In_ UINT id,
281 _In_ WORD wLanguage)
282 {
283 HRSRC hResource;
284 hResource = ::FindResourceExW(hInstance, (LPWSTR)RT_STRING, MAKEINTRESOURCEW((((id >> 4) + 1) & static_cast<WORD>(~0))), wLanguage);
285 if (hResource == NULL) return NULL;
286 return _AtlGetStringResourceImage(hInstance, hResource, id);
287 }
288
289 inline HINSTANCE AtlFindStringResourceInstance(
290 UINT nID,
291 WORD wLanguage = 0)
292 {
293 const ATLSTRINGRESOURCEIMAGE* strRes = NULL;
294 HINSTANCE hInst = _AtlBaseModule.GetHInstanceAt(0);
295
296 for (int i = 1; hInst != NULL && strRes == NULL; hInst = _AtlBaseModule.GetHInstanceAt(i++))
297 {
298 strRes = AtlGetStringResourceImage(hInst, nID, wLanguage);
299 if (strRes != NULL) return hInst;
300 }
301
302 return NULL;
303 }
304
305 }; // namespace ATL