diff --git a/ExplorerPatcher/ExplorerPatcher.vcxproj b/ExplorerPatcher/ExplorerPatcher.vcxproj
index d973142..cbad6c5 100644
--- a/ExplorerPatcher/ExplorerPatcher.vcxproj
+++ b/ExplorerPatcher/ExplorerPatcher.vcxproj
@@ -341,6 +341,7 @@
+
diff --git a/ExplorerPatcher/ImmersiveColor.h b/ExplorerPatcher/ImmersiveColor.h
new file mode 100644
index 0000000..5c002fe
--- /dev/null
+++ b/ExplorerPatcher/ImmersiveColor.h
@@ -0,0 +1,108 @@
+#pragma once
+
+#include
+
+enum IMMERSIVE_COLOR_TYPE
+{
+ // Defining only used ones
+ IMCLR_SystemAccentLight2 = 2,
+ IMCLR_SystemAccentDark2 = 6
+};
+
+struct IMMERSIVE_COLOR_PREFERENCE
+{
+ DWORD crStartColor;
+ DWORD crAccentColor;
+};
+
+enum IMMERSIVE_HC_CACHE_MODE
+{
+ IHCM_USE_CACHED_VALUE = 0,
+ IHCM_REFRESH = 1
+};
+
+typedef bool (*RefreshImmersiveColorPolicyState_t)(); // 104
+inline bool RefreshImmersiveColorPolicyState()
+{
+ static RefreshImmersiveColorPolicyState_t fn;
+ if (!fn)
+ {
+ HMODULE h = GetModuleHandleW(L"uxtheme.dll");
+ if (h)
+ fn = (RefreshImmersiveColorPolicyState_t)GetProcAddress(h, MAKEINTRESOURCEA(104));
+ }
+ return fn ? fn() : false;
+}
+
+typedef bool (*GetIsImmersiveColorUsingHighContrast_t)(IMMERSIVE_HC_CACHE_MODE); // 106
+inline bool GetIsImmersiveColorUsingHighContrast(IMMERSIVE_HC_CACHE_MODE mode)
+{
+ static GetIsImmersiveColorUsingHighContrast_t fn;
+ if (!fn)
+ {
+ HMODULE h = GetModuleHandleW(L"uxtheme.dll");
+ if (h)
+ fn = (GetIsImmersiveColorUsingHighContrast_t)GetProcAddress(h, MAKEINTRESOURCEA(106));
+ }
+ return fn ? fn(mode) : false;
+}
+
+typedef HRESULT (*GetUserColorPreference_t)(IMMERSIVE_COLOR_PREFERENCE*, bool); // 120
+inline HRESULT GetUserColorPreference(IMMERSIVE_COLOR_PREFERENCE* pcpColorPreference, bool fForceReload)
+{
+ static GetUserColorPreference_t fn;
+ if (!fn)
+ {
+ HMODULE h = GetModuleHandleW(L"uxtheme.dll");
+ if (h)
+ fn = (GetUserColorPreference_t)GetProcAddress(h, MAKEINTRESOURCEA(120));
+ }
+ return fn ? fn(pcpColorPreference, fForceReload) : E_FAIL;
+}
+
+typedef DWORD (*GetColorFromPreference_t)(const IMMERSIVE_COLOR_PREFERENCE*, IMMERSIVE_COLOR_TYPE, bool, IMMERSIVE_HC_CACHE_MODE); // 121
+inline DWORD GetColorFromPreference(const IMMERSIVE_COLOR_PREFERENCE* cpcpPreference, IMMERSIVE_COLOR_TYPE colorType, bool fNoHighContrast, IMMERSIVE_HC_CACHE_MODE mode)
+{
+ static GetColorFromPreference_t fn;
+ if (!fn)
+ {
+ HMODULE h = GetModuleHandleW(L"uxtheme.dll");
+ if (h)
+ fn = (GetColorFromPreference_t)GetProcAddress(h, MAKEINTRESOURCEA(121));
+ }
+ return fn ? fn(cpcpPreference, colorType, fNoHighContrast, mode) : 0;
+}
+
+class CImmersiveColor
+{
+public:
+ static DWORD GetColor(IMMERSIVE_COLOR_TYPE colorType)
+ {
+ IMMERSIVE_COLOR_PREFERENCE icp;
+ icp.crStartColor = 0;
+ icp.crAccentColor = 0;
+ GetUserColorPreference(&icp, false/*, true*/);
+ return GetColorFromPreference(&icp, colorType, false, IHCM_REFRESH);
+ }
+
+ static bool IsColorSchemeChangeMessage(UINT uMsg, LPARAM lParam)
+ {
+ bool bRet = false;
+ if (uMsg == WM_SETTINGCHANGE && lParam && CompareStringOrdinal((WCHAR*)lParam, -1, L"ImmersiveColorSet", -1, TRUE) == CSTR_EQUAL)
+ {
+ RefreshImmersiveColorPolicyState();
+ bRet = true;
+ }
+ GetIsImmersiveColorUsingHighContrast(IHCM_REFRESH);
+ return bRet;
+ }
+};
+
+class CImmersiveColorImpl
+{
+public:
+ static HRESULT GetColorPreferenceImpl(IMMERSIVE_COLOR_PREFERENCE* pcpPreference, bool fForceReload, bool fUpdateCached)
+ {
+ return GetUserColorPreference(pcpPreference, fForceReload);
+ }
+};
diff --git a/ExplorerPatcher/Taskbar10.cpp b/ExplorerPatcher/Taskbar10.cpp
index f738602..62648a5 100644
--- a/ExplorerPatcher/Taskbar10.cpp
+++ b/ExplorerPatcher/Taskbar10.cpp
@@ -1,4 +1,5 @@
#include "utility.h"
+#include "ImmersiveColor.h"
#include
@@ -6,8 +7,6 @@
#include
#include
-extern "C" DWORD (*CImmersiveColor_GetColorFunc)(int colorType);
-
#pragma region "Enable old taskbar"
/***
Our target is in `CTray::Init()`. It constructs either the Windows 11 or the Windows 10 taskbar based on the result of
@@ -242,9 +241,9 @@ DWORD GetTaskbarColor()
if (tt.IsHighContrast())
return GetSysColor(COLOR_WINDOW);
- if (tt.bColorPrevalence && CImmersiveColor_GetColorFunc)
+ if (tt.bColorPrevalence)
{
- DWORD result = CImmersiveColor_GetColorFunc(tt.IsDark() ? 6 /*IMCLR_SystemAccentDark2*/ : 2 /*IMCLR_SystemAccentLight2*/);
+ DWORD result = CImmersiveColor::GetColor(tt.IsDark() ? IMCLR_SystemAccentDark2 : IMCLR_SystemAccentLight2);
if (tt.bEnableTransparency)
return (result & 0xFFFFFF) | 0xCC000000;
return result;
diff --git a/ExplorerPatcher/dllmain.c b/ExplorerPatcher/dllmain.c
index 22194cf..dc45980 100644
--- a/ExplorerPatcher/dllmain.c
+++ b/ExplorerPatcher/dllmain.c
@@ -1606,8 +1606,6 @@ finalize:
#pragma region "Windows 10 Taskbar Hooks"
#ifdef _WIN64
-DWORD (*CImmersiveColor_GetColorFunc)(int colorType);
-
// credits: https://github.com/m417z/7-Taskbar-Tweaker
DEFINE_GUID(IID_ITaskGroup,
@@ -10731,86 +10729,6 @@ inline BOOL FollowJnz(PBYTE pJnz, PBYTE* pTarget, DWORD* pJnzSize)
void TryToFindExplorerOffsets(HANDLE hExplorer, MODULEINFO* pmiExplorer, DWORD* pOffsets)
{
if (!pOffsets[0] || pOffsets[0] == 0xFFFFFFFF)
- {
- // CImmersiveColor::GetColor()
-
- // Ref: Anything `CImmersiveColor::GetColor(colorTheme == CT_Light ? IMCLR_LightAltMediumLow : IMCLR_DarkListLow)`
- // = 1 = 323 = 298
- // 8D 41 19 0F 44 C8 E8 ?? ?? ?? ?? 44 8B
- // ^^^^^^^^^^^
- PBYTE match = FindPattern(
- hExplorer, pmiExplorer->SizeOfImage,
- "\x8D\x41\x19\x0F\x44\xC8\xE8\x00\x00\x00\x00\x44\x8B",
- "xxxxxxx????xx"
- );
- if (match)
- {
- match += 6;
- pOffsets[0] = match + 5 + *(int*)(match + 1) - (PBYTE)hExplorer;
- }
- else
- {
- // Ref: Anything `CImmersiveColor::GetColor(colorTheme != CT_Light ? IMCLR_DarkListLow : IMCLR_LightAltMediumLow)`
- // = 1 = 298 = 323
- // 8D 41 E7 0F 45 C8 E8 ?? ?? ?? ?? 44 8B
- // ^^^^^^^^^^^
- match = FindPattern(
- hExplorer, pmiExplorer->SizeOfImage,
- "\x8D\x41\xE7\x0F\x45\xC8\xE8\x00\x00\x00\x00\x44\x8B",
- "xxxxxxx????xx"
- );
- if (match)
- {
- match += 6;
- pOffsets[0] = match + 5 + *(int*)(match + 1) - (PBYTE)hExplorer;
- }
- }
- if (match)
- {
- printf("explorer.exe!CImmersiveColor::GetColor() = %lX\n", pOffsets[0]);
- }
- }
-
- if (!pOffsets[1] || pOffsets[1] == 0xFFFFFFFF)
- {
- // CImmersiveColor::IsColorSchemeChangeMessage()
- // Ref: Anything `if (CImmersiveColor::IsColorSchemeChangeMessage(WM_SETTINGCHANGE, lParam)) { ... }`
- // = 0x1A
- // B9 1A 00 00 00 E8 ?? ?? ?? ?? 84 C0
- // ^^^^^^^^^^^
- PBYTE match = FindPattern(
- hExplorer, pmiExplorer->SizeOfImage,
- "\xB9\x1A\x00\x00\x00\xE8\x00\x00\x00\x00\x84\xC0",
- "xxxxxx????xx"
- );
- if (match)
- {
- match += 5;
- pOffsets[1] = match + 5 + *(int*)(match + 1) - (PBYTE)hExplorer;
- printf("explorer.exe!CImmersiveColor::IsColorSchemeChangeMessage() = %lX\n", pOffsets[1]);
- }
- }
-
- if (!pOffsets[2] || pOffsets[2] == 0xFFFFFFFF)
- {
- // CImmersiveColorImpl::GetColorPreferenceImpl()
- // Ref: CImmersiveColorImpl::SetColorPreferenceImpl()
- // 48 83 64 24 ?? 00 45 33 C0 33 D2 48 8D 4C 24 ?? E8 ?? ?? ?? ??
- // ^^^^^^^^^^^
- PBYTE match = FindPattern(
- hExplorer, pmiExplorer->SizeOfImage,
- "\x48\x83\x64\x24\x00\x00\x45\x33\xC0\x33\xD2\x48\x8D\x4C\x24\x00\xE8",
- "xxxx?xxxxxxxxxx?x"
- );
- if (match)
- {
- match += 16;
- pOffsets[2] = match + 5 + *(int*)(match + 1) - (PBYTE)hExplorer;
- printf("explorer.exe!CImmersiveColorImpl::GetColorPreferenceImpl() = %lX\n", pOffsets[2]);
- }
- }
-
- if (!pOffsets[3] || pOffsets[3] == 0xFFFFFFFF)
{
// ImmersiveTray::AttachWindowToTray()
// Ref: CTaskListThumbnailWnd::SetSite()
@@ -10824,12 +10742,12 @@ void TryToFindExplorerOffsets(HANDLE hExplorer, MODULEINFO* pmiExplorer, DWORD*
if (match)
{
match += 14;
- pOffsets[3] = match + 5 + *(int*)(match + 1) - (PBYTE)hExplorer;
- printf("explorer.exe!ImmersiveTray::AttachWindowToTray() = %lX\n", pOffsets[3]);
+ pOffsets[0] = match + 5 + *(int*)(match + 1) - (PBYTE)hExplorer;
+ printf("explorer.exe!ImmersiveTray::AttachWindowToTray() = %lX\n", pOffsets[0]);
}
}
- if (!pOffsets[4] || pOffsets[4] == 0xFFFFFFFF)
+ if (!pOffsets[1] || pOffsets[1] == 0xFFFFFFFF)
{
// ImmersiveTray::RaiseWindow()
// Ref: CTaskListThumbnailWnd::_RaiseWindowForLivePreviewIfNeeded()
@@ -10843,12 +10761,12 @@ void TryToFindExplorerOffsets(HANDLE hExplorer, MODULEINFO* pmiExplorer, DWORD*
if (match)
{
match += 13;
- pOffsets[4] = match + 5 + *(int*)(match + 1) - (PBYTE)hExplorer;
- printf("explorer.exe!ImmersiveTray::RaiseWindow() = %lX\n", pOffsets[4]);
+ pOffsets[1] = match + 5 + *(int*)(match + 1) - (PBYTE)hExplorer;
+ printf("explorer.exe!ImmersiveTray::RaiseWindow() = %lX\n", pOffsets[1]);
}
}
- if (!pOffsets[5] || pOffsets[5] == 0xFFFFFFFF)
+ if (!pOffsets[2] || pOffsets[2] == 0xFFFFFFFF)
{
// CTaskBand_CreateInstance()
// Ref: CTrayBandSite::_AddRequiredBands()
@@ -10865,7 +10783,7 @@ void TryToFindExplorerOffsets(HANDLE hExplorer, MODULEINFO* pmiExplorer, DWORD*
if (match)
{
match += 14;
- pOffsets[5] = match + 5 + *(int*)(match + 1) - (PBYTE)hExplorer;
+ pOffsets[2] = match + 5 + *(int*)(match + 1) - (PBYTE)hExplorer;
}
else
{
@@ -10881,16 +10799,16 @@ void TryToFindExplorerOffsets(HANDLE hExplorer, MODULEINFO* pmiExplorer, DWORD*
if (match)
{
match += 13;
- pOffsets[5] = match + 5 + *(int*)(match + 1) - (PBYTE)hExplorer;
+ pOffsets[2] = match + 5 + *(int*)(match + 1) - (PBYTE)hExplorer;
}
}
if (match)
{
- printf("explorer.exe!CTaskBand_CreateInstance() = %lX\n", pOffsets[5]);
+ printf("explorer.exe!CTaskBand_CreateInstance() = %lX\n", pOffsets[2]);
}
}
- if (!pOffsets[6] || pOffsets[6] == 0xFFFFFFFF)
+ if (!pOffsets[3] || pOffsets[3] == 0xFFFFFFFF)
{
// HandleFirstTimeLegacy()
// Ref: TrayUI::WndProc()
@@ -10907,7 +10825,7 @@ void TryToFindExplorerOffsets(HANDLE hExplorer, MODULEINFO* pmiExplorer, DWORD*
if (match)
{
match += 11;
- pOffsets[6] = match + 5 + *(int*)(match + 1) - (PBYTE)hExplorer;
+ pOffsets[3] = match + 5 + *(int*)(match + 1) - (PBYTE)hExplorer;
}
else
{
@@ -10923,16 +10841,16 @@ void TryToFindExplorerOffsets(HANDLE hExplorer, MODULEINFO* pmiExplorer, DWORD*
if (match)
{
match += 15;
- pOffsets[6] = match + 5 + *(int*)(match + 1) - (PBYTE)hExplorer;
+ pOffsets[3] = match + 5 + *(int*)(match + 1) - (PBYTE)hExplorer;
}
}
if (match)
{
- printf("explorer.exe!HandleFirstTimeLegacy() = %lX\n", pOffsets[6]);
+ printf("explorer.exe!HandleFirstTimeLegacy() = %lX\n", pOffsets[3]);
}
}
- if (!pOffsets[7] || pOffsets[7] == 0xFFFFFFFF)
+ if (!pOffsets[4] || pOffsets[4] == 0xFFFFFFFF)
{
// SetColorPreferenceForLogonUI()
// Ref: TrayUI::_HandleSettingChange()
@@ -10946,8 +10864,8 @@ void TryToFindExplorerOffsets(HANDLE hExplorer, MODULEINFO* pmiExplorer, DWORD*
if (match)
{
match += 17;
- pOffsets[7] = match + 5 + *(int*)(match + 1) - (PBYTE)hExplorer;
- printf("explorer.exe!SetColorPreferenceForLogonUI() = %lX\n", pOffsets[7]);
+ pOffsets[4] = match + 5 + *(int*)(match + 1) - (PBYTE)hExplorer;
+ printf("explorer.exe!SetColorPreferenceForLogonUI() = %lX\n", pOffsets[4]);
}
}
}
@@ -11911,13 +11829,13 @@ BOOL CrashCounterHandleEntryPoint()
BOOL CheckExplorerSymbols(symbols_addr* symbols_PTRS)
{
BOOL bAllValid = TRUE;
- for (SIZE_T j = 0; j < ARRAYSIZE(symbols_PTRS->explorer_PTRS) - 1; ++j)
+ /*for (SIZE_T j = 0; j < ARRAYSIZE(symbols_PTRS->explorer_PTRS) - 1; ++j)
{
DWORD i = symbols_PTRS->explorer_PTRS[j];
bAllValid &= i && i != 0xFFFFFFFF;
if (!bAllValid)
break;
- }
+ }*/
return bAllValid;
}
@@ -11963,7 +11881,7 @@ void PrepareAlternateTaskbarImplementation(symbols_addr* symbols_PTRS, const WCH
typedef DWORD (*GetVersion_t)();
GetVersion_t GetVersion = (GetVersion_t)GetProcAddress(hMyTaskbar, "GetVersion");
DWORD version = GetVersion ? GetVersion() : 0;
- if (version != 1)
+ if (version != 2)
{
wprintf(L"[TB] '%s' with version %d is not compatible\n", pszTaskbarDll, version);
return;
@@ -12450,11 +12368,6 @@ DWORD Inject(BOOL bIsExplorer)
{
TryToFindExplorerOffsets(hExplorer, &miExplorer, symbols_PTRS.explorer_PTRS);
- if (symbols_PTRS.explorer_PTRS[0] && symbols_PTRS.explorer_PTRS[0] != 0xFFFFFFFF)
- {
- CImmersiveColor_GetColorFunc = (DWORD(*)(int))((uintptr_t)hExplorer + symbols_PTRS.explorer_PTRS[0]);
- }
-
#if 0
if (global_rovi.dwBuildNumber >= 26002)
{
@@ -12599,9 +12512,9 @@ DWORD Inject(BOOL bIsExplorer)
// Enable Windows 10 taskbar search box on 22621+
if (IsWindows11Version22H2OrHigher())
{
- if (symbols_PTRS.explorer_PTRS[8] && symbols_PTRS.explorer_PTRS[8] != 0xFFFFFFFF)
+ if (symbols_PTRS.explorer_PTRS[5] && symbols_PTRS.explorer_PTRS[5] != 0xFFFFFFFF)
{
- TrayUI__UpdatePearlSizeFunc = (PBYTE)hExplorer + symbols_PTRS.explorer_PTRS[8];
+ TrayUI__UpdatePearlSizeFunc = (PBYTE)hExplorer + symbols_PTRS.explorer_PTRS[5];
}
UpdateSearchBox();
}
diff --git a/ExplorerPatcher/symbols.c b/ExplorerPatcher/symbols.c
index 57a6ec7..8704a73 100644
--- a/ExplorerPatcher/symbols.c
+++ b/ExplorerPatcher/symbols.c
@@ -6,10 +6,7 @@ const char* explorer_SN[EXPLORER_SB_CNT] = {
EXPLORER_SB_2,
EXPLORER_SB_3,
EXPLORER_SB_4,
- EXPLORER_SB_5,
- EXPLORER_SB_6,
- EXPLORER_SB_7,
- EXPLORER_SB_8
+ EXPLORER_SB_5
};
const char* twinui_pcshell_SN[TWINUI_PCSHELL_SB_CNT] = {
TWINUI_PCSHELL_SB_0,
@@ -134,9 +131,6 @@ static BOOL ProcessExplorerSymbols(const char* pszSettingsPath, DWORD* pOffsets)
RegSetValueExW(hKey, TEXT(EXPLORER_SB_3), 0, REG_DWORD, &pOffsets[3], sizeof(DWORD));
RegSetValueExW(hKey, TEXT(EXPLORER_SB_4), 0, REG_DWORD, &pOffsets[4], sizeof(DWORD));
RegSetValueExW(hKey, TEXT(EXPLORER_SB_5), 0, REG_DWORD, &pOffsets[5], sizeof(DWORD));
- RegSetValueExW(hKey, TEXT(EXPLORER_SB_6), 0, REG_DWORD, &pOffsets[6], sizeof(DWORD));
- RegSetValueExW(hKey, TEXT(EXPLORER_SB_7), 0, REG_DWORD, &pOffsets[7], sizeof(DWORD));
- RegSetValueExW(hKey, TEXT(EXPLORER_SB_8), 0, REG_DWORD, &pOffsets[8], sizeof(DWORD));
RegSetValueExA(hKey, "Hash", 0, REG_SZ, szHash, strlen(szHash) + 1);
SaveVersion(hKey, EXPLORER_SB_VERSION);
@@ -672,9 +666,6 @@ LoadSymbolsResult LoadSymbols(symbols_addr* symbols_PTRS)
RegQueryValueExW(hKey, TEXT(EXPLORER_SB_3), 0, NULL, &symbols_PTRS->explorer_PTRS[3], &dwSize);
RegQueryValueExW(hKey, TEXT(EXPLORER_SB_4), 0, NULL, &symbols_PTRS->explorer_PTRS[4], &dwSize);
RegQueryValueExW(hKey, TEXT(EXPLORER_SB_5), 0, NULL, &symbols_PTRS->explorer_PTRS[5], &dwSize);
- RegQueryValueExW(hKey, TEXT(EXPLORER_SB_6), 0, NULL, &symbols_PTRS->explorer_PTRS[6], &dwSize);
- RegQueryValueExW(hKey, TEXT(EXPLORER_SB_7), 0, NULL, &symbols_PTRS->explorer_PTRS[7], &dwSize);
- RegQueryValueExW(hKey, TEXT(EXPLORER_SB_8), 0, NULL, &symbols_PTRS->explorer_PTRS[8], &dwSize);
bOffsetsValid = TRUE;
}
else
diff --git a/ExplorerPatcher/symbols.h b/ExplorerPatcher/symbols.h
index 4467f2f..3b06c28 100644
--- a/ExplorerPatcher/symbols.h
+++ b/ExplorerPatcher/symbols.h
@@ -14,17 +14,14 @@
#define EXIT_CODE_EXPLORER 1
#define EXPLORER_SB_NAME "explorer"
-#define EXPLORER_SB_0 "CImmersiveColor::GetColor"
-#define EXPLORER_SB_1 "CImmersiveColor::IsColorSchemeChangeMessage"
-#define EXPLORER_SB_2 "CImmersiveColorImpl::GetColorPreferenceImpl"
-#define EXPLORER_SB_3 "ImmersiveTray::AttachWindowToTray"
-#define EXPLORER_SB_4 "ImmersiveTray::RaiseWindow"
-#define EXPLORER_SB_5 "CTaskBand_CreateInstance"
-#define EXPLORER_SB_6 "HandleFirstTimeLegacy"
-#define EXPLORER_SB_7 "SetColorPreferenceForLogonUI"
-#define EXPLORER_SB_8 "TrayUI::_UpdatePearlSize"
-#define EXPLORER_SB_CNT 9
-#define EXPLORER_SB_VERSION 2
+#define EXPLORER_SB_0 "ImmersiveTray::AttachWindowToTray"
+#define EXPLORER_SB_1 "ImmersiveTray::RaiseWindow"
+#define EXPLORER_SB_2 "CTaskBand_CreateInstance"
+#define EXPLORER_SB_3 "HandleFirstTimeLegacy"
+#define EXPLORER_SB_4 "SetColorPreferenceForLogonUI"
+#define EXPLORER_SB_5 "TrayUI::_UpdatePearlSize"
+#define EXPLORER_SB_CNT 6
+#define EXPLORER_SB_VERSION 3
#define TWINUI_PCSHELL_SB_NAME "twinui.pcshell"
#define TWINUI_PCSHELL_SB_0 "CImmersiveContextMenuOwnerDrawHelper::s_ContextMenuWndProc"
diff --git a/ExplorerPatcher/utility.h b/ExplorerPatcher/utility.h
index 45ef3eb..100327b 100644
--- a/ExplorerPatcher/utility.h
+++ b/ExplorerPatcher/utility.h
@@ -265,8 +265,6 @@ static bool(*ShouldSystemUseDarkMode)();
static void(*GetThemeName)(void*, void*, void*);
-extern DWORD (*CImmersiveColor_GetColorFunc)(int colorType);
-
void* ReadFromFile(wchar_t* wszFileName, DWORD* dwSize);
int ComputeFileHash(LPCWSTR filename, LPSTR hash, DWORD dwHash);