예제 #1
0
파일: timer.cpp 프로젝트: bragin/ring3k
NTSTATUS NTAPI NtQueryTimer(
	HANDLE TimerHandle,
	TIMER_INFORMATION_CLASS TimerInformationClass,
	PVOID TimerInformation,
	ULONG TimerInformationLength,
	PULONG ResultLength)
{
	NTSTATUS r;

	NTTIMER* timer = 0;
	r = ObjectFromHandle( timer, TimerHandle, TIMER_MODIFY_STATE );
	if (r < STATUS_SUCCESS)
		return r;

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

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

	// this seems like the wrong order, but agrees with what tests show
	r = VerifyForWrite( TimerInformation, sz );
	if (r < STATUS_SUCCESS)
		return r;

	if (sz != TimerInformationLength)
		return STATUS_INFO_LENGTH_MISMATCH;

	switch (TimerInformationClass)
	{
	case TimerBasicInformation:
		info.basic.SignalState = timer->IsSignalled();
		timer->TimeRemaining( info.basic.TimeRemaining );
		break;
	default:
		assert(0);
	}

	r = CopyToUser( TimerInformation, &info, sz );
	if (r < STATUS_SUCCESS)
		return r;

	if (ResultLength)
		CopyToUser( ResultLength, &sz, sizeof sz );

	return r;
}
예제 #2
0
파일: timer.cpp 프로젝트: bragin/ring3k
NTSTATUS NTAPI NtQueryTimerResolution( PULONG CoarsestResolution, PULONG FinestResolution, PULONG ActualResolution)
{
	ULONG resolution = 100000LL; // 10ms
	NTSTATUS r;
	r = CopyToUser( CoarsestResolution, &resolution );
	if (r < STATUS_SUCCESS)
		return r;
	r = CopyToUser( FinestResolution, &resolution );
	if (r < STATUS_SUCCESS)
		return r;
	r = CopyToUser( ActualResolution, &resolution );
	if (r < STATUS_SUCCESS)
		return r;
	return STATUS_SUCCESS;
}
예제 #3
0
파일: timer.cpp 프로젝트: bragin/ring3k
NTSTATUS NtCancelTimer(
	HANDLE TimerHandle,
	PBOOLEAN PreviousState)
{
	NTSTATUS r;

	NTTIMER* timer = 0;
	r = ObjectFromHandle( timer, TimerHandle, TIMER_MODIFY_STATE );
	if (r < STATUS_SUCCESS)
		return r;

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

	BOOLEAN prev = 0;
	timer->Cancel(prev);

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

	return STATUS_SUCCESS;
}
예제 #4
0
파일: token.cpp 프로젝트: bragin/ring3k
static NTSTATUS CopyPtrToUser( USER_COPY& item, PVOID info, ULONG infolen, ULONG& retlen )
{
	// really screwy - have to write back a pointer to the sid, then the sid
	retlen = item.GetLength() + sizeof (PVOID);
	if (retlen > infolen)
		return STATUS_BUFFER_TOO_SMALL;

	// pointer followed by the data blob
	PVOID ptr = (PVOID) ((PVOID*) info + 1);
	NTSTATUS r = CopyToUser( info, &ptr, sizeof ptr );
	if (r < STATUS_SUCCESS)
		return r;
	return item.CopyToUser( ptr );
}
예제 #5
0
파일: token.cpp 프로젝트: bragin/ring3k
//NtPrivilegeCheck(00000154,0006fdc0,0006fe34) ret=77fa7082
NTSTATUS NtPrivilegeCheck(
	HANDLE TokenHandle,
	PPRIVILEGE_SET RequiredPrivileges,
	PBOOLEAN Result)
{
	TOKEN *token = 0;

	NTSTATUS r = ObjectFromHandle( token, TokenHandle, TOKEN_QUERY );
	if (r < STATUS_SUCCESS)
		return r;

	PRIVILEGES_SET ps;
	r = ps.CopyFromUser( RequiredPrivileges );
	if (r < STATUS_SUCCESS)
		return r;

	BOOLEAN ok = TRUE;
	r = CopyToUser( Result, &ok, sizeof ok );

	FIXME("\n");

	return r;
}
예제 #6
0
파일: timer.cpp 프로젝트: bragin/ring3k
NTSTATUS NtSetTimer(
	HANDLE TimerHandle,
	PLARGE_INTEGER DueTime,
	PTIMER_APC_ROUTINE TimerApcRoutine,
	PVOID TimerContext,
	BOOLEAN Resume,
	LONG Period,
	PBOOLEAN PreviousState)
{
	LARGE_INTEGER due;

	NTSTATUS r = CopyFromUser( &due, DueTime, sizeof due );
	if (r < STATUS_SUCCESS)
		return r;

	TRACE("due = %llx\n", due.QuadPart);

	NTTIMER* timer = 0;
	r = ObjectFromHandle( timer, TimerHandle, TIMER_MODIFY_STATE );
	if (r < STATUS_SUCCESS)
		return r;

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

	BOOLEAN prev = FALSE;
	r = timer->Set( due, (PKNORMAL_ROUTINE)TimerApcRoutine, TimerContext, Resume, Period, prev );
	if (r == STATUS_SUCCESS && PreviousState )
		CopyToUser( PreviousState, &prev, sizeof prev );

	return r;
}
예제 #7
0
파일: timer.cpp 프로젝트: bragin/ring3k
NTSTATUS NTAPI NtQuerySystemTime(PLARGE_INTEGER CurrentTime)
{
	LARGE_INTEGER now = TIMEOUT::CurrentTime();

	return CopyToUser( CurrentTime, &now, sizeof now );
}
예제 #8
0
파일: api.c 프로젝트: Cppowboy/mtcp
/*----------------------------------------------------------------------------*/
ssize_t
mtcp_read(mctx_t mctx, int sockid, char *buf, size_t len)
{
	mtcp_manager_t mtcp;
	socket_map_t socket;
	tcp_stream *cur_stream;
	struct tcp_recv_vars *rcvvar;
	int event_remaining;
	int ret;

	mtcp = GetMTCPManager(mctx);
	if (!mtcp) {
		return -1;
	}

	if (sockid < 0 || sockid >= CONFIG.max_concurrency) {
		TRACE_API("Socket id %d out of range.\n", sockid);
		errno = EBADF;
		return -1;
	}

	socket = &mtcp->smap[sockid];
	if (socket->socktype == MTCP_SOCK_UNUSED) {
		TRACE_API("Invalid socket id: %d\n", sockid);
		errno = EBADF;
		return -1;
	}

	if (socket->socktype == MTCP_SOCK_PIPE) {
		return PipeRead(mctx, sockid, buf, len);
	}
	
	if (socket->socktype != MTCP_SOCK_STREAM) {
		TRACE_API("Not an end socket. id: %d\n", sockid);
		errno = ENOTSOCK;
		return -1;
	}

	/* stream should be in ESTABLISHED, FIN_WAIT_1, FIN_WAIT_2, CLOSE_WAIT */
	cur_stream = socket->stream;
	if (!cur_stream || 
			!(cur_stream->state >= TCP_ST_ESTABLISHED && 
			cur_stream->state <= TCP_ST_CLOSE_WAIT)) {
		errno = ENOTCONN;
		return -1;
	}

	rcvvar = cur_stream->rcvvar;

	/* if CLOSE_WAIT, return 0 if there is no payload */
	if (cur_stream->state == TCP_ST_CLOSE_WAIT) {
		if (!rcvvar->rcvbuf)
			return 0;
		
		if (rcvvar->rcvbuf->merged_len == 0)
			return 0;
	}

	/* return EAGAIN if no receive buffer */
	if (socket->opts & MTCP_NONBLOCK) {
		if (!rcvvar->rcvbuf || rcvvar->rcvbuf->merged_len == 0) {
			errno = EAGAIN;
			return -1;
		}
	}

	SBUF_LOCK(&rcvvar->read_lock);
#if BLOCKING_SUPPORT
	if (!(socket->opts & MTCP_NONBLOCK)) {
		while (rcvvar->rcvbuf->merged_len == 0) {
			if (!cur_stream || cur_stream->state != TCP_ST_ESTABLISHED) {
				SBUF_UNLOCK(&rcvvar->read_lock);
				errno = EINTR;
				return -1;
			}
			pthread_cond_wait(&rcvvar->read_cond, &rcvvar->read_lock);
		}
	}
#endif

	ret = CopyToUser(mtcp, cur_stream, buf, len);

	event_remaining = FALSE;
	/* if there are remaining payload, generate EPOLLIN */
	/* (may due to insufficient user buffer) */
	if (socket->epoll & MTCP_EPOLLIN) {
		if (!(socket->epoll & MTCP_EPOLLET) && rcvvar->rcvbuf->merged_len > 0) {
			event_remaining = TRUE;
		}
	}
	/* if waiting for close, notify it if no remaining data */
	if (cur_stream->state == TCP_ST_CLOSE_WAIT && 
			rcvvar->rcvbuf->merged_len == 0 && ret > 0) {
		event_remaining = TRUE;
	}
	
	SBUF_UNLOCK(&rcvvar->read_lock);

	if (event_remaining) {
		if (socket->epoll) {
			AddEpollEvent(mtcp->ep, 
					USR_SHADOW_EVENT_QUEUE, socket, MTCP_EPOLLIN);
#if BLOCKING_SUPPORT
		} else if (!(socket->opts & MTCP_NONBLOCK)) {
			if (!cur_stream->on_rcv_br_list) {
				cur_stream->on_rcv_br_list = TRUE;
				TAILQ_INSERT_TAIL(&mtcp->rcv_br_list, 
						cur_stream, rcvvar->rcv_br_link);
				mtcp->rcv_br_list_cnt++;
			}
#endif
		}
	}

	TRACE_API("Stream %d: mtcp_read() returning %d\n", cur_stream->id, ret);
	return ret;
}
예제 #9
0
파일: token.cpp 프로젝트: bragin/ring3k
NTSTATUS NTAPI NtQueryInformationToken(
	HANDLE TokenHandle,
	TOKEN_INFORMATION_CLASS TokenInformationClass,
	PVOID TokenInformation,
	ULONG TokenInformationLength,
	PULONG ReturnLength )
{
	TOKEN *token;
	ULONG len;
	NTSTATUS r;
	TOKEN_STATISTICS stats;

	TRACE("%p %u %p %lu %p\n", TokenHandle, TokenInformationClass,
		  TokenInformation, TokenInformationLength, ReturnLength );

	r = ObjectFromHandle( token, TokenHandle, TOKEN_QUERY );
	if (r < STATUS_SUCCESS)
		return r;

	switch( TokenInformationClass )
	{
	case TokenOwner:
		TRACE("TokenOwner\n");
		r = CopyPtrToUser( token->GetOwner(), TokenInformation, TokenInformationLength, len );
		break;

	case TokenPrimaryGroup:
		TRACE("TokenPrimaryGroup\n");
		r = CopyPtrToUser( token->GetPrimaryGroup(), TokenInformation, TokenInformationLength, len );
		break;

	case TokenDefaultDacl:
		TRACE("TokenDefaultDacl\n");
		r = CopyPtrToUser( token->GetDefaultDacl(), TokenInformation, TokenInformationLength, len );
		break;

	case TokenUser:
		TRACE("TokenUser\n");
		len = token->GetUser().GetLength();
		if (len > TokenInformationLength)
		{
			r = STATUS_BUFFER_TOO_SMALL;
			break;
		}

		r = token->GetUser().CopyToUser( (SID_AND_ATTRIBUTES*) TokenInformation );
		break;

	case TokenImpersonationLevel:
		FIXME("UNIMPLEMENTED: TokenImpersonationLevel\n");
		return STATUS_INVALID_INFO_CLASS;

	case TokenStatistics:
		TRACE("TokenStatistics\n");
		len = sizeof stats;
		if (len != TokenInformationLength)
			return STATUS_INFO_LENGTH_MISMATCH;

		memset( &stats, 0, sizeof stats );
		r = CopyToUser( TokenInformation, &stats, sizeof stats );
		if (r < STATUS_SUCCESS)
			return r;

		break;

	case TokenGroups:
		TRACE("TokenGroups\n");
		len = token->GetGroups().GetLength();
		if (len > TokenInformationLength)
		{
			r = STATUS_BUFFER_TOO_SMALL;
			break;
		}

		r = token->GetGroups().CopyToUser( (TOKEN_GROUPS*) TokenInformation );
		break;

	case TokenRestrictedSids:
		TRACE("TokenRestrictedSids\n");
		len = token->GetRestrictedSids().GetLength();
		if (len > TokenInformationLength)
		{
			r = STATUS_BUFFER_TOO_SMALL;
			break;
		}

		r = token->GetGroups().CopyToUser((TOKEN_GROUPS*)TokenInformation);
		break;

	default:
		FIXME("UNIMPLEMENTED: info class %d\n", TokenInformationClass);
		return STATUS_INVALID_INFO_CLASS;
	}

	if (ReturnLength)
		CopyToUser( ReturnLength, &len, sizeof len );

	return r;
}
예제 #10
0
파일: token.cpp 프로젝트: bragin/ring3k
NTSTATUS NTAPI NtAdjustPrivilegesToken(
	HANDLE TokenHandle,
	BOOLEAN DisableAllPrivileges,
	PTOKEN_PRIVILEGES NewState,
	ULONG BufferLength,
	PTOKEN_PRIVILEGES PreviousState,
	PULONG ReturnLength )
{
	NTSTATUS r;

	TRACE("%p %u %p %lu %p %p\n", TokenHandle, DisableAllPrivileges,
		  NewState, BufferLength, PreviousState, ReturnLength );

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

	if (!NewState)
		return STATUS_INVALID_PARAMETER;

	// getting the old state requires query rights
	ACCESS_MASK mask = TOKEN_ADJUST_PRIVILEGES;
	if (PreviousState)
		mask |= TOKEN_QUERY;

	TOKEN *token = 0;
	r = ObjectFromHandle( token, TokenHandle, mask );
	if (r < STATUS_SUCCESS)
		return r;

	CTOKEN_PRIVILEGES privs;
	r = privs.CopyFromUser( NewState );
	if (r < STATUS_SUCCESS)
		return r;

	// return previous state information if required
	if (PreviousState)
	{
		CTOKEN_PRIVILEGES& prev_state = token->GetPrivs();

		ULONG len = prev_state.GetLength();
		TRACE("old privs %ld bytes\n", len);
		prev_state.Dump();
		if (len > BufferLength)
			return STATUS_BUFFER_TOO_SMALL;

		r = prev_state.CopyToUser( PreviousState );
		if (r < STATUS_SUCCESS)
			return r;

		r = CopyToUser( ReturnLength, &len, sizeof len );
		assert( r == STATUS_SUCCESS );
	}

	r = token->Adjust( privs );

	TRACE("new privs\n");
	privs.Dump();

	return r;
}
예제 #11
0
static bool CopyFdsToUser(struct pollfd* user_fds,
                          const struct pollfd* kernel_fds, size_t nfds)
{
	size_t size = sizeof(struct pollfd) * nfds;
	return CopyToUser(user_fds, kernel_fds, size);
}
예제 #12
0
/* this doesn't set STATUS_MORE_DATA */
NTSTATUS IREGKEY::RegQueryValue(
	IREGVAL* val,
	ULONG KeyValueInformationClass,
	PVOID KeyValueInformation,
	ULONG KeyValueInformationLength,
	ULONG& len )
{
	NTSTATUS r = STATUS_SUCCESS;
	union
	{
		KEY_VALUE_FULL_INFORMATION full;
		KEY_VALUE_PARTIAL_INFORMATION partial;
	} info;
	ULONG info_sz;

	len = 0;

	TRACE("%pus\n", &val->Name());

	memset( &info, 0, sizeof info );

	switch( KeyValueInformationClass )
	{
	case KeyValueFullInformation:
		info_sz = FIELD_OFFSET( KEY_VALUE_FULL_INFORMATION, Name );
		// include nul terminator at the end of the Name
		info.full.DataOffset = info_sz + val->Name().Length + 2;
		len = info.full.DataOffset + val->Size();
		if (KeyValueInformationLength < info_sz)
			return STATUS_BUFFER_TOO_SMALL;

		info.full.Type = val->Type();
		info.full.DataLength = val->Size();
		info.full.NameLength = val->Name().Length;

		r = CopyToUser( KeyValueInformation, &info.full, info_sz );
		if (r < STATUS_SUCCESS)
			break;

		if (len > KeyValueInformationLength)
			return STATUS_BUFFER_OVERFLOW;

		r = CopyToUser( (BYTE*)KeyValueInformation + info_sz,
						  val->Name().Buffer, val->Name().Length );
		if (r < STATUS_SUCCESS)
			break;

		r = CopyToUser( (BYTE*)KeyValueInformation + info.full.DataOffset,
						  val->Data(), val->Size() );
		break;

	case KeyValuePartialInformation:
		info_sz = FIELD_OFFSET( KEY_VALUE_PARTIAL_INFORMATION, Data );
		TRACE("info_sz %d val->Size() %d\n", info_sz, val->Size());
		len = info_sz + val->Size();
		if (KeyValueInformationLength < info_sz)
			return STATUS_BUFFER_TOO_SMALL;

		info.partial.Type = val->Type();
		info.partial.DataLength = val->Size();

		r = CopyToUser( KeyValueInformation, &info.partial, info_sz );
		if (r < STATUS_SUCCESS)
			break;

		if (len > KeyValueInformationLength)
			return STATUS_BUFFER_OVERFLOW;

		r = CopyToUser( (BYTE*)KeyValueInformation + info_sz, val->Data(), val->Size() );
		break;

	case KeyValueBasicInformation:
	case KeyValueFullInformationAlign64:
	case KeyValuePartialInformationAlign64:
	default:
		FIXME("RegQueryValue: UNIMPLEMENTED case %ld\n", KeyValueInformationClass);
		r = STATUS_NOT_IMPLEMENTED;
	}

	return r;

}
예제 #13
0
NTSTATUS IREGKEY::Query(
	KEY_INFORMATION_CLASS KeyInformationClass,
	PVOID KeyInformation,
	ULONG KeyInformationLength,
	PULONG ReturnLength)
{
	union
	{
		KEY_BASIC_INFORMATION basic;
		KEY_FULL_INFORMATION full;
	} info;
	NTSTATUS r;

	memset( &info, 0, sizeof info );
	ULONG sz = 0;
	UNICODE_STRING keycls, keyname;
	keyname.Length = 0;
	keyname.Buffer = 0;
	keycls.Length = 0;
	keycls.Buffer = 0;

	switch (KeyInformationClass)
	{
	case KeyBasicInformation:
		Query( info.basic, keyname );
		sz = sizeof info.basic + keyname.Length;
		if (sz > KeyInformationLength)
			return STATUS_INFO_LENGTH_MISMATCH;

		r = CopyToUser( KeyInformation, &info, sz );
		if (r < STATUS_SUCCESS)
			break;

		r = CopyToUser( (BYTE*)KeyInformation + FIELD_OFFSET( KEY_BASIC_INFORMATION, Name ), keyname.Buffer, keyname.Length );

		break;

	case KeyFullInformation:
		Query( info.full, keycls );
		sz = sizeof info.full + keycls.Length;
		if (sz > KeyInformationLength)
			return STATUS_INFO_LENGTH_MISMATCH;

		r = CopyToUser( KeyInformation, &info, sz );
		if (r < STATUS_SUCCESS)
			break;

		TRACE("keycls = %pus\n", &keycls);
		r = CopyToUser( (BYTE*)KeyInformation + FIELD_OFFSET( KEY_FULL_INFORMATION, Class ), keycls.Buffer, keycls.Length );

		break;

	case KeyNodeInformation:
		FIXME("KeyNodeInformation\n");
	default:
		assert(0);
	}

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

	return r;
}
예제 #14
0
// blocking
NTSTATUS NTAPI NtRemoveIoCompletion(
	HANDLE IoCompletionHandle,
	PULONG IoCompletionKey,
	PULONG IoCompletionValue,
	PIO_STATUS_BLOCK IoStatusBlock,
	PLARGE_INTEGER TimeOut)
{
	NTSTATUS r;

	TRACE("%p %p %p %p %p\n", IoCompletionHandle, IoCompletionKey,
		  IoCompletionValue, IoStatusBlock, TimeOut);

	COMPLETION_PORT_IMPL *port = 0;
	r = ObjectFromHandle( port, IoCompletionHandle, IO_COMPLETION_MODIFY_STATE );
	if (r < STATUS_SUCCESS)
		return r;

	if (IoCompletionKey)
	{
		r = VerifyForWrite( IoCompletionKey, sizeof *IoCompletionKey );
		if (r < STATUS_SUCCESS)
			return r;
	}

	if (IoCompletionValue)
	{
		r = VerifyForWrite( IoCompletionValue, sizeof *IoCompletionValue );
		if (r < STATUS_SUCCESS)
			return r;
	}

	if (IoStatusBlock)
	{
		r = VerifyForWrite( IoStatusBlock, sizeof *IoStatusBlock );
		if (r < STATUS_SUCCESS)
			return r;
	}

	LARGE_INTEGER t;
	t.QuadPart = 0LL;
	if (TimeOut)
	{
		r = CopyFromUser( &t, TimeOut, sizeof t );
		if (r < STATUS_SUCCESS)
			return r;
		TimeOut = &t;
	}

	ULONG key = 0, val = 0;
	IO_STATUS_BLOCK iosb;
	iosb.Status = 0;
	iosb.Information = 0;
	port->Remove( key, val, iosb.Status, iosb.Information, TimeOut );

	if (IoCompletionKey)
		CopyToUser( IoCompletionKey, &key, sizeof key );

	if (IoCompletionValue)
		CopyToUser( IoCompletionValue, &val, sizeof val );

	if (IoStatusBlock)
		CopyToUser( IoStatusBlock, &iosb, sizeof iosb );

	return r;
}