Which thread is used in the same function of multithread - multithreading

In mfc code,
Declare as follow
CWinThread* _pThread[5];
DWORD _ThreadArg[5] = { HIGHEST_THREAD, // 0x00
ABOVE_AVE_THREAD, // 0x3F
NORMAL_THREAD, // 0x7F
BELOW_AVE_THREAD, // 0xBF
LOWEST_THREAD // 0xFF
};
int i;
for (i= 0; i< 5; i++)
{
_pThread[i] = AfxBeginThread(ThreadFunc,
&_ThreadArg[i],
THREAD_PRIORITY_NORMAL,
0,
//CREATE_SUSPENDED,
NULL,
NULL);
//_pThread[i]->ResumeThread();
}
// setup relative priority of threads
_pThread[0]->SetThreadPriority(THREAD_PRIORITY_HIGHEST);
_pThread[1]->SetThreadPriority(THREAD_PRIORITY_ABOVE_NORMAL);
_pThread[2]->SetThreadPriority(THREAD_PRIORITY_NORMAL);
_pThread[3]->SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
_pThread[4]->SetThreadPriority(THREAD_PRIORITY_LOWEST);
use same thread function
UINT CThreadPoolDlg::ThreadFuncTh1(LPVOID ThreadArg)
{
DWORD dwArg = *(DWORD*)ThreadArg;
//txtTh[0].SetWindowTextW(_T("23"));
AfxGetMainWnd()->GetDlgItem(IDC_THD1)->SetWindowText(_T("1"));
return 0;
}
How do I check which thread is in use in same function?

I get a answer as follow
_pThread[0] = AfxBeginThread(ThreadFunc,this,
THREAD_PRIORITY_NORMAL,
0,
NULL,
NULL);
_pThread[1] = AfxBeginThread(ThreadFunc,this,
THREAD_PRIORITY_NORMAL,
0,
CREATE_SUSPENDED,
NULL);
_pThread[2] = AfxBeginThread(ThreadFunc,this,
THREAD_PRIORITY_NORMAL,
0,
CREATE_SUSPENDED,
NULL);
the thread function is declare as follow
UINT CThreadPoolDlg::ThreadFunc(LPVOID ThreadArg)
{
CThreadPoolDlg* dwArg = (CThreadPoolDlg*)ThreadArg;
DWORD dThread = GetCurrentThreadId();
//txtTh[0].SetWindowTextW(_T("23"));
while(1)
{
CString strTemp;
if(dThread == dwArg->_pThread[0]->m_nThreadID)
{
AfxGetMainWnd()->GetDlgItem(IDC_THD1)->GetWindowText(strTemp);
int n = _wtoi(strTemp);
strTemp.Format(_T("%d"), ++n);
AfxGetMainWnd()->GetDlgItem(IDC_THD1)->SetWindowText(strTemp);
if(n > 5)
{
::SendMessage(dwArg->GetSafeHwnd(), OWM_MYMETHOD, 0, 0);
//dwArg->_pThread[1]->ResumeThread();
}
}
if(dThread == dwArg->_pThread[1]->m_nThreadID)
{
AfxGetMainWnd()->GetDlgItem(IDC_THD2)->GetWindowText(strTemp);
int n = _wtoi(strTemp);
strTemp.Format(_T("%d"), ++n);
AfxGetMainWnd()->GetDlgItem(IDC_THD2)->SetWindowText(strTemp);
if(n > 5)
{
dwArg->_pThread[2]->ResumeThread();
}
}
if(dThread == dwArg->_pThread[2]->m_nThreadID)
{
AfxGetMainWnd()->GetDlgItem(IDC_THD3)->GetWindowText(strTemp);
int n = _wtoi(strTemp);
strTemp.Format(_T("%d"), ++n);
AfxGetMainWnd()->GetDlgItem(IDC_THD3)->SetWindowText(strTemp);
}
Sleep(500);
}
return 0;
}
Just look at the
DWORD dThread = GetCurrentThreadId();
dThread == dwArg->_pThread[1]->m_nThreadID
then I will get current thread id...

Related

I don't know why my IOCP's numberOfConcurrentThreads argument doesn't work

