Browse Source

WinX: Revised patch method, hide/unhide Terminal entries accordingly, and updated ARM64 patterns

pull/4392/head
Amrsatrio 7 months ago
parent
commit
1b20cbd342
  1. 8
      ExplorerPatcher/ExplorerPatcher.vcxproj
  2. 647
      ExplorerPatcher/TwinUIPatches.cpp
  3. 86
      ExplorerPatcher/inc/ContainerPolicies.h
  4. 906
      ExplorerPatcher/inc/NativeString.h
  5. 46
      ExplorerPatcher/inc/RefCountedObject.h
  6. 29
      ExplorerPatcher/inc/ResultUtils.h
  7. 583
      ExplorerPatcher/inc/SimpleArray.h
  8. 720
      ExplorerPatcher/inc/memsafe.h
  9. 142
      ExplorerPatcher/symbols.c
  10. 18
      ExplorerPatcher/symbols.h

8
ExplorerPatcher/ExplorerPatcher.vcxproj

@ -132,7 +132,7 @@ @@ -132,7 +132,7 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(SolutionDir)libs\funchook\include;$(SolutionDir)libs\libvalinet;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>inc;$(SolutionDir)libs\funchook\include;$(SolutionDir)libs\libvalinet;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<LanguageStandard>stdcpp20</LanguageStandard>
<UseFullPaths>false</UseFullPaths>
</ClCompile>
@ -301,6 +301,12 @@ @@ -301,6 +301,12 @@
<ClInclude Include="TaskbarCenter.h" />
<ClInclude Include="updates.h" />
<ClInclude Include="utility.h" />
<ClInclude Include="inc\ContainerPolicies.h" />
<ClInclude Include="inc\memsafe.h" />
<ClInclude Include="inc\NativeString.h" />
<ClInclude Include="inc\RefCountedObject.h" />
<ClInclude Include="inc\ResultUtils.h" />
<ClInclude Include="inc\SimpleArray.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="ExplorerPatcher.rc" />

647
ExplorerPatcher/TwinUIPatches.cpp

File diff suppressed because it is too large Load Diff

86
ExplorerPatcher/inc/ContainerPolicies.h

@ -0,0 +1,86 @@ @@ -0,0 +1,86 @@
#pragma once
#include <Windows.h>
#include <memsafe.h>
template<typename T>
class CTContainer_PolicyUnOwned
{
public:
static void Destroy(T* p) {}
};
template<typename T>
class CTContainer_PolicyRelease
{
public:
static void Destroy(T* p)
{
if (p)
p->Release();
}
};
class CTContainer_PolicyNewMem
{
public:
template<typename T>
static void Destroy(T* p)
{
delete p;
}
};
class CTContainer_PolicyCoTaskMem
{
public:
static void Destroy(void* p)
{
CoTaskMemFree(p);
}
};
class CTContainer_PolicyLocalMem
{
public:
static void Destroy(void* p)
{
DestroyMem(p);
}
static BOOL DestroyMem(void* p)
{
return !LocalFree(p);
}
};
template <typename T>
class CTPolicyCoTaskMem : CTContainer_PolicyCoTaskMem
{
public:
static void Destroy(void* p)
{
CTContainer_PolicyCoTaskMem::Destroy(p);
}
static HRESULT ReallocArray(T* pv, size_t cItems, T** ppv)
{
return CoReallocArray(pv, cItems, ppv);
}
};
template <typename T>
class CTPolicyLocalMem : CTContainer_PolicyLocalMem
{
public:
static void Destroy(void* p)
{
DestroyMem(p);
}
static HRESULT ReallocArray(T* pv, size_t cItems, T** ppv)
{
return LocalReallocArray(pv, cItems, ppv);
}
};

906
ExplorerPatcher/inc/NativeString.h

