|
|
2f270e |
/*********************************************************/
|
|
|
2f270e |
/* toksvc: a framework-native token broker service */
|
|
|
2f270e |
/* Copyright (C) 2020 Z. Gilboa */
|
|
|
2f270e |
/* Released under GPLv2 and GPLv3; see COPYING.TOKSVC. */
|
|
|
2f270e |
/*********************************************************/
|
|
|
2f270e |
|
|
|
2f270e |
#include <psxtypes/psxtypes.h>
|
|
|
2f270e |
|
|
|
2f270e |
#include "toksvc_driver_impl.h"
|
|
|
2f270e |
#include "toksvc_dprintf_impl.h"
|
|
|
2f270e |
#include "toksvc_log_impl.h"
|
|
|
2f270e |
|
|
|
2f270e |
static const char * toks_log_entry_header[15] = {
|
|
|
2f270e |
[TOKS_LOG_ENTRY_SERVER_STATUS] = "SERVER (STATUS):",
|
|
|
2f270e |
[TOKS_LOG_ENTRY_SERVER_INFO] = "SERVER (INFO): ",
|
|
|
2f270e |
[TOKS_LOG_ENTRY_SERVER_ERROR] = "SERVER (ERROR): ",
|
|
|
2f270e |
[TOKS_LOG_ENTRY_CLIENT_STATUS] = "CLIENT (STATUS):",
|
|
|
2f270e |
[TOKS_LOG_ENTRY_CLIENT_INFO] = "CLIENT (INFO): ",
|
|
|
2f270e |
[TOKS_LOG_ENTRY_CLIENT_ERROR] = "CLIENT (ERROR): ",
|
|
|
2f270e |
[TOKS_LOG_ENTRY_SUB_LEVEL_1] = " ├─",
|
|
|
2f270e |
[TOKS_LOG_ENTRY_SUB_LEVEL_2] = " ├───",
|
|
|
2f270e |
[TOKS_LOG_ENTRY_SUB_LEVEL_3] = " ├─────",
|
|
|
2f270e |
[TOKS_LOG_ENTRY_SUB_LEVEL_4] = " ├───────",
|
|
|
2f270e |
[TOKS_LOG_ENTRY_SUB_LEVEL_5] = " ├─────────",
|
|
|
2f270e |
[TOKS_LOG_ENTRY_SUB_LEVEL_6] = " ├───────────",
|
|
|
2f270e |
};
|
|
|
2f270e |
|
|
|
2f270e |
static int32_t toks_log_strconv_utf16_to_utf8(
|
|
|
2f270e |
const wchar16_t * wch,
|
|
|
2f270e |
size_t len,
|
|
|
2f270e |
char * ch,
|
|
|
2f270e |
size_t bufsize)
|
|
|
2f270e |
{
|
|
|
2f270e |
int32_t status;
|
|
|
2f270e |
nt_strconv_nativetomb params;
|
|
|
2f270e |
|
|
|
2f270e |
params.src = wch;
|
|
|
2f270e |
params.src_size_in_bytes = len;
|
|
|
2f270e |
params.dst = (unsigned char *)ch;
|
|
|
2f270e |
params.dst_size_in_bytes = bufsize;
|
|
|
2f270e |
params.code_points = 0;
|
|
|
2f270e |
params.bytes_written = 0;
|
|
|
2f270e |
|
|
|
2f270e |
status = ntapi->uc_convert_unicode_stream_utf16_to_utf8(¶ms);
|
|
|
2f270e |
|
|
|
2f270e |
if (status == NT_STATUS_SUCCESS)
|
|
|
2f270e |
ch[params.bytes_written] = 0;
|
|
|
2f270e |
|
|
|
2f270e |
return params.leftover_count
|
|
|
2f270e |
? NT_STATUS_ILLEGAL_CHARACTER
|
|
|
2f270e |
: status;
|
|
|
2f270e |
}
|
|
|
2f270e |
|
|
|
2f270e |
static int32_t toks_log_write_impl(
|
|
|
2f270e |
const struct toks_driver_ctx * dctx,
|
|
|
2f270e |
const void * buf,
|
|
|
2f270e |
size_t size)
|
|
|
2f270e |
{
|
|
|
2f270e |
int32_t status;
|
|
|
2f270e |
nt_runtime_data * rtdata;
|
|
|
2f270e |
ntapi_zw_write_file * iofn;
|
|
|
2f270e |
void * hlog;
|
|
|
2f270e |
void * hio;
|
|
|
2f270e |
void * hevent;
|
|
|
2f270e |
int fdtype;
|
|
|
2f270e |
nt_iosb iosb;
|
|
|
f0dcca |
const char * ch;
|
|
|
2f270e |
|
|
|
2f270e |
/* size */
|
|
|
2f270e |
if (size >= 0x80000000)
|
|
|
2f270e |
return NT_STATUS_INVALID_PARAMETER;
|
|
|
2f270e |
|
|
|
2f270e |
/* rtdata, hevent, hlog */
|
|
|
2f270e |
hevent = toks_get_driver_hevent(dctx);
|
|
|
2f270e |
rtdata = toks_get_driver_rtdata(dctx);
|
|
|
2f270e |
hlog = rtdata->hlog;
|
|
|
f0dcca |
ch = buf;
|
|
|
2f270e |
|
|
|
2f270e |
/* hio, io type */
|
|
|
2f270e |
if (hlog) {
|
|
|
2f270e |
hio = hlog;
|
|
|
2f270e |
fdtype = NT_FILE_TYPE_UNKNOWN;
|
|
|
2f270e |
} else {
|
|
|
2f270e |
hio = rtdata->hstderr;
|
|
|
2f270e |
fdtype = rtdata->stderr_type;
|
|
|
2f270e |
}
|
|
|
2f270e |
|
|
|
2f270e |
if (!hio)
|
|
|
2f270e |
return NT_STATUS_INVALID_HANDLE;
|
|
|
2f270e |
|
|
|
2f270e |
/* iofn */
|
|
|
2f270e |
iofn = (fdtype == NT_FILE_TYPE_PTY)
|
|
|
2f270e |
? (ntapi_zw_write_file *)toks_ntapi->pty_write
|
|
|
2f270e |
: toks_ntapi->zw_write_file;
|
|
|
2f270e |
|
|
|
2f270e |
/* iowrite */
|
|
|
f0dcca |
do {
|
|
|
f0dcca |
iosb.status = NT_STATUS_PENDING;
|
|
|
f0dcca |
|
|
|
f0dcca |
status = iofn(
|
|
|
f0dcca |
hio,hevent,
|
|
|
f0dcca |
0,0,&iosb,
|
|
|
f0dcca |
(void *)ch,
|
|
|
f0dcca |
size,0,0);
|
|
|
f0dcca |
|
|
|
f0dcca |
if (status == NT_STATUS_PENDING)
|
|
|
f0dcca |
toks_ntapi->zw_wait_for_single_object(
|
|
|
2f270e |
hevent,0,0);
|
|
|
2f270e |
|
|
|
f0dcca |
size -= iosb.info;
|
|
|
f0dcca |
ch += iosb.info;
|
|
|
f0dcca |
} while (size && (iosb.status == NT_STATUS_SUCCESS));
|
|
|
f0dcca |
|
|
|
2f270e |
|
|
|
2f270e |
/* ret */
|
|
|
f0dcca |
return iosb.status;
|
|
|
2f270e |
}
|
|
|
2f270e |
|
|
|
2f270e |
void toks_log_header(
|
|
|
2f270e |
const struct toks_driver_ctx * dctx,
|
|
|
2f270e |
enum toks_log_entry_type type,
|
|
|
2f270e |
const char * fmt,
|
|
|
2f270e |
...)
|
|
|
2f270e |
{
|
|
|
2f270e |
nt_filetime pcnt;
|
|
|
2f270e |
va_list ap;
|
|
|
2f270e |
char * ch;
|
|
|
2f270e |
char buf[2048];
|
|
|
2f270e |
|
|
|
2f270e |
toks_query_performance_counters(dctx,&pcnt);
|
|
|
2f270e |
|
|
|
2f270e |
va_start(ap, fmt);
|
|
|
2f270e |
ch = buf;
|
|
|
2f270e |
ch += ntapi->sprintf(ch,"\n[%08x.%08x]: ",pcnt.ihigh,pcnt.ulow);
|
|
|
2f270e |
ch += ntapi->sprintf(ch,"%s ",toks_log_entry_header[type]);
|
|
|
2f270e |
ch += ntapi->vsnprintf(ch, &buf[sizeof(buf)] - ch, fmt, ap);
|
|
|
2f270e |
va_end(ap);
|
|
|
2f270e |
|
|
|
2f270e |
toks_log_write_impl(dctx,buf,ch-buf);
|
|
|
2f270e |
}
|
|
|
2f270e |
|
|
|
2f270e |
void toks_log_write(
|
|
|
2f270e |
const struct toks_driver_ctx * dctx,
|
|
|
2f270e |
enum toks_log_entry_type type,
|
|
|
2f270e |
const char * fmt,
|
|
|
2f270e |
...)
|
|
|
2f270e |
{
|
|
|
2f270e |
va_list ap;
|
|
|
2f270e |
char * ch;
|
|
|
2f270e |
char buf[2048];
|
|
|
2f270e |
|
|
|
2f270e |
va_start(ap, fmt);
|
|
|
2f270e |
ch = buf;
|
|
|
2f270e |
ch += ntapi->sprintf(buf,"%s ",toks_log_entry_header[type]);
|
|
|
2f270e |
ch += ntapi->vsnprintf(ch, &buf[sizeof(buf)] - ch, fmt, ap);
|
|
|
2f270e |
va_end(ap);
|
|
|
2f270e |
|
|
|
2f270e |
toks_log_write_impl(dctx,buf,ch-buf);
|
|
|
2f270e |
}
|
|
|
2f270e |
|
|
|
2f270e |
void toks_log_get_process_name(void * hprocess, char * utf8, size_t bytes)
|
|
|
2f270e |
{
|
|
|
2f270e |
wchar16_t buf[0x1000];
|
|
|
2f270e |
nt_unicode_string * path;
|
|
|
2f270e |
|
|
|
2f270e |
path = (nt_unicode_string *)buf;
|
|
|
2f270e |
|
|
|
2f270e |
if (!(ntapi->zw_query_information_process(
|
|
|
2f270e |
hprocess,
|
|
|
2f270e |
NT_PROCESS_IMAGE_FILE_NAME,
|
|
|
2f270e |
buf,sizeof(buf),
|
|
|
2f270e |
&(uint32_t){0})))
|
|
|
2f270e |
if (!(toks_log_strconv_utf16_to_utf8(
|
|
|
2f270e |
path->buffer,
|
|
|
2f270e |
path->strlen,
|
|
|
2f270e |
utf8,bytes)))
|
|
|
2f270e |
return;
|
|
|
2f270e |
|
|
|
2f270e |
ntapi->tt_generic_memcpy(
|
|
|
2f270e |
utf8,
|
|
|
2f270e |
(char[]){'#','E','R','R','O','R',0},
|
|
|
2f270e |
7);
|
|
|
2f270e |
}
|
|
|
2f270e |
|
|
|
2f270e |
void toks_log_get_arbitrary_process_name(nt_cid * cid, char * utf8, size_t bytes)
|
|
|
2f270e |
{
|
|
|
2f270e |
void * hprocess = NT_INVALID_HANDLE_VALUE;
|
|
|
2f270e |
nt_oa oa = {sizeof(oa),0,0,0,0,0};
|
|
|
2f270e |
|
|
|
2f270e |
if (cid->process_id == 0) {
|
|
|
2f270e |
*utf8++ = '(';
|
|
|
2f270e |
*utf8++ = 'N';
|
|
|
2f270e |
*utf8++ = '/';
|
|
|
2f270e |
*utf8++ = 'A';
|
|
|
2f270e |
*utf8++ = ')';
|
|
|
2f270e |
*utf8++ = 0;
|
|
|
2f270e |
return;
|
|
|
2f270e |
}
|
|
|
2f270e |
|
|
|
2f270e |
ntapi->zw_open_process(
|
|
|
2f270e |
&hprocess,
|
|
|
2f270e |
NT_PROCESS_SYNCHRONIZE | NT_PROCESS_QUERY_INFORMATION,
|
|
|
2f270e |
&oa,cid);
|
|
|
2f270e |
|
|
|
2f270e |
if (hprocess == NT_INVALID_HANDLE_VALUE) {
|
|
|
2f270e |
ntapi->tt_generic_memcpy(
|
|
|
2f270e |
utf8,
|
|
|
2f270e |
(char[]){'#','E','R','R','O','R',0},
|
|
|
2f270e |
7);
|
|
|
2f270e |
|
|
|
2f270e |
return;
|
|
|
2f270e |
}
|
|
|
2f270e |
|
|
|
2f270e |
toks_log_get_process_name(
|
|
|
2f270e |
hprocess,
|
|
|
2f270e |
utf8,bytes);
|
|
|
2f270e |
|
|
|
2f270e |
ntapi->zw_close(
|
|
|
2f270e |
hprocess);
|
|
|
2f270e |
}
|
|
|
2f270e |
|
|
|
2f270e |
const char * toks_log_basename(const char * path)
|
|
|
2f270e |
{
|
|
|
2f270e |
const char * ch;
|
|
|
2f270e |
|
|
|
2f270e |
for (ch=path; *ch; ch++)
|
|
|
2f270e |
(void)0;
|
|
|
2f270e |
|
|
|
2f270e |
for (--ch; ch>=path; ch--)
|
|
|
2f270e |
if (*ch == '\\')
|
|
|
2f270e |
return ++ch;
|
|
|
2f270e |
|
|
|
2f270e |
return path;
|
|
|
2f270e |
}
|