Where does an output file go? - c

If you have a program that writes to an output file in C, how do you access/see that output file? For instance, I'm trying to write a program that writes the values from a .ppm image file to another .ppm image file, but I don't know how to access the output file after I've done so. I know that's a pretty general question, but I don't have a block of code I can share just yet.

When creating a file with fopen by only specifying a file name, without specifying a path, then the file will be put in the current working directory of your program.
If you are using an integrated development environment (IDE) to launch your program, then you can probably see and set your program's initial working directory in your IDE. If you are running your program directly from a command-line shell, then the file will be placed in the current working directory of the shell.
On most operating systems, you can also determine your program's current working directory by calling a certain function provided by the operating system. For example, on POSIX-compliant operating systems, such as Linux, you can call getcwd. On Microsoft Windows, you can call _getcwd or GetCurrentDirectory. That way, you should easily be able to find out in which directory your file is being created.

Related

Do you need to be specific about a file location when using os or do you still ned to write (folder/file)?

Let's say I have a file called hello.txt in the folder called coding, and I want to open that in python. I know that if I don't use os, I would have to write open("coding/hello.txt") but if I would write os.open would I still have to specify the folder like ("coding/hello.txt") or can I just write os.open("hello.txt") because I am using os?
"File" and "operating system" can mean a lot of different things, but typically operating systems have the concept of a "current" or "working" directory. Each process has its own current directory, and if you don't specify a directory for a file it uses the current directory.
Do not rely on this. Too many things can change the current directory unexpectedly, and your program will suddenly start using a different file.
Instead always specify the full file path like open("/usr/tmp/coding/hello.txt") or whatever is appropriate for your operating system; it will probably provide environment variables or something for the user's home or temporary directories.
Note that your examples "coding/hello.txt" and "hello.txt" both use the current directory, and are different files.

Run a .exe file when a file is opened in a folder

I am mounting a folder as a virtual drive and i want to run a .exe file everytime user opens any file present in that folder. To be precise the folder would contain dummy files present on some other machine. By dummy files i mean the file would be listed but it would be a empty file. Whenever user opens a file i want the .exe program to download that file from another machine and display it to user.
That functionality (remote access on demand) can be implemented using reparse points and file system filters.
You could
use hooks to rewrite the jump address of OpenFile and in the
detour function check for the handle type, retrieve it's info by
using GetFileInformationByHandleEx, parse the data, download
what you need, open the downloaded file and then return
STATUS_SUCCESS or any appropriate error status in case one occurs.
Note
this is a bit more complicated as you also need a auto-inject
mechanism to inject function/library into each process according to
it's architecture.
this is not a safe procedure as most AV's will most likely consider your code malware.

GetPrivateProfileString and AppData VirtualStore directory

I have a program which reads GetPrivateProfileString from a file ".\abcd.ini" - i.e. it will look for the ini file in the current directory.
If it does not find the ini file, it has a default value set in the 3rd parameter to GetPrivateProfileString.
I have an installer which installs the program to c:\program files (x86)\abcd\client directory.
Initially, the installer also installed an abcd.ini file in the same directory with a particular profile string key/value pair. Post that, I changed the installer to not install any ini file.
However, the program continued taking the value from the old ini file which I had shipped even if it didn't exist in that directory.
After doing a system wide search I found a copy of abcd.ini in c:\Users\myusername\AppData\Local\VirtualStore\Program Files (x86)\abcd\Client
Once I deleted this, the program worked correctly (as if there is no ini file).
Googling it seems that the virtualstore is used because myuser does not have full permissions for c:\program files (x86). However, the program itself doesn't write to the ini file, it only reads from it.
Is this actually how it's supposed to be? Why is the ini file copied to AppData & why does the program read from there if there is no local copy?
I am on Windows 10 64 bit.
The diagnostic is that the EXE program does not contain a manifest that declares itself compatible with UAC. Not unusual for the kind of app that still uses GetPrivateProfileString().
Is this actually how it's supposed to be?
Yes, this the way modern versions of Windows (major version >= 6, Vista and up) deal with legacy programs that assume the user always has admin privileges. Redirecting the file access to the VirtualStore directory ensures that the missing access rights to Program Files directory does not cause trouble.
it only reads from it
The OS does not have a time machine to guess whether you might write to the file and did so in a previous session. So it has to check the VirtualStore directory first. To find that .ini file.
It is also important to not assume that it was your program that got the .ini file in that directory. It could have been done by another ancient program, like a text editor. Or a previous version of your program. Or the installer you use.
Yes, because the program would crash, so Windows redirects the program to the VirtualStore directory.

