How to pass function pointer as lpParameter to CreateThread? - c++

I have the following function which will be called by CreateThread:
DWORD WINAPI start_thread(LPVOID handleFunction)
{
int prio = 4;
// call handleFunction()
handleFunction(prio);
return TRUE;
}
And I create the thread here:
DECL_PREFIX tid_t so_fork(so_handler *handleFunction, unsigned priority) {
DWORD dw;
hThr[currentThread] = CreateThread(
NULL, // default security attributes
0, // use default stack size
(LPTHREAD_START_ROUTINE)start_thread, // thread function name
(LPVOID)&handleFunction, // argument to thread function
0, // use default creation flags
&dw); // returns the thread identifier
return 0;
}
I get the following error when I am builind it:
Error C2064 term does not evaluate to a function taking 1 arguments libscheduler
expression preceding parentheses of apparent call must have (pointer-to-) function type libscheduler
What am I doing it wrong?

Passing &handleFunction to CreateThread() is wrong, because you are passing the local address of the handleFunction variable itself, not the address of the so_handler that it is pointing at.
Since handleFunction is already a pointer, try something more like this instead:
DWORD WINAPI start_thread(LPVOID handleFunction)
{
int prio = 4;
// call handleFunction()
so_handler *handler = (so_handler *) handleFunction;
handler(prio); // or maybe (*handler)(prio), depending on how so_handler is actually defined...
return TRUE;
}
DECL_PREFIX tid_t so_fork(so_handler *handleFunction, unsigned priority) {
DWORD dw;
hThr[currentThread] = CreateThread(
NULL, // default security attributes
0, // use default stack size
&start_thread, // thread function name
handleFunction, // argument to thread function
0, // use default creation flags
&dw); // returns the thread identifier
return 0;
}

Related

sending a struct with MapViewOfFile and reading an unknown value

I am basically trying to cast or copy my struct to my other process section view but I keep getting an error
C2760: syntax error: unexpected token 'identifier', expected 'declaration'
This is what I am doing:
type RPM(UINT_PTR ReadAddress)
{
if (hDriver == INVALID_HANDLE_VALUE) {
return {};
}
DWORD64 Bytes;
KM_READ_REQUEST ReadRequest{};
type response{};
ReadRequest.ProcessId = PID;
ReadRequest.Address = ReadAddress;
ReadRequest.Size = sizeof(type);
ReadRequest.Output = &response;
The problem is here:
auto pBuf = (ReadRequest)MapViewOfFile(hMapFile, FILE_MAP_WRITE, 0, 0, 4096);
if (!pBuf)
{
printf("OpenFileMappingA(write) fail! Error: %u\n", GetLastError());
system("pause");
}
printf("MapViewOfFile(write) created ! \n");
I am having another problem trying to read an unknown value from my kernel driver. It basically reads memory and then changes that value to another thing based on what I am reading from if its int, float, etc..
PKM_READ_REQUEST ReadInput = (PKM_READ_REQUEST)SharedSection; // cast readRequest to our struct which is in SharedSection.
void* ReadOutput = ReadInput->Output;
Status = ReadKernelMemory(Process, ReadInput->Address, ReadOutput, ReadInput->Size);
I am trying to copy it to my shared section so I can read it from user mode, but idk how to cast it or what the value would be.
memcpy(SharedSection, &ReadOutput, sizeof(ReadOutput));
This is how I want to try to read it, but cast it as the same way because I don't want to read it as void, I want to read it as the value that was given from my kernel mode.
auto pBuf = MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 4096);
if (!pBuf)
{
printf("OpenFileMappingA(write) fail! Error: %u\n", GetLastError());
system("pause");
}
printf("MapViewOfFile(write) created ! \n");
BTW, I am using the un-documented function mmcopyvirtualmemory in my kernel driver.
1.
auto pBuf = (ReadRequest)MapViewOfFile(hMapFile, FILE_MAP_WRITE, 0, 0, 4096);
The ReadRequest is not a type but an object, If you want to write the file map address as the struct KM_READ_REQUEST, you should convert the return pointer to the type of PKM_READ_REQUEST, and also take the control of the size of file map:
auto pBuf = (PKM_READ_REQUEST)MapViewOfFile(hMapFile, FILE_MAP_WRITE, 0, 0, sizeof(KM_READ_REQUEST));
So that you can set the PID,Address,Size and Output for it.
2.
memcpy(SharedSection, &ReadOutput, sizeof(ReadOutput));
ReadOutput is already the address of output value, So you don't
need the operation &.
Sizeof(a pointer) is always equal to 4(in 32-bit) and 8(in
64-bit);
You'd better use a new variable to store copied values, Instead of overwriting previous data。
So
type new_var;
memcpy(&new_var, ReadOutput, sizeof(KM_READ_REQUEST));
EDIT: Answer your comments,
You can set a single Event to communicate between driver and UM.
App:
hDevice = CreateFile(Device);
hEvent = CreateEvent(...);
DeviceIoControl(hDevice, IOCTL_SET_EVENT, &hEvent,...);
WaitForSingleObject(hEvent, INFINITE);
Driver:
case IOCTL_SET_EVENT:
{
HANDLE hUserEvent = *(HANDLE *)pIrp->AssociatedIrp.SystemBuffer;
status = ObReferenceObjectByHandle(hUserEvent, EVENT_MODIFY_STATE,*ExEventObjectType, KernelMode, (PVOID*)&pDevExt->pEvent, NULL);
ObDereferenceObject(pDevExt->pEvent);
break;
}
Then set event:
KeSetEvent(pdx->pEvent,...);

