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