I have read a material below and tested some code.
Does IOCP creates its own threads?
My codes are as below:
#include <functional>
#include <stdio.h>
#include <iostream>
#include <crtdbg.h>
#include <conio.h>
#include <array>
#include <unordered_map>
using namespace std;
namespace IOCP_test {
struct myOverlapped {
OVERLAPPED overLapped;
int number;
};
DWORD WINAPI myCallBack(LPVOID completionPort) {
DWORD NumberOfByteTransfered = 0;
VOID* CompletionKey = NULL;
OVERLAPPED* overlappedPointer = NULL;
while (true) {
auto success = GetQueuedCompletionStatus(
(HANDLE)completionPort,
&NumberOfByteTransfered,
(LPDWORD)&CompletionKey,
&overlappedPointer,
INFINITE);
if (success) {
myOverlapped* mO = (myOverlapped*)overlappedPointer;
while (true) {
cout << mO->number << endl;
}
//Sleep(10);
//PostQueuedCompletionStatus(completionPort, 0, 0, overlappedPointer);
}
}
}
void IOCP_test() {
// TODO: sleep을 안걸었는데.. 왜 5개 스레드가 모두 작동할까?
int workerThreadCount = 5;
HANDLE hIOCP = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1);
vector<HANDLE> workerThreadVector;
DWORD NumberOfByteTransfered = 0;
VOID* CompletionKey = NULL;
OVERLAPPED* overlappedPointer = NULL;
for (DWORD i = 0; i < workerThreadCount; i++)
{
HANDLE WorkerThread = CreateThread(NULL, 0, myCallBack, hIOCP, 0, NULL);
workerThreadVector.push_back(WorkerThread);
}
myOverlapped a1;
a1.number = 1;
myOverlapped a2;
a2.number = 2;
myOverlapped a3;
a3.number = 3;
myOverlapped a4;
a4.number = 4;
myOverlapped a5;
a5.number = 5;
if (hIOCP) {
PostQueuedCompletionStatus(hIOCP, 0, 0, (LPOVERLAPPED)&a1);
PostQueuedCompletionStatus(hIOCP, 0, 0, (LPOVERLAPPED)&a2);
PostQueuedCompletionStatus(hIOCP, 0, 0, (LPOVERLAPPED)&a3);
PostQueuedCompletionStatus(hIOCP, 0, 0, (LPOVERLAPPED)&a4);
PostQueuedCompletionStatus(hIOCP, 0, 0, (LPOVERLAPPED)&a5);
}
char key;
while (true) {
key = _getch();
if (key == 'e') {
break;
}
if (key == 'n') {
cout << endl;
}
}
for (DWORD i = 0; i < workerThreadVector.size(); i++)
{
CloseHandle(workerThreadVector[i]);
}
if (hIOCP) {
CloseHandle(hIOCP);
}
}
//IOCP_test::IOCP_test();
}
int main()
{
IOCP_test::IOCP_test();
_CrtDumpMemoryLeaks();
return 0;
}
I thought, if numberOfConcurrentThreads works, only a thread that cout '1' should be running, not all five threads.
However, result is as below.
All overlapped works were being processed by worker threads..
Why all overlapped works were processed by 5 worker threads?
I think it should be 1 worker thread that works because numberOfConcurrentThreads is 1.
I hope your wise answers.
Thank you for reading.
I figured it out.
It is because I called 'cout' in my worker thread's function.
I think 'cout' invokes IO interrupt for my worker thread, and it makes IOCP signal another worker thread.
My test code is as below.
You can run this code, and press any key except 'e'.('e' is for exit.)
You can see which worker thread works in IOCP.
#include <functional>
#include <stdio.h>
#include <iostream>
#include <crtdbg.h>
#include <conio.h>
#include <array>
#include <unordered_map>
int iocp_test = -1;
namespace IOCP_test {
struct myOverlapped {
OVERLAPPED overLapped;
int number;
};
DWORD WINAPI myCallBack(LPVOID completionPort) {
DWORD NumberOfByteTransfered = 0;
VOID* CompletionKey = NULL;
OVERLAPPED* overlappedPointer = NULL;
while (true) {
auto success = GetQueuedCompletionStatus(
(HANDLE)completionPort,
&NumberOfByteTransfered,
(LPDWORD)&CompletionKey,
&overlappedPointer,
INFINITE);
if (success) {
myOverlapped* mO = (myOverlapped*)overlappedPointer;
while (true) {
iocp_test = mO->number;
}
//Sleep(10);
//PostQueuedCompletionStatus(completionPort, 0, 0, overlappedPointer);
}
}
}
void IOCP_test() {
// sleep을 안걸었는데.. 왜 5개 스레드가 모두 작동할까?
// cout 같은 IO 인터럽트가 워커 스레드에서 호출되면 IOCP에서 그 스레드는 작업 중이 아닌 스레드로 판단하는 것 같다.
int workerThreadCount = 5;
HANDLE hIOCP = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 2);
vector<HANDLE> workerThreadVector;
DWORD NumberOfByteTransfered = 0;
VOID* CompletionKey = NULL;
OVERLAPPED* overlappedPointer = NULL;
for (DWORD i = 0; i < workerThreadCount; i++)
{
HANDLE WorkerThread = CreateThread(NULL, 0, myCallBack, hIOCP, 0, NULL);
workerThreadVector.push_back(WorkerThread);
}
myOverlapped a1;
a1.number = 1;
myOverlapped a2;
a2.number = 2;
myOverlapped a3;
a3.number = 3;
myOverlapped a4;
a4.number = 4;
myOverlapped a5;
a5.number = 5;
if (hIOCP) {
PostQueuedCompletionStatus(hIOCP, 0, 0, (LPOVERLAPPED)&a1);
PostQueuedCompletionStatus(hIOCP, 0, 0, (LPOVERLAPPED)&a2);
PostQueuedCompletionStatus(hIOCP, 0, 0, (LPOVERLAPPED)&a3);
PostQueuedCompletionStatus(hIOCP, 0, 0, (LPOVERLAPPED)&a4);
PostQueuedCompletionStatus(hIOCP, 0, 0, (LPOVERLAPPED)&a5);
}
char key;
while (true) {
key = _getch();
cout << iocp_test;
if (key == 'e') {
break;
}
if (key == 'n') {
cout << endl;
}
}
for (DWORD i = 0; i < workerThreadVector.size(); i++)
{
CloseHandle(workerThreadVector[i]);
}
if (hIOCP) {
CloseHandle(hIOCP);
}
}
//IOCP_test::IOCP_test();
}
int main()
{
IOCP_test::IOCP_test();
_CrtDumpMemoryLeaks();
return 0;
}

