1+ #include " stdafx.h"
2+ #include " TypeLibHelper.h"
3+
4+ #include < strsafe.h> // for StringCchPrintf()
5+
6+ using namespace ATL ;
7+ extern HRESULT GetHKCRRegistryKeyAndValue (PCWSTR pszSubKey, PCWSTR pszValueName, PWSTR pszData, DWORD cbData); // from Reg.cpp
8+
9+ HRESULT GetTypeLibGuid (_In_ HINSTANCE hInstTypeLib, _In_opt_z_ LPCOLESTR lpszIndex, GUID& guid)
10+ {
11+ ZeroMemory (&guid, sizeof (GUID));
12+ TLIBATTR sTLibAttr ;
13+ HRESULT hr = GetTypeLibAttribute (hInstTypeLib, lpszIndex, &sTLibAttr );
14+ if ( SUCCEEDED (hr) )
15+ guid = sTLibAttr .guid ;
16+ return hr;
17+ }
18+
19+ HRESULT GetTypeLibAttribute (_In_ HINSTANCE hInstTypeLib, _In_opt_z_ LPCOLESTR lpszIndex, _Out_ LPTLIBATTR pTLibAttr)
20+ {
21+ if ( NULL == pTLibAttr )
22+ return E_INVALIDARG;
23+
24+ ZeroMemory (pTLibAttr, sizeof (TLIBATTR));
25+
26+ CComBSTR bstrPath;
27+ CComPtr<ITypeLib> pTypeLib;
28+ HRESULT hr = AtlLoadTypeLib (hInstTypeLib, lpszIndex, &bstrPath, &pTypeLib);
29+ if ( SUCCEEDED (hr) )
30+ {
31+ TLIBATTR* ptla;
32+ hr = pTypeLib->GetLibAttr (&ptla);
33+ if ( SUCCEEDED (hr) )
34+ {
35+ *pTLibAttr = *ptla;
36+
37+ pTypeLib->ReleaseTLibAttr (ptla);
38+ }
39+ }
40+ return hr;
41+ }
42+
43+ HRESULT IsTypeLibRegisteredOnSystem (const GUID& guid, PCWSTR szVersion)
44+ {
45+ TLIBATTR sTLibAttr ;
46+ ZeroMemory (&sTLibAttr , sizeof (TLIBATTR));
47+ sTLibAttr .guid = guid;
48+ sTLibAttr .syskind = SYS_WIN64;
49+ sTLibAttr .wMajorVerNum = 1 ;
50+ sTLibAttr .wMinorVerNum = 0 ;
51+
52+ HRESULT hr = IsTypeLibRegisteredOnSystem (&sTLibAttr );
53+ return hr;
54+ }
55+
56+ HRESULT IsTypeLibRegisteredOnSystem (_In_ LPTLIBATTR pTLibAttr)
57+ {
58+ if ( NULL == pTLibAttr )
59+ return E_INVALIDARG;
60+
61+ HRESULT hr;
62+
63+ // guid to string
64+ wchar_t szGUID[64 ] = { 0 };
65+ StringFromGUID2 (pTLibAttr->guid , szGUID, 64 );
66+
67+ // version to string
68+ wchar_t szVersion[32 ] = { 0 };
69+ hr = StringCchPrintf (szVersion, ARRAYSIZE (szVersion), L" %d.%d" , pTLibAttr->wMajorVerNum , pTLibAttr->wMajorVerNum );
70+ if ( FAILED (hr) )
71+ return hr;
72+
73+ // syskind to string
74+ const wchar_t * szSysKind = NULL ;
75+ switch ( pTLibAttr->syskind )
76+ {
77+ // case SYS_WIN32: // not supported
78+ case SYS_WIN64:
79+ szSysKind = L" win64" ;
80+ break ;
81+ default :
82+ return HRESULT_FROM_WIN32 (ERROR_INVALID_FLAGS);
83+ };
84+
85+ // Check for the "HKCR\TypeLib\{guid}\{version}" key.
86+ wchar_t szSubkey[MAX_PATH];
87+ hr = StringCchPrintf (szSubkey, ARRAYSIZE (szSubkey), L" TypeLib\\ %s\\ %s" , szGUID, szVersion);
88+ if ( FAILED (hr) )
89+ return hr;
90+
91+ // Get the TypeLib name
92+ wchar_t szTypeLibName[MAX_PATH];
93+ hr = GetHKCRRegistryKeyAndValue (szSubkey, nullptr , szTypeLibName, sizeof (szTypeLibName));
94+ if ( FAILED (hr) )
95+ {
96+ if ( hr == HRESULT_FROM_WIN32 (ERROR_FILE_NOT_FOUND) )
97+ return S_FALSE;
98+ return hr; // unexpected error
99+ }
100+
101+ // If TypeLib name is empty.
102+ if ( szTypeLibName[0 ] == L' \0 ' )
103+ return S_FALSE;
104+
105+ // Check for the "HKCR\TypeLib\{guid}\{version}\0\{syskind}" key.
106+ hr = StringCchPrintf (szSubkey, ARRAYSIZE (szSubkey), L" TypeLib\\ %s\\ %s\\ 0\\ %s" , szGUID, szVersion, szSysKind);
107+ if ( FAILED (hr) )
108+ return hr;
109+
110+ // Get the TypeLib dll path
111+ wchar_t szDllPath[MAX_PATH];
112+ hr = GetHKCRRegistryKeyAndValue (szSubkey, nullptr , szDllPath, sizeof (szDllPath));
113+ if ( FAILED (hr) )
114+ {
115+ if ( hr == HRESULT_FROM_WIN32 (ERROR_FILE_NOT_FOUND) )
116+ return S_FALSE;
117+ return hr; // unexpected error
118+ }
119+
120+ // If TypeLib dll path is empty.
121+ if ( szDllPath[0 ] == L' \0 ' )
122+ return S_FALSE;
123+
124+ // // Get path to current module
125+ // wchar_t szModule[MAX_PATH];
126+ // HINSTANCE hInst = GetModuleHandle(NULL);
127+ // hr = S_OK;
128+ // if ( GetModuleFileName(hInst, szModule, ARRAYSIZE(szModule)) == 0 )
129+ // {
130+ // hr = HRESULT_FROM_WIN32(GetLastError());
131+ // return hr;
132+ // }
133+
134+ // // If TypeLib dll path is not this module's path.
135+ // if ( _wcsicmp(szDllPath, szModule) == 0)
136+ // return S_FALSE;
137+
138+ return S_OK;
139+ }
0 commit comments