I want to use the function QueryFullProcessImageName from winbase.h in my Qt 4.8.1 app that uses the lastest MingW version (I downloaded it lately). The problem is that this function is quite new: it was introduced in Windows Vista and I'll guess it would be avaliable with such a new version of MingW, but it's not. Microsoft MSDN sad I needed to put the appropriate define in order for this function to be avaliable, but not only that didn't solve my problem, but I also can't find the function's declaration in winbase.h by Ctrl+F anyway.
Well, how can I solve this problem? I quite need that function :X
Just another insight to my problem: http://www.qtcentre.org/threads/53769-Mingw-included-in-Qt-installator-including-old-h-files
And a quite very interesting thing: http://sourceforge.net/apps/trac/mingw-w64/browser/trunk/mingw-w64-headers/include/winbase.h?rev=5487 (it would seem that MingW does has the lastest winbase.h file, altought it didn't come with the installator)
My PC has a Windows 7 64-bit, while my Qt and Qt Creator is 32 bit.
Thanks,
Momergil
If you don't want to (or can't) move to a version of MinGW that has QyeryFullProcessImageName() in its SDK headers, then you can add the following near the end of winbase.h (make sure it's before the closing brace of the extern "C" block):
#if (_WIN32_WINNT >= 0x0600)
#define PROCESS_NAME_NATIVE 0x00000001
WINBASEAPI BOOL WINAPI QueryFullProcessImageNameA(
HANDLE hProcess,
DWORD dwFlags,
LPSTR lpExeName,
PDWORD lpdwSize
);
WINBASEAPI BOOL WINAPI QueryFullProcessImageNameW(
HANDLE hProcess,
DWORD dwFlags,
LPWSTR lpExeName,
PDWORD lpdwSize
);
#ifdef UNICODE
#define QueryFullProcessImageName QueryFullProcessImageNameW
#else
#define QueryFullProcessImageName QueryFullProcessImageNameA
#endif
#endif
If the API is in the libkernel32.a import library that should be all you need. The API was in the library for versions of MinGW 4.7.x that I have installed where it wasn't in the winbase.h header, so there's a good chance that all you'll need is the few lines of code from above.
Related
I try to use an undocumented API while developing a windows kernel driver. Please don't tell me this is not the best thing to do ;)
Anyway, the undocumented API is PsGetProcessPeb that i found with IDA into ntoskrnl.exe
I define the following structures:
_PEB
_PEB_LDR_DATA
_LDR_DATA_TABLE_ENTRY
Also, I found that I have to define the function like:
NTKERNELAPI PPEB NTAPI PsGetProcessPeb(IN PEPROCESS Process);
The code (a part of) that I try to compile is:
PsLookupProcessByProcessId(ProcessId, &pProcess);
PPEB pPeb = PsGetProcessPeb(pProcess);
When i try to compile I get the following error code:
LNK2019
LNK1120: unresolved externals
The externals that is not resolved is PsGetProcessPeb
I guess that the linker doesn't find the function and doesn't know how to link.
The OS used to compile is Windows 10 build 19044 (x64) and I use Visual Studio 2019.
If you have any idea, please let me know.
Regards
The key to use an undocumented API is to find the API's address.
In kernelland, there is MmGetSystemRoutineAddress().
https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-mmgetsystemroutineaddress
The MmGetSystemRoutineAddress routine returns a pointer to a function specified by SystemRoutineName.
Syntax
C++
PVOID MmGetSystemRoutineAddress(
[in] PUNICODE_STRING SystemRoutineName
);
Parameters
[in] SystemRoutineName
Specifies the name of the system routine to resolve.
Return value
If the function name can be resolved, the routine returns a pointer to the function. Otherwise, the routine returns NULL.
Remarks
Drivers can use this routine to determine if a routine is available on a specific version of Windows. It can only be used for routines exported by the kernel or HAL, not for any driver-defined routine.
I decided to create applications direct with Notepad + GCC Compiler (and the entire Mingw environment).
Well I started by creating a simple Win32 application (a simple window). The file is only 4 Kb (which, with an IDE like C:B or VS is about 8 kb.
Anyway, my problem is that the window is displayed but also a window console. Well, I don't want the console to appear but only the GUI window. I think this is achieved by creating manifest files or something like that, of which I don't know much about, as this is the first time I am trying this. How do I tell GCC that it shouldn't create a console window - just a GUI window?
Thanks!
You need to create an executable that targets the GUI subsystem rather than the console subsystem. In the MS tools the normal way to indicate that is to use a different form of main function:
int WINAPI WinMain(HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nCmdShow)
I believe that mingw supports the same convention.
Yeah, -mwindows can solve the problem. And I found another option, passing -Wl,--subsystem,windows when using gcc to compile. Both of them are OK.
I found out how to do it. For anyone having the same question: use -mwindows in your command line, when compiling the code with GCC. Thanks!
I have an application which runs on windows 2003, window 2008 and windows small business server.
There is a windows call that I make to reboot the system.All the calls mentioned below come from advapi32.dll
InitiateSystemshutdown - This is fine in windows 2003 and windows 2008 but for some reason not working in Windows aurora
InitiateShutdown - since the above call is not working in windows aurora we used this call and minimum supported OS for this call is windows 2008
Now my application fails to run in windows 2003 since the InitiateShutDown is not present in the advapi32.dll on Windows 2003
I get a failed to find procedure entry point for Initiateshutdown in advapi32.dll
I have already put a condition also so that the proper function calls are called with respect to the windows version.
Is there way to stop looking for the entry point in the dll when the application launches.The condition will make sure that the proper function call are called?
OR
I should be asking Microsoft why the old call InitiateSystemshutdown is not working properly ?
You have to use GetProcAddress and set your preprocessor variables for the earlier version of Windows. See http://msdn.microsoft.com/en-us/library/aa383745(VS.85).aspx#setting_winver_or__win32_winnt
Basically, you should:
Set WINVER to the earliest version of Windows you must support so you don't accidentally use something newer.
Some API calls and definitions won't work anymore (like InitiateShutdown in your case) in your code, because they aren't included by header files. For these, you must use them dynamically. Typically you use the GetProcAddress API and use a "typedef" to define the function's signature (since it isn't in the header files you're including anymore). An example is here: http://msdn.microsoft.com/en-us/library/ms683212(VS.85).aspx. In your case you would use the InitiateShutdown API instead of the given GetNativeSystemInfo. If the call to GetProcAddress fails then you can assume that the API is not supported on that version of Windows.
Rather that explicitly calling that function in your code (such that your app will fail to load if the function can't be loaded from the expected DLL), call it implicitly via LoadLibrary and GetProcAddress.
Do a "LoadLibrary" on advapi32.dll. And then call GetProcAddress for "InitiateShutdown". Fail gracefully if the function doesn't exist, otherwise cast it to an appropriate function pointer and
invoke it.
typedef DWORD (WINAPI *InitiateSystemShutdownTypeA) (char*, char*, DWORD, DWORD, DWORD);
typedef DWORD (WINAPI *InitiateSystemShutdownTypeW) (wchar_t*, wchar_t*, DWORD, DWORD, DWORD);
InitiateShutdownTypeA func = NULL;
HMODULE hMod = LoadLibrary("advapi32.dll");
if (hMod)
func = (InitiateShutdownTypeA)GetProcAddress("InitiateShutdownW");
if (func)
func(pwszMachineName, pwszMessage, dwGracePeriod, dwFlags, dwReason);
Is there a Windows API call that will tell me if I'm running on a 64-bit OS? I have some legacy c++ code that makes a call to GetVersionEx to fill in a OSVERSIONINFO structure, but that only tells me (AFAIK) the OS (Vista, V7, etc.), but not the processing architecture. I can hack around this by simply looking for the existence of "C:\Program Files (x86)...", but this seems ugly. I'm sure there must be an API to return this info.
IsWow64Process might be what you are looking for.
GetNativeSystemInfo()
I found this post that seems to provide a good answer: Detect whether current Windows version is 32 bit or 64 bit
I don't know why it didn't come up when I search Stack Overflow before posting.
Incidentally, the best solution for me is to simply check for the ProgramW6432 environment variable.
The solution is pretty straight-forward. If you are compiling for 64-bit, you already know that you are running on a 64-bit version of Windows. So you only need to call IsWow64Process when compiling for 32-bit. The following implementation returns true, if it is running on a 64-bit version of Windows:
bool Is64BitPlatform() {
#if defined(_WIN64)
return true; // 64-bit code implies a 64-bit OS
#elif defined(_WIN32)
// 32-bit code runs on a 64-bit OS, if IsWow64Process returns TRUE
BOOL f = FALSE;
return ::IsWow64Process(GetCurrentProcess(), &f) && f;
#else
#error Unexpected platform.
#endif
}
This answers the question you asked. The answer to the question you should have asked instead was posted in the response by Jerry Coffin already: Simply call GetNativeSystemInfo.
In VS9, when i call the GetTickCount() function, it automatically converts it into the GetTickCount64() function upon compilation. This second function only works on Vista+, and thus my program errors when run on XP.
How can I 'over-ride' this so that it calls the original GetTickCount() ?
Thanks
Set WINVER to the version of windows you want to target. Or maybe it's _WIN32_WINNT or _WIN32_WINDOWS. Maybe even all of them...
Take a look at http://blogs.msdn.com/oldnewthing/archive/2007/04/11/2079137.aspx for details on that small mess-o-version macros.
However, I don't see that redefinition at all in the Windows SDK - could there be something else in our setup that's doing the redefinition (or maybe I'm missing it...)?
Remember that you're not compiling your application for Vista or Windows XP, rather you're compiling for a 32-bit or 64-bit operating system. If your application needs to support other versions of Windows than 64-bit Vista, then specify in your build options to be 32-bit.
I set the following inside targetver.h:
#define WINVER 0x0501
#define _WIN32_WINNT 0x0501
#define _WIN32_WINDOWS 0x0501
and it still gets re-defined. However, when i create a simple new project that prints out GetTickCount(), it works fine on XP even without me having to define the above.
I did not change anything in the project settings. The only difference between the sample GetTickCount() that works and the one that doesn't is that it has plenty of other code around it and using it, but none of that code should be changing anything.
What could be causing this?
EDIT: One of the other files I was using was calling GetTickCount64() directly, and I did not know about this, so I assumed it was my own GetTickCount() function. Please ignore what i wrote above