Example #1
0
EVQ_API int
evq_wait (struct event_queue *evq, msec_t timeout)
{
    struct event *ev_ready = NULL;
    struct win32thr *wth = &evq->head;
    struct win32thr *threads = wth->next;
    CRITICAL_SECTION *head_cs = &wth->cs;
    HANDLE head_signal = wth->signal;
    int n = wth->n;
    int sig_ready = 0;
    DWORD wait_res;

    if (threads && win32thr_poll(evq) && evq_is_empty(evq))
	return 0;

    if (timeout != 0L) {
	timeout = timeout_get(wth->tq, timeout, evq->now);
	if (timeout == 0L) {
	    ev_ready = timeout_process(wth->tq, NULL, evq->now);
	    goto end;
	}
    }

    if (is_WinNT) {
	if (!iocp_is_empty(evq))
	    ev_ready = win32iocp_process(evq, NULL, 0L);

	if (ev_ready) {
	    evq->ev_ready = ev_ready;
	    timeout = 0L;
	} else {
	    /* head_signal is resetted by IOCP WSARecv/WSASend */
	    EnterCriticalSection(head_cs);
	    if (evq->sig_ready)
		timeout = 0L;
	    LeaveCriticalSection(head_cs);
	}
    }

    sys_vm_leave();
    wait_res = MsgWaitForMultipleObjects(n + 1, wth->handles, FALSE, timeout,
     (evq->win_msg ? QS_ALLEVENTS : 0));
    sys_vm_enter();

    evq->now = sys_milliseconds();

    ev_ready = evq->ev_ready;

    if (wait_res == WAIT_TIMEOUT) {
	if (ev_ready) goto end;
	if (!wth->tq && !evq->sig_ready)
	    return EVQ_TIMEOUT;
    }
    if (wait_res == (DWORD) (WAIT_OBJECT_0 + n + 1)) {
	struct event *ev = evq->win_msg;
	if (ev && !(ev->flags & EVENT_ACTIVE)) {
	    ev->flags |= EVENT_ACTIVE;
	    ev->next_ready = ev_ready;
	    ev_ready = ev;
	}
	goto end;
    }
    if (wait_res == WAIT_FAILED)
	return EVQ_FAILED;

    timeout = evq->now;
    if (!iocp_is_empty(evq))
	ev_ready = win32iocp_process(evq, ev_ready, timeout);

    wth->idx = wait_res;

    if (threads) {
	EnterCriticalSection(head_cs);
	ResetEvent(head_signal);

	threads = evq->wth_ready;
	evq->wth_ready = NULL;

	sig_ready = evq->sig_ready;
	evq->sig_ready = 0;
	LeaveCriticalSection(head_cs);

	if (wait_res == (DWORD) (WAIT_OBJECT_0 + n))
	    wth = threads;
	else
	    wth->next_ready = threads;
    } else {
	wth->next_ready = NULL;

	if (evq->sig_ready) {
	    EnterCriticalSection(head_cs);
	    ResetEvent(head_signal);

	    sig_ready = evq->sig_ready;
	    evq->sig_ready = 0;
	    LeaveCriticalSection(head_cs);
	}
    }

    if (sig_ready)
	ev_ready = signal_process_interrupt(evq, sig_ready, ev_ready, timeout);

    for (; wth; wth = wth->next_ready) {
	HANDLE *hp;  /* event handles */
	const int idx = wth->idx;
	int i;

	wth->state = WTHR_SLEEP;

	if (wth->tq) {
	    if (idx == WAIT_TIMEOUT) {
		ev_ready = timeout_process(wth->tq, ev_ready, timeout);
		continue;
	    }
	}

	hp = &wth->handles[idx];
	n = wth->n;
	i = idx;
	if (i >= n) continue;  /* some events deleted? */

	/* Traverse array of events */
	for (; ; ) {
	    WSANETWORKEVENTS ne;
	    struct event *ev = wth->events[i];
	    const int ev_flags = ev->flags;
	    unsigned int res = 0;

	    if (!(ev_flags & EVENT_SOCKET)) {
		if (ev_flags & EVENT_PID) {
		    DWORD status;
		    GetExitCodeProcess(ev->fd, &status);
		    res = (status << EVENT_EOF_SHIFT_RES);
		} else
		    ResetEvent(ev->fd);  /* all events must be manual-reset */
		res |= EVENT_READ_RES;
	    } else if (!WSAEnumNetworkEvents((int) ev->fd, *hp, &ne)) {
		if ((ev_flags & EVENT_READ)
		 && (ne.lNetworkEvents & WFD_READ))
		    res = EVENT_READ_RES;
		if ((ev_flags & EVENT_WRITE)
		 && (ne.lNetworkEvents & WFD_WRITE))
		    res |= EVENT_WRITE_RES;
		if (ne.lNetworkEvents & FD_CLOSE)
		    res |= EVENT_EOF_RES;
	    }

	    if (res) {
		ev->flags |= EVENT_ACTIVE | res;
		ev->next_ready = ev_ready;
		ev_ready = ev;

		if (ev_flags & EVENT_ONESHOT) {
		    win32thr_del(wth, ev);
		    --i, --n, --hp;
		} else if (ev->tq && !(ev_flags & EVENT_TIMEOUT_MANUAL))
		    timeout_reset(ev, timeout);
	    }

	    /* skip inactive events */
	    do {
		if (++i == n)
		    goto end_thread;
	    } while (WaitForSingleObject(*(++hp), 0) != WAIT_OBJECT_0);
	}
 end_thread:
	((void) 0);  /* avoid warning */
    }

    /* always check window messages */
    {
	struct event *ev = evq->win_msg;

	if (ev && GetQueueStatus(QS_ALLEVENTS)) {
	    ev->next_ready = ev_ready;
	    ev_ready = ev;
	}
    }
    if (!ev_ready)
	return (wait_res == WAIT_TIMEOUT && !sig_ready)
	 ? EVQ_TIMEOUT : 0;
 end:
    evq->ev_ready = ev_ready;
    return 0;
}
Example #2
0
void fastPoll( void )
	{
	static BOOLEAN addedFixedItems = FALSE, hasHardwareRNG = FALSE;
	static CEGENRANDOM pCeGenRandom = NULL;
	static GETSYSTEMPOWERSTATUS pGetSystemPowerStatusEx2 = NULL;
	FILETIME  creationTime, exitTime, kernelTime, userTime;
	LARGE_INTEGER performanceCount;
	SYSTEM_POWER_STATUS_EX2 powerStatus;
	MEMORYSTATUS memoryStatus;
	HANDLE handle;
	POINT point;
	RANDOM_STATE randomState;
	BYTE buffer[ RANDOM_BUFSIZE ];
	int length;

	if( krnlIsExiting() )
		return;

	/* Initialize the native function pointers if necessary.  CeGetRandom()
	   is only available in relatively new versions of WinCE, so we have to
	   link it dynamically */
	if( pCeGenRandom == NULL )
		{
		HANDLE hCoreDLL;

		if( ( hCoreDLL = GetModuleHandle( TEXT( "Coredll.dll" ) ) ) != NULL )
			pCeGenRandom = ( CEGENRANDOM ) GetProcAddress( hCoreDLL, TEXT( "CeGenRandom" ) );
		}
	if( pGetSystemPowerStatusEx2 == NULL )
		{
		HANDLE hGetpower;

		if( ( hGetpower = GetModuleHandle( TEXT( "Getpower.dll" ) ) ) != NULL )
			pGetSystemPowerStatusEx2 = ( GETSYSTEMPOWERSTATUS ) \
							GetProcAddress( hGetpower, TEXT( "GetSystemPowerStatusEx2" ) );
		}

	initRandomData( randomState, buffer, RANDOM_BUFSIZE );

	/* Get various basic pieces of system information: Handle of active
	   window, handle of window with mouse capture, handle of clipboard owner
	   handle of start of clpboard viewer list, pseudohandle of current
	   process, current process ID, pseudohandle of current thread, current
	   thread ID, handle of desktop window, handle  of window with keyboard
	   focus, whether system queue has any events, cursor position for last
	   message, 1 ms time for last message, handle of window with clipboard
	   open, handle of process heap, handle of procs window station, types of
	   events in input queue, and milliseconds since Windows was started */
	addRandomValue( randomState, GetActiveWindow() );
	addRandomValue( randomState, GetCapture() );
	addRandomValue( randomState, GetCaretBlinkTime() );
	addRandomValue( randomState, GetClipboardOwner() );
	addRandomValue( randomState, GetCurrentProcess() );
	addRandomValue( randomState, GetCurrentProcessId() );
	addRandomValue( randomState, GetCurrentThread() );
	addRandomValue( randomState, GetCurrentThreadId() );
	addRandomValue( randomState, GetDesktopWindow() );
	addRandomValue( randomState, GetDC( NULL ) );
	addRandomValue( randomState, GetDoubleClickTime() );
	addRandomValue( randomState, GetFocus() );
	addRandomValue( randomState, GetForegroundWindow() );
	addRandomValue( randomState, GetMessagePos() );
	addRandomValue( randomState, GetOpenClipboardWindow() );
	addRandomValue( randomState, GetProcessHeap() );
	addRandomValue( randomState, GetQueueStatus( QS_ALLINPUT ) );
	addRandomValue( randomState, GetTickCount() );
	if( krnlIsExiting() )
		return;

	/* Get multiword system information: Current caret position, current
	   mouse cursor position */
	GetCaretPos( &point );
	addRandomData( randomState, &point, sizeof( POINT ) );
	GetCursorPos( &point );
	addRandomData( randomState, &point, sizeof( POINT ) );

	/* Get percent of memory in use, bytes of physical memory, bytes of free
	   physical memory, bytes in paging file, free bytes in paging file, user
	   bytes of address space, and free user bytes */
	memoryStatus.dwLength = sizeof( MEMORYSTATUS );
	GlobalMemoryStatus( &memoryStatus );
	addRandomData( randomState, &memoryStatus, sizeof( MEMORYSTATUS ) );

	/* Get thread and process creation time, exit time, time in kernel mode,
	   and time in user mode in 100ns intervals */
	handle = GetCurrentThread();
	GetThreadTimes( handle, &creationTime, &exitTime, &kernelTime, &userTime );
	addRandomData( randomState, &creationTime, sizeof( FILETIME ) );
	addRandomData( randomState, &exitTime, sizeof( FILETIME ) );
	addRandomData( randomState, &kernelTime, sizeof( FILETIME ) );
	addRandomData( randomState, &userTime, sizeof( FILETIME ) );

	/* Get extended battery/power status information.  We set the fUpdate
	   flag to force a re-read of fresh data rather than a re-use of cached
	   information */
	if( pGetSystemPowerStatusEx2 != NULL && \
		( length = \
				pGetSystemPowerStatusEx2( &powerStatus,
										  sizeof( SYSTEM_POWER_STATUS_EX2 ),
										  TRUE ) ) > 0 )
		addRandomData( randomState, &powerStatus, length );

	/* Get random data provided by the OS.  Since this is expected to be
	   provided by the system vendor, it's quite likely to be the usual
	   process ID + time */
	if( pCeGenRandom != NULL )
		{
		BYTE randomBuffer[ 32 ];

		if( pCeGenRandom( 32, randomBuffer ) )
			addRandomData( randomState, randomBuffer, 32 );
		}

	/* The following are fixed for the lifetime of the process so we only
	   add them once */
	if( !addedFixedItems )
		{
		SYSTEM_INFO systemInfo;

		GetSystemInfo( &systemInfo );
		addRandomData( randomState, &systemInfo, sizeof( SYSTEM_INFO ) );
		addedFixedItems = TRUE;
		}

	/* The performance of QPC varies depending on the architecture it's
	   running on, and is completely platform-dependant.  If there's no
	   hardware performance counter available, it uses the 1ms system timer,
	   although usually there's some form of hardware timer available.
	   Since there may be no correlation, or only a weak correlation,
	   between the performance counter and the system clock, we get the
	   time from both sources */
	if( QueryPerformanceCounter( &performanceCount ) )
		addRandomData( randomState, &performanceCount,
					   sizeof( LARGE_INTEGER ) );
	addRandomValue( randomState, GetTickCount() );

	/* Flush any remaining data through.  Quality = int( 33 1/3 % ) */
	endRandomData( randomState, 34 );
	}
