diff options
Diffstat (limited to 'src/osd/modules')
-rw-r--r-- | src/osd/modules/font/font_dwrite.cpp | 4 | ||||
-rw-r--r-- | src/osd/modules/lib/osdlib_uwp.cpp | 146 | ||||
-rw-r--r-- | src/osd/modules/monitor/monitor_dxgi.cpp | 18 |
3 files changed, 164 insertions, 4 deletions
diff --git a/src/osd/modules/font/font_dwrite.cpp b/src/osd/modules/font/font_dwrite.cpp index 6e66ccf320b..db85f96790f 100644 --- a/src/osd/modules/font/font_dwrite.cpp +++ b/src/osd/modules/font/font_dwrite.cpp @@ -9,7 +9,7 @@ #include "modules/osdmodule.h" #include "modules/lib/osdlib.h" -#if defined(OSD_WINDOWS) +#if defined(OSD_WINDOWS) || defined(OSD_UWP) #define WIN32_LEAN_AND_MEAN #include <windows.h> @@ -429,7 +429,7 @@ public: uint32_t tempChar = chnum; uint16_t glyphIndex; - HR_RET0(face->GetGlyphIndicesW(&tempChar, 1, &glyphIndex)); + HR_RET0(face->GetGlyphIndices(&tempChar, 1, &glyphIndex)); // get the width of this character DWRITE_GLYPH_METRICS glyph_metrics = { 0 }; diff --git a/src/osd/modules/lib/osdlib_uwp.cpp b/src/osd/modules/lib/osdlib_uwp.cpp index 66f753444b6..484ed3fb44c 100644 --- a/src/osd/modules/lib/osdlib_uwp.cpp +++ b/src/osd/modules/lib/osdlib_uwp.cpp @@ -315,7 +315,148 @@ char *osd_get_clipboard_text(void) #define load_library(filename) LoadLibrary(filename) #else // for Windows Store universal applications -#define load_library(filename) LoadPackagedLibrary(filename, 0) + +// This needs to change ASAP as it won't be allowed in the store +typedef HMODULE __stdcall t_LLA(const char *); +typedef FARPROC __stdcall t_GPA(HMODULE H, const char *); + +PIMAGE_NT_HEADERS WINAPI ImageNtHeader(PVOID Base) +{ + return (PIMAGE_NT_HEADERS) + ((LPBYTE)Base + ((PIMAGE_DOS_HEADER)Base)->e_lfanew); +} + +PIMAGE_SECTION_HEADER WINAPI RtlImageRvaToSection(const IMAGE_NT_HEADERS *nt, + HMODULE module, DWORD_PTR rva) +{ + int i; + const IMAGE_SECTION_HEADER *sec; + + sec = (const IMAGE_SECTION_HEADER*)((const char*)&nt->OptionalHeader + + nt->FileHeader.SizeOfOptionalHeader); + for (i = 0; i < nt->FileHeader.NumberOfSections; i++, sec++) + { + if ((sec->VirtualAddress <= rva) && (sec->VirtualAddress + sec->SizeOfRawData > rva)) + return (PIMAGE_SECTION_HEADER)sec; + } + return NULL; +} + +PVOID WINAPI RtlImageRvaToVa(const IMAGE_NT_HEADERS *nt, HMODULE module, + DWORD_PTR rva, IMAGE_SECTION_HEADER **section) +{ + IMAGE_SECTION_HEADER *sec; + + if (section && *section) /* try this section first */ + { + sec = *section; + if ((sec->VirtualAddress <= rva) && (sec->VirtualAddress + sec->SizeOfRawData > rva)) + goto found; + } + if (!(sec = RtlImageRvaToSection(nt, module, rva))) return NULL; +found: + if (section) *section = sec; + return (char *)module + sec->PointerToRawData + (rva - sec->VirtualAddress); +} + +PVOID WINAPI ImageDirectoryEntryToDataEx(PVOID base, BOOLEAN image, USHORT dir, PULONG size, PIMAGE_SECTION_HEADER *section) +{ + const IMAGE_NT_HEADERS *nt; + DWORD_PTR addr; + + *size = 0; + if (section) *section = NULL; + + if (!(nt = ImageNtHeader(base))) return NULL; + if (dir >= nt->OptionalHeader.NumberOfRvaAndSizes) return NULL; + if (!(addr = nt->OptionalHeader.DataDirectory[dir].VirtualAddress)) return NULL; + + *size = nt->OptionalHeader.DataDirectory[dir].Size; + if (image || addr < nt->OptionalHeader.SizeOfHeaders) return (char *)base + addr; + + return RtlImageRvaToVa(nt, (HMODULE)base, addr, section); +} + +// == Windows API GetProcAddress +void *PeGetProcAddressA(void *Base, LPCSTR Name) +{ + DWORD Tmp; + + IMAGE_NT_HEADERS *NT = ImageNtHeader(Base); + IMAGE_EXPORT_DIRECTORY *Exp = (IMAGE_EXPORT_DIRECTORY*)ImageDirectoryEntryToDataEx(Base, TRUE, IMAGE_DIRECTORY_ENTRY_EXPORT, &Tmp, 0); + if (Exp == 0 || Exp->NumberOfFunctions == 0) + { + SetLastError(ERROR_NOT_FOUND); + return 0; + } + + DWORD *Names = (DWORD*)(Exp->AddressOfNames + (DWORD_PTR)Base); + WORD *Ordinals = (WORD*)(Exp->AddressOfNameOrdinals + (DWORD_PTR)Base); + DWORD *Functions = (DWORD*)(Exp->AddressOfFunctions + (DWORD_PTR)Base); + + FARPROC Ret = 0; + + if ((DWORD_PTR)Name<65536) + { + if ((DWORD_PTR)Name - Exp->Base<Exp->NumberOfFunctions) + Ret = (FARPROC)(Functions[(DWORD_PTR)Name - Exp->Base] + (DWORD_PTR)Base); + } + else + { + for (DWORD i = 0; i<Exp->NumberOfNames && Ret == 0; i++) + { + char *Func = (char*)(Names[i] + (DWORD_PTR)Base); + if (Func && strcmp(Func, Name) == 0) + Ret = (FARPROC)(Functions[Ordinals[i]] + (DWORD_PTR)Base); + } + } + + if (Ret) + { + DWORD ExpStart = NT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + (DWORD)Base; + DWORD ExpSize = NT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size; + if ((DWORD)Ret >= ExpStart && (DWORD)Ret <= ExpStart + ExpSize) + { + // Forwarder + return 0; + } + return Ret; + } + + return 0; +} + +t_LLA* g_LoadLibraryA = 0; +t_GPA* g_GetProcAddressA = 0; + +void find_load_exports() +{ + char *Tmp = (char*)GetTickCount64; + Tmp = (char*)((~0xFFF)&(DWORD_PTR)Tmp); + + while (Tmp) + { + __try + { + if (Tmp[0] == 'M' && Tmp[1] == 'Z') + break; + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + } + Tmp -= 0x1000; + } + + if (Tmp == 0) + return; + + g_LoadLibraryA = (t_LLA*)PeGetProcAddressA(Tmp, "LoadLibraryA"); + g_GetProcAddressA = (t_GPA*)PeGetProcAddressA(Tmp, "GetProcAddress"); +} + +#define load_library(filename) g_LoadLibraryA(osd::text::from_wstring(filename).c_str()) +#define get_proc_address(mod, proc) g_GetProcAddressA(mod, proc) + #endif namespace osd { @@ -326,6 +467,9 @@ public: : m_module(nullptr) { m_libraries = libraries; +#if defined(OSD_UWP) + find_load_exports(); +#endif } virtual ~dynamic_module_win32_impl() override diff --git a/src/osd/modules/monitor/monitor_dxgi.cpp b/src/osd/modules/monitor/monitor_dxgi.cpp index d506a00e95a..9fbc32a25bc 100644 --- a/src/osd/modules/monitor/monitor_dxgi.cpp +++ b/src/osd/modules/monitor/monitor_dxgi.cpp @@ -8,7 +8,7 @@ #include "modules/osdmodule.h" #include "monitor_module.h" -#if defined(OSD_WINDOWS) +#if defined(OSD_WINDOWS) || defined(OSD_UWP) // standard windows headers #define WIN32_LEAN_AND_MEAN @@ -86,6 +86,7 @@ public: if (!m_initialized) return nullptr; +#if defined(OSD_WINDOWS) RECT p; p.top = rect.top(); p.left = rect.left(); @@ -95,6 +96,13 @@ public: auto nearest = monitor_from_handle(reinterpret_cast<std::uintptr_t>(MonitorFromRect(&p, MONITOR_DEFAULTTONEAREST))); assert(nearest != nullptr); return nearest; +#elif defined(OSD_UWP) + if (list().size() == 0) + return nullptr; + + // For now just return first monitor + return list()[0]; +#endif } // Currently this method implementation is duplicated from the win32 module @@ -104,9 +112,17 @@ public: if (!m_initialized) return nullptr; +#if defined(OSD_WINDOWS) auto nearest = monitor_from_handle(reinterpret_cast<std::uintptr_t>(MonitorFromWindow(window.platform_window<HWND>(), MONITOR_DEFAULTTONEAREST))); assert(nearest != nullptr); return nearest; +#elif defined(OSD_UWP) + if (list().size() == 0) + return nullptr; + + // For now just return first monitor + return list()[0]; +#endif } protected: |