Exemplo n.º 1
0
NTSTATUS NTAPI NtCreateNamedPipeFile(
	PHANDLE PipeHandle,
	ACCESS_MASK AccessMask,
	POBJECT_ATTRIBUTES ObjectAttributes,
	PIO_STATUS_BLOCK IoStatusBlock,
	ULONG ShareAccess,
	ULONG CreateDisposition,
	ULONG CreateOptions,
	BOOLEAN TypeMessage,
	BOOLEAN ReadModeMessage,
	BOOLEAN NonBlocking,
	ULONG MaxInstances,
	ULONG InBufferSize,
	ULONG OutBufferSize,
	PLARGE_INTEGER DefaultTimeout)
{
	LARGE_INTEGER timeout;
	object_attributes_t oa;
	NTSTATUS r;

	if (CreateDisposition != FILE_OPEN_IF)
		return STATUS_INVALID_PARAMETER;

	if (MaxInstances == 0)
		return STATUS_INVALID_PARAMETER;

	if (ObjectAttributes == NULL)
		return STATUS_INVALID_PARAMETER;

	if (!(ShareAccess & FILE_SHARE_READ))
		return STATUS_INVALID_PARAMETER;
	if (!(ShareAccess & FILE_SHARE_WRITE))
		return STATUS_INVALID_PARAMETER;

	r = copy_from_user( &timeout, DefaultTimeout, sizeof timeout );
	if (r < STATUS_SUCCESS)
		return r;

	if (timeout.QuadPart > 0)
		return STATUS_INVALID_PARAMETER;

	r = verify_for_write( PipeHandle, sizeof *PipeHandle );
	if (r < STATUS_SUCCESS)
		return r;

	r = verify_for_write( IoStatusBlock, sizeof IoStatusBlock );
	if (r < STATUS_SUCCESS)
		return r;

	pipe_factory factory( MaxInstances );

	return factory.create( PipeHandle, AccessMask, ObjectAttributes );
}
Exemplo n.º 2
0
NTSTATUS NTAPI NtQuerySymbolicLinkObject(
	HANDLE SymbolicLinkHandle,
	PUNICODE_STRING LinkName,
	PULONG DataWritten )
{
	UNICODE_STRING name;
	NTSTATUS r;

	r = copy_from_user( &name, LinkName, sizeof name );
	if (r < STATUS_SUCCESS)
		return r;

	// make sure we can write back the length
	r = verify_for_write( &LinkName->Length, sizeof LinkName->Length );
	if (r < STATUS_SUCCESS)
		return r;

	if (DataWritten)
	{
		r = verify_for_write( DataWritten, sizeof DataWritten );
		if (r < STATUS_SUCCESS)
			return r;
	}

	symlink_t *symlink = 0;
	r = object_from_handle( symlink, SymbolicLinkHandle, 0 );
	if (r < STATUS_SUCCESS)
		return r;

	const unicode_string_t& target = symlink->get_target();

	if (name.MaximumLength < target.Length)
		return STATUS_BUFFER_TOO_SMALL;

	r = copy_to_user( name.Buffer, target.Buffer, target.Length );
	if (r < STATUS_SUCCESS)
		return r;

	copy_to_user( &LinkName->Length, &target.Length, sizeof target.Length );

	if (DataWritten)
	{
		// convert from USHORT to ULONG
		ULONG len = target.Length;
		copy_to_user( DataWritten, &len, sizeof len );
	}

	return r;
}
Exemplo n.º 3
0
NTSTATUS NTAPI NtEnumerateKey(
	HANDLE KeyHandle,
	ULONG Index,
	KEY_INFORMATION_CLASS KeyInformationClass,
	PVOID KeyInformation,
	ULONG KeyInformationLength,
	PULONG ResultLength)
{
	regkey_t *key = 0;
	NTSTATUS r = object_from_handle( key, KeyHandle, KEY_ENUMERATE_SUB_KEYS );
	if (r < STATUS_SUCCESS)
		return r;

	if (ResultLength)
	{
		r = verify_for_write( ResultLength, sizeof *ResultLength );
		if (r < STATUS_SUCCESS)
			return r;
	}

	if (!key_info_class_valid(KeyInformationClass))
		return STATUS_INVALID_INFO_CLASS;

	regkey_t *child = key->get_child( Index );
	if (!child)
		return STATUS_NO_MORE_ENTRIES;

	return child->query( KeyInformationClass, KeyInformation, KeyInformationLength, ResultLength );
}
Exemplo n.º 4
0
NTSTATUS NTAPI NtCreateKey(
	PHANDLE KeyHandle,
	ACCESS_MASK DesiredAccess,
	POBJECT_ATTRIBUTES ObjectAttributes,
	ULONG TitleIndex,
	PUNICODE_STRING Class,
	ULONG CreateOptions,
	PULONG Disposition )
{
	object_attributes_t oa;
	NTSTATUS r;
	regkey_t *key = NULL;

	trace("%p %08lx %p %lu %p %lu %p\n", KeyHandle, DesiredAccess,
			ObjectAttributes, TitleIndex, Class, CreateOptions, Disposition );

	if (Disposition)
	{
		r = verify_for_write( Disposition, sizeof *Disposition );
		if (r < STATUS_SUCCESS)
			return r;
	}

	r = oa.copy_from_user( ObjectAttributes );
	if (r < STATUS_SUCCESS)
		return r;

	trace("len %08lx root %p attr %08lx %pus\n",
			oa.Length, oa.RootDirectory, oa.Attributes, oa.ObjectName);

	unicode_string_t cls;
	if (Class)
	{
		r = cls.copy_from_user( Class );
		if (r < STATUS_SUCCESS)
			return r;
	}

	bool opened_existing = false;
	r = create_key( &key, &oa, opened_existing );
	if (r == STATUS_SUCCESS)
	{
		if (Disposition)
		{
			ULONG dispos = opened_existing ? REG_OPENED_EXISTING_KEY : REG_CREATED_NEW_KEY;
			copy_to_user( Disposition, &dispos, sizeof *Disposition );
		}
		key->cls.copy( &cls );
		r = alloc_user_handle( key, DesiredAccess, KeyHandle );
		//release( event );
	}
	return r;
}
Exemplo n.º 5
0
// pg 108
NTSTATUS NTAPI NtMapViewOfSection(
	HANDLE SectionHandle,
	HANDLE ProcessHandle,
	PVOID *BaseAddress,
	ULONG ZeroBits,
	ULONG CommitSize,
	PLARGE_INTEGER SectionOffset,
	PULONG ViewSize,
	SECTION_INHERIT InheritDisposition,
	ULONG AllocationType,
	ULONG Protect )
{
	process_t *p = NULL;
	BYTE *addr = NULL;
	NTSTATUS r;

	trace("%p %p %p %lu %08lx %p %p %u %08lx %08lx\n",
			SectionHandle, ProcessHandle, BaseAddress, ZeroBits, CommitSize,
			SectionOffset, ViewSize, InheritDisposition, AllocationType, Protect );

	r = process_from_handle( ProcessHandle, &p );
	if (r < STATUS_SUCCESS)
		return r;

	section_t *section = 0;
	r = object_from_handle( section, SectionHandle, 0 );
	if (r < STATUS_SUCCESS)
		return r;

	r = copy_from_user( &addr, BaseAddress, sizeof addr );
	if (r < STATUS_SUCCESS)
		return r;

	if (addr)
		trace("requested specific address %p\n", addr);

	r = verify_for_write( ViewSize, sizeof *ViewSize );
	if (r < STATUS_SUCCESS)
		return r;

	r = section->mapit( p->vm, addr, ZeroBits,
						MEM_COMMIT | (AllocationType&MEM_TOP_DOWN), Protect );
	if (r < STATUS_SUCCESS)
		return r;

	r = copy_to_user( BaseAddress, &addr, sizeof addr );

	trace("mapped at %p\n", addr );

	return r;
}
Exemplo n.º 6
0
NTSTATUS NTAPI NtCreateMailslotFile(
	PHANDLE MailslotHandle,
	ACCESS_MASK AccessMask,
	POBJECT_ATTRIBUTES ObjectAttributes,
	PIO_STATUS_BLOCK IoStatusBlock,
	ULONG CreateOptions,
	ULONG InBufferSize,
	ULONG MaxMessageSize,
	PLARGE_INTEGER ReadTimeout)
{
	trace("%p %08lx %p %p %08lx %lu %lu %p\n", MailslotHandle, AccessMask,
			ObjectAttributes, IoStatusBlock, CreateOptions,
			InBufferSize, MaxMessageSize, ReadTimeout);

	NTSTATUS r;

	r = verify_for_write( IoStatusBlock, sizeof *IoStatusBlock );
	if (r < STATUS_SUCCESS)
		return r;

	if (!ObjectAttributes)
		return STATUS_INVALID_PARAMETER;

	object_attributes_t oa;
	r = oa.copy_from_user( ObjectAttributes );
	if (r < STATUS_SUCCESS)
		return r;

	if (!oa.ObjectName)
		return STATUS_OBJECT_PATH_SYNTAX_BAD;

	// FIXME: these checks should be done in the object manager
	UNICODE_STRING &us = *oa.ObjectName;
	if (us.Length<2)
		return STATUS_OBJECT_PATH_SYNTAX_BAD;

	if (us.Length&1)
		return STATUS_OBJECT_NAME_INVALID;

	if (us.Length == 2 && us.Buffer[0] == '\\')
		return STATUS_OBJECT_TYPE_MISMATCH;

	PCWSTR ptr = (PCWSTR) L"\\??\\mailslot\\";
	if (us.Length < 26 || memcmp(ptr, us.Buffer, 26))
		return STATUS_OBJECT_NAME_NOT_FOUND;

	mailslot_factory factory;
	return factory.create( MailslotHandle, AccessMask, ObjectAttributes );
}
Exemplo n.º 7
0
NTSTATUS NTAPI NtQueryValueKey(
	HANDLE KeyHandle,
	PUNICODE_STRING ValueName,
	KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
	PVOID KeyValueInformation,
	ULONG KeyValueInformationLength,
	PULONG ResultLength )
{
	unicode_string_t us;
	NTSTATUS r;
	ULONG len;
	regkey_t *key;
	regval_t *val;

	trace("%p %p %d %p %lu %p\n", KeyHandle, ValueName, KeyValueInformationClass,
			KeyValueInformation, KeyValueInformationLength, ResultLength );

	r = check_key_value_info_class( KeyValueInformationClass );
	if (r < STATUS_SUCCESS)
		return r;

	r = object_from_handle( key, KeyHandle, KEY_QUERY_VALUE );
	if (r < STATUS_SUCCESS)
		return r;

	r = us.copy_from_user( ValueName );
	if (r < STATUS_SUCCESS)
		return r;

	r = verify_for_write( ResultLength, sizeof *ResultLength );
	if (r < STATUS_SUCCESS)
		return r;

	trace("%pus\n", &us );

	val = key_find_value( key, &us );
	if (!val)
		return STATUS_OBJECT_NAME_NOT_FOUND;

	r = reg_query_value( val, KeyValueInformationClass, KeyValueInformation,
						 KeyValueInformationLength, len );

	copy_to_user( ResultLength, &len, sizeof len );

	return r;
}
Exemplo n.º 8
0
NTSTATUS NTAPI NtQueryKey(
	HANDLE KeyHandle,
	KEY_INFORMATION_CLASS KeyInformationClass,
	PVOID KeyInformation,
	ULONG KeyInformationLength,
	PULONG ReturnLength)
{
	if (!key_info_class_valid(KeyInformationClass))
		return STATUS_INVALID_INFO_CLASS;

	NTSTATUS r;
	r = verify_for_write( ReturnLength, sizeof *ReturnLength );
	if (r < STATUS_SUCCESS)
		return r;

	regkey_t *key = 0;
	r = object_from_handle( key, KeyHandle, KEY_QUERY_VALUE );
	if (r < STATUS_SUCCESS)
		return r;

	return key->query( KeyInformationClass, KeyInformation, KeyInformationLength, ReturnLength );
}
Exemplo n.º 9
0
NTSTATUS NTAPI NtEnumerateValueKey(
	HANDLE KeyHandle,
	ULONG Index,
	KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
	PVOID KeyValueInformation,
	ULONG KeyValueInformationLength,
	PULONG ResultLength )
{
	regkey_t *key;
	ULONG len = 0;
	NTSTATUS r = STATUS_SUCCESS;

	trace("%p %lu %u %p %lu %p\n", KeyHandle, Index, KeyValueInformationClass,
			KeyValueInformation, KeyValueInformationLength, ResultLength );

	r = object_from_handle( key, KeyHandle, KEY_QUERY_VALUE );
	if (r < STATUS_SUCCESS)
		return r;

	r = verify_for_write( ResultLength, sizeof *ResultLength );
	if (r < STATUS_SUCCESS)
		return r;

	regval_iter i(key->values);
	for ( ; i && Index; i.next())
		Index--;

	if (!i)
		return STATUS_NO_MORE_ENTRIES;

	r = reg_query_value( i, KeyValueInformationClass, KeyValueInformation,
						 KeyValueInformationLength, len );

	copy_to_user( ResultLength, &len, sizeof len );

	return r;
}
Exemplo n.º 10
0
NTSTATUS nteventfunc( HANDLE Handle, PULONG PreviousState, void (event_t::*fn)(PULONG) )
{
	NTSTATUS r;
	ULONG prev;

	if (PreviousState)
	{
		r = verify_for_write( PreviousState, sizeof PreviousState );
		if (r < STATUS_SUCCESS)
			return r;
	}

	event_t *event = 0;
	r = object_from_handle( event, Handle, EVENT_MODIFY_STATE );
	if (r < STATUS_SUCCESS)
		return r;

	(event->*fn)( &prev );

	if (PreviousState)
		copy_to_user( PreviousState, &prev, sizeof prev );

	return r;
}
Exemplo n.º 11
0
NTSTATUS NTAPI NtQueryInformationThread(
	HANDLE ThreadHandle,
	THREADINFOCLASS ThreadInformationClass,
	PVOID ThreadInformation,
	ULONG ThreadInformationLength,
	PULONG ReturnLength)
{
	union {
		THREAD_BASIC_INFORMATION basic;
		KERNEL_USER_TIMES times;
		ULONG last_thread;
	} info;
	ULONG sz = 0;
	NTSTATUS r;
	thread_impl_t *t;

	dprintf("%p %d %p %lu %p\n", ThreadHandle,
			ThreadInformationClass, ThreadInformation, ThreadInformationLength, ReturnLength);

	switch( ThreadInformationClass )
	{
	case ThreadBasicInformation:
		sz = sizeof info.basic;
		break;
	case ThreadTimes:
		sz = sizeof info.times;
		break;
	case ThreadAmILastThread:
		sz = sizeof info.last_thread;
		break;
	default:
		 dprintf("info class %d\n", ThreadInformationClass);
		 return STATUS_INVALID_INFO_CLASS;
	}

	if (sz != ThreadInformationLength)
		return STATUS_INFO_LENGTH_MISMATCH;

	memset( &info, 0, sizeof info );

	r = object_from_handle( t, ThreadHandle, 0 );
	if (r < STATUS_SUCCESS)
		return r;

	if (ReturnLength)
	{
		r = verify_for_write( ReturnLength, sizeof *ReturnLength );
		if (r < STATUS_SUCCESS)
			return r;
	}

	switch( ThreadInformationClass )
	{
	case ThreadBasicInformation:
		t->query_information( info.basic );
		break;
	case ThreadTimes:
		t->query_information( info.times );
		break;
	case ThreadAmILastThread:
		info.last_thread = t->is_last_thread();
		break;
	default:
		assert(0);
	}

	r = copy_to_user( ThreadInformation, &info, sz );

	if (r == STATUS_SUCCESS && ReturnLength)
		copy_to_user( ReturnLength, &sz, sizeof sz );

	return r;
}
Exemplo n.º 12
0
NTSTATUS NTAPI NtCreateSection(
	PHANDLE SectionHandle,
	ACCESS_MASK DesiredAccess,
	POBJECT_ATTRIBUTES ObjectAttributes,
	PLARGE_INTEGER SectionSize,
	ULONG Protect,
	ULONG Attributes,
	HANDLE FileHandle )
{
	NTSTATUS r;
	object_t *file = NULL;
	LARGE_INTEGER sz;

	trace("%p %08lx %p %p %08lx %08lx %p\n", SectionHandle, DesiredAccess,
			ObjectAttributes, SectionSize, Protect, Attributes, FileHandle );

	// check there's no bad flags
	if (Attributes & ~VALID_SECTION_FLAGS)
		return STATUS_INVALID_PARAMETER_6;

	switch (Attributes & (SEC_IMAGE|SEC_COMMIT|SEC_RESERVE))
	{
	case SEC_IMAGE:
	case SEC_RESERVE:
	case SEC_COMMIT:
		break;
	default:
		return STATUS_INVALID_PARAMETER_6;
	}

	r = verify_for_write( SectionHandle, sizeof *SectionHandle );
	if (r < STATUS_SUCCESS)
		return r;

	// PE sections cannot be written to
	if (Attributes & SEC_IMAGE)
	{
		switch (Protect)
		{
		case PAGE_READONLY:
		case PAGE_EXECUTE:
		case PAGE_EXECUTE_READ:
			break;
		default:
			return STATUS_INVALID_PAGE_PROTECTION;
		}

		if (!FileHandle)
			return STATUS_INVALID_FILE_FOR_SECTION;

		r = object_from_handle( file, FileHandle, 0 );
		if (r < STATUS_SUCCESS)
			return r;

		SectionSize = 0;
	}
	else
	{
		switch (Protect)
		{
		case PAGE_READONLY:
		case PAGE_READWRITE:
		case PAGE_EXECUTE:
		case PAGE_EXECUTE_READ:
		case PAGE_WRITECOPY:
		case PAGE_EXECUTE_READWRITE:
		case PAGE_EXECUTE_WRITECOPY:
			break;
		default:
			return STATUS_INVALID_PAGE_PROTECTION;
		}

		if (FileHandle)
		{
			r = object_from_handle( file, FileHandle, 0 );
			if (r < STATUS_SUCCESS)
				return r;
		}
	}

	if (SectionSize)
	{
		r = copy_from_user( &sz, SectionSize, sizeof sz );
		if (r < STATUS_SUCCESS)
			return r;
		if (sz.QuadPart == 0)
			return STATUS_INVALID_PARAMETER_4;
		SectionSize = &sz;
	}

	section_factory factory( file, SectionSize, Attributes, Protect );
	return factory.create( SectionHandle, DesiredAccess, ObjectAttributes );
}