You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

346 lines
9.2 KiB

/*
* Copyright 2002-2019 Intel Corporation.
*
* This software is provided to you as Sample Source Code as defined in the accompanying
* End User License Agreement for the Intel(R) Software Development Products ("Agreement")
* section 1.L.
*
* This software and the related documents are provided as is, with no express or implied
* warranties, other than those that are expressly stated in the License.
*/
#define _WIN32_WINNT 0x0400
#include <stdio.h>
#include <windows.h>
#include <iostream>
using std::string;
using std::cerr;
using std::endl;
volatile int doloop = 1;
__declspec(dllexport) int DoLoop()
{
return doloop;
}
DWORD WINAPI ThreadProc1(VOID * p)
{
while(DoLoop())
{
HMODULE h1 = LoadLibraryW(L"version.dll");
FARPROC a1 = GetProcAddress(h1, "GetFileVersionInfoW");
Sleep(1);
FreeLibrary(h1);
}
return 0;
}
DWORD WINAPI ThreadProc2(VOID * p)
{
while(DoLoop())
{
static int i = 0;
i++;
i = i % 0x8;
LPVOID aaa = VirtualAlloc(0, i * 0x1000000, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
Sleep(1);
VirtualFree(aaa, 0, MEM_RELEASE);
}
return 0;
}
__declspec(dllexport) void ShortFunction1(DWORD h)
{
volatile DWORD i = h;
Sleep(1);
if(i != 1)
{
exit(-1);
}
}
__declspec(dllexport) void ShortFunction2(DWORD h)
{
volatile DWORD i = h;
Sleep(1);
if(i != 2)
{
exit(-1);
}
}
DWORD WINAPI ThreadProc3(VOID * p)
{
while(DoLoop())
{
ShortFunction1(1);
}
return 0;
}
DWORD WINAPI ThreadProc4(VOID * p)
{
while(DoLoop())
{
ShortFunction2(2);
}
return 0;
}
DWORD WINAPI ThreadProc5(VOID * p)
{
DWORD recursionDepth = DWORD(p);
if(recursionDepth == 3)
{
return 0;
}
DWORD childRecursionDepth = recursionDepth + 1;
HANDLE threads[2];
while(DoLoop())
{
threads[0] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc5, (VOID *)childRecursionDepth, 0, NULL);
threads[1] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc5, (VOID *)childRecursionDepth, 0, NULL);
WaitForMultipleObjects(2, threads, TRUE, INFINITE);
CloseHandle(threads[0]);
CloseHandle(threads[1]);
}
return 0;
}
//Wait for a process completion
//Verify it returned the expected exit code
bool WaitAndVerify(HANDLE process)
{
if(WaitForSingleObject( process, INFINITE ) == WAIT_FAILED)
{
cerr << "WaitForSingleObject failed" << endl;
return FALSE;
}
DWORD processExitCode;
if(GetExitCodeProcess (process, &processExitCode) == FALSE)
{
cerr << "GetExitCodeProcess Failed" << endl;
return FALSE;
}
if(processExitCode != 0)
{
cerr << "Got unexpected exit code" << endl;
return FALSE;
}
return TRUE;
}
typedef WINADVAPI BOOL WINAPI OPEN_PROCESS_TOKEN_FUNC(HANDLE, DWORD, PHANDLE);
typedef WINADVAPI BOOL WINAPI CREATE_PROCESS_AS_USER_A_FUNC (HANDLE,LPCSTR, LPSTR,
LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, LPCSTR,
LPSTARTUPINFOA, LPPROCESS_INFORMATION);
DWORD WINAPI ThreadProc6(VOID * p)
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
while(DoLoop())
{
{
memset(&si, 0, sizeof(si));
si.cb = sizeof(STARTUPINFO);
memset(&pi, 0, sizeof(pi));
string cmdLine = "cmd /c";
HMODULE advapi32Handle = LoadLibraryW(L"advapi32.dll");
if(advapi32Handle == NULL)
{
cerr << "w_app1 failed! (load library advapi32.dll)" << endl;
exit(-1);
}
HANDLE tokenHandle;
if(!((OPEN_PROCESS_TOKEN_FUNC *)GetProcAddress(advapi32Handle, "OpenProcessToken"))
(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tokenHandle))
{
cerr << "w_app1 failed! (open process token)" << endl;
exit(-1);
}
if (!((CREATE_PROCESS_AS_USER_A_FUNC *)GetProcAddress(advapi32Handle, "CreateProcessAsUserA"))
(tokenHandle, NULL, (LPSTR)cmdLine.c_str(), NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi))
{
cerr << "w_app1 failed! (create process as user)" << endl;
exit(-1);
}
else
{
if(!WaitAndVerify(pi.hProcess))
{
cerr << "w_app1 failed! (on WaitAndVerify())" << endl;
exit(-1);
}
CloseHandle(tokenHandle);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
FreeLibrary(advapi32Handle);
}
{
memset(&si, 0, sizeof(si));
si.cb = sizeof(STARTUPINFO);
memset(&pi, 0, sizeof(pi));
string cmdLine = "cmd /c";
if(!CreateProcess(NULL, (LPSTR)cmdLine.c_str(), NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi))
{
cerr << "w_app1 failed! (create process)" << endl;
exit(-1);
}
else
{
if(!WaitAndVerify(pi.hProcess))
{
cerr << "w_app1 failed! (on WaitAndVerify())" << endl;
exit(-1);
}
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
}
Sleep(1);
}
return 0;
}
volatile LONG globalQueueCnt = 0;
VOID CALLBACK My_APCProc(ULONG_PTR dwParam)
{
if(dwParam == 1)
{
InterlockedDecrement(&globalQueueCnt);
return;
}
QueueUserAPC(My_APCProc, GetCurrentThread() , dwParam - 1);
DWORD status = SleepEx(10, true);
}
DWORD WINAPI ThreadProc7(VOID * p)
{
while(DoLoop())
{
DWORD status = SleepEx(1000, true);
}
return 0;
}
DWORD WINAPI ThreadProc8(VOID * p)
{
while(DoLoop())
{
InterlockedIncrement(&globalQueueCnt);
QueueUserAPC(My_APCProc, HANDLE(p) , 2);
while(DoLoop() && (InterlockedCompareExchange(&globalQueueCnt, 0, 0) != 0))
{
Sleep(50);
}
}
return 0;
}
void DivideByZero()
{
static int zero = 0;
int i = 1 / zero;
}
DWORD WINAPI ThreadProc9(VOID * p)
{
while(DoLoop())
{
__try
{
DivideByZero();
}
__except(GetExceptionCode() == EXCEPTION_INT_DIVIDE_BY_ZERO ? EXCEPTION_EXECUTE_HANDLER :
EXCEPTION_CONTINUE_SEARCH)
{
volatile int j = 11;
}
Sleep(10);
}
return 0;
}
DWORD WINAPI ThreadProc10(VOID * p)
{
while(DoLoop())
{
Sleep(20);
}
return 0;
}
DWORD WINAPI ThreadProc11(VOID * p)
{
while(DoLoop())
{
if(SuspendThread(HANDLE(p)) != (DWORD)-1)
{
CONTEXT context;
context.ContextFlags = CONTEXT_FULL;
Sleep(1);
if(GetThreadContext(HANDLE(p), &context))
{
Sleep(1);
SetThreadContext(HANDLE(p), &context);
}
Sleep(1);
ResumeThread(HANDLE(p));
Sleep(1);
}
}
return 0;
}
int main()
{
HANDLE threads[64];
threads[0] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc1, NULL, 0, NULL);
threads[1] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc2, NULL, 0, NULL);
threads[2] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc2, NULL, 0, NULL);
threads[3] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc2, NULL, 0, NULL);
threads[4] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc2, NULL, 0, NULL);
for(int i = 5; i < 30; i++)
{
threads[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc3, NULL, 0, NULL);
}
for(int i = 30; i < 57; i++)
{
threads[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc4, NULL, 0, NULL);
}
DWORD recursionDepth = 0;
threads[57] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc5, (VOID *)recursionDepth, 0, NULL);
threads[58] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc6, NULL, 0, NULL);
threads[59] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc7, NULL, 0, NULL);
threads[60] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc8, (VOID *)(threads[59]), 0, NULL);
threads[61] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc9, NULL, 0, NULL);
threads[62] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc10, NULL, 0, NULL);
threads[63] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc11, (VOID *)(threads[62]), 0, NULL);
HANDLE susThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc1, NULL, CREATE_SUSPENDED, NULL);
DWORD ret = WaitForMultipleObjects(64, threads, TRUE, 420*1000);
TerminateThread(susThread, 0);
WaitForSingleObject(susThread, 20*1000);
if(ret == WAIT_TIMEOUT)
{
cerr << "w_app1 failed!" << endl;
doloop = 0;
//let the threads the opportunity to terminate cleanly
WaitForMultipleObjects(64, threads, TRUE, 20*1000);
exit(-1);
}
return 0;
}