C++ GetBinaryType Failing - c++

I am using GetBinaryType to check if an executable is 32 or 64bit. I am testing against a 64bit file and it keeps failing. I believe this is due to the way I am comparing the DWORD result?
I am using Visual Studio 2010 C++:
DWORD dwBinaryType;
if (GetBinaryType(ChildFile(), &dwBinaryType) == 6)
{
MessageBox(NULL, L"64bit Detected...", L"Debug: GetBinaryType", MB_OK); // DEBUG
}
else
{
MessageBox(NULL, L"Probably 32bit...", L"Debug: GetBinaryType", MB_OK); // DEBUG
}
Any advice would be great thanks.

According to MSDN for GetBinaryType:
Return value
If the file is executable, the return value is nonzero. The function sets the variable pointed to by lpBinaryType to indicate the file's executable type.
Changing your above code to this should do the trick:
if (GetBinaryType(ChildFile(), &dwBinaryType)
&& dwBinaryType == SCS_64BIT_BINARY)
{
// ...
}

Related

VS 2019 C++ console app gets parameters in UTF-8 instead of expected UTF-16LE

I'm building a new project in Visual Studio 2019. It's a console app that includes MFC headers. Here's the relevant code:
int main(int argc, TCHAR* argv[]) // VS wrote "int main()", I added parameters myself.
{
int nRetCode = 0;
HMODULE hModule = ::GetModuleHandle(nullptr);
if (hModule != nullptr)
{
// initialize MFC and print and error on failure
if (!AfxWinInit(hModule, nullptr, ::GetCommandLine(), 0))
{
// TODO: code your application's behavior here.
wprintf(L"Fatal Error: MFC initialization failed\n");
nRetCode = 1;
}
else
{
nRetCode = MyFunction(argc, argv);
}
}
else
{
// TODO: change error code to suit your needs
wprintf(L"Fatal Error: GetModuleHandle failed\n");
nRetCode = 1;
}
return nRetCode;
}
Most of this is boilerplate code generates by VS. I added parameters to the main function and the call to my own code, namely MyFunction(). It built just fine; didn't issue so much as a warning. On the very first test run I found that the text in argv[1] and argv[2] are in plain 8-bit ASCII or UTF-8. I was expecting UNICODE as UTF-16LE.I do have the project properties set to use UNICODE. What have I done wrong to get command line parameters in UTF-8? Here's my setup in VS 2019:
My OS is Windows 10.
main() only works with char in the argv[] array. If you want to use wchar_t instead, you need to rename main() to wmain() instead.
Or, since you are using TCHAR, you can rename main() to _tmain(), so that it will automatically map to main() in a MBCS build, and to wmain() in a Unicode build. See What is difference between main and _tmain in Visual studio

How can I overcome silent failure to change the PATH environment variable in VC++ 2013?

