xref: /reactos/sdk/lib/atl/atlcore.h (revision 5100859e)
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
306