Enumerating subkeys with CSettingsStore

I have been looking at using CSettingsStore class.
I know how to read a value from the registry. Example:
CSettingsStore store(TRUE, TRUE);
if (store.Open(_T("Software\\TruckleSoft\\VisitsRota")))
{
if (store.Read(_T("AppPath"), m_strPathVisitsRota))
{
//yes, but is the path still valid
if (!PathFileExists(m_strPathVisitsRota))
{
// it exists
m_strPathVisitsRota = _T("");
}
}
}
Now, in the documentation is states:
The security access depends on the bReadOnly parameter. If bReadonly is FALSE, the security access will be set to KEY_ALL_ACCESS. If bReadyOnly is TRUE, the security access will be set to a combination of KEY_QUERY_VALUE, KEY_NOTIFY and KEY_ENUMERATE_SUB_KEYS.
So it implies you can enumerate sub keys. But I can't find an example explaining about to enumerate a set of key / value pairs using this class.
Note that KEY_ENUMERATE_SUB_KEYS is a flag which request access to enumerate the subkeys, it doesn't actually do it.
KEY_ALL_ACCESS is a combination of different flags, including KEY_ENUMERATE_SUB_KEYS. So in both cases enumeration access is requested.
To enumerate values we need ::RegEnumValue API, this method is not wrapped in CRegKey, but it doesn't matter, we can get HKEY directly.
Here is example, based on your code and Microsoft sample
void CMySettingsStore::EnumKeys(std::vector<CString>& vec)
{
vec.clear();
DWORD subkey_total;
if (ERROR_SUCCESS != RegQueryInfoKey(m_reg.m_hKey, NULL, NULL, NULL,
&subkey_total, NULL, NULL, NULL, NULL, NULL, NULL, NULL))
return;
wchar_t buf[1024];
for (DWORD i = 0; i < subkey_total; i++)
{
DWORD len = _countof(buf);
if (ERROR_SUCCESS == m_reg.EnumKey(i, buf, &len))
vec.push_back(buf);
}
}
void CMySettingsStore::EnumValues(std::vector<CString>& vec)
{
vec.clear();
DWORD values_total;
if (ERROR_SUCCESS != RegQueryInfoKey(m_reg.m_hKey, NULL, NULL, NULL,
NULL, NULL, NULL, &values_total, NULL, NULL, NULL, NULL))
return;
wchar_t buf[1024];
for (DWORD i = 0; i < values_total; i++)
{
DWORD len = _countof(buf);
if (ERROR_SUCCESS == RegEnumValue(m_reg.m_hKey, i, buf, &len,
NULL, NULL, NULL, NULL))
vec.push_back(buf);
}
}
Udpate from Question Author
This code does not resolve all the code analysis warnings but it does add error handling and support for obtaining the value types:
#include "stdafx.h"
#include "MySettingsStore.h"
CMySettingsStore::CMySettingsStore(BOOL bAdmin, BOOL bReadOnly)
: CSettingsStore(bAdmin, bReadOnly)
{
}
bool CMySettingsStore::EnumKeys(std::vector<CString>& vec)
{
vec.clear();
DWORD subkey_total{}, lResult{};
if (RegQueryInfoKey(m_reg.m_hKey, NULL, NULL, NULL,
&subkey_total, NULL, NULL, NULL, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
{
const DWORD dwError = ::GetLastError();
AfxMessageBox(GetLastErrorAsString(dwError), MB_OK | MB_ICONWARNING);
return false;
}
wchar_t buf[1024];
for (DWORD i = 0; i < subkey_total; i++)
{
DWORD len = _countof(buf);
lResult = m_reg.EnumKey(i, buf, &len);
if(lResult == ERROR_SUCCESS || ERROR_NO_MORE_ITEMS)
vec.push_back(buf);
}
if (lResult != ERROR_NO_MORE_ITEMS)
{
const DWORD dwError = ::GetLastError();
AfxMessageBox(GetLastErrorAsString(dwError), MB_OK | MB_ICONWARNING);
return false;
}
return true;
}
bool CMySettingsStore::EnumValues(std::map<CString, DWORD>& map)
{
map.clear();
DWORD values_total{}, dwType{}, lResult{};
if (RegQueryInfoKey(m_reg.m_hKey, NULL, NULL, NULL,
NULL, NULL, NULL, &values_total, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
{
const DWORD dwError = ::GetLastError();
AfxMessageBox(GetLastErrorAsString(dwError), MB_OK | MB_ICONWARNING);
return false;
}
wchar_t buf[1024];
for (DWORD i = 0; i < values_total; i++)
{
DWORD len = _countof(buf);
lResult = RegEnumValue(m_reg.m_hKey, i, buf, &len,
NULL, &dwType, NULL, NULL);
if(lResult == ERROR_SUCCESS || lResult == ERROR_NO_MORE_ITEMS)
map.emplace(buf, dwType);
}
if (lResult != ERROR_NO_MORE_ITEMS)
{
const DWORD dwError = ::GetLastError();
AfxMessageBox(GetLastErrorAsString(dwError), MB_OK | MB_ICONWARNING);
return false;
}
return true;
}
CString CMySettingsStore::GetLastErrorAsString(DWORD dwError)
{
LPVOID lpMsgBuf{};
CString strError;
::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
nullptr,
dwError,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR)&lpMsgBuf,
0,
nullptr);
strError = static_cast<LPTSTR>(lpMsgBuf);
LocalFree(lpMsgBuf);
return strError;
}
This answer is a work in progress.
Header
#pragma once
#include <afxsettingsstore.h>
#include <vector>
class CMySettingsStore :
public CSettingsStore
{
public:
CMySettingsStore(BOOL bAdmin, BOOL bReadOnly);
void EnumKey(std::vector<CString> &vecKeys);
};
Source
#include "pch.h"
#include "CMySettingsStore.h"
CMySettingsStore::CMySettingsStore(BOOL bAdmin, BOOL bReadOnly)
: CSettingsStore(bAdmin, bReadOnly)
{
}
void CMySettingsStore::EnumKey(std::vector<CString>& vecKeys)
{
DWORD dwIndex = 0;
long lResult = ERROR_SUCCESS;
vecKeys.clear();
while (lResult == ERROR_SUCCESS)
{
CString strSubKey;
DWORD dwLength = _MAX_PATH;
lResult = m_reg.EnumKey(dwIndex, strSubKey.GetBuffer(_MAX_PATH), &dwLength);
strSubKey.ReleaseBuffer();
dwIndex++;
vecKeys.push_back(strSubKey);
}
}
Test Code
Code assumes there is a CListBox control on your dialog:
CMySettingsStore mySettings(FALSE, TRUE);
if (mySettings.Open(_T("Software\\xxxx")))
{
std::vector<CString> list;
mySettings.EnumKey(list);
mySettings.Close();
for (const auto& strSubKey : list)
{
m_lbData.AddString(strSubKey);
}
}
The above works and gives me a list of subkeys for the specified key. However, I have not yet worked out how to enumerate the values in a given key.

Pthread Scheduling policy and priority

I have four threads which are waiting on a condition variable and fifth thread posts condition variable when all four threads are waiting. When I set thread priority to maximum that is 99, threads switch takes a lot of time which is far from acceptable. Can anybody please take a look and tell what's happening ?
#define N_WORK_THREADS 4
pthread_mutex_t count_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t condition_var = PTHREAD_COND_INITIALIZER;
void *functionCount1(void * arg);
void *functionCount2(void * arg);
int count = 0;
int valid = 0;
int thread_personal[N_WORK_THREADS];
static int display_thread_sched_attr(int id)
{
int policy, s;
struct sched_param param;
s = pthread_getschedparam(pthread_self(), &policy, &param);
if (s != 0) { printf("pthread_getschedparam"); return 1; }
printf("Thread Id=%d policy=%s, priority=%d\n",id,
(policy == SCHED_FIFO) ? "SCHED_FIFO" : (policy == SCHED_RR) ? "SCHED_RR" : (policy == SCHED_OTHER) ? "SCHED_OTHER" : "???",
param.sched_priority);
return 0;
}
int main(void)
{
pthread_t thread_work[N_WORK_THREADS];
pthread_t thread;
int i,s;
pthread_attr_t attr;
struct sched_param param;
s = pthread_attr_init(&attr);
if (s != 0) { printf("pthread_attr_init"); return 1; }
s = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
if (s != 0) { printf("pthread_attr_setinheritsched"); return 1; }
s = pthread_attr_setschedpolicy(&attr, SCHED_RR);
if (s != 0) { printf("pthread_attr_setschedpolicy"); return 1; }
param.sched_priority = 99;
s = pthread_attr_setschedparam(&attr, &param);
if (s != 0) { printf("pthread_attr_setschedparam"); return 1; }
for (i=0; i<N_WORK_THREADS; i++) { thread_personal[i] = 0; }
for (i=0; i<N_WORK_THREADS; i++) { pthread_create( &thread_work[i], &attr, &functionCount1, (void *)i); }
param.sched_priority = 99;
s = pthread_attr_setschedparam(&attr, &param);
if (s != 0) { printf("pthread_attr_setschedparam"); return 1; }
pthread_create( &thread, &attr, &functionCount2, (void *)N_WORK_THREADS);
for (i=0; i<N_WORK_THREADS; i++) { pthread_join( thread_work[i], NULL); }
pthread_join( thread, NULL);
for (i=0; i<N_WORK_THREADS; i++) { printf("Thread Id=%d Mutex USed=%d\n",i,thread_personal[i]); }
exit(EXIT_SUCCESS);
}
void *functionCount1(void * arg)
{
int i;
int id = (int) arg;
display_thread_sched_attr(id);
for(i=0; i<10; i++)
{
pthread_mutex_lock( &count_mutex );
thread_personal[id] += 1;
while (((count>>id) & 0x1) == 0)
{
pthread_cond_wait( &condition_var, &count_mutex );
}
count = count^ (1<<id);
printf("Thread Id %d: Valid = %d\n",id,valid);
pthread_mutex_unlock( &count_mutex );
}
return NULL;
}
void *functionCount2(void * arg)
{
int check;
int id = (int) arg;
display_thread_sched_attr(id);
check =0;
while (check < 10)
{
pthread_mutex_lock( &count_mutex );
if (count == 0)
{
pthread_cond_broadcast ( &condition_var );
count =0xF;
printf("Thread Id %d: Counter = %d\n",id,check);
valid = check++;
}
pthread_mutex_unlock( &count_mutex );
}
return NULL;
}
I'm unable to test your program with the scheduling policy code enabled because the program simply doesn't work when that's in there (as I mention in a comment: Linux 3.16.0 x86_64 with gcc 4.8.4).
But I'm guessing that your problem might be due to the loop in functionCount2():
while (check < 10)
{
pthread_mutex_lock( &count_mutex );
if (count == 0)
{
pthread_cond_broadcast ( &condition_var );
count =0xF;
printf("Thread Id %d: Counter = %d\n",id,check);
valid = check++;
}
pthread_mutex_unlock( &count_mutex );
}
In general, acquisition of mutex objects in pthreads is not guaranteed to be fair or FIFO (though to be honest, I'm not sure how thread scheduling policies might affect it). What I believe is happening is that this loop releases count_mutex then immediately re-acquires it even though other threads are blocked waiting to claim the mutex. And with the scheduling policy in place, this may occur until the thread uses its quantum.

Remote Code injection in Win 7 SP 1 using NtCreateThreadEx API

I am trying to learn how to inject code into a running process using NtCreateThreadEx. I found few tutorials online and tried the code shown below which basically tries to inject a piece of code to a a running notepad.exe. Code injection to notepad.exe was successful; however, this program crashes just after injection (i.e., after calling funNtCreateThreadEx) throwing following error:
Run-Time Check Failure #2 - Stack around the variable 'temp2' was corrupted.
Could someone help me explaining why I am getting this error? I tried to Google about this error and figured out its something related to memory overflow. However, I don't see any memory overflow in this following code. Please let me know what could be the reason for the above error. Thank you so much for your time.
HANDLE NtCreateThreadEx(HANDLE process, LPTHREAD_START_ROUTINE Start, LPVOID lpParameter);
typedef NTSTATUS(WINAPI *LPFUN_NtCreateThreadEx)
(
OUT PHANDLE hThread,
IN ACCESS_MASK DesiredAccess,
IN LPVOID ObjectAttributes,
IN HANDLE ProcessHandle,
IN LPTHREAD_START_ROUTINE lpStartAddress,
IN LPVOID lpParameter,
IN BOOL CreateSuspended,
IN DWORD StackZeroBits,
IN DWORD SizeOfStackCommit,
IN DWORD SizeOfStackReserve,
OUT LPVOID lpBytesBuffer
);
struct NtCreateThreadExBuffer
{
ULONG Size;
ULONG Unknown1;
ULONG Unknown2;
PULONG Unknown3;
ULONG Unknown4;
ULONG Unknown5;
ULONG Unknown6;
PULONG Unknown7;
ULONG Unknown8;
};
HANDLE NtCreateThreadEx(HANDLE process, LPTHREAD_START_ROUTINE Start, LPVOID lpParameter) {
HMODULE modNtDll = LoadLibrary(L"ntdll.dll");
if (!modNtDll) {
std::cout << "Error loading ntdll.dll" << std::endl;
return 0;
}
LPFUN_NtCreateThreadEx funNtCreateThreadEx = (LPFUN_NtCreateThreadEx)GetProcAddress(modNtDll, "NtCreateThreadEx");
if (!funNtCreateThreadEx) {
std::cout << "Error loading NtCreateThreadEx()" << std::endl;
return 0;
}
NtCreateThreadExBuffer ntbuffer;
memset(&ntbuffer, 0, sizeof(NtCreateThreadExBuffer));
DWORD temp1 = 0;
DWORD temp2 = 0;
ntbuffer.Size = sizeof(NtCreateThreadExBuffer);
ntbuffer.Unknown1 = 0x10003;
ntbuffer.Unknown2 = 0x8;
ntbuffer.Unknown3 = &temp2;
ntbuffer.Unknown4 = 0;
ntbuffer.Unknown5 = 0x10004;
ntbuffer.Unknown6 = 4;
ntbuffer.Unknown7 = &temp1;
// ntbuffer.Unknown8 = 0;
HANDLE hThread;
NTSTATUS status = funNtCreateThreadEx(
&hThread,
0x1FFFFF,
NULL,
process,
(LPTHREAD_START_ROUTINE)Start,
lpParameter,
FALSE, //start instantly
0, //null
0, //null
0, //null
&ntbuffer
);
return hThread;
}
int main()
{
int res = -1;
res = privileges(); //get all required privileges
DWORD pid = getPid(L"notepad.exe");
if (pid == 0)
return PROCESS_NOT_FOUND; //error
HANDLE p;
p = OpenProcess(PROCESS_ALL_ACCESS, false, pid);
if (p == NULL) return OPEN_PROCESS_FAILED; //error
char * mytext = "Hello by CodeCave!";
char * mycaption = "Injection result";
PARAMETERS data; //let's fill in a PARAMETERS struct
HMODULE user32 = LoadLibrary(L"User32.dll");
data.MessageBoxInj = (DWORD)GetProcAddress(user32, "MessageBoxA");
strcpy_s(data.text, mytext);
strcpy_s(data.caption, mycaption);
data.buttons = MB_OKCANCEL | MB_ICONQUESTION;
//Writing funtion to notepad memory
DWORD size_myFunc = 0x8000; //Creating more memory than required
LPVOID MyFuncAddress = VirtualAllocEx(p, NULL, size_myFunc, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(p, MyFuncAddress, (void*)myFunc, 0x1000, NULL);
//Parameters to the function to notepad's memory
LPVOID DataAddress = VirtualAllocEx(p, NULL, sizeof(PARAMETERS), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(p, DataAddress, &data, sizeof(PARAMETERS), NULL);
//invokes injected function
HANDLE thread = NtCreateThreadEx(p, (LPTHREAD_START_ROUTINE)MyFuncAddress, DataAddress);
if (thread != 0) {
//injection completed, not we can wait it to end and free the memory
}
return 0;
}
static DWORD myFunc(PARAMETERS * myparam) {
MsgBoxParam MsgBox = (MsgBoxParam)myparam->MessageBoxInj;
int result = MsgBox(0, myparam->text, myparam->caption, myparam->buttons);
switch (result) {
case IDOK:
//your code
break;
case IDCANCEL:
//your code
break;
}
return 0;
}
int privileges() {
HANDLE Token;
TOKEN_PRIVILEGES tp;
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &Token))
{
LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid);
tp.PrivilegeCount = 1;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (AdjustTokenPrivileges(Token, 0, &tp, sizeof(tp), NULL, NULL) == 0) {
return 1; //FAIL
}
else {
return 0; //SUCCESS
}
}
return 1;
}
typedef int (WINAPI* MsgBoxParam)(HWND, LPCSTR, LPCSTR, UINT);
struct PARAMETERS {
DWORD MessageBoxInj;
char text[50];
char caption[25];
int buttons;
};
DWORD myFunc(PARAMETERS * myparam);

Multithread decoding of Video PID of Mpeg2Ts using FFMPEG

I'm working on an app in VC++ to display video frames of a video Pid of mpeg2ts stream using FFMPEG and need to do the same, for other mpeg2stream simultaneously by using multi thread process,my source code is:
int main (int argc, char* argv[])
{
av_register_all();
avformat_network_init();
pFormatCtx = avformat_alloc_context();
if(avformat_open_input(&pFormatCtx,filepath,NULL,NULL)!=0){
printf("Couldn't open input stream.\n");
return -1;
}
if(avformat_find_stream_info(pFormatCtx,NULL)<0){
printf("Couldn't find stream information.\n");
return -1;
}
videoindex=-1;
for(i=0; i<pFormatCtx->nb_streams; i++)
if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO){
videoindex=i;
break;
}
if(videoindex==-1){
printf("Didn't find a video stream.\n");
return -1;
}
pCodecCtx=pFormatCtx->streams[videoindex]->codec;
pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
if(pCodec==NULL){
printf("Codec not found.\n");
return -1;
}
if(avcodec_open2(pCodecCtx, pCodec,NULL)<0){
printf("Could not open codec.\n");
return -1;
}
pFrame=av_frame_alloc();
pFrameYUV=av_frame_alloc();
out_buffer=(uint8_t *)av_malloc(avpicture_get_size(PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height));
avpicture_fill((AVPicture *)pFrameYUV, out_buffer, PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height);
packet=(AVPacket *)av_malloc(sizeof(AVPacket));
//Output Info-----------------------------
printf("--------------- File Information ----------------\n");
av_dump_format(pFormatCtx,0,filepath,0);
printf("-------------------------------------------------\n");
img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt,
pCodecCtx->width, pCodecCtx->height, PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);
#if OUTPUT_YUV420P
fp_yuv=fopen("output.yuv","wb+");
#endif
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) {
printf( "Could not initialize SDL - %s\n", SDL_GetError());
return -1;
}
screen_w = pCodecCtx->width;
screen_h = pCodecCtx->height;
//SDL 2.0 Support for multiple windows
screen = SDL_CreateWindow("Simplest ffmpeg player's Window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
screen_w, screen_h, SDL_WINDOW_OPENGL);
if(!screen) {
printf("SDL: could not create window - exiting:%s\n",SDL_GetError());
return -1;
}
sdlRenderer = SDL_CreateRenderer(screen, -1, 0);
//IYUV: Y + U + V (3 planes)
//YV12: Y + V + U (3 planes)
sdlTexture = SDL_CreateTexture(sdlRenderer, SDL_PIXELFORMAT_IYUV, SDL_TEXTUREACCESS_STREAMING,pCodecCtx->width,pCodecCtx->height);
sdlRect.x=0;
sdlRect.y=0;
sdlRect.w=screen_w;
sdlRect.h=screen_h;
//SDL End----------------------
BYTE buffer [4] ;
int nSize = 0 ;
int nByteCnt = 0 ;
int nPreviuosPos = 0 ;
mpgfile = fopen ("D:\\00_Projects\\Farzan II\\SampleData\\Yahsat1996V_N_PID(2101).pes", "rb");
while(av_read_frame(pFormatCtx, packet)>=0 /*&& nSize > 0*/)
{
if(packet->stream_index==videoindex)
{
ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet);
if(ret < 0)
{
printf("Decode Error.\n");
return -1;
}
if(got_picture)
{
sws_scale(img_convert_ctx, (const uint8_t* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height,
pFrameYUV->data, pFrameYUV->linesize);
#if OUTPUT_YUV420P
y_size=pCodecCtx->width*pCodecCtx->height;
fwrite(pFrameYUV->data[0],1,y_size,fp_yuv); //Y
fwrite(pFrameYUV->data[1],1,y_size/4,fp_yuv); //U
fwrite(pFrameYUV->data[2],1,y_size/4,fp_yuv); //V
#endif
//SDL---------------------------
#if 0
SDL_UpdateTexture( sdlTexture, NULL, pFrameYUV->data[0], pFrameYUV->linesize[0] );
#else
SDL_UpdateYUVTexture(sdlTexture, &sdlRect,
pFrameYUV->data[0], pFrameYUV->linesize[0],
pFrameYUV->data[1], pFrameYUV->linesize[1],
pFrameYUV->data[2], pFrameYUV->linesize[2]);
#endif
SDL_RenderClear( sdlRenderer );
SDL_RenderCopy( sdlRenderer, sdlTexture, NULL, &sdlRect);
SDL_RenderPresent( sdlRenderer );
//SDL End-----------------------
//Delay 40ms
SDL_Delay(40);
}
}
av_free_packet(packet);
}
//flush decoder
//FIX: Flush Frames remained in Codec
while (1) {
ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet);
if (ret < 0)
break;
if (!got_picture)
break;
sws_scale(img_convert_ctx, (const uint8_t* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height,
pFrameYUV->data, pFrameYUV->linesize);
#if OUTPUT_YUV420P
int y_size=pCodecCtx->width*pCodecCtx->height;
fwrite(pFrameYUV->data[0],1,y_size,fp_yuv); //Y
fwrite(pFrameYUV->data[1],1,y_size/4,fp_yuv); //U
fwrite(pFrameYUV->data[2],1,y_size/4,fp_yuv); //V
#endif
//SDL---------------------------
SDL_UpdateTexture( sdlTexture, &sdlRect, pFrameYUV->data[0], pFrameYUV->linesize[0] );
SDL_RenderClear( sdlRenderer );
SDL_RenderCopy( sdlRenderer, sdlTexture, NULL, &sdlRect);
SDL_RenderPresent( sdlRenderer );
//SDL End-----------------------
//Delay 40ms
SDL_Delay(40);
}
sws_freeContext(img_convert_ctx);
#if OUTPUT_YUV420P
fclose(fp_yuv);
#endif
SDL_Quit();
av_frame_free(&pFrameYUV);
av_frame_free(&pFrame);
avcodec_close(pCodecCtx);
avformat_close_input(&pFormatCtx);
return 0;
}
it works well when i call it in One thread but,after calling this function in multi thread ,the error of access violation occurred , is there anyone to guide me to solution?

Resources