Example #3
0
int
_gcry_rndw32_gather_random_fast (void (*add)(const void*, size_t, int),
                                 int requester )
{
    static int addedFixedItems = 0;

    if ( debug_me )
	log_debug ("rndw32#gather_random_fast: req=%d\n", requester );

    /* Get various basic pieces of system information: Handle of active
     * window, handle of window with mouse capture, handle of clipboard owner
     * handle of start of clpboard viewer list, pseudohandle of current
     * process, current process ID, pseudohandle of current thread, current
     * thread ID, handle of desktop window, handle  of window with keyboard
     * focus, whether system queue has any events, cursor position for last
     * message, 1 ms time for last message, handle of window with clipboard
     * open, handle of process heap, handle of procs window station, types of
     * events in input queue, and milliseconds since Windows was started */
    {	byte buffer[20*sizeof(ulong)], *bufptr;
	bufptr = buffer;
#define ADD(f)  do { ulong along = (ulong)(f);		      \
			   memcpy (bufptr, &along, sizeof (along) );  \
			   bufptr += sizeof (along); } while (0)
	ADD ( GetActiveWindow ());
	ADD ( GetCapture ());
	ADD ( GetClipboardOwner ());
	ADD ( GetClipboardViewer ());
	ADD ( GetCurrentProcess ());
	ADD ( GetCurrentProcessId ());
	ADD ( GetCurrentThread ());
	ADD ( GetCurrentThreadId ());
	ADD ( GetDesktopWindow ());
	ADD ( GetFocus ());
	ADD ( GetInputState ());
	ADD ( GetMessagePos ());
	ADD ( GetMessageTime ());
	ADD ( GetOpenClipboardWindow ());
	ADD ( GetProcessHeap ());
	ADD ( GetProcessWindowStation ());
	ADD ( GetQueueStatus (QS_ALLEVENTS));
	ADD ( GetTickCount ());

	assert ( bufptr-buffer < sizeof (buffer) );
	(*add) ( buffer, bufptr-buffer, requester );
#undef ADD
    }

    /* Get multiword system information: Current caret position, current
     * mouse cursor position */
    {	POINT point;
	GetCaretPos (&point);
	(*add) ( &point, sizeof (point), requester );
	GetCursorPos (&point);
	(*add) ( &point, sizeof (point), requester );
    }

    /* Get percent of memory in use, bytes of physical memory, bytes of free
     * physical memory, bytes in paging file, free bytes in paging file, user
     * bytes of address space, and free user bytes */
    {	MEMORYSTATUS memoryStatus;
	memoryStatus.dwLength = sizeof (MEMORYSTATUS);
	GlobalMemoryStatus (&memoryStatus);
	(*add) ( &memoryStatus, sizeof (memoryStatus), requester );
    }

    /* Get thread and process creation time, exit time, time in kernel mode,
       and time in user mode in 100ns intervals */
    {	HANDLE handle;
	FILETIME creationTime, exitTime, kernelTime, userTime;
	DWORD minimumWorkingSetSize, maximumWorkingSetSize;

	handle = GetCurrentThread ();
	GetThreadTimes (handle, &creationTime, &exitTime,
					       &kernelTime, &userTime);
	(*add) ( &creationTime, sizeof (creationTime), requester );
	(*add) ( &exitTime, sizeof (exitTime), requester );
	(*add) ( &kernelTime, sizeof (kernelTime), requester );
	(*add) ( &userTime, sizeof (userTime), requester );

	handle = GetCurrentProcess ();
	GetProcessTimes (handle, &creationTime, &exitTime,
						&kernelTime, &userTime);
	(*add) ( &creationTime, sizeof (creationTime), requester );
	(*add) ( &exitTime, sizeof (exitTime), requester );
	(*add) ( &kernelTime, sizeof (kernelTime), requester );
	(*add) ( &userTime, sizeof (userTime), requester );

	/* Get the minimum and maximum working set size for the
           current process */
	GetProcessWorkingSetSize (handle, &minimumWorkingSetSize,
					  &maximumWorkingSetSize);
	(*add) ( &minimumWorkingSetSize,
				   sizeof (minimumWorkingSetSize), requester );
	(*add) ( &maximumWorkingSetSize,
				   sizeof (maximumWorkingSetSize), requester );
    }


    /* The following are fixed for the lifetime of the process so we only
     * add them once */
    if (!addedFixedItems) {
	STARTUPINFO startupInfo;

	/* Get name of desktop, console window title, new window position and
	 * size, window flags, and handles for stdin, stdout, and stderr */
	startupInfo.cb = sizeof (STARTUPINFO);
	GetStartupInfo (&startupInfo);
	(*add) ( &startupInfo, sizeof (STARTUPINFO), requester );
	addedFixedItems = 1;
    }

    /* The performance of QPC varies depending on the architecture it's
     * running on and on the OS.  Under NT it reads the CPU's 64-bit timestamp
     * counter (at least on a Pentium and newer '486's, it hasn't been tested
     * on anything without a TSC), under Win95 it reads the 1.193180 MHz PIC
     * timer.  There are vague mumblings in the docs that it may fail if the
     * appropriate hardware isn't available (possibly '386's or MIPS machines
     * running NT), but who's going to run NT on a '386? */
    {	LARGE_INTEGER performanceCount;
	if (QueryPerformanceCounter (&performanceCount)) {
	    if ( debug_me )
		log_debug ("rndw32#gather_random_fast: perf data\n");
	    (*add) (&performanceCount, sizeof (performanceCount), requester);
	}
	else { /* Millisecond accuracy at best... */
	    DWORD aword = GetTickCount ();
	    (*add) (&aword, sizeof (aword), requester );
	}
    }

    return 0;
}
Example #4
0
/////////////////////////////////////////////////////////////////////////
// The thread process the user's conversation: Get user's request command, send it
// to scheduler, Get the response code and return it to user.
// The parameter "lpvParam" if the NamedPipe instance handle value.
DWORD WINAPI TcpipClientAgentThread( LPVOID lpvParam )
{
	LPTS_COM_PROPS lptsComProps;
	REQUEST 	Request;
	CHAR 		szBuffer[PIPE_BUFFER_SIZE];
	DWORD 		cbWriten, cbReaded;
	DWORD 		dwRetCode;
	int 		iRet;
	BOOL 		fDirect = TRUE;
	MSG 		Msg;
	SOCKET 		iSocket;

	iSocket = (SOCKET)lpvParam;

	// If the parameter lpvParam is an invalid pipe handle.
	//if( iSocket == SOCKET_ERROR )
	//	ExitThread( ERROR_INVALID_PARAMETER );

	GetQueueStatus( QS_SENDMESSAGE );

	lprintfs( "Client agent thread starts.\n" );

	_try {
	// Wait and read the message send by the client, until the client post.

	cbReaded = recvPacket(iSocket, szBuffer, PIPE_BUFFER_SIZE);
	//if( cbReaded == SOCKET_ERROR ) {
	if( cbReaded <= 0 ) {
		ExitThread( GetLastError() );
	}

	// Get the packet header, analyse the packet information.
	lptsComProps = (LPTS_COM_PROPS)szBuffer;

	// If the user's first packet is not logon information packet,
	// Reject the user's request.
	if( lptsComProps->packetType != pkTS_SYNC_PIPE ||
						lptsComProps->msgType != msgTS_CLIENT_LOGON ) {
		ZeroMemory( szBuffer, PIPE_BUFFER_SIZE );
		lptsComProps->packetType = pkTS_ERROR;
		lptsComProps->msgType = msgTS_ERROR_MSG;

		lptsComProps->len = wsprintfA( (LPSTR)(szBuffer+sizeof( TS_COM_PROPS )),
				"User can not access the server before logon." );

		iRet = sendPacket(iSocket, szBuffer,
							 lptsComProps->len+sizeof( TS_COM_PROPS ) );
		//if( iRet == SOCKET_ERROR ) {
		if( iRet <= 0 ) {
			ExitThread( GetLastError() );
		}

		ExitThread( TERR_NOT_LOGON );
	}

#ifndef TREESVR_STANDALONE
	// Add by Jingyu Niu, 2000.08.25, for support single user mode.
	if( singleUserMode ) {
		ZeroMemory( szBuffer, PIPE_BUFFER_SIZE );
		lptsComProps->packetType = pkTS_SYNC_PIPE;
		lptsComProps->msgType = msgTS_LOGON_ERROR;
		lptsComProps->lp = 0x10000;
		
		lptsComProps->len = wsprintfA( (LPSTR)(szBuffer+sizeof( TS_COM_PROPS )),
			"Server now running in single user mode, not accept connect request." );

		cbWriten = sendPacket( iSocket, szBuffer,
							 lptsComProps->len+sizeof(TS_COM_PROPS) );
		//if( cbWriten == SOCKET_ERROR ) {
		if( cbWriten <= 0 ) {
			ExitThread( GetLastError() );
		}

		ExitThread( 0x10000 );
	}
#endif
	
	// If the user's logon information packet is invalid,
	// Reject the user's request.
	dwRetCode = MsgToRequest( (LPCSTR)(szBuffer+sizeof( TS_COM_PROPS )), &Request );
	if( dwRetCode != TERR_SUCCESS ) {
		ZeroMemory( szBuffer, PIPE_BUFFER_SIZE );
		lptsComProps->packetType = pkTS_SYNC_PIPE;
		lptsComProps->msgType = msgTS_LOGON_ERROR;
		lptsComProps->lp = dwRetCode;
		
		lptsComProps->len = wsprintfA( (LPSTR)(szBuffer+sizeof( TS_COM_PROPS )),
			"Logon information error(error code:%ld).", dwRetCode );

		cbWriten = sendPacket( iSocket, szBuffer,
							 lptsComProps->len+sizeof(TS_COM_PROPS) );
		//if( cbWriten == SOCKET_ERROR ) {
		if( cbWriten <= 0 ) {
			ExitThread( GetLastError() );
		}

		ExitThread( dwRetCode );
	}
	
	// Send the request to scheduler.
	dwRetCode = SendRequest( &Request );
	if( dwRetCode != TERR_SUCCESS ) {
		ZeroMemory( szBuffer, PIPE_BUFFER_SIZE );
		lptsComProps->packetType = pkTS_ERROR;
		lptsComProps->msgType = msgTS_LOGON_ERROR;
		lptsComProps->lp = dwRetCode;
		
		lptsComProps->len = wsprintfA( (LPSTR)(szBuffer+sizeof( TS_COM_PROPS )),
			"Can not logon the server(error code:%ld).", dwRetCode );

		cbWriten = sendPacket( iSocket, szBuffer,
							 lptsComProps->len+sizeof(TS_COM_PROPS) );
		//if( cbWriten == SOCKET_ERROR ) {
		if( cbWriten <= 0 ) {
			ExitThread( GetLastError() );
		}

		ExitThread( dwRetCode );
	}


	ZeroMemory( szBuffer, PIPE_BUFFER_SIZE );
	lptsComProps->packetType = pkTS_SYNC_PIPE;

	if( Request.dwRequest == TERR_SUCCESS ) {
		lptsComProps->msgType = msgTS_LOGON_OK;
		lptsComProps->lp = Request.dwRequestId;
	}
	else {
		lptsComProps->msgType = msgTS_LOGON_ERROR;
		lptsComProps->lp = Request.dwRequest;
	}

	cbWriten = sendPacket( iSocket, szBuffer, sizeof(TS_COM_PROPS) );
	//if( cbWriten == SOCKET_ERROR ) {
	if( cbWriten <= 0 ) {
		ExitThread( GetLastError() );
	}

	if( Request.dwRequest != TERR_SUCCESS ) {
		ExitThread( TERR_SUCCESS );
	}

	// Add by NiuJingyu, 1998.03
	GetMessage( &Msg, NULL, TS_SERVICE_START, TS_SERVICE_START );

	dwRetCode = TERR_SUCCESS;

	while( 1 ) {
		if( fDirect ) {
			cbReaded = recvPacket(iSocket, szBuffer, PIPE_BUFFER_SIZE);
			//if( cbReaded == SOCKET_ERROR ) {
			if( cbReaded <= 0 ) {
				dwRetCode = GetLastError();
				CliSetExchBufError( Request.lpExchangeBuf );
				dwRetCode = TERR_CLIENT_CLOSE;
				break;
			}

			lptsComProps = (LPTS_COM_PROPS)szBuffer;
			if( lptsComProps->endPacket == '\x0' )
				fDirect = FALSE;

			if( lptsComProps->packetType == pkTS_SYNC_PIPE ) {
				if( lptsComProps->msgType == msgTS_PIPE_CLOSE ) {
					dwRetCode = TERR_SUCCESS;
					break;
				}
			} 

#ifndef TREESVR_STANDALONE
			// Add by Jingyu Niu, 2000.08.25, for support single user mode.
			if( singleUserMode && singleUserThread != GetCurrentThreadId() ) {
				if( fDirect )
					continue;
				else {
					dwRetCode = TERR_SUCCESS;
					break;
				}
			}

#endif
			
//			lprintfs( "########################## Client write exchange buffer.\n" );
			dwRetCode = CliWriteExchngBuf( Request.lpExchangeBuf, szBuffer, 4096 );
			if( dwRetCode != TERR_SUCCESS ) {
				break;
			}
		}
		else {
			// Service thread is voluntary.
			// Read the packet from service thread.
			dwRetCode = CliReadExchngBuf( Request.lpExchangeBuf, szBuffer, 4096 );
			if( dwRetCode != TERR_SUCCESS )
				break;

			lptsComProps = (LPTS_COM_PROPS)szBuffer;
			if( lptsComProps->endPacket == '\x0' )
				fDirect = TRUE;
	
			if( lptsComProps->packetType == pkTS_SYNC_PIPE ) {
				if( lptsComProps->msgType == msgTS_NO_DATA )
					continue;
			}

#ifndef TREESVR_STANDALONE
			// Add by Jingyu Niu, 2000.08.25, for support single user mode.
			if( singleUserMode && singleUserThread != GetCurrentThreadId() && fDirect ) {
				lptsComProps->packetType = pkTS_SYNC_PIPE;
				lptsComProps->msgType = msgTS_PIPE_CLOSE;
				lptsComProps->lp = 0;
				lptsComProps->len = 0;
				lptsComProps->leftPacket = '\x0';
				lptsComProps->endPacket = '\x0';

				dwRetCode = CliWriteExchngBuf( Request.lpExchangeBuf, szBuffer, 4096 );
				break;
			}
#endif

			cbWriten = sendPacket( iSocket, szBuffer,
								 lptsComProps->len+sizeof(TS_COM_PROPS) );
			//if( cbWriten == SOCKET_ERROR ) {
			if( cbWriten <= 0 ) {
				dwRetCode = GetLastError();
				CliSetExchBufError( Request.lpExchangeBuf );
				break;
			}
		}

		dwRetCode = TERR_SUCCESS;
	}

	if( dwRetCode == TERR_SUCCESS ) {
		ZeroMemory( szBuffer, 4096 );
		lptsComProps->packetType = pkTS_SYNC_PIPE;
		lptsComProps->msgType = msgTS_CLIENT_LOGOFF;
		dwRetCode = CliWriteExchngBuf( Request.lpExchangeBuf, szBuffer, 4096 );
		if( dwRetCode != TERR_SUCCESS )
			CliSetExchBufError( Request.lpExchangeBuf );
	}

	lprintfs( "Client agent thread ends.\n" );

	}
	_except ( EXCEPTION_EXECUTE_HANDLER ) {
		char szBuffer[256];

		wsprintf( szBuffer, "Client adent thread cause an exception.\n" );
		MessageBox( NULL, szBuffer, "Inspector", MB_OK | MB_ICONSTOP );
	}

	closesocket( iSocket );
	ExitThread( TERR_SUCCESS );

	return  0;

}
Example #5
0
// The thread process the user's conversation: Get user's request command, send it
// to scheduler, Get the response code and return it to user.
// The parameter "lpvParam" if the NamedPipe instance handle value.
DWORD WINAPI ClientAgentThread ( LPVOID lpvParam )
{
	LPTS_COM_PROPS lptsComProps;
	REQUEST Request;
	CHAR szBuffer[PIPE_BUFFER_SIZE];
	DWORD cbWriten, cbReaded;
	DWORD dwRetCode;
	BOOL fSuccess;
	BOOL fDirect = TRUE;
	MSG Msg;

#ifdef TREESVR_STANDALONE
	HANDLE hReadPipe, hWritePipe;

	hReadPipe  = ( ( PIPE_STRU * )lpvParam )->hReadPipe;
	hWritePipe = ( ( PIPE_STRU * )lpvParam )->hWritePipe;
#else
	HANDLE hPipe;

	hPipe = (HANDLE) lpvParam;

	// If the parameter lpvParam is an invalid pipe handle.
	if( hPipe == 0 || hPipe == INVALID_HANDLE_VALUE )
		ExitThread( ERROR_INVALID_PARAMETER );
#endif

	GetQueueStatus( QS_SENDMESSAGE ); 
	
	lprintfs( "Client agent thread starts.\n" );
    
	_try {
	// Wait and read the message send by the client, until the client post.

#ifdef TREESVR_STANDALONE
	fSuccess = ReadFile ( hReadPipe,
			szBuffer, 
			PIPE_BUFFER_SIZE,
			&cbReaded,
			NULL );
#else
	fSuccess = ReadFile ( hPipe,
			szBuffer, 
			PIPE_BUFFER_SIZE,
			&cbReaded,
			NULL );
#endif

	if( !fSuccess ) {
#ifdef TREESVR_STANDALONE
//		FlushFileBuffers( hWritePipe );
#else
		FlushFileBuffers( hPipe );
		DisconnectNamedPipe ( hPipe );
		CloseHandle( hPipe );
#endif
		ExitThread( GetLastError() );
	}

	// Get the packet header, analyse the packet information. 
	lptsComProps = (LPTS_COM_PROPS)szBuffer;
	
	// If the user's first packet is not logon information packet,
	// Reject the user's request.
	if( lptsComProps->packetType != pkTS_SYNC_PIPE || 
			lptsComProps->msgType != msgTS_CLIENT_LOGON ) {
		ZeroMemory( szBuffer, PIPE_BUFFER_SIZE );
		lptsComProps->packetType = pkTS_ERROR;
		lptsComProps->msgType = msgTS_ERROR_MSG;
		
		lptsComProps->len = wsprintfA( (LPSTR)(szBuffer+sizeof( TS_COM_PROPS )),
				"User can not access the server before logon." );

#ifdef TREESVR_STANDALONE
		fSuccess = WriteFile ( hWritePipe,
				(LPCVOID)szBuffer, 
//				lptsComProps->len+sizeof( TS_COM_PROPS ), 
				PIPE_BUFFER_SIZE,
				&cbWriten,
				NULL );

//		FlushFileBuffers( hWritePipe );
#else
		fSuccess = WriteFile ( hPipe,
				(LPCVOID)szBuffer, 
				lptsComProps->len+sizeof( TS_COM_PROPS ), 
				&cbWriten,
				NULL );

		FlushFileBuffers( hPipe );
		DisconnectNamedPipe ( hPipe );
		CloseHandle( hPipe );
#endif
		
		ExitThread( TERR_NOT_LOGON );
	}

#ifndef TREESVR_STANDALONE
	// Add by Jingyu Niu, 2000.08.25, for support single user mode.
	if( singleUserMode ) {
		ZeroMemory( szBuffer, PIPE_BUFFER_SIZE );
		lptsComProps->packetType = pkTS_SYNC_PIPE;
		lptsComProps->msgType = msgTS_LOGON_ERROR;
		lptsComProps->lp = 0x10000;
		
		lptsComProps->len = wsprintfA( (LPSTR)(szBuffer+sizeof( TS_COM_PROPS )),
			"Server now running in single user mode, not accept connect request." );

#ifdef TREESVR_STANDALONE
		fSuccess = WriteFile ( hWritePipe,
				(LPCVOID)szBuffer, 
//				lptsComProps->len+sizeof( TS_COM_PROPS ), 
				PIPE_BUFFER_SIZE,
				&cbWriten,
				NULL );

//		FlushFileBuffers( hWritePipe );
#else
		fSuccess = WriteFile ( hPipe,
				(LPCVOID)szBuffer, 
				lptsComProps->len+sizeof( TS_COM_PROPS ), 
				&cbWriten,
				NULL );

		FlushFileBuffers( hPipe );
		DisconnectNamedPipe ( hPipe );
		CloseHandle( hPipe );
#endif

		ExitThread( 0x10000 );
	}
#endif

	// If the user's logon information packet is invalid,
	// Reject the user's request.
	dwRetCode = MsgToRequest( (LPCSTR)(szBuffer+sizeof( TS_COM_PROPS )), &Request );
	if( dwRetCode != TERR_SUCCESS ) {
		ZeroMemory( szBuffer, PIPE_BUFFER_SIZE );
		lptsComProps->packetType = pkTS_SYNC_PIPE;
		lptsComProps->msgType = msgTS_LOGON_ERROR;
		lptsComProps->lp = dwRetCode;
		
		lptsComProps->len = wsprintfA( (LPSTR)(szBuffer+sizeof( TS_COM_PROPS )),
			"Logon information error(error code:%ld).", dwRetCode );

#ifdef TREESVR_STANDALONE
		fSuccess = WriteFile ( hWritePipe,
				(LPCVOID)szBuffer, 
//				lptsComProps->len+sizeof( TS_COM_PROPS ), 
				PIPE_BUFFER_SIZE,
				&cbWriten,
				NULL );

//		FlushFileBuffers( hWritePipe );
#else
		fSuccess = WriteFile ( hPipe,
				(LPCVOID)szBuffer, 
				lptsComProps->len+sizeof( TS_COM_PROPS ), 
				&cbWriten,
				NULL );

		FlushFileBuffers( hPipe );
		DisconnectNamedPipe ( hPipe );
		CloseHandle( hPipe );
#endif

		ExitThread( dwRetCode );
	}

	// Send the request to scheduler.
	dwRetCode = SendRequest( &Request );
	if( dwRetCode != TERR_SUCCESS ) {
		ZeroMemory( szBuffer, PIPE_BUFFER_SIZE );
		lptsComProps->packetType = pkTS_ERROR;
		lptsComProps->msgType = msgTS_LOGON_ERROR;
		lptsComProps->lp = dwRetCode;
		
		lptsComProps->len = wsprintfA( (LPSTR)(szBuffer+sizeof( TS_COM_PROPS )),
			"Can not logon the server(error code:%ld).", dwRetCode );

#ifdef TREESVR_STANDALONE
		fSuccess = WriteFile ( hWritePipe,
				(LPCVOID)szBuffer, 
//				lptsComProps->len+sizeof( TS_COM_PROPS ), 
				PIPE_BUFFER_SIZE,
				&cbWriten,
				NULL );

//		FlushFileBuffers( hWritePipe );
#else
		fSuccess = WriteFile ( hPipe,
				(LPCVOID)szBuffer, 
				lptsComProps->len+sizeof( TS_COM_PROPS ), 
				&cbWriten,
				NULL );

		FlushFileBuffers( hPipe );
		DisconnectNamedPipe ( hPipe );
		CloseHandle( hPipe );
#endif

		ExitThread( dwRetCode );
	}
	

	ZeroMemory( szBuffer, PIPE_BUFFER_SIZE );
	lptsComProps->packetType = pkTS_SYNC_PIPE;

	if( Request.dwRequest == TERR_SUCCESS ) {
		lptsComProps->msgType = msgTS_LOGON_OK;
		lptsComProps->lp = Request.dwRequestId;
	}
	else { 
		lptsComProps->msgType = msgTS_LOGON_ERROR;
		lptsComProps->lp = Request.dwRequest;
	}
	
#ifdef TREESVR_STANDALONE
	fSuccess = WriteFile ( hWritePipe,
			(LPCVOID)szBuffer, 
//			sizeof( TS_COM_PROPS ), 
			PIPE_BUFFER_SIZE,
			&cbWriten,
			NULL );
#else
	fSuccess = WriteFile ( hPipe,
			(LPCVOID)szBuffer, 
			sizeof( TS_COM_PROPS ), 
			&cbWriten,
			NULL );
#endif

	if( !fSuccess ) {
#ifdef TREESVR_STANDALONE
//		FlushFileBuffers( hWritePipe );
#else
		FlushFileBuffers( hPipe );
		DisconnectNamedPipe ( hPipe );
		CloseHandle( hPipe );
#endif

		ExitThread( GetLastError() );
	}
	
	if( Request.dwRequest != TERR_SUCCESS ) {
#ifdef TREESVR_STANDALONE		
//		FlushFileBuffers( hWritePipe );
#else		
		FlushFileBuffers( hPipe );
		DisconnectNamedPipe ( hPipe );
		CloseHandle ( hPipe );
#endif

		ExitThread( TERR_SUCCESS );
	}

	// Add by NiuJingyu, 1998.03
	GetMessage( &Msg, NULL, TS_SERVICE_START, TS_SERVICE_START );

	dwRetCode = TERR_SUCCESS;

//	lprintfs( "########################## Begin transfer loop.\n" );
	while( 1 ) {
		if( fDirect ) {
			// Client is voluntary.
//		lprintfs( "########################## Read namedpipe.\n" );
#ifdef TREESVR_STANDALONE		
			fSuccess = ReadFile ( hReadPipe,
					szBuffer, 
					PIPE_BUFFER_SIZE,
					&cbReaded,
					NULL );
#else
			fSuccess = ReadFile ( hPipe,
					szBuffer, 
					PIPE_BUFFER_SIZE,
					&cbReaded,
					NULL );
#endif

			if( !fSuccess ) {
				dwRetCode = GetLastError();
				if( dwRetCode == ERROR_BROKEN_PIPE )  { //The pipe has been ended.
					CliSetExchBufError( Request.lpExchangeBuf );
					dwRetCode = TERR_CLIENT_CLOSE;
					break;
				}
			}

#ifdef TREESVR_STANDALONE		
//			FlushFileBuffers ( hWritePipe );
#else
			FlushFileBuffers ( hPipe );
#endif
		
			lptsComProps = (LPTS_COM_PROPS)szBuffer;
			if( lptsComProps->endPacket == '\x0' )
				fDirect = FALSE;

			if( lptsComProps->packetType == pkTS_SYNC_PIPE ) {
				if( lptsComProps->msgType == msgTS_PIPE_CLOSE ) {
					dwRetCode = TERR_SUCCESS;
					break;
				}
			} 

#ifndef TREESVR_STANDALONE
			// Add by Jingyu Niu, 2000.08.25, for support single user mode.
			if( singleUserMode && singleUserThread != GetCurrentThreadId() ) {
				if( fDirect )
					continue;
				else {
					dwRetCode = TERR_SUCCESS;
					break;
				}
			}
#endif

//			lprintfs( "########################## Client write exchange buffer.\n" );
			dwRetCode = CliWriteExchngBuf( Request.lpExchangeBuf, szBuffer, 4096 );
			if( dwRetCode != TERR_SUCCESS ) {
				break;
			}
		}
		else {
			// Service thread is voluntary.
			// Read the packet from service thread.
			dwRetCode = CliReadExchngBuf( Request.lpExchangeBuf, szBuffer, 4096 );
			if( dwRetCode != TERR_SUCCESS )
				break;

			lptsComProps = (LPTS_COM_PROPS)szBuffer;
			if( lptsComProps->endPacket == '\x0' )
				fDirect = TRUE;
	
			if( lptsComProps->packetType == pkTS_SYNC_PIPE ) {
				if( lptsComProps->msgType == msgTS_NO_DATA )
					continue;
			}

#ifndef TREESVR_STANDALONE
			// Add by Jingyu Niu, 2000.08.25, for support single user mode.
			if( singleUserMode && singleUserThread != GetCurrentThreadId() && fDirect ) {
				lptsComProps->packetType = pkTS_SYNC_PIPE;
				lptsComProps->msgType = msgTS_PIPE_CLOSE;
				lptsComProps->lp = 0;
				lptsComProps->len = 0;
				lptsComProps->leftPacket = '\x0';
				lptsComProps->endPacket = '\x0';

				dwRetCode = CliWriteExchngBuf( Request.lpExchangeBuf, szBuffer, 4096 );
				break;
			}
#endif

#ifdef TREESVR_STANDALONE
			fSuccess = WriteFile ( hWritePipe,
					(LPCVOID)szBuffer, 
//					lptsComProps->len+sizeof( TS_COM_PROPS ), 
					PIPE_BUFFER_SIZE,
					&cbWriten,
					NULL );
#else
			fSuccess = WriteFile ( hPipe,
					(LPCVOID)szBuffer, 
					lptsComProps->len+sizeof( TS_COM_PROPS ), 
					&cbWriten,
					NULL );
#endif
			
			if( !fSuccess ) {
				dwRetCode = GetLastError();
				if( dwRetCode == ERROR_NO_DATA ) { // Pipe close in progress.
					dwRetCode = TERR_CLIENT_CLOSE;
					CliSetExchBufError( Request.lpExchangeBuf );
					break;
				}
			}
#ifdef TREESVR_STANDALONE		
//			FlushFileBuffers ( hWritePipe );
#else
			FlushFileBuffers ( hPipe );
#endif
		}
		
		dwRetCode = TERR_SUCCESS;
	}

	if( dwRetCode == TERR_SUCCESS ) {
		ZeroMemory( szBuffer, 4096 );
		lptsComProps->packetType = pkTS_SYNC_PIPE;
		lptsComProps->msgType = msgTS_CLIENT_LOGOFF;
		dwRetCode = CliWriteExchngBuf( Request.lpExchangeBuf, szBuffer, 4096 );
		if( dwRetCode != TERR_SUCCESS )
			CliSetExchBufError( Request.lpExchangeBuf );
	}

	lprintfs( "Client agent thread ends.\n" );

#ifdef TREESVR_STANDALONE		
//	FlushFileBuffers ( hWritePipe );
#else
	FlushFileBuffers ( hPipe );
	DisconnectNamedPipe ( hPipe );
	CloseHandle ( hPipe );
#endif
	}
	_except ( EXCEPTION_EXECUTE_HANDLER ) {
		char szBuffer[256];

		wsprintf( szBuffer, "Client adent thread cause an exception.\n" );
		MessageBox( NULL, szBuffer, "Inspector", MB_OK | MB_ICONSTOP );
	}

	ExitThread( TERR_SUCCESS );

	return  0;

}
Example #6
0
/*-------------------------------------------------------*/
PIORB NEAR PreProcessIORBs (NPA npA, NPU npU, PPIORB ppFirstIORB)
{
  PIORB  pIORB, pIORBPrev, pIORBNext;
  USHORT Cmd;

#define CmdCode (Cmd >> 8)
#define CmdModifier (UCHAR)(Cmd & 0xFF)

  pIORB     = *ppFirstIORB;
  pIORBPrev = 0;

  do {
    pIORBNext = (pIORB->RequestControl & IORB_CHAIN) ? pIORB->pNxtIORB : 0;
    Cmd = REQ (pIORB->CommandCode, pIORB->CommandModifier);

    if ((Cmd == REQ (IOCC_ADAPTER_PASSTHRU, IOCM_EXECUTE_CDB)) ||
	(CmdCode == IOCC_CONFIGURATION) ||
	(CmdCode == IOCC_RESOURCE)	||
	(CmdCode == IOCC_DEVICE_CONTROL)) {

      if (pIORBPrev) {
	pIORBPrev->pNxtIORB = pIORBNext;
      } else {
	*ppFirstIORB = pIORBNext;
      }

      if (CmdCode == IOCC_RESOURCE) Cmd = 10 + CmdModifier;
      if (CmdCode == IOCC_CONFIGURATION) Cmd = 8 + CmdModifier;
      if (CmdCode == IOCC_ADAPTER_PASSTHRU) {
	PCHAR SCSICmd = ((PIORB_ADAPTER_PASSTHRU)pIORB)->pControllerCmd;

	Cmd = 0;
	if ((SCSICmd[0] == SCSI_START_STOP_UNIT) && (SCSICmd[4] == 2))
	  Cmd = IOCM_EJECT_MEDIA;
      }

      switch (CmdModifier) {
	case 9 /* IOCM_GET_DEVICE_TABLE */ :
	  GetDeviceTable (pIORB); break;

	case 10 /* IOCM_COMPLETE_INIT */ :
	  CompleteInit (npA); break;

	case 11 /* IOCM_REPORT_RESOURCES */ :
	  GetUnitResources (npA, pIORB); break;

	case IOCM_SUSPEND :
	  SuspendIORBReq (npA, pIORB); break;

	case IOCM_RESUME :
	  ResumeIORBReq (npA, pIORB); break;

	case IOCM_GET_QUEUE_STATUS :
	  GetQueueStatus (npA, pIORB); break;

	case IOCM_EJECT_MEDIA :
	case IOCM_LOCK_MEDIA :
	case IOCM_UNLOCK_MEDIA :
	  ProcessLockUnlockEject (npU, pIORB, CmdModifier); break;

	default:
	  pIORB->Status   |= IORB_ERROR;
	  pIORB->ErrorCode = IOERR_CMD_NOT_SUPPORTED;
      }

      if (CmdModifier != IOCM_SUSPEND) {
	pIORB->Status |= IORB_DONE;

	if (pIORB->RequestControl & IORB_ASYNC_POST)
	  ((PIORBNotify)pIORB->NotifyAddress) (pIORB);
      }
      continue;
    }
    pIORBPrev = pIORB;
  } while (pIORB = pIORBNext);

  if (pIORBPrev)
    pIORBPrev->pNxtIORB = 0;

  return (pIORBPrev);
}
Example #7
0
/* This is the fastpoll function which gathers up info by calling various api's */
BOOL FastPoll (void)
{
	int nOriginalRandIndex = nRandIndex;
	static BOOL addedFixedItems = FALSE;
	FILETIME creationTime, exitTime, kernelTime, userTime;
	DWORD minimumWorkingSetSize, maximumWorkingSetSize;
	LARGE_INTEGER performanceCount;
	MEMORYSTATUS memoryStatus;
	HANDLE handle;
	POINT point;

	/* Get various basic pieces of system information */
	RandaddInt32 (GetActiveWindow ());	/* Handle of active window */
	RandaddInt32 (GetCapture ());	/* Handle of window with mouse
					   capture */
	RandaddInt32 (GetClipboardOwner ());	/* Handle of clipboard owner */
	RandaddInt32 (GetClipboardViewer ());	/* Handle of start of
						   clpbd.viewer list */
	RandaddInt32 (GetCurrentProcess ());	/* Pseudohandle of current
						   process */
	RandaddInt32 (GetCurrentProcessId ());	/* Current process ID */
	RandaddInt32 (GetCurrentThread ());	/* Pseudohandle of current
						   thread */
	RandaddInt32 (GetCurrentThreadId ());	/* Current thread ID */
	RandaddInt32 (GetCurrentTime ());	/* Milliseconds since Windows
						   started */
	RandaddInt32 (GetDesktopWindow ());	/* Handle of desktop window */
	RandaddInt32 (GetFocus ());	/* Handle of window with kb.focus */
	RandaddInt32 (GetInputState ());	/* Whether sys.queue has any events */
	RandaddInt32 (GetMessagePos ());	/* Cursor pos.for last message */
	RandaddInt32 (GetMessageTime ());	/* 1 ms time for last message */
	RandaddInt32 (GetOpenClipboardWindow ());	/* Handle of window with
							   clpbd.open */
	RandaddInt32 (GetProcessHeap ());	/* Handle of process heap */
	RandaddInt32 (GetProcessWindowStation ());	/* Handle of procs
							   window station */
	RandaddInt32 (GetQueueStatus (QS_ALLEVENTS));	/* Types of events in
							   input queue */

	/* Get multiword system information */
	GetCaretPos (&point);	/* Current caret position */
	RandaddBuf ((unsigned char *) &point, sizeof (POINT));
	GetCursorPos (&point);	/* Current mouse cursor position */
	RandaddBuf ((unsigned char *) &point, sizeof (POINT));

	/* Get percent of memory in use, bytes of physical memory, bytes of
	   free physical memory, bytes in paging file, free bytes in paging
	   file, user bytes of address space, and free user bytes */
	memoryStatus.dwLength = sizeof (MEMORYSTATUS);
	GlobalMemoryStatus (&memoryStatus);
	RandaddBuf ((unsigned char *) &memoryStatus, sizeof (MEMORYSTATUS));

	/* Get thread and process creation time, exit time, time in kernel
	   mode, and time in user mode in 100ns intervals */
	handle = GetCurrentThread ();
	GetThreadTimes (handle, &creationTime, &exitTime, &kernelTime, &userTime);
	RandaddBuf ((unsigned char *) &creationTime, sizeof (FILETIME));
	RandaddBuf ((unsigned char *) &exitTime, sizeof (FILETIME));
	RandaddBuf ((unsigned char *) &kernelTime, sizeof (FILETIME));
	RandaddBuf ((unsigned char *) &userTime, sizeof (FILETIME));
	handle = GetCurrentProcess ();
	GetProcessTimes (handle, &creationTime, &exitTime, &kernelTime, &userTime);
	RandaddBuf ((unsigned char *) &creationTime, sizeof (FILETIME));
	RandaddBuf ((unsigned char *) &exitTime, sizeof (FILETIME));
	RandaddBuf ((unsigned char *) &kernelTime, sizeof (FILETIME));
	RandaddBuf ((unsigned char *) &userTime, sizeof (FILETIME));

	/* Get the minimum and maximum working set size for the current
	   process */
	GetProcessWorkingSetSize (handle, &minimumWorkingSetSize,
				  &maximumWorkingSetSize);
	RandaddInt32 (minimumWorkingSetSize);
	RandaddInt32 (maximumWorkingSetSize);

	/* The following are fixed for the lifetime of the process so we only
	   add them once */
	if (addedFixedItems == 0)
	{
		STARTUPINFO startupInfo;

		/* Get name of desktop, console window title, new window
		   position and size, window flags, and handles for stdin,
		   stdout, and stderr */
		startupInfo.cb = sizeof (STARTUPINFO);
		GetStartupInfo (&startupInfo);
		RandaddBuf ((unsigned char *) &startupInfo, sizeof (STARTUPINFO));
		addedFixedItems = TRUE;
	}
	/* The docs say QPC can fail if appropriate hardware is not
	   available. It works on 486 & Pentium boxes, but hasn't been tested
	   for 386 or RISC boxes */
	if (QueryPerformanceCounter (&performanceCount))
		RandaddBuf ((unsigned char *) &performanceCount, sizeof (LARGE_INTEGER));
	else
	{
		/* Millisecond accuracy at best... */
		DWORD dwTicks = GetTickCount ();
		RandaddBuf ((unsigned char *) &dwTicks, sizeof (dwTicks));
	}

	// CryptoAPI
	if (CryptoAPIAvailable && CryptGenRandom (hCryptProv, sizeof (buffer), buffer)) 
		RandaddBuf (buffer, sizeof (buffer));

	/* Apply the pool mixing function */
	Randmix();

	/* Restore the original pool cursor position. If this wasn't done, mouse coordinates
	   could be written to a limited area of the pool, especially when moving the mouse
	   uninterruptedly. The severity of the problem would depend on the length of data
	   written by FastPoll (if it was equal to the size of the pool, mouse coordinates
	   would be written only to a particular 4-byte area, whenever moving the mouse
	   uninterruptedly). */
	nRandIndex = nOriginalRandIndex;

	return TRUE;
}
Example #8
0
void
_gcry_rndw32_gather_random_fast (void (*add)(const void*, size_t,
                                             enum random_origins),
                                 enum random_origins origin)
{
  static int addedFixedItems = 0;