Win32 CreateThread() Arguments Zero'ed?

Situation
Up until yesterday, my thread code was working fine. Now though, my thread arguments are being zeroed and moved as they are passed into the thread.
Relevant code in main.cpp
//First socket: UDP | Second Socket: TCP
std::pair<SOCKET, SOCKET> ServerSockets = Network::Operations::Server();
SOCKET UDPSocket = ServerSockets.first;
//Need to pass two arguments to the thread, when it only accepts one pointer. So create a struct and send the pointer.
ListenData UDPServ;
UDPServ.pNetwork = &Network;
UDPServ.LocalUDPSocket = UDPSocket;
//Set up the listener.
HANDLE UDPListener = Network::Operations::UDPListen(UDPServ);
At this stage UDPSocket is the correct value (e.g. 103), and pNetwork is also correct.
Relevant code in UDPListen()
static HANDLE UDPListen(ListenData UDPListenData)
{
HANDLE NetworkThread;
NetworkThread = CreateThread(
NULL, //Default security
0, //Default thread stack size
Network::Operations::Listen, //Thread function name
&UDPListenData, //Thread arguments
0, //Default creation flags
NULL);
//CloseHandle(NetworkThread);
return NetworkThread;
}
At this state, the values are as they should be.
Relevant code in Listen()
static DWORD WINAPI Listen(void *param)
{
ListenData *UDPServ = (ListenData*)param;
SOCKET Socket = UDPServ->LocalUDPSocket;
std::vector<Net> *Network = UDPServ->pNetwork;
Now however, UDPSocket is zero, and pNetwork is 103. This is a mystery.
The only code I've really changed is the code to initialise the server, which I modified to incorporate binding a TCP socket. The function used to return a single SOCKET but now returns an std::pair<SOCKET, SOCKET>.
you pass pointer to local data in stack - &UDPListenData - but this data is become undefined just after UDPListen return. you may be need code like
ListenData* UDPServ = new ListenData;
// init UDPServ
HANDLE NetworkThread = CreateThread(
NULL, //Default security
0, //Default thread stack size
Network::Operations::Listen, //Thread function name
UDPServ, //Thread arguments
0, //Default creation flags
NULL);
if (!NetworkThread) delete UDPServ;
//...
static DWORD WINAPI Listen(void *param)
{
ListenData *UDPServ = (ListenData*)param;
SOCKET Socket = UDPServ->LocalUDPSocket;
std::vector<Net> *Network = UDPServ->pNetwork;
//...
delete UDPServ;
}

Usage of InternetGetConnectedStateEx

I'm trying to use InternetGetConnectedStateEx but I'm not able to retrieve lpszConnectionName. If I initialise it as 0 I don't get any value, but if I initialised with _T("hol"); I get an access violation
DWORD dwFlags;
LPTSTR lpszConnectionName = _T("hol");
DWORD dwNameLen = 3;
if (InternetGetConnectedStateEx(&dwFlags, lpszConnectionName, dwNameLen, NULL))
{
printf("Connected to internet");
}
else {
printf("not connected");
}
Thanks!
The documentation says (emphasis mine):
lpszConnectionName [out]
Pointer to a string value that receives the connection name.
That is an output parameter, that will be filled with the connection name if there is one active. Specifying the contents of this parameter yourself is a mistake, having it point to a string literal doubly so (since modifying it will trigger undefined behavior).
The appropriate way to invoke the function would be something like:
DWORD dwFlags;
TCHAR lpszConnectionName[512];
if (InternetGetConnectedStateEx(&dwFlags, lpszConnectionName,
_countof(lpszConnectionName), NULL)) {
// ...
} else {
// ...
}

C++ - Pthread how to send in value

How do I send in a std::string into my thread?
This is my code:
void* sendReminder(void*)
{
system("echo 'hello' >> buffer.txt");
}
int main()
{
string str1 = "somevalue";
pthread_t t1;
pthread_create(&t1, NULL, &sendReminder, NULL);
}
Use the fourth argument to pthread_create to send an "argument" to your function, just be sure to make a copy of it on the heap:
string *userData = new string("somevalue");
pthread_create(&t1, NULL, &sendReminder, (void *) userData);
If you'll be using pthread_join to wait on the new thread(s), suspending execution of the caller, you can get away with just passing an address of the local variable:
if (pthread_create(&t1, NULL, &sendReminder, (void *) &str1) == 0)
{
pthread_join(t1, &result);
// ...
You can retrieve the value with:
void* sendReminder(void* data)
{
std::string* userData = reinterpret_cast<std::string*>(data);
// Think about wrapping `userData` within a smart pointer.
cout << *userData << endl;
}
You pass the value in as a void* in the last argument to pthread_create. Inside the thread function, you cast the void* back to the type of the object that you passed in. In this case a string.

How can you get the return value of a Windows thread?

I was just wondering if it is possible (and if so, how) to get the return value of a thread in C++ (Windows). I have several threads, and I use WaitForMultipleObjects(...) on them. This waits until a thread is done, and returns the index of said thread, and all is well. However, I want to be able to obtain the return value of the thread that finished using its handle.
For example:
DWORD WINAPI Thread1(void *parameter){
...
if(...) return 0;
else return -1;
}
DWORD WINAPI Thread2(void *parameter){
...
if(...) return 1;
else return 0;
}
int main(){
HANDLE t1 = CreateThread(0, 0, Thread1, NULL, 0, 0);
HANDLE t2 = CreateThread(0, 0, Thread2, NULL, 0, 0);
HANDLE *threads = new HANDLE[2];
threads[0] = t1;
threads[1] = t2;
int result = WaitForMultipleObjects(2, threads, false, INFINITE);
if(result == 0){
//get the threads value here:
int retVal = SomeFunction(t1); //What is SomeFunction?
}
...
}
I have tried to use GetExitCodeThread(thread) but I'm assuming this returns a system exit code, as it always gives me a very strange integer. Does anyone know a way, or a workaround?
GetExitCodeThread is the correct function. Here is the MSDN description of what it does:
This function returns immediately. If the specified thread has not
terminated and the function succeeds, the status returned is
STILL_ACTIVE. If the thread has terminated and the function succeeds,
the status returned is one of the following values:
The exit value specified in the ExitThread or TerminateThread function.
The return value from the thread function.
The exit value of the thread's process.
The problem with most programmer is that they don't pay attention to compiler warnings. At level 4 (/W4), the compiler produces following warning when returning -1 from a function that is returning DWORD:
warning C4245: 'return' : conversion from 'int' to 'DWORD', signed/unsigned mismatch
you need to check for STILL_ACTIVE for the values one of these threads may still be active
You can use C++ 11's threads concepts using std::future.
See an example below.
int ReturnFrmThread() {
return 100;
}
int main() {
std::future<int> GetRetVal= std::async(ReturnFrmThread); // Execution of ReturnFrmThread starts
int answer = GetAnAnswer.get(); // gets value as 100;
// Waits until ReturnFrmThread has finished
}