Blob Blame History Raw
/*********************************************************/
/*  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(&params)))
		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);
}