  if ( debug_me )
    log_debug ("rndw32#gather_random_fast: ori=%d\n", origin );

  /* Get various basic pieces of system information: Handle of active
     window, handle of window with mouse capture, handle of clipboard
     owner handle of start of clpboard viewer list, pseudohandle of
     current process, current process ID, pseudohandle of current
     thread, current thread ID, handle of desktop window, handle of
     window with keyboard focus, whether system queue has any events,
     cursor position for last message, 1 ms time for last message,
     handle of window with clipboard open, handle of process heap,
     handle of procs window station, types of events in input queue,
     and milliseconds since Windows was started.  */

  {
    byte buffer[20*sizeof(ulong)], *bufptr;

    bufptr = buffer;
#define ADD(f)  do { ulong along = (ulong)(f);                  \
                     memcpy (bufptr, &along, sizeof (along) );  \
                     bufptr += sizeof (along);                  \
                   } while (0)

    ADD ( GetActiveWindow ());
    ADD ( GetCapture ());
    ADD ( GetClipboardOwner ());
    ADD ( GetClipboardViewer ());
    ADD ( GetCurrentProcess ());
    ADD ( GetCurrentProcessId ());
    ADD ( GetCurrentThread ());
    ADD ( GetCurrentThreadId ());
    ADD ( GetDesktopWindow ());
    ADD ( GetFocus ());
    ADD ( GetInputState ());
    ADD ( GetMessagePos ());
    ADD ( GetMessageTime ());
    ADD ( GetOpenClipboardWindow ());
    ADD ( GetProcessHeap ());
    ADD ( GetProcessWindowStation ());
    ADD ( GetQueueStatus (QS_ALLEVENTS));
    ADD ( GetTickCount ());

