|
|
393c20 |
/*****************************************************************************/
|
|
|
393c20 |
/* pemagination: a (virtual) tour into portable bits and executable bytes */
|
|
|
6dda52 |
/* Copyright (C) 2013--2020 SysDeer Technologies, LLC */
|
|
|
393c20 |
/* Released under GPLv2 and GPLv3; see COPYING.PEMAGINE. */
|
|
|
393c20 |
/*****************************************************************************/
|
|
|
393c20 |
|
|
|
393c20 |
#include <psxtypes/psxtypes.h>
|
|
|
393c20 |
#include <pemagine/pemagine.h>
|
|
|
393c20 |
#include <pemagine/pe_structs.h>
|
|
|
393c20 |
#include "pe_os.h"
|
|
|
393c20 |
|
|
|
393c20 |
int32_t pe_open_physical_parent_directory(
|
|
|
393c20 |
__out void ** hparent,
|
|
|
393c20 |
__in void * href,
|
|
|
393c20 |
__out uintptr_t * buffer,
|
|
|
29ad40 |
__in uint32_t bufsize,
|
|
|
9d2131 |
__in uint32_t oattr,
|
|
|
393c20 |
__in uint32_t desired_access,
|
|
|
9d2131 |
__in uint32_t share_access,
|
|
|
393c20 |
__in uint32_t open_options)
|
|
|
393c20 |
{
|
|
|
393c20 |
int32_t status;
|
|
|
393c20 |
struct os_oa oa;
|
|
|
393c20 |
struct os_iosb iosb;
|
|
|
393c20 |
wchar16_t * wch;
|
|
|
393c20 |
wchar16_t * root;
|
|
|
393c20 |
struct pe_unicode_str * path;
|
|
|
393c20 |
uint32_t len;
|
|
|
3a475b |
int mup;
|
|
|
393c20 |
void * hntdll;
|
|
|
393c20 |
os_zw_query_object * zw_query_object;
|
|
|
393c20 |
os_zw_open_file * zw_open_file;
|
|
|
393c20 |
|
|
|
393c20 |
|
|
|
393c20 |
/* init */
|
|
|
393c20 |
path = (struct pe_unicode_str *)buffer;
|
|
|
393c20 |
|
|
|
393c20 |
if (!(hntdll = pe_get_ntdll_module_handle()))
|
|
|
393c20 |
return OS_STATUS_INTERNAL_ERROR;
|
|
|
393c20 |
|
|
|
393c20 |
if (!(zw_query_object = (os_zw_query_object *)pe_get_procedure_address(
|
|
|
393c20 |
hntdll,"ZwQueryObject")))
|
|
|
393c20 |
return OS_STATUS_INTERNAL_ERROR;
|
|
|
393c20 |
|
|
|
393c20 |
if (!(zw_open_file = (os_zw_open_file *)pe_get_procedure_address(
|
|
|
393c20 |
hntdll,"ZwOpenFile")))
|
|
|
393c20 |
return OS_STATUS_INTERNAL_ERROR;
|
|
|
393c20 |
|
|
|
393c20 |
/* native path of base directory */
|
|
|
393c20 |
if ((status = zw_query_object(
|
|
|
393c20 |
href,
|
|
|
393c20 |
OS_OBJECT_NAME_INFORMATION,
|
|
|
393c20 |
path,
|
|
|
29ad40 |
bufsize,
|
|
|
393c20 |
&len)))
|
|
|
393c20 |
return status;
|
|
|
393c20 |
|
|
|
393c20 |
/* integrity */
|
|
|
393c20 |
if (len == sizeof(struct pe_unicode_str))
|
|
|
393c20 |
return OS_STATUS_BAD_FILE_TYPE;
|
|
|
393c20 |
|
|
|
393c20 |
/* device root directory */
|
|
|
393c20 |
root = path->buffer;
|
|
|
393c20 |
wch = path->buffer + (path->strlen / sizeof(uint16_t));
|
|
|
393c20 |
|
|
|
393c20 |
|
|
|
3a475b |
if ((wch < &root[8])
|
|
|
3a475b |
|| (root[0] != '\\')
|
|
|
393c20 |
|| (root[1] != 'D') || (root[2] != 'e')
|
|
|
393c20 |
|| (root[3] != 'v') || (root[4] != 'i')
|
|
|
393c20 |
|| (root[5] != 'c') || (root[6] != 'e')
|
|
|
393c20 |
|| (root[7] != '\\'))
|
|
|
393c20 |
return OS_STATUS_INTERNAL_ERROR;
|
|
|
393c20 |
|
|
|
3a475b |
mup = (wch > &root[11])
|
|
|
3a475b |
&& (root[8]=='M')
|
|
|
3a475b |
&& (root[9]=='u')
|
|
|
3a475b |
&& (root[10]=='p')
|
|
|
3a475b |
&& (root[11]=='\\');
|
|
|
3a475b |
|
|
|
3a475b |
root = mup ? &root[12] : &root[8];
|
|
|
3a475b |
|
|
|
3a475b |
for (; (root
|
|
|
393c20 |
root++;
|
|
|
393c20 |
|
|
|
3a475b |
if (root == wch)
|
|
|
3a475b |
return OS_STATUS_INTERNAL_ERROR;
|
|
|
3a475b |
|
|
|
3a475b |
if (mup)
|
|
|
3a475b |
for (root++; (root
|
|
|
3a475b |
root++;
|
|
|
3a475b |
|
|
|
3a475b |
if (root == wch)
|
|
|
3a475b |
return OS_STATUS_INTERNAL_ERROR;
|
|
|
3a475b |
|
|
|
3a475b |
if (&root[1] == wch)
|
|
|
393c20 |
return OS_STATUS_MORE_PROCESSING_REQUIRED;
|
|
|
393c20 |
|
|
|
3a475b |
if (wch[-1] == '\\')
|
|
|
3a475b |
wch--;
|
|
|
3a475b |
|
|
|
393c20 |
/* physical parent directory path */
|
|
|
3a475b |
for (root++; (wch>=root) && (wch[-1]!='\\'); )
|
|
|
393c20 |
wch--;
|
|
|
393c20 |
|
|
|
3a475b |
path->strlen = (uint16_t)(wch - path->buffer) * sizeof(uint16_t);
|
|
|
393c20 |
path->maxlen = 0;
|
|
|
393c20 |
|
|
|
393c20 |
/* oa */
|
|
|
393c20 |
oa.len = sizeof(struct os_oa);
|
|
|
393c20 |
oa.root_dir = 0;
|
|
|
393c20 |
oa.obj_name = path;
|
|
|
9d2131 |
oa.obj_attr = oattr;
|
|
|
393c20 |
oa.sec_desc = 0;
|
|
|
393c20 |
oa.sec_qos = 0;
|
|
|
393c20 |
|
|
|
393c20 |
/* default access */
|
|
|
393c20 |
desired_access = desired_access
|
|
|
393c20 |
? desired_access
|
|
|
393c20 |
: OS_SEC_SYNCHRONIZE | OS_FILE_READ_ATTRIBUTES | OS_FILE_READ_ACCESS;
|
|
|
393c20 |
|
|
|
393c20 |
/* open parent directory */
|
|
|
393c20 |
return zw_open_file(
|
|
|
393c20 |
hparent,
|
|
|
393c20 |
desired_access,
|
|
|
9d2131 |
&oa,&iosb,
|
|
|
9d2131 |
share_access,
|
|
|
393c20 |
open_options | OS_FILE_DIRECTORY_FILE);
|
|
|
393c20 |
}
|