This is my first time dealing with windows. I tried to create thread, but I can't compile my code.
This is a part of my code:
WORD _tid;
HANDLE readerThread= CreateThread(0,0,readFromPort,0,0,&_tid);
DWORD WINAPI readFromPort(LPVOID lpParam ){}
I also tried :
LPDWORD_tid;
HANDLE readerThread= CreateThread(0,0,readFromPort,0,0,_tid);
DWORD WINAPI readFromPort(LPVOID lpParam ){}
Neither compiled. onyone knows what is the problem?
(I'm using windows xp)
thanks.
well, don't know what's error you have. But can provide a good example to you
#include "windows.h"
DWORD WINAPI readFromPort(LPVOID lpParam ){return 0;}
int _tmain(int argc, _TCHAR* argv[])
{
DWORD _tid;
HANDLE readerThread= CreateThread(0,0,readFromPort,0,0,&_tid);
return 0;
}
difference to yours:
_tid is DWORD, not WORD.
the readFromPort returns value 0.
Let me guess: readFromPort must return a value?
Next time please add the error also.
Well, it would have been nice if you have provided a minimal code example and at least a compilation error. But fine, I will pretend to be a compiler. Assuming that your code snippet is inside a function, you have a function declaration in there:
DWORD WINAPI readFromPort(LPVOID lpParam ){}
I believe that is screwing you up. You have to declare/define functions outside other function's scope.
Also, readFromPort function is declared after the call to CreateThread where it is being referenced as a parameter. So it won't work even if you put all of that in a global scope (which is a bad idea in itself).
Related
I have read a lot about how to change the WinMain entry point procedure, some say you can change the entry point from the linker and some others say you can put the WinMain into DLL (dllMain) and so on.
Honestly, I am confused. I believe that there are one or more ways to change the entry point procedure to a custom procedure because there are some examples like MFC don't have a direct WinMain function and the Qt framework also has a custom entry point procedure it's similar to the console application main function int main(int argc, char *argv[]), so, there are ways as I expected.
I want a whatever way to replace/change the entry point procedure for GUI application on Windows from the traditional procedural WinMain to int main(int argc, char *argv[]) like Qt or even any other custom function but it must be compatible with (MS, GCC, Clang) compilers.
///////////Windows main/////////////
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR cmdParam, int cmdShow){
}
///////////Console main and Qt framework////////////
int main(int argc, char *argv[]) {
}
//////////MFC////////////
class CMyFrame : public CFrameWnd {
public:
CMyFrame() {}
};
class CExample : public CWinApp {
BOOL InitInstance() {}
};
CExample theApp;
How do I do that?
entry point of exe can by any function with signature
ULONG CALLBACK ep(void* )
possible and use ULONG CALLBACK ep() - despite on x86 will be wrong stack pointer (esp) after return, this not lead to error, because windows just call ExitThread after entry return, if it return control at all - usually it call ExitProcess instead return.
the name of this entry point of course not play any role at all - it can be any valid c/c++ name. entry point found/called not by name but by AddressOfEntryPoint offset from IMAGE_OPTIONAL_HEADER
but when we build PE - we need tell linker name of this function, for it can set AddressOfEntryPoint, but this info (name of function) used only during build process (not used in runtime)
different linkers of course have different options for do this, link.exe have option /ENTRY. this option is optional and by default, the starting address is a function name from the C run-time library.
if /ENTRY:MyEntry explicitly stated - it used as is - MyEntry will be used as entry point. if no /ENTRY option set - used default:
if /SUBSYSTEM:CONSOLE set - used mainCRTStartup or if it not found wmainCRTStartup
if /SUBSYSTEM:WINDOWS set - used WinMainCRTStartup or if it not found wWinMainCRTStartup
but in most case c/c++ developers use CRT libraries. regardless of whether static or dynamic linking used with CRT - some lib code always statically linked with your exe and this code containing function which you used as entry point. for ms windows crt - this is mainCRTStartup or wmainCRTStartup (for console apps), WinMainCRTStartup or wWinMainCRTStartup for gui apps.
in all this 4 functions - called hardcoded function by name
mainCRTStartup call main
wmainCRTStartup call wmain
WinMainCRTStartup call WinMain
wWinMainCRTStartup call wWinMain
of course called function must be implemented somewhere in your code or in another lib code. for example if you use MFC - it implement wWinMain by self and called your code in another way ( via calling virtual functions on object which you override - InitApplication and InitInstance)
if back to question how change name of your custom entry point - but for what ? you really not need change name. you need only understand how your entry point is called. if you understand this - you can do almost all.
assume we want use main as "entry point". i take this in quotes because we really want have real entry point in CRT code and we want that CRT code call exactly main function.
possible ? simply !
set /ENTRY: mainCRTStartup linker option. so mainCRTStartup will be real entry point and it call main.
another question, i personally think that this is senseless trick, which nothing change and nothing give
also possible simply call main from WinMain
typedef struct
{
int newmode;
} _startupinfo;
/*
* new mode flag -- when set, makes malloc() behave like new()
*/
EXTERN_C _CRTIMP int __cdecl _query_new_mode( );
EXTERN_C _CRTIMP int __cdecl _set_new_mode( _In_ int _NewMode);
EXTERN_C
_CRTIMP int __cdecl __getmainargs(__out int * _Argc,
__deref_out_ecount(*_Argc) char *** _Argv,
__deref_out_opt char *** _Env,
__in int _DoWildCard,
__in _startupinfo * _StartInfo);
int __cdecl main(__in int _Argc, __in_ecount_z(_Argc) char ** _Argv, ...);
int CALLBACK WinMain( _In_ HINSTANCE , _In_opt_ HINSTANCE , _In_ LPSTR , _In_ int )
{
int _Argc, r;
char ** _Argv;
char ** _Env;
_startupinfo _StartInfo { _query_new_mode( ) };
if (!(r = __getmainargs(&_Argc, &_Argv, &_Env, 0, &_StartInfo)))
{
r = main(_Argc, _Argv, _Env);
if (_Argv) free(_Argv);
}
return r;
}
it must be compatible with (MS, GCC, Clang) compilers
How you do that depends on your compiler. Most of them will have some flags to choose which "subsystem" (the Windows term) you are targeting and even customize the entry point manually.
Put another way, there is no standard way of doing so because this is outside the scope of the C++ standard.
Having said that, some compilers provide the means to emulate the flags of other compilers. For instance, Clang can imitate Microsoft's.
Feeling stupid here but why is this code giving me a syntax error in Visual
Studio when trying to compile it?
DetourAttach(&(PVOID&)true_create_file, create_file);
The compiler complains with (underlining the & after PVOID)
Error (active) E0018 expected a ')'
The code is literally copied from the Detours example page. I'm assuming it is because my containing file has a .c extension and is thus compiled as C by VS while the example has a .cpp extension and is compiled as C++.
I'm not entirely sure what's going on in this line with all the casting. Why doesn't the C compiler like it and how do I get it to compile this line?
Here's the complete listing of the code:
#include <Windows.h>
#include "detours.h"
#pragma comment(lib, "detours.lib")
static HANDLE(WINAPI *true_create_file) (LPCSTR file, DWORD access,
DWORD share, LPSECURITY_ATTRIBUTES sec, DWORD disp, DWORD flags,
HANDLE tmpl) = CreateFileA;
HANDLE WINAPI create_file(LPCSTR file, DWORD access, DWORD share,
LPSECURITY_ATTRIBUTES sec, DWORD disp, DWORD flags, HANDLE tmpl) {
}
int hook_create_file() {
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
/* syntax error */
DetourAttach(&(PVOID&)true_create_file, create_file);
DetourTransactionCommit();
}
PVOID is defined as
typedef void *PVOID;
The &(PVOID&) part: cast the parameter to a reference to a pointer to void first, and then taking the address of that. As comment point out, you compile it as C, but the reference operation do not exist in C. So the compiler recognizes "&" as taking address, but only ")" behind it, then get the expected a ')' error.
Since PVOID& doesn't make sense here, just to increase readability. You could use PVOIDinstead of PVOID& here:
DetourAttach(&(PVOID)true_create_file, create_file);
You could also get the DetourAttach function details from here.
Okay so I'm coming dangerously close to a repost here but my situation is a little bit different than the numerous other posters about this function. I am interfacing with a DLL that was written way back in the day and all I have is the file. I don't have a .lib file so I'm using the LoadLibrary and GetProcessAddress functions. I followed the tutorial on the MSDN website to get the basic structure. the DLL is located in the project folder. it compiles. at run time, I am getting a numerical value for "hinstLib" so I'm assuming the DLL was found. I am getting a null value for "ProcAdd" variable. Other posters had there issues resolved by putting extern C in the DLL functions but I don't really have that option. not to mention, to my knowledge this DLL was written in plain C. I do have an interface document and am quite sure I have the function name correct (replaced with a generic example for these purposes). I honestly didn't run anything past the ProcAdd assignment because it came out NULL. Any thoughts as to why this is giving me a 0 value for the function assignment would be great appreciated. Note: unfortunately due to various reasons I can't upload the DLL.
#include <iostream>
#include "stdafx.h"
#include "Windows.h"
#include <stdio.h>
typedef int(__cdecl *MYPROC)(LPWSTR);
using namespace std;
int main()
{
HINSTANCE hinstLib;
MYPROC ProcAdd;
BOOL fFreeResult, fRunTimeLinkSuccess = FALSE;
hinstLib = LoadLibrary(TEXT("dllName.dll"));
if (hinstLib != NULL)
{
ProcAdd = (MYPROC) GetProcAddress(hinstLib, "funcName");
// If the function address is valid, call the function.
if (NULL != ProcAdd)
{
fRunTimeLinkSuccess = TRUE;
//(ProcAdd) (L"Message sent to the DLL function\n");
}
// Free the DLL module.
fFreeResult = FreeLibrary(hinstLib);
}
// If unable to call the DLL function, use an alternative.
if (! fRunTimeLinkSuccess)
printf("Message printed from executable\n");
return 0;
}
Compilers usually mangle function names, then a function named funcName may appear inside the DLL with a name funcName#16 , for example... It depends on calling convention and are important for a function to be called properly. For __cdecl calling convention you probably need _funcName :-) .
I have the following code:
#include <windows.h>
class systemfunctions
{
public:
void (*sleep) (DWORD ms);
systemfunctions ()
{
sleep = reinterpret_cast<void>(Sleep);
}
} sys;
When I call sys.sleep(), the application crashes. Why does the program crash, and what can I do to resolve the problem?
Windows.h declares Sleep() like WINBASEAPI VOID WINAPI Sleep(__in DWORD dwMilliseconds);, try telling the compiler it needs to use the proper calling convention when it uses that pointer:
typedef VOID (WINAPI * SleepFunction)(DWORD ms);
SleepFunction sleep;
sleep = Sleep;
The only time you should cast a function pointer is when using the return value from GetProcAddress.
Get rid of the cast, and then the compiler will tell you what is wrong.
i want to read a file.. but.. when i debug my program it runs but a pop up appears and says system programming has stopped working and in the console, it`s written that Press enter to close the program. my code is ::
// System Programming.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "iostream"
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hin;
HANDLE hout;
TCHAR buff[20]= {'q','2','3'};
TCHAR buff2[20]={'a','v'};
hin = CreateFile(_T("Abid.txt"),GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
if(hin == INVALID_HANDLE_VALUE)
{
cout<<"error";
}
WriteFile(hin,buff,40,0,NULL);
CloseHandle(hin);
hout = CreateFile(_T("Abid.txt"),GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
if(hout == INVALID_HANDLE_VALUE)
{
cout<<"error";
}
ReadFile(hout,buff2,40,0,NULL);
CloseHandle(hout);
return 0;
}
According to MSDN, lpNumberOfBytesWritten paremeter can be NULL only when the lpOverlapped parameter is not NULL. So the calls should be
DWORD nWritten;
WriteFile(hin, buff, 40, &nWritten, NULL);
and
DWORD nRead;
ReadFile(hout, buff2, 40, &nRead, NULL);
Also, rename hin and hout.
Others have already answered your question. This is about the code.
// Your code:
// System Programming.cpp : Defines the entry point for the console application.
//
Just remove that comment. It isn't true. :-) The entry point for your program is where the machine code starts executing, and with the Microsoft toolchain it's specified by the /entry linker option.
Note that Microsoft's documentation is generally confused about entry points, e.g. it has always, one way or other, documented incorrect signature for entry point.
It's one of the most infamous Microsoft documentation errors, and, given that it's persisted, in various forms, for 15 years, I think it says something (not sure exactly what, though).
// Your code:
#include "stdafx.h"
You don't need this automatically generated header. Instead use <windows.h>. A minimal way to include <windows.h> for your program would be
#undef UNICODE
#define UNICODE
#include <windows.h>
For C++ in general you'll want to also make sure that STRICT and NOMINMAX are defined before including <windows.h>. With modern tools at least STRICT is defined by default, but it doesn't hurt to make sure. Without it some of declarations won't compile with a C++ compiler, at least not without reinterpret casts, e.g. dialog procedures.
// Your code:
#include "iostream"
using namespace std;
Almost OK.
Do this:
#include <iostream>
using namespace std;
The difference is where the compiler searches for headers. With quoted name it searches in some additional places first (and that's all that the standard has to say about it). With most compilers those additional places include the directory of the including file.
// Your code:
int _tmain(int argc, _TCHAR* argv[])
Oh no! Don't do this. It's a Microsoft "feature" that helps support Windows 9.x. And it's only relevant when you're using MFC linked dynamically and you're targeting Windows 9.x; without MFC in the picture you'd just use the Microsoft Unicode layer.
Area you really targeting Windows 9.x with an app using dynamically linked MFC?
Instead, do ...
int main()
... which is standard, or use the Microsoft language extension ...
int wMain( int argc, wchar_t* argv[] )
... if you want to handle command line arguments the "easy" way.
// Your code:
{
HANDLE hin;
HANDLE hout;
TCHAR buff[20]= {'q','2','3'};
TCHAR buff2[20]={'a','v'};
The TCHAR stuff is just more of that MFC in Windows 9.x support stuff.
Apart from being totally unnecessary (presumably, you're not really targeting Windows 9.x, are you?), it hides your intention and hurts the eyes.
Did you mean ...
char buff[20] = {'q', '2', '3'};
... perhaps?
// Your code:
hin = CreateFile(_T("Abid.txt"),GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
if(hin == INVALID_HANDLE_VALUE)
{
cout<<"error";
}
As others have mentioned, OPEN_EXISTING isn't logical when you're creating the file, and the count pointer argument can't be 0 for your usage.
When using <windows.h>, with UNICODE defined as it should be, the filename argument should be specifed as L"Abid.txt".
Cheers & hth.,
The problem is that you're passing a NULL pointer in for the lpNumberOfBytesWritten/lpNumberOfBytesread parameter. While this is an optional parameter, there's a condition:
This parameter can be NULL only when the lpOverlapped parameter is not NULL
Also, you may have the size of your buffers wrong:
WriteFile(hin,buff,40,0,NULL); // says that buff has 40 bytes
ReadFile(hout,buff2,40,0,NULL); // says that buff2 has 40 bytes
But if you're compiling for ANSI instead of UNICODE, these will only be 20 bytes in size.
You should probably use sizeof(buff) and sizeof(buff2) instead.
Assuming your initial code attempts to create the file as a new file, then you cannot use OPEN_EXISTING, you have to use OPEN_ALWAYS (or some other creational variant) on this call.
The OPEN_EXISTING usage for readback will be OK.
btw once this is fixed the WriteFile calls causes an access violation, as you are trying to write more bytes that your array contains.