    gcry_assert ( bufptr-buffer < sizeof (buffer) );
    (*add) ( buffer, bufptr-buffer, origin );
#undef ADD
  }

  /* Get multiword system information: Current caret position, current
     mouse cursor position.  */
  {
    POINT point;

    GetCaretPos (&point);
    (*add) ( &point, sizeof (point), origin );
    GetCursorPos (&point);
    (*add) ( &point, sizeof (point), origin );
  }

  /* Get percent of memory in use, bytes of physical memory, bytes of
     free physical memory, bytes in paging file, free bytes in paging
     file, user bytes of address space, and free user bytes.  */
  {
    MEMORYSTATUS memoryStatus;

    memoryStatus.dwLength = sizeof (MEMORYSTATUS);
    GlobalMemoryStatus (&memoryStatus);
    (*add) ( &memoryStatus, sizeof (memoryStatus), origin );
  }

  /* Get thread and process creation time, exit time, time in kernel
     mode, and time in user mode in 100ns intervals.  */
  {
    HANDLE handle;
    FILETIME creationTime, exitTime, kernelTime, userTime;
    DWORD minimumWorkingSetSize, maximumWorkingSetSize;

    handle = GetCurrentThread ();
    GetThreadTimes (handle, &creationTime, &exitTime,
                    &kernelTime, &userTime);
    (*add) ( &creationTime, sizeof (creationTime), origin );
    (*add) ( &exitTime, sizeof (exitTime), origin );
    (*add) ( &kernelTime, sizeof (kernelTime), origin );
    (*add) ( &userTime, sizeof (userTime), origin );

    handle = GetCurrentProcess ();
    GetProcessTimes (handle, &creationTime, &exitTime,
                     &kernelTime, &userTime);
    (*add) ( &creationTime, sizeof (creationTime), origin );
    (*add) ( &exitTime, sizeof (exitTime), origin );
    (*add) ( &kernelTime, sizeof (kernelTime), origin );
    (*add) ( &userTime, sizeof (userTime), origin );

    /* Get the minimum and maximum working set size for the current
       process.  */
    GetProcessWorkingSetSize (handle, &minimumWorkingSetSize,
                              &maximumWorkingSetSize);
    (*add) ( &minimumWorkingSetSize,
             sizeof (minimumWorkingSetSize), origin );
    (*add) ( &maximumWorkingSetSize,
             sizeof (maximumWorkingSetSize), origin );
  }


  /* The following are fixed for the lifetime of the process so we only
   * add them once */
  if (!addedFixedItems)
    {
      STARTUPINFO startupInfo;

      /* Get name of desktop, console window title, new window
         position and size, window flags, and handles for stdin,
         stdout, and stderr.  */
      startupInfo.cb = sizeof (STARTUPINFO);
      GetStartupInfo (&startupInfo);
      (*add) ( &startupInfo, sizeof (STARTUPINFO), origin );
      addedFixedItems = 1;
    }

  /* The performance of QPC varies depending on the architecture it's
     running on and on the OS, the MS documentation is vague about the
     details because it varies so much.  Under Win9x/ME it reads the
     1.193180 MHz PIC timer.  Under NT/Win2K/XP it may or may not read the
     64-bit TSC depending on the HAL and assorted other circumstances,
     generally on machines with a uniprocessor HAL
     KeQueryPerformanceCounter() uses a 3.579545MHz timer and on machines
     with a multiprocessor or APIC HAL it uses the TSC (the exact time
     source is controlled by the HalpUse8254 flag in the kernel).  That
     choice of time sources is somewhat peculiar because on a
     multiprocessor machine it's theoretically possible to get completely
     different TSC readings depending on which CPU you're currently
     running on, while for uniprocessor machines it's not a problem.
     However, the kernel appears to synchronise the TSCs across CPUs at
     boot time (it resets the TSC as part of its system init), so this
     shouldn't really be a problem.  Under WinCE it's completely platform-
     dependant, if there's no hardware performance counter available, it
     uses the 1ms system timer.

     Another feature of the TSC (although it doesn't really affect us here)
     is that mobile CPUs will turn off the TSC when they idle, Pentiums
     will change the rate of the counter when they clock-throttle (to
     match the current CPU speed), and hyperthreading Pentiums will turn
     it off when both threads are idle (this more or less makes sense,
     since the CPU will be in the halted state and not executing any
     instructions to count).

     To make things unambiguous, we detect a CPU new enough to call RDTSC
     directly by checking for CPUID capabilities, and fall back to QPC if
     this isn't present.  */
