summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/pemagine/pe_ldso.h1
-rw-r--r--include/pemagine/pemagine.h9
-rw-r--r--src/ldso/pe_load_framework_loader.c79
3 files changed, 89 insertions, 0 deletions
diff --git a/include/pemagine/pe_ldso.h b/include/pemagine/pe_ldso.h
index 7f6382c..2d81774 100644
--- a/include/pemagine/pe_ldso.h
+++ b/include/pemagine/pe_ldso.h
@@ -32,6 +32,7 @@
#define pe_get_procedure_address __ldso_get_procedure_address
#define pe_get_symbol_module_info __ldso_get_symbol_module_info
#define pe_get_symbol_name __ldso_get_symbol_name
+#define pe_load_framework_library __ldso_load_framework_library
#define pe_load_framework_loader __ldso_load_framework_loader
#define pe_load_framework_loader_ex __ldso_load_framework_loader_ex
#define pe_open_image_from_addr __ldso_open_image_from_addr
diff --git a/include/pemagine/pemagine.h b/include/pemagine/pemagine.h
index 9cfe47a..3f374f8 100644
--- a/include/pemagine/pemagine.h
+++ b/include/pemagine/pemagine.h
@@ -257,6 +257,15 @@ pe_api int32_t pe_find_framework_loader(
uint32_t flags);
+pe_api int32_t pe_load_framework_library(
+ void ** baseaddr,
+ void * hat,
+ const wchar16_t * atrelname,
+ uintptr_t * buffer,
+ uint32_t bufsize,
+ uint32_t * sysflags);
+
+
pe_api int32_t pe_load_framework_loader(
void ** baseaddr,
struct pe_framework_runtime_data * rtdata,
diff --git a/src/ldso/pe_load_framework_loader.c b/src/ldso/pe_load_framework_loader.c
index e70c183..347d3ab 100644
--- a/src/ldso/pe_load_framework_loader.c
+++ b/src/ldso/pe_load_framework_loader.c
@@ -259,3 +259,82 @@ int32_t pe_load_framework_loader(
buffer,bufsize,
sysflags);
}
+
+
+int32_t pe_load_framework_library(
+ void ** baseaddr,
+ void * hat,
+ const wchar16_t * atrelname,
+ uintptr_t * buffer,
+ uint32_t bufsize,
+ uint32_t * sysflags)
+{
+ int32_t status;
+ struct pe_unicode_str path;
+ struct os_oa oa;
+ struct os_iosb iosb;
+ const wchar16_t * wch;
+ const wchar16_t * wch_cap;
+ void * hdsolib;
+ void * hntdll;
+ os_zw_close * zw_close;
+ os_zw_open_file * zw_open_file;
+
+ /* init */
+ if (!(hntdll = pe_get_ntdll_module_handle()))
+ return OS_STATUS_INTERNAL_ERROR;
+
+ if (!(zw_close = (os_zw_close *)pe_get_procedure_address(
+ hntdll,"ZwClose")))
+ return OS_STATUS_INTERNAL_ERROR;
+
+ if (!(zw_open_file = (os_zw_open_file *)pe_get_procedure_address(
+ hntdll,"ZwOpenFile")))
+ return OS_STATUS_INTERNAL_ERROR;
+
+ /* oa */
+ oa.len = sizeof(struct os_oa);
+ oa.root_dir = hat;
+ oa.obj_name = &path;
+ oa.obj_attr = 0;
+ oa.sec_desc = 0;
+ oa.sec_qos = 0;
+
+ /* at-relative path */
+ wch = atrelname;
+ wch_cap = atrelname + 512;
+
+ for (; *wch && wch<wch_cap; )
+ wch++;
+
+ if (*wch)
+ return OS_STATUS_NAME_TOO_LONG;
+
+ path.buffer = (wchar16_t *)atrelname;
+ path.strlen = sizeof(wchar16_t) * (wch - atrelname);
+ path.maxlen = 0;
+
+ /* open at */
+ if ((status = zw_open_file(
+ &hdsolib,
+ OS_SEC_SYNCHRONIZE
+ | OS_FILE_READ_ACCESS
+ | OS_FILE_READ_ATTRIBUTES,
+ &oa,&iosb,
+ OS_FILE_SHARE_READ
+ | OS_FILE_SHARE_WRITE
+ | OS_FILE_SHARE_DELETE,
+ OS_FILE_NON_DIRECTORY_FILE)))
+ return status;
+
+ /* hoppla */
+ status = pe_load_library_impl(
+ baseaddr,hdsolib,
+ buffer,bufsize,
+ sysflags);
+
+ /* all done */
+ zw_close(hdsolib);
+
+ return status;
+}