Example #1
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;
}
Example #2
0
NTSTATUS NTAPI NtSetContextThread(
	HANDLE ThreadHandle,
	PCONTEXT Context)
{
	dprintf("%p %p\n", ThreadHandle, Context );

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

	CONTEXT c;
	r = copy_from_user( &c, Context, sizeof c );
	if (r < STATUS_SUCCESS)
		return r;

	t->set_context( c );
	return STATUS_SUCCESS;
}
Example #3
0
NTSTATUS NTAPI NtQueryEvent(
	HANDLE Handle,
	EVENT_INFORMATION_CLASS EventInformationClass,
	PVOID EventInformation,
	ULONG EventInformationLength,
	PULONG ReturnLength)
{
	event_t *event;
	NTSTATUS r;

	r = object_from_handle( event, Handle, EVENT_QUERY_STATE );
	if (r < STATUS_SUCCESS)
		return r;

	union {
		EVENT_BASIC_INFORMATION basic;
	} info;
	ULONG sz = 0;

	switch (EventInformationClass)
	{
	case EventBasicInformation:
		sz = sizeof info.basic;
		break;
	default:
		return STATUS_INVALID_INFO_CLASS;
	}

	if (sz != EventInformationLength)
		return STATUS_INFO_LENGTH_MISMATCH;

	event->query( info.basic );

	r = copy_to_user( EventInformation, &info, sz );
	if (r < STATUS_SUCCESS)
		return r;

	if (ReturnLength)
		copy_to_user( ReturnLength, &sz, sizeof sz );

	return r;
}
Example #4
0
NTSTATUS NTAPI NtSetValueKey(
	HANDLE KeyHandle,
	PUNICODE_STRING ValueName,
	ULONG TitleIndex,
	ULONG Type,
	PVOID Data,
	ULONG DataSize )
{
	unicode_string_t us;
	regkey_t *key;
	NTSTATUS r;

	trace("%p %p %lu %lu %p %lu\n", KeyHandle, ValueName, TitleIndex, Type, Data, DataSize );

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

	r = us.copy_from_user( ValueName );
	if (r == STATUS_SUCCESS)
	{
		regval_t *val;

		val = new regval_t( &us, Type, DataSize );
		if (val)
		{
			r = copy_from_user( val->data, Data, DataSize );
			if (r == STATUS_SUCCESS)
			{
				delete_value( key, &us );
				key->values.append( val );
			}
			else
				delete val;
		}
		else
			r = STATUS_NO_MEMORY;
	}

	return r;
}
Example #5
0
NTSTATUS NTAPI NtTerminateThread(
	HANDLE ThreadHandle,
	NTSTATUS Status)
{
	thread_t *t;
	NTSTATUS r;

	dprintf("%p %08lx\n", ThreadHandle, Status);

	if (ThreadHandle == 0)
		t = current;
	else
	{
		r = object_from_handle( t, ThreadHandle, 0 );
		if (r < STATUS_SUCCESS)
			return r;
	}

	// If we killed ourselves we'll return the the scheduler but never run again.
	return t->terminate( Status );
}
Example #6
0
NTSTATUS NTAPI NtResumeThread(
	HANDLE ThreadHandle,
	PULONG PreviousSuspendCount )
{
	thread_t *thread;
	ULONG count = 0;
	NTSTATUS r;

	dprintf("%p %p\n", ThreadHandle, PreviousSuspendCount );

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

	r = thread->resume( &count );

	if (r == STATUS_SUCCESS && PreviousSuspendCount)
		r = copy_to_user( PreviousSuspendCount, &count, sizeof count );

	return r;
}
Example #7
0
NTSTATUS NTAPI NtNotifyChangeKey(
	HANDLE KeyHandle,
	HANDLE EventHandle,
	PIO_APC_ROUTINE ApcRoutine,
	PVOID ApcContext,
	PIO_STATUS_BLOCK IoStatusBlock,
	ULONG NotifyFilter,
	BOOLEAN WatchSubtree,
	PVOID Buffer,
	ULONG BufferLength,
	BOOLEAN Asynchronous)
{
	regkey_t *key = 0;
	NTSTATUS r = object_from_handle( key, KeyHandle, 0 );
	if (r < STATUS_SUCCESS)
		return r;

	trace("does nothing...\n");

	return STATUS_SUCCESS;
}
Example #8
0
NTSTATUS NTAPI NtDeleteValueKey(
	HANDLE KeyHandle,
	PUNICODE_STRING ValueName )
{
	unicode_string_t us;
	NTSTATUS r;
	regkey_t *key;

	trace("%p %p\n", KeyHandle, ValueName);

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

	r = object_from_handle( key, KeyHandle, KEY_SET_VALUE );
	if (r < STATUS_SUCCESS)
		return r;
	r = delete_value( key, &us );

	return r;
}
Example #9
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 );
}
Example #10
0
NTSTATUS open_key( regkey_t **out, OBJECT_ATTRIBUTES *oa )
{
	UNICODE_STRING parsed_name;
	regkey_t *key = root_key;
	NTSTATUS r;

	if (oa->RootDirectory)
	{
		r = object_from_handle( key, oa->RootDirectory, 0 );
		if (r < STATUS_SUCCESS)
			return r;
	}
	else
		key = root_key;

	memcpy( &parsed_name, oa->ObjectName, sizeof parsed_name );
	r = open_parse_key( key, &parsed_name, oa->Attributes & OBJ_CASE_INSENSITIVE );

	if (r == STATUS_SUCCESS)
		*out = key;

	return r;
}
Example #11
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;
}
Example #12
0
NTSTATUS open_root( object_t*& obj, open_info_t& info )
{
	// look each directory in the path and make sure it exists
	object_dir_t *dir = 0;

	NTSTATUS r;

	// parse the root directory
	if (info.root)
	{
		// relative path
		if (info.path.Buffer[0] == '\\')
			return STATUS_OBJECT_PATH_SYNTAX_BAD;

		r = object_from_handle( dir, info.root, DIRECTORY_QUERY );
		if (r < STATUS_SUCCESS)
			return r;
	}
	else
	{
		// absolute path
		if (info.path.Buffer[0] != '\\')
			return STATUS_OBJECT_PATH_SYNTAX_BAD;
		dir = root;
		info.path.Buffer++;
		info.path.Length -= 2;
	}

	if (info.path.Length == 0)
	{
		obj = dir;
		return info.on_open( 0, obj, info );
	}

	return dir->open( obj, info );
}
Example #13
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;
}
Example #14
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;
}
Example #15
0
NTSTATUS thread_impl_t::wait_on_handles(
	ULONG count,
	PHANDLE handles,
	WAIT_TYPE type,
	BOOLEAN alert,
	PLARGE_INTEGER timeout)
{
	NTSTATUS r = STATUS_SUCCESS;

	Alertable = alert;
	WaitType = type;

	// iterate the array and wait on each handle
	for (ULONG i=0; i<count; i++)
	{
		dprintf("handle[%ld] = %08lx\n", i, (ULONG) handles[i]);
		object_t *any = 0;
		r = object_from_handle( any, handles[i], SYNCHRONIZE );
		if (r < STATUS_SUCCESS)
		{
			end_wait();
			return r;
		}

		sync_object_t *obj = dynamic_cast<sync_object_t*>( any );
		if (!obj)
		{
			end_wait();
			return STATUS_INVALID_HANDLE;
		}

		r = wait_on( obj );
		if (r < STATUS_SUCCESS)
		{
			end_wait();
			return r;
		}
	}

	// make sure we wait for a little bit every time
	LARGE_INTEGER t;
	if (timeout && timeout->QuadPart <= 0 && timeout->QuadPart> -100000LL)
	{
		t.QuadPart = -100000LL;
		timeout = &t;
	}

	set_timeout( timeout );
	while (1)
	{
		r = check_wait();
		if (r != STATUS_PENDING)
			break;

		if (alerted)
		{
			alerted = FALSE;
			r = STATUS_ALERTED;
			break;
		}

		if (timeout && has_expired())
		{
			r = STATUS_TIMEOUT;
			break;
		}

		in_wait = TRUE;
		wait();
		assert( in_wait == FALSE );
	}

	end_wait();
	set_timeout( 0 );

	return r;
}
Example #16
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 );
}