#ifdef __GNUC__
/*   FIXME: We would need to implement the CPU feature tests first.  */
/*   if (cpu_has_feature_rdtsc) */
/*     { */
/*       uint32_t lo, hi; */
      /* We cannot use "=A", since this would use %rax on x86_64. */
/*       __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); */
      /* Ignore high 32 bits, hwich are >1s res.  */
/*       (*add) (&lo, 4, origin ); */
/*     } */
/*   else */
#endif /*!__GNUC__*/
    {
      LARGE_INTEGER performanceCount;

      if (QueryPerformanceCounter (&performanceCount))
        {
          if ( debug_me )
          log_debug ("rndw32#gather_random_fast: perf data\n");
          (*add) (&performanceCount, sizeof (performanceCount), origin);
        }
      else
        {
          /* Millisecond accuracy at best... */
          DWORD aword = GetTickCount ();
          (*add) (&aword, sizeof (aword), origin );
        }
    }


}
Example #9
0
// Waits for the HANDLE hObject.  While waiting messages sent
// to windows on our thread by SendMessage will be processed.
// Using this function to do waits and mutual exclusion
// avoids some deadlocks in objects with windows.
// Return codes are the same as for WaitForSingleObject
DWORD WINAPI WaitDispatchingMessages(
    HANDLE hObject,
    DWORD dwWait,
    HWND hwnd,
    UINT uMsg,
    HANDLE hEvent)
{
    BOOL bPeeked = FALSE;
    DWORD dwResult;
    DWORD dwStart;
    DWORD dwThreadPriority;

    static UINT uMsgId = 0;

    HANDLE hObjects[2] = { hObject, hEvent };
    if (dwWait != INFINITE && dwWait != 0) {
        dwStart = GetTickCount();
    }
    for (; ; ) {
        DWORD nCount = NULL != hEvent ? 2 : 1;

        //  Minimize the chance of actually dispatching any messages
        //  by seeing if we can lock immediately.
        dwResult = WaitForMultipleObjects(nCount, hObjects, FALSE, 0);
        if (dwResult < WAIT_OBJECT_0 + nCount) {
            break;
        }

        DWORD dwTimeOut = dwWait;
        if (dwTimeOut > 10) {
            dwTimeOut = 10;
        }
        dwResult = MsgWaitForMultipleObjects(
                             nCount,
                             hObjects,
                             FALSE,
                             dwTimeOut,
                             hwnd == NULL ? QS_SENDMESSAGE :
                                            QS_SENDMESSAGE + QS_POSTMESSAGE);
        if (dwResult == WAIT_OBJECT_0 + nCount ||
            dwResult == WAIT_TIMEOUT && dwTimeOut != dwWait) {
            MSG msg;
            if (hwnd != NULL) {
                while (PeekMessage(&msg, hwnd, uMsg, uMsg, PM_REMOVE)) {
                    DispatchMessage(&msg);
                }
            }
            // Do this anyway - the previous peek doesn't flush out the
            // messages
            PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);

            if (dwWait != INFINITE && dwWait != 0) {
                DWORD dwNow = GetTickCount();

                // Working with differences handles wrap-around
                DWORD dwDiff = dwNow - dwStart;
                if (dwDiff > dwWait) {
                    dwWait = 0;
                } else {
                    dwWait -= dwDiff;
                }
                dwStart = dwNow;
            }
            if (!bPeeked) {
                //  Raise our priority to prevent our message queue
                //  building up
                dwThreadPriority = GetThreadPriority(GetCurrentThread());
                if (dwThreadPriority < THREAD_PRIORITY_HIGHEST) {
                    SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
                }
                bPeeked = TRUE;
            }
        } else {
            break;
        }
    }
    if (bPeeked) {
        SetThreadPriority(GetCurrentThread(), dwThreadPriority);
        if (HIWORD(GetQueueStatus(QS_POSTMESSAGE)) & QS_POSTMESSAGE) {
            if (uMsgId == 0) {
                uMsgId = RegisterWindowMessage(TEXT("AMUnblock"));
            }
            if (uMsgId != 0) {
                MSG msg;
                //  Remove old ones
                while (PeekMessage(&msg, (HWND)-1, uMsgId, uMsgId, PM_REMOVE)) {
                }
            }
            PostThreadMessage(GetCurrentThreadId(), uMsgId, 0, 0);
        }
    }
    return dwResult;
}
bool
CMSWindowsEventQueueBuffer::isEmpty() const
{
	return (HIWORD(GetQueueStatus(QS_ALLINPUT)) == 0);
}