An alternative implementation of libdelayimp.a, which is a thin wrapper
around OS APIs present in Windows 8 and newer, and which is required to
be used in store apps that wish to delay load, in lieu of libdelayimp.a.
Signed-off-by: Jeremy Drake <jeremyd2...@users.sourceforge.net>
---
 mingw-w64-crt/Makefile.am          | 17 ++++++++
 mingw-w64-crt/libsrc/dloadhelper.c | 63 ++++++++++++++++++++++++++++++
 2 files changed, 80 insertions(+)
 create mode 100644 mingw-w64-crt/libsrc/dloadhelper.c

diff --git a/mingw-w64-crt/Makefile.am b/mingw-w64-crt/Makefile.am
index a4699e0c2..229a6aa9f 100644
--- a/mingw-w64-crt/Makefile.am
+++ b/mingw-w64-crt/Makefile.am
@@ -116,6 +116,7 @@ src_libsensorsapi=libsrc/sensorsapi.c
 src_libportabledeviceguids=libsrc/portabledeviceguids.c
 src_libtaskschd=libsrc/taskschd.c
 src_libntoskrnl=libsrc/memcmp.c
+src_libdloadhelper=libsrc/dloadhelper.c misc/delay-f.c

 src_libmingw32=include/oscalls.h include/internal.h include/sect_attribs.h \
   crt/crt0_c.c        crt/dll_argv.c  crt/gccmain.c     crt/natstart.c  
crt/pseudo-reloc-list.c  crt/wildcard.c \
@@ -870,6 +871,10 @@ lib32_LIBRARIES += lib32/libadsiid.a
 lib32_libadsiid_a_SOURCES = $(src_adsiid)
 lib32_libadsiid_a_CPPFLAGS=$(CPPFLAGS32) $(sysincludes)

+lib32_LIBRARIES += lib32/libdloadhelper.a
+lib32_libdloadhelper_a_SOURCES = $(src_libdloadhelper)
+lib32_libdloadhelper_a_CPPFLAGS=$(CPPFLAGS32) $(sysincludes)
+
 if !W32API
 lib32_LIBRARIES += lib32/libdelayimp.a
 lib32_libdelayimp_a_SOURCES =
@@ -1227,6 +1232,10 @@ lib64_LIBRARIES += lib64/libadsiid.a
 lib64_libadsiid_a_SOURCES = $(src_adsiid)
 lib64_libadsiid_a_CPPFLAGS=$(CPPFLAGS64) $(sysincludes)

+lib64_LIBRARIES += lib64/libdloadhelper.a
+lib64_libdloadhelper_a_SOURCES = $(src_libdloadhelper)
+lib64_libdloadhelper_a_CPPFLAGS=$(CPPFLAGS64) $(sysincludes)
+
 if !W32API
 lib64_LIBRARIES += lib64/libdelayimp.a
 lib64_libdelayimp_a_SOURCES =
@@ -1557,6 +1566,10 @@ libarm32_LIBRARIES += libarm32/libadsiid.a
 libarm32_libadsiid_a_SOURCES = $(src_adsiid)
 libarm32_libadsiid_a_CPPFLAGS=$(CPPFLAGSARM32) $(sysincludes)

+libarm32_LIBRARIES += libarm32/libdloadhelper.a
+libarm32_libdloadhelper_a_SOURCES = $(src_libdloadhelper)
+libarm32_libdloadhelper_a_CPPFLAGS=$(CPPFLAGSARM32) $(sysincludes)
+
 if !W32API
 libarm32_LIBRARIES += libarm32/libdelayimp.a
 libarm32_libdelayimp_a_SOURCES =
@@ -1839,6 +1852,10 @@ libarm64_LIBRARIES += libarm64/libadsiid.a
 libarm64_libadsiid_a_SOURCES = $(src_adsiid)
 libarm64_libadsiid_a_CPPFLAGS=$(CPPFLAGSARM64) $(sysincludes)

