From 224f38d84d94ecc12f4cf5b286967109ff3d9504 Mon Sep 17 00:00:00 2001
From: midipix <writeonce@midipix.org>
Date: Wed, 18 Oct 2017 12:09:39 +0000
Subject: ldso: added pe_load_framework_library().

---
 include/pemagine/pe_ldso.h          |  1 +
 include/pemagine/pemagine.h         |  9 +++++
 src/ldso/pe_load_framework_loader.c | 79 +++++++++++++++++++++++++++++++++++++
 3 files changed, 89 insertions(+)

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;
+}
-- 
cgit v1.2.3