Tool for determining version of Win32 APIs used by C++ code? - c++

I'm modifying a large C++ project whose first release was Windows 7-only to work on Vista and XP.
The main work will be to change the W7 API calls to use GetProcAddress at runtime (to avoid static linking with methods that are not available on the other platforms), and so I'm wondering if there are any tools that can help identify which calls need to be changed -- hopefully by examining the C++ code itself.
Failing that, would it be best to try building the project against an older Windows SDK? -- for example: http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=6510

#define WINVER 0x501
Now everything that is newer than Windows XP will cause a compilation error.
Replace everything that causes an error until none remain.
If you have some sed-fu, you can probably write a filter that directly finds all #if WINVER > 0x501 blocks in the windows headers, but for me, this is a bit out of my scope :-)

I would open your binaries using the depends.exe tool (either from your VS install or from here) under WinXP and Vista to see which functions can't be statically linked under these OSes. These would be the functions which your binary is using, but which are missing in older releases of the OS. You'll have to deal with them somehow: either implement them by yourself, replace them with something else or disable some of the functionality of your app.

Related

How to build the most compatible binary with Visual Studio 2019?

I'm using VS2019 for C and C++ under win7
I would like to build (x32bit or x64bit?) binaries which will run correctly under all later OS, including Windows Server 2019
Do I have to set WINVER/_WIN32_WINNT ? Does this concern the building env or the target env ? and if yes, with which value ?
https://learn.microsoft.com/en-us/cpp/porting/modifying-winver-and-win32-winnt?view=vs-2019
On Windows, unlike Linux, the building environment is almost entirely irrelevant. When linking, you don't link against the libraries in the build environment, but you link against the Windows SDK.
Strictly speaking, you probably don't need WINVER and _WIN32_WINNT. They mainly help to hide functions from <windows.h>, so you don't end up calling functions that you didn't intend to call.
But there are a few rare structures where the layout changed over Windows versions, in which case you want to use the old layout. Windows 10 supports both layouts; typically by inspecting the .cb member of the structure. You set this field to sizeof(type), and this size will depend on the WINVER variable.

Build my application for a previous Windows platform

