I am new to Windows programming and I'm trying to discover the best way to check for the existence of Windows Shell API functions. I want to use some of the new taskbar features in Windows7.
https://msdn.microsoft.com/en-us/library/dd378460%28VS.85%29.aspx#custom_jump_lists
But I still want my program to be usable by previous versions of Windows. Is there an easy way to know if the functions are available to be called in the end users system. I'm programming in C++.
It depends on the kinds of the functions.
For plain (non-COM) functions, the only way is to use LoadLibrary and GetProcAddress. If either fails, you know the OS is missing that function. Writing those function pointer type declarations for function pointers duplicating existing function signatures can be tedious, though in VC++2010 you can use decltype for that. For example:
HMODULE user32 = LoadLibraryW(L"user32");
if (user32 != NULL)
{
auto messageBoxW = reinterpret_cast<decltype(MessageBoxW)*>(GetProcAddress(user32, "MessageBoxW"));
if (messageBoxW != NULL)
{
messageBoxW(HWND_DESKTOP, L"Hello!", NULL, MB_OK);
}
}
However, many Shell APIs are exposed via COM components and interfaces. Those cases are different. Sometimes you need to deal with entirely new components; e.g. IApplicationDestinations is a new interface in Win7, and the coclass that implements it is also new. In those cases, you can just do CoCreateInstance, and check the return value for REGDB_E_CLASSNOTREG - this means that such coclass isn't registered on the system (and, effectively, isn't supported).
Sometimes, however, new OS versions introduce new interfaces on existing coclasses. An example is ITaskbarList3, new in Win7, but provided on existing coclass that implements ITaskbarList and dates back to Win95. In those cases, you should first instantiate the coclass for the most basic interface, and then use QueryInterface to obtain new interface versions, and detect that they're not supported by checking return value for E_NOINTERFACE.
I believe MSDN is your best bet for this. Every MSDN page for a function's documentation contains a section in the end which states that which version of Windows support this function.
As an example, Check the doumentation of GetModuleHandle. This contains a section named Requirements under which there is a field Minimum Supported Client and Minimum Supported Server.
However, if you want to check for the existence of functions dynamically, then you can do this through LoadLibrary and GetProcAddress.
I disagree with the currrent solutions. You'll end up with quite a bit of unreadable code.
A nicer alternative is to wrap the functionality in a custom Windows 7-only DLL. For other systems, provide another version of the DLL that implements the same functions. This can often be a no-op. E.g. a function to set the taskbar extensions would be a no-op on older Windows versions.
The dynamic switching between these DLLs is done by using the delay-load feature of MSVC. You can use a custom hook in your EXE to pick the correct DLL version when the first function in your DLL is called, at which time you know whether you're running on Windows 7.
you should use LoadLibrary and GetProcAddress to dynamically load and invoke the new functionality.
Yes you can always check for the existence of function within a library at runtime and take suitable actions.
Check the LoadLibrary and GetProcAddress APIs.
http://msdn.microsoft.com/en-us/library/ms683212(VS.85).aspx
If you want to find out at compile time so as to get a build break if the function is not available on the OS you are targetting (eg Win 95), then you can define some macros, documented here:NTDDI_VERSION, _WIN32_WINNT, WINVER.
If you want your app to work fine when the functionality is not available (eg JumpLists on OSes older than Win7), then you should do combination of LoadLibrary/GetProcAddress to figure out whether the function you are looking for is available.
Use LoadLibarary to get library handle and GerProcAddress to get pointer to a function. For those functions that are not supported by current OS you will get ERROR_CALL_NOT_IMPLEMENTED error from GetLastError.
Related
I'm working on a Win32 application and am currently trying to implement multi-display features. For this, I want to use EnumDisplayMonitors, a feature that is only present in Windows 2000-upwards. I've done my best to maintain backwards compatibility up to Windows 95 thus far.
I want to, therefore, ignore this related section of code when the program runs on older versions of Windows. However, its mere presence anywhere in the code, even if it's not executed, crashes the program. I want to use #ifdef to ignore this section of code, however I can't seem to figure out a way to get the current Windows version from the Preprocessor. I've seen suggestions to use WINVER or _WIN32_WINNT but both need to be set by me as far as I can understand, defeating the whole point. Any attempts to use them predictably did not work as intended.
Is there a way to get the current version of Windows from the preprocessor? If not, is there another way to disable this function completely depending on the OS? Again, regardless whether it's used, its mere presence crashes on Windows 95.
The correct way to handle this is not with the preprocessor at all. You need to use the Win32 API GetProcAddress() function at runtime instead, eg:
typedef BOOL (WINAPI *LPFN_EDM)(HDC, LPCRECT, MONITORENUMPROC, LPARAM);
LPFN_EDM lpEnumDisplayMonitors = (LPFN_EDM) GetProcAddress(GetModuleHandle("user32.dll"), "EnumDisplayMonitors");
if (lpEnumDisplayMonitors)
{
// use lpEnumDisplayMonitors as needed...
}
else
{
// use something else...
}
This is even described in Microsoft's documentation:
Operating System Version
Identifying the current operating system is usually not the best way to determine whether a particular operating system feature is present. This is because the operating system may have had new features added in a redistributable DLL. Rather than using the Version API Helper functions to determine the operating system platform or version number, test for the presence of the feature itself.
To determine the best way to test for a feature, refer to the documentation for the feature of interest. The following list discusses some common techniques for feature detection:
You can test for the presence of the functions associated with a feature. To test for the presence of a function in a system DLL, call the LoadLibrary function to load the DLL. Then call the GetProcAddress function to determine whether the function of interest is present in the DLL. Use the pointer returned by GetProcAddress to call the function. Note that even if the function is present, it may be a stub that just returns an error code such as ERROR_CALL_NOT_IMPLEMENTED.
You can determine the presence of some features by using the GetSystemMetrics function. For example, you can detect multiple display monitors by calling GetSystemMetrics(SM_CMONITORS). There are several versions of the redistributable DLLs that implement shell and common control features. For information about determining which versions are present on the system your application is running on, see the topic Shell and Common Controls Versions.
If your compiler toolchain supports Delay Loading, then you can use that instead of calling GetProcAddress() manually. Set your project to delay-load user32.dll and then call EnumDisplayMonitors() normally after first validating the OS supports what you need, such as checking if Windows is Win2K or later via GetVersionEx(), or checking if multiple monitors are installed, eg:
OSVERSIONINFO osvi;
osvi.dwOSVersionInfoSize = sizeof(osvi);
GetVersionEx(&osvi);
if (osvi.dwMajorVersion >= 5) // Win2K = 5.0
{
// use EnumDisplayMonitors as needed...
}
else
{
// use something else...
}
if (GetSystemMetrics(SM_CMONITORS) > 1)
{
// use EnumDisplayMonitors as needed...
}
else
{
// use something else...
}
Compile targeting the lowest Windows you support with WINVER/_WIN32_WINNT (whatever your SDK supports), then load whatever functions you need dynamically at runtime (LoadLibrary etc.) after knowing where you are actually running.
I want to use some Windows API functions specific to the latest Windows 10 versions. E.g. functions like CreatePseudoConsole() supporting Windows Pseudo Console (ConPTY) were introduced only in Windows 10 version 1809 (the fall update of Windows 10 released in 2018).
The classic approach is to load Windows kernel dynamic library where the needed functions are implemented (using LoadLibrary() function) and to check every needed function via GetProcAddress() call.
The newer approach introduced in Visual C++ 6.0 is called Delay Loading.
Is there any modern (simple, clear, and transparent) way to check what parts of Windows API are available for a running application? Or is it a way to check what is an exact Windows 10 version an application is running on? I want to use functions like CreatePseudoConsole() only if they are available (if they are not available some other code should be executed).
GetProcAddress() is the only way to do what you are asking for. Definitely DO NOT rely on detecting the OS version (in recent Windows versions, it gets increasingly more difficult to do that reliably), DO rely on whether the desired function(s) actually exist instead.
Even a linker's delay-load feature uses GetProcAddress() internally. In this case, you can use a delay-load notification hook to determine the result of the load so you can flag your code accordingly for later checks, or even supply a pointer to an alternative fallback function if needed.
This last part is important, because a delay-loaded function is not loaded until it is called for the first time, so if you call a delay-loaded function that does not exist at runtime, and a notification hook does not provide an alternative function, your code will likely crash trying to execute a function via a NULL pointer. To avoid that, you can just call GetProcAddress() explicitly before making any calls to the function.
If the API belongs to an API set, it's recommended to use IsApiSetImplemented instead of GetProcAddress().
The traditional approach for testing whether a Win32 API is available is to use LoadLibrary or GetProcAddress. However, these are not a reliable means for testing API sets because of the reverse forwarding support in Windows 10.
To identify whether a particular Win32 API belongs to an API set, review the requirements table in the reference documentation for the API.
I have this habit always a C++ project is compiled and the release is built up. I always open the .EXE with a hexadecimal editor (usually HxD) and have a look at the binary information.
What I hate most and try to find a solution for is the fact that somewhere in the string table, relevant (at least, from my point of view) information is offered. Maybe for other people this sounds like a schizophrenia obsession but I just don't like when my executable contains, for example, the names of all the Windows functions used in the application.
I have tried many compilers to see which of them published the least information. For example, GCC leaves all this in all of its produced final exe
libgcj_s.dll._Jv_RegisterClasses....\Data.ald.rb.Error.Data file is corrupt!
....Data for the application not found!.€.#.ř.#.0.#.€.#.°.#.p.#.p.#.p.#.p.#.
¸.#.$.#.€.#°.#.std::bad_alloc..__gnu_cxx::__concurrence_lock_error.__gnu_cxx
::__concurrence_unlock_error...std::exception.std::bad_exception...pure virt
ual method called..../../runtime/pseudo-reloc.c....VirtualQuery (addr, &b, s
ize of(b))............................/../../../gcc-4.4.1/libgcc/../gcc/conf
ig/i386/cygming-shared-data.c...0 && "Couldn't retrieve name of GCClib share
d data atom"....ret->size == sizeof(__cygming_shared) && "GCClib shared data
size mismatch".0 && "Couldn't add GCClib shared data atom".....-GCCLIBCYGMI
NG-EH-TDM1-SJLJ-GTHR-MINGW32........
Here, you can see what compiler I used, and what version. Now, a few lines below you can see a list with every Windows function I used, like CreateMainWindow, GetCurrentThreadId, etc.
I wonder if there are ways of not displaying this, or encrypting, obfuscating it.
With Visual C++ this information is not published. Instead, it is not so cross-platform as GCC, which even between two Windows systems like 7 and XP, doesn't need C++ run-time, frameworks or whatever programs compiled with VC++ need. Moreover, the VC++ executables also contain those procedures entry points to the Windows functions used in the application.
I know that even NASM, for example, saves the name of the called Windows functions, so it looks like it's a Windows issue. But maybe they can be encrypted or there's some trick to not show them.
I will have a look over the GCC source code to see where are those strings specified to be saved in the executables - maybe that instruction can be skipped or something.
Well, this is one of my last paranoia and maybe it can be treated some way. Thanks for your opinions and answers.
If you compile with -nostdlib then the GCC stuff should go away but you also lose some of the C++ support and std::*.
On Windows you can create an application that only links to LoadLibrary and GetProcAddress and at runtime it can get the rest of the functions you need (The names of the functions can be stored in encrypted form and you decrypt the string before passing it to GetProcAddress) Doing this is a lot of work and the Windows loader is probably faster at this than your code is going to be so it seems pointless to me to obfuscate the fact that you are calling simple functions like GetLastError and CreateWindow.
Windows API functions are loaded from dlls, like kernel32.dll. In order to get the loaded API function's memory address, a table of exported function names from the dll is searched. Thus the presence of these names.
You could manually load any Windows API functions you reference with LoadLibrary. The you could look up the functions' addresses with GetProcAddress and functions names stored in some obfuscated form. Alternately, you could use each function's "ordinal" -- a numeric value that identifies each function in a dll). This way, you could create a set of function pointers that you will use to call API functions.
But, to really make it clean, you would probably have to turn off linking of default libraries and replace components of the C Runtime library that are implicitly used by the compiler. Doing this is a hasslse, though.
maybe stupid question, but i dont know answer. What is difference between using GetModuleHandle or LoadLibrary to load dll(and then to use function of that dll) and to include directly desired header. For example, with using GetModuleHandle:
typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO);
// Call GetNativeSystemInfo if supported or GetSystemInfo otherwise.
PGNSI pGNSI;
SYSTEM_INFO si;
ZeroMemory(&si, sizeof(SYSTEM_INFO));
pGNSI = (PGNSI) GetProcAddress(
GetModuleHandle(TEXT("kernel32.dll")),
"GetNativeSystemInfo");
if(NULL != pGNSI)
pGNSI(&si); //calling function through pointer
else GetSystemInfo(&si);
But I can include windows.h header to directly call that function from my code:
#include <windows.h>
SYSTEM_INFO si;
ZeroMemory(&si, sizeof(SYSTEM_INFO));
GetNativeSystemInfo(&si);
The same applies for example to opengl32.dll, i dont know if it is better to include header file for opengl functions in my project or to use Getmodulehandle and GetProcAdress to invoke desired functions. What is the difference? Is first method with using getmodulehandle benefit in some way? Thanks for answers.
First, make sure you understand that GetModuleHandle and LoadLibrary are not exactly equivalent. But since that's not directly part of your question, I'll leave off a big explanation and just suggest you make sure to understand the documentation in those two links.
To use a dll function directly as if it were like any other function, you don't just include the header. In addition to the header, somewhere in your project it is being told to link against a corresponding lib file. In your example, it would be kernel32.lib. This might be done through various means, such as linker settings in the project or having a #pragma comment (lib, ...) in a file.
When a program is built like that, code is written by the compiler to load that dll when the program starts. If the dll in question cannot be found when you actually try to run the program, then it will fail with an error message. You have no way to write code to catch the failure and take some alternative action.
For dlls that are part of the operating system (like kernel32.dll) or at least typically supplied with it, this immediate loading behavior isn't an issue since you can safely assume the dll will always be there. On the other hand, if you were to build against a dll which is not typically present, then you would have more of a concern. Either you would have to make sure such a dll is distributed with your program or else somehow try to make sure the user installs whatever other package is necessary to get that dll on their system.
Also, if the dll loads but any of the functions you're trying to use from that dll don't actually exist in it, then it will immediately fail with an error message. (It doesn't wait until your program tries to call the function. It finds this discrepancy when the program starts and aborts then.) This can be an issue if different versions of the dll exist out in the world.
Now, when you use LoadLibrary/GetProcAddress, you are asking for the dll to be loaded at the time of your choosing and asking to find a particular function provided by that dll. If either of those steps fails, you have the ability to write code to deal with it in some reasonable manner.
This can be used for various purposes. For instance, you could make a plugin mechanism where the program searches for and loads plugin dlls from some particular folder on the fly. Since the program doesn't know ahead of time which plugins will be present, LoadLibrary is the only way to do this.
Another thing LoadLibrary/GetProcAddress can be used for is to load a dll and call a function from it even when you don't have the proper header and lib files. If you know the name of the dll, the name of the function, and exact signature of the function (parameter types, return type, calling convention) then you have enough to write the code to load that dll and call the function successfully. Occasionally this can be useful. For instance, it's one way that people are able to use certain "undocumented" functions provided by Windows dlls.
Lastly, LoadLibrary/GetModuleHandle/GetProcAddress can be used to let you use functionality that doesn't necessarily exist on all the operating systems you want to support. This appears to be the reason for the code snippet you have that calls either GetNativeSystemInfo or GetSystemInfo. The former is only available from WinXP/2003 on up while the latter is available on Win2000. If the code had just been written as a direct call to GetNativeSystemInfo, then the program would fail to run on Windows 2000. But instead, what you have there checks to see if GetNativeSystemInfo exists on the current operation system and only uses it if so, otherwise it falls back on the more widely supported GetSystemInfo.
So in the case of your example, which technique you choose to call that function depends on which operating systems you intend to support. If your software does not need to run on Windows 2000, then just directly calling GetNativeSystemInfo is a lot easier (and most likely the preferable way to go).
Some functions don't exist in older versions of Windows and when you call a function directly, that function ends up in the import table of your program. If Windows fails to find one of the functions in the import table, the program will not run at all.
In your specific example, GetNativeSystemInfo was added in Windows XP and if you call it directly then your program will not run on Windows 2000 or older.
LoadLibrary is also useful if you want to support 3rd-party plug-ins etc.
GetModuleHandle enables you to load dlls dynamically, what can be used for instance for implementing plug-ins or loading some resources on-demand.
Underneath, there is no difference between the two methods -- static library that you link just contains code that does dynamic linking when program starts (in C).
It depends, in this case I'd say its being used so that the dll/exe won't get loading errors from the windows LDR if the system(kernel32.dll etc) doesn't have exports that the binary might use, onr good example of this is the DEP functions for windows XP, which only exist in SP 2+, but its not a good idea to force a required SP, as it can cut down on the avaiable audience for the program.
OpenGL uses the same sorta principle, due to the fact one can't predict the API support (and extensions), so one must check for it, then import it or an alternative with wglGetProcAddress
Another reason, which is more 'cheap' is so that one doesn't not have to link to certain libs and include certain headers, especially if your using say only 1 function from a very large SDK, this prevents other developers wasting time tring to get the huge SDK(they ofc will need the binary contianing the export)
LoadLibrary and GetModulehandle both will work for the same stuff i.e; they will map the module on to the process at run time but in case of LoadLibrary it increases the reference count in the kernel perspective where as the later will not do so..
I am writing a Win32 DLL library that can be redistributed. I am using different versions of the windows API because I want to support Windows 7 functions, but still have support for Windows 2000 (with some function disabled). What I have currently is MyLib2000.dll, MyLibXP.dll, and MyLibVista.dll, and my application chooses which library to load at runtime. I want a way to have a single DLL (MyLib.dll) that stores the other three in itself and when it's being loaded, it extracts the correct DLL out of itself and loads it.
I know this is not the best way to do this, so suggestions on another method of doing this is welcome.
Use delayloading and implement the dliNotePreLoadLibrary notification hook to load the correct version of your DLL. The linker-provided delay load logic will then pull in all the functions from whichever DLL you loaded.
http://msdn.microsoft.com/en-us/library/z9h1h6ty(v=VS.100).aspx
Or use delay-loading and implement your functions to check the OS version before calling any function that could fail to be loaded (since it doesn't exist on the old OS).
Why not just abstract out the OS-version dependencies in a software layer, implemented in terms of something like STLSoft's dl_call() function template suite.