/* Find a thread record given a thread id.  If GET_CONTEXT is set then
   also retrieve the context for this thread.  */
static thread_info *
thread_rec (DWORD id, int get_context)
{
  struct thread_info *thread;
  thread_info *th;

  thread = (struct thread_info *) find_inferior_id (&all_threads, id);
  if (thread == NULL)
    return NULL;

  th = inferior_target_data (thread);
  if (!th->suspend_count && get_context)
    {
      if (get_context > 0 && id != current_event.dwThreadId)
	th->suspend_count = SuspendThread (th->h) + 1;
      else if (get_context < 0)
	th->suspend_count = -1;

      th->context.ContextFlags = CONTEXT_DEBUGGER_DR;

      GetThreadContext (th->h, &th->context);

      if (id == current_event.dwThreadId)
	{
	  /* Copy dr values from that thread.  */
	  dr[0] = th->context.Dr0;
	  dr[1] = th->context.Dr1;
	  dr[2] = th->context.Dr2;
	  dr[3] = th->context.Dr3;
	  dr[6] = th->context.Dr6;
	  dr[7] = th->context.Dr7;
	}
    }

  return th;
}
Example #2
0
static DWORD WINAPI profiler_thread_entry(LPVOID lpParameter)
{
	HANDLE mainThread = (HANDLE)lpParameter;
	CONTEXT context;

	/* loop until done */
	memset(&context, 0, sizeof(context));
	while (!profiler_thread_exit)
	{
		/* pause the main thread and get its context */
		SuspendThread(mainThread);
		context.ContextFlags = CONTEXT_FULL;
		GetThreadContext(mainThread, &context);
		ResumeThread(mainThread);

		/* add to the bucket */
		increment_bucket(context.Eip);

		/* sleep */
		Sleep(1);
	}

	return 0;
}
static gboolean
gst_directsound_ring_buffer_pause (GstRingBuffer * buf)
{
  HRESULT hr = S_OK;
  GstDirectSoundRingBuffer * dsoundbuffer;

  dsoundbuffer = GST_DIRECTSOUND_RING_BUFFER (buf);

  GST_DEBUG ("Pausing RingBuffer");

  GST_DSOUND_LOCK (dsoundbuffer);

  if (dsoundbuffer->pDSB8) {
    hr = IDirectSoundBuffer8_Stop (dsoundbuffer->pDSB8);
  }

  if (G_LIKELY (!dsoundbuffer->suspended)) {
    if (G_UNLIKELY(SuspendThread (dsoundbuffer->hThread) == -1))
      GST_WARNING ("gst_directsound_ring_buffer_pause: SuspendThread failed.");
    else 
      dsoundbuffer->suspended = TRUE;
  }

  GST_DSOUND_UNLOCK (dsoundbuffer);

  /* in the unlikely event that a device was reconfigured, we can consider
   * ourselves stopped even though the stop call failed */
  if (G_UNLIKELY (FAILED(hr)) &&
      G_UNLIKELY(hr != DIRECTSOUND_ERROR_DEVICE_RECONFIGURED) &&
      G_UNLIKELY(hr != DIRECTSOUND_ERROR_DEVICE_NO_DRIVER)) {
    GST_WARNING ("gst_directsound_ring_buffer_pause: IDirectSoundBuffer8_Stop, hr = %X", (unsigned int) hr);
    return FALSE;
  }

  return TRUE;
}
Example #4
0
DWORD WINAPI stream_run(void * data)
{
  SoundThread * me = (SoundThread *) data;
  while(me->running) {
    if(me->sound) {
      Sound * sound = me->sound;
      ALuint uiSource;
      ALint iState = AL_PLAYING;
      ALuint uiBuffers[1];

      alGenBuffers(1, uiBuffers);
      alGenSources(1, &uiSource);
      alBufferData(uiBuffers[0], sound->format, sound->data, sound->size, sound->freq);
      assert(AL_NO_ERROR == alGetError());
      alSourceQueueBuffers(uiSource, 1, &uiBuffers[0]);
      alSourcef(uiSource, AL_GAIN, sound->volume);
      alSourcePlay(uiSource);

      while(iState == AL_PLAYING) {
        Sleep(16);
        alGetSourcei(uiSource, AL_SOURCE_STATE, &iState);
      }

      alSourceStop(uiSource);
      alSourcei(uiSource, AL_BUFFER, 0);

      alDeleteSources(1, &uiSource);
      alDeleteBuffers(1, uiBuffers);

      me->occupied = false;
      me->sound = 0;
    }
    if(me->running) SuspendThread(me->handle);
  }
  return 0;
}
static void prvProcessSimulatedInterrupts( void )
{
unsigned long ulSwitchRequired, i;
xThreadState *pxThreadState;
void *pvObjectList[ 2 ];

	/* Going to block on the mutex that ensured exclusive access to the simulated 
	interrupt objects, and the event that signals that a simulated interrupt
	should be processed. */
	pvObjectList[ 0 ] = pvInterruptEventMutex;
	pvObjectList[ 1 ] = pvInterruptEvent;

	for(;;)
	{
		WaitForMultipleObjects( sizeof( pvObjectList ) / sizeof( void * ), pvObjectList, TRUE, INFINITE );

		/* Used to indicate whether the simulated interrupt processing has
		necessitated a context switch to another task/thread. */
		ulSwitchRequired = pdFALSE;

		/* For each interrupt we are interested in processing, each of which is
		represented by a bit in the 32bit ulPendingInterrupts variable. */
		for( i = 0; i < portMAX_INTERRUPTS; i++ )
		{
			/* Is the simulated interrupt pending? */
			if( ulPendingInterrupts & ( 1UL << i ) )
			{
				/* Is a handler installed? */
				if( ulIsrHandler[ i ] != NULL )
				{
					/* Run the actual handler. */
					if( ulIsrHandler[ i ]() != pdFALSE )
					{
						ulSwitchRequired |= ( 1 << i );
					}
				}

				/* Clear the interrupt pending bit. */
				ulPendingInterrupts &= ~( 1UL << i );
			}
		}

		if( ulSwitchRequired != pdFALSE )
		{
			void *pvOldCurrentTCB;

			pvOldCurrentTCB = pxCurrentTCB;

			/* Select the next task to run. */
			vTaskSwitchContext();

			/* If the task selected to enter the running state is not the task
			that is already in the running state. */
			if( pvOldCurrentTCB != pxCurrentTCB )
			{
				/* Suspend the old thread. */
				pxThreadState = ( xThreadState *) *( ( unsigned long * ) pvOldCurrentTCB );

				if( ( ulSwitchRequired & ( 1 << portINTERRUPT_DELETE_THREAD ) ) != pdFALSE )
				{
					TerminateThread( pxThreadState->pvThread, 0 );
				}
				else
				{
					SuspendThread( pxThreadState->pvThread );
				}							

				/* Obtain the state of the task now selected to enter the 
				Running state. */
				pxThreadState = ( xThreadState * ) ( *( unsigned long *) pxCurrentTCB );
				ResumeThread( pxThreadState->pvThread );
			}
		}

		ReleaseMutex( pvInterruptEventMutex );
	}
}
Example #6
0
/*
 * ThreadCtlProc
 */
