|
|
dd89bb |
/********************************************************/
|
|
|
dd89bb |
/* ntapi: Native API core library */
|
|
|
64e606 |
/* Copyright (C) 2013--2021 SysDeer Technologies, LLC */
|
|
|
dd89bb |
/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */
|
|
|
dd89bb |
/********************************************************/
|
|
|
dd89bb |
|
|
|
dd89bb |
#include <psxtypes/psxtypes.h>
|
|
|
dd89bb |
#include <ntapi/nt_ldr.h>
|
|
|
dd89bb |
#include <ntapi/ntapi.h>
|
|
|
dd89bb |
#include "ntapi_impl.h"
|
|
|
dd89bb |
|
|
|
dd89bb |
int32_t __stdcall __ntapi_ldr_load_system_dll(
|
|
|
dd89bb |
__in void * hsysdir __optional,
|
|
|
dd89bb |
__in wchar16_t * base_name,
|
|
|
ee679a |
__in uint16_t base_name_size,
|
|
|
dd89bb |
__in uint32_t * image_flags __optional,
|
|
|
dd89bb |
__out void ** image_base)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
int32_t status;
|
|
|
1f892c |
void * hkernel32;
|
|
|
8e91cc |
wchar16_t * wch;
|
|
|
1f892c |
wchar16_t * cap;
|
|
|
22238c |
wchar16_t * sysdir;
|
|
|
22238c |
nt_unicode_string nt_sysdir;
|
|
|
dd89bb |
nt_unicode_string nt_image_name;
|
|
|
1f892c |
size_t buffer[0x200/sizeof(size_t)];
|
|
|
1f892c |
void * (*load_library_ex_utf16)(
|
|
|
1f892c |
wchar16_t *,
|
|
|
1f892c |
void *,
|
|
|
1f892c |
uint32_t);
|
|
|
dd89bb |
|
|
|
c713d8 |
(void)image_flags;
|
|
|
c713d8 |
|
|
|
1f892c |
/* shell-style dos path */
|
|
|
22238c |
sysdir = (wchar16_t *)buffer;
|
|
|
dd89bb |
|
|
|
22238c |
if ((status = __ntapi->tt_get_system_directory_dos_path(
|
|
|
22238c |
hsysdir,
|
|
|
22238c |
sysdir,sizeof(buffer),
|
|
|
22238c |
0,0,&nt_sysdir)))
|
|
|
dd89bb |
return status;
|
|
|
dd89bb |
|
|
|
da3cfa |
sysdir = &sysdir[4];
|
|
|
da3cfa |
|
|
|
da3cfa |
/* image */
|
|
|
22238c |
nt_image_name.strlen = base_name_size;
|
|
|
22238c |
nt_image_name.maxlen = base_name_size;
|
|
|
22238c |
nt_image_name.buffer = base_name;
|
|
|
22238c |
|
|
|
1f892c |
/* the logical way */
|
|
|
8e91cc |
status = __ntapi->ldr_load_dll(
|
|
|
8e91cc |
sysdir,0,
|
|
|
8e91cc |
&nt_image_name,
|
|
|
8e91cc |
image_base);
|
|
|
8e91cc |
|
|
|
1f892c |
/* eight point one big sigh support */
|
|
|
1f892c |
if (status) {
|
|
|
1f892c |
cap = &sysdir[sizeof(buffer)/sizeof(wchar16_t)];
|
|
|
1f892c |
|
|
|
1f892c |
for (wch=sysdir; *wch; wch++)
|
|
|
1f892c |
(void)0;
|
|
|
1f892c |
|
|
|
1f892c |
if (&wch[base_name_size/sizeof(wchar16_t)] >= cap)
|
|
|
1f892c |
return NT_STATUS_BUFFER_TOO_SMALL;
|
|
|
1f892c |
|
|
|
1f892c |
if (!(hkernel32 = pe_get_kernel32_module_handle()))
|
|
|
1f892c |
return NT_STATUS_INTERNAL_ERROR;
|
|
|
1f892c |
|
|
|
1f892c |
if (!(load_library_ex_utf16 = pe_get_procedure_address(
|
|
|
1f892c |
hkernel32,"LoadLibraryExW")))
|
|
|
1f892c |
return NT_STATUS_INTERNAL_ERROR;
|
|
|
1f892c |
|
|
|
1f892c |
__ntapi->tt_memcpy_utf16(
|
|
|
1f892c |
wch,base_name,
|
|
|
1f892c |
base_name_size);
|
|
|
1f892c |
|
|
|
1f892c |
wch[base_name_size/sizeof(wchar16_t)] = 0;
|
|
|
8e91cc |
|
|
|
1f892c |
if ((*image_base = load_library_ex_utf16(sysdir,0,0)))
|
|
|
1f892c |
status = NT_STATUS_SUCCESS;
|
|
|
8e91cc |
}
|
|
|
8e91cc |
|
|
|
1f892c |
/* downlevel... */
|
|
|
1f892c |
if (status) {
|
|
|
1f892c |
if (&wch[base_name_size/sizeof(wchar16_t)] >= &cap[-10])
|
|
|
1f892c |
return NT_STATUS_BUFFER_TOO_SMALL;
|
|
|
1f892c |
|
|
|
1f892c |
*wch++ = 'd';
|
|
|
1f892c |
*wch++ = 'o';
|
|
|
1f892c |
*wch++ = 'w';
|
|
|
1f892c |
*wch++ = 'n';
|
|
|
1f892c |
*wch++ = 'l';
|
|
|
1f892c |
*wch++ = 'e';
|
|
|
1f892c |
*wch++ = 'v';
|
|
|
1f892c |
*wch++ = 'e';
|
|
|
1f892c |
*wch++ = 'l';
|
|
|
1f892c |
*wch++ = '\\';
|
|
|
1f892c |
|
|
|
1f892c |
__ntapi->tt_memcpy_utf16(
|
|
|
1f892c |
wch,base_name,
|
|
|
1f892c |
base_name_size);
|
|
|
1f892c |
|
|
|
1f892c |
wch[base_name_size/sizeof(wchar16_t)] = 0;
|
|
|
1f892c |
|
|
|
1f892c |
if ((*image_base = load_library_ex_utf16(sysdir,0,0)))
|
|
|
1f892c |
status = NT_STATUS_SUCCESS;
|
|
|
1f892c |
}
|
|
|
1f892c |
|
|
|
1f892c |
return status;
|
|
|
dd89bb |
}
|