How to find out where a Kernel32 dependency comes from - c++

I'm building an application to which I've just added a library (which in turn uses a number of other libraries), and for some reason it's trying to use "GetLogicalProcessorInfo" from kernel32.dll. Unfortunately, this function is newer than the Windows version that some of my users are using (some are using XP SP2, this function requires XP SP3) - so I got error reports about this.
I'm trying to figure out why this function is being referenecd, but I can't find it. I don't see it in any of the .lib files that I'm using. Or in any .cpp or .h file. Still, something is triggering that this function is used.
So, is there a way to find out where this is coming from? Which function or which library is using it?
I'm developing in Visual Studio 2015 with the Intel C++ compiler. There is a way to tell it to compile for Windows XP, but the minimum supported version is SP3 - before I added this library my code worked fine though. If I have to push people to move to SP3, so be it, but I would prefer not to. Many are using a pc running my software as an appliance, often not even connected to the internet, and have been running it for years (hence the old OS).

If you have immunity debugger or ollydbg, you can open up your program in that. Once its loaded right click and select view which shows all the modules your program imports. Select your library and right click again and click on search->all intermodular calls and you'll see a list of functions that the module calls from external libraries. If you double click on the specific function it will take you to the location in that program which calls that kernel32 function.
Most likely you probably won't be able to get rid of it as it will be used by other parts of the library which you don't control.

Related

When I execute an .exe (compiled on my machine) on another computer it give me this error

It's my first time using Visual Studio 2017. I built a simple program in C++ on my PC. I was curious to see if my program works on another PC. I tried to execute the .exe on the other computer and it gave me this kind of error:
vs(some letters and numbers).dll is missing.
I assume that the .dll in question is part of Visual Studio.
I tried on a third PC, and this time the cmd stops working and becomes unresponsive after I execute my .exe.
I also have this problem when I compile with MinGW using the g++ compile feature in the cmd. When I execute the program compiled with MinGW on another PC, it gives me the same error, but this time it says something like
gw...dll is missing
Is there a way to avoid this error without installing the Visual Studio (or MinGW at this point) on any other PC I want my program to run on?
If you're interested in the code, I can put it here, but I don't think it's the problem here because I have the same issue for every other .exe compiled on my PC.
Here's a picture of the error:
In case of Visual Studio, you need to install Visual C++ Redistributable libraries or provide the libraries that are required by your application with .exe file (I am not sure if it violates license or not though).
In case of MinGW, you need to provide required DLL as well. I guess that you need libgcc_s_dw2-1.dll and libstdc++-6.dll, but you would better check it yourself. And remember about the license.
You may use Dependency Walker to analyse dependencies of your application.
UPDATE (2017-12-12):
I've missed the time you posted the screenshot. As far as I see from it the problem is that you are trying to run debug version of your executable: ucrtbased.dll is the debug version of the ucrtbase library and is only available (from what I know) from Visual Studio distribution. If you want to run your application on the computers that do not have installed Visual Studio, then you should use the Release version of your application.
In order to understand your problem you need to understand the concept of DLL.
Dynamic-link library(DLL) - As described by Microsoft:
A DLL is a library that contains code and data that can be used by
more than one program at the same time. For example, in Windows
operating systems, the Comdlg32 DLL performs common dialog box related
functions. Therefore, each program can use the functionality that is
contained in this DLL to implement an Open dialog box. This helps
promote code reuse and efficient memory usage.
So to put it simply, DLL is basically a bunch of compiled code, which is being linked to your code at load (or even run-time). Now, of course if your system is missing the DLL, your progrem will fail to work. To make things even worse, DLL are sensitive to the compiler that was used. So each DLL might have multiple version, so you will need to right DLL.
Now to the problem itself, the error message are the best way to start. They guide you what DLL are missing, and what is their name. For instance in your case "vs*.dll" is most likely related to Visual C++ runtime redistributable.
Finally, please note you have another consideration to make in addition to make your own system work: Every one that will use your code might face the exact same problem. So if you actually intend to share your .EXE with other people, you will need to understand how to guide them, or even automate their installation process.

api-ms-win-core-synch-l1-2-1.dll is missing from your computer

I am developing a C/C++ application using Visual Studio Community 2015.
I used to build my application the system library: OneCoreUAP.lib. I am using Windows 8.1.
I used the function if_nametoindex defined in https://msdn.microsoft.com/en-us/library/windows/hardware/ff553788%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396
In the link they specifies that you require ONeCOreUAP.lib
but I found Another links that indicates another library: Iphlpapi.lib: https://msdn.microsoft.com/en-us/library/windows/desktop/bb408409%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396
When launching my app I getting the following error:
The program can't start because api-ms-win-core-synch-l1-2-1.dll is missing from your computer.
Try reinstalling the program to fix this problem.
This is the message image:
When searching the dll, I know from the this link:
https://msdn.microsoft.com/en-us/library/windows/desktop/mt657574(v=vs.85).aspx
that:
Introduced into api-ms-win-core-synch-l1-2-1.dll in Windows 10.0.10240.0
I tried to update the Windows 10 SDK, But this did not solve the problem.
How to solve the problem? Should I upgrade my windows 8.1 to windows 10 to solve it?
The page you found appears to have to do with Windows drivers that link against the Universal App Platform runtime, which is only available in Windows 10 and up. OneCoreUAP.lib is the .lib file that represents the UAP runtime. If someone who knows more about this could enlighten me on the specifics of this, that would be helpful; I don't fully understand what's going on or how and hwy it works.
You are not writing one of these; instead, you are writing a desktop program. So instead, you want to look at the desktop program documentation. Usually this is the first thing that Googling for the function name in question will get you. In your case, this is that page, and at the bottom of the page it says the function can be found in Iphlpapi.lib, so you must link aganst that .lib file instead.
The bottom of that page also says the function was introduced no later than Windows Vista, so you are able to use it on 8.1.

