You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
230 lines
6.7 KiB
230 lines
6.7 KiB
// stdafx.cpp : source file that includes just the standard includes
|
|
// stdafx.pch will be the pre-compiled header
|
|
// stdafx.obj will contain the pre-compiled type information
|
|
|
|
#include "stdafx.h"
|
|
|
|
#ifdef _ATL_STATIC_REGISTRY
|
|
#include <statreg.h>
|
|
#include <statreg.cpp>
|
|
#endif
|
|
|
|
#include <atlimpl.cpp>
|
|
|
|
#include "ShellExtensions.h"
|
|
#include "strsafe.h"
|
|
|
|
typedef DWORD (*PFNSHDeleteKeyW)(HKEY hkey, LPWSTR pszSubkey);
|
|
|
|
HRESULT WINAPI
|
|
CLayerUIModule::UpdateRegistryCLSID(
|
|
const CLSID& clsid,
|
|
BOOL bRegister
|
|
)
|
|
{
|
|
static const TCHAR szIPS32[] = _T("InprocServer32");
|
|
static const TCHAR szCLSID[] = _T("CLSID");
|
|
static const TCHAR szPropPageExt[] = _T("ShimLayer Property Page");
|
|
|
|
HRESULT hRes = S_OK;
|
|
HRESULT hr = S_OK;
|
|
|
|
LPOLESTR lpOleStrCLSIDValue = NULL;
|
|
|
|
if (clsid != CLSID_ShimLayerPropertyPage) {
|
|
LogMsg(_T("[UpdateRegistryCLSID] unknown CLSID!\n"));
|
|
return E_FAIL;
|
|
}
|
|
|
|
hr = ::StringFromCLSID(clsid, &lpOleStrCLSIDValue);
|
|
if (hr != S_OK) {
|
|
LogMsg(_T("[UpdateRegistryCLSID] can't get string from CLSID!\n"));
|
|
return E_FAIL;
|
|
}
|
|
|
|
|
|
HKEY hkey = NULL;
|
|
LONG lRes;
|
|
|
|
if (bRegister) {
|
|
|
|
TCHAR szBuffer[MAX_PATH];
|
|
DWORD keyType = 0;
|
|
|
|
//
|
|
// Write the key for registration. Include the value to specify
|
|
// the threading model.
|
|
//
|
|
StringCchPrintf(szBuffer, ARRAYSIZE(szBuffer), _T("%s\\%s\\%s"), szCLSID, lpOleStrCLSIDValue, szIPS32);
|
|
|
|
lRes = RegCreateKey(HKEY_CLASSES_ROOT, szBuffer, &hkey);
|
|
|
|
if (lRes != ERROR_SUCCESS) {
|
|
LogMsg(_T("[UpdateRegistryCLSID] failed to open/create \"%s\"\n"),
|
|
szBuffer);
|
|
goto Exit;
|
|
}
|
|
|
|
::GetModuleFileName(m_hInst, szBuffer, MAX_PATH);
|
|
|
|
lRes = RegSetValueEx(hkey,
|
|
NULL,
|
|
0,
|
|
REG_SZ,
|
|
(BYTE*)szBuffer,
|
|
(lstrlen(szBuffer) + 1) * sizeof(TCHAR));
|
|
|
|
if (lRes != ERROR_SUCCESS) {
|
|
LogMsg(_T("[UpdateRegistryCLSID] failed to write value \"%s\"\n"),
|
|
szBuffer);
|
|
goto Exit;
|
|
}
|
|
|
|
lRes = RegSetValueEx(hkey,
|
|
_T("ThreadingModel"),
|
|
0,
|
|
REG_SZ,
|
|
(BYTE*)_T("Apartment"),
|
|
sizeof(_T("Apartment")));
|
|
|
|
if (lRes != ERROR_SUCCESS) {
|
|
LogMsg(_T("[UpdateRegistryCLSID] failed to write \"ThreadingModel\"\n"));
|
|
goto Exit;
|
|
}
|
|
|
|
RegCloseKey(hkey);
|
|
hkey = NULL;
|
|
|
|
//
|
|
// Open the key with the name of the .exe extension and
|
|
// add the keys to support the shell extensions.
|
|
//
|
|
StringCchPrintf(szBuffer,
|
|
ARRAYSIZE(szBuffer),
|
|
_T("lnkfile\\shellex\\PropertySheetHandlers\\%s"),
|
|
szPropPageExt);
|
|
|
|
lRes = RegCreateKey(HKEY_CLASSES_ROOT, szBuffer, &hkey);
|
|
|
|
if (lRes != ERROR_SUCCESS) {
|
|
goto Exit;
|
|
}
|
|
|
|
lRes = RegSetValueEx(hkey,
|
|
NULL,
|
|
0,
|
|
REG_SZ,
|
|
(BYTE*)lpOleStrCLSIDValue,
|
|
(lstrlen(lpOleStrCLSIDValue) + 1) * sizeof(TCHAR));
|
|
|
|
if (lRes != ERROR_SUCCESS) {
|
|
LogMsg(_T("[UpdateRegistryCLSID] failed to add the shell extension handler\n"));
|
|
goto Exit;
|
|
}
|
|
|
|
RegCloseKey(hkey);
|
|
hkey = NULL;
|
|
|
|
//
|
|
// Now add the shell extension to the approved list.
|
|
//
|
|
lRes = RegCreateKey(HKEY_LOCAL_MACHINE,
|
|
_T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved"),
|
|
&hkey);
|
|
|
|
if (lRes != ERROR_SUCCESS) {
|
|
LogMsg(_T("[UpdateRegistryCLSID] failed to approve the shell extension handler\n"));
|
|
goto Exit;
|
|
}
|
|
|
|
lRes = RegSetValueEx(hkey,
|
|
lpOleStrCLSIDValue,
|
|
0,
|
|
REG_SZ,
|
|
(BYTE*)szPropPageExt,
|
|
sizeof(szPropPageExt));
|
|
|
|
if (lRes != ERROR_SUCCESS) {
|
|
LogMsg(_T("[UpdateRegistryCLSID] failed to approve the shell extension handler\n"));
|
|
goto Exit;
|
|
}
|
|
|
|
Exit:
|
|
if (hkey != NULL) {
|
|
RegCloseKey(hkey);
|
|
hkey = NULL;
|
|
}
|
|
|
|
hRes = HRESULT_FROM_WIN32(lRes);
|
|
|
|
} else {
|
|
//
|
|
// Time to clean up.
|
|
//
|
|
PFNSHDeleteKeyW pfnSHDeleteKey;
|
|
|
|
HMODULE hmod = LoadLibrary(_T("Shlwapi.dll"));
|
|
|
|
if (hmod == NULL) {
|
|
LogMsg(_T("[UpdateRegistryCLSID] failed to load Shlwapi.dll\n"));
|
|
return E_FAIL;
|
|
}
|
|
|
|
pfnSHDeleteKey = (PFNSHDeleteKeyW)GetProcAddress(hmod, "SHDeleteKeyW");
|
|
|
|
if (pfnSHDeleteKey == NULL) {
|
|
FreeLibrary(hmod);
|
|
LogMsg(_T("[UpdateRegistryCLSID] cannot get Shlwapi!SHDeleteKeyW\n"));
|
|
return E_FAIL;
|
|
}
|
|
|
|
lRes = RegOpenKey(HKEY_CLASSES_ROOT, szCLSID, &hkey);
|
|
|
|
if (lRes == ERROR_SUCCESS) {
|
|
(*pfnSHDeleteKey)(hkey, lpOleStrCLSIDValue);
|
|
|
|
RegCloseKey(hkey);
|
|
hkey = NULL;
|
|
}
|
|
|
|
lRes = RegOpenKey(HKEY_CLASSES_ROOT, _T("lnkfile\\shellex"), &hkey);
|
|
|
|
if (lRes == ERROR_SUCCESS) {
|
|
|
|
(*pfnSHDeleteKey)(hkey, _T("PropertySheetHandlers\\ShimLayer Property Page"));
|
|
|
|
RegCloseKey(hkey);
|
|
hkey = NULL;
|
|
}
|
|
|
|
lRes = RegOpenKey(HKEY_LOCAL_MACHINE,
|
|
_T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved"),
|
|
&hkey);
|
|
|
|
if (lRes == ERROR_SUCCESS) {
|
|
RegDeleteValue(hkey, lpOleStrCLSIDValue);
|
|
|
|
RegCloseKey(hkey);
|
|
hkey = NULL;
|
|
}
|
|
|
|
FreeLibrary(hmod);
|
|
}
|
|
|
|
//
|
|
// Delete the layer storage.
|
|
//
|
|
InitLayerStorage(TRUE);
|
|
|
|
//
|
|
// Notify the shell of our changes
|
|
//
|
|
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL);
|
|
|
|
if (lpOleStrCLSIDValue) {
|
|
::CoTaskMemFree(lpOleStrCLSIDValue);
|
|
}
|
|
|
|
|
|
return hRes;
|
|
}
|