| | 179 | // CBlackListAwareComCreatorT |
| | 180 | |
| | 181 | template <typename T, const CLSID* t_pClassIdentifier> |
| | 182 | class ATL_NO_VTABLE CTransparentCoClassT |
| | 183 | { |
| | 184 | public: |
| | 185 | // CTransparentCoClassT |
| | 186 | static HINSTANCE CoLoadOriginalLibrary() |
| | 187 | { |
| | 188 | const HINSTANCE hModule = CoLoadLibrary(const_cast<LPOLESTR>((LPCOLESTR) CT2COLE(T::GetOriginalLibraryName())), TRUE); |
| | 189 | __E(hModule); |
| | 190 | return hModule; |
| | 191 | } |
| | 192 | static CComPtr<IUnknown> CoCreateOriginalInstance(HINSTANCE hModule, IUnknown* pControllingUnknown = NULL) |
| | 193 | { |
| | 194 | typedef HRESULT (WINAPI *DLLGETCLASSOBJECT)(REFCLSID, REFIID, VOID**); |
| | 195 | DLLGETCLASSOBJECT DllGetClassObject = (DLLGETCLASSOBJECT) GetProcAddress(hModule, "DllGetClassObject"); |
| | 196 | __E(DllGetClassObject); |
| | 197 | CComPtr<IClassFactory> pClassFactory; |
| | 198 | __C(DllGetClassObject(*t_pClassIdentifier, __uuidof(IClassFactory), (VOID**) &pClassFactory)); |
| | 199 | _A(pClassFactory); |
| | 200 | CComPtr<IUnknown> pUnknown; |
| | 201 | __C(pClassFactory->CreateInstance(pControllingUnknown, __uuidof(IUnknown), (VOID**) &pUnknown)); |
| | 202 | return pUnknown; |
| | 203 | } |
| | 204 | static CComPtr<IUnknown> CoCreateOriginalInstance(IUnknown* pControllingUnknown = NULL) |
| | 205 | { |
| | 206 | CComPtr<IUnknown> pUnknown; |
| | 207 | const HINSTANCE hModule = CoLoadOriginalLibrary(); |
| | 208 | _ATLTRY |
| | 209 | { |
| | 210 | pUnknown = CoCreateOriginalInstance(hModule, pControllingUnknown); |
| | 211 | } |
| | 212 | _ATLCATCHALL() |
| | 213 | { |
| | 214 | CoFreeLibrary(hModule); |
| | 215 | _ATLRETHROW; |
| | 216 | } |
| | 217 | CoFreeLibrary(hModule); |
| | 218 | return pUnknown; |
| | 219 | } |
| | 220 | }; |
| | 221 | |
| | 222 | //////////////////////////////////////////////////////////// |
| | 223 | // CBlackListAwareComCreatorT |
| | 224 | |
| | 225 | template <typename _ObjectClass, typename _Class, LPCTSTR* t_ppszName> |
| | 226 | class CBlackListAwareComCreatorT : |
| | 227 | public CComCreator<_ObjectClass> |
| | 228 | { |
| | 229 | public: |
| | 230 | // CBlackListAwareComCreatorT |
| | 231 | static HRESULT WINAPI CreateInstance(VOID* pvControllingUnknown, REFIID InterfaceIdentifier, VOID** ppvObject) throw() |
| | 232 | { |
| | 233 | _A(ppvObject); |
| | 234 | *ppvObject = NULL; |
| | 235 | #pragma region Check Black List |
| | 236 | static INT g_nBlackListed = 0; // 0 Unknown, 1 No, 2 Yes |
| | 237 | { |
| | 238 | _A(_pAtlModule); |
| | 239 | CComCritSecLock<CComCriticalSection> Lock(_pAtlModule->m_csStaticDataInitAndTypeInfo); |
| | 240 | if(!g_nBlackListed) |
| | 241 | { |
| | 242 | TCHAR pszPath[MAX_PATH] = { 0 }; |
| | 243 | _W(GetModuleFileName(NULL, pszPath, DIM(pszPath))); |
| | 244 | LPTSTR pszFileName = FindFileName(pszPath); |
| | 245 | _A(pszFileName); |
| | 246 | RemoveExtension(pszFileName); |
| | 247 | const CString sBlackList = _RegKeyHelper::QueryStringValue(HKEY_LOCAL_MACHINE, REGISTRY_ROOT, AtlFormatString(_T("%s Black List"),
*t_ppszName)); |
| | 248 | CRoArrayT<CString> BlackListArray; |
| | 249 | _StringHelper::GetCommaSeparatedItems(sBlackList, BlackListArray); |
| | 250 | BOOL bFound = FALSE; |
| | 251 | for(SIZE_T nIndex = 0; nIndex < BlackListArray.GetCount(); nIndex++) |
| | 252 | { |
| | 253 | CPath sFileName = (LPCTSTR) BlackListArray[nIndex]; |
| | 254 | sFileName.RemoveExtension(); |
| | 255 | if(_tcsicmp(sFileName, pszFileName) == 0) |
| | 256 | { |
| | 257 | _Z2(atlTraceCOM, 2, _T("Will instantiate original COM class, sFileName \"%s\"\n"), sFileName); |
| | 258 | bFound = TRUE; |
| | 259 | break; |
| | 260 | } |
| | 261 | } |
| | 262 | g_nBlackListed = bFound ? 2 : 1; |
| | 263 | } |
| | 264 | } |
| | 265 | #pragma endregion |
| | 266 | if(g_nBlackListed == 2) |
| | 267 | #pragma region CoCreateInstance Original Class |
| | 268 | _ATLTRY |
| | 269 | { |
| | 270 | _A(_pAtlModule); |
| | 271 | const LONG nLockResult = _pAtlModule->Lock(); |
| | 272 | _ATLTRY |
| | 273 | { |
| | 274 | CComPtr<IUnknown> pUnknown = _Class::CoCreateOriginalInstance((IUnknown*) pvControllingUnknown); |
| | 275 | if(InterfaceIdentifier == __uuidof(IUnknown)) |
| | 276 | *ppvObject = pUnknown.Detach(); |
| | 277 | else |
| | 278 | __C(pUnknown->QueryInterface(InterfaceIdentifier, ppvObject)); |
| | 279 | } |
| | 280 | _ATLCATCHALL() |
| | 281 | { |
| | 282 | _pAtlModule->Unlock(); |
| | 283 | _ATLRETHROW; |
| | 284 | } |
| | 285 | const LONG nUnlockResult = _pAtlModule->Unlock(); |
| | 286 | _Z4(atlTraceGeneral, 6-2, _T("nLockResult %d, nUnlockResult %d\n"), nLockResult, nUnlockResult); |
| | 287 | return S_OK; |
| | 288 | } |
| | 289 | _ATLCATCH(Exception) |
| | 290 | { |
| | 291 | _A(FAILED(Exception)); |
| | 292 | _C(Exception); |
| | 293 | } |
| | 294 | #pragma endregion |
| | 295 | return __super::CreateInstance(pvControllingUnknown, InterfaceIdentifier, ppvObject); |
| | 296 | } |
| | 297 | }; |
| | 298 | |
| | 299 | //////////////////////////////////////////////////////////// |