[ACPPAGE] Implement the base of the compatibility tab in explorer as shell extension.
[reactos.git] / reactos / dll / shellext / acppage / ACPPage.cpp
1 /*
2 * Copyright 2015 Mark Jansen
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17 */
18
19 #include "precomp.h"
20
21 HMODULE g_hModule = NULL;
22 LONG g_ModuleRefCnt = 0;
23
24 class CLayerUIPropPageModule : public CComModule
25 {
26 public:
27 void Term()
28 {
29 CComModule::Term();
30 }
31 };
32
33 BEGIN_OBJECT_MAP(ObjectMap)
34 OBJECT_ENTRY(CLSID_CLayerUIPropPage, CLayerUIPropPage)
35 END_OBJECT_MAP()
36
37 CLayerUIPropPageModule gModule;
38
39 EXTERN_C
40 BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
41 {
42 switch (dwReason)
43 {
44 case DLL_PROCESS_ATTACH:
45 DisableThreadLibraryCalls(hInstance);
46 g_hModule = hInstance;
47 gModule.Init(ObjectMap, hInstance, NULL);
48 break;
49 }
50
51 return(TRUE);
52 }
53
54 STDAPI DllCanUnloadNow()
55 {
56 if (g_ModuleRefCnt)
57 return S_FALSE;
58 return gModule.DllCanUnloadNow();
59 }
60
61 STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
62 {
63 return gModule.DllGetClassObject(rclsid, riid, ppv);
64 }
65
66 STDAPI DllRegisterServer()
67 {
68 HRESULT hr;
69
70 hr = gModule.DllRegisterServer(FALSE);
71 if (FAILED(hr))
72 return hr;
73
74 hr = gModule.UpdateRegistryFromResource(IDR_ACPPAGE, TRUE, NULL);
75 if (FAILED(hr))
76 return hr;
77
78 return S_OK;
79 }
80
81 STDAPI DllUnregisterServer()
82 {
83 HRESULT hr;
84
85 hr = gModule.DllUnregisterServer(FALSE);
86 if (FAILED(hr))
87 return hr;
88
89 hr = gModule.UpdateRegistryFromResource(IDR_ACPPAGE, FALSE, NULL);
90 if (FAILED(hr))
91 return hr;
92
93 return S_OK;
94 }
95
96 struct CCoInit
97 {
98 CCoInit() { hres = CoInitialize(NULL); }
99 ~CCoInit() { if (SUCCEEDED(hres)) { CoUninitialize(); } }
100 HRESULT hres;
101 };
102
103 EXTERN_C
104 BOOL WINAPI GetExeFromLnk(PCWSTR pszLnk, PWSTR pszExe, size_t cchSize)
105 {
106 CCoInit init;
107 if (FAILED(init.hres))
108 return FALSE;
109
110 CComPtr<IShellLinkW> spShellLink;
111 if (FAILED(CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IShellLinkW, &spShellLink))))
112 return FALSE;
113
114 CComPtr<IPersistFile> spPersistFile;
115 if (FAILED(spShellLink->QueryInterface(IID_PPV_ARG(IPersistFile, &spPersistFile))))
116 return FALSE;
117
118 if (FAILED(spPersistFile->Load(pszLnk, STGM_READ)) || FAILED(spShellLink->Resolve(NULL, SLR_NO_UI | SLR_NOUPDATE | SLR_NOSEARCH)))
119 return FALSE;
120
121 return SUCCEEDED(spShellLink->GetPath(pszExe, cchSize, NULL, SLGP_RAWPATH));
122 }