summaryrefslogtreecommitdiffhomepage
path: root/src/ldso
diff options
context:
space:
mode:
authormidipix <writeonce@midipix.org>2017-01-17 19:40:32 +0000
committermidipix <writeonce@midipix.org>2017-01-18 00:30:45 -0500
commit393c205aed99a73cb8ff984858f288f8cb901688 (patch)
tree0a9da201dff8413e2ea582ec01bc5075b1d9b217 /src/ldso
parent034d8a34fb0c1b049bb8cb5ea52868c4c6f47d5f (diff)
downloadpemagine-393c205aed99a73cb8ff984858f288f8cb901688.tar.bz2
pemagine-393c205aed99a73cb8ff984858f288f8cb901688.tar.xz
ldso: added pe_open_physical_parent_directory().
Diffstat (limited to 'src/ldso')
-rw-r--r--src/ldso/pe_open_physical_parent_directory.c105
1 files changed, 105 insertions, 0 deletions
diff --git a/src/ldso/pe_open_physical_parent_directory.c b/src/ldso/pe_open_physical_parent_directory.c
new file mode 100644
index 0000000..7166df5
--- /dev/null
+++ b/src/ldso/pe_open_physical_parent_directory.c
@@ -0,0 +1,105 @@
+/*****************************************************************************/
+/* pemagination: a (virtual) tour into portable bits and executable bytes */
+/* Copyright (C) 2013--2017 Z. Gilboa */
+/* Released under GPLv2 and GPLv3; see COPYING.PEMAGINE. */
+/*****************************************************************************/
+
+#include <psxtypes/psxtypes.h>
+#include <pemagine/pemagine.h>
+#include <pemagine/pe_structs.h>
+#include "pe_os.h"
+
+int32_t pe_open_physical_parent_directory(
+ __out void ** hparent,
+ __in void * href,
+ __out uintptr_t * buffer,
+ __in uint32_t buffer_size,
+ __in uint32_t desired_access,
+ __in uint32_t open_options)
+{
+ int32_t status;
+ struct os_oa oa;
+ struct os_iosb iosb;
+ wchar16_t * wch;
+ wchar16_t * root;
+ struct pe_unicode_str * path;
+ uint32_t len;
+ void * hntdll;
+ os_zw_query_object * zw_query_object;
+ os_zw_open_file * zw_open_file;
+
+
+ /* init */
+ path = (struct pe_unicode_str *)buffer;
+
+ if (!(hntdll = pe_get_ntdll_module_handle()))
+ return OS_STATUS_INTERNAL_ERROR;
+
+ if (!(zw_query_object = (os_zw_query_object *)pe_get_procedure_address(
+ hntdll,"ZwQueryObject")))
+ return OS_STATUS_INTERNAL_ERROR;
+
+ if (!(zw_open_file = (os_zw_open_file *)pe_get_procedure_address(
+ hntdll,"ZwOpenFile")))
+ return OS_STATUS_INTERNAL_ERROR;
+
+ /* native path of base directory */
+ if ((status = zw_query_object(
+ href,
+ OS_OBJECT_NAME_INFORMATION,
+ path,
+ buffer_size,
+ &len)))
+ return status;
+
+ /* integrity */
+ if (len == sizeof(struct pe_unicode_str))
+ return OS_STATUS_BAD_FILE_TYPE;
+
+ /* device root directory */
+ root = path->buffer;
+ wch = path->buffer + (path->strlen / sizeof(uint16_t));
+
+
+ if ((root[0] != '\\')
+ || (root[1] != 'D') || (root[2] != 'e')
+ || (root[3] != 'v') || (root[4] != 'i')
+ || (root[5] != 'c') || (root[6] != 'e')
+ || (root[7] != '\\'))
+ return OS_STATUS_INTERNAL_ERROR;
+
+ for (root=&root[8]; (root<wch) && (*root!='\\'); )
+ root++;
+
+ if ((uint16_t)((++root - path->buffer) * sizeof(uint16_t)) == path->strlen)
+ return OS_STATUS_MORE_PROCESSING_REQUIRED;
+
+ /* physical parent directory path */
+ for (; (wch>root) && (wch[-1]!='\\'); )
+ wch--;
+
+ path->strlen = sizeof(uint16_t) * (uint16_t)(wch-path->buffer);
+ path->maxlen = 0;
+
+ /* oa */
+ oa.len = sizeof(struct os_oa);
+ oa.root_dir = 0;
+ oa.obj_name = path;
+ oa.obj_attr = 0;
+ oa.sec_desc = 0;
+ oa.sec_qos = 0;
+
+ /* default access */
+ desired_access = desired_access
+ ? desired_access
+ : OS_SEC_SYNCHRONIZE | OS_FILE_READ_ATTRIBUTES | OS_FILE_READ_ACCESS;
+
+ /* open parent directory */
+ return zw_open_file(
+ hparent,
+ desired_access,
+ &oa,
+ &iosb,
+ OS_FILE_SHARE_READ | OS_FILE_SHARE_WRITE,
+ open_options | OS_FILE_DIRECTORY_FILE);
+}