| |
| |
| |
| |
| |
| |
| #include <ntapi/ntapi.h> |
| #include <ntapi/nt_file.h> |
| #include "ntapi_impl.h" |
| |
| int32_t __stdcall __ntapi_tt_open_physical_parent_directory( |
| __out void ** hparent, |
| __in void * hdir, |
| __out void * buffer, |
| __in uint32_t buffer_size, |
| __in uint32_t oattr, |
| __in uint32_t desired_access, |
| __in uint32_t share_access, |
| __in uint32_t open_options, |
| __out int * reserved) |
| { |
| int32_t status; |
| nt_oa oa; |
| nt_iosb iosb; |
| wchar16_t * wch; |
| wchar16_t * root; |
| nt_unicode_string * path; |
| uint32_t len; |
| int mup; |
| uintptr_t addr; |
| uintptr_t addr_cap; |
| |
| (void)reserved; |
| |
| addr = (uintptr_t)buffer; |
| addr_cap = addr + buffer_size; |
| |
| addr += 0xf; |
| addr |= 0xf; |
| addr ^= 0xf; |
| |
| path = (nt_unicode_string *)addr; |
| buffer_size = addr_cap - addr; |
| |
| if ((status = __ntapi->zw_query_object( |
| hdir, |
| NT_OBJECT_NAME_INFORMATION, |
| path, |
| buffer_size, |
| &len))) |
| return status; |
| |
| |
| if (len == sizeof(nt_unicode_string)) |
| return NT_STATUS_BAD_FILE_TYPE; |
| |
| |
| root = path->buffer; |
| wch = path->buffer + (path->strlen / sizeof(uint16_t)); |
| |
| |
| if ((wch < &root[8]) |
| || (root[0] != '\\') |
| || (root[1] != 'D') || (root[2] != 'e') |
| || (root[3] != 'v') || (root[4] != 'i') |
| || (root[5] != 'c') || (root[6] != 'e') |
| || (root[7] != '\\')) |
| return NT_STATUS_INTERNAL_ERROR; |
| |
| mup = (wch > &root[11]) |
| && (root[8]=='M') |
| && (root[9]=='u') |
| && (root[10]=='p') |
| && (root[11]=='\\'); |
| |
| root = mup ? &root[12] : &root[8]; |
| |
| for (; (root<wch) && (*root!='\\'); ) |
| root++; |
| |
| if (root == wch) |
| return NT_STATUS_INTERNAL_ERROR; |
| |
| if (mup) |
| for (root++; (root<wch) && (*root!='\\'); ) |
| root++; |
| |
| if (root == wch) |
| return NT_STATUS_INTERNAL_ERROR; |
| |
| if (&root[1] == wch) |
| return NT_STATUS_MORE_PROCESSING_REQUIRED; |
| |
| if (wch[-1] == '\\') |
| wch--; |
| |
| |
| for (root++; (wch>=root) && (wch[-1]!='\\'); ) |
| wch--; |
| |
| path->strlen = (uint16_t)(wch - path->buffer) * sizeof(uint16_t); |
| path->maxlen = 0; |
| |
| |
| oa.len = sizeof(nt_oa); |
| oa.root_dir = 0; |
| oa.obj_name = path; |
| oa.obj_attr = oattr, |
| oa.sec_desc = 0; |
| oa.sec_qos = 0; |
| |
| |
| desired_access = desired_access |
| ? desired_access |
| : NT_SEC_SYNCHRONIZE | NT_FILE_READ_ATTRIBUTES | NT_FILE_READ_ACCESS; |
| |
| |
| return __ntapi->zw_open_file( |
| hparent, |
| desired_access, |
| &oa,&iosb, |
| share_access, |
| open_options | NT_FILE_DIRECTORY_FILE); |
| } |