Background
I'm writing a C++ app using VS2015 on WIN 7. This app will run on all windows OS greater than equal to XP.
Through out my code, I use lots of WINAPI calls.
I wish to prevent, at compile time, the usage of API that are not defined in win XP.
Motivation
At some point, I used function RegDeleteKeyEx function without noticing that this API is NOT available in win XP
Solution
So, I follow this post: Modifying WINVER and _WIN32_WINNT and declared this:
#include <winsdkver.h>
#define _WIN32_WINNT 0x0501
#define WINVER 0x0501
in file targetver.h
I was hoping that after this fix, when I compile my project that contains usage of RegDeleteKeyEx function, I will get compilation error.
But I didn't.
QA
I tried looking for other, new WINAPI in vista, and just added a call to GetTickCount64 function. when compiling, I got this:
error C3861: 'GetTickCount64': identifier not found
which confirmed my solution.
Question
I've noticed that for RegDeleteKeyEx function, the Minimum supported client is Windows Vista, Windows XP Professional x64 Edition
However, my app will run in XP 32 as well.
How may I enforce compilation error in such use case?
Unfortunately, as I can see in "winreg.h", there is no conditional compilation of RegDeleteKeyEx (other than RegDeleteKey). So there is no (easy) way to trigger compilation error in this case.
The only option (for the regular statical DLL loading) would be to create your own wrapper over winreg.h (or windows.h) which would handle the version check (and e.g. #undef RegDeleteKeyEx in the corresponding cases).
Sometimes this kind of stuff is also solved using dynamic DLL loading (LoadLibrary / GetProcAdress) where you can check the presence of the particular function on the current version of Windows, where the application runs (so you could for example create a RegDeleteKey wrapper which would call RegDeleteKeyEx on the windows versions which support it and RegDeleteKey if run under versions which don't). The check of the feature presence is then done at runtime, so the program can run on any version of system and still use the newest features on the versions which support them (and doesn't have DLL "unresolved import" loading issues on the lower versions which do not support the feature).

CryptoPP::selfTestFailure when using FIPS validated library and AES

I have a server. I want to add to it AES encryption.
I've tried using the Crypto++, after a lot of searching it compiled but it always throw exceptions that come from "CryptoPP::selfTestFailure".
I've read somewhere that it has something with this define in the file fips140.cpp:
// Define this to 1 to turn on FIPS 140-2 compliance features, including additional tests during
// startup, random number generation, and key generation. These tests may affect performance.
#ifndef CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2
#define CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 0
endif
but when i change the define to 1 the project that i took the DLL from don't compile.
what did i do wrong? / is there any other way to implantation the AES algorithm?
... after a lot of searching it compiled but it always throw exceptions that come from "CryptoPP::selfTestFailure". I've read somewhere that it has something with this define in the file fips140.cpp:
The FIPS DLL is a special purpose Windows DLL with considerable restrictions. One of the restrictions is the Operational Environment or OE. The OE includes OS versions and service pack levels.
For the FIPS DLL, here are the approved OE's:
5.0.4 - Windows 2000 Professional Operating System, Service Pack 1
5.2.3 - Windows 2000 Professional Operating System, Service Pack 1
5.3.0 - Windows XP Professional with SP2 and Windows Server 2003 X64 with SP1
If the OS is wrong, or the Service Pack level is wrong, then that can cause the self test failure. One of the reasons it can cause a failure is because the DLL locates certain specific memory functions from the C++ runtime. If it does not find them, it throws an exception.
There's a not-so-readily apparent dependency, and that's the version of Visual Studio. The last version of the library that was validated is 5.3, and for it you need Visual Studio 2005.
Usually what you have to do now is set up a a build/test machine with the specific OS, ervice Pack level and Visual Studio, and then build and test on it. Then, when you install Crypto++ and your program in production, you use the compatibility tab to provide the runtime OE.
when i change the define to 1 the project that I took the DLL from don't compile. what did i do wrong?
If you want or need more specific answers, then you need to provide more information, like your version of Windows, your version of Visual Studio, and a call stack.
I would also encourage you to avoid the FIPS DLL if possible. Most users don't realize its special purpose and don't know how to use it properly. Its a pain in the butt to work with and its a constant source of problems.
If you want a DLL, then create a wrapper DLL that exports the symbols you want to export. Then, link to the static version of the Crypto++ library.

Want to run a program on some unknown system

I have been working on a VS 2005 project and have successfully generated an exe file which works fine on my system. However when I tried to run it on some other pc it didnt run. It throws up the error message "the system cannot run the specified program". Can someone tell me how to make my code immune to such message i.e. system independent?
platform used: Windows XP, VS 2005
the extension of all my code files is cpp but I know only c and thats what I wrote inside them.
I have seen before exe created on Windows Sp1 not working on SP2 and problems such as that.
This should help you perhaps.
I've seen this when you run on a different version of Windows that doesn't have some DLL you depend on. The easiest thing to do is statically link the C runtime (that's the usual culprit) and use depends.exe to see if there are any others.
You will almost certainly need to create an installer that installs your executable and any non-OS-included DLL's it relies upon. It is not always possible or desirable to statically link all dependencies. You can in many cases simply copy the DLL's to the same folder as the executable.
By default, even the C/C++ standard library is provided by a DLL. While the MSVCRT.DLL used by VC++ 6 is included with the OS since later editions Win95, the MSVCRT required by VS2005 is not included with XP installations (other versions I do not know). The run-time support is included VC redistributes package. You may need to arrange for your installer to include that installation, or you could be more selective is you know your dependencies.
Some Win32 API calls if you are using them are dependent on the OS version (check the documentation), but if you built and rin it on XP, it should normally work of any subsequent version of Windows. You need to define various API version macros if you want to extend support to earlier versions of Windows (which seems unlikley).
You might need to install the VS 2005 redistributables on the other machines, depending on how you have compiled your program.

how do i turn my program into something i can install?

how do i turn my VC++ 2008 program into something i can get to run on other computers. i have tryed using the .exe it makes in the debug but it will say that im missing some files and lists all of my .cpp file names and .h files(if i use it on other computers). i wanted something so i could encrypt my files because one of them is about encrypting passwords/other stuff so i can't have someone just open my files. also i would very much like someway to make them accept the terms and conditions so they can't sue me if they lose something, that would be very very nice. ^^
i only have Microsoft virtual c++ 2008 express edition that i got from their web site.
o also if i make something on windows 7 will it run in xp or vista?
You generally can't and almost never should distribute debug builds to client machines. At least three reasons.
Client machines will not have the debug versions of your dependant libraries, like the VC runtime (msvcrtd.dll), so they won't be able to run your app.
When compiling in debug, your code will in many ways run unoptimized. For one thing, you don't let an optimizing compiler optimize when you compile in debug, so it will run slower and/or fatter. For another, there are debug version of things like operator new which allocate much more than you ask for, which is used in runtime integrity checking etc. So your program runs fatter & slower once more.
When you compile in debug it is easier to reverse-engineer your code.
UPDATE:
And to answer your question if a Win7-compiled app will run on XP/Vista, the answer is 'yes' so long as you don't use any Win7 features.
You will need the redist pack for the binary to run on another machine (if it does not already have the pack installed).
You need to make a Deployment Project that generates an MSI, but I'm not sure your Express edition does that. As for encryption, compilation doesn't do that, and nothing stops people from disassembling your code. Finally, you probably should not be writing your own encryption algorithms, since most people get those wrong most of the time. Use something out of the box.
if you are compiling using .NET 3.5 in Win 7 it should work in xp and vista as well
(provided .NET 3.5 framework is installed on them).
The first part is already answered (release build, include redistributable C++ DLLs).
The second part, running on Vista/XP is not that trivial.
If you write a pure C++ program, it will run on XP and Vista, unconditionally. But once you include <windows.h>, you introduce a dependency on a minimum Windows version. The default today is still XP. That means that you cannot use any Vista or W7 feature directly, and therefore your program can run on XP.
But if you #define WINVER 0x0600 before including <windows.h>, then you can use Vista-specific functions. The price you pay for using those Vista functions is that your program won't start on XP anymore. Similarly, #define WINVER 0x0601 also gives you access to Windows 7 functions, on top of the XP and Vista functions. And again, using a Windows 7 function stops you from running on XP or Vista.
There are some tricks that allow you to use Windows 7 functions if available. Basically, they all boil down to calling GetProcAddress("some_windows7_function") and somehow handling the case where it returns NULL.