@ -0,0 +1,906 @@ @@ -0,0 +1,906 @@
#pragma once
#include <intsafe.h>
#include <strsafe.h>
#include "ResultUtils.h"
namespace Windows::Internal
{
class ResourceString
{
public:
static bool FindAndSize(HINSTANCE hInstance, UINT uId, WORD wLanguage, const WCHAR** ppch, WORD* plen)
{
bool fRet = false;
*ppch = nullptr;
if (plen)
*plen = 0;
HRSRC hRes = FindResourceExW(hInstance, RT_STRING, MAKEINTRESOURCEW((uId >> 4) + 1), wLanguage);
if (hRes)
{
HGLOBAL hStringSeg = LoadResource(hInstance, hRes);
if (hStringSeg)
{
WCHAR* pch = (WCHAR*)LockResource(hStringSeg);
if (pch)
{
for (uId = (char)uId & 0xF; uId; --uId)
pch += *pch + 1;
*ppch = *pch ? pch + 1 : L"";
if (plen)
*plen = *pch;
fRet = true;
}
}
}
return fRet;
}
};
template <typename ElementType>
class CoTaskMemPolicy
{
public:
static ElementType* Alloc(size_t bytes)
{
return (ElementType*)CoTaskMemAlloc(bytes);
}
static ElementType* Realloc(ElementType* p, size_t bytes)
{
return (ElementType*)CoTaskMemRealloc(p, bytes);
}
static void Free(ElementType* p)
{
CoTaskMemFree(p);
}
};
template <typename ElementType>
class LocalMemPolicy
{
public:
static ElementType* Alloc(size_t bytes)
{
return (ElementType*)LocalAlloc(LMEM_FIXED, bytes);
}
static ElementType* Realloc(ElementType* p, size_t bytes)
{
return (ElementType*)LocalReAlloc(p, bytes, LMEM_MOVEABLE);
}
static void Free(ElementType* p)
{
LocalFree(p);
}
};
template <typename Allocator>
class NativeString
{
public:
NativeString() : _pszStringData(nullptr), _cchStringData(0), _cchStringDataCapacity(0)
{
}
NativeString(NativeString&& other) noexcept
: _pszStringData(other._pszStringData)
, _cchStringData(other._cchStringData)
, _cchStringDataCapacity(other._cchStringDataCapacity)
{
other._pszStringData = nullptr;
other._cchStringData = 0;
other._cchStringDataCapacity = 0;
}
private:
NativeString(const NativeString&) = delete;
public:
~NativeString()
{
Free();
}
HRESULT Initialize(const WCHAR* psz, const size_t cch)
{
return _Initialize(psz, cch);
}
HRESULT Initialize(const WCHAR* psz)
{
return _Initialize(psz, s_cchUnknown);
}
HRESULT Initialize(const NativeString& other)
{
return _Initialize(other._pszStringData, other.GetCount());
}
HRESULT Initialize(HINSTANCE hInstance, UINT uId, WORD wLanguage)
{
HRESULT hr;
const WCHAR* rgch;
WORD cch;
if (ResourceString::FindAndSize(hInstance, uId, wLanguage, &rgch, &cch))
{
hr = _Initialize(rgch, cch);
}
else
{
hr = E_FAIL;
}
return hr;
}
HRESULT Initialize(HINSTANCE hInstance, UINT uId)
{
return Initialize(hInstance, uId, MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL));
}
HRESULT Initialize(HKEY hKey, const WCHAR* pszValueName)
{
return _InitializeFromRegistry(hKey, pszValueName, true);
}
HRESULT Initialize(HKEY hKey, const WCHAR* pszSubKey, const WCHAR* pszValueName)
{
HKEY hkeySub;
HRESULT hr = HRESULT_FROM_WIN32(RegOpenKeyExW(hKey, pszSubKey, 0, KEY_READ, &hkeySub));
if (SUCCEEDED(hr))
{
hr = Initialize(hkeySub, pszValueName);
RegCloseKey(hkeySub);
}
return hr;
}
HRESULT InitializeNoExpand(HKEY hKey, const WCHAR* pszValueName)
{
return _InitializeFromRegistry(hKey, pszValueName, false);
}
HRESULT InitializeNoExpand(HKEY hKey, const WCHAR* pszSubKey, const WCHAR* pszValueName)
{
HKEY hkeySub;
HRESULT hr = HRESULT_FROM_WIN32(RegOpenKeyExW(hKey, pszSubKey, 0, KEY_READ, &hkeySub));
if (SUCCEEDED(hr))
{
hr = InitializeNoExpand(hkeySub, pszValueName);
RegCloseKey(hkeySub);
}
return hr;
}
HRESULT InitializeFormat(const WCHAR* pszFormat, va_list argList)
{
return _InitializeHelper(pszFormat, argList, [](const WCHAR* pszFormat, va_list argList, WCHAR* pszStringData, size_t cchStringData) -> HRESULT
{
_set_errno(0);
HRESULT hr = StringCchVPrintfW(pszStringData, cchStringData, pszFormat, argList);
if (hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER))
{
errno_t err;
_get_errno(&err);
if (err == EINVAL)
{
hr = E_INVALIDARG;
}
}
return hr;
});
}
HRESULT InitializeFormat(const WCHAR* pszFormat, ...)
{
va_list args;
va_start(args, pszFormat);
return InitializeFormat(pszFormat, args);
}
HRESULT InitializeResFormat(HINSTANCE hInstance, UINT uId, ...)
{
va_list argList;
va_start(argList, uId);
NativeString spszFormat;
HRESULT hr = spszFormat.Initialize(hInstance, uId);
if (SUCCEEDED(hr))
{
hr = InitializeFormat(spszFormat._pszStringData, argList);
}
return hr;
}
HRESULT InitializeResMessage(HINSTANCE hInstance, UINT uId, ...)
{
va_list argList;
va_start(argList, uId);
NativeString spszFormat;
HRESULT hr = spszFormat.Initialize(hInstance, uId);
if (SUCCEEDED(hr))
{
hr = _InitializeHelper(spszFormat._pszStringData, argList, [](const WCHAR* pszFormat, va_list argList, WCHAR* pszStringData, size_t cchStringData) -> HRESULT
{
va_list argListT = argList;
DWORD cchResult = FormatMessageW(FORMAT_MESSAGE_FROM_STRING, pszFormat, 0, 0, pszStringData, (DWORD)cchStringData, &argListT);
return ResultFromWin32Bool(cchResult);
});
}
return hr;
}
void Free()
{
_Free();
}
void Attach(WCHAR* psz)
{
_Attach(psz);
}
void Attach(WCHAR* psz, const size_t cch)
{
_Attach(psz, cch);
}
WCHAR* Detach()
{
return _Detach();
}
HRESULT DetachInitializeIfEmpty(WCHAR** ppsz)
{
*ppsz = nullptr;
HRESULT hr = S_OK;
if (_pszStringData)
{
hr = Initialize(L"");
}
if (SUCCEEDED(hr))
{
*ppsz = Detach();
}
return hr;
}
WCHAR** FreeAndGetAddressOf()
{
return _FreeAndGetAddressOf();
}
HRESULT CopyTo(WCHAR** ppszDest) const
{
HRESULT hr;
*ppszDest = nullptr;
if (_pszStringData)
{
NativeString spszT;
hr = spszT.Initialize(*this);
if (SUCCEEDED(hr))
{
*ppszDest = spszT.Detach();
}
}
else
{
hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
}
return hr;
}
HRESULT CopyTo(WCHAR* pszDest, size_t cchDest) const
{
if (!_pszStringData)
{
if (cchDest)
*pszDest = 0;
return HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
}
return StringCchCopyW(pszDest, cchDest, _pszStringData);
}
const WCHAR* Get() const
{
return _Get();
}
const WCHAR* GetNonNull() const
{
return _pszStringData ? _pszStringData : L"";
}
size_t GetCount()
{
return _GetCount();
}
size_t GetCount() const
{
return _GetCount();
}
bool IsEmpty() const
{
return _IsEmpty();
}
bool HasLength() const
{
return !_IsEmpty();
}
int CompareOrdinal(const WCHAR* psz, const size_t cch) const
{
return CompareStringOrdinal(GetNonNull(), (int)GetCount(), psz ? psz : L"", psz ? (int)cch : 0, FALSE);
}
int CompareOrdinal(const WCHAR* psz) const
{
return CompareOrdinal(psz, s_cchUnknown);
}
int CompareOrdinal(const NativeString& other) const
{
return CompareOrdinal(other.GetNonNull(), other.GetCount());
}
int CompareOrdinalIgnoreCase(const WCHAR* psz, const size_t cch) const
{
return CompareStringOrdinal(GetNonNull(), (int)GetCount(), psz ? psz : L"", psz ? (int)cch : 0, TRUE);
}
int CompareOrdinalIgnoreCase(const WCHAR* psz) const
{
return CompareOrdinalIgnoreCase(psz, s_cchUnknown);
}
int CompareOrdinalIgnoreCase(const NativeString& other) const
{
return CompareOrdinalIgnoreCase(other.GetNonNull(), other.GetCount());
}
HRESULT Concat(const WCHAR* psz, const size_t cch)
{
return _Concat(psz, cch);
}
HRESULT Concat(WCHAR c)
{
return _Concat(c);
}
HRESULT Concat(const WCHAR* psz)
{
return _Concat(psz, psz ? wcslen(psz) : 0);
}
HRESULT Concat(const NativeString& other)
{
return _Concat(other.Get(), other.GetCount());
}
HRESULT Concat(HINSTANCE hInstance, UINT uId, WORD wLanguage)
{
HRESULT hr;
const WCHAR* rgch;
WORD cch;
if (ResourceString::FindAndSize(hInstance, uId, wLanguage, &rgch, &cch))
{
hr = _Concat(rgch, cch);
}
else
{
hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
}
return hr;
}
HRESULT Concat(HINSTANCE hInstance, UINT uId)
{
return Concat(hInstance, uId, MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL));
}
HRESULT ConcatFormat(const WCHAR* pszFormat, va_list argList)
{
if (IsEmpty())
{
return InitializeFormat(pszFormat, argList);
}
NativeString strT;
HRESULT hr = strT.InitializeFormat(pszFormat, argList);
if (SUCCEEDED(hr))
{
hr = Concat(strT);
}
return hr;
}
HRESULT ConcatFormat(const WCHAR* pszFormat, ...)
{
va_list argList;
va_start(argList, pszFormat);
return ConcatFormat(pszFormat, argList);
}
bool RemoveAt(size_t iElem, size_t cchElem)
{
return _RemoveAt(iElem, cchElem);
}
bool TrimStart(const WCHAR* pszTrim)
{
return _TrimStart(pszTrim);
}
bool TrimEnd(const WCHAR* pszTrim)
{
return _TrimEnd(pszTrim);
}
inline static const WCHAR* const s_pszTrimWhitespaceCharacterSet =
L"\u0020" // Space
L"\u0009" // Tab
L"\u3000" // Ideographic Space
L"\u17D2" // Khmer Sign Coeng
L"\u0F0B" // Tibetan Mark Intersyllabic Tsheg
L"\u1680" // Ogham Space Mark
L"\u180E" // Mongolian Vowel Separator
;
bool TrimWhitespace()
{
bool fWasCharacterTrimmedEnd = _TrimEnd(s_pszTrimWhitespaceCharacterSet);
bool fWasCharacterTrimmedStart = _TrimStart(s_pszTrimWhitespaceCharacterSet);
return fWasCharacterTrimmedStart || fWasCharacterTrimmedEnd;
}
void ReplaceChars(const WCHAR wcFind, const WCHAR wcReplace)
{
_EnsureCount();
for (size_t i = 0; i < _cchStringData; i++)
{
if (_pszStringData[i] == wcFind)
_pszStringData[i] = wcReplace;
}
}
NativeString& operator=(NativeString&& other) noexcept
{
_Free();
_pszStringData = other._pszStringData;
_cchStringData = other._cchStringData;
_cchStringDataCapacity = other._cchStringDataCapacity;
other._pszStringData = nullptr;
other._cchStringData = 0;
other._cchStringDataCapacity = 0;
return *this;
}
private:
NativeString& operator=(const NativeString& other) = delete;
public:
WCHAR** operator&()
{
return FreeAndGetAddressOf();
}
/*WCHAR* operator*() const
{
return Get();
}*/
bool operator==(const WCHAR* pszOther) const
{
return pszOther ? CompareOrdinal(pszOther) == CSTR_EQUAL : !_pszStringData;
}
bool operator!=(const WCHAR* pszOther) const
{
return !operator==(pszOther);
}
HRESULT AppendMayTruncate(const WCHAR* psz, size_t cchMaxCapacity)
{
return _ConcatMayTruncate(psz, cchMaxCapacity);
}
HRESULT EnsureCapacity(size_t cchDesired)
{
return _EnsureCapacity(cchDesired);
}
private:
void _EnsureCount()
{
if (_cchStringData == s_cchUnknown)
{
_cchStringData = _pszStringData ? wcslen(_pszStringData) : 0;
}
}
HRESULT _EnsureCapacity(size_t cchDesired)
{
size_t cchCapacityCur;
HRESULT hr = SizeTAdd(cchDesired, 1, &cchCapacityCur);
if (SUCCEEDED(hr))
{
if (_cchStringDataCapacity == s_cchUnknown)
{
_EnsureCount();
_cchStringDataCapacity = _pszStringData ? _cchStringData + 1 : 0;
}
if (_cchStringDataCapacity == 0) // First allocation
{
size_t cbDesired;
hr = SizeTMult(cchCapacityCur, sizeof(WCHAR), &cbDesired);
if (SUCCEEDED(hr))
{
WCHAR* pvArrayT = Allocator::Alloc(cbDesired);
hr = pvArrayT ? S_OK : E_OUTOFMEMORY;
if (SUCCEEDED(hr))
{
_cchStringDataCapacity = cchCapacityCur;
_pszStringData = pvArrayT;
pvArrayT[0] = 0;
}
}
}
else if (cchCapacityCur > _cchStringDataCapacity) // Growing
{
size_t celemNew;
hr = SizeTMult(_cchStringDataCapacity, 2, &celemNew); // Double the capacity
if (SUCCEEDED(hr))
{
if (celemNew - _cchStringDataCapacity > 2048)
celemNew = _cchStringDataCapacity + 2048; // Make sure it doesn't grow too much; TODO Check disassembly
if (cchCapacityCur <= celemNew)
cchCapacityCur = celemNew;
WCHAR* pvArrayT = Allocator::Realloc(_pszStringData, sizeof(WCHAR) * cchCapacityCur);
hr = pvArrayT ? S_OK : E_OUTOFMEMORY;
if (SUCCEEDED(hr))
{
_cchStringDataCapacity = cchCapacityCur;
_pszStringData = pvArrayT;
}
}
}
}
return hr;
}
bool _IsEmpty() const
{
return !_pszStringData || !_pszStringData[0];
}
HRESULT _Initialize(const WCHAR* psz, size_t cch)
{
size_t cchDesired = cch;
size_t cchStringData;
HRESULT hr = S_OK;
if (psz)
{
if (cchDesired == s_cchUnknown)
{
cchDesired = wcslen(psz);
cchStringData = cchDesired;
}
else
{
cchStringData = _NativeString_Min<size_t>(cchDesired, wcslen(psz)); // @MOD Prevent double evaluation
}
hr = _EnsureCapacity(cchDesired);
if (SUCCEEDED(hr))
{
StringCchCopyNW(_pszStringData, cchDesired + 1, psz, cchStringData);
_cchStringData = cchStringData;
}
}
else
{
_Free();
}
return hr;
}
template <typename T>
HRESULT _InitializeHelper(const WCHAR* pszFormat, va_list argList, const T& callback)
{
HRESULT hr;
size_t cchCapacityGuess = 32;
do
{
hr = _EnsureCapacity(cchCapacityGuess);
if (SUCCEEDED(hr))
{
hr = callback(pszFormat, argList, _pszStringData, _cchStringDataCapacity);
if (hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER))
{
size_t cchCapacityT;
hr = SizeTAdd(_cchStringDataCapacity, 32, &cchCapacityT);
if (SUCCEEDED(hr))
{
cchCapacityGuess = cchCapacityT;
}
}
else
{
break;
}
}
}
while (SUCCEEDED(hr));
if (SUCCEEDED(hr))
{
_cchStringData = s_cchUnknown;
}
else
{
_Free();
}
return hr;
}
HRESULT _InitializeFromRegistry(HKEY hKey, const WCHAR* pszValueName, bool fExpand)
{
DWORD dwType;
DWORD cbT = 0;
LSTATUS lRes = RegQueryValueExW(hKey, pszValueName, nullptr, &dwType, nullptr, &cbT);
HRESULT hr = HRESULT_FROM_WIN32(lRes);
if (SUCCEEDED(hr) && ((dwType != REG_SZ && dwType != REG_EXPAND_SZ) || cbT == 0 || (cbT & 1) != 0))
{
hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
}
WCHAR* pszT = nullptr;
if (SUCCEEDED(hr))
{
pszT = Allocator::Alloc(cbT);
hr = pszT ? S_OK : E_OUTOFMEMORY;
}
if (SUCCEEDED(hr))
{
lRes = RegQueryValueExW(hKey, pszValueName, nullptr, &dwType, (LPBYTE)pszT, &cbT);
hr = HRESULT_FROM_WIN32(lRes);
}
DWORD cchT = 0;
if (SUCCEEDED(hr))
{
cchT = (cbT / sizeof(WCHAR)) - 1;
if (dwType == REG_EXPAND_SZ && fExpand)
{
DWORD cchBuffer = ExpandEnvironmentStringsW(pszT, nullptr, 0);
if (cchBuffer != 0)
{
WCHAR* pszExpand = Allocator::Alloc(sizeof(WCHAR) * cchBuffer);
hr = pszExpand ? S_OK : E_OUTOFMEMORY;
if (SUCCEEDED(hr))
{
DWORD cchResult = ExpandEnvironmentStringsW(pszT, pszExpand, cchBuffer);
hr = ResultFromWin32Count(cchResult, cchBuffer);
if (SUCCEEDED(hr))
{
Allocator::Free(pszT);
pszT = pszExpand;
cchT = cchResult - 1;
}
else
{
Allocator::Free(pszExpand);
}
}
}
}
}
if (SUCCEEDED(hr))
{
if (!pszT[cchT])
{
_Attach(pszT, cchT + 1);
pszT = nullptr;
}
else
{
hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
}
}
Allocator::Free(pszT);
return hr;
}
size_t _GetCount()
{
_EnsureCount();
return _cchStringData;
}
size_t _GetCount() const
{
if (_cchStringData != s_cchUnknown)
return _cchStringData;
return _pszStringData ? wcslen(_pszStringData) : 0;
}
const WCHAR* _Get() const
{
return _pszStringData;
}
HRESULT _Concat(const WCHAR c)
{
WCHAR sz[2] = { c, 0 };
return _Concat(sz, 1);
}
HRESULT _Concat(const WCHAR* psz, const size_t cch)
{
HRESULT hr = S_OK;
if (psz)
{
_EnsureCount();
hr = _EnsureCapacity(cch + _cchStringData);
if (SUCCEEDED(hr))
{
StringCchCopyNW(&_pszStringData[_cchStringData], cch + 1, psz, cch);
_cchStringData += cch;
}
}
return hr;
}
HRESULT _ConcatMayTruncate(const WCHAR* psz, size_t cchMaxCapacity)
{
_EnsureCount();
HRESULT hr = S_OK;
if (cchMaxCapacity > _cchStringData)
{
size_t cchDesired = _NativeString_Min<size_t>(cchMaxCapacity - _cchStringData, wcslen(psz)); // @MOD Prevent double evaluation
hr = _Concat(psz, cchDesired);
}
else if (cchMaxCapacity < _cchStringData)
{
_cchStringData = cchMaxCapacity;
_pszStringData[cchMaxCapacity] = 0;
}
return hr;
}
bool _RemoveAt(size_t iElem, size_t cchElem)
{
_EnsureCount();
bool fRet = false;
if (iElem < _cchStringData)
{
cchElem = _NativeString_Min<size_t>(cchElem, _cchStringData - iElem); // @MOD Prevent double evaluation
if (cchElem)
{
memmove(&_pszStringData[iElem], &_pszStringData[iElem + cchElem], sizeof(WCHAR) * (_cchStringData - iElem - cchElem));
_cchStringData -= cchElem;
}
_pszStringData[_cchStringData] = 0;
fRet = true;
}
return fRet;
}
bool _TrimStart(const WCHAR* pszTrim)
{
_EnsureCount();
bool fNeedsTrimming = false;
size_t cch;
for (cch = 0; cch < _cchStringData; ++cch)
{
if (!wcschr(pszTrim, _pszStringData[cch]))
break;
}
if (cch)
{
fNeedsTrimming = true;
memmove(_pszStringData, &_pszStringData[cch], sizeof(WCHAR) * (_cchStringData - cch) + sizeof(WCHAR));
_cchStringData -= cch;
}
return fNeedsTrimming;
}
bool _TrimEnd(const WCHAR* pszTrim)
{
_EnsureCount();
size_t cch;
for (cch = _cchStringData; cch; --cch)
{
if (!wcschr(pszTrim, _pszStringData[cch - 1]))
break;
}
bool fNeedsTrimming = false;
if (cch != _cchStringData)
{
fNeedsTrimming = true;
_pszStringData[cch] = 0;
_cchStringData = cch;
}
return fNeedsTrimming;
}
void _Free()
{
if (_pszStringData)
{
Allocator::Free(_pszStringData);
_pszStringData = nullptr;
}
_cchStringData = 0;
_cchStringDataCapacity = 0;
}
void _Attach(WCHAR* psz)
{
return _Attach(psz, wcslen(psz) + 1);
}
void _Attach(WCHAR* psz, const size_t cch)
{
_Free();
if (psz && cch)
{
_pszStringData = psz;
_cchStringData = cch - 1;
_cchStringDataCapacity = cch;
psz[cch - 1] = 0;
}
}
WCHAR* _Detach()
{
WCHAR* pszStringData = _pszStringData;
_pszStringData = nullptr;
_cchStringData = 0;
_cchStringDataCapacity = 0;
return pszStringData;
}
WCHAR** _FreeAndGetAddressOf()
{
_Free();
_cchStringData = s_cchUnknown;
_cchStringDataCapacity = s_cchUnknown;
return &_pszStringData;
}
static const size_t s_cchUnknown = -1;
WCHAR* _pszStringData;
size_t _cchStringData;
size_t _cchStringDataCapacity;
template <typename T>
static FORCEINLINE constexpr const T& (_NativeString_Min)(const T& a, const T& b)
{
return a < b ? a : b;
}
};
}
typedef Windows::Internal::NativeString<Windows::Internal::CoTaskMemPolicy<WCHAR>> CoTaskMemNativeString;