+libarm64_LIBRARIES += libarm64/libdloadhelper.a
+libarm64_libdloadhelper_a_SOURCES = $(src_libdloadhelper)
+libarm64_libdloadhelper_a_CPPFLAGS=$(CPPFLAGSARM64) $(sysincludes)
+
 if !W32API
 libarm64_LIBRARIES += libarm64/libdelayimp.a
 libarm64_libdelayimp_a_SOURCES =
diff --git a/mingw-w64-crt/libsrc/dloadhelper.c 
b/mingw-w64-crt/libsrc/dloadhelper.c
new file mode 100644
index 000000000..ce3a57914
--- /dev/null
+++ b/mingw-w64-crt/libsrc/dloadhelper.c
@@ -0,0 +1,63 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the mingw-w64 runtime package.
+ * No warranty is given; refer to the file DISCLAIMER.PD within this package.
+ */
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#endif
+#include <windows.h>
+#include <delayloadhandler.h>
+
+/* XXX NTSTATUS is supposed to be a LONG, but there are a bunch of STATUS_
+ * constants in winnt.h defined as ((DWORD)0x...), including
+ * STATUS_DLL_NOT_FOUND which we need, so using DWORD here to silence a warning
+ */
+typedef DWORD NTSTATUS;
+
+#define __ImageBase __MINGW_LSYMBOL(_image_base__)
+extern IMAGE_DOS_HEADER __ImageBase;
+
+/* this typedef is missing from the Windows SDK header, but is present in
+ * Wine's version. */
+typedef FARPROC (WINAPI *PDELAYLOAD_FAILURE_SYSTEM_ROUTINE)(LPCSTR pszDllName, 
LPCSTR pszProcName);
+
+/* these functions aren't in any Windows SDK header, but are documented at
+ * https://docs.microsoft.com/en-us/windows/win32/devnotes/delay-loaded-dlls */
+WINBASEAPI FARPROC WINAPI DelayLoadFailureHook(LPCSTR pszDllName, LPCSTR 
pszProcName);
+
+WINBASEAPI PVOID WINAPI ResolveDelayLoadedAPI(
+               PVOID ParentModuleBase,
+               PCIMAGE_DELAYLOAD_DESCRIPTOR DelayloadDescriptor,
+               PDELAYLOAD_FAILURE_DLL_CALLBACK FailureDllHook,
+               PDELAYLOAD_FAILURE_SYSTEM_ROUTINE FailureSystemHook,
+               PIMAGE_THUNK_DATA ThunkAddress,
+               ULONG Flags);
+
+WINBASEAPI NTSTATUS WINAPI ResolveDelayLoadsFromDll(
+               PVOID ParentBase,
+               LPCSTR TargetDllName,
+               ULONG Flags);
+
+/* These functions are defined here, part of the delayimp API */
+PVOID WINAPI __delayLoadHelper2(
+               PCIMAGE_DELAYLOAD_DESCRIPTOR DelayloadDescriptor,
+               PIMAGE_THUNK_DATA ThunkAddress);
+
+HRESULT WINAPI __HrLoadAllImportsForDll(LPCSTR szDll);
+
+PVOID WINAPI __delayLoadHelper2(
+               PCIMAGE_DELAYLOAD_DESCRIPTOR DelayloadDescriptor,
+               PIMAGE_THUNK_DATA ThunkAddress)
+{
+       return ResolveDelayLoadedAPI(&__ImageBase, DelayloadDescriptor, 
__pfnDliFailureHook2, DelayLoadFailureHook, ThunkAddress, 0);
+}
+
+HRESULT WINAPI __HrLoadAllImportsForDll(LPCSTR szDll)
+{
+       NTSTATUS status = ResolveDelayLoadsFromDll(&__ImageBase, szDll, 0);
+       if (status == STATUS_DLL_NOT_FOUND)
+               return HRESULT_FROM_WIN32(ERROR_MOD_NOT_FOUND);
+       else
+               return S_OK;
+}
-- 
2.35.1.windows.2
From 6a7736a96f09109ef00acb1ca960130a1ca55df3 Mon Sep 17 00:00:00 2001
From: Jeremy Drake <jeremyd2...@users.sourceforge.net>
Date: Wed, 6 Apr 2022 23:55:47 -0700
Subject: [PATCH 2/2] crt: add libdloadhelper.a