BOOL CALLBACK ThreadCtlProc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
{
    WORD                cmd;
    ThreadCtlInfo       *info;
    LRESULT             index;
    char                buf[200];
    DWORD               threadid;
    ThreadNode          *thread;
    ProcNode            *process;
    DWORD               susp_cnt;
    DWORD               rc;
    char                *action;

    info = (ThreadCtlInfo *)GET_DLGDATA( hwnd );
    switch( msg ) {
    case WM_INITDIALOG:
        info = MemAlloc( sizeof( ThreadCtlInfo ) );
        if( !GetProcessInfo( lparam, &info->procinfo ) ) {
             RCsprintf( buf, STR_CANT_GET_PROC_INFO, info->procid );
             MessageBox( hwnd, buf, AppName, MB_OK | MB_ICONEXCLAMATION );
             SendMessage( hwnd, WM_CLOSE, 0, 0 );
        }
        info->procid = lparam;
        ThreadDlg = hwnd;
        SET_DLGDATA( hwnd, info );
        fillThreadCtl( hwnd, &info->procinfo, buf );
        RCsprintf( buf, STR_THREAD_4_PROC_X, lparam );
        SetDlgItemText( hwnd, THREAD_PROC_NAME, buf );
        sprintf( buf, "(%s)", info->procinfo.name );
        SetDlgItemText( hwnd, THREAD_PROC_PATH, buf );
        SendDlgItemMessage( hwnd, THREAD_LIST, LB_SETCURSEL, 0, 0L );
        index = SendDlgItemMessage( hwnd, THREAD_LIST, LB_GETCURSEL, 0, 0L );
        if( index != LB_ERR ) {
            enableChoices( hwnd, TRUE );
        }
        fillThreadInfo( hwnd, &info->procinfo );
        break;
    case WM_COMMAND:
        cmd = LOWORD( wparam );
        if( cmd == THREAD_SUSPEND || cmd == THREAD_RESUME ||
            cmd == THREAD_KILL || cmd == THREAD_SET_PRIORITY ) {
            index = SendDlgItemMessage( hwnd, THREAD_LIST, LB_GETCURSEL, 0, 0L );
            if( index == LB_ERR ) {
                RCMessageBox( hwnd, STR_NO_SELECTED_THREAD, AppName, MB_OK | MB_ICONEXCLAMATION );
                break;
            }
            SendDlgItemMessage( hwnd, THREAD_LIST, LB_GETTEXT, (WPARAM)index, (LPARAM)(LPSTR)buf );
            threadid = getThreadId( buf );
            process = FindProcess( info->procinfo.pid );
            thread = FindThread( process, threadid );
        }
        switch( cmd ) {
        case IDOK:
            SendMessage( hwnd, WM_CLOSE, 0, 0L );
            break;
        case THREAD_REFRESH:
            RefreshInfo();
            if( GetProcessInfo( info->procid, &info->procinfo ) ) {
                fillThreadCtl( hwnd, &info->procinfo, buf );
                fillThreadInfo( hwnd, &info->procinfo );
            } else {
                action = AllocRCString( STR_REFRESH );
                RCMessageBox( hwnd, STR_CANT_REFRESH_THRD, action,
                              MB_OK | MB_ICONEXCLAMATION );
                FreeRCString( action );
            }
            break;
        case THREAD_SUSPEND:
            action = AllocRCString( STR_THREAD_SUSPEND );
            if( thread == NULL ) {
                RCsprintf( buf, STR_CANT_GET_HDL_4_THD_X, threadid );
                MessageBox( hwnd, buf, action, MB_OK | MB_ICONEXCLAMATION );
            } else {
                susp_cnt = SuspendThread( thread->threadhdl );
                if( susp_cnt == -1 ) {
                    RCsprintf( buf, STR_CANT_SUSPEND_THRD_X, threadid );
                    MessageBox( hwnd, buf, action, MB_ICONQUESTION | MB_OK );
                } else if( susp_cnt > 0 ) {
                    RCsprintf( buf, STR_THREAD_ALREADY_SUSP, threadid, susp_cnt );
                    index = MessageBox( hwnd, buf, action, MB_ICONQUESTION | MB_YESNO );
                    if( index == IDNO ) {
                        ResumeThread( thread->threadhdl );
                    }
                }
                SendMessage( hwnd, WM_COMMAND, THREAD_REFRESH, 0L );
            }
            FreeRCString( action );
            break;
        case THREAD_RESUME:
            action = AllocRCString( STR_RESUME );
            if( thread == NULL ) {
                RCsprintf( buf, STR_THREAD_NOT_RESUMED , threadid );
                MessageBox( hwnd, buf, action, MB_OK | MB_ICONEXCLAMATION );
            } else {
                susp_cnt = ResumeThread( thread->threadhdl );
                if( susp_cnt == -1 ) {
                    RCsprintf( buf, STR_CANT_RESUME_THRD_X, threadid );
                    MessageBox( hwnd, buf, action,
                                MB_ICONEXCLAMATION | MB_OK );
                } else if( susp_cnt == 0 ) {
                    RCsprintf( buf, STR_THRD_IS_NOT_SUSP, threadid );
                    MessageBox( hwnd, buf, action,
                                MB_ICONEXCLAMATION | MB_OK );
                } else if( susp_cnt > 1 ) {
                    RCsprintf( buf, STR_SUSP_COUNT_DECREMENTED,
                                threadid, susp_cnt );
                    MessageBox( hwnd, buf, action,
                                MB_ICONEXCLAMATION | MB_OK );
                }
                SendMessage( hwnd, WM_COMMAND, THREAD_REFRESH, 0L );
            }
            FreeRCString( action );
            break;
        case THREAD_KILL:
            action = AllocRCString( STR_KILL );
            if( thread == NULL ) {
                RCsprintf( buf, STR_THRD_NOT_TERMINATED, threadid );
                MessageBox( hwnd, buf, action, MB_OK | MB_ICONEXCLAMATION );
            } else if( GetRetCode( hwnd, RETCD_THREAD, thread->threadid, &rc ) ) {
                if( !TerminateThread( thread->threadhdl, rc ) ) {
                    RCsprintf( buf, STR_CANT_KILL_THRD_X, threadid );
                    MessageBox( hwnd, buf, action,
                                MB_OK | MB_ICONEXCLAMATION );
                }
                SendMessage( hwnd, WM_COMMAND, THREAD_REFRESH, 0L );
            }
            FreeRCString( action );
            break;
        case THREAD_SET_PRIORITY:
//          {
//              ThreadPriorityInfo      prinfo;
//
//              if( thread == NULL ) {
//                  sprintf( buf, "Unable to get a handle for thread %08X.\n",
//                           threadid );
//                  MessageBox( hwnd, buf, "Set Priority",
//                              MB_OK | MB_ICONEXCLAMATION );
//              } else {
//                  prinfo.procid = info->procid;
//                  prinfo.thread = thread;
//                  prinfo.priority = GetThreadPriority( thread->threadhdl );
//                  prinfo.procinfo = &info->procinfo;
//                  DialogBoxParam( Instance, "THREAD_PRIORITY_DLG", hwnd,
//                                  ThreadPriorityDlgProc, (DWORD)&prinfo );
//                  fillThreadInfo( hwnd, &info->procinfo );
//              }
//          }
//          break;
        case THREAD_LIST:
            if( HIWORD( wparam ) == LBN_SELCHANGE ) {
                fillThreadInfo( hwnd, &info->procinfo );
            }
            break;
        }
        break;
    case DR_TASK_LIST_CHANGE:
        /* make sure this process still exists */
//here  if( FindProcess( info->procid ) == NULL ) {
//here      SendDlgItemMessage( hwnd, THREAD_LIST, LB_RESETCONTENT, 0, 0L );
//here      enableChoices( hwnd, FALSE );
//here      info->proc = NULL;
//here  } else {
//here      fillThreadCtl( hwnd, info->proc, buf );
//here  }
        break;
    case WM_CLOSE:
        EndDialog( hwnd, 0 );
        break;
    case WM_DESTROY:
        MemFree( info );
        ThreadDlg = NULL;
        break;
    default:
        return( FALSE );
    }
    return( TRUE );
}
Example #7
0
File: ssq.c Project: mpapierski/ssq
BOOL WINAPI SSQ_SetLogStatus(BOOL status,USHORT port)
{
	static LPADDRINFO response;
	static char hostname[64];

	if(status==log_status||HIWORD(Callback)==0||ssq_is_initialized==FALSE)
	{
		SSQ_OutputDebugString(EXTERNAL_SSQ_SET_LOG_STATUS,0,1,0);

		return FALSE;
	}	
	else if(GetExitCodeThread(handle_log_thread,&exit_code_log_thread)==FALSE)
	{
		SSQ_OutputDebugString(EXTERNAL_SSQ_SET_LOG_STATUS,0,1,(DWORD)GetExitCodeThread);

		return FALSE;
	}
	else if(exit_code_log_thread!=STILL_ACTIVE)
	{
		handle_log_thread = CreateThread(0,0,SSQ_LogThread,0,CREATE_SUSPENDED,&identifier_log_thread);

		if(handle_log_thread==0)
		{
			SSQ_OutputDebugString(EXTERNAL_SSQ_SET_LOG_STATUS,0,1,(DWORD)CreateThread);

			return FALSE;
		}
	}

	if(status==TRUE)
	{
		if(gethostname(hostname,sizeof(hostname))==SOCKET_ERROR)
		{
			SSQ_OutputDebugString(EXTERNAL_SSQ_SET_LOG_STATUS,1,1,(DWORD)gethostname);

			return FALSE;
		}
		else if(getaddrinfo(hostname,0,0,&response)!=0)
		{
			SSQ_OutputDebugString(EXTERNAL_SSQ_SET_LOG_STATUS,1,1,(DWORD)getaddrinfo);

			return FALSE;
		}
		else if(closesocket(ssq_socket[SSQ_UDP_LOG])==SOCKET_ERROR)
		{
			SSQ_OutputDebugString(EXTERNAL_SSQ_SET_LOG_STATUS,1,1,(DWORD)closesocket);

			return FALSE;
		}

		ssq_socket[SSQ_UDP_LOG] = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);

		if(ssq_socket[SSQ_UDP_LOG]==INVALID_SOCKET)
		{
			SSQ_OutputDebugString(EXTERNAL_SSQ_SET_LOG_STATUS,1,1,(DWORD)socket);

			return FALSE;
		}

		((PSOCKADDR_IN)response->ai_addr)->sin_port = htons(port);

		if(bind(ssq_socket[SSQ_UDP_LOG],response->ai_addr,sizeof(*response->ai_addr))==SOCKET_ERROR)
		{
			SSQ_OutputDebugString(EXTERNAL_SSQ_SET_LOG_STATUS,1,1,(DWORD)bind);

			return FALSE;
		}

		freeaddrinfo(response);

		if(ResumeThread(handle_log_thread)==0xFFFFFFFF)
		{
			SSQ_OutputDebugString(EXTERNAL_SSQ_SET_LOG_STATUS,0,1,(DWORD)ResumeThread);

			return FALSE;
		}

		log_status = TRUE;
	}
	else if(status==FALSE)
	{
		if(SuspendThread(handle_log_thread)==0xFFFFFFFF)
		{
			SSQ_OutputDebugString(EXTERNAL_SSQ_SET_LOG_STATUS,0,1,(DWORD)SuspendThread);

			return FALSE;
		}

		log_status = FALSE;
	}
	else
	{
		SSQ_OutputDebugString(EXTERNAL_SSQ_SET_LOG_STATUS,0,1,0);

		return FALSE;
	}

	return TRUE;
}
Example #8
0
void CThread::Suspend()
{
	SuspendThread(m_hThread);
}
/** Print out a stacktrace. */
static void Stacktrace(const char *threadName, LPEXCEPTION_POINTERS e, HANDLE hThread = INVALID_HANDLE_VALUE)
{
	PIMAGEHLP_SYMBOL pSym;
	STACKFRAME sf;
	HANDLE process, thread;
	DWORD dwModBase, Disp, dwModAddrToPrint;
	BOOL more = FALSE;
	int count = 0;
	char modname[MAX_PATH];

	process = GetCurrentProcess();

	if(threadName)
		PRINT("Stacktrace (%s):", threadName);
	else
		PRINT("Stacktrace:");

	bool suspended = false;
	CONTEXT c;
	if (e) {
		c = *e->ContextRecord;
		thread = GetCurrentThread();
	} else {
		SuspendThread(hThread);
		suspended = true;
		memset(&c, 0, sizeof(CONTEXT));
		c.ContextFlags = CONTEXT_FULL;
		// FIXME: This does not work if you want to dump the current thread's stack
		if (!GetThreadContext(hThread, &c)) {
			ResumeThread(hThread);
			return;
		}
		thread = hThread;
	}
	ZeroMemory(&sf, sizeof(sf));
	sf.AddrPC.Offset = c.Eip;
	sf.AddrStack.Offset = c.Esp;
	sf.AddrFrame.Offset = c.Ebp;
	sf.AddrPC.Mode = AddrModeFlat;
	sf.AddrStack.Mode = AddrModeFlat;
	sf.AddrFrame.Mode = AddrModeFlat;

	// use globalalloc to reduce risk for allocator related deadlock
	pSym = (PIMAGEHLP_SYMBOL)GlobalAlloc(GMEM_FIXED, 16384);
	char* printstrings = (char*)GlobalAlloc(GMEM_FIXED, 0);

	bool containsOglDll = false;
	while (true) {
		more = StackWalk(
			IMAGE_FILE_MACHINE_I386, // TODO: fix this for 64 bit windows?
			process,
			thread,
			&sf,
			&c,
			NULL,
			SymFunctionTableAccess,
			SymGetModuleBase,
			NULL
		);
		if (!more || sf.AddrFrame.Offset == 0 || count > MAX_STACK_DEPTH) {
			break;
		}

		dwModBase = SymGetModuleBase(process, sf.AddrPC.Offset);

		if (dwModBase) {
			GetModuleFileName((HINSTANCE)dwModBase, modname, MAX_PATH);
		} else {
			strcpy(modname, "Unknown");
		}

		pSym->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL);
		pSym->MaxNameLength = MAX_PATH;

		char* printstringsnew = (char*) GlobalAlloc(GMEM_FIXED, (count + 1) * BUFFER_SIZE);
		memcpy(printstringsnew, printstrings, count * BUFFER_SIZE);
		GlobalFree(printstrings);
		printstrings = printstringsnew;

		if (SymGetSymFromAddr(process, sf.AddrPC.Offset, &Disp, pSym)) {
			// This is the code path taken on VC if debugging syms are found.
			SNPRINTF(printstrings + count * BUFFER_SIZE, BUFFER_SIZE, "(%d) %s(%s+%#0lx) [0x%08lX]", count, modname, pSym->Name, Disp, sf.AddrPC.Offset);
		} else {
			// This is the code path taken on MinGW, and VC if no debugging syms are found.
			if (strstr(modname, ".exe")) {
				// for the .exe, we need the absolute address
				dwModAddrToPrint = sf.AddrPC.Offset;
			} else {
				// for DLLs, we need the module-internal/relative address
				dwModAddrToPrint = sf.AddrPC.Offset - dwModBase;
			}
			SNPRINTF(printstrings + count * BUFFER_SIZE, BUFFER_SIZE, "(%d) %s [0x%08lX]", count, modname, dwModAddrToPrint);
		}

		// OpenGL lib names (ATI): "atioglxx.dll" "atioglx2.dll"
		containsOglDll = containsOglDll || strstr(modname, "atiogl");
		// OpenGL lib names (Nvidia): "nvoglnt.dll" "nvoglv32.dll" "nvoglv64.dll" (last one is a guess)
		containsOglDll = containsOglDll || strstr(modname, "nvogl");
		// OpenGL lib names (Intel): "ig4dev32.dll" "ig4dev64.dll"
		containsOglDll = containsOglDll || strstr(modname, "ig4dev");

		++count;
	}

	if (suspended) {
		ResumeThread(hThread);
	}

	if (containsOglDll) {
		PRINT("This stack trace indicates a problem with your graphic card driver. "
		      "Please try upgrading or downgrading it. "
		      "Specifically recommended is the latest driver, and one that is as old as your graphic card. "
		      "Make sure to use a driver removal utility, before installing other drivers.");
	}

	for (int i = 0; i < count; ++i) {
		PRINT("%s", printstrings + i * BUFFER_SIZE);
	}

	GlobalFree(printstrings);
	GlobalFree(pSym);
}
Example #10
0
DWORD PALAPI SuspenderThread()
{
    HANDLE targetThread;
    DWORD ret;
    int i,j,idx,jdx;

    printf("[Suspender Thread] Starting\n");

    while (!g_bDone)
    {
        jdx = rand()%2;
        for (j=0; j<2; j++, jdx++)
        {
            switch(jdx % 2)
            {
            case 0:
            {
                idx = rand() % g_lCurrentExecutingThreadCount;
                for (i=0; i < g_lCurrentExecutingThreadCount; i++)
                {
                    targetThread = g_rghExecutingThread[idx];
                    if (NULL != targetThread)
                    {
                        ret = SuspendThread(targetThread);
                        if (-1 != ret)
                        {
                            g_lSuspCount += 1;
                        }
                        else
                        {
                            g_lSuspFailCount += 1;
                        }
                    }
                    idx = (idx+1) % g_lCurrentExecutingThreadCount;
                }
                break;
            }
            case 1:
            default:
            {
                idx = rand() % g_lPostingThreadCount;
                for (i=0; i < g_lPostingThreadCount; i++)
                {
                    targetThread = g_rghPostingThread[idx];
                    if (NULL != targetThread)
                    {
                        ret = SuspendThread(targetThread);
                        if (-1 != ret)
                        {
                            g_lSuspCount += 1;
                        }
                        else
                        {
                            g_lSuspFailCount += 1;
                        }
                    }
                    idx = (idx+1) % g_lPostingThreadCount;
                }
                break;
            }
            }
        }

        Sleep(rand() % 100);

        jdx = rand() % 2;
        for (j=0; j<2; j++, jdx++)
        {
            switch(jdx % 2)
            {
            case 0:
            {
                idx = rand() % g_lCurrentExecutingThreadCount;
                for (i=0; i < g_lCurrentExecutingThreadCount; i++)
                {
                    targetThread = g_rghExecutingThread[idx];
                    if (NULL != targetThread)
                    {
                        ret = ResumeThread(targetThread);
                        if (-1 != ret)
                        {
                            g_lResumeCount += 1;
                        }
                        else
                        {
                            g_lResumeFailCount += 1;
                        }
                    }
                    idx = (idx+1) % g_lCurrentExecutingThreadCount;
                }
                break;
            }
            case 1:
            default:
            {
                idx = rand() % g_lPostingThreadCount;
                for (i=0; i < g_lPostingThreadCount; i++)
                {
                    targetThread = g_rghPostingThread[idx];
                    if (NULL != targetThread)
                    {
                        ret = ResumeThread(targetThread);
                        if (-1 != ret)
                        {
                            g_lResumeCount += 1;
                        }
                        else
                        {
                            g_lResumeFailCount += 1;
                        }
                    }
                    idx = (idx+1) % g_lPostingThreadCount;
                }
                break;
            }
            }
        }

        Sleep(rand() % 100);
    }

    printf("[Suspender Thread] Done\n");

    return 0;
}
Example #11
0
void cThreadWrapper::Suspend()
{
	m_dwThreadSuspendCount = SuspendThread(m_hThreadHandle);
}
Example #12
0
File: port.c Project: HclX/freertos
static void prvProcessSimulatedInterrupts( void )
{
uint32_t ulSwitchRequired, i;
xThreadState *pxThreadState;
void *pvObjectList[ 2 ];
CONTEXT xContext;

	/* Going to block on the mutex that ensured exclusive access to the simulated
	interrupt objects, and the event that signals that a simulated interrupt
	should be processed. */
	pvObjectList[ 0 ] = pvInterruptEventMutex;
	pvObjectList[ 1 ] = pvInterruptEvent;

	/* Create a pending tick to ensure the first task is started as soon as
	this thread pends. */
	ulPendingInterrupts |= ( 1 << portINTERRUPT_TICK );
	SetEvent( pvInterruptEvent );

	xPortRunning = pdTRUE;

	for(;;)
	{
		WaitForMultipleObjects( sizeof( pvObjectList ) / sizeof( void * ), pvObjectList, TRUE, INFINITE );

		/* Used to indicate whether the simulated interrupt processing has
		necessitated a context switch to another task/thread. */
		ulSwitchRequired = pdFALSE;

		/* For each interrupt we are interested in processing, each of which is
		represented by a bit in the 32bit ulPendingInterrupts variable. */
		for( i = 0; i < portMAX_INTERRUPTS; i++ )
		{
			/* Is the simulated interrupt pending? */
			if( ulPendingInterrupts & ( 1UL << i ) )
			{
				/* Is a handler installed? */
				if( ulIsrHandler[ i ] != NULL )
				{
					/* Run the actual handler. */
					if( ulIsrHandler[ i ]() != pdFALSE )
					{
						ulSwitchRequired |= ( 1 << i );
					}
				}

				/* Clear the interrupt pending bit. */
				ulPendingInterrupts &= ~( 1UL << i );
			}
		}

		if( ulSwitchRequired != pdFALSE )
		{
			void *pvOldCurrentTCB;

			pvOldCurrentTCB = pxCurrentTCB;

			/* Select the next task to run. */
			vTaskSwitchContext();

			/* If the task selected to enter the running state is not the task
			that is already in the running state. */
			if( pvOldCurrentTCB != pxCurrentTCB )
			{
				/* Suspend the old thread. */
				pxThreadState = ( xThreadState *) *( ( size_t * ) pvOldCurrentTCB );
				SuspendThread( pxThreadState->pvThread );

				/* Ensure the thread is actually suspended by performing a 
				synchronous operation that can only complete when the thread is 
				actually suspended.  The below code asks for dummy register
				data. */
				xContext.ContextFlags = CONTEXT_INTEGER;
				( void ) GetThreadContext( pxThreadState->pvThread, &xContext );

				/* Obtain the state of the task now selected to enter the
				Running state. */
				pxThreadState = ( xThreadState * ) ( *( size_t *) pxCurrentTCB );
				ResumeThread( pxThreadState->pvThread );
			}
		}

		ReleaseMutex( pvInterruptEventMutex );
	}
}
DWORD demoSuspendInjectResume(PCWSTR pszLibFile, DWORD dwProcessId)
{
	void *stub;
	unsigned long threadID, oldIP, oldprot;
	HANDLE hThread;
	CONTEXT ctx;

	DWORD stubLen = sizeof(sc);

	HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
	if (hProcess == NULL)
	{
		wprintf(L"[-] Error: Could not open process for PID (%d).\n", dwProcessId);
		return(1);
	}
	DWORD LoadLibraryAddress = (DWORD)GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryW");
	if (LoadLibraryAddress == NULL)
	{
		wprintf(L"[-] Error: Could not find LoadLibraryA function inside kernel32.dll library.\n");
		exit(1);
	}

	SIZE_T dwSize = (wcslen(pszLibFile) + 1) * sizeof(wchar_t);

	LPVOID lpDllAddr = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); 
	if (lpDllAddr == NULL)
	{
		wprintf(L"[-] Error: Could not allocate memory inside PID (%d).\n", dwProcessId);
		exit(1);
	}

	stub = VirtualAllocEx(hProcess, NULL, stubLen, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
	if (stub == NULL)
	{
		wprintf(L"[-] Error: Could not allocate memory for stub.\n");
		exit(1);
	}

	BOOL bStatus = WriteProcessMemory(hProcess, lpDllAddr, pszLibFile, dwSize, NULL);
	if (bStatus == 0)
	{
		wprintf(L"[-] Error: Could not write any bytes into the PID (%d) address space.\n", dwProcessId);
		return(1);
	}

	threadID = getThreadID(dwProcessId);
	hThread = OpenThread((THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME), false, threadID);
	if (hThread != NULL)
	{
		SuspendThread(hThread);
	}
	else
		printf("could not open thread\n");

	ctx.ContextFlags = CONTEXT_CONTROL;
	GetThreadContext(hThread, &ctx);
	oldIP = ctx.Eip;
	ctx.Eip = (DWORD)stub;
	ctx.ContextFlags = CONTEXT_CONTROL;

	VirtualProtect(sc, stubLen, PAGE_EXECUTE_READWRITE, &oldprot);
	memcpy((void *)((unsigned long)sc + 1), &oldIP, 4);
	memcpy((void *)((unsigned long)sc + 8), &lpDllAddr, 4);
	memcpy((void *)((unsigned long)sc + 13), &LoadLibraryAddress, 4);

	WriteProcessMemory(hProcess, stub, sc, stubLen, NULL);
	SetThreadContext(hThread, &ctx);

	ResumeThread(hThread);

	Sleep(8000);

	VirtualFreeEx(hProcess, lpDllAddr, dwSize, MEM_DECOMMIT);
	VirtualFreeEx(hProcess, stub, stubLen, MEM_DECOMMIT);
	CloseHandle(hProcess);
	CloseHandle(hThread);

	return(0);
}
DWORD demoSuspendInjectResume64(PCWSTR pszLibFile, DWORD dwProcessId)
{
	void *stub;
	unsigned long threadID, oldprot;
	HANDLE hThread;
	CONTEXT ctx;

	DWORD64 stubLen = sizeof(sc);
	wprintf(TEXT("[+] Shellcode Length is: %d\n"), stubLen);

	HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
	if (hProcess == NULL)
	{
		wprintf(L"[-] Error: Could not open process for PID (%d).\n", dwProcessId);
		return(1);
	}

	DWORD64 LoadLibraryAddress = (DWORD64)GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryW");
	if (LoadLibraryAddress == NULL)
	{
		wprintf(L"[-] Error: Could not find LoadLibraryA function inside kernel32.dll library.\n");
		exit(1);
	}

	SIZE_T dwSize = (wcslen(pszLibFile) + 1) * sizeof(wchar_t);

	LPVOID lpDllAddr = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
	if (lpDllAddr == NULL)
	{
		wprintf(L"[-] Error: Could not allocate memory inside PID (%d).\n", dwProcessId);
		exit(1);
	}

	stub = VirtualAllocEx(hProcess, NULL, stubLen, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
	if (stub == NULL)
	{
		wprintf(L"[-] Error: Could not allocate memory for stub.\n");
		exit(1);
	}

	SIZE_T nBytesWritten = 0;
	BOOL bStatus = WriteProcessMemory(hProcess, lpDllAddr, pszLibFile, dwSize, &nBytesWritten);
	if (bStatus == 0)
	{
		wprintf(L"[-] Error: Could not write any bytes into the PID (%d) address space.\n", dwProcessId);
		return(1);
	}
	if (nBytesWritten != dwSize)
		wprintf(TEXT("[-] Something is wrong!\n"));

	threadID = getThreadID(dwProcessId);
	hThread = OpenThread((THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME), false, threadID);
	if (hThread != NULL)
	{
		SuspendThread(hThread);
	}
	else
		wprintf(L"[-] Could not open thread\n");

	ctx.ContextFlags = CONTEXT_CONTROL;
	GetThreadContext(hThread, &ctx);

	DWORD64 oldIP = ctx.Rip;
	ctx.Rip = (DWORD64)stub;
	ctx.ContextFlags = CONTEXT_CONTROL;

	memcpy(sc + 3, &oldIP, sizeof(oldIP));
	memcpy(sc + 41, &lpDllAddr, sizeof(lpDllAddr));
	memcpy(sc + 51, &LoadLibraryAddress, sizeof(LoadLibraryAddress));

#ifdef _DEBUG
	wprintf(TEXT("[+] Shellcode Launcher Code:\n\t"));
	for (int i = 0; i < stubLen; i++)
		wprintf(TEXT("%02x "), sc[i]);
	wprintf(TEXT("\n"));
#endif

	WriteProcessMemory(hProcess, (void *)stub, &sc, stubLen, NULL);

	SetThreadContext(hThread, &ctx);
	ResumeThread(hThread);

	Sleep(8000);

	VirtualFreeEx(hProcess, lpDllAddr, dwSize, MEM_DECOMMIT);
	VirtualFreeEx(hProcess, stub, stubLen, MEM_DECOMMIT);
	CloseHandle(hProcess);
	CloseHandle(hThread);

	return(0);
}
Example #15
0
__declspec (dllexport) DWORD
QueueUserAPCEx(PAPCFUNC pfnApc, HANDLE hThread, DWORD dwData)
     /*
      * ------------------------------------------------------
      * DOCPUBLIC
      *      Adds a user-mode asynchronous procedure call (APC) object
      *      to the APC queue of the specified thread AND sets this
      *      thread in alertarte state.
      *
      * PARAMETERS
      *      Uses the same parameters as QueueUserAPC.
      *
      * DESCRIPTION
      *      Adds a user-mode asynchronous procedure call (APC) object
      *      to the APC queue of the specified thread AND sets this
      *      thread in alertarte state.
      *
      * RESULTS
	  *		 1    Success
	  *      0    Failure
      * ------------------------------------------------------
      */
{
  DWORD cbReturned;

  /* trivial case */
  if (hThread == GetCurrentThread())
    {
      if (!QueueUserAPC(pfnApc, hThread, dwData))
        {
	      return 0;
        }

      SleepEx(0, TRUE);
      return 1;
    }

  if (INVALID_HANDLE_VALUE == hDevice
      /* && !QueueUserAPCEx_Init() */
      )
    {
      return 0;
    }

  /* probably not necessary */
  if (SuspendThread(hThread) == -1)
    {
      return 0;
    }

  /* Send the APC */
  if (!QueueUserAPC(pfnApc, hThread, dwData))
    {
      return 0;
    }

  /* Ensure the execution of the APC */
  if (DeviceIoControl (hDevice, (DWORD)IOCTL_ALERTDRV_SET_ALERTABLE2, &hThread, sizeof(HANDLE),
		NULL, 0, &cbReturned, 0))
    {
	}
  else
    {
      return 0;
    }

  /* Here, we could even cancel suspended threads */
  ResumeThread(hThread);

  return 1;
}
Example #16
0
 void Thread::suspend()
 {
   assert(handle); // Thread object is null
   int ret = SuspendThread(handle);
   assert(ret >= 0); // Failed to suspend thread
 }
Example #17
0
tb_bool_t tb_thread_suspend(tb_thread_ref_t thread)
{
    if (thread) return ((DWORD)-1 != SuspendThread((HANDLE)thread))? tb_true : tb_false;
    return tb_false;
}
Example #18
0
void cThread::Suspend()
{
	SuspendThread(hThread);
}
Example #19
0
File: myfork.c Project: 0x7678/zzuf
static int dll_inject(PROCESS_INFORMATION *pinfo, char const *lib)
{
#ifdef  _M_AMD64
#   define InstructionPointer   Rip
#   define StackPointer         Rsp
#   define LoaderRegister       Rcx
#   define LoadLibraryAOffset   0x15

    /* This payload allows us to load arbitrary module located
     * at the end of this buffer */
    static uint8_t const loader[] =
    {
        "\x55"                          /* push rbp              */
        "\x48\x89\xE5"                  /* mov rbp,rsp           */
        "\x48\x83\xEC\x20"              /* sub rsp,byte +0x20    */
        "\x48\x83\xE4\xF0"              /* and rsp,byte -0x10    */
        "\x48\x8D\x0D\x14\x00\x00\x00"  /* lea rcx,[rel 0x27]    */
        "\x48\xB8________"              /* mov rax, LoadLibraryA */
        "\xFF\xD0"                      /* call rax              */
        "\x48\x85\xC0"                  /* test rax,rax          */
        "\x75\x01"                      /* jnz 0x25              */
        "\xCC"                          /* int3                  */
        "\xC9"                          /* leave                 */
        "\xC3"                          /* ret                   */
    };

#elif defined (_M_IX86)
#   define InstructionPointer   Eip
#   define StackPointer         Esp
#   define LoaderRegister       Eax /* It seems the Windows loader store the oep as the first param
                                     * but by a side effect it's also contained in eax register */
#   define loader               loader32
#   define LoadLibraryAOffset   0x04

    /* This payload allows us to load arbitrary module located
     * at the end of this buffer */
    static uint8_t const loader[] =
    {
        "\x60"                  /* pushad               */
        "\xEB\x0E"              /* jmp short 0x11       */
        "\xB8____"              /* mov eax,LoadLibraryA */
        "\xFF\xD0"              /* call eax             */
        "\x85\xC0"              /* test eax,eax         */
        "\x75\x01"              /* jnz 0xf              */
        "\xCC"                  /* int3                 */
        "\x61"                  /* popad                */
        "\xC3"                  /* ret                  */
        "\xE8\xED\xFF\xFF\xFF"  /* call dword 0x3       */
    };
#else
#   error Unimplemented architecture !
#endif

    /* We use this code to make the targeted process wait for us */
    static uint8_t const wait[] = "\xeb\xfe"; /* jmp $-1 */
    size_t wait_len = sizeof(wait) - 1;

    void *process = pinfo->hProcess;
    void *thread = pinfo->hThread;
    SIZE_T written = 0;
    BOOL tmp;

    /* Payload */
    size_t payload_len = sizeof(loader) - 1 + strlen(lib) + 1;
    uint8_t *payload = malloc(payload_len);
    if (payload == NULL)
        goto error;

    /* Use the main thread to inject our library */
    CONTEXT ctxt;
    ctxt.ContextFlags = CONTEXT_FULL;
    if (!GetThreadContext(thread, &ctxt))
        goto error;

    /* Make the target program wait when it reaches the original entry
     * point, because we can't do many thing from the Windows loader */

    DWORD_PTR oep = ctxt.LoaderRegister; /* Original Entry Point */
    uint8_t orig_data[2];
    tmp = ReadProcessMemory(process, (LPVOID)oep, orig_data,
                            sizeof(orig_data), &written);
    if (!tmp || written != sizeof(orig_data))
        goto error; /* save original opcode */

    tmp = WriteProcessMemory(process, (LPVOID)oep, wait, wait_len, &written);
    if (!tmp || written != wait_len)
        goto error; /* write jmp short $-1 */
    if (!FlushInstructionCache(process, (LPVOID)oep, wait_len))
        goto error;
    if (ResumeThread(thread) == (DWORD)-1)
        goto error;

    /* Stop when the program reachse the oep */
    while (oep != ctxt.InstructionPointer)
    {
        if (!GetThreadContext(thread, &ctxt))
            goto error;
        Sleep(10);
    }

    if (SuspendThread(thread) == (DWORD)-1)
        goto error;

    /* Resolve LoadLibraryA from the target process memory context */
    DWORD pid = pinfo->dwProcessId;
    void *rldlib = get_proc_address(process, pid, "LoadLibraryA");
    if (rldlib == NULL)
        goto error;

    void *rpl = VirtualAllocEx(process, NULL, payload_len,
                               MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    if (rpl == NULL)
        goto error;

    /* Emulate a call to the loader code, thus the ret instruction from
     * loader will get (e|r)ip back to the original entry point */
    ctxt.StackPointer -= sizeof(oep);
    tmp = WriteProcessMemory(process, (LPVOID)ctxt.StackPointer,
                             &oep, sizeof(oep), &written);
    if (!tmp || written != sizeof(oep))
        goto error;
    ctxt.InstructionPointer = (DWORD_PTR)rpl;
    if (!SetThreadContext(thread, &ctxt))
        goto error;

    /* Forge the payload */
    memcpy(payload, loader, sizeof(loader) - 1);
    /* Write the address of LoadLibraryA */
    memcpy(payload + LoadLibraryAOffset, &rldlib, sizeof(rldlib));
    /* Write the first parameter of LoadLibraryA */
    strcpy((char *)(payload + sizeof(loader) - 1), lib);

    tmp = WriteProcessMemory(process, rpl, payload, payload_len, &written);
    if (!tmp || written != payload_len)
        goto error;

    /* Restore original opcode */
    tmp = WriteProcessMemory(process, (LPVOID)oep, orig_data,
                             sizeof(orig_data), &written);
    if (!tmp || written != sizeof(orig_data))
        goto error;

    if (!FlushInstructionCache(process, rpl, payload_len))
        goto error;
    if (!FlushInstructionCache(process, (LPVOID)oep, sizeof(orig_data)))
        goto error;

    /* We must not free remote allocated memory since they will be used
     * after the process will be resumed */
    free(payload);
    return 0;

error:
    free(payload);
    return -1;
}
Example #20
0
void opzThread::Suspend()
{
	SuspendThread(_hThread);
}
Example #21
0
/* 
 * Main Test Case worker thread which will suspend and resume all other worker threads
 */
DWORD
PALAPI 
suspendandresumethreads( LPVOID lpParam )
{
       
	unsigned int loopcount = REPEAT_COUNT;
	int Id=(int)lpParam;
	unsigned int i,j,k;
	DWORD dwStart;
	 DWORD dwWaitResult=0;
	 DWORD dwLastError = 0;
	struct statistics stats;
	  struct statistics* buffer;

	  

	//Initialize the Statistics Structure
	stats.relationId = RELATION_ID;
	stats.processId = USE_PROCESS_COUNT;
	stats.operationsFailed = 0;
	stats.operationsPassed = 0;
	stats.operationsTotal  = 0;
	stats.operationTime    = 0;

	
	
	//Wait for event to signal to start test	
	WaitForSingleObject(g_hEvent,INFINITE);
	if (WAIT_OBJECT_0 != dwWaitResult)
	{
		Fail ("suspendandresumethreads: Wait for Single Object (g_hEvent) failed.  Failing test.\n"
	    "GetLastError returned %d\n", GetLastError()); 
	}

	 
	//Capture Start Import 
	dwStart = GetTickCount();

	for(i = 0; i < loopcount; i++)
	{

		failFlag = false;
		
		//Suspend Worker Threads
		for (k=0;k<WORKER_THREAD_MULTIPLIER_COUNT;k++)
		{
			for (j=0;j<4;j++)
			{
				if (-1 == SuspendThread(hThread[j][k]))
				{
					//If the operation indicate failure
					failFlag = true;
				}
			}
		}


		//Resume Worker Threads
		for (k=0;k<WORKER_THREAD_MULTIPLIER_COUNT;k++)
		{
			for (j=0;j<4;j++)
			{

				//Only suspend if not already in suspended state
				
				if (-1 == ResumeThread(hThread[j][k]))
				{
					//If the operation indicate failure
					failFlag = true;
				}
			
			}
		}


		//Check for Fail Flag.  If set increment number of failures
		// If Fail flag not set then increment number of operations and number of passe
		if (failFlag == true) 
			{
				stats.operationsFailed++;
			}
		else
			{
				stats.operationsPassed +=1;
		
			}
		stats.operationsTotal  +=1;
		
	}

	stats.operationTime = GetTickCount() - dwStart;

	/*Trace("\n\n\n\nOperation Time: %d milliseconds\n", stats.operationTime);
	Trace("Operation Passed: %d\n", stats.operationsPassed);
	Trace("Operation Total: %d\n", stats.operationsTotal);
	Trace("Operation Failed: %d\n", stats.operationsFailed);
		*/
	if(resultBuffer->LogResult(Id, (char *)&stats))
    	{
        	Fail("Error while writing to shared memory, Thread Id is[%d] and Process id is [%d]\n", Id, USE_PROCESS_COUNT);
    	}

	 buffer = (struct statistics *)resultBuffer->getResultBuffer(Id);
       //Trace("\n%d,%d,%d,%lu\n", buffer->operationsFailed, buffer->operationsPassed, buffer->operationsTotal, buffer->operationTime );
            
	
    return 0;
}
int
pthread_cancel (pthread_t thread)
     /*
      * ------------------------------------------------------
      * DOCPUBLIC
      *      This function requests cancellation of 'thread'.
      *
      * PARAMETERS
      *      thread
      *              reference to an instance of pthread_t
      *
      *
      * DESCRIPTION
      *      This function requests cancellation of 'thread'.
      *      NOTE: cancellation is asynchronous; use pthread_join to
      *                wait for termination of 'thread' if necessary.
      *
      * RESULTS
      *              0               successfully requested cancellation,
      *              ESRCH           no thread found corresponding to 'thread',
      *              ENOMEM          implicit self thread create failed.
      * ------------------------------------------------------
      */
{
  int result;
  int cancel_self;
  pthread_t self;

  if (thread == NULL )
    {
      return ESRCH;
    }

  result = 0;
  if ((self = pthread_self()) == NULL)
    {
      return ENOMEM;
    };

  /*
   * FIXME!!
   *
   * Can a thread cancel itself?
   *
   * The standard doesn't
   * specify an error to be returned if the target
   * thread is itself.
   *
   * If it may, then we need to ensure that a thread can't
   * deadlock itself trying to cancel itself asyncronously
   * (pthread_cancel is required to be an async-cancel
   * safe function).
   */
  cancel_self = pthread_equal(thread, self);

  /*
   * Lock for async-cancel safety.
   */
  (void) pthread_mutex_lock(&thread->cancelLock);

  if (thread->cancelType == PTHREAD_CANCEL_ASYNCHRONOUS
      && thread->cancelState == PTHREAD_CANCEL_ENABLE
      && thread->state < PThreadStateCanceling )
    {
      if (cancel_self)
        {
          thread->state = PThreadStateCanceling;
          thread->cancelState = PTHREAD_CANCEL_DISABLE;

          (void) pthread_mutex_unlock(&thread->cancelLock);
          ptw32_throw(PTW32_EPS_CANCEL);

          /* Never reached */
        }
      else
        {
          HANDLE threadH = thread->threadH;

          SuspendThread(threadH);

          if (WaitForSingleObject(threadH, 0) == WAIT_TIMEOUT )
            {
              CONTEXT context;

              thread->state = PThreadStateCanceling;
              thread->cancelState = PTHREAD_CANCEL_DISABLE;
              context.ContextFlags = CONTEXT_CONTROL;
              GetThreadContext(threadH, &context);
              PTW32_PROGCTR(context) = (DWORD) ptw32_cancel_self;
              SetThreadContext(threadH, &context);
              (void) pthread_mutex_unlock(&thread->cancelLock);
              ResumeThread(threadH);
            }
        }
    }
  else
    {
      /*
       * Set for deferred cancellation.
       */
      if ( thread->state >= PThreadStateCanceling
           || !SetEvent (thread->cancelEvent))
        {
          result = ESRCH;
        }

      (void) pthread_mutex_unlock(&thread->cancelLock);
    }

  return (result);
}
Example #23
0
File: ansicon.c Project: kmkkmk/app
//int _tmain( int argc, TCHAR* argv[] )
int main( void )
{
  STARTUPINFO si;
  PROCESS_INFORMATION pi;
  TCHAR*  cmd;
  BOOL	  option;
  BOOL	  opt_m;
  BOOL	  installed;
  HMODULE ansi;
  int	  rc = 0;

  int argc;
  LPWSTR* argv = CommandLineToArgvW( GetCommandLine(), &argc );

  if (argc > 1)
  {
    if (lstrcmp( argv[1], L"--help" ) == 0 ||
	(argv[1][0] == '-' && (argv[1][1] == '?' || argv[1][1] == 'h')) ||
	(argv[1][0] == '/' && argv[1][1] == '?'))
    {
      help();
      return rc;
    }
    if (lstrcmp( argv[1], L"--version" ) == 0)
    {
      _putws( L"ANSICON (" BITS L"-bit) version " PVERS L" (" PDATE L")." );
      return rc;
    }
  }

#if (MYDEBUG > 1)
  DEBUGSTR( NULL ); // create a new file
#endif

  option = (argc > 1 && argv[1][0] == '-');
  if (option && (towlower( argv[1][1] ) == 'i' ||
		 towlower( argv[1][1] ) == 'u'))
  {
    process_autorun( argv[1][1] );
    argv[1][1] = 'p';
  }

  get_original_attr();

  opt_m = FALSE;
  if (option && argv[1][1] == 'm')
  {
    WORD attr = 7;
    if (iswxdigit( argv[1][2] ))
    {
      attr = iswdigit( argv[1][2] ) ? argv[1][2] - '0'
				    : (argv[1][2] | 0x20) - 'a' + 10;
      if (iswxdigit( argv[1][3]))
      {
	attr <<= 4;
	attr |= iswdigit( argv[1][3] ) ? argv[1][3] - '0'
				       : (argv[1][3] | 0x20) - 'a' + 10;
      }
    }
    SetConsoleTextAttribute( hConOut, attr );

    opt_m = TRUE;
    ++argv;
    --argc;
    option = (argc > 1 && argv[1][0] == '-');
  }

  installed = (GetEnvironmentVariable( L"ANSICON", NULL, 0 ) != 0);

  if (option && argv[1][1] == 'p')
  {
    // If it's already installed, there's no need to do anything.
    if (installed)
      ;
    else if (GetParentProcessInfo( &pi ))
    {
      pi.hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, pi.dwProcessId );
      pi.hThread  = OpenThread(  THREAD_ALL_ACCESS,  FALSE, pi.dwThreadId  );
      SuspendThread( pi.hThread );
      if (!Inject( &pi ))
      {
	_putws( L"ANSICON: parent process type is not supported." );
	rc = 1;
      }
      ResumeThread( pi.hThread );
      CloseHandle( pi.hThread );
      CloseHandle( pi.hProcess );
    }
    else
    {
      _putws( L"ANSICON: could not obtain the parent process." );
      rc = 1;
    }
  }
  else
  {
    ansi = 0;
    if (!installed)
    {
      ansi = LoadLibrary( L"ANSI" BITS L".dll" );
      if (!ansi)
      {
	fputws( L"ANSICON: failed to load ANSI" BITS L".dll.\n", stderr );
	rc = 1;
      }
    }

    if (option && (argv[1][1] == 't' || argv[1][1] == 'T'))
    {
      BOOL title = (argv[1][1] == 'T');
      if (argc == 2)
      {
	argv[2] = L"-";
	++argc;
      }
      for (; argc > 2; ++argv, --argc)
      {
	if (title)
	  wprintf( L"==> %s <==\n", argv[2] );
	display( argv[2], title );
	if (title)
	  putwchar( '\n' );
      }
    }
    else
    {
      // Retrieve the original command line, skipping our name and the option.
      cmd = skip_spaces( skip_arg( skip_spaces( GetCommandLine() ) ) );
      if (opt_m)
	cmd = skip_spaces( skip_arg( cmd ) );

      if (cmd[0] == '-' && (cmd[1] == 'e' || cmd[1] == 'E'))
      {
	fputws( cmd + 3, stdout );
	if (cmd[1] == 'e')
	  putwchar( '\n' );
      }
      else if (!_isatty( 0 ) && *cmd == '\0')
      {
	display( L"-", FALSE );
      }
      else
      {
	if (*cmd == '\0')
	{
	  cmd = _wgetenv( L"ComSpec" );
	  if (cmd == NULL)
	    cmd = L"cmd";
	}

	ZeroMemory( &si, sizeof(si) );
	si.cb = sizeof(si);
	if (CreateProcess( NULL, cmd, NULL,NULL, TRUE, 0, NULL,NULL, &si, &pi ))
	{
	  BOOL	console = FALSE;
	  TCHAR name[MAX_PATH];
	  DWORD rc;
	  CoInitialize( NULL );
	  do
	  {
	    // When I first tried doing this, it took a little while to
	    // succeed.  Testing again shows it works immediately - perhaps the
	    // CoInitialize introduces enough of a delay.  Still, play it safe
	    // and keep trying.  And if you're wondering why I do it at all,
	    // ProcessType may detect GUI, even for a console process.	That's
	    // fine after injection (including -p), but not here.  We *need* to
	    // suspend our own execution whilst running the child, otherwise
	    // bad things happen (besides which, I want to restore the original
	    // attributes when the child exits).
	    if (GetModuleFileNameEx( pi.hProcess, NULL, name, lenof(name) ))
	    {
	      DWORD_PTR info;
	      info = SHGetFileInfo( name, 0, NULL, 0, SHGFI_EXETYPE );
	      if (info == 0x00004550) // console PE
		console = TRUE;
	      DEBUGSTR( L"%s", name );
	      DEBUGSTR( L"  %s (%p)", (console) ? L"Console" : L"Not console",
				      info );
	      break;
	    }
	    Sleep( 10 );
	  } while (GetExitCodeProcess( pi.hProcess, &rc ) &&
		   rc == STILL_ACTIVE);
	  CoUninitialize();
	  if (console)
	  {
	    SetConsoleCtrlHandler( (PHANDLER_ROUTINE)CtrlHandler, TRUE );
	    WaitForSingleObject( pi.hProcess, INFINITE );
	  }
	  CloseHandle( pi.hProcess );
	  CloseHandle( pi.hThread );
	}
	else
	{
	  *skip_arg( cmd ) = '\0';
	  wprintf( L"ANSICON: '%s' could not be executed.\n", cmd );
	  rc = 1;
	}
      }
    }

    if (ansi)
      FreeLibrary( ansi );
  }

  set_original_attr();
  return rc;
}
Example #24
0
static void
dump_thread(void *arg)
{
    HANDLE dbghelp;
    BOOL (WINAPI *pSymInitialize)(HANDLE, const char *, BOOL);
    BOOL (WINAPI *pSymCleanup)(HANDLE);
    BOOL (WINAPI *pStackWalk64)(DWORD, HANDLE, HANDLE, STACKFRAME64 *, void *, PREAD_PROCESS_MEMORY_ROUTINE64, PFUNCTION_TABLE_ACCESS_ROUTINE64, PGET_MODULE_BASE_ROUTINE64, PTRANSLATE_ADDRESS_ROUTINE64);
    DWORD64 (WINAPI *pSymGetModuleBase64)(HANDLE, DWORD64);
    BOOL (WINAPI *pSymFromAddr)(HANDLE, DWORD64, DWORD64 *, SYMBOL_INFO *);
    BOOL (WINAPI *pSymGetLineFromAddr64)(HANDLE, DWORD64, DWORD *, IMAGEHLP_LINE64 *);
    HANDLE (WINAPI *pOpenThread)(DWORD, BOOL, DWORD);
    DWORD tid = *(DWORD *)arg;
    HANDLE ph;
    HANDLE th;

    dbghelp = LoadLibrary("dbghelp.dll");
    if (!dbghelp) return;
    pSymInitialize = (BOOL (WINAPI *)(HANDLE, const char *, BOOL))GetProcAddress(dbghelp, "SymInitialize");
    pSymCleanup = (BOOL (WINAPI *)(HANDLE))GetProcAddress(dbghelp, "SymCleanup");
    pStackWalk64 = (BOOL (WINAPI *)(DWORD, HANDLE, HANDLE, STACKFRAME64 *, void *, PREAD_PROCESS_MEMORY_ROUTINE64, PFUNCTION_TABLE_ACCESS_ROUTINE64, PGET_MODULE_BASE_ROUTINE64, PTRANSLATE_ADDRESS_ROUTINE64))GetProcAddress(dbghelp, "StackWalk64");
    pSymGetModuleBase64 = (DWORD64 (WINAPI *)(HANDLE, DWORD64))GetProcAddress(dbghelp, "SymGetModuleBase64");
    pSymFromAddr = (BOOL (WINAPI *)(HANDLE, DWORD64, DWORD64 *, SYMBOL_INFO *))GetProcAddress(dbghelp, "SymFromAddr");
    pSymGetLineFromAddr64 = (BOOL (WINAPI *)(HANDLE, DWORD64, DWORD *, IMAGEHLP_LINE64 *))GetProcAddress(dbghelp, "SymGetLineFromAddr64");
    pOpenThread = (HANDLE (WINAPI *)(DWORD, BOOL, DWORD))GetProcAddress(GetModuleHandle("kernel32.dll"), "OpenThread");
    if (pSymInitialize && pSymCleanup && pStackWalk64 && pSymGetModuleBase64 &&
	pSymFromAddr && pSymGetLineFromAddr64 && pOpenThread) {
	SymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS | SYMOPT_DEBUG | SYMOPT_LOAD_LINES);
	ph = GetCurrentProcess();
	pSymInitialize(ph, NULL, TRUE);
	th = pOpenThread(THREAD_SUSPEND_RESUME|THREAD_GET_CONTEXT, FALSE, tid);
	if (th) {
	    if (SuspendThread(th) != (DWORD)-1) {
		CONTEXT context;
		memset(&context, 0, sizeof(context));
		context.ContextFlags = CONTEXT_FULL;
		if (GetThreadContext(th, &context)) {
		    char libpath[MAX_PATH];
		    char buf[sizeof(SYMBOL_INFO) + MAX_SYM_NAME];
		    SYMBOL_INFO *info = (SYMBOL_INFO *)buf;
		    DWORD mac;
		    STACKFRAME64 frame;
		    memset(&frame, 0, sizeof(frame));
#if defined(_M_AMD64) || defined(__x86_64__)
		    mac = IMAGE_FILE_MACHINE_AMD64;
		    frame.AddrPC.Mode = AddrModeFlat;
		    frame.AddrPC.Offset = context.Rip;
		    frame.AddrFrame.Mode = AddrModeFlat;
		    frame.AddrFrame.Offset = context.Rbp;
		    frame.AddrStack.Mode = AddrModeFlat;
		    frame.AddrStack.Offset = context.Rsp;
#elif defined(_M_IA64) || defined(__ia64__)
		    mac = IMAGE_FILE_MACHINE_IA64;
		    frame.AddrPC.Mode = AddrModeFlat;
		    frame.AddrPC.Offset = context.StIIP;
		    frame.AddrBStore.Mode = AddrModeFlat;
		    frame.AddrBStore.Offset = context.RsBSP;
		    frame.AddrStack.Mode = AddrModeFlat;
		    frame.AddrStack.Offset = context.IntSp;
#else	/* i386 */
		    mac = IMAGE_FILE_MACHINE_I386;
		    frame.AddrPC.Mode = AddrModeFlat;
		    frame.AddrPC.Offset = context.Eip;
		    frame.AddrFrame.Mode = AddrModeFlat;
		    frame.AddrFrame.Offset = context.Ebp;
		    frame.AddrStack.Mode = AddrModeFlat;
		    frame.AddrStack.Offset = context.Esp;
#endif

		    while (pStackWalk64(mac, ph, th, &frame, &context, NULL,
					NULL, NULL, NULL)) {
			DWORD64 addr = frame.AddrPC.Offset;
			IMAGEHLP_LINE64 line;
			DWORD64 displacement;
			DWORD tmp;

			if (addr == frame.AddrReturn.Offset || addr == 0 ||
			    frame.AddrReturn.Offset == 0)
			    break;

			memset(buf, 0, sizeof(buf));
			info->SizeOfStruct = sizeof(SYMBOL_INFO);
			info->MaxNameLen = MAX_SYM_NAME;
			if (pSymFromAddr(ph, addr, &displacement, info)) {
			    if (GetModuleFileName((HANDLE)(uintptr_t)pSymGetModuleBase64(ph, addr), libpath, sizeof(libpath)))
				fprintf(stderr, "%s", libpath);
			    fprintf(stderr, "(%s+0x%I64x)",
				    info->Name, displacement);
			}
			fprintf(stderr, " [0x%p]", (void *)(VALUE)addr);
			memset(&line, 0, sizeof(line));
			line.SizeOfStruct = sizeof(line);
			if (pSymGetLineFromAddr64(ph, addr, &tmp, &line))
			    fprintf(stderr, " %s:%lu", line.FileName, line.LineNumber);
			fprintf(stderr, "\n");
		    }
		}

		ResumeThread(th);
	    }
	    CloseHandle(th);
	}
	pSymCleanup(ph);
    }
    FreeLibrary(dbghelp);
}
Example #25
0
int
pthread_cancel (pthread_t thread)
     /*
      * ------------------------------------------------------
      * DOCPUBLIC
      *      This function requests cancellation of 'thread'.
      *
      * PARAMETERS
      *      thread
      *              reference to an instance of pthread_t
      *
      *
      * DESCRIPTION
      *      This function requests cancellation of 'thread'.
      *      NOTE: cancellation is asynchronous; use pthread_join to
      *                wait for termination of 'thread' if necessary.
      *
      * RESULTS
      *              0               successfully requested cancellation,
      *              ESRCH           no thread found corresponding to 'thread',
      *              ENOMEM          implicit self thread create failed.
      * ------------------------------------------------------
      */
{
  int result;
  int cancel_self;
  pthread_t self;
  ptw32_thread_t * tp;

  result = pthread_kill (thread, 0);

  if (0 != result)
    {
      return result;
    }

  if ((self = pthread_self ()).p == NULL)
    {
      return ENOMEM;
    };

  /*
   * FIXME!!
   *
   * Can a thread cancel itself?
   *
   * The standard doesn't
   * specify an error to be returned if the target
   * thread is itself.
   *
   * If it may, then we need to ensure that a thread can't
   * deadlock itself trying to cancel itself asyncronously
   * (pthread_cancel is required to be an async-cancel
   * safe function).
   */
  cancel_self = pthread_equal (thread, self);

  tp = (ptw32_thread_t *) thread.p;

  /*
   * Lock for async-cancel safety.
   */
  (void) pthread_mutex_lock (&tp->cancelLock);

  if (tp->cancelType == PTHREAD_CANCEL_ASYNCHRONOUS
      && tp->cancelState == PTHREAD_CANCEL_ENABLE
      && tp->state < PThreadStateCanceling)
    {
      if (cancel_self)
	{
	  tp->state = PThreadStateCanceling;
	  tp->cancelState = PTHREAD_CANCEL_DISABLE;

	  (void) pthread_mutex_unlock (&tp->cancelLock);
	  ptw32_throw (PTW32_EPS_CANCEL);

	  /* Never reached */
	}
      else
	{
	  HANDLE threadH = tp->threadH;

	  SuspendThread (threadH);

	  if (WaitForSingleObject (threadH, 0) == WAIT_TIMEOUT)
	    {
	      tp->state = PThreadStateCanceling;
	      tp->cancelState = PTHREAD_CANCEL_DISABLE;
	      /*
	       * If alertdrv and QueueUserAPCEx is available then the following
	       * will result in a call to QueueUserAPCEx with the args given, otherwise
	       * this will result in a call to ptw32_RegisterCancelation and only
	       * the threadH arg will be used.
	       */
	      ptw32_register_cancelation (ptw32_cancel_callback, threadH, 0);
	      (void) pthread_mutex_unlock (&tp->cancelLock);
	      //ResumeThread (threadH);
	    }
	}
    }
  else
    {
      /*
       * Set for deferred cancellation.
       */
      if (tp->state < PThreadStateCancelPending)
	{
	  tp->state = PThreadStateCancelPending;
	  if (!SetEvent (tp->cancelEvent))
	    {
	      result = ESRCH;
	    }
	}
      else if (tp->state >= PThreadStateCanceling)
	{
	  result = ESRCH;
	}

      (void) pthread_mutex_unlock (&tp->cancelLock);
    }
  return (result);
}
/* this thread assists with the returns from simulated interrupts
   
   ideally, the interrupthandler would just assume the state right before the
   interrupt, but this is not possible given the x86 and nt, so the interrupt
   handling thread has to suspend itself, and let some other thread manipulate
   its state while it is suspended. 
   
   when this thread runs, interrupts will be disabled, so we reenable them
   once it is finished.
   */
