How to get the path of the exexuter in C++? - c++

I am using Visual studio 2008 and I want to get the absolute path of the .exe file?
meaning when the user opens the exe file, I need to know its absolute path??
thanks in advance

Under Windows try the following:
char ExeName[8192]; // or what ever max. size you expect.
if (0 != GetModuleFileName (NULL, ExeName, sizeof (ExeName)))
{
printf ("Your array was probably not large enough. Call GetLastError for details\n");
}
If you compile for unicode use wchar_t.

Using the _pgmptr or _wpgmptr global variable is probably the easiest way.* (They're in stdlib.h.)
*Note: Under some rather rare circumstances, it's possible that this won't work... in that case, use GetModuleFileName(NULL, ...);

If you want to obtain a path of the current process, you should use API function:
GetModuleFileName
But, if you want to obtain a full path of the process that is not written by you, use
GetModuleFileNameEx
Above function expects one argument more than GetModuleFileName - it is a HANDLE of a process which path is supposed to be obtained. It is explained in more details on MSDN.

Related

Move a text file from one location to another in Turbo C++

I have been trying to use the following code snippet to move a text file from one location to another (to a folder on the Desktop). However, the method of using the REN function of DOSBox or the rename function of C++ has failed.
char billfile[] = "Text.txt";
char path[67] = "ren C:\\TURBOC3\\Projects\\";
strcat(path, billfile);
strcat(path, " C:\\Users\\Admini~1\\Desktop\\Bills");
system(path);
Are there any other alternatives to this?
P.S.: This is for a school project, where Turbo C++ has to be used
Corresponding to this website for stdio.h the TurboC run-time library supports the rename function.
So even if you are obliged to use a totally outdated tool like TurboC++ it's not necessary to spawn a new process with the system function just to rename the file.
If you are using the Win32 API then consider looking into the functions CopyFile or CopyFileEx.
You can use the first in a way similar to the following:
CopyFile( szFilePath.c_str(), szCopyPath.c_str(), FALSE );
This will copy the file found at the contents of szFilePath to the contents of szCopyPath, and will return FALSE if the copy was unsuccessful. To find out more about why the function failed you can use the GetLastError() function and then look up the error codes in the Microsoft Documentation.

Finding where a handle is open to

I'm messing around with handles / hooks, and have a question. Right now, I have a DLL that I inject into the process that I'm playing with. The DLL hooks the CloseHandle() function. When CloseHandle is called, I do the following:
int WINAPI DetourCloseHandle(HANDLE hObject)
{
OutputDebugStringA("CLOSE HADNLE");
char name[MAX_PATH];
GetFinalPathNameByHandle(hObject, name, MAX_PATH, FILE_NAME_NORMALIZED);
OutputDebugStringA(name);
return oCloseHandle(hObject);
}
My goal in this is to figure out where the handle is open to, and if the handle is open to a certain process, then use the handle to read that processes memory. What gets printed out when CloseHandle is called is usually paths to random files that the application reads, but I also noticed random ASCII characters being printed at times, as the "Name" of where the handle is opened to. This can be seen here.
Sometimes I also notice paths to certain .exe files. This is not unusual, as the application that I'm injecting into does read / look at binary files. My question is, when I see the "name" returned from GetFinalPathNameByHandle as the path to an exe file, how do I know if the handle is opened to the binary file itself, or if the handle file is opened to the actual running process with that name.
I would also like some insight as to what the ASCII characters that are being printed are. Thanks!
For the random data print you pasted, it likely was because it is just uninitialized garbage in name array, you should always check GetFinalPathNameByHandle's return value before do something with name:
DWORD ret = GetFinalPathNameByHandle(hObject, name, MAX_PATH, FILE_NAME_NORMALIZED);
if (ret) {
OutputDebugStringA(name);
} else {
OutputDebugStringA("GetFinalPathNameByHandle");
// check GetLastError()
}
Also, note that GetFinalPathNameByHandle thake the string as TCHAR strings, and you are print it via OutputDebugStringA. So I would suggest either use the ANSI version GetFinalPathNameByHandleA, or use TCHAR name[MAX_PATH]; and print with OutputDebugString instead.

GetDiskFreeSpaceEx with NULL Directory Name failing

I'm trying to use GetDiskFreeSpaceEx in my C++ win32 application to get the total available bytes on the 'current' drive. I'm on Windows 7.
I'm using this sample code: http://support.microsoft.com/kb/231497
And it works! Well, almost. It works if I provide a drive, such as:
...
szDrive[0] = 'C'; // <-- specifying drive
szDrive[1] = ':';
szDrive[2] = '\\';
szDrive[3] = '\0';
pszDrive = szDrive;
...
fResult = pGetDiskFreeSpaceEx ((LPCTSTR)pszDrive,
    (PULARGE_INTEGER)&i64FreeBytesToCaller,
    (PULARGE_INTEGER)&i64TotalBytes,
(PULARGE_INTEGER)&i64FreeBytes);
fResult becomes true and i can go on to accurately calculate the number of free bytes available.
The problem, however, is that I was hoping to not have to specify the drive, but instead just use the 'current' one. The docs I found online (Here) state:
lpDirectoryName [in, optional]
A directory on the disk. If this parameter is NULL, the function uses the root of the current disk.
But if I pass in NULL for the Directory Name then GetDiskFreeSpaceEx ends up returning false and the data remains as garbage.
fResult = pGetDiskFreeSpaceEx (NULL,
    (PULARGE_INTEGER)&i64FreeBytesToCaller,
    (PULARGE_INTEGER)&i64TotalBytes,
(PULARGE_INTEGER)&i64FreeBytes);
//fResult == false
Is this odd? Surely I'm missing something? Any help is appreciated!
EDIT
As per JosephH's comment, I did a GetLastError() call. It returned the DWORD for:
ERROR_INVALID_NAME 123 (0x7B)
The filename, directory name, or volume label syntax is incorrect.
2nd EDIT
Buried down in the comments I mentioned:
I tried GetCurrentDirectory and it returns the correct absolute path, except it prefixes it with \\?\
it returns the correct absolute path, except it prefixes it with \\?\
That's the key to this mystery. What you got back is the name of the directory with the native api path name. Windows is an operating system that internally looks very different from what you are familiar with winapi programming. The Windows kernel has a completely different api, it resembles the DEC VMS operating system a lot. No coincidence, David Cutler used to work for DEC. On top of that native OS were originally three api layers, Win32, POSIX and OS/2. They made it easy to port programs from other operating systems to Windows NT. Nobody cared much for the POSIX and OS/2 layers, they were dropped at XP time.
One infamous restriction in Win32 is the value of MAX_PATH, 260. It sets the largest permitted size of a C string that stores a file path name. The native api permits much larger names, 32000 characters. You can bypass the Win32 restriction by using the path name using the native api format. Which is simply the same path name as you are familiar with, but prefixed with \\?\.
So surely the reason that you got such a string back from GetCurrentDirectory() is because your current directory name is longer than 259 characters. Extrapolating further, GetDiskFreeSpaceEx() failed because it has a bug, it rejects the long name it sees when you pass NULL. Somewhat understandable, it isn't normally asked to deal with long names. Everybody just passes the drive name.
This is fairly typical for what happens when you create directories with such long names. Stuff just starts falling over randomly. In general there is a lot of C code around that uses MAX_PATH and that code will fail miserably when it has to deal with path names that are longer than that. This is a pretty exploitable problem too for its ability to create stack buffer overflow in a C program, technically a carefully crafted file name could be used to manipulate programs and inject malware.
There is no real cure for this problem, that bug in GetDiskFreeSpaceEx() isn't going to be fixed any time soon. Delete that directory, it can cause lots more trouble, and write this off as a learning experience.
I am pretty sure you will have to retrieve the current drive and directory and pass that to the function. I remember attempting to use GetDiskFreeSpaceEx() with the directory name as ".", but that did not work.

Win API Local File Reference c++

I am trying to hard code into C++ program to look for config.ini in the same directory as the executable, without knowing the complete path to the file. I am trying to find a way to make a local reference to the executable.
Basically load ("./config.ini")
without doing
("C:\foo\bar\config.ini")
There isn't really any guaranteed portable way of doing this, but I like to use this code because it works in the vast majority of cases (unless symlinks or other magic is involved):
boost::filesystem::current_path(boost::filesystem::path(argv[0]).remove_filename());
If you are willing to use platform specific code look at GetModuleFileName on Windows and a mix of getpid, reading from /proc and readlink on Linux.
You want GetModuleFilename() on Windows (pass NULL to get filename of current executable). Otherwise, call boost::filesystem::initial_path() early in the program (see Boost docs in link for the reason to do this early). That should cover most of the situations.
Edit
Brain malfunction. We always start our programs from the executable's directory, so the boost::initial_path() thing works, but it won't work so well if you start the program from another direcory. Sorry for the confusion on that. On Windows, though, I'd get the path from GetModuleFilename and use boost::path to manipulate the result.
For windows, this will get the directory containing the excutable as a c++ string:
#include <windows.h>
#include <string>
#include <iostream>
using namespace std;;
string ExePath() {
char buffer[MAX_PATH];
GetModuleFileName( NULL, buffer, MAX_PATH );
string::size_type pos = string( buffer ).find_last_of( "\\/" );
return string( buffer ).substr( 0, pos);
}
You can then just tag the name of your config file on the end.
For Windows:
#include <direct.h>
char cur_path[FILENAME_MAX];
if (!_getcwd(cur_path, sizeof(cur_path)))
{
// deal with error
}
cur_path[sizeof(cur_path) - 1] = '/0'; // adding \0 at the end of the string
printf("Current dir: %s", cur_path);
A platform-agnostic solution was discussed here:
How do I get the directory that a program is running from?

How to set the application path to the running program?

I have a program that is executed by another program. The program that is being executed needs files located at its own location [same folder]. If I call myfile.open("xpo.dll") I might get an error because I am not passing the [fullpath + name + extension]. The program that is being executed can vary paths depending on the installation path. Therefore, I was wondering if there is a way to get the application path [where the application is located] and set it so that when another program executes from another path everything might work properly...?
[Using C++ without .NET Framework]
Thanks.
Use GetModuleFileName and pass NULL for hModule.
DWORD GetModuleFileName(
HMODULE hModule, // handle to module
LPTSTR lpFilename, // path buffer
DWORD nSize // size of buffer
);
First off, I run into this problem in other languages a lot, and find Process Monitor (http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx) very useful for finding out what folder it is currently trying to access.
There is no standard function for doing this.
Just a thought, have you tried doing myfile.open "./xpo.dll"?
If it's a console application, you can use the POSIX getcwd function: http://www.dreamincode.net/code/snippet77.htm
If it's a Windows app and you can use the windows API, you can use GetModuleFileName... see the second reply to this question here: How do I get the directory that a program is running from?