An alternative implementation of libdelayimp.a, which is a thin wrapper
around OS APIs present in Windows 8 and newer, and which is required to
be used in store apps that wish to delay load, in lieu of libdelayimp.a.

Signed-off-by: Jeremy Drake <jeremyd2...@users.sourceforge.net>
---
 mingw-w64-crt/Makefile.am          | 17 ++++++++
 mingw-w64-crt/libsrc/dloadhelper.c | 63 ++++++++++++++++++++++++++++++
 2 files changed, 80 insertions(+)
 create mode 100644 mingw-w64-crt/libsrc/dloadhelper.c

diff --git a/mingw-w64-crt/Makefile.am b/mingw-w64-crt/Makefile.am
index a4699e0c2..229a6aa9f 100644
--- a/mingw-w64-crt/Makefile.am
+++ b/mingw-w64-crt/Makefile.am
@@ -116,6 +116,7 @@ src_libsensorsapi=libsrc/sensorsapi.c
 src_libportabledeviceguids=libsrc/portabledeviceguids.c
 src_libtaskschd=libsrc/taskschd.c
 src_libntoskrnl=libsrc/memcmp.c
+src_libdloadhelper=libsrc/dloadhelper.c misc/delay-f.c
 
 src_libmingw32=include/oscalls.h include/internal.h include/sect_attribs.h \
   crt/crt0_c.c        crt/dll_argv.c  crt/gccmain.c     crt/natstart.c  
crt/pseudo-reloc-list.c  crt/wildcard.c \
@@ -870,6 +871,10 @@ lib32_LIBRARIES += lib32/libadsiid.a
 lib32_libadsiid_a_SOURCES = $(src_adsiid)
 lib32_libadsiid_a_CPPFLAGS=$(CPPFLAGS32) $(sysincludes)
 
+lib32_LIBRARIES += lib32/libdloadhelper.a
+lib32_libdloadhelper_a_SOURCES = $(src_libdloadhelper)
+lib32_libdloadhelper_a_CPPFLAGS=$(CPPFLAGS32) $(sysincludes)
+
 if !W32API
 lib32_LIBRARIES += lib32/libdelayimp.a
 lib32_libdelayimp_a_SOURCES =
@@ -1227,6 +1232,10 @@ lib64_LIBRARIES += lib64/libadsiid.a
 lib64_libadsiid_a_SOURCES = $(src_adsiid)
 lib64_libadsiid_a_CPPFLAGS=$(CPPFLAGS64) $(sysincludes)
 
+lib64_LIBRARIES += lib64/libdloadhelper.a
+lib64_libdloadhelper_a_SOURCES = $(src_libdloadhelper)
+lib64_libdloadhelper_a_CPPFLAGS=$(CPPFLAGS64) $(sysincludes)
+
 if !W32API
 lib64_LIBRARIES += lib64/libdelayimp.a
 lib64_libdelayimp_a_SOURCES =
@@ -1557,6 +1566,10 @@ libarm32_LIBRARIES += libarm32/libadsiid.a
 libarm32_libadsiid_a_SOURCES = $(src_adsiid)
 libarm32_libadsiid_a_CPPFLAGS=$(CPPFLAGSARM32) $(sysincludes)
 
+libarm32_LIBRARIES += libarm32/libdloadhelper.a
+libarm32_libdloadhelper_a_SOURCES = $(src_libdloadhelper)
+libarm32_libdloadhelper_a_CPPFLAGS=$(CPPFLAGSARM32) $(sysincludes)
+
 if !W32API
 libarm32_LIBRARIES += libarm32/libdelayimp.a
 libarm32_libdelayimp_a_SOURCES =
@@ -1839,6 +1852,10 @@ libarm64_LIBRARIES += libarm64/libadsiid.a
 libarm64_libadsiid_a_SOURCES = $(src_adsiid)
 libarm64_libadsiid_a_CPPFLAGS=$(CPPFLAGSARM64) $(sysincludes)
 
