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