/*********************************************************/
/* toksvc: a framework-native token broker service */
/* Copyright (C) 2020 Z. Gilboa */
/* Released under GPLv2 and GPLv3; see COPYING.TOKSVC. */
/*********************************************************/
#include <psxtypes/psxtypes.h>
#include <ntapi/ntapi.h>
#include <toksvc/toksvc.h>
#include "toksvc_driver_impl.h"
static int32_t toks_open(
void ** hfile,
void * hat,
const char * arg,
nt_sd * sd,
uint32_t attr,
uint32_t options,
uint32_t disposition,
bool fprivate)
{
int32_t status;
nt_oa oa;
nt_iosb iosb;
nt_unicode_string path;
nt_unicode_conversion_params_utf8_to_utf16 params = {0,0,0,0,0,0,0,0,0};
wchar16_t buffer[4096];
wchar16_t * wch;
size_t nbytes;
uint32_t access;
nt_large_integer alloc_size;
/* utf-8 --> utf-16 */
params.src = (const unsigned char *)arg;
params.src_size_in_bytes= ntapi->tt_string_null_offset_multibyte(arg);
params.dst = buffer;
params.dst_size_in_bytes= sizeof(buffer);
if ((status = ntapi->uc_convert_unicode_stream_utf8_to_utf16(¶ms)))
return status;
/* convenience */
for (wch=buffer, nbytes=params.bytes_written; nbytes; ) {
if (*wch == '/')
*wch = '\\';
nbytes -= sizeof(wchar16_t);
wch++;
}
/* path */
path.maxlen = 0;
path.strlen = (uint16_t)params.bytes_written;
path.buffer = buffer;
/* oa */
oa.len = sizeof(nt_oa);
oa.root_dir = (buffer[0]=='\\') ? 0 : hat;
oa.obj_name = &path;
oa.obj_attr = fprivate ? 0 : NT_OBJ_INHERIT;
oa.sec_desc = sd;
oa.sec_qos = 0;
/* alloc_size (always zero) */
alloc_size.quad = 0;
/* access */
access = NT_SEC_SYNCHRONIZE | NT_FILE_READ_ATTRIBUTES | NT_FILE_READ_DATA;
access |= (disposition == NT_FILE_OPEN_IF) ? NT_FILE_WRITE_DATA : 0;
/* open/create */
return ntapi->zw_create_file(
hfile,
access,&oa,&iosb,&alloc_size,attr,
NT_FILE_SHARE_READ | NT_FILE_SHARE_WRITE | NT_FILE_SHARE_DELETE,
disposition,
options | NT_FILE_SYNCHRONOUS_IO_ALERT,
0,0);
}
static int32_t toks_open_volume(
void ** hfile,
void * hat,
const char * arg,
nt_sd * sd,
uint32_t attr,
uint32_t options,
uint32_t disposition,
bool fprivate)
{
int32_t status;
void * hvolume = 0;
wchar16_t drive = arg[0];
if ((arg[1]==':') && ((arg[2]=='\\') || (arg[2]=='/'))) {
if ((status = ntapi->tt_get_dos_drive_root_handle(
&hvolume,drive)))
return status;
hat = hvolume;
arg = &arg[3];
}
status = toks_open(
hfile,hat,arg,sd,attr,
options,disposition,
fprivate);
if (hvolume)
ntapi->zw_close(hvolume);
return status;
}
int32_t toks_open_file(void ** hfile, void * hat, const char * arg, bool fprivate)
{
return toks_open_volume(
hfile,hat,arg,0,
NT_FILE_ATTRIBUTE_NORMAL,
NT_FILE_NON_DIRECTORY_FILE,
NT_FILE_OPEN,
fprivate);
}
int32_t toks_open_dir(void ** hfile, void * hat, const char * arg, bool fprivate)
{
return toks_open_volume(
hfile,hat,arg,0,
NT_FILE_ATTRIBUTE_DIRECTORY,
NT_FILE_DIRECTORY_FILE,
NT_FILE_OPEN,
fprivate);
}