xref: /reactos/dll/shellext/fontext/fontext.cpp (revision 6b700c6a)
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,2020 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_UNEXPECTEDLY(hr))
63          return hr;
64  
65      hr = SHGetFolderPathW(NULL, CSIDL_FONTS, NULL, 0, Path);
66      if (FAILED_UNEXPECTEDLY(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  }
121