[SDK][ATL] Independence day of ReactOS ATL (#1473)
[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 #ifdef __REACTOS__
26 #define WIN32_NO_STATUS
27 #define _INC_WINDOWS
28 #define COM_NO_WINDOWS_H
29 #include <stdarg.h>
30 #include <windef.h>
31 #include <winbase.h>
32 #include <winreg.h>
33 #include <winnls.h>
34 #else
35 #include <windows.h>
36 #endif
37 #include <ole2.h>
38 #include <olectl.h>
39 #include <crtdbg.h>
40
41 #ifndef ATLASSERT
42 #define ATLASSERT(expr) _ASSERTE(expr)
43 #endif // ATLASSERT
44
45 namespace ATL
46 {
47
48 class CComCriticalSection
49 {
50 public:
51 CRITICAL_SECTION m_sec;
52 public:
53 CComCriticalSection()
54 {
55 memset(&m_sec, 0, sizeof(CRITICAL_SECTION));
56 }
57
58 virtual ~CComCriticalSection()
59 {
60 }
61
62 HRESULT Lock()
63 {
64 EnterCriticalSection(&m_sec);
65 return S_OK;
66 }
67
68 HRESULT Unlock()
69 {
70 LeaveCriticalSection(&m_sec);
71 return S_OK;
72 }
73
74 HRESULT Init()
75 {
76 InitializeCriticalSection(&m_sec);
77 return S_OK;
78 }
79
80 HRESULT Term()
81 {
82 DeleteCriticalSection(&m_sec);
83 return S_OK;
84 }
85 };
86
87 class CComFakeCriticalSection
88 {
89 public:
90 HRESULT Lock()
91 {
92 return S_OK;
93 }
94
95 HRESULT Unlock()
96 {
97 return S_OK;
98 }
99
100 HRESULT Init()
101 {
102 return S_OK;
103 }
104
105 HRESULT Term()
106 {
107 return S_OK;
108 }
109 };
110
111 class CComAutoCriticalSection : public CComCriticalSection
112 {
113 public:
114 CComAutoCriticalSection()
115 {
116 HRESULT hResult __MINGW_ATTRIB_UNUSED;
117
118 hResult = CComCriticalSection::Init();
119 ATLASSERT(SUCCEEDED(hResult));
120 }
121 ~CComAutoCriticalSection()
122 {
123 CComCriticalSection::Term();
124 }
125 };
126
127 class CComSafeDeleteCriticalSection : public CComCriticalSection
128 {
129 private:
130 bool m_bInitialized;
131 public:
132 CComSafeDeleteCriticalSection()
133 {
134 m_bInitialized = false;
135 }
136
137 ~CComSafeDeleteCriticalSection()
138 {
139 Term();
140 }
141
142 HRESULT Lock()
143 {
144 ATLASSERT(m_bInitialized);
145 return CComCriticalSection::Lock();
146 }
147
148 HRESULT Init()
149 {
150 HRESULT hResult;
151
152 ATLASSERT(!m_bInitialized);
153 hResult = CComCriticalSection::Init();
154 if (SUCCEEDED(hResult))
155 m_bInitialized = true;
156 return hResult;
157 }
158
159 HRESULT Term()
160 {
161 if (!m_bInitialized)
162 return S_OK;
163 m_bInitialized = false;
164 return CComCriticalSection::Term();
165 }
166 };
167
168 class CComAutoDeleteCriticalSection : public CComSafeDeleteCriticalSection
169 {
170 private:
171 // CComAutoDeleteCriticalSection::Term should never be called
172 HRESULT Term();
173 };
174
175 struct _ATL_BASE_MODULE70
176 {
177 UINT cbSize;
178 HINSTANCE m_hInst;
179 HINSTANCE m_hInstResource;
180 bool m_bNT5orWin98;
181 DWORD dwAtlBuildVer;
182 GUID *pguidVer;
183 CRITICAL_SECTION m_csResource;
184 #ifdef NOTYET
185 CSimpleArray<HINSTANCE> m_rgResourceInstance;
186 #endif
187 };
188 typedef _ATL_BASE_MODULE70 _ATL_BASE_MODULE;
189
190 class CAtlBaseModule : public _ATL_BASE_MODULE
191 {
192 public :
193 static bool m_bInitFailed;
194 public:
195 CAtlBaseModule()
196 {
197 cbSize = sizeof(_ATL_BASE_MODULE);
198 GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCWSTR)this, &m_hInst);
199 m_hInstResource = m_hInst;
200 }
201
202 HINSTANCE GetModuleInstance()
203 {
204 return m_hInst;
205 }
206
207 HINSTANCE GetResourceInstance()
208 {
209 return m_hInstResource;
210 }
211
212 HINSTANCE SetResourceInstance(HINSTANCE hInst)
213 {
214 return static_cast< HINSTANCE >(InterlockedExchangePointer((void**)&m_hInstResource, hInst));
215 }
216
217 HINSTANCE GetHInstanceAt(int i);
218 };
219
220 extern CAtlBaseModule _AtlBaseModule;
221
222
223 ///
224 // String Resource helper functions
225 //
226 #ifdef _MSC_VER
227 #pragma warning(push)
228 #pragma warning(disable:4200)
229 #endif
230 struct ATLSTRINGRESOURCEIMAGE
231 {
232 WORD nLength;
233 WCHAR achString[];
234 };
235 #ifdef _MSC_VER
236 #pragma warning(pop)
237 #endif
238
239 inline const ATLSTRINGRESOURCEIMAGE* _AtlGetStringResourceImage(
240 _In_ HINSTANCE hInstance,
241 _In_ HRSRC hResource,
242 _In_ UINT id)
243 {
244 const ATLSTRINGRESOURCEIMAGE* pImage;
245 const ATLSTRINGRESOURCEIMAGE* pImageEnd;
246 ULONG nResourceSize;
247 HGLOBAL hGlobal;
248 UINT iIndex;
249
250 hGlobal = ::LoadResource(hInstance, hResource);
251 if (hGlobal == NULL) return NULL;
252
253 pImage = (const ATLSTRINGRESOURCEIMAGE*)::LockResource(hGlobal);
254 if (pImage == NULL) return NULL;
255
256 nResourceSize = ::SizeofResource(hInstance, hResource);
257 pImageEnd = (const ATLSTRINGRESOURCEIMAGE*)(LPBYTE(pImage) + nResourceSize);
258 iIndex = id & 0x000f;
259
260 while ((iIndex > 0) && (pImage < pImageEnd))
261 {
262 pImage = (const ATLSTRINGRESOURCEIMAGE*)(LPBYTE(pImage) + (sizeof(ATLSTRINGRESOURCEIMAGE) + (pImage->nLength * sizeof(WCHAR))));
263 iIndex--;
264 }
265
266 if (pImage >= pImageEnd) return NULL;
267 if (pImage->nLength == 0) return NULL;
268
269 return pImage;
270 }
271
272 inline const ATLSTRINGRESOURCEIMAGE* AtlGetStringResourceImage(
273 _In_ HINSTANCE hInstance,
274 _In_ UINT id) throw()
275 {
276 HRSRC hResource;
277 hResource = ::FindResourceW(hInstance, MAKEINTRESOURCEW((((id >> 4) + 1) & static_cast<WORD>(~0))), (LPWSTR)RT_STRING);
278 if (hResource == NULL) return NULL;
279 return _AtlGetStringResourceImage(hInstance, hResource, id);
280 }
281
282 inline const ATLSTRINGRESOURCEIMAGE* AtlGetStringResourceImage(
283 _In_ HINSTANCE hInstance,
284 _In_ UINT id,
285 _In_ WORD wLanguage)
286 {
287 HRSRC hResource;
288 hResource = ::FindResourceExW(hInstance, (LPWSTR)RT_STRING, MAKEINTRESOURCEW((((id >> 4) + 1) & static_cast<WORD>(~0))), wLanguage);
289 if (hResource == NULL) return NULL;
290 return _AtlGetStringResourceImage(hInstance, hResource, id);
291 }
292
293 inline HINSTANCE AtlFindStringResourceInstance(
294 UINT nID,
295 WORD wLanguage = 0)
296 {
297 const ATLSTRINGRESOURCEIMAGE* strRes = NULL;
298 HINSTANCE hInst = _AtlBaseModule.GetHInstanceAt(0);
299
300 for (int i = 1; hInst != NULL && strRes == NULL; hInst = _AtlBaseModule.GetHInstanceAt(i++))
301 {
302 strRes = AtlGetStringResourceImage(hInst, nID, wLanguage);
303 if (strRes != NULL) return hInst;
304 }
305
306 return NULL;
307 }
308
309 }; // namespace ATL