xref: /reactos/sdk/lib/atl/atlcore.h (revision 8a978a17)
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 __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 
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 
273 inline const ATLSTRINGRESOURCEIMAGE* AtlGetStringResourceImage(
274     _In_ HINSTANCE hInstance,
275     _In_ UINT id) throw()
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 
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