Skip to content

Commit

Permalink
add support winxp on latest vc2019
Browse files Browse the repository at this point in the history
  • Loading branch information
ctapmex committed Apr 25, 2021
1 parent d2bbffa commit a0430c0
Show file tree
Hide file tree
Showing 2 changed files with 230 additions and 2 deletions.
5 changes: 5 additions & 0 deletions libs/far3sdk/vc_crt_fix.asm
Expand Up @@ -63,5 +63,10 @@ endif
HOOK InitializeCriticalSectionEx , 12, :dword, :dword, :dword
HOOK CompareStringEx , 36, :dword, :dword, :dword, :dword, :dword, :dword, :dword, :dword, :dword
HOOK LCMapStringEx , 36, :dword, :dword, :dword, :dword, :dword, :dword, :dword, :dword, :dword
HOOK InitializeSRWLock , 4, :dword
HOOK AcquireSRWLockExclusive , 4, :dword
HOOK AcquireSRWLockShared , 4, :dword
HOOK ReleaseSRWLockExclusive , 4, :dword
HOOK ReleaseSRWLockShared , 4, :dword

end
227 changes: 225 additions & 2 deletions libs/far3sdk/vc_crt_fix_impl.cpp
Expand Up @@ -31,9 +31,10 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include <utility>

#include <windows.h>
#include <string>
#include <utility>
#include <vector>

#ifdef __clang__
#pragma clang diagnostic ignored "-Wmissing-prototypes"
Expand Down Expand Up @@ -471,6 +472,228 @@ extern "C" int WINAPI LCMapStringExWrapper(LPCWSTR LocaleName, DWORD MapFlags, L
return Function(LocaleName, MapFlags, SrcStr, SrcCount, DestStr, DestCount, VersionInformation, Reserved, SortHandle);
}

namespace RWLock {
typedef struct _RTL_RWLOCK
{
RTL_CRITICAL_SECTION rtlCS;

HANDLE hSharedReleaseSemaphore;
UINT uSharedWaiters;

HANDLE hExclusiveReleaseSemaphore;
UINT uExclusiveWaiters;

INT iNumberActive;
HANDLE hOwningThreadId;
DWORD dwTimeoutBoost;
PVOID pDebugInfo;
} RTL_RWLOCK, *LPRTL_RWLOCK;

typedef void(__stdcall* RtlManagePtr)(LPRTL_RWLOCK);
typedef BYTE(__stdcall* RtlOperatePtr)(LPRTL_RWLOCK, BYTE);

struct elem_arr
{
PSRWLOCK psrwlock;
RTL_RWLOCK rwlock;
};

class RWLockXP // Implementation for Windows XP
{
public:
RWLockXP()
: hGetProcIDDLL(nullptr),
RtlInitializeResource_func(nullptr),
RtlDeleteResource_func(nullptr),
RtlReleaseResource_func(nullptr),
RtlAcquireResourceExclusive_func(nullptr),
RtlAcquireResourceShared_func(nullptr)
{
wchar_t path[MAX_PATH] = {0};
GetSystemDirectoryW(path, sizeof(path));
std::wstring dllPath = std::wstring(path) + L"\\ntdll.dll";
HINSTANCE hGetProcIDDLL = LoadLibraryW(dllPath.c_str());
if (hGetProcIDDLL) {
RtlDeleteResource_func = (RtlManagePtr) GetProcAddress(hGetProcIDDLL, "RtlDeleteResource");
if (!RtlDeleteResource_func) {
return;
}
RtlReleaseResource_func = (RtlManagePtr) GetProcAddress(hGetProcIDDLL, "RtlReleaseResource");
if (!RtlReleaseResource_func) {
return;
}
RtlAcquireResourceExclusive_func = (RtlOperatePtr) GetProcAddress(hGetProcIDDLL, "RtlAcquireResourceExclusive");
if (!RtlAcquireResourceExclusive_func) {
return;
}
RtlAcquireResourceShared_func = (RtlOperatePtr) GetProcAddress(hGetProcIDDLL, "RtlAcquireResourceShared");
if (!RtlAcquireResourceShared_func) {
return;
}

RtlInitializeResource_func = (RtlManagePtr) GetProcAddress(hGetProcIDDLL, "RtlInitializeResource");
if (!RtlInitializeResource_func) {
return;
}
}
}

~RWLockXP()
{
if (RtlDeleteResource_func) {
for (auto a : array) {
RtlDeleteResource_func(&a.rwlock);
}
}
if (hGetProcIDDLL) {
FreeLibrary(hGetProcIDDLL);
}
}

void InitializeSRWLock(PSRWLOCK& SRWLock)
{
if (RtlInitializeResource_func) {
elem_arr a {};
a.psrwlock = SRWLock;

RtlInitializeResource_func(&a.rwlock);
array.push_back(a);
}
}

void readLock(PSRWLOCK& SRWLock)
{
if (RtlAcquireResourceShared_func) {
for (auto a : array) {
if (a.psrwlock == SRWLock) {
RtlAcquireResourceShared_func(&a.rwlock, TRUE);
}
}
}
}

void readUnLock(PSRWLOCK& SRWLock)
{
if (RtlReleaseResource_func) {
for (auto a : array) {
if (a.psrwlock == SRWLock) {
RtlReleaseResource_func(&a.rwlock);
}
}
}
}

void writeLock(PSRWLOCK& SRWLock)
{
if (RtlAcquireResourceExclusive_func) {
for (auto a : array) {
if (a.psrwlock == SRWLock) {
RtlAcquireResourceExclusive_func(&a.rwlock, TRUE);
}
}
}
}

void writeUnLock(PSRWLOCK& SRWLock)
{
if (RtlReleaseResource_func) {
for (auto a : array) {
if (a.psrwlock == SRWLock) {
RtlReleaseResource_func(&a.rwlock);
}
}
}
}

private:
HINSTANCE hGetProcIDDLL;
RtlManagePtr RtlInitializeResource_func;
RtlManagePtr RtlDeleteResource_func;
RtlManagePtr RtlReleaseResource_func;
RtlOperatePtr RtlAcquireResourceExclusive_func;
RtlOperatePtr RtlAcquireResourceShared_func;

std::vector<elem_arr> array;
};

static RWLockXP locks;
} // namespace RWLock