DWORD WINAPI interrupt_return_assist(LPVOID ptr) {
  signal_queue_t *sq;
  int scount, rcount;
  int success = FALSE;
  CONTEXT context;

  if (DEBUG)
    kprintf("IRA:starting ...\n");

  for(;;) {
    /* wait politely until we are needed */
    WaitOnObject(cleanup);

    if (DEBUG)
      kprintf("IRA:woken up ...\n");
	
    WaitOnObject(mutex);

    {
      success = FALSE;
      sq = signalq;
      signalq = signalq->next;
      assert(signalq == NULL);

      /* wait for the system thread to enter a "safe" state */
      while(readytoreturn != TRUE)
	SwitchToThread();

      while(success != TRUE) {

	scount = SuspendThread(sq->threadid);
	memset(&context, 0, sizeof(CONTEXT));

#ifdef WINCE
	context.ContextFlags = CONTEXT_FULL;
#else
	context.ContextFlags = 
	  CONTEXT_FULL | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS;
#endif

	AbortOnError(GetThreadContext(system_thread, &context));

	if (DEBUG)
	  kprintf("IRA:system thread is at 0x%x.\n", EIP);
	if((EIP >= (unsigned int)loopforever_start_address && 
	    EIP <= (unsigned int)loopforever_end_address)) {
	  if (DEBUG)
	    kprintf("IRA:enabling interrupts.\n");
	  interrupt_level = ENABLED;

	  AbortOnError(SetThreadContext(sq->threadid, sq->context));

	  rcount = ResumeThread(sq->threadid);

	  if (DEBUG)
	    kprintf("IRA:Interrupt return assist scount %d rcount %d\n", 
		   scount, rcount);

	  assert(rcount >= scount + 1);
	  success = TRUE;
	} 
	else {
	  ResumeThread(system_thread);
	  ReleaseMutex(mutex);
	  SwitchToThread();
	  WaitOnObject(mutex);
	}
      }
    } 
    ReleaseMutex(mutex);
    free(sq);
  }

  /* never reached */
  return 0;
}
Example #27
0
	void pause() const
	{
		_mutex.lock();
		SuspendThread(_handle);
		_mutex.unlock();
	}
