[TASKMGR] Process page: Allow using "Open File Location" functionality without runnin...
[reactos.git] / dll / shellext / fontext / CFontCache.cpp
index 4d3ae5f..53a7a5a 100644 (file)
@@ -2,23 +2,23 @@
  * PROJECT:     ReactOS Font Shell Extension
  * LICENSE:     GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
  * PURPOSE:     font list cache handling
- * COPYRIGHT:   Copyright 2019 Mark Jansen (mark.jansen@reactos.org)
+ * COPYRIGHT:   Copyright 2019-2021 Mark Jansen <mark.jansen@reactos.org>
  */
 
 #include "precomp.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(fontext);
 
-
-#define FONT_HIVE   HKEY_LOCAL_MACHINE
-#define FONT_KEY    L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts"
-
 CFontCache* g_FontCache = NULL;
 
 CFontInfo::CFontInfo(LPCWSTR name)
     : m_Name(name)
     , m_FileRead(false)
+    , m_AttrsRead(false)
+    , m_FileWriteTime({})
+    , m_dwFileAttributes(0)
 {
+    m_FileSize.QuadPart = 0;
 }
 
 const CStringW& CFontInfo::Name() const
@@ -66,12 +66,63 @@ const CStringW& CFontInfo::File()
     return m_File;
 }
 
+void CFontInfo::ReadAttrs()
+{
+    CStringW File = g_FontCache->Filename(this, true);
+
+    m_AttrsRead = true;
+
+    WIN32_FIND_DATAW findFileData;
+    HANDLE hFile = FindFirstFileW(File, &findFileData);
+    if (hFile != INVALID_HANDLE_VALUE)
+    {
+
+        // File write time
+        FileTimeToLocalFileTime(&findFileData.ftLastWriteTime, &m_FileWriteTime);
+
+        // File size
+        m_FileSize.HighPart = findFileData.nFileSizeHigh;
+        m_FileSize.LowPart = findFileData.nFileSizeLow;
+
+        m_dwFileAttributes = findFileData.dwFileAttributes;
+        FindClose(hFile);
+    }
+}
+
+const LARGE_INTEGER& CFontInfo::FileSize()
+{
+    if (!m_AttrsRead)
+        ReadAttrs();
+
+    return m_FileSize;
+}
+
+const FILETIME& CFontInfo::FileWriteTime()
+{
+    if (!m_AttrsRead)
+        ReadAttrs();
 
+    return m_FileWriteTime;
+}
+
+DWORD CFontInfo::FileAttributes()
+{
+    if (!m_AttrsRead)
+        ReadAttrs();
+
+    return m_dwFileAttributes;
+}
 
 CFontCache::CFontCache()
 {
 }
 
+void CFontCache::SetFontDir(const LPCWSTR Path)
+{
+    if (m_FontFolderPath.IsEmpty())
+        m_FontFolderPath = Path;
+}
+
 size_t CFontCache::Size()
 {
     if (m_Fonts.GetCount() == 0u)
@@ -91,23 +142,43 @@ CStringW CFontCache::Name(size_t Index)
     return m_Fonts[Index].Name();
 }
 
-CStringW CFontCache::Filename(const FontPidlEntry* fontEntry)
+CFontInfo* CFontCache::Find(const FontPidlEntry* fontEntry)
 {
     if (fontEntry->Index < m_Fonts.GetCount())
     {
-        CFontInfo& info = m_Fonts[fontEntry->Index];
-
-        if (info.Name().CompareNoCase(fontEntry->Name) == 0)
-            return info.File();
+        if (m_Fonts[fontEntry->Index].Name().CompareNoCase(fontEntry->Name) == 0)
+            return &m_Fonts[fontEntry->Index];
     }
 
     for (UINT n = 0; n < Size(); ++n)
     {
         if (m_Fonts[n].Name().CompareNoCase(fontEntry->Name) == 0)
-            return m_Fonts[n].File();
+        {
+            return &m_Fonts[n];
+        }
+    }
+    return nullptr;
+}
+
+
+CStringW CFontCache::Filename(CFontInfo* info, bool alwaysFullPath)
+{
+    CStringW File;
+    if (info)
+    {
+        File = info->File();
+
+        if (!File.IsEmpty() && alwaysFullPath)
+        {
+            // Ensure this is a full path
+            if (PathIsRelativeW(File))
+            {
+                File = m_FontFolderPath + File;
+            }
+        }
     }
 
-    return CStringW();
+    return File;
 }
 
 void CFontCache::Insert(CAtlList<CFontInfo>& fonts, const CStringW& KeyName)