extern "C" void WINAPI InitializeSRWLockWrapper(PSRWLOCK SRWLock)
{
struct implementation
{
static void WINAPI InitializeSRWLock(PSRWLOCK SRWLock)
{
using namespace RWLock;
locks.InitializeSRWLock(SRWLock);
}
};

CREATE_FUNCTION_POINTER(modules::kernel32, InitializeSRWLock);
return Function(SRWLock);
}

extern "C" void WINAPI AcquireSRWLockExclusiveWrapper(PSRWLOCK SRWLock)
{
struct implementation
{
static void WINAPI AcquireSRWLockExclusive(PSRWLOCK SRWLock)
{
using namespace RWLock;
locks.writeLock(SRWLock);
}
};

CREATE_FUNCTION_POINTER(modules::kernel32, AcquireSRWLockExclusive);
return Function(SRWLock);
}

extern "C" void WINAPI AcquireSRWLockSharedWrapper(PSRWLOCK SRWLock)
{
struct implementation
{
static void WINAPI AcquireSRWLockShared(PSRWLOCK SRWLock)
{
using namespace RWLock;
locks.readLock(SRWLock);
}
};

CREATE_FUNCTION_POINTER(modules::kernel32, AcquireSRWLockShared);
return Function(SRWLock);
}

extern "C" void WINAPI ReleaseSRWLockExclusiveWrapper(PSRWLOCK SRWLock)
{
struct implementation
{
static void WINAPI ReleaseSRWLockExclusive(PSRWLOCK SRWLock)
{
using namespace RWLock;
locks.writeUnLock(SRWLock);
}
};

CREATE_FUNCTION_POINTER(modules::kernel32, ReleaseSRWLockExclusive);
return Function(SRWLock);
}

extern "C" void WINAPI ReleaseSRWLockSharedWrapper(PSRWLOCK SRWLock)
{
struct implementation
{
static void WINAPI ReleaseSRWLockShared(PSRWLOCK SRWLock)
{
using namespace RWLock;
locks.readUnLock(SRWLock);
}
};

CREATE_FUNCTION_POINTER(modules::kernel32, ReleaseSRWLockShared);
return Function(SRWLock);
}


// disable VS2015 telemetry
extern "C"
Expand Down

0 comments on commit a0430c0

Please sign in to comment.