/* 
 * Send an interrupt to the system thread: adjust its stack to call
 * the appropriate interrupt handler with the specified argument. the
 * "type" argument identifies interrupt-specific processing which must
 * be done, in particular, what we should do if interrupts are
 * disabled or the system thread is in a non-preemptable state
 * (e.g. executing a system library function). clock interrupts are
 * dropped, network interrupts are deferred. this function replaces
 * code which used to be common to clock_poll and network_poll.
*/
void send_interrupt(int type, void* arg) {
  CONTEXT context;
  int safe_to_proceed = 0;
  int drop_interrupt = 0;
  interrupt_queue_t* interrupt_info = NULL;

  for (;;) {
    WaitOnObject(mutex);

    /* need to protect this code: we only activate the interrupt if interrupts
       are actually enabled, but we also need to ensure they are not disabled
       after we test -- so we suspend the system thread first.
       */
    SuspendThread(system_thread);
    memset(&context, 0, sizeof(CONTEXT));
#ifdef WINCE
    context.ContextFlags = CONTEXT_FULL;
#else
    context.ContextFlags = 
      CONTEXT_FULL | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS;
#endif
    /* Warning: a printf here makes the system lock */

    AbortOnError(GetThreadContext(system_thread, &context));

    /* find interrupt description in the interrupt queue */
    interrupt_info = interrupt_queue;
    while (interrupt_info!=NULL && interrupt_info->type!=type)
      interrupt_info = interrupt_info->next;
    
    if (interrupt_info == NULL) {
      /* 
       * we couldn't find the interrupt with type "type" so we crash the
       * sistem.
      */

		kprintf("INT ERR: An interrupt of the unregistered type %d was received.\n",
	     type);
      AbortOnCondition(1,"Crashing.");
    } else {
      /*
       * interrupt-type-specific processing: can we interrupt now? If we 
       * ended up interrupting the process at a time when it is in some non-minithread-safe
       * Windows library, then defer or drop the interrupt.
       */
      switch (interrupt_info->property){
      case INTERRUPT_DROP:
	if (interrupt_level == DISABLED
	    || (EIP < start_address)
	    || (EIP > end_address)) {
	  drop_interrupt = 1;
	}
	else {
		//interrupt_level = DISABLED;
	  safe_to_proceed = 1;
	}
	break;
      case INTERRUPT_DEFER:
	if (interrupt_level == ENABLED 
	    && (EIP >= start_address)
	    && (EIP <= end_address)) {
	  interrupt_level = DISABLED;
	  safe_to_proceed = 1;
	}
	break;
      default:
	break;
      }
    } 
     
    if (safe_to_proceed == 1)
      break;
    else {
      ResumeThread(system_thread);
      ReleaseMutex(mutex);
      if (DEBUG) {
	switch (interrupt_info->property) {
	case INTERRUPT_DROP:
	  kprintf("Interrupt of type %d dropped, eip = 0x%x.\n", 
		 interrupt_info->type, EIP);
	  break;
	case INTERRUPT_DEFER:
	  kprintf("Interrupt of type %d deffered, eip = 0x%x.\n", 
		 interrupt_info->type, EIP);
	  break;
	}
      }
    }

    if (drop_interrupt == 1)
      return;
    else
      SwitchToThread();
  }

  /* now fix the system thread's stack so it runs run_user_handler */
  {
    int stack;
    int oldpc = 0;

    //if (DEBUG) {
      //kprintf("Interrupts are enabled, system thread pc = 0x%x\n", EIP);
      //kprintf("Adjusting system thread context ...\n");
  //  }

    /* set the interrupt number */
    /* arg->intnumber = ++intnumber; */

    oldpc = EIP;
    stack = ESP;	/* Esp == extended stack pointer */

    /* safe to do a printf because other thread is stunned in user code */
   // if (DEBUG)
      //kprintf("Suspended system thread, adjusting stack, sp = 0x%x\n", stack);

    stack -= (sizeof(CONTEXT) + 64); /* 64 is slop */
    memcpy((int *) stack, &context, sizeof(CONTEXT));

    EIP = (int) ((void *) receive_interrupt);
    REG1 = stack; /*pointer to context*/    
    REG2 = (int) type; /*type, second argument */
#ifndef WINCE
    /* for x86 put arg pointer on the stack since only two 
       parameters can be passed in registers.
    */
    stack-=sizeof(void*);
    *((int*)stack)=(int) arg;
    stack-=sizeof(void*); 
#else
    /* for ARM put the third argument in R2 */
    context.R2 = (int) arg;
#endif
    ESP = stack;
    
    AbortOnError(SetThreadContext(system_thread, &context));

    AbortOnError(GetThreadContext(system_thread, &context));
    
    ResumeThread(system_thread);
  }
  ReleaseMutex(mutex);
}
Example #29
0
void Thread::suspend()
{
    SuspendThread(m_handle);
}
bool
windows_suspend(DWORD pid)
{
	// make sure we haven't already suspended this process, then allocate
	// a SuspendedProcess object and add it to the hash table
	//
	SuspendedProcess* sp;
	int ret = suspended_processes.lookup(pid, sp);
	ASSERT(ret == -1);
	sp = new SuspendedProcess(11, hash_func);
	ASSERT(sp != NULL);
	ret = suspended_processes.insert(pid, sp);
	ASSERT(ret != -1);

	// we need to loop until iterating through the thread list for this
	// process shows that all threads are suspended
	//
	bool finished = false;
	while (!finished) {

		// assume we're going to succeed on this iteration until
		// proven otherwise
		//
		finished = true;

		// get the list of threads for this process
		//
		ExtArray<DWORD> tid_array;
		int num_tids = sys_info.GetTIDs(pid, tid_array);
		if (num_tids == 0) {
			// TODO: we need to handle this case!!!
			//
			EXCEPT("windows_suspend_process failed: can't get threads for pid %u",
			       pid);
		}

		// go through the thread list, calling SuspendThread on each
		//
		for (int i = 0; i < num_tids; i++) {

			// see if we already have a record for this thread
			//
			SuspendedThread* st;
			ret = sp->lookup(tid_array[i], st);
			if (ret == -1) {

				// no record yet; open up this thread's handle
				//
				HANDLE handle = OpenThread(THREAD_SUSPEND_RESUME, FALSE, tid_array[i]);
				if (handle == NULL) {

					// the thread probably exited; however, it may have called ResumeThread
					// or CreateThread first, so we'll have to loop again
					//
					finished = false;
					dprintf(D_FULLDEBUG,
					        "windows_suspend_process: OpenThread error: %u\n",
					        GetLastError());
					continue;
				}

				// now that we have a handle, create a record for this thread
				//
				st = new SuspendedThread;
				ASSERT(st != NULL);
				st->handle = handle;
				st->num_suspends = 0;
				ret = sp->insert(tid_array[i], st);
				ASSERT(ret != -1);
			}

			// now suspend the thread
			//
			DWORD result = SuspendThread(st->handle);
			if (result == (DWORD)-1) {

				// how can this happen? maybe the thread exited?
				//
				finished = false;
				dprintf(D_FULLDEBUG,
						"windows_suspend_process: SuspendThread error: %u\n",
						GetLastError());
				continue;
			}

			// if the thread was not suspended prior to our SuspendThread call,
			// it may have called CreateThread or ResumeThread so we need to loop
			// at least one more time
			//
			if (result == 0) {
				finished = false;
			}

			// keep track of how many suspends we've sent this thread
			//
			st->num_suspends++;
		}
	}

	return true;
}