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:
CComCriticalSection()53 CComCriticalSection()
54 {
55 memset(&m_sec, 0, sizeof(CRITICAL_SECTION));
56 }
57
~CComCriticalSection()58 ~CComCriticalSection()
59 {
60 }
61
Lock()62 HRESULT Lock()
63 {
64 EnterCriticalSection(&m_sec);
65 return S_OK;
66 }
67
Unlock()68 HRESULT Unlock()
69 {
70 LeaveCriticalSection(&m_sec);
71 return S_OK;
72 }
73
Init()74 HRESULT Init()
75 {
76 InitializeCriticalSection(&m_sec);
77 return S_OK;
78 }
79
Term()80 HRESULT Term()
81 {
82 DeleteCriticalSection(&m_sec);
83 return S_OK;
84 }
85 };
86
87 class CComFakeCriticalSection
88 {
89 public:
Lock()90 HRESULT Lock()
91 {
92 return S_OK;
93 }
94
Unlock()95 HRESULT Unlock()
96 {
97 return S_OK;
98 }
99
Init()100 HRESULT Init()
101 {
102 return S_OK;
103 }
104
Term()105 HRESULT Term()
106 {
107 return S_OK;
108 }
109 };
110
111 class CComAutoCriticalSection : public CComCriticalSection
112 {
113 public:
CComAutoCriticalSection()114 CComAutoCriticalSection()
115 {
116 HRESULT hResult __MINGW_ATTRIB_UNUSED;
117
118 hResult = CComCriticalSection::Init();
119 ATLASSERT(SUCCEEDED(hResult));
120 }
~CComAutoCriticalSection()121 ~CComAutoCriticalSection()
122 {
123 CComCriticalSection::Term();
124 }
125 };
126
127 class CComSafeDeleteCriticalSection : public CComCriticalSection
128 {
129 private:
130 bool m_bInitialized;
131 public:
CComSafeDeleteCriticalSection()132 CComSafeDeleteCriticalSection()
133 {
134 m_bInitialized = false;
135 }
136
~CComSafeDeleteCriticalSection()137 ~CComSafeDeleteCriticalSection()
138 {
139 Term();
140 }
141
Lock()142 HRESULT Lock()
143 {
144 ATLASSERT(m_bInitialized);
145 return CComCriticalSection::Lock();
146 }
147
Init()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
Term()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:
CAtlBaseModule()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
GetModuleInstance()202 HINSTANCE GetModuleInstance()
203 {
204 return m_hInst;
205 }
206
GetResourceInstance()207 HINSTANCE GetResourceInstance()
208 {
209 return m_hInstResource;
210 }
211
SetResourceInstance(HINSTANCE hInst)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
231 struct ATLSTRINGRESOURCEIMAGE
232 {
233 WORD nLength;
234 WCHAR achString[];
235 };
236 #ifdef _MSC_VER
237 #pragma warning(pop)
238 #endif
239
_AtlGetStringResourceImage(_In_ HINSTANCE hInstance,_In_ HRSRC hResource,_In_ UINT id)240 inline 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
AtlGetStringResourceImage(_In_ HINSTANCE hInstance,_In_ UINT id)273 inline 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
AtlGetStringResourceImage(_In_ HINSTANCE hInstance,_In_ UINT id,_In_ WORD wLanguage)283 inline 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
294 inline 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
311