Skip to content

Commit 8dce952

Browse files
committed
Added TypeLibHelper.h/cpp which have utility functions for configuring Windows Registry for TypeLib com libraries.
1 parent e699716 commit 8dce952

File tree

3 files changed

+191
-0
lines changed

3 files changed

+191
-0
lines changed

src/shellextension/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ add_library(sa.shellextension SHARED
2020
stdafx.cpp
2121
stdafx.h
2222
targetver.h
23+
TypeLibHelper.cpp
24+
TypeLibHelper.h
2325
utils.cpp
2426
utils.h
2527
)
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
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+
}

src/shellextension/TypeLibHelper.h

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#pragma once
2+
3+
#include <Windows.h>
4+
5+
/// <summary>
6+
/// Get the GUID of the TypeLib at index lpszIndex within this module.
7+
/// </summary>
8+
/// <param name="hInstTypeLib">A reference to the module that contains the TypeLib.</param>
9+
/// <param name="lpszIndex">The index of the TyleLib within this module.</param>
10+
/// <param name="guid">The output guid value of the typelib at given index.</param>
11+
/// <returns>Returns S_OK if the attributes of the requested typelib is found. Returns an HRESULT matching an error code otherwise.</returns>
12+
HRESULT GetTypeLibGuid(_In_ HINSTANCE hInstTypeLib, _In_opt_z_ LPCOLESTR lpszIndex, GUID& guid);
13+
14+
/// <summary>
15+
/// Get the attributes of the TypeLib at index lpszIndex within this module.
16+
/// </summary>
17+
/// <param name="hInstTypeLib">A reference to the module that contains the TypeLib.</param>
18+
/// <param name="lpszIndex">The index of the queries TypeLib within the instance.</param>
19+
/// <param name="libattr">A pointer to the output library attributes</param>
20+
/// <returns>Returns S_OK if the attributes of the requested typelib is found. Returns an HRESULT matching an error code otherwise.</returns>
21+
HRESULT GetTypeLibAttribute(_In_ HINSTANCE hInstTypeLib, _In_opt_z_ LPCOLESTR lpszIndex, _Out_ LPTLIBATTR pTLibAttr);
22+
23+
/// <summary>
24+
/// Check if the given typelib guid is registered on system.
25+
/// </summary>
26+
/// <remarks>
27+
/// The following registry keys and values are present for a registered typelib:
28+
/// [HKEY_CLASSES_ROOT\TypeLib\{guid}\1.0]
29+
/// @ = "MyClassNameLib"
30+
/// [HKEY_CLASSES_ROOT\TypeLib\{guid}\1.0\0\win64]
31+
/// @ = "Z:\\path\\to\\current\\file.dll"
32+
/// </remarks>
33+
/// <param name="guid">The typelib's guid value.</param>
34+
/// <param name="guid">The typelib version value. Usually "1.0".</param>
35+
/// <returns>Returns S_OK if the typelib is registered on system. Returns S_FALSE if the typelib is not registered on system. Returns an HRESULT matching an error code otherwise.</returns>
36+
HRESULT IsTypeLibRegisteredOnSystem(const GUID& guid, PCWSTR szVersion);
37+
38+
/// <summary>
39+
/// Check if the given typelib is registered on system.
40+
/// </summary>
41+
/// <remarks>
42+
/// The following registry keys and values are present for a registered typelib:
43+
/// [HKEY_CLASSES_ROOT\TypeLib\{guid}\{version}]
44+
/// @ = "MyClassNameLib"
45+
/// [HKEY_CLASSES_ROOT\TypeLib\{guid}\{version}\0\win64]
46+
/// @ = "Z:\\path\\to\\current\\file.dll"
47+
/// </remarks>
48+
/// <param name="pTLibAttr">A pointer to the typelib's attributes.</param>
49+
/// <returns>Returns S_OK if the typelib is registered on system. Returns S_FALSE if the typelib is not registered on system. Returns an HRESULT matching an error code otherwise.</returns>
50+
HRESULT IsTypeLibRegisteredOnSystem(_In_ LPTLIBATTR pTLibAttr);

0 commit comments

Comments
 (0)