46
ExplorerPatcher/inc/RefCountedObject.h

@ -0,0 +1,46 @@ @@ -0,0 +1,46 @@
#pragma once
#include <wrl/client.h>
template <typename T>
class CRefCountedObject : public IUnknown, public T
{
public:
template <typename ...TArgs>
CRefCountedObject(TArgs&& ...args)
: T(std::forward<TArgs>(args)...)
, _cRef(0)
{
}
virtual ~CRefCountedObject()
{
}
STDMETHODIMP QueryInterface(REFIID riid, void** ppvObject) override
{
*ppvObject = nullptr;
return E_NOTIMPL;
}
STDMETHODIMP_(ULONG) AddRef() override
{
return InterlockedIncrement(&_cRef);
}
STDMETHODIMP_(ULONG) Release() override
{
ULONG refCount = InterlockedDecrement(&_cRef);
if (refCount == 0)
delete this;
return refCount;
}
ULONG _cRef;
};
template <typename T, typename ...TArgs>
Microsoft::WRL::ComPtr<CRefCountedObject<T>> CreateRefCountedObj(TArgs&& ...args)
{
return new(std::nothrow) CRefCountedObject<T>(std::forward<TArgs>(args)...);
}

29
ExplorerPatcher/inc/ResultUtils.h

@ -0,0 +1,29 @@ @@ -0,0 +1,29 @@
#pragma once
#include <Windows.h>
inline HRESULT ResultFromWin32(__in DWORD dwErr)
{
return HRESULT_FROM_WIN32(dwErr);
}
inline HRESULT ResultFromLastError()
{
return ResultFromWin32(GetLastError());
}
inline HRESULT ResultFromKnownLastError()
{
HRESULT hr = ResultFromLastError();
return (SUCCEEDED(hr) ? E_FAIL : hr);
}
inline HRESULT ResultFromWin32Bool(BOOL b)
{
return b ? S_OK : ResultFromKnownLastError();
}
inline HRESULT ResultFromWin32Count(UINT cchResult, UINT cchBuffer)
{
return cchResult && cchResult <= cchBuffer ? S_OK : ResultFromWin32(ERROR_INSUFFICIENT_BUFFER);
}

583
ExplorerPatcher/inc/SimpleArray.h

@ -0,0 +1,583 @@ @@ -0,0 +1,583 @@
#pragma once
#include <Windows.h>
#include <type_traits>
#include "ContainerPolicies.h"
template <typename T>
class CSimpleArrayStandardCompareHelper
{
public:
int Compare(const T& t1, const T& t2) const
{
return t2 == t1 ? 0 : t2 < t1 ? 1 : -1;
}
};
class CSimpleArrayCaseInsensitiveOrdinalStringCompareHelper
{
public:
int Compare(const WCHAR* psz1, const WCHAR* psz2) const
{
return CompareStringOrdinal(psz1, -1, psz2, -1, TRUE) - CSTR_EQUAL;
}
};
template <typename T>
class CSimpleArrayStandardMergeHelper
{
};
template <
typename T,
typename CompareHelper
>
class CTSimpleFixedArray
{
public:
T* _parray;
size_t _celem;
CTSimpleFixedArray()
: _parray(nullptr)
, _celem(0)
{
}
size_t GetSize() const { return _celem; }
T& operator[](size_t iElem) { return _parray[iElem]; }
const T& operator[](size_t iElem) const { return _parray[iElem]; }
HRESULT GetAt(size_t iElem, T& tOut) const
{
HRESULT hr = TYPE_E_OUTOFBOUNDS;
if (iElem < _celem)
{
tOut = _parray[iElem];
hr = S_OK;
}
return hr;
}
T* GetData() const { return _parray; }
T* begin() { return _parray; }
T* begin() const { return _parray; }
T* end() { return _parray + _celem; }
T* end() const { return _parray + _celem; }
HRESULT Find(const T& t, size_t* piElem, size_t iStartAt = 0) const
{
return FindEx(CompareHelper(), t, piElem, iStartAt);
}
template <typename Comparer>
HRESULT FindEx(const Comparer& tcompare, const T& t, size_t* piElem, size_t iStartAt = 0) const
{
*piElem = 0;
for (size_t i = iStartAt; i < _celem; ++i)
{
if (tcompare.Compare(_parray[i], t) == 0)
{
*piElem = i;
return S_OK;
}
}
return TYPE_E_ELEMENTNOTFOUND;
}
HRESULT BinarySearch(const T& t, size_t* piElem) const
{
return BinarySearchEx(CompareHelper(), t, piElem);
}
template <typename Comparer>
HRESULT BinarySearchEx(const Comparer& tcompare, const T& t, size_t* piElem) const
{
*piElem = 0;
HRESULT hr = TYPE_E_ELEMENTNOTFOUND;
if (_celem != 0)
{
hr = S_OK;
size_t iLow = 0;
size_t iHigh = _celem - 1;
while (true)
{
size_t iMid = (iLow + iHigh) / 2;
int compare = tcompare.Compare(_parray[iMid], t);
if (compare > 0)
{
if (iMid != 0)
{
iHigh = iMid - 1;
}
else
{
hr = TYPE_E_ELEMENTNOTFOUND;
}
}
else if (compare < 0)
{
iLow = iMid + 1;
}
else
{
for (; iMid != 0; --iMid)
{
if (tcompare.Compare(_parray[iMid - 1], t) != 0)
break;
}
*piElem = iMid;
break;
}
if (iHigh < iLow)
hr = TYPE_E_ELEMENTNOTFOUND;
if (FAILED(hr))
{
*piElem = compare < 0 ? iLow : iMid;
break;
}
}
}
return hr;
}
template <typename TCallback>
void ForEach(const TCallback& callback) const // @MOD Pass callback by reference
{
for (size_t iElement = 0; iElement < _celem; ++iElement)
{
callback(iElement, _parray[iElement]);
}
}
};
template <
typename T,
size_t MaxSize,
typename Allocator,
typename CompareHelper,
typename MergeHelper = CSimpleArrayStandardMergeHelper<T>
>
class CTSimpleArray : public CTSimpleFixedArray<T, CompareHelper>
{
public:
T* _parrayT;
size_t _celemCapacity;
CTSimpleArray()
: CTSimpleFixedArray<T, CompareHelper>()
, _parrayT(nullptr)
, _celemCapacity(0)
{
}
~CTSimpleArray()
{
RemoveAll();
}
HRESULT Add(const T& t, size_t* piElemInsertedAt = nullptr)
{
return _Add(t, piElemInsertedAt);
}
HRESULT Add(T&& t, size_t* piElemInsertedAt = nullptr)
{
return _Add(std::move(t), piElemInsertedAt);
}
HRESULT InsertAt(const T& t, size_t iElem)
{
return _InsertAt(t, iElem);
}
HRESULT InsertAt(T&& t, size_t iElem)
{
return _InsertAt(std::move(t), iElem);
}
HRESULT SetAtIndex(size_t iElem, const T& t)
{
return _SetAtIndex(iElem, t);
}
HRESULT SetAtIndex(size_t iElem, T&& t)
{
return _SetAtIndex(iElem, std::move(t));
}
HRESULT Remove(const T& t, size_t* piElemRemovedAt = nullptr)
{
if (piElemRemovedAt)
*piElemRemovedAt = 0;
size_t iElem;
HRESULT hr = this->Find(t, &iElem);
if (SUCCEEDED(hr))
{
hr = RemoveAt(iElem);
if (SUCCEEDED(hr) && piElemRemovedAt)
{
*piElemRemovedAt = iElem;
}
}
return hr;
}
HRESULT RemoveAt(size_t iElem)
{
if (iElem >= this->_celem)
return TYPE_E_OUTOFBOUNDS;
if constexpr (!std::is_trivially_destructible_v<T>)
this->_parray[iElem].~T();
if (iElem != this->_celem - 1)
memmove(std::addressof(this->_parray[iElem]), std::addressof(this->_parray[iElem + 1]), sizeof(T) * (this->_celem - iElem - 1));
--this->_celem;
return S_OK;
}
void RemoveAll()
{
if (this->_parray)
{
if constexpr (!std::is_trivially_destructible_v<T>)
{
for (size_t i = 0; i < this->_celem; ++i)
this->_parray[i].~T();
}
Allocator::Destroy(this->_parray);
this->_parray = nullptr;
}
this->_celem = 0;
_celemCapacity = 0;
}
void TransferData(CTSimpleArray* other)
{
RemoveAll();
this->_parray = other->_parray;
this->_celem = other->_celem;
this->_parrayT = other->_parrayT;
this->_celemCapacity = other->_celemCapacity;
other->_parray = nullptr;
other->_celem = 0;
other->_parrayT = nullptr;
other->_celemCapacity = 0;
}
size_t GetCapacity() const
{
return _celemCapacity;
}
HRESULT Sort()
{
return SortEx(CompareHelper());
}
template <typename Comparer>
HRESULT SortEx(const Comparer& tcompare)
{
HRESULT hr = S_OK;
if (this->_celem > 1)
{
_parrayT = nullptr;
hr = Allocator::ReallocArray(nullptr, this->_celem / 2, &_parrayT);
if (SUCCEEDED(hr))
{
_MergeSort(tcompare, 0, this->_celem);
Allocator::Destroy(_parrayT);
_parrayT = nullptr;
}
}
return hr;
}
HRESULT _EnsureCapacity(size_t celemCapacityDesired, size_t celemMaxCapacity = 4096)
{
HRESULT hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
if (celemCapacityDesired > MaxSize)
return hr;
// If we have enough capacity, we're done
hr = S_OK;
size_t celemCapacityCur = _celemCapacity;
if (celemCapacityDesired <= celemCapacityCur)
return hr;
// Double the capacity
size_t celemCapacityT;
hr = SizeTMult(celemCapacityCur, 2, &celemCapacityT);
if (FAILED(hr))
return hr;
// Make sure we don't grow too much
celemCapacityT = celemCapacityT - celemCapacityCur > celemMaxCapacity ? celemCapacityCur + celemMaxCapacity : celemCapacityT;
// Cap at desired capacity and max capacity
celemCapacityT = celemCapacityDesired > celemCapacityT || celemCapacityT <= MaxSize ? max(celemCapacityDesired, celemCapacityT) : MaxSize;
// Realloc
T* pvArrayT;
hr = Allocator::ReallocArray(this->_parray, celemCapacityT, &pvArrayT);
if (FAILED(hr))
return hr;
_celemCapacity = celemCapacityT;
this->_parray = pvArrayT;
return hr;
}
HRESULT _MakeRoomAt(size_t iElem)
{
HRESULT hr = S_OK;
size_t cElemGrowTo = max(this->_celem, iElem) + 1;
if (cElemGrowTo > _celemCapacity)
{
hr = _EnsureCapacity(cElemGrowTo);
}
if (SUCCEEDED(hr))
{
if (iElem < this->_celem)
memmove(std::addressof(this->_parray[iElem + 1]), std::addressof(this->_parray[iElem]), sizeof(T) * (this->_celem - iElem));
this->_celem = cElemGrowTo;
}
return hr;
}
template <typename ArgType>
void _InternalSetAtIndex(size_t iElem, ArgType&& t)
{
T* newPos = std::addressof(this->_parray[iElem]);
if (newPos)
new(newPos) T(std::forward<ArgType>(t));
}
template <typename ArgType>
HRESULT _Add(ArgType&& t, size_t* piElemInsertedAt)
{
if (piElemInsertedAt)
*piElemInsertedAt = 0;
HRESULT hr = S_OK;
if (this->_celem == _celemCapacity)
{
hr = _EnsureCapacity(_celemCapacity + 1);
}
if (SUCCEEDED(hr))
{
_InternalSetAtIndex(this->_celem++, std::forward<ArgType>(t));
if (piElemInsertedAt)
*piElemInsertedAt = this->_celem - 1;
}
return hr;
}
template <typename ArgType>
HRESULT _InsertAt(ArgType&& t, size_t iElem)
{
HRESULT hr = _MakeRoomAt(iElem);
if (SUCCEEDED(hr))
{
_InternalSetAtIndex(iElem, std::forward<ArgType>(t));
}
return hr;
}
template <typename ArgType>
HRESULT _SetAtIndex(size_t iElem, ArgType&& t)
{
HRESULT hr = TYPE_E_OUTOFBOUNDS;
if (iElem < this->_celem)
{
_InternalSetAtIndex(iElem, std::forward<ArgType>(t));
hr = S_OK;
}
return hr;
}
template <typename Comparer>
void _MergeThem(const Comparer& tcompare, size_t iFirst, size_t cElems)
{
size_t cHalf = cElems / 2;
T* parraySrc = &this->_parray[iFirst];
memcpy(_parrayT, parraySrc, sizeof(T) * cHalf);
size_t iIn1 = 0;
size_t iIn2 = cHalf;
size_t iOut = 0;
bool fDone = false;
while (!fDone)
{
if (tcompare.Compare(_parrayT[iIn1], parraySrc[iIn2]) > 0)
{
memmove(&parraySrc[iOut], &parraySrc[iIn2], sizeof(T));
++iOut;
if (++iIn2 == cElems)
{
memcpy(&parraySrc[iOut], &_parrayT[iIn1], sizeof(T) * (cElems - iOut));
fDone = true;
}
}
else
{
memmove(&parraySrc[iOut], &_parrayT[iIn1], sizeof(T));
++iOut;
if (++iIn1 == cHalf)
{
fDone = true;
}
}
}
}
template <typename Comparer>
void _MergeSort(const Comparer& tcompare, size_t iFirst, size_t cElems)
{
if (cElems == 1)
return;
if (cElems == 2)
{
if (tcompare.Compare(this->_parray[iFirst], this->_parray[iFirst + 1]) > 0)
{
memmove(_parrayT, &this->_parray[iFirst], sizeof(T));
memmove(&this->_parray[iFirst], &this->_parray[iFirst + 1], sizeof(T));
memmove(&this->_parray[iFirst + 1], _parrayT, sizeof(T));
}
}
else
{
size_t cHalf = cElems >> 1;
_MergeSort(tcompare, iFirst, cHalf);
_MergeSort(tcompare, iFirst + cHalf, cElems - cHalf);
_MergeThem(tcompare, iFirst, cElems);
}
}
};
template <
typename T,
size_t MaxSize = UINT_MAX - 1,
typename CompareHelper = CSimpleArrayStandardCompareHelper<T>
>
class CCoSimpleArray : public CTSimpleArray<T, MaxSize, CTPolicyCoTaskMem<T>, CompareHelper>
{
public:
CCoSimpleArray()
{
}
CCoSimpleArray(CCoSimpleArray&& other) noexcept
{
this->TransferData(&other);
}
CCoSimpleArray& operator=(CCoSimpleArray&& other) noexcept
{
if (this != &other)
{
this->TransferData(&other);
}
return *this;
}
};
template <
typename T,
size_t MaxSize = UINT_MAX - 1,
typename CompareHelper = CSimpleArrayStandardCompareHelper<T>
>
class CLocalSimpleArray : public CTSimpleArray<T, MaxSize, CTPolicyLocalMem<T>, CompareHelper>
{
};
template <
typename T,
typename ElementAllocator,
typename CompareHelper = CSimpleArrayStandardCompareHelper<T>
>
class CSimplePointerArray : public CCoSimpleArray<T*, UINT_MAX - 1, CompareHelper>
{
public:
~CSimplePointerArray()
{
RemoveAndReleaseAll();
}
HRESULT RemoveAndReleaseAt(size_t iElem)
{
T* pT;
HRESULT hr = this->GetAt(iElem, pT);
if (SUCCEEDED(hr))
{
hr = this->RemoveAt(iElem);
if (SUCCEEDED(hr))
{
ElementAllocator::Destroy(pT);
}
}
return hr;
}
void RemoveAndReleaseAll()
{
for (size_t i = 0; i < this->_celem; ++i)
{
ElementAllocator::Destroy(this->_parray[i]);
}
this->RemoveAll();
}
};
template <
typename T,
typename CompareHelper = CSimpleArrayStandardCompareHelper<T*>
>
class CSimplePointerArrayNewMem : public CSimplePointerArray<T, CTContainer_PolicyNewMem, CompareHelper>
{
};
template <
typename T,
typename CompareHelper = CSimpleArrayStandardCompareHelper<T*>
>
class CSimplePointerArrayCoTaskMem : public CSimplePointerArray<T, CTPolicyCoTaskMem<T>, CompareHelper>
{
};
template <
typename T,
typename CompareHelper = CSimpleArrayStandardCompareHelper<T*>
>
class CSimplePointerArrayLocalMem : public CSimplePointerArray<T, CTPolicyLocalMem<T>, CompareHelper>
{
};
template <typename T>
class CSimplePointerArrayRelease : public CSimplePointerArray<T, CTContainer_PolicyRelease<T>>
{
};