My goal is to write code that prepends a directory to the existing value of the PATH environment variable and sets the PATH environment variable to the new value for the duration of the program so that DLLs can be loaded from the new directory as well as from directories previously on the path. The code only needs to run on Windows and only needs to be compiled with Visual C++ 2013 and 2015. (Ideally, I'd like to be able to compile with MinGW as well, but the fact that there's no equivalent to /DELAYLOAD means that that may not be possible.)
I found, after experimentation, that SetEnvironmentVariable[W] silently fails to change the value of PATH, but _putenv, _putenv_s, _wputenv, and _wputenv_s work correctly --- but only on VC++ 2015. On VC++ 2013, they fail silently, and leave the value of PATH unchanged (the same way that SetEnvironmentVariable fails silently on VC++ 2013). I have not found any references to this behavior anywhere that I have searched on the Internet.
I can put up with using _putenv rather than SetEnvironmentVariable, but I need to figure out a way to change the value of PATH dynamically in VS2013, even if it's different from the way that works in VS2015.
UPDATE:
Here's prependDirToEnvVarW() (and getPathFromEnvVarW(), which it calls). prependDirToEnvVarW() works correctly on VC++ 2015 but silently fails to change the path on VC++ 2013.
inline std::wstring getPathFromEnvVarW()
{
DWORD bufferSize = GetEnvironmentVariableW(L"PATH", NULL, 0);
std::wstring ret(bufferSize, wchar_t(0));
DWORD getPathEnv = GetEnvironmentVariableW(L"PATH", &ret[0], bufferSize);
return (getPathEnv ? ret : L"");
}
inline bool prependDirToEnvVarW(const std::wstring & wstrDir)
{
const std::wstring PATH_VAR_NAME = L"PATH";
std::wstring wstrPrevPath = getPathFromEnvVarW();
std::wstring wstrValue = wstrDir;
if (!wstrValue.empty() && wstrValue[wstrValue.length() - 1] != L';')
{
wstrValue += L";";
}
wstrValue += wstrPrevPath;
std::replace(wstrValue.begin(), wstrValue.end(), L'/', L'\\');
errno_t retVal = _wputenv_s(PATH_VAR_NAME.c_str(), wstrValue.c_str());
std::cout << "Attempted to change PATH to:\n" <<
std::string(wstrValue.cbegin(), wstrValue.cend()) << std::endl;
if (retVal == 0)
{
return true;
}
else
{
std::cout << "retVal is nonzero: " << retVal
<< " (compare to EINVAL == " << EINVAL << ")" << std::endl;
return false;
}
}
The premise is incorrect. The PATH is the last thing searched for DLLs.
Instead, you should be calling SetDllDirectory() or AddDllDirectory() . This sets the DLL search path so that your added path is searched second, right after the executable directory.
If you need finer control than that, you will need to specify a full pathname to the LoadLibrary() function.

call matlab dll from c++: fail to initialize the library