C bind config file to executable

I have a C Programm which reads from a configuration file during runtime. This file have to be in the same Directory as the executable program. Is there a way to bind or compile the configuration file to to executable that when i copy the executable elsewhere i don't have to copy the configuration file aswell?
Is there a way to bind or compile the configuration file to to executable that when i copy the executable elsewhere i don't have to copy the configuration file aswell?
It is inherent in your configuration file indeed being a separate file from your executable binary that the two can be manipulated independently.
If program configuration is performed only at compile time then yes, you can embed the configuration data into the program. That carries the additional advantage that you then need no file I/O to access the configuration data. That would involve your configuration process generating source code to be compiled into the program.
If yours is a conventional form of configuration file, however, meant to be adjusted some time after compilation, and maybe even by end users, then the configuration data cannot be integrated into the executable binary. In that case, no, what you ask is not possible. You cannot then ensure that the config file is moved or copied whenever the executable is.
Additional thoughts:
Requiring the configuration file to be collocated with the binary is fundamentally problematic on the many systems where the location of the binary on the file system is not directly exposed to the running program.
It is usually better for an executable to rely on a default location for its config file, independent of the location of the binary itself. Such a default location can be system-wide, per-user, or a combination of both.
It is fairly common for programs that rely on config files to have the ability to write a default configuration file, either automatically or in response to a special argument. The automatic alternative is more applicable to programs with per-user configuration than to programs with global configuration, however.
When a program is runtime-configurable via a file, it is usually a good idea to offer the option of specifying the file to use via a command-line argument.

How to determine if a file is on a FAT system (to see if it really is executable)

I am working at an OS independent file manager, and I divide files in groups, usually based on the extension. On Linux, I check if a file has the executable permissions or not, and if it does, I add it to the executables group.
This works great for Windows or Linux, but if you combine them it doesn't work so well. For example, while using it on Linux and exploring a windows mounted drive, all the files appear to be executable. I am trying to find a way to ignore those files and not add them to the executables group.
My code (on Linux) uses stat:
#ifndef WINDOWS
stat(ep->d_name, &buf);
....
if(!files_list[i].is_dir && buf.st_mode & 0111)
files_list[i].is_exe=1;
#endif
The first part of the answer is to find what filesystem the file is mounted on. To do that you need to find the filesystem using the st_dev field of the stat information for the file. (You can also do this by checking the file path, but you then have to check every path element for symbolic links).
You can then cross-reference the st_dev field with the mount table in /proc/mounts using getmntent_r(). There's an example of that in a previous answer. The mnt_type field will give you the text of the filesystem type, and you'll need to compare the string with a list of Windows filesystems.
Once you've found the filesystem, the only way to identify an executable is by heuristics. As other people have suggested, you can look at the file extension for Windows executables, and look at the initial bytes of the file for Linux executables. Don't forget executable scripts with the #! prefix, and you may need to read into a Jar file to find out if it contains an executable static main() method.
If you are browsing Windows files then you need to apply Windows rules for whether or not a file is executable. If the file extension is .EXE, .COM, .BAT, or .CMD then it is executable. If you want a more complete list then you should check MSDN. Note that it is possible to add registry entries on a machine that makes any extension you want to be considered executable, but it is best to ignore that kind of thing when you are browsing a drive from the network.
The fact is that you are fighting an uphill battle. The reason all the files have executable permissions is that the windows filesystem driver on Linux allows you to specify that as an option. This masks whether or not any files are Linux exceutables, for instance.
However, you could look into the file header for EVERY file and see if it is a Linux ELF executable (just like the Linux file command does).
It might be helpful to start by checking all the information about mounted filesystems so that you know what you are dealing with. For instance, do you have a CIFS filesystem mounted that is actually a Linux filesystem served up by SAMBA? If you enumerate every bit of information available about the mounted filesystem plus the complete set of stat info, you can probably identify combinations that act as fingerprints of the different scenarios.
Another option I could imagine, is to call the file util, and depend on its output (maybe its enough to grep for the words executable / script). This util exist/is compileable for windows (basically it just checks for some magic bytes in the files), too.

Resources