How do I determine which c++ redistributables my program needs to run?

Is it possible that I need to install both a vcredist for vs2012 AND for vs2010?
I just had an error where my app couldn't load a .dll and it suddenly started working after I did an unrelated installation, which prompted me to guess that it must have installed an older vcredist which fixed the issue.
However I'm sure I'm using c++11 features.
Deployment is a job on its own. And I hate it, I hate the way you have to write installations on Windows. …So that feel better now…
You only need one vcredist. The one the linker decided to link your program to. If you have the "Windows SDK's" installed you will find the actual redist in:
C:\Program Files\Microsoft SDKs\Windows\v7.0A\Bootstrapper\Packages\vcredist_x86
If you install all updates including the not important ones, Microsoft will update your redist in that folder!
Maybe you have an executable, which do not want to run, you need the dependency walker. A tool, so usefully that Microsoft had to remove it from the Visual Studio. Download the program and open your exe in it. You do not need to understand what really happen. As long as no Dialog comes up during opening, everything is okay, even if there are exclamation marks in the bottom window. If a Dialog comes up with something like "Could not resolve" than look in the bottom window. Usually there is now in the lower window something like
"msvcr.dll" or "msvcr100.dll" or "msvcr110.dll".
If it includes an "d" before the extension like "msvcr100d.dll" the executable was compiled in debug mode and your journey ends on a system without installed compiler. If not, the name is telling you which vcredist you need:
msvcr100 = VS 2010 redist (32bit) (64bit)
msvcr110 = VS 2012 redist (32/64bit?)
sometimes it is not msvcr but it always starts with "ms". Of course the program will tell you every dll which is missing, not only microsofts and which command in the dll is used. This is sometimes extremely useful.
You have to do that with every dll in the folder of your executable as they can also have unresolveable dependencies.
Back to your first question. Your program can only link to msvcr100 or msvcr110, not to both, that is the reason you only need one vcredist per executable.
As mentioned in a commentary, A third party DLL can be guilty of using a different msvcp version. So yeah, you have to search all DLL's you use and you have to install both vcredist some times.
PS: There are always at least two of them, msvcr and msvcp.
I solved this problem as follows (on Windows 7):
I tried to load the library and it failed showing "The application failed to start because its side by side information is incorrect."
I opened "Computer management" window: Start -> right click on Computer->Manage.
In the "Computer management" window I selected "Event Viewer"->"Windows logs"->"Application".
The log corresponding to the error said that a DLL for a certain version of Microsoft.VC90.CRT was not found. In my case the version was 9.0.30729.6161 and the search for it in Google revealed I needed to install an "unusual" version of redistributables from here.
The dependency walker did not help for me (it only confused me by reporting unnecessary dependencies).
If you want to know which runtimes are needed, you can try using the "Dependencies" tool from lucasg on github (https://github.com/lucasg/Dependencies) which works on modern systems like win10.
You'll just have to look for MsVcR##.dll o VcRuntime###.dll (where # stands for a digit) in the dependency tree..
HTH
PS: The old-and-faithful "dependency walker" we've been using for years seems to be unable to handle the way newer OS handle delayed dependencies, marking them as "missing", while they are not missing, just delay loaded in a way it doesn't know...
If your OS is Vista or later (not XP), use the built-in SxStrace.exe to generate a log of which DLL's are being loaded and what module requires them. It will clearly show you if multiple CRT DLL versions are being loaded, and for what DLL's (3rd party or no).
The VS2012 redistributable is put into, e.g. "C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\redist".
-- David

wxWidgets running on other machine

I created application which uses wxWidgets library using visual studio 2008. Now I would like to create version which may be run on other machine.
Because right now when I want to run It on another machine there is an error:
the application failed to start because its side-by-side configuration is incorrect.
What can I do to make It work ?
The Event Viewer should have a record showing what DLL was being searched for, what version of that DLL if found in the SxS cache, and what version it was looking for but couldn't find. You'll then want to (for example) include the correct version of that DLL to be installed with your program. Alternatively, just link to virtually everything statically -- it'll make your executable a lot bigger, but eliminate a lot of problems like this relatively painlessly.

Checking if DWM/Aero is enabled, and having that code live in the same binary for 2000/XP/Vista/7

I know the title makes little sense, mostly because it's hard to explain in just one line. So here's the situation:
I have a program who's binary is targeted at Windows 2000 and newer. Now, I went ahead and added some code to check if the user is running under Vista/7, and if so then check if Aero/DWM is enabled. Based on this I'll disable some stuff that isn't relevant to that particular platform, and enable some other features. My main problem is that in order to call DwmIsCompositionEnabled from Visual C++ 2008 I have to add the dwmapi.lib file and compile against it. Running the binary in anything other than Vista or 7 gives the "Unable to locate component. The application failed to start because dwmapi.dll was not found" error. This, of course, is expected to happen since DWM is new and not available for older platforms.
My question is then: will it be possible for me to somehow manage to pull this off? One binary for all OS versions AND include that DWM check code? This program was written under Visual Studio 2008, Visual C++ using MFC.
Turns out I can just tell the linker to delayload the dwmapi.dll.
I'd like to thank ewanm89 because something he said sort of resonated and led me down the path to finding the actual answer.
The normal solution is to use LoadLibrary() and GetProcAddress(). Both can be done after your program started. But still +1 for the DelayLoad solution, which does the same for you behind the scenes.