I try to use Demo code for detecting and matching SIFT features of David Lowe (lowe#cs.ubc.ca)
in my code. So I compile the (.m)file in Matlab to generate DLL. Here is the command code in Matlab:
mcc -B csharedlib:SiftMatch match.m sift.m -v
However, when I use the DLL in my C++ code( under VS2010), there is a problem:
SiftMatchInitialize();
This function returned false. I could not initialize the library.
and debug showed that:
bool MW_CALL_CONV SiftMatchInitializeWithHandlers(
mclOutputHandlerFcn error_handler,
mclOutputHandlerFcn print_handler)
{
int bResult = 0;
if (_mcr_inst != NULL)
return true;
if (!mclmcrInitialize())
return false;
if (!GetModuleFileName(GetModuleHandle("SiftMatch"), path_to_dll, _MAX_PATH))
return false;
{
mclCtfStream ctfStream =
mclGetEmbeddedCtfStream(path_to_dll);
if (ctfStream) {
bResult = mclInitializeComponentInstanceEmbedded( &_mcr_inst,
error_handler,
print_handler,
ctfStream);
mclDestroyStream(ctfStream);
} else {
bResult = 0;
}
}
if (!bResult)
return false;
return true;
}
In this function ctfStream is NULL and bResult equals 0.
So, what's the problem?
Do not include the .c/.cpp files generated by MATLAB Compiler into your project. Only the header file and .lib file is needed.

DoModal crashed in visual studio 2010

I am going throught Multiple Selection in a File Dialog article of code project,
this code works fine for visual studio 2005 but when i run it on visual studio 2010 it gives me an debug assertion as follow,
Unhandled exception at 0x76f515de in MultiSelect.exe: 0xC0000005:
Access violation reading location 0x00000020.
At the following point,
int ret = CFileDialog::DoModal(); //**Point where assersion occures**
Whole function is like follow(Note:-CFECFileDialog inherited from CFileDialog)
int CFECFileDialog::DoModal()
{
if (Files)
{
delete[] Files;
Files = NULL;
delete[] Folder;
Folder = NULL;
}
int ret = CFileDialog::DoModal(); //**Point where assersion occures**
if (ret == IDCANCEL)
{
DWORD err = CommDlgExtendedError();
if (err == FNERR_BUFFERTOOSMALL/*0x3003*/ && Files)
ret = IDOK;
}
return ret;
}
I also ask question for author of that article but he is not replying.
I downloaded the project from CodeProject and got a crash at CFECFileDialog::OnFileNameChange. Using the VS2010 debugger and the "Go to disassembly" option, i saw that the crash was caused by GetParent returning NULL.
As I have no idea why the CommDlg_OpenSave_* macros were called with a "parent" handle, I just tried calling them with the "this" handle (m_hWnd). Works for me.
Try replacing each instance of "GetParent()->m_hWnd" by "m_hWnd" in CFECFileDialog::OnFileNameChange
EDIT: precision, I did not got the crash you had in DoModal

Get path to My Documents

From Visual C++, how do I get the path to the current user's My Documents folder?
Edit:
I have this:
TCHAR my_documents[MAX_PATH];
HRESULT result = SHGetFolderPath(NULL, CSIDL_MYDOCUMENTS, NULL, SHGFP_TYPE_CURRENT, my_documents);
However, result is coming back with a value of E_INVALIDARG. Any thoughts as to why this might be?
It depends on how old of a system you need compatibility with. For old systems, there's SHGetSpecialFolderPath. For somewhat newer systems, there's SHGetFolderPath. Starting with Vista, there's SHGetKnownFolderPath.
Here's some demo code that works, at least on my machine:
#include <windows.h>
#include <iostream>
#include <shlobj.h>
#pragma comment(lib, "shell32.lib")
int main() {
CHAR my_documents[MAX_PATH];
HRESULT result = SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, my_documents);
if (result != S_OK)
std::cout << "Error: " << result << "\n";
else
std::cout << "Path: " << my_documents << "\n";
return 0;
}
Use the SHGetFolderPath Windows API function and request CSIDL_MYDOCUMENTS.
Using Visual Studio 2017 with an MFC application under Windows 10 I am using the following code snippet with SHGetKnownFolderPath function to get the current user's Documents folder:
#include <string> // include file for C++ native strings
// . . . other code.
PWSTR ppszPath; // variable to receive the path memory block pointer.
HRESULT hr = SHGetKnownFolderPath(FOLDERID_Documents, 0, NULL, &ppszPath);
std::wstring myPath;
if (SUCCEEDED(hr)) {
myPath = ppszPath; // make a local copy of the path
}
CoTaskMemFree(ppszPath); // free up the path memory block
Note that the documentation has this to say about the path variable usage and the path returned:
ppszPath [out]
Type: PWSTR*
When this method returns, contains the address of a pointer to a
null-terminated Unicode string that specifies the path of the known
folder. The calling process is responsible for freeing this resource
once it is no longer needed by calling CoTaskMemFree. The returned
path does not include a trailing backslash. For example, "C:\Users" is
returned rather than "C:\Users\".
For a list of the FOLDERID_ arguments possible see the MSDN article KNOWN_FOLDER_FLAG enumeration.
Note that CSIDL_PERSONAL will not return the desired folder if the user has changed the default save folder in the Win7 Documents library. To get the right folder, you need to use SHLoadLibraryFromKnownFolder to obtain the IShellLibrary for the Documents library, use IShellLibrary::GetDefaultSaveFolder to get the IShellItem for the library's default save folder, and finally use IShellItem::GetDisplayName to get the folder name.
std::string GetMyDocumentsFolderPath()
{
wchar_t Folder[1024];
HRESULT hr = SHGetFolderPathW(0, CSIDL_MYDOCUMENTS, 0, 0, Folder);
if (SUCCEEDED(hr))
{
char str[1024];
wcstombs(str, Folder, 1023);
return str;
}
else return "";
}
cout<<GetMyDocumentsFolderPath()<<endl;
how about this solution? Its working fine for me.