[FONTEXT] Initial implementation
[reactos.git] / dll / shellext / fontext / fontext.cpp
1 /*
2 * PROJECT: ReactOS Font Shell Extension
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: Shell extension entry point
5 * COPYRIGHT: Copyright 2019 Mark Jansen (mark.jansen@reactos.org)
6 */
7
8 #include "precomp.h"
9
10 WINE_DEFAULT_DEBUG_CHANNEL(fontext);
11
12 const GUID CLSID_CFontExt = { 0xbd84b380, 0x8ca2, 0x1069, { 0xab, 0x1d, 0x08, 0x00, 0x09, 0x48, 0xf5, 0x34 } };
13
14
15 class CFontExtModule : public CComModule
16 {
17 public:
18 void Init(_ATL_OBJMAP_ENTRY *p, HINSTANCE h, const GUID *plibid)
19 {
20 g_FontCache = new CFontCache();
21 CComModule::Init(p, h, plibid);
22 }
23
24 void Term()
25 {
26 delete g_FontCache;
27 g_FontCache = NULL;
28 CComModule::Term();
29 }
30 };
31
32 BEGIN_OBJECT_MAP(ObjectMap)
33 OBJECT_ENTRY(CLSID_CFontExt, CFontExt)
34 END_OBJECT_MAP()
35
36
37 LONG g_ModuleRefCnt;
38 CFontExtModule gModule;
39
40
41 STDAPI DllCanUnloadNow()
42 {
43 if (g_ModuleRefCnt)
44 return S_FALSE;
45 return gModule.DllCanUnloadNow();
46 }
47
48 STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
49 {
50 return gModule.DllGetClassObject(rclsid, riid, ppv);
51 }
52
53
54 STDAPI DllRegisterServer()
55 {
56 WCHAR Path[MAX_PATH] = { 0 };
57 static const char DesktopIniContents[] = "[.ShellClassInfo]\r\nCLSID={BD84B380-8CA2-1069-AB1D-08000948F534}\r\n";
58 HANDLE hFile;
59 HRESULT hr;
60
61 hr = gModule.DllRegisterServer(FALSE);
62 if (FAILED(hr))
63 return hr;
64
65 hr = SHGetFolderPathW(NULL, CSIDL_FONTS, NULL, 0, Path);
66 if (FAILED(hr))
67 return hr;
68
69 // Make this a system folder:
70 // Ideally this should not be done here, but when installing
71 // Otherwise, livecd won't have this set properly
72 DWORD dwAttributes = GetFileAttributesW(Path);
73 if (dwAttributes != INVALID_FILE_ATTRIBUTES)
74 {
75 dwAttributes |= FILE_ATTRIBUTE_SYSTEM;
76 SetFileAttributesW(Path, dwAttributes);
77 }
78 else
79 {
80 ERR("Unable to get attributes for fonts folder (%d)\n", GetLastError());
81 }
82
83 if (!PathAppendW(Path, L"desktop.ini"))
84 return E_FAIL;
85
86 hFile = CreateFileW(Path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN, NULL);
87 if (hFile == INVALID_HANDLE_VALUE)
88 return HRESULT_FROM_WIN32(GetLastError());
89
90 DWORD BytesWritten, BytesToWrite = strlen(DesktopIniContents);
91 if (WriteFile(hFile, DesktopIniContents, (DWORD)BytesToWrite, &BytesWritten, NULL))
92 hr = (BytesToWrite == BytesWritten) ? S_OK : E_FAIL;
93 else
94 hr = HRESULT_FROM_WIN32(GetLastError());
95 CloseHandle(hFile);
96 return hr;
97 }
98
99 STDAPI DllUnregisterServer()
100 {
101 return gModule.DllUnregisterServer(FALSE);
102 }
103
104
105 EXTERN_C
106 BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
107 {
108 switch (dwReason)
109 {
110 case DLL_PROCESS_ATTACH:
111 DisableThreadLibraryCalls(hInstance);
112 gModule.Init(ObjectMap, hInstance, NULL);
113 break;
114 case DLL_PROCESS_DETACH:
115 gModule.Term();
116 break;
117 }
118
119 return TRUE;
120 }