mirror of
https://github.com/decompals/wibo.git
synced 2025-10-15 14:45:12 +00:00
Implement some ActCtx functions for msvcr80.dll
This commit is contained in:
parent
5a2f8e2926
commit
b87fb5e472
@ -221,6 +221,17 @@ if(BUILD_TESTING)
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test/test_heap.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test/test_assert.h)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${WIBO_TEST_BIN_DIR}/test_actctx.exe
|
||||
COMMAND ${WIBO_MINGW_CC} -Wall -Wextra -O2
|
||||
-I${CMAKE_CURRENT_SOURCE_DIR}/test
|
||||
-o test_actctx.exe
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test/test_actctx.c
|
||||
WORKING_DIRECTORY ${WIBO_TEST_BIN_DIR}
|
||||
DEPENDS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test/test_actctx.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test/test_assert.h)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${WIBO_TEST_BIN_DIR}/test_overlapped_io.exe
|
||||
COMMAND ${WIBO_MINGW_CC} -Wall -Wextra -O2
|
||||
@ -310,6 +321,7 @@ if(BUILD_TESTING)
|
||||
${WIBO_TEST_BIN_DIR}/test_resources.exe
|
||||
${WIBO_TEST_BIN_DIR}/test_threading.exe
|
||||
${WIBO_TEST_BIN_DIR}/test_heap.exe
|
||||
${WIBO_TEST_BIN_DIR}/test_actctx.exe
|
||||
${WIBO_TEST_BIN_DIR}/test_overlapped_io.exe
|
||||
${WIBO_TEST_BIN_DIR}/test_time.exe
|
||||
${WIBO_TEST_BIN_DIR}/test_virtualalloc.exe
|
||||
@ -358,6 +370,12 @@ if(BUILD_TESTING)
|
||||
WORKING_DIRECTORY ${WIBO_TEST_BIN_DIR}
|
||||
DEPENDS wibo.build_fixtures)
|
||||
|
||||
add_test(NAME wibo.test_actctx
|
||||
COMMAND $<TARGET_FILE:wibo> ${WIBO_TEST_BIN_DIR}/test_actctx.exe)
|
||||
set_tests_properties(wibo.test_actctx PROPERTIES
|
||||
WORKING_DIRECTORY ${WIBO_TEST_BIN_DIR}
|
||||
DEPENDS wibo.build_fixtures)
|
||||
|
||||
add_test(NAME wibo.test_overlapped_io
|
||||
COMMAND $<TARGET_FILE:wibo> ${WIBO_TEST_BIN_DIR}/test_overlapped_io.exe)
|
||||
set_tests_properties(wibo.test_overlapped_io PROPERTIES
|
||||
|
@ -246,6 +246,10 @@ void *resolveByName(const char *name) {
|
||||
return (void *)kernel32::GetCurrentDirectoryA;
|
||||
if (strcmp(name, "GetCurrentDirectoryW") == 0)
|
||||
return (void *)kernel32::GetCurrentDirectoryW;
|
||||
if (strcmp(name, "GetSystemWindowsDirectoryA") == 0)
|
||||
return (void *)kernel32::GetSystemWindowsDirectoryA;
|
||||
if (strcmp(name, "GetSystemWindowsDirectoryW") == 0)
|
||||
return (void *)kernel32::GetSystemWindowsDirectoryW;
|
||||
if (strcmp(name, "SetCurrentDirectoryA") == 0)
|
||||
return (void *)kernel32::SetCurrentDirectoryA;
|
||||
if (strcmp(name, "SetCurrentDirectoryW") == 0)
|
||||
@ -264,6 +268,10 @@ void *resolveByName(const char *name) {
|
||||
return (void *)kernel32::DecodePointer;
|
||||
if (strcmp(name, "SetDllDirectoryA") == 0)
|
||||
return (void *)kernel32::SetDllDirectoryA;
|
||||
if (strcmp(name, "FindActCtxSectionStringA") == 0)
|
||||
return (void *)kernel32::FindActCtxSectionStringA;
|
||||
if (strcmp(name, "FindActCtxSectionStringW") == 0)
|
||||
return (void *)kernel32::FindActCtxSectionStringW;
|
||||
if (strcmp(name, "GetLongPathNameA") == 0)
|
||||
return (void *)kernel32::GetLongPathNameA;
|
||||
if (strcmp(name, "GetLongPathNameW") == 0)
|
||||
|
@ -312,7 +312,7 @@ BOOL WIN_FUNC HeapFree(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem) {
|
||||
return FALSE;
|
||||
}
|
||||
if (!mi_heap_check_owned(record->heap, lpMem)) {
|
||||
DEBUG_LOG("HeapFree: block %p not owned by heap %p\n", lpMem, record->heap);
|
||||
DEBUG_LOG("-> INVALID_PARAMETER (not owned)\n");
|
||||
wibo::lastError = ERROR_INVALID_PARAMETER;
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -13,11 +13,13 @@
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <limits>
|
||||
#include <mimalloc.h>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/statvfs.h>
|
||||
#include <system_error>
|
||||
@ -298,7 +300,82 @@ constexpr DWORD kComputerNameRequiredSize = kComputerNameLength + 1;
|
||||
constexpr const char kComputerNameAnsi[] = "COMPNAME";
|
||||
const uint16_t kComputerNameWide[] = {u'C', u'O', u'M', u'P', u'N', u'A', u'M', u'E', 0};
|
||||
|
||||
struct DllRedirectionEntry {
|
||||
std::string nameLower;
|
||||
ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION dllData;
|
||||
};
|
||||
|
||||
struct ActivationContext {
|
||||
std::vector<DllRedirectionEntry> dllRedirections;
|
||||
};
|
||||
|
||||
ActivationContext g_builtinActCtx;
|
||||
|
||||
ActivationContext *currentActivationContext() {
|
||||
// TODO: hook into real activation context stack once we have it.
|
||||
return &g_builtinActCtx;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
void ensureDefaultActivationContext() {
|
||||
static std::once_flag initFlag;
|
||||
std::call_once(initFlag, [] {
|
||||
ActivationContext *ctx = currentActivationContext();
|
||||
auto addDll = [ctx](const std::string &name) {
|
||||
DllRedirectionEntry entry;
|
||||
entry.nameLower = stringToLower(name);
|
||||
entry.dllData.Size = sizeof(entry.dllData);
|
||||
entry.dllData.Flags = ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_OMITS_ASSEMBLY_ROOT;
|
||||
entry.dllData.TotalPathLength = 0;
|
||||
entry.dllData.PathSegmentCount = 0;
|
||||
entry.dllData.PathSegmentOffset = 0;
|
||||
ctx->dllRedirections.emplace_back(std::move(entry));
|
||||
};
|
||||
addDll("msvcr80.dll");
|
||||
addDll("msvcp80.dll");
|
||||
addDll("mfc80.dll");
|
||||
addDll("mfc80u.dll");
|
||||
addDll("msvcrt.dll");
|
||||
});
|
||||
}
|
||||
|
||||
constexpr const char kVc80ManifestName[] = "Microsoft.VC80.CRT.manifest";
|
||||
|
||||
void ensureVc80ManifestOnDisk(const DllRedirectionEntry &entry) {
|
||||
static std::once_flag manifestOnce;
|
||||
if (entry.nameLower != "msvcr80.dll") {
|
||||
return;
|
||||
}
|
||||
std::call_once(manifestOnce, [] {
|
||||
wibo::ModuleInfo *module = wibo::findLoadedModule("msvcr80.dll");
|
||||
if (!module || module->resolvedPath.empty()) {
|
||||
DEBUG_LOG("VC80 manifest: module not yet loaded, skipping creation\n");
|
||||
return;
|
||||
}
|
||||
std::filesystem::path manifestPath = module->resolvedPath.parent_path() / kVc80ManifestName;
|
||||
std::error_code ec;
|
||||
if (std::filesystem::exists(manifestPath, ec)) {
|
||||
return;
|
||||
}
|
||||
constexpr const char kManifestContents[] =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n"
|
||||
"<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">\n"
|
||||
" <assemblyIdentity type=\"win32\" name=\"Microsoft.VC80.CRT\" version=\"8.0.50727.762\" processorArchitecture=\"x86\" publicKeyToken=\"1fc8b3b9a1e18e3b\"/>\n"
|
||||
" <file name=\"msvcr80.dll\"/>\n"
|
||||
" <file name=\"msvcp80.dll\"/>\n"
|
||||
" <file name=\"msvcm80.dll\"/>\n"
|
||||
"</assembly>\n";
|
||||
std::ofstream out(manifestPath, std::ios::binary);
|
||||
if (!out) {
|
||||
DEBUG_LOG("VC80 manifest: failed to create %s\n", manifestPath.string().c_str());
|
||||
return;
|
||||
}
|
||||
out.write(kManifestContents, sizeof(kManifestContents) - 1);
|
||||
if (!out) {
|
||||
DEBUG_LOG("VC80 manifest: write error for %s\n", manifestPath.string().c_str());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
namespace kernel32 {
|
||||
|
||||
@ -553,6 +630,90 @@ BOOL WIN_FUNC SetDllDirectoryA(LPCSTR lpPathName) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL WIN_FUNC FindActCtxSectionStringA(DWORD dwFlags, const GUID *lpExtensionGuid, ULONG ulSectionId,
|
||||
LPCSTR lpStringToFind, PACTCTX_SECTION_KEYED_DATA ReturnedData) {
|
||||
DEBUG_LOG("FindActCtxSectionStringA(%#x, %p, %u, %s, %p)\n", dwFlags, lpExtensionGuid, ulSectionId,
|
||||
lpStringToFind ? lpStringToFind : "<null>", ReturnedData);
|
||||
std::vector<uint16_t> wideStorage;
|
||||
if (lpStringToFind) {
|
||||
size_t length = strlen(lpStringToFind);
|
||||
wideStorage.resize(length + 1);
|
||||
for (size_t i = 0; i <= length; ++i) {
|
||||
wideStorage[i] = static_cast<uint8_t>(lpStringToFind[i]);
|
||||
}
|
||||
}
|
||||
const uint16_t *widePtr = wideStorage.empty() ? nullptr : wideStorage.data();
|
||||
return FindActCtxSectionStringW(dwFlags, lpExtensionGuid, ulSectionId,
|
||||
reinterpret_cast<LPCWSTR>(widePtr), ReturnedData);
|
||||
}
|
||||
|
||||
BOOL WIN_FUNC FindActCtxSectionStringW(DWORD dwFlags, const GUID *lpExtensionGuid, ULONG ulSectionId,
|
||||
LPCWSTR lpStringToFind, PACTCTX_SECTION_KEYED_DATA ReturnedData) {
|
||||
std::string lookup = lpStringToFind ? wideStringToString(lpStringToFind) : std::string();
|
||||
DEBUG_LOG("FindActCtxSectionStringW(%#x, %p, %u, %s, %p)\n", dwFlags, lpExtensionGuid, ulSectionId,
|
||||
lookup.c_str(), ReturnedData);
|
||||
|
||||
if (lpExtensionGuid) {
|
||||
wibo::lastError = ERROR_INVALID_PARAMETER;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!ReturnedData) {
|
||||
wibo::lastError = ERROR_INVALID_PARAMETER;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (dwFlags & ~FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX) {
|
||||
wibo::lastError = ERROR_INVALID_PARAMETER;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ULONG originalSize = ReturnedData->cbSize;
|
||||
if (originalSize < sizeof(ACTCTX_SECTION_KEYED_DATA)) {
|
||||
wibo::lastError = ERROR_INSUFFICIENT_BUFFER;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ensureDefaultActivationContext();
|
||||
ActivationContext *ctx = currentActivationContext();
|
||||
const DllRedirectionEntry *matchedEntry = nullptr;
|
||||
if (ulSectionId == ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION && !lookup.empty()) {
|
||||
std::string lowerLookup = stringToLower(lookup);
|
||||
for (const auto &entry : ctx->dllRedirections) {
|
||||
if (entry.nameLower == lowerLookup) {
|
||||
matchedEntry = &entry;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t zeroSize = std::min(static_cast<size_t>(ReturnedData->cbSize), sizeof(*ReturnedData));
|
||||
std::memset(ReturnedData, 0, zeroSize);
|
||||
ReturnedData->cbSize = originalSize;
|
||||
ReturnedData->ulDataFormatVersion = 1;
|
||||
ReturnedData->ulFlags = ACTCTX_SECTION_KEYED_DATA_FLAG_FOUND_IN_ACTCTX;
|
||||
if (dwFlags & FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX) {
|
||||
ReturnedData->hActCtx = reinterpret_cast<HANDLE>(&g_builtinActCtx);
|
||||
}
|
||||
|
||||
if (!matchedEntry) {
|
||||
wibo::lastError = ERROR_SXS_KEY_NOT_FOUND;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ensureVc80ManifestOnDisk(*matchedEntry);
|
||||
|
||||
ReturnedData->lpData = const_cast<ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION *>(&matchedEntry->dllData);
|
||||
ReturnedData->ulLength = matchedEntry->dllData.Size;
|
||||
ReturnedData->lpSectionBase = const_cast<ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION *>(&matchedEntry->dllData);
|
||||
ReturnedData->ulSectionTotalLength = matchedEntry->dllData.Size;
|
||||
ReturnedData->ulAssemblyRosterIndex = 1;
|
||||
ReturnedData->AssemblyMetadata = {};
|
||||
|
||||
wibo::lastError = ERROR_SUCCESS;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void tryMarkExecutable(void *mem) {
|
||||
if (!mem) {
|
||||
return;
|
||||
@ -824,6 +985,27 @@ UINT WIN_FUNC GetWindowsDirectoryA(LPSTR lpBuffer, UINT uSize) {
|
||||
return static_cast<UINT>(len);
|
||||
}
|
||||
|
||||
UINT WIN_FUNC GetSystemWindowsDirectoryA(LPSTR lpBuffer, UINT uSize) {
|
||||
DEBUG_LOG("GetSystemWindowsDirectoryA(%p, %u)\n", lpBuffer, uSize);
|
||||
return GetWindowsDirectoryA(lpBuffer, uSize);
|
||||
}
|
||||
|
||||
UINT WIN_FUNC GetSystemWindowsDirectoryW(LPWSTR lpBuffer, UINT uSize) {
|
||||
DEBUG_LOG("GetSystemWindowsDirectoryW(%p, %u)\n", lpBuffer, uSize);
|
||||
if (!lpBuffer) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *windowsDir = "C:\\Windows";
|
||||
auto wide = stringToWideString(windowsDir);
|
||||
UINT length = static_cast<UINT>(wide.size() - 1);
|
||||
if (uSize < length + 1) {
|
||||
return length + 1;
|
||||
}
|
||||
std::memcpy(lpBuffer, wide.data(), (length + 1) * sizeof(uint16_t));
|
||||
return length;
|
||||
}
|
||||
|
||||
DWORD WIN_FUNC GetCurrentDirectoryA(DWORD nBufferLength, LPSTR lpBuffer) {
|
||||
HOST_CONTEXT_GUARD();
|
||||
DEBUG_LOG("GetCurrentDirectoryA(%u, %p)\n", nBufferLength, lpBuffer);
|
||||
|
@ -4,6 +4,61 @@
|
||||
|
||||
#include <cstdarg>
|
||||
|
||||
struct GUID;
|
||||
|
||||
struct ACTCTX_SECTION_KEYED_DATA_ASSEMBLY_METADATA {
|
||||
PVOID lpInformation;
|
||||
PVOID lpSectionBase;
|
||||
ULONG ulSectionLength;
|
||||
PVOID lpSectionGlobalData;
|
||||
ULONG ulSectionGlobalDataLength;
|
||||
};
|
||||
|
||||
struct ACTCTX_SECTION_KEYED_DATA {
|
||||
ULONG cbSize;
|
||||
ULONG ulDataFormatVersion;
|
||||
PVOID lpData;
|
||||
ULONG ulLength;
|
||||
PVOID lpSectionGlobalData;
|
||||
ULONG ulSectionGlobalDataLength;
|
||||
PVOID lpSectionBase;
|
||||
ULONG ulSectionTotalLength;
|
||||
HANDLE hActCtx;
|
||||
ULONG ulAssemblyRosterIndex;
|
||||
ULONG ulFlags;
|
||||
ACTCTX_SECTION_KEYED_DATA_ASSEMBLY_METADATA AssemblyMetadata;
|
||||
};
|
||||
|
||||
using PACTCTX_SECTION_KEYED_DATA = ACTCTX_SECTION_KEYED_DATA *;
|
||||
using PCACTCTX_SECTION_KEYED_DATA = const ACTCTX_SECTION_KEYED_DATA *;
|
||||
|
||||
constexpr DWORD FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX = 0x00000001;
|
||||
|
||||
constexpr ULONG ACTIVATION_CONTEXT_SECTION_ASSEMBLY_INFORMATION = 1;
|
||||
constexpr ULONG ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION = 2;
|
||||
constexpr ULONG ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION = 3;
|
||||
constexpr ULONG ACTIVATION_CONTEXT_SECTION_COM_PROGID_REDIRECTION = 7;
|
||||
|
||||
constexpr ULONG ACTCTX_SECTION_KEYED_DATA_FLAG_FOUND_IN_ACTCTX = 0x00000001;
|
||||
|
||||
constexpr ULONG ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_INCLUDES_BASE_NAME = 1;
|
||||
constexpr ULONG ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_OMITS_ASSEMBLY_ROOT = 2;
|
||||
constexpr ULONG ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_EXPAND = 4;
|
||||
constexpr ULONG ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_SYSTEM_DEFAULT_REDIRECTED_SYSTEM32_DLL = 8;
|
||||
|
||||
struct ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION {
|
||||
ULONG Size;
|
||||
ULONG Flags;
|
||||
ULONG TotalPathLength;
|
||||
ULONG PathSegmentCount;
|
||||
ULONG PathSegmentOffset;
|
||||
};
|
||||
|
||||
struct ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_SEGMENT {
|
||||
ULONG Length;
|
||||
ULONG Offset;
|
||||
};
|
||||
|
||||
namespace kernel32 {
|
||||
|
||||
BOOL WIN_FUNC IsBadReadPtr(LPCVOID lp, UINT_PTR ucb);
|
||||
@ -21,6 +76,11 @@ PVOID WIN_FUNC EncodePointer(PVOID Ptr);
|
||||
PVOID WIN_FUNC DecodePointer(PVOID Ptr);
|
||||
BOOL WIN_FUNC SetDllDirectoryA(LPCSTR lpPathName);
|
||||
|
||||
BOOL WIN_FUNC FindActCtxSectionStringA(DWORD dwFlags, const GUID *lpExtensionGuid, ULONG ulSectionId,
|
||||
LPCSTR lpStringToFind, PACTCTX_SECTION_KEYED_DATA ReturnedData);
|
||||
BOOL WIN_FUNC FindActCtxSectionStringW(DWORD dwFlags, const GUID *lpExtensionGuid, ULONG ulSectionId,
|
||||
LPCWSTR lpStringToFind, PACTCTX_SECTION_KEYED_DATA ReturnedData);
|
||||
|
||||
BOOL WIN_FUNC GetComputerNameA(LPSTR lpBuffer, LPDWORD nSize);
|
||||
BOOL WIN_FUNC GetComputerNameW(LPWSTR lpBuffer, LPDWORD nSize);
|
||||
|
||||
@ -43,6 +103,8 @@ UINT WIN_FUNC GetSystemDirectoryW(LPWSTR lpBuffer, UINT uSize);
|
||||
UINT WIN_FUNC GetSystemWow64DirectoryA(LPSTR lpBuffer, UINT uSize);
|
||||
UINT WIN_FUNC GetSystemWow64DirectoryW(LPWSTR lpBuffer, UINT uSize);
|
||||
UINT WIN_FUNC GetWindowsDirectoryA(LPSTR lpBuffer, UINT uSize);
|
||||
UINT WIN_FUNC GetSystemWindowsDirectoryA(LPSTR lpBuffer, UINT uSize);
|
||||
UINT WIN_FUNC GetSystemWindowsDirectoryW(LPWSTR lpBuffer, UINT uSize);
|
||||
DWORD WIN_FUNC GetCurrentDirectoryA(DWORD nBufferLength, LPSTR lpBuffer);
|
||||
DWORD WIN_FUNC GetCurrentDirectoryW(DWORD nBufferLength, LPWSTR lpBuffer);
|
||||
int WIN_FUNC SetCurrentDirectoryA(LPCSTR lpPathName);
|
||||
|
@ -5,6 +5,14 @@
|
||||
namespace user32 {
|
||||
constexpr uint32_t RT_STRING_ID = 6;
|
||||
constexpr uintptr_t kDefaultKeyboardLayout = 0x04090409;
|
||||
constexpr int UOI_FLAGS = 1;
|
||||
constexpr DWORD WSF_VISIBLE = 0x0001;
|
||||
|
||||
struct USEROBJECTFLAGS {
|
||||
BOOL fInherit;
|
||||
BOOL fReserved;
|
||||
DWORD dwFlags;
|
||||
};
|
||||
|
||||
int WIN_FUNC LoadStringA(void* hInstance, unsigned int uID, char* lpBuffer, int cchBufferMax) {
|
||||
HOST_CONTEXT_GUARD();
|
||||
@ -122,6 +130,48 @@ namespace user32 {
|
||||
wibo::lastError = ERROR_SUCCESS;
|
||||
return reinterpret_cast<HKL>(kDefaultKeyboardLayout);
|
||||
}
|
||||
|
||||
HWINSTA WIN_FUNC GetProcessWindowStation() {
|
||||
DEBUG_LOG("GetProcessWindowStation()\n");
|
||||
static int kWindowStationStub;
|
||||
wibo::lastError = ERROR_SUCCESS;
|
||||
return reinterpret_cast<HWINSTA>(&kWindowStationStub);
|
||||
}
|
||||
|
||||
BOOL WIN_FUNC GetUserObjectInformationA(HANDLE hObj, int nIndex, PVOID pvInfo, DWORD nLength,
|
||||
LPDWORD lpnLengthNeeded) {
|
||||
DEBUG_LOG("GetUserObjectInformationA(%p, %d, %p, %u, %p)\n", hObj, nIndex, pvInfo, nLength,
|
||||
lpnLengthNeeded);
|
||||
(void)hObj;
|
||||
|
||||
if (lpnLengthNeeded) {
|
||||
*lpnLengthNeeded = sizeof(USEROBJECTFLAGS);
|
||||
}
|
||||
|
||||
if (nIndex != UOI_FLAGS) {
|
||||
wibo::lastError = ERROR_CALL_NOT_IMPLEMENTED;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!pvInfo || nLength < sizeof(USEROBJECTFLAGS)) {
|
||||
wibo::lastError = ERROR_INSUFFICIENT_BUFFER;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
auto *flags = reinterpret_cast<USEROBJECTFLAGS *>(pvInfo);
|
||||
flags->fInherit = FALSE;
|
||||
flags->fReserved = FALSE;
|
||||
flags->dwFlags = WSF_VISIBLE;
|
||||
|
||||
wibo::lastError = ERROR_SUCCESS;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
HWND WIN_FUNC GetActiveWindow() {
|
||||
DEBUG_LOG("GetActiveWindow()\n");
|
||||
wibo::lastError = ERROR_SUCCESS;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -130,6 +180,9 @@ static void *resolveByName(const char *name) {
|
||||
if (strcmp(name, "LoadStringW") == 0) return (void *) user32::LoadStringW;
|
||||
if (strcmp(name, "MessageBoxA") == 0) return (void *) user32::MessageBoxA;
|
||||
if (strcmp(name, "GetKeyboardLayout") == 0) return (void *) user32::GetKeyboardLayout;
|
||||
if (strcmp(name, "GetProcessWindowStation") == 0) return (void *) user32::GetProcessWindowStation;
|
||||
if (strcmp(name, "GetUserObjectInformationA") == 0) return (void *) user32::GetUserObjectInformationA;
|
||||
if (strcmp(name, "GetActiveWindow") == 0) return (void *) user32::GetActiveWindow;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -98,6 +98,8 @@ using REGSAM = DWORD;
|
||||
using LSTATUS = LONG;
|
||||
using LCID = DWORD;
|
||||
using LCTYPE = DWORD;
|
||||
using HWINSTA = HANDLE;
|
||||
using HWND = HANDLE;
|
||||
|
||||
constexpr BOOL TRUE = 1;
|
||||
constexpr BOOL FALSE = 0;
|
||||
|
@ -39,6 +39,7 @@
|
||||
#define ERROR_NOT_OWNER 288
|
||||
#define ERROR_TOO_MANY_POSTS 298
|
||||
#define ERROR_SEM_TIMEOUT 121
|
||||
#define ERROR_SXS_KEY_NOT_FOUND 14007
|
||||
|
||||
#define INVALID_SET_FILE_POINTER ((DWORD) - 1)
|
||||
#define INVALID_HANDLE_VALUE ((HANDLE) - 1)
|
||||
|
110
test/test_actctx.c
Normal file
110
test/test_actctx.c
Normal file
@ -0,0 +1,110 @@
|
||||
#include <windows.h>
|
||||
|
||||
#include "test_assert.h"
|
||||
|
||||
#ifndef ACTCTX_SECTION_KEYED_DATA_FLAG_FOUND_IN_ACTCTX
|
||||
#define ACTCTX_SECTION_KEYED_DATA_FLAG_FOUND_IN_ACTCTX 0x00000001
|
||||
#endif
|
||||
|
||||
#ifndef ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION
|
||||
typedef struct _ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION {
|
||||
ULONG Size;
|
||||
ULONG Flags;
|
||||
ULONG TotalPathLength;
|
||||
ULONG PathSegmentCount;
|
||||
ULONG PathSegmentOffset;
|
||||
} ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION;
|
||||
#endif
|
||||
|
||||
static BOOL isRunningUnderWine(void) {
|
||||
HMODULE hNtdll = GetModuleHandleW(L"ntdll.dll");
|
||||
return hNtdll != NULL && GetProcAddress(hNtdll, "wine_get_version") != NULL;
|
||||
}
|
||||
|
||||
static void check_success_w(void) {
|
||||
ACTCTX_SECTION_KEYED_DATA data = { 0 };
|
||||
data.cbSize = sizeof(data);
|
||||
SetLastError(0);
|
||||
BOOL ok = FindActCtxSectionStringW(0, NULL, ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION,
|
||||
L"msvcr80.dll", &data);
|
||||
TEST_CHECK(ok);
|
||||
TEST_CHECK_EQ(ERROR_SUCCESS, GetLastError());
|
||||
TEST_CHECK_EQ(1u, data.ulDataFormatVersion);
|
||||
TEST_CHECK((data.ulFlags & ACTCTX_SECTION_KEYED_DATA_FLAG_FOUND_IN_ACTCTX) != 0);
|
||||
TEST_CHECK(data.lpData != NULL);
|
||||
TEST_CHECK(data.ulLength >= sizeof(ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION));
|
||||
TEST_CHECK(data.hActCtx == NULL);
|
||||
TEST_CHECK_EQ(1u, data.ulAssemblyRosterIndex);
|
||||
}
|
||||
|
||||
static void check_success_a(void) {
|
||||
ACTCTX_SECTION_KEYED_DATA data = { 0 };
|
||||
data.cbSize = sizeof(data);
|
||||
SetLastError(0);
|
||||
BOOL ok = FindActCtxSectionStringA(FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX, NULL,
|
||||
ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION,
|
||||
"msvcp80.dll", &data);
|
||||
TEST_CHECK(ok);
|
||||
TEST_CHECK_EQ(ERROR_SUCCESS, GetLastError());
|
||||
TEST_CHECK((data.ulFlags & ACTCTX_SECTION_KEYED_DATA_FLAG_FOUND_IN_ACTCTX) != 0);
|
||||
TEST_CHECK(data.lpData != NULL);
|
||||
TEST_CHECK(data.hActCtx != NULL);
|
||||
TEST_CHECK_EQ(1u, data.ulAssemblyRosterIndex);
|
||||
}
|
||||
|
||||
static void check_invalid_parameters(void) {
|
||||
ACTCTX_SECTION_KEYED_DATA data = { 0 };
|
||||
data.cbSize = sizeof(data);
|
||||
GUID fakeGuid = {0};
|
||||
SetLastError(0);
|
||||
BOOL ok = FindActCtxSectionStringW(0, &fakeGuid, ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION,
|
||||
L"msvcr80.dll", &data);
|
||||
TEST_CHECK(!ok);
|
||||
TEST_CHECK_EQ(ERROR_INVALID_PARAMETER, GetLastError());
|
||||
|
||||
ACTCTX_SECTION_KEYED_DATA sized = { 0 };
|
||||
sized.cbSize = sizeof(data) - 4;
|
||||
SetLastError(0);
|
||||
ok = FindActCtxSectionStringW(0, NULL, ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION,
|
||||
L"msvcr80.dll", &sized);
|
||||
TEST_CHECK(!ok);
|
||||
TEST_CHECK_EQ(ERROR_INSUFFICIENT_BUFFER, GetLastError());
|
||||
|
||||
ACTCTX_SECTION_KEYED_DATA flags = { 0 };
|
||||
flags.cbSize = sizeof(flags);
|
||||
SetLastError(0);
|
||||
ok = FindActCtxSectionStringW(0x2, NULL, ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION,
|
||||
L"msvcr80.dll", &flags);
|
||||
TEST_CHECK(!ok);
|
||||
TEST_CHECK_EQ(ERROR_INVALID_PARAMETER, GetLastError());
|
||||
}
|
||||
|
||||
static void check_missing_entries(void) {
|
||||
ACTCTX_SECTION_KEYED_DATA data = { 0 };
|
||||
data.cbSize = sizeof(data);
|
||||
SetLastError(0);
|
||||
BOOL ok = FindActCtxSectionStringW(0, NULL, ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION,
|
||||
L"totally_missing.dll", &data);
|
||||
TEST_CHECK(!ok);
|
||||
TEST_CHECK_EQ(ERROR_SXS_KEY_NOT_FOUND, GetLastError());
|
||||
|
||||
ACTCTX_SECTION_KEYED_DATA wrongSection = { 0 };
|
||||
wrongSection.cbSize = sizeof(wrongSection);
|
||||
SetLastError(0);
|
||||
ok = FindActCtxSectionStringW(0, NULL, ACTIVATION_CONTEXT_SECTION_ASSEMBLY_INFORMATION,
|
||||
L"msvcr80.dll", &wrongSection);
|
||||
TEST_CHECK(!ok);
|
||||
TEST_CHECK_EQ(ERROR_SXS_KEY_NOT_FOUND, GetLastError());
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
if (isRunningUnderWine()) {
|
||||
printf("test_actctx: skipping under wine\n");
|
||||
return 0;
|
||||
}
|
||||
check_success_w();
|
||||
check_success_a();
|
||||
check_invalid_parameters();
|
||||
check_missing_entries();
|
||||
return 0;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user