Blame src/internal/ptycon_open_impl.c

acafe9
/*********************************************************/
acafe9
/*  ptycon: a pty-console bridge                         */
f25e99
/*  Copyright (C) 2016--2017  SysDeer Technologies, LLC  */
acafe9
/*  Released under GPLv2 and GPLv3; see COPYING.PTYCON.  */
acafe9
/*********************************************************/
acafe9
acafe9
#include <psxtypes/psxtypes.h>
acafe9
#include <ntcon/ntcon.h>
acafe9
#include <ntapi/ntapi.h>
acafe9
acafe9
#include <ptycon/ptycon.h>
acafe9
#include "ptycon_driver_impl.h"
acafe9
acafe9
static int32_t ptyc_open(
acafe9
	void **		hfile,
acafe9
	void *		hat,
acafe9
	const char *	arg,
acafe9
	uint32_t	options,
acafe9
	bool		fprivate)
acafe9
{
acafe9
	int32_t						status;
acafe9
	nt_oa						oa;
acafe9
	nt_iosb						iosb;
acafe9
	nt_unicode_string				path;
acafe9
	nt_unicode_conversion_params_utf8_to_utf16	params = {0,0,0,0,0,0,0,0,0};
acafe9
	wchar16_t					buffer[4096];
acafe9
	wchar16_t *					wch;
acafe9
	size_t						nbytes;
acafe9
acafe9
	/* utf-8 --> utf-16 */
acafe9
	params.src		= (const unsigned char *)arg;
acafe9
	params.src_size_in_bytes= ntapi->tt_string_null_offset_multibyte(arg);
acafe9
	params.dst		= buffer;
acafe9
	params.dst_size_in_bytes= sizeof(buffer);
acafe9
acafe9
	if ((status = ntapi->uc_convert_unicode_stream_utf8_to_utf16(&params)))
acafe9
		return status;
acafe9
acafe9
	/* convenience */
acafe9
	for (wch=buffer, nbytes=params.bytes_written; nbytes; ) {
acafe9
		if (*wch == '/')
acafe9
			*wch = '\\';
acafe9
acafe9
		nbytes -= sizeof(wchar16_t);
acafe9
		wch++;
acafe9
	}
acafe9
acafe9
	/* path */
acafe9
	path.maxlen = 0;
acafe9
	path.strlen = (uint16_t)params.bytes_written;
acafe9
	path.buffer = buffer;
acafe9
acafe9
	/* oa */
acafe9
	oa.len      = sizeof(nt_oa);
3995d6
	oa.root_dir = (buffer[0]=='\\') ? 0 : hat;
acafe9
	oa.obj_name = &pat;;
acafe9
	oa.obj_attr = fprivate ? 0 : NT_OBJ_INHERIT;
acafe9
	oa.sec_desc = 0;
acafe9
	oa.sec_qos  = 0;
acafe9
acafe9
	/* open */
acafe9
	return ntapi->zw_open_file(
acafe9
		hfile,
acafe9
		NT_SEC_SYNCHRONIZE | NT_FILE_READ_ATTRIBUTES | NT_FILE_READ_DATA,
acafe9
		&oa,&iosb,
acafe9
		NT_FILE_SHARE_READ | NT_FILE_SHARE_WRITE | NT_FILE_SHARE_DELETE,
acafe9
		options | NT_FILE_SYNCHRONOUS_IO_ALERT);
acafe9
}
acafe9
83af1d
static int32_t ptyc_open_volume(
83af1d
	void **		hfile,
83af1d
	void *		hat,
83af1d
	const char *	arg,
83af1d
	uint32_t	options,
83af1d
	bool		fprivate)
83af1d
{
83af1d
	int32_t   status;
83af1d
	void *    hvolume = 0;
83af1d
	wchar16_t drive   = arg[0];
83af1d
83af1d
	if ((arg[1]==':') && ((arg[2]=='\\') || (arg[2]=='/'))) {
83af1d
		if ((status = ntapi->tt_get_dos_drive_root_handle(
fbf30b
				&hvolume,drive)))
83af1d
			return status;
83af1d
83af1d
		hat = hvolume;
83af1d
		arg = &arg[3];
83af1d
	}
83af1d
83af1d
	status = ptyc_open(
83af1d
		hfile,hat,arg,
83af1d
		options,fprivate);
83af1d
83af1d
	if (hvolume)
83af1d
		ntapi->zw_close(hvolume);
83af1d
83af1d
	return status;
83af1d
}
83af1d
acafe9
int32_t ptyc_open_file(void ** hfile, void * hat, const char * arg, bool fprivate)
acafe9
{
83af1d
	return ptyc_open_volume(hfile,hat,arg,NT_FILE_NON_DIRECTORY_FILE,fprivate);
acafe9
}
acafe9
acafe9
int32_t ptyc_open_dir(void ** hfile, void * hat, const char * arg, bool fprivate)
acafe9
{
83af1d
	return ptyc_open_volume(hfile,hat,arg,NT_FILE_DIRECTORY_FILE,fprivate);
acafe9
}