720
ExplorerPatcher/inc/memsafe.h

@ -0,0 +1,720 @@ @@ -0,0 +1,720 @@
// Downloaded from:
// https://github.com/namealt/winsdk10/blob/d1acc505c51b11a6ceafb0f93c9dc584b8b4a9d3/Include/10.0.16299.0/um/memsafe.h
//
// Copyright (C) Microsoft. All rights reserved.
//
#if (_MSC_VER > 1000)
#pragma once
#endif
#ifndef __memsafe_h__
#define __memsafe_h__
#ifdef __cplusplus
//
// Various heap allocation helpers, featuring
// - Fully annotated
// - HRESULT return values
// - Integer overflow checks via intsafe.h
// - Type safety via templates (no typecasting required)
// - Zero initialization
//
// CoAllocBytes
// CoReallocBytes
// CoAllocObject
// CoAllocArray
// CoReallocArray
//
// CoAllocString
// CoAllocStringLen
// CoAllocStringDoubleNullTerminate
// CoAllocStringOpt
//
// LocalAllocBytes
// LocalReallocBytes
// LocalAllocObject
// LocalAllocArray
// LocalReallocArray
//
// LocalAllocString
// LocalAllocStringLen
// LocalAllocStringDoubleNullTerminate
// LocalAllocStringOpt
//
// HeapAllocBytes
// HeapReallocBytes
// HeapAllocObject
// HeapAllocArray
// HeapReallocArray
//
// HeapAllocString
// HeapAllocStringLen
// HeapAllocStringDoubleNullTerminate
// HeapAllocStringOpt
//
// GlobalAllocBytes
// GlobalReallocBytes
// GlobalAllocObject
// GlobalAllocArray
// GlobalReallocArray
//
// GlobalAllocString
// GlobalAllocStringLen
// GlobalAllocStringDoubleNullTerminate
// GlobalAllocStringOpt
//
#include <intsafe.h>
#include <strsafe.h>
// Flag for inhibiting zero-initialization
#define NO_ZERO_INIT 0x00000000
// Templates for isolating T* <--> void* conversions and integer arithmetic
template <class T, class TAllocPolicy>
inline HRESULT _AllocBytes(_In_opt_ HANDLE hHeap, _In_ DWORD dwFlags, _In_ size_t cb, _Outptr_result_bytebuffer_(cb) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv)
{
return TAllocPolicy::Alloc(hHeap, dwFlags, cb, (void**)ppv);
}
template <class T, class TAllocPolicy>
inline HRESULT _ReallocBytes(_In_opt_ HANDLE hHeap, _In_ DWORD dwFlags, _In_opt_ T *pv, _In_ size_t cb, _Outptr_result_bytebuffer_(cb) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv)
{
return TAllocPolicy::Realloc(hHeap, dwFlags, pv, cb, (void**)ppv);
}
template <class T, class TAllocPolicy>
inline HRESULT _AllocArray(_In_opt_ HANDLE hHeap, _In_ DWORD dwFlags, _In_ size_t cItems, _Outptr_result_buffer_(cItems) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv)
{
*ppv = NULL;
size_t cb;
HRESULT hr = SizeTMult(cItems, sizeof(T), &cb);
if (SUCCEEDED(hr))
{
hr = TAllocPolicy::Alloc(hHeap, dwFlags, cb, (void**)ppv);
}
return hr;
}
template <class T, class TAllocPolicy>
inline HRESULT _ReallocArray(_In_opt_ HANDLE hHeap, _In_ DWORD dwFlags, _In_opt_ T *pv, _In_ size_t cItems, _Outptr_result_buffer_(cItems) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv)
{
*ppv = NULL;
size_t cb;
HRESULT hr = SizeTMult(cItems, sizeof(T), &cb);
if (SUCCEEDED(hr))
{
hr = TAllocPolicy::Realloc(hHeap, dwFlags, pv, cb, (void**)ppv);
}
return hr;
}
// Templates for isolating string-specific functionality
template <class TAllocPolicy>
inline HRESULT _AllocStringWorker(_In_opt_ HANDLE hHeap, _In_ DWORD dwFlags, _In_reads_opt_(cch) PCNZWCH pszSource, _In_ size_t cch, _In_ size_t cchExtra, _Outptr_result_buffer_(cch+cchExtra) _On_failure_(_Post_satisfies_(*ppsz == 0)) PWSTR *ppsz)
{
*ppsz = NULL;
size_t cchTotal;
HRESULT hr = SizeTAdd(cch, cchExtra, &cchTotal);
if (SUCCEEDED(hr))
{
// Note that we do not require dwFlags to include the allocator-specific
// zero-initialization flag here.
hr = _AllocArray<WCHAR,TAllocPolicy>(hHeap, dwFlags, cchTotal, ppsz);
if (SUCCEEDED(hr))
{
// The source string may be shorter than cch, so zero-initialize
// the entire buffer using STRSAFE_FILL_BEHIND_NULL.
//
// Note that _AllocStringDoubleNullTerminate relies on
// zero-initialization to provide the 2nd NULL terminator.
StringCchCopyNExW(*ppsz, cchTotal, pszSource, cch, NULL, NULL, STRSAFE_IGNORE_NULLS | STRSAFE_FILL_BEHIND_NULL);
}
}
return hr;
}
template <class TAllocPolicy>
inline HRESULT _AllocString(_In_opt_ HANDLE hHeap, _In_ DWORD dwFlags, _In_ PCWSTR pszSource, _Outptr_result_nullonfailure_ PWSTR *ppsz)
{
// pszSource must be valid (non-NULL)
return _AllocStringWorker<TAllocPolicy>(hHeap, dwFlags, pszSource, wcslen(pszSource), 1, ppsz);
}
template <class TAllocPolicy>
inline HRESULT _AllocStringLen(_In_opt_ HANDLE hHeap, _In_ DWORD dwFlags, _In_reads_or_z_opt_(cch) PCNZWCH pszSource, _In_ size_t cch, _Outptr_result_buffer_(cch+1) _On_failure_(_Post_satisfies_(*ppsz == 0)) PWSTR *ppsz)
{
// pszSource is optional (may be NULL)
return _AllocStringWorker<TAllocPolicy>(hHeap, dwFlags, pszSource, cch, 1, ppsz);
}
// Takes a single-null terminated string and allocates a double-null terminated string.
template <class TAllocPolicy>
inline HRESULT _AllocStringDoubleNullTerminate(_In_opt_ HANDLE hHeap, _In_ DWORD dwFlags, _In_ PCWSTR pszSource, _Outptr_result_nullonfailure_ PZZWSTR *ppsz)
{
// pszSource must be valid (non-NULL)
return _AllocStringWorker<TAllocPolicy>(hHeap, dwFlags, pszSource, wcslen(pszSource), 2, ppsz);
}
template <class TAllocPolicy>
inline HRESULT _AllocStringOpt(_In_opt_ HANDLE hHeap, _In_ DWORD dwFlags, _In_opt_ PCWSTR pszSource, _Outptr_result_maybenull_ _On_failure_(_Post_satisfies_(*ppsz == 0)) PWSTR *ppsz)
{
// pszSource is optional (may be NULL)
if (pszSource != NULL)
{
return _AllocString<TAllocPolicy>(hHeap, dwFlags, pszSource, ppsz);
}
*ppsz = NULL;
return S_OK;
}
#ifndef NO_COALLOC_HELPERS
#include <objbase.h>
// CoTaskMemAlloc does not zero-initialize by default. Define a flag to enable
// zero-init behavior.
#define CO_MEM_ZERO_INIT 0x00000001
class CTCoAllocPolicy
{
private:
#if (NTDDI_VERSION < NTDDI_WIN10_RS1) || defined(COM_SUPPORT_MALLOC_SPIES)
static size_t _CoTaskMemSize(_In_ _Post_writable_byte_size_(return) void *pv)
{
size_t cb = 0;
IMalloc *pMalloc;
if (SUCCEEDED(CoGetMalloc(1, &pMalloc))) // should never fail (static v-table)
{
// Returns (size_t)-1 if pv is NULL.
// Result is indeterminate if pv does not belong to CoTaskMemAlloc.
cb = pMalloc->GetSize(pv);
pMalloc->Release();
}
return cb;
}
#endif
public:
static HRESULT Alloc(_In_opt_ HANDLE /*hHeap*/, _In_ DWORD dwFlags, _In_ size_t cb, _Outptr_result_bytebuffer_(cb) _On_failure_(_Post_satisfies_(*ppv == 0)) void **ppv)
{
*ppv = CoTaskMemAlloc(cb);
if (*ppv)
{
if (dwFlags & CO_MEM_ZERO_INIT)
{
#ifdef COM_SUPPORT_MALLOC_SPIES
// Zero-initialize the buffer
// The actual size might be larger than cb due to spies present.
// Initialize to the actual size in case of realloc later,
// or there might be an uninitialized gap in between.
size_t cbActual = _CoTaskMemSize(*ppv);
ZeroMemory(*ppv, cbActual);
#else
ZeroMemory(*ppv, cb);
#endif
}
return S_OK;
}
return E_OUTOFMEMORY;
}
static HRESULT Realloc(_In_opt_ HANDLE /*hHeap*/, _In_ DWORD dwFlags, _In_opt_ void *pv, _In_ size_t cb, _Outptr_result_bytebuffer_(cb) _On_failure_(_Post_satisfies_(*ppv == 0)) void **ppv)
{
#if (NTDDI_VERSION < NTDDI_WIN10_RS1)
size_t cbKeepIntact = 0;
if (pv && (dwFlags & CO_MEM_ZERO_INIT))
{
// Get the current size, so we know how much to zero-initialize
cbKeepIntact = _CoTaskMemSize(pv);
if (cb < cbKeepIntact)
{
// Shrinking the buffer, only keep the new size
cbKeepIntact = cb;
}
}
#else
// As of Redstone CoTaskMemRealloc always zero-initializes
// the tail of the allocation.
size_t cbKeepIntact = cb;
#endif
// If pv is NULL, CoTaskMemRealloc allocates a new block
*ppv = CoTaskMemRealloc(pv, cb);
if (*ppv)
{
if (dwFlags & CO_MEM_ZERO_INIT)
{
// Zero-initialize the trailing part of the buffer
#ifdef COM_SUPPORT_MALLOC_SPIES
// The actual size might be larger than cb due to due to spies present.
size_t cbActual = _CoTaskMemSize(*ppv);
#else
size_t cbActual = cb;
#endif
if (cbActual > cbKeepIntact)
{
ZeroMemory(((BYTE*)*ppv) + cbKeepIntact, cbActual - cbKeepIntact);
}
}
return S_OK;
}
return E_OUTOFMEMORY;
}
};
// CoTaskMemAlloc helpers
template <class T>
inline HRESULT CoAllocBytes(_In_ DWORD dwFlags, _In_ size_t cb, _Outptr_result_bytebuffer_(cb) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv)
{
return _AllocBytes<T, CTCoAllocPolicy>(NULL, dwFlags, cb, ppv);
}
template <class T>
inline HRESULT CoReallocBytes(_In_ DWORD dwFlags, _In_opt_ T *pv, _In_ size_t cb, _Outptr_result_bytebuffer_(cb) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv)
{
return _ReallocBytes<T, CTCoAllocPolicy>(NULL, dwFlags, pv, cb, ppv);
}
template <class T>
inline HRESULT CoAllocObject(_In_ DWORD dwFlags, _Outptr_result_buffer_(1) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv)
{
return _AllocBytes<T, CTCoAllocPolicy>(NULL, dwFlags, sizeof(T), ppv);
}
template <class T>
inline HRESULT CoAllocArray(_In_ DWORD dwFlags, _In_ size_t cItems, _Outptr_result_buffer_(cItems) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv)
{
return _AllocArray<T, CTCoAllocPolicy>(NULL, dwFlags, cItems, ppv);
}
template <class T>
inline HRESULT CoReallocArray(_In_ DWORD dwFlags, _In_opt_ T *pv, _In_ size_t cItems, _Outptr_result_buffer_(cItems) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv)
{
return _ReallocArray<T, CTCoAllocPolicy>(NULL, dwFlags, pv, cItems, ppv);
}
// Zero-initializing CoTaskMemAlloc helpers
template <class T>
inline HRESULT CoAllocBytes(_In_ size_t cb, _Outptr_result_bytebuffer_(cb) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv)
{
return CoAllocBytes(CO_MEM_ZERO_INIT, cb, ppv);
}
template <class T>
inline HRESULT CoReallocBytes(_In_opt_ T *pv, _In_ size_t cb, _Outptr_result_bytebuffer_(cb) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv)
{
return CoReallocBytes(CO_MEM_ZERO_INIT, pv, cb, ppv);
}
template <class T>
inline HRESULT CoAllocObject(_Outptr_result_buffer_(1) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv)
{
return CoAllocObject(CO_MEM_ZERO_INIT, ppv);
}
template <class T>
inline HRESULT CoAllocArray(_In_ size_t cItems, _Outptr_result_buffer_(cItems) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv)
{
return CoAllocArray(CO_MEM_ZERO_INIT, cItems, ppv);
}
template <class T>
inline HRESULT CoReallocArray(_In_opt_ T *pv, _In_ size_t cItems, _Outptr_result_buffer_(cItems) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv)
{
return CoReallocArray(CO_MEM_ZERO_INIT, pv, cItems, ppv);
}
// CoTaskMemAlloc string helpers
inline HRESULT CoAllocString(_In_ PCWSTR pszSource, _Outptr_result_nullonfailure_ PWSTR *ppsz)
{
return _AllocString<CTCoAllocPolicy>(NULL, NO_ZERO_INIT, pszSource, ppsz);
}
inline HRESULT CoAllocStringLen( _In_reads_or_z_opt_(cch) PCNZWCH pszSource, _In_ size_t cch, _Outptr_result_buffer_(cch+1) _On_failure_(_Post_satisfies_(*ppsz == 0)) PWSTR *ppsz)
{
return _AllocStringLen<CTCoAllocPolicy>(NULL, NO_ZERO_INIT, pszSource, cch, ppsz);
}
inline HRESULT CoAllocStringDoubleNullTerminate(_In_ PCWSTR pszSource, _Outptr_result_nullonfailure_ PZZWSTR *ppsz)
{
return _AllocStringDoubleNullTerminate<CTCoAllocPolicy>(NULL, NO_ZERO_INIT, pszSource, ppsz);
}
inline HRESULT CoAllocStringOpt(_In_opt_ PCWSTR pszSource, _Outptr_result_maybenull_ _On_failure_(_Post_satisfies_(*ppsz == 0)) PWSTR *ppsz)
{
return _AllocStringOpt<CTCoAllocPolicy>(NULL, NO_ZERO_INIT, pszSource, ppsz);
}
#endif // NO_COALLOC_HELPERS
#ifndef NO_LOCALALLOC_HELPERS
class CTLocalAllocPolicy
{
public:
static HRESULT Alloc(_In_opt_ HANDLE /*hHeap*/, _In_ DWORD dwFlags, _In_ size_t cb, _Outptr_result_bytebuffer_(cb) _On_failure_(_Post_satisfies_(*ppv == 0)) void **ppv)
{
// ignore flags other than zero-init, assume fixed
*ppv = LocalAlloc(LMEM_FIXED | (dwFlags & LMEM_ZEROINIT), cb);
return (*ppv) ? S_OK : E_OUTOFMEMORY;
}
static HRESULT Realloc(_In_opt_ HANDLE hHeap, _In_ DWORD dwFlags, _In_opt_ void *pv, _In_ size_t cb, _Outptr_result_bytebuffer_(cb) _On_failure_(_Post_satisfies_(*ppv == 0)) void **ppv)
{
if (pv == NULL)
{
return Alloc(hHeap, dwFlags, cb, ppv);
}
// LMEM_MOVEABLE is correct when reallocating LMEM_FIXED buffers
*ppv = LocalReAlloc(pv, cb, LMEM_MOVEABLE | (dwFlags & LMEM_ZEROINIT));
return (*ppv) ? S_OK : E_OUTOFMEMORY;
}
};
// LocalAlloc helpers
template <class T>
inline HRESULT LocalAllocBytes(_In_ DWORD dwFlags, _In_ size_t cb, _Outptr_result_bytebuffer_(cb) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv)
{
return _AllocBytes<T, CTLocalAllocPolicy>(NULL, dwFlags, cb, ppv);
}
template <class T>
inline HRESULT LocalReallocBytes(_In_ DWORD dwFlags, _In_opt_ T *pv, _In_ size_t cb, _Outptr_result_bytebuffer_(cb) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv)
{
return _ReallocBytes<T, CTLocalAllocPolicy>(NULL, dwFlags, pv, cb, ppv);
}
template <class T>
inline HRESULT LocalAllocObject(_In_ DWORD dwFlags, _Outptr_result_buffer_(1) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv)
{
return _AllocBytes<T, CTLocalAllocPolicy>(NULL, dwFlags, sizeof(T), ppv);
}
template <class T>
inline HRESULT LocalAllocArray(_In_ DWORD dwFlags, _In_ size_t cItems, _Outptr_result_buffer_(cItems) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv)
{
return _AllocArray<T, CTLocalAllocPolicy>(NULL, dwFlags, cItems, ppv);
}
template <class T>
inline HRESULT LocalReallocArray(_In_ DWORD dwFlags, _In_opt_ T *pv, _In_ size_t cItems, _Outptr_result_buffer_(cItems) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv)
{
return _ReallocArray<T, CTLocalAllocPolicy>(NULL, dwFlags, pv, cItems, ppv);
}
// Zero-initializing LocalAlloc helpers
template <class T>
inline HRESULT LocalAllocBytes(_In_ size_t cb, _Outptr_result_bytebuffer_(cb) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv)
{
return LocalAllocBytes(LMEM_ZEROINIT, cb, ppv);
}
template <class T>
inline HRESULT LocalReallocBytes(_In_opt_ T *pv, _In_ size_t cb, _Outptr_result_bytebuffer_(cb) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv)
{
return LocalReallocBytes(LMEM_ZEROINIT, pv, cb, ppv);
}
template <class T>
inline HRESULT LocalAllocObject(_Outptr_result_buffer_(1) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv)
{
return LocalAllocObject(LMEM_ZEROINIT, ppv);
}
template <class T>
inline HRESULT LocalAllocArray(_In_ size_t cItems, _Outptr_result_buffer_(cItems) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv)
{
return LocalAllocArray(LMEM_ZEROINIT, cItems, ppv);
}
template <class T>
inline HRESULT LocalReallocArray(_In_opt_ T *pv, _In_ size_t cItems, _Outptr_result_buffer_(cItems) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv)
{
return LocalReallocArray(LMEM_ZEROINIT, pv, cItems, ppv);
}
// LocalAlloc string helpers
inline HRESULT LocalAllocString(_In_ PCWSTR pszSource, _Outptr_result_nullonfailure_ PWSTR *ppsz)
{
return _AllocString<CTLocalAllocPolicy>(NULL, NO_ZERO_INIT, pszSource, ppsz);
}
inline HRESULT LocalAllocStringLen( _In_reads_or_z_opt_(cch) PCNZWCH pszSource, _In_ size_t cch, _Outptr_result_buffer_(cch+1) _On_failure_(_Post_satisfies_(*ppsz == 0)) PWSTR *ppsz)
{
return _AllocStringLen<CTLocalAllocPolicy>(NULL, NO_ZERO_INIT, pszSource, cch, ppsz);
}
inline HRESULT LocalAllocStringDoubleNullTerminate(_In_ PCWSTR pszSource, _Outptr_result_nullonfailure_ PZZWSTR *ppsz) //todo sal 00?
{
return _AllocStringDoubleNullTerminate<CTLocalAllocPolicy>(NULL, NO_ZERO_INIT, pszSource, ppsz);
}
inline HRESULT LocalAllocStringOpt(_In_opt_ PCWSTR pszSource, _Outptr_result_maybenull_ _On_failure_(_Post_satisfies_(*ppsz == 0)) PWSTR *ppsz)
{
return _AllocStringOpt<CTLocalAllocPolicy>(NULL, NO_ZERO_INIT, pszSource, ppsz);
}
#endif // NO_LOCALALLOC_HELPERS
#ifndef NO_HEAPALLOC_HELPERS
class CTHeapAllocPolicy
{
public:
static HRESULT Alloc(_In_ HANDLE hHeap, _In_ DWORD dwFlags, _In_ size_t cb, _Outptr_result_bytebuffer_(cb) _On_failure_(_Post_satisfies_(*ppv == 0)) void **ppv)
{
*ppv = HeapAlloc(hHeap, dwFlags, cb);
return (*ppv) ? S_OK : E_OUTOFMEMORY;
}
static HRESULT Realloc(_In_ HANDLE hHeap, _In_ DWORD dwFlags, _In_opt_ void *pv, _In_ size_t cb, _Outptr_result_bytebuffer_(cb) _On_failure_(_Post_satisfies_(*ppv == 0)) void **ppv)
{
if (pv == NULL)
{
return Alloc(hHeap, dwFlags, cb, ppv);
}
*ppv = HeapReAlloc(hHeap, dwFlags, pv, cb);
return (*ppv) ? S_OK : E_OUTOFMEMORY;
}
};
// HeapAlloc helpers
template <class T>
inline HRESULT HeapAllocBytes(_In_ HANDLE hHeap, _In_ DWORD dwFlags, _In_ size_t cb, _Outptr_result_bytebuffer_(cb) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv)
{
return _AllocBytes<T, CTHeapAllocPolicy>(hHeap, dwFlags, cb, ppv);
}
template <class T>
inline HRESULT HeapReallocBytes(_In_ HANDLE hHeap, _In_ DWORD dwFlags, _In_opt_ T *pv, _In_ size_t cb, _Outptr_result_bytebuffer_(cb) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv)
{
return _ReallocBytes<T, CTHeapAllocPolicy>(hHeap, dwFlags, pv, cb, ppv);
}
template <class T>
inline HRESULT HeapAllocObject(_In_ HANDLE hHeap, _In_ DWORD dwFlags, _Outptr_result_buffer_(1) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv)
{
return _AllocBytes<T, CTHeapAllocPolicy>(hHeap, dwFlags, sizeof(T), ppv);
}
template <class T>
inline HRESULT HeapAllocArray(_In_ HANDLE hHeap, _In_ DWORD dwFlags, _In_ size_t cItems, _Outptr_result_buffer_(cItems) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv)
{
return _AllocArray<T, CTHeapAllocPolicy>(hHeap, dwFlags, cItems, ppv);
}
template <class T>
inline HRESULT HeapReallocArray(_In_ HANDLE hHeap, _In_ DWORD dwFlags, _In_opt_ T *pv, _In_ size_t cItems, _Outptr_result_buffer_(cItems) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv)
{
return _ReallocArray<T, CTHeapAllocPolicy>(hHeap, dwFlags, pv, cItems, ppv);
}
// Zero-initializing HeapAlloc helpers (process heap)
template <class T>
inline HRESULT HeapAllocBytes(_In_ size_t cb, _Outptr_result_bytebuffer_(cb) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv)
{
return HeapAllocBytes(GetProcessHeap(), HEAP_ZERO_MEMORY, cb, ppv);
}
template <class T>
inline HRESULT HeapReallocBytes(_In_opt_ T *pv, _In_ size_t cb, _Outptr_result_bytebuffer_(cb) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv)
{
return HeapReallocBytes(GetProcessHeap(), HEAP_ZERO_MEMORY, pv, cb, ppv);
}
template <class T>
inline HRESULT HeapAllocObject(_Outptr_result_buffer_(1) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv)
{
return HeapAllocObject(GetProcessHeap(), HEAP_ZERO_MEMORY, ppv);
}
template <class T>
inline HRESULT HeapAllocArray(_In_ size_t cItems, _Outptr_result_buffer_(cItems) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv)
{
return HeapAllocArray(GetProcessHeap(), HEAP_ZERO_MEMORY, cItems, ppv);
}
template <class T>
inline HRESULT HeapReallocArray(_In_opt_ T *pv, _In_ size_t cItems, _Outptr_result_buffer_(cItems) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv)
{
return HeapReallocArray(GetProcessHeap(), HEAP_ZERO_MEMORY, pv, cItems, ppv);
}
// HeapAlloc string helpers
inline HRESULT HeapAllocString(_In_ HANDLE hHeap, _In_ DWORD dwFlags, _In_ PCWSTR pszSource, _Outptr_result_nullonfailure_ PWSTR *ppsz)
{
return _AllocString<CTHeapAllocPolicy>(hHeap, dwFlags, pszSource, ppsz);
}
inline HRESULT HeapAllocStringLen(_In_ HANDLE hHeap, _In_ DWORD dwFlags, _In_reads_or_z_opt_(cch) PCNZWCH pszSource, _In_ size_t cch, _Outptr_result_buffer_(cch+1) _On_failure_(_Post_satisfies_(*ppsz == 0)) PWSTR *ppsz)
{
return _AllocStringLen<CTHeapAllocPolicy>(hHeap, dwFlags, pszSource, cch, ppsz);
}
inline HRESULT HeapAllocStringDoubleNullTerminate(_In_ HANDLE hHeap, _In_ DWORD dwFlags, _In_ PCWSTR pszSource, _Outptr_result_nullonfailure_ PZZWSTR *ppsz)
{
return _AllocStringDoubleNullTerminate<CTHeapAllocPolicy>(hHeap, dwFlags, pszSource, ppsz);
}
inline HRESULT HeapAllocStringOpt(_In_ HANDLE hHeap, _In_ DWORD dwFlags, _In_opt_ PCWSTR pszSource, _Outptr_result_maybenull_ _On_failure_(_Post_satisfies_(*ppsz == 0)) PWSTR *ppsz)
{
return _AllocStringOpt<CTHeapAllocPolicy>(hHeap, dwFlags, pszSource, ppsz);
}
// HeapAlloc string helpers (process heap)
inline HRESULT HeapAllocString(_In_ PCWSTR pszSource, _Outptr_result_nullonfailure_ PWSTR *ppsz)
{
return HeapAllocString(GetProcessHeap(), NO_ZERO_INIT, pszSource, ppsz);
}
inline HRESULT HeapAllocStringLen(_In_reads_opt_(cch) PCNZWCH pszSource, _In_ size_t cch, _Outptr_result_buffer_(cch+1) _On_failure_(_Post_satisfies_(*ppsz == 0)) PWSTR *ppsz)
{
return HeapAllocStringLen(GetProcessHeap(), NO_ZERO_INIT, pszSource, cch, ppsz);
}
inline HRESULT HeapAllocStringDoubleNullTerminate(_In_ PCWSTR pszSource, _Outptr_result_nullonfailure_ PZZWSTR *ppsz)
{
return HeapAllocStringDoubleNullTerminate(GetProcessHeap(), NO_ZERO_INIT, pszSource, ppsz);
}
inline HRESULT HeapAllocStringOpt(_In_opt_ PCWSTR pszSource, _Outptr_result_maybenull_ _On_failure_(_Post_satisfies_(*ppsz == 0)) PWSTR *ppsz)
{
return HeapAllocStringOpt(GetProcessHeap(), NO_ZERO_INIT, pszSource, ppsz);
}
#endif // NO_HEAPALLOC_HELPERS
#ifndef NO_GLOBALALLOC_HELPERS
class CTGlobalAllocPolicy
{
public:
static HRESULT Alloc(_In_opt_ HANDLE /*hHeap*/, _In_ DWORD dwFlags, _In_ size_t cb, _Outptr_result_bytebuffer_(cb) _On_failure_(_Post_satisfies_(*ppv == 0)) void **ppv)
{
// ignore flags other than zero-init, assume fixed
*ppv = GlobalAlloc(GMEM_FIXED | (dwFlags & GMEM_ZEROINIT), cb);
return (*ppv) ? S_OK : E_OUTOFMEMORY;
}
static HRESULT Realloc(_In_opt_ HANDLE hHeap, _In_ DWORD dwFlags, _In_opt_ void *pv, _In_ size_t cb, _Outptr_result_bytebuffer_(cb) _On_failure_(_Post_satisfies_(*ppv == 0)) void **ppv)
{
if (pv == NULL)
{
return Alloc(hHeap, dwFlags, cb, ppv);
}
// GMEM_MOVEABLE is correct when reallocating GMEM_FIXED buffers
*ppv = GlobalReAlloc(pv, cb, GMEM_MOVEABLE | (dwFlags & GMEM_ZEROINIT));
return (*ppv) ? S_OK : E_OUTOFMEMORY;
}
};
// GlobalAlloc helpers
template <class T>
inline HRESULT GlobalAllocBytes(_In_ DWORD dwFlags, _In_ size_t cb, _Outptr_result_bytebuffer_(cb) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv)
{
return _AllocBytes<T, CTGlobalAllocPolicy>(NULL, dwFlags, cb, ppv);
}
template <class T>
inline HRESULT GlobalReallocBytes(_In_ DWORD dwFlags, _In_opt_ T *pv, _In_ size_t cb, _Outptr_result_bytebuffer_(cb) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv)
{
return _ReallocBytes<T, CTGlobalAllocPolicy>(NULL, dwFlags, pv, cb, ppv);
}
template <class T>
inline HRESULT GlobalAllocObject(_In_ DWORD dwFlags, _Outptr_result_buffer_(1) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv)
{
return _AllocBytes<T, CTGlobalAllocPolicy>(NULL, dwFlags, sizeof(T), ppv);
}
template <class T>
inline HRESULT GlobalAllocArray(_In_ DWORD dwFlags, _In_ size_t cItems, _Outptr_result_buffer_(cItems) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv)
{
return _AllocArray<T, CTGlobalAllocPolicy>(NULL, dwFlags, cItems, ppv);
}
template <class T>
inline HRESULT GlobalReallocArray(_In_ DWORD dwFlags, _In_opt_ T *pv, _In_ size_t cItems, _Outptr_result_buffer_(cItems) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv)
{
return _ReallocArray<T, CTGlobalAllocPolicy>(NULL, dwFlags, pv, cItems, ppv);
}
// Zero-initializing GlobalAlloc helpers
template <class T>
inline HRESULT GlobalAllocBytes(_In_ size_t cb, _Outptr_result_bytebuffer_(cb) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv)
{
return GlobalAllocBytes<T>(GMEM_ZEROINIT, cb, ppv);
}
template <class T>
inline HRESULT GlobalReallocBytes(_In_opt_ T *pv, _In_ size_t cb, _Outptr_result_bytebuffer_(cb) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv)
{
return GlobalReallocBytes<T>(GMEM_ZEROINIT, pv, cb, ppv);
}
template <class T>
inline HRESULT GlobalAllocObject(_Outptr_result_buffer_(1) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv)
{
return GlobalAllocObject<T>(GMEM_ZEROINIT, ppv);
}
template <class T>
inline HRESULT GlobalAllocArray(_In_ size_t cItems, _Outptr_result_buffer_(cItems) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv)
{
return GlobalAllocArray<T>(GMEM_ZEROINIT, cItems, ppv);
}
template <class T>
inline HRESULT GlobalReallocArray(_In_opt_ T *pv, _In_ size_t cItems, _Outptr_result_buffer_(cItems) _On_failure_(_Post_satisfies_(*ppv == 0)) T **ppv)
{
return GlobalReallocArray<T>(GMEM_ZEROINIT, pv, cItems, ppv);
}
// GlobalAlloc string helpers
inline HRESULT GlobalAllocString(_In_ PCWSTR pszSource, _Outptr_result_nullonfailure_ PWSTR *ppsz)
{
return _AllocString<CTGlobalAllocPolicy>(NULL, NO_ZERO_INIT, pszSource, ppsz);
}
inline HRESULT GlobalAllocStringLen( _In_reads_or_z_opt_(cch) PCNZWCH pszSource, _In_ size_t cch, _Outptr_result_buffer_(cch+1) _On_failure_(_Post_satisfies_(*ppsz == 0)) PWSTR *ppsz)
{
return _AllocStringLen<CTGlobalAllocPolicy>(NULL, NO_ZERO_INIT, pszSource, cch, ppsz);
}
inline HRESULT GlobalAllocStringDoubleNullTerminate(_In_ PCWSTR pszSource, _Outptr_result_nullonfailure_ PZZWSTR *ppsz)
{
return _AllocStringDoubleNullTerminate<CTGlobalAllocPolicy>(NULL, NO_ZERO_INIT, pszSource, ppsz);
}
inline HRESULT GlobalAllocStringOpt(_In_opt_ PCWSTR pszSource, _Outptr_result_maybenull_ _On_failure_(_Post_satisfies_(*ppsz == 0)) PWSTR *ppsz)
{
return _AllocStringOpt<CTGlobalAllocPolicy>(NULL, NO_ZERO_INIT, pszSource, ppsz);
}
#endif // NO_GLOBALALLOC_HELPERS
#endif // __cplusplus
#endif // __memsafe_h__