+libarm64_LIBRARIES += libarm64/libdloadhelper.a
+libarm64_libdloadhelper_a_SOURCES = $(src_libdloadhelper)
+libarm64_libdloadhelper_a_CPPFLAGS=$(CPPFLAGSARM64) $(sysincludes)
+
 if !W32API
 libarm64_LIBRARIES += libarm64/libdelayimp.a
 libarm64_libdelayimp_a_SOURCES =
diff --git a/mingw-w64-crt/libsrc/dloadhelper.c 
b/mingw-w64-crt/libsrc/dloadhelper.c
new file mode 100644
index 000000000..ce3a57914
--- /dev/null
+++ b/mingw-w64-crt/libsrc/dloadhelper.c
@@ -0,0 +1,63 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the mingw-w64 runtime package.
+ * No warranty is given; refer to the file DISCLAIMER.PD within this package.
+ */
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#endif
+#include <windows.h>
+#include <delayloadhandler.h>
+
+/* XXX NTSTATUS is supposed to be a LONG, but there are a bunch of STATUS_
+ * constants in winnt.h defined as ((DWORD)0x...), including
+ * STATUS_DLL_NOT_FOUND which we need, so using DWORD here to silence a warning
+ */
+typedef DWORD NTSTATUS;
+
+#define __ImageBase __MINGW_LSYMBOL(_image_base__)
+extern IMAGE_DOS_HEADER __ImageBase;
+
+/* this typedef is missing from the Windows SDK header, but is present in
+ * Wine's version. */
+typedef FARPROC (WINAPI *PDELAYLOAD_FAILURE_SYSTEM_ROUTINE)(LPCSTR pszDllName, 
LPCSTR pszProcName);
+
+/* these functions aren't in any Windows SDK header, but are documented at
+ * https://docs.microsoft.com/en-us/windows/win32/devnotes/delay-loaded-dlls */
+WINBASEAPI FARPROC WINAPI DelayLoadFailureHook(LPCSTR pszDllName, LPCSTR 
pszProcName);
+
+WINBASEAPI PVOID WINAPI ResolveDelayLoadedAPI(
+               PVOID ParentModuleBase,
+               PCIMAGE_DELAYLOAD_DESCRIPTOR DelayloadDescriptor,
+               PDELAYLOAD_FAILURE_DLL_CALLBACK FailureDllHook,
+               PDELAYLOAD_FAILURE_SYSTEM_ROUTINE FailureSystemHook,
+               PIMAGE_THUNK_DATA ThunkAddress,
+               ULONG Flags);
+
+WINBASEAPI NTSTATUS WINAPI ResolveDelayLoadsFromDll(
+               PVOID ParentBase,
+               LPCSTR TargetDllName,
+               ULONG Flags);
+
+/* These functions are defined here, part of the delayimp API */
+PVOID WINAPI __delayLoadHelper2(
+               PCIMAGE_DELAYLOAD_DESCRIPTOR DelayloadDescriptor,
+               PIMAGE_THUNK_DATA ThunkAddress);
+
+HRESULT WINAPI __HrLoadAllImportsForDll(LPCSTR szDll);
+
+PVOID WINAPI __delayLoadHelper2(
+               PCIMAGE_DELAYLOAD_DESCRIPTOR DelayloadDescriptor,
+               PIMAGE_THUNK_DATA ThunkAddress)
+{
+       return ResolveDelayLoadedAPI(&__ImageBase, DelayloadDescriptor, 
__pfnDliFailureHook2, DelayLoadFailureHook, ThunkAddress, 0);
+}
+
+HRESULT WINAPI __HrLoadAllImportsForDll(LPCSTR szDll)
+{
+       NTSTATUS status = ResolveDelayLoadsFromDll(&__ImageBase, szDll, 0);
+       if (status == STATUS_DLL_NOT_FOUND)
+               return HRESULT_FROM_WIN32(ERROR_MOD_NOT_FOUND);
+       else
+               return S_OK;
+}
-- 
2.35.1.windows.2

_______________________________________________
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to