Reactos
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
45namespace ATL
46{
47
48class CComCriticalSection
49{
50public:
51 CRITICAL_SECTION m_sec;
52public:
53 CComCriticalSection()
54 {
55 memset(&m_sec, 0, sizeof(CRITICAL_SECTION));
56 }
57
58 ~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
87class CComFakeCriticalSection
88{
89public:
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
111class CComAutoCriticalSection : public CComCriticalSection
112{
113public:
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
127class CComSafeDeleteCriticalSection : public CComCriticalSection
128{
129private:
130 bool m_bInitialized;
131public:
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
168class CComAutoDeleteCriticalSection : public CComSafeDeleteCriticalSection
169{
170private:
171 // CComAutoDeleteCriticalSection::Term should never be called
172 HRESULT Term();
173};
174
175struct _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};
188typedef _ATL_BASE_MODULE70 _ATL_BASE_MODULE;
189
190class CAtlBaseModule : public _ATL_BASE_MODULE
191{
192public :
193 static bool m_bInitFailed;
194public:
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__declspec(selectany) CAtlBaseModule _AtlBaseModule;
221__declspec(selectany) bool CAtlBaseModule::m_bInitFailed = false;
222
223
224///
225// String Resource helper functions
226//
227#ifdef _MSC_VER
228#pragma warning(push)
229#pragma warning(disable:4200)
230#endif
231struct ATLSTRINGRESOURCEIMAGE
232{
233 WORD nLength;
234 WCHAR achString[];
235};
236#ifdef _MSC_VER
237#pragma warning(pop)
238#endif
239
240inline const ATLSTRINGRESOURCEIMAGE* _AtlGetStringResourceImage(
241 _In_ HINSTANCE hInstance,
242 _In_ HRSRC hResource,
243 _In_ UINT id)
244{
245 const ATLSTRINGRESOURCEIMAGE* pImage;
246 const ATLSTRINGRESOURCEIMAGE* pImageEnd;
247 ULONG nResourceSize;
248 HGLOBAL hGlobal;
249 UINT iIndex;
250
251 hGlobal = ::LoadResource(hInstance, hResource);
252 if (hGlobal == NULL) return NULL;
253
254 pImage = (const ATLSTRINGRESOURCEIMAGE*)::LockResource(hGlobal);
255 if (pImage == NULL) return NULL;
256
257 nResourceSize = ::SizeofResource(hInstance, hResource);
258 pImageEnd = (const ATLSTRINGRESOURCEIMAGE*)(LPBYTE(pImage) + nResourceSize);
259 iIndex = id & 0x000f;
260
261 while ((iIndex > 0) && (pImage < pImageEnd))
262 {
263 pImage = (const ATLSTRINGRESOURCEIMAGE*)(LPBYTE(pImage) + (sizeof(ATLSTRINGRESOURCEIMAGE) + (pImage->nLength * sizeof(WCHAR))));
264 iIndex--;
265 }
266
267 if (pImage >= pImageEnd) return NULL;
268 if (pImage->nLength == 0) return NULL;
269
270 return pImage;
271}
272
273inline const ATLSTRINGRESOURCEIMAGE* AtlGetStringResourceImage(
274 _In_ HINSTANCE hInstance,
275 _In_ UINT id) noexcept
276{
277 HRSRC hResource;
278 hResource = ::FindResourceW(hInstance, MAKEINTRESOURCEW((((id >> 4) + 1) & static_cast<WORD>(~0))), (LPWSTR)RT_STRING);
279 if (hResource == NULL) return NULL;
280 return _AtlGetStringResourceImage(hInstance, hResource, id);
281}
282
283inline const ATLSTRINGRESOURCEIMAGE* AtlGetStringResourceImage(
284 _In_ HINSTANCE hInstance,
285 _In_ UINT id,
286 _In_ WORD wLanguage)
287{
288 HRSRC hResource;
289 hResource = ::FindResourceExW(hInstance, (LPWSTR)RT_STRING, MAKEINTRESOURCEW((((id >> 4) + 1) & static_cast<WORD>(~0))), wLanguage);
290 if (hResource == NULL) return NULL;
291 return _AtlGetStringResourceImage(hInstance, hResource, id);
292}
293
294inline HINSTANCE AtlFindStringResourceInstance(
295 UINT nID,
296 WORD wLanguage = 0)
297{
298 const ATLSTRINGRESOURCEIMAGE* strRes = NULL;
299 HINSTANCE hInst = _AtlBaseModule.GetHInstanceAt(0);
300
301 for (int i = 1; hInst != NULL && strRes == NULL; hInst = _AtlBaseModule.GetHInstanceAt(i++))
302 {
303 strRes = AtlGetStringResourceImage(hInst, nID, wLanguage);
304 if (strRes != NULL) return hInst;
305 }
306
307 return NULL;
308}
309
310}; // namespace ATL