142
ExplorerPatcher/symbols.c

@ -1,3 +1,4 @@ @@ -1,3 +1,4 @@
#include <stdio.h>
#include "symbols.h"
const char* explorer_SN[EXPLORER_SB_CNT] = {
@ -6,7 +7,7 @@ const char* explorer_SN[EXPLORER_SB_CNT] = { @@ -6,7 +7,7 @@ const char* explorer_SN[EXPLORER_SB_CNT] = {
EXPLORER_SB_2,
EXPLORER_SB_3,
EXPLORER_SB_4,
EXPLORER_SB_5
EXPLORER_SB_5,
};
const char* explorer_SN_26244[1] = {
EXPLORER_SB_4,
@ -19,18 +20,16 @@ const char* twinui_pcshell_SN[TWINUI_PCSHELL_SB_CNT] = { @@ -19,18 +20,16 @@ const char* twinui_pcshell_SN[TWINUI_PCSHELL_SB_CNT] = {
TWINUI_PCSHELL_SB_4,
TWINUI_PCSHELL_SB_5,
TWINUI_PCSHELL_SB_6,
TWINUI_PCSHELL_SB_7,
TWINUI_PCSHELL_SB_8
};
const char* startdocked_SN[STARTDOCKED_SB_CNT] = {
STARTDOCKED_SB_0,
STARTDOCKED_SB_1,
STARTDOCKED_SB_2,
STARTDOCKED_SB_3,
STARTDOCKED_SB_4
STARTDOCKED_SB_4,
};
const char* startui_SN[STARTUI_SB_CNT] = {
STARTUI_SB_0
STARTUI_SB_0,
};
const wchar_t DownloadNotificationXML[] =
@ -53,7 +52,7 @@ BOOL CheckVersion(HKEY hKey, DWORD dwVersion) @@ -53,7 +52,7 @@ BOOL CheckVersion(HKEY hKey, DWORD dwVersion)
{
DWORD dwSize = sizeof(DWORD);
DWORD dwStoredVersion = 0;
if (RegQueryValueExW(hKey, TEXT("Version"), 0, NULL, &dwStoredVersion, &dwSize) == ERROR_SUCCESS)
if (RegQueryValueExW(hKey, TEXT("Version"), 0, NULL, (LPBYTE)&dwStoredVersion, &dwSize) == ERROR_SUCCESS)
{
return dwStoredVersion == dwVersion;
}
@ -62,10 +61,10 @@ BOOL CheckVersion(HKEY hKey, DWORD dwVersion) @@ -62,10 +61,10 @@ BOOL CheckVersion(HKEY hKey, DWORD dwVersion)
void SaveVersion(HKEY hKey, DWORD dwVersion)
{
RegSetValueExW(hKey, TEXT("Version"), 0, REG_DWORD, &dwVersion, sizeof(DWORD));
RegSetValueExW(hKey, TEXT("Version"), 0, REG_DWORD, (const BYTE*)&dwVersion, sizeof(DWORD));
}
static BOOL ProcessExplorerSymbols(const char* pszSettingsPath, DWORD* pOffsets)
static BOOL ProcessExplorerSymbols(char* pszSettingsPath, DWORD* pOffsets)
{
HKEY hKey = NULL;
DWORD dwDisposition;
@ -116,10 +115,10 @@ static BOOL ProcessExplorerSymbols(const char* pszSettingsPath, DWORD* pOffsets) @@ -116,10 +115,10 @@ static BOOL ProcessExplorerSymbols(const char* pszSettingsPath, DWORD* pOffsets)
}
printf("[Symbols] Reading symbols...\n");
if (VnGetSymbols(pszSettingsPath, pOffsets, explorer_SN, ARRAYSIZE(explorer_SN)) != 0)
if (VnGetSymbols(pszSettingsPath, pOffsets, (char**)explorer_SN, ARRAYSIZE(explorer_SN)) != 0)
{
DWORD offsets26244[ARRAYSIZE(explorer_SN_26244)];
if (VnGetSymbols(pszSettingsPath, offsets26244, explorer_SN_26244, ARRAYSIZE(explorer_SN_26244)) == 0)
if (VnGetSymbols(pszSettingsPath, offsets26244, (char**)explorer_SN_26244, ARRAYSIZE(explorer_SN_26244)) == 0)
{
pOffsets[4] = offsets26244[0];
}
@ -131,21 +130,21 @@ static BOOL ProcessExplorerSymbols(const char* pszSettingsPath, DWORD* pOffsets) @@ -131,21 +130,21 @@ static BOOL ProcessExplorerSymbols(const char* pszSettingsPath, DWORD* pOffsets)
}
}
RegSetValueExW(hKey, TEXT(EXPLORER_SB_0), 0, REG_DWORD, &pOffsets[0], sizeof(DWORD));
RegSetValueExW(hKey, TEXT(EXPLORER_SB_1), 0, REG_DWORD, &pOffsets[1], sizeof(DWORD));
RegSetValueExW(hKey, TEXT(EXPLORER_SB_2), 0, REG_DWORD, &pOffsets[2], sizeof(DWORD));
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_0), 0, REG_DWORD, (const BYTE*)&pOffsets[0], sizeof(DWORD));
RegSetValueExW(hKey, TEXT(EXPLORER_SB_1), 0, REG_DWORD, (const BYTE*)&pOffsets[1], sizeof(DWORD));
RegSetValueExW(hKey, TEXT(EXPLORER_SB_2), 0, REG_DWORD, (const BYTE*)&pOffsets[2], sizeof(DWORD));
RegSetValueExW(hKey, TEXT(EXPLORER_SB_3), 0, REG_DWORD, (const BYTE*)&pOffsets[3], sizeof(DWORD));
RegSetValueExW(hKey, TEXT(EXPLORER_SB_4), 0, REG_DWORD, (const BYTE*)&pOffsets[4], sizeof(DWORD));
RegSetValueExW(hKey, TEXT(EXPLORER_SB_5), 0, REG_DWORD, (const BYTE*)&pOffsets[5], sizeof(DWORD));
RegSetValueExA(hKey, "Hash", 0, REG_SZ, szHash, strlen(szHash) + 1);
RegSetValueExA(hKey, "Hash", 0, REG_SZ, szHash, (DWORD)(strlen(szHash) + 1));
SaveVersion(hKey, EXPLORER_SB_VERSION);
if (hKey) RegCloseKey(hKey);
return TRUE;
}
static BOOL ProcessTwinuiPcshellSymbols(const char* pszSettingsPath, DWORD* pOffsets)
static BOOL ProcessTwinuiPcshellSymbols(char* pszSettingsPath, DWORD* pOffsets)
{
HKEY hKey = NULL;
DWORD dwDisposition;
@ -198,20 +197,11 @@ static BOOL ProcessTwinuiPcshellSymbols(const char* pszSettingsPath, DWORD* pOff @@ -198,20 +197,11 @@ static BOOL ProcessTwinuiPcshellSymbols(const char* pszSettingsPath, DWORD* pOff
}
printf("[Symbols] Reading symbols...\n");
if (!IsWindows11())
{
DWORD flOldProtect = 0;
if (VirtualProtect(twinui_pcshell_SN, sizeof(twinui_pcshell_SN), PAGE_EXECUTE_READWRITE, &flOldProtect))
{
twinui_pcshell_SN[1] = twinui_pcshell_SN[0];
VirtualProtect(twinui_pcshell_SN, sizeof(twinui_pcshell_SN), flOldProtect, &flOldProtect);
}
}
if (VnGetSymbols(
pszSettingsPath,
pOffsets,
twinui_pcshell_SN,
IsWindows11() ? TWINUI_PCSHELL_SB_CNT : 4
(char**)twinui_pcshell_SN,
IsWindows11() ? TWINUI_PCSHELL_SB_CNT : 3
))
{
printf("[Symbols] Failure in reading symbols for \"%s\".\n", twinui_pcshell_sb_dll);
@ -223,24 +213,22 @@ static BOOL ProcessTwinuiPcshellSymbols(const char* pszSettingsPath, DWORD* pOff @@ -223,24 +213,22 @@ static BOOL ProcessTwinuiPcshellSymbols(const char* pszSettingsPath, DWORD* pOff
{
pOffsets[1] = 0;
}
RegSetValueExW(hKey, TEXT(TWINUI_PCSHELL_SB_0), 0, REG_DWORD, &pOffsets[0], sizeof(DWORD));
RegSetValueExW(hKey, TEXT(TWINUI_PCSHELL_SB_1), 0, REG_DWORD, &pOffsets[1], sizeof(DWORD));
RegSetValueExW(hKey, TEXT(TWINUI_PCSHELL_SB_2), 0, REG_DWORD, &pOffsets[2], sizeof(DWORD));
RegSetValueExW(hKey, TEXT(TWINUI_PCSHELL_SB_3), 0, REG_DWORD, &pOffsets[3], sizeof(DWORD));
RegSetValueExW(hKey, TEXT(TWINUI_PCSHELL_SB_4), 0, REG_DWORD, &pOffsets[4], sizeof(DWORD));
RegSetValueExW(hKey, TEXT(TWINUI_PCSHELL_SB_5), 0, REG_DWORD, &pOffsets[5], sizeof(DWORD));
RegSetValueExW(hKey, TEXT(TWINUI_PCSHELL_SB_6), 0, REG_DWORD, &pOffsets[6], sizeof(DWORD));
RegSetValueExW(hKey, TEXT(TWINUI_PCSHELL_SB_7), 0, REG_DWORD, &pOffsets[7], sizeof(DWORD));
RegSetValueExW(hKey, TEXT(TWINUI_PCSHELL_SB_8), 0, REG_DWORD, &pOffsets[8], sizeof(DWORD));
RegSetValueExA(hKey, "Hash", 0, REG_SZ, szHash, strlen(szHash) + 1);
RegSetValueExW(hKey, TEXT(TWINUI_PCSHELL_SB_0), 0, REG_DWORD, (const BYTE*)&pOffsets[0], sizeof(DWORD));
RegSetValueExW(hKey, TEXT(TWINUI_PCSHELL_SB_1), 0, REG_DWORD, (const BYTE*)&pOffsets[1], sizeof(DWORD));
RegSetValueExW(hKey, TEXT(TWINUI_PCSHELL_SB_2), 0, REG_DWORD, (const BYTE*)&pOffsets[2], sizeof(DWORD));
RegSetValueExW(hKey, TEXT(TWINUI_PCSHELL_SB_3), 0, REG_DWORD, (const BYTE*)&pOffsets[3], sizeof(DWORD));
RegSetValueExW(hKey, TEXT(TWINUI_PCSHELL_SB_4), 0, REG_DWORD, (const BYTE*)&pOffsets[4], sizeof(DWORD));
RegSetValueExW(hKey, TEXT(TWINUI_PCSHELL_SB_5), 0, REG_DWORD, (const BYTE*)&pOffsets[5], sizeof(DWORD));
RegSetValueExW(hKey, TEXT(TWINUI_PCSHELL_SB_6), 0, REG_DWORD, (const BYTE*)&pOffsets[6], sizeof(DWORD));
RegSetValueExA(hKey, "Hash", 0, REG_SZ, szHash, (DWORD)(strlen(szHash) + 1));
SaveVersion(hKey, TWINUI_PCSHELL_SB_VERSION);
if (hKey) RegCloseKey(hKey);
return TRUE;
}
static BOOL ProcessStartDockedSymbols(const char* pszSettingsPath, DWORD* pOffsets)
static BOOL ProcessStartDockedSymbols(char* pszSettingsPath, DWORD* pOffsets)
{
HKEY hKey = NULL;
DWORD dwDisposition;
@ -296,7 +284,7 @@ static BOOL ProcessStartDockedSymbols(const char* pszSettingsPath, DWORD* pOffse @@ -296,7 +284,7 @@ static BOOL ProcessStartDockedSymbols(const char* pszSettingsPath, DWORD* pOffse
if (VnGetSymbols(
pszSettingsPath,
pOffsets,
startdocked_SN,
(char**)startdocked_SN,
STARTDOCKED_SB_CNT
))
{
@ -305,20 +293,20 @@ static BOOL ProcessStartDockedSymbols(const char* pszSettingsPath, DWORD* pOffse @@ -305,20 +293,20 @@ static BOOL ProcessStartDockedSymbols(const char* pszSettingsPath, DWORD* pOffse
return FALSE;
}
RegSetValueExW(hKey, TEXT(STARTDOCKED_SB_0), 0, REG_DWORD, &pOffsets[0], sizeof(DWORD));
RegSetValueExW(hKey, TEXT(STARTDOCKED_SB_1), 0, REG_DWORD, &pOffsets[1], sizeof(DWORD));
RegSetValueExW(hKey, TEXT(STARTDOCKED_SB_2), 0, REG_DWORD, &pOffsets[2], sizeof(DWORD));
RegSetValueExW(hKey, TEXT(STARTDOCKED_SB_3), 0, REG_DWORD, &pOffsets[3], sizeof(DWORD));
RegSetValueExW(hKey, TEXT(STARTDOCKED_SB_4), 0, REG_DWORD, &pOffsets[4], sizeof(DWORD));
RegSetValueExW(hKey, TEXT(STARTDOCKED_SB_0), 0, REG_DWORD, (const BYTE*)&pOffsets[0], sizeof(DWORD));
RegSetValueExW(hKey, TEXT(STARTDOCKED_SB_1), 0, REG_DWORD, (const BYTE*)&pOffsets[1], sizeof(DWORD));
RegSetValueExW(hKey, TEXT(STARTDOCKED_SB_2), 0, REG_DWORD, (const BYTE*)&pOffsets[2], sizeof(DWORD));
RegSetValueExW(hKey, TEXT(STARTDOCKED_SB_3), 0, REG_DWORD, (const BYTE*)&pOffsets[3], sizeof(DWORD));
RegSetValueExW(hKey, TEXT(STARTDOCKED_SB_4), 0, REG_DWORD, (const BYTE*)&pOffsets[4], sizeof(DWORD));
RegSetValueExA(hKey, "Hash", 0, REG_SZ, szHash, strlen(szHash) + 1);
RegSetValueExA(hKey, "Hash", 0, REG_SZ, szHash, (DWORD)(strlen(szHash) + 1));
SaveVersion(hKey, STARTDOCKED_SB_VERSION);
if (hKey) RegCloseKey(hKey);
return TRUE;
}
static BOOL ProcessStartUISymbols(const char* pszSettingsPath, DWORD* pOffsets)
static BOOL ProcessStartUISymbols(char* pszSettingsPath, DWORD* pOffsets)
{
HKEY hKey = NULL;
DWORD dwDisposition;
@ -384,7 +372,7 @@ static BOOL ProcessStartUISymbols(const char* pszSettingsPath, DWORD* pOffsets) @@ -384,7 +372,7 @@ static BOOL ProcessStartUISymbols(const char* pszSettingsPath, DWORD* pOffsets)
if (VnGetSymbols(
pszSettingsPath,
pOffsets,
startui_SN,
(char**)startui_SN,
STARTUI_SB_CNT
))
{
@ -393,9 +381,9 @@ static BOOL ProcessStartUISymbols(const char* pszSettingsPath, DWORD* pOffsets) @@ -393,9 +381,9 @@ static BOOL ProcessStartUISymbols(const char* pszSettingsPath, DWORD* pOffsets)
return FALSE;
}
RegSetValueExW(hKey, TEXT(STARTUI_SB_0), 0, REG_DWORD, &pOffsets[0], sizeof(DWORD));
RegSetValueExW(hKey, TEXT(STARTUI_SB_0), 0, REG_DWORD, (const BYTE*)&pOffsets[0], sizeof(DWORD));
RegSetValueExA(hKey, "Hash", 0, REG_SZ, szHash, strlen(szHash) + 1);
RegSetValueExA(hKey, "Hash", 0, REG_SZ, szHash, (DWORD)(strlen(szHash) + 1));
SaveVersion(hKey, STARTUI_SB_VERSION);
if (hKey) RegCloseKey(hKey);
@ -452,7 +440,7 @@ DWORD DownloadSymbols(DownloadSymbolsParams* params) @@ -452,7 +440,7 @@ DWORD DownloadSymbols(DownloadSymbolsParams* params)
TEXT("SymbolsLastNotifiedOSBuild"),
0,
NULL,
szLastNotifiedBuild,
(LPBYTE)szLastNotifiedBuild,
&dwSize
);
@ -472,7 +460,7 @@ DWORD DownloadSymbols(DownloadSymbolsParams* params) @@ -472,7 +460,7 @@ DWORD DownloadSymbols(DownloadSymbolsParams* params)
__x_ABI_CWindows_CData_CXml_CDom_CIXmlDocument* inputXml = NULL;
hr = String2IXMLDocument(
buffer,
wcslen(buffer),
(DWORD)wcslen(buffer),
&inputXml,
#ifdef DEBUG
stdout
@ -496,8 +484,8 @@ DWORD DownloadSymbols(DownloadSymbolsParams* params) @@ -496,8 +484,8 @@ DWORD DownloadSymbols(DownloadSymbolsParams* params)
TEXT("SymbolsLastNotifiedOSBuild"),
0,
REG_SZ,
szReportedVersion,
wcslen(szReportedVersion) * sizeof(wchar_t)
(const BYTE*)szReportedVersion,
(DWORD)(wcslen(szReportedVersion) * sizeof(wchar_t))
);
}
@ -600,7 +588,7 @@ DWORD DownloadSymbols(DownloadSymbolsParams* params) @@ -600,7 +588,7 @@ DWORD DownloadSymbols(DownloadSymbolsParams* params)
__x_ABI_CWindows_CData_CXml_CDom_CIXmlDocument* inputXml2 = NULL;
HRESULT hr = String2IXMLDocument(
buffer,
wcslen(buffer),
(DWORD)wcslen(buffer),
&inputXml2,
#ifdef DEBUG
stdout
@ -676,12 +664,12 @@ LoadSymbolsResult LoadSymbols(symbols_addr* symbols_PTRS) @@ -676,12 +664,12 @@ LoadSymbolsResult LoadSymbols(symbols_addr* symbols_PTRS)
&& !_stricmp(szHash, szStoredHash) && CheckVersion(hKey, EXPLORER_SB_VERSION))
{
dwSize = sizeof(DWORD);
RegQueryValueExW(hKey, TEXT(EXPLORER_SB_0), 0, NULL, &symbols_PTRS->explorer_PTRS[0], &dwSize);
RegQueryValueExW(hKey, TEXT(EXPLORER_SB_1), 0, NULL, &symbols_PTRS->explorer_PTRS[1], &dwSize);
RegQueryValueExW(hKey, TEXT(EXPLORER_SB_2), 0, NULL, &symbols_PTRS->explorer_PTRS[2], &dwSize);
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_0), 0, NULL, (LPBYTE)&symbols_PTRS->explorer_PTRS[0], &dwSize);
RegQueryValueExW(hKey, TEXT(EXPLORER_SB_1), 0, NULL, (LPBYTE)&symbols_PTRS->explorer_PTRS[1], &dwSize);
RegQueryValueExW(hKey, TEXT(EXPLORER_SB_2), 0, NULL, (LPBYTE)&symbols_PTRS->explorer_PTRS[2], &dwSize);
RegQueryValueExW(hKey, TEXT(EXPLORER_SB_3), 0, NULL, (LPBYTE)&symbols_PTRS->explorer_PTRS[3], &dwSize);
RegQueryValueExW(hKey, TEXT(EXPLORER_SB_4), 0, NULL, (LPBYTE)&symbols_PTRS->explorer_PTRS[4], &dwSize);
RegQueryValueExW(hKey, TEXT(EXPLORER_SB_5), 0, NULL, (LPBYTE)&symbols_PTRS->explorer_PTRS[5], &dwSize);
bOffsetsValid = TRUE;
}
else
@ -729,15 +717,13 @@ LoadSymbolsResult LoadSymbols(symbols_addr* symbols_PTRS) @@ -729,15 +717,13 @@ LoadSymbolsResult LoadSymbols(symbols_addr* symbols_PTRS)
&& !_stricmp(szHash, szStoredHash) && CheckVersion(hKey, TWINUI_PCSHELL_SB_VERSION))
{
dwSize = sizeof(DWORD);
RegQueryValueExW(hKey, TEXT(TWINUI_PCSHELL_SB_0), 0, NULL, &symbols_PTRS->twinui_pcshell_PTRS[0], &dwSize);
RegQueryValueExW(hKey, TEXT(TWINUI_PCSHELL_SB_1), 0, NULL, &symbols_PTRS->twinui_pcshell_PTRS[1], &dwSize);
RegQueryValueExW(hKey, TEXT(TWINUI_PCSHELL_SB_2), 0, NULL, &symbols_PTRS->twinui_pcshell_PTRS[2], &dwSize);
RegQueryValueExW(hKey, TEXT(TWINUI_PCSHELL_SB_3), 0, NULL, &symbols_PTRS->twinui_pcshell_PTRS[3], &dwSize);
RegQueryValueExW(hKey, TEXT(TWINUI_PCSHELL_SB_4), 0, NULL, &symbols_PTRS->twinui_pcshell_PTRS[4], &dwSize);
RegQueryValueExW(hKey, TEXT(TWINUI_PCSHELL_SB_5), 0, NULL, &symbols_PTRS->twinui_pcshell_PTRS[5], &dwSize);
RegQueryValueExW(hKey, TEXT(TWINUI_PCSHELL_SB_6), 0, NULL, &symbols_PTRS->twinui_pcshell_PTRS[6], &dwSize);
RegQueryValueExW(hKey, TEXT(TWINUI_PCSHELL_SB_7), 0, NULL, &symbols_PTRS->twinui_pcshell_PTRS[7], &dwSize);
RegQueryValueExW(hKey, TEXT(TWINUI_PCSHELL_SB_8), 0, NULL, &symbols_PTRS->twinui_pcshell_PTRS[8], &dwSize);
RegQueryValueExW(hKey, TEXT(TWINUI_PCSHELL_SB_0), 0, NULL, (LPBYTE)&symbols_PTRS->twinui_pcshell_PTRS[0], &dwSize);
RegQueryValueExW(hKey, TEXT(TWINUI_PCSHELL_SB_1), 0, NULL, (LPBYTE)&symbols_PTRS->twinui_pcshell_PTRS[1], &dwSize);
RegQueryValueExW(hKey, TEXT(TWINUI_PCSHELL_SB_2), 0, NULL, (LPBYTE)&symbols_PTRS->twinui_pcshell_PTRS[2], &dwSize);
RegQueryValueExW(hKey, TEXT(TWINUI_PCSHELL_SB_3), 0, NULL, (LPBYTE)&symbols_PTRS->twinui_pcshell_PTRS[3], &dwSize);
RegQueryValueExW(hKey, TEXT(TWINUI_PCSHELL_SB_4), 0, NULL, (LPBYTE)&symbols_PTRS->twinui_pcshell_PTRS[4], &dwSize);
RegQueryValueExW(hKey, TEXT(TWINUI_PCSHELL_SB_5), 0, NULL, (LPBYTE)&symbols_PTRS->twinui_pcshell_PTRS[5], &dwSize);
RegQueryValueExW(hKey, TEXT(TWINUI_PCSHELL_SB_6), 0, NULL, (LPBYTE)&symbols_PTRS->twinui_pcshell_PTRS[6], &dwSize);
bOffsetsValid = TRUE;
}
else
@ -784,11 +770,11 @@ LoadSymbolsResult LoadSymbols(symbols_addr* symbols_PTRS) @@ -784,11 +770,11 @@ LoadSymbolsResult LoadSymbols(symbols_addr* symbols_PTRS)
&& !_stricmp(szHash, szStoredHash) && CheckVersion(hKey, STARTDOCKED_SB_VERSION))
{
dwSize = sizeof(DWORD);
RegQueryValueExW(hKey, TEXT(STARTDOCKED_SB_0), 0, NULL, &symbols_PTRS->startdocked_PTRS[0], &dwSize);
RegQueryValueExW(hKey, TEXT(STARTDOCKED_SB_1), 0, NULL, &symbols_PTRS->startdocked_PTRS[1], &dwSize);
RegQueryValueExW(hKey, TEXT(STARTDOCKED_SB_2), 0, NULL, &symbols_PTRS->startdocked_PTRS[2], &dwSize);
RegQueryValueExW(hKey, TEXT(STARTDOCKED_SB_3), 0, NULL, &symbols_PTRS->startdocked_PTRS[3], &dwSize);
RegQueryValueExW(hKey, TEXT(STARTDOCKED_SB_4), 0, NULL, &symbols_PTRS->startdocked_PTRS[4], &dwSize);
RegQueryValueExW(hKey, TEXT(STARTDOCKED_SB_0), 0, NULL, (LPBYTE)&symbols_PTRS->startdocked_PTRS[0], &dwSize);
RegQueryValueExW(hKey, TEXT(STARTDOCKED_SB_1), 0, NULL, (LPBYTE)&symbols_PTRS->startdocked_PTRS[1], &dwSize);
RegQueryValueExW(hKey, TEXT(STARTDOCKED_SB_2), 0, NULL, (LPBYTE)&symbols_PTRS->startdocked_PTRS[2], &dwSize);
RegQueryValueExW(hKey, TEXT(STARTDOCKED_SB_3), 0, NULL, (LPBYTE)&symbols_PTRS->startdocked_PTRS[3], &dwSize);
RegQueryValueExW(hKey, TEXT(STARTDOCKED_SB_4), 0, NULL, (LPBYTE)&symbols_PTRS->startdocked_PTRS[4], &dwSize);
bOffsetsValid = TRUE;
}
else
@ -838,7 +824,7 @@ LoadSymbolsResult LoadSymbols(symbols_addr* symbols_PTRS) @@ -838,7 +824,7 @@ LoadSymbolsResult LoadSymbols(symbols_addr* symbols_PTRS)
&& !_stricmp(szHash, szStoredHash) && CheckVersion(hKey, STARTUI_SB_VERSION))
{
dwSize = sizeof(DWORD);
RegQueryValueExW(hKey, TEXT(STARTUI_SB_0), 0, NULL, &symbols_PTRS->startui_PTRS[0], &dwSize);
RegQueryValueExW(hKey, TEXT(STARTUI_SB_0), 0, NULL, (LPBYTE)&symbols_PTRS->startui_PTRS[0], &dwSize);
bOffsetsValid = TRUE;
}
else

18
ExplorerPatcher/symbols.h

@ -25,16 +25,14 @@ @@ -25,16 +25,14 @@
#define TWINUI_PCSHELL_SB_NAME "twinui.pcshell"
#define TWINUI_PCSHELL_SB_0 "CImmersiveContextMenuOwnerDrawHelper::s_ContextMenuWndProc"
#define TWINUI_PCSHELL_SB_1 "CLauncherTipContextMenu::GetMenuItemsAsync"
#define TWINUI_PCSHELL_SB_2 "ImmersiveContextMenuHelper::ApplyOwnerDrawToMenu"
#define TWINUI_PCSHELL_SB_3 "ImmersiveContextMenuHelper::RemoveOwnerDrawFromMenu"
#define TWINUI_PCSHELL_SB_4 "CLauncherTipContextMenu::_ExecuteShutdownCommand"
#define TWINUI_PCSHELL_SB_5 "CLauncherTipContextMenu::_ExecuteCommand"
#define TWINUI_PCSHELL_SB_6 "CLauncherTipContextMenu::ShowLauncherTipContextMenu"
#define TWINUI_PCSHELL_SB_7 "CMultitaskingViewManager::_CreateXamlMTVHost"
#define TWINUI_PCSHELL_SB_8 "CMultitaskingViewManager::_CreateDCompMTVHost"
#define TWINUI_PCSHELL_SB_CNT 9
#define TWINUI_PCSHELL_SB_VERSION 1
#define TWINUI_PCSHELL_SB_1 "ImmersiveContextMenuHelper::ApplyOwnerDrawToMenu"
#define TWINUI_PCSHELL_SB_2 "ImmersiveContextMenuHelper::RemoveOwnerDrawFromMenu"
#define TWINUI_PCSHELL_SB_3 "CLauncherTipContextMenu::_ExecuteShutdownCommand"
#define TWINUI_PCSHELL_SB_4 "CLauncherTipContextMenu::_ExecuteCommand"
#define TWINUI_PCSHELL_SB_5 "CMultitaskingViewManager::_CreateXamlMTVHost"
#define TWINUI_PCSHELL_SB_6 "CMultitaskingViewManager::_CreateDCompMTVHost"
#define TWINUI_PCSHELL_SB_CNT 7
#define TWINUI_PCSHELL_SB_VERSION 2
#define STARTDOCKED_SB_NAME "StartDocked"
#define STARTDOCKED_SB_0 "StartDocked::LauncherFrame::ShowAllApps" // UNUSED

Loading…
Cancel
Save