Recovering Files on Windows and C - c++

Well this time I'm trying to write a program in C which recover deleted files from a disk, it could be an external disk, I have an idea than i had used before on linux, it is to open the disk as a kind of file and scaning the Headers and file footers of everything within the disk, the point is I'm not sure if there's allow on windows to open a disk as an File, basiclly I have the logic how to develope this program, but I'm not sure how to implement it on windows, anybody can give me a hand with this?.
The code I used on linux to open a disk as a file was:
Edit: That was a sample of what I was using guys, it's just to give you an idea of what I was doing, the correct syntax I used was the next:
direccion = ui->linea->text().toLatin1().constData();
f = fopen(direccion,"rb");
I used QT creator on linux, and direccion variable was a TextField value which contained the file path of the disk through a button function that open a QFileDialog...
could I use it in windows as well?
Thank you before hand..

"The code I used on linux to open a disk as a file was:"
File *f = fopen("E:\", "rb");
I seriously doubt you ever got this code working on any linux system (or windows either).
You'll need to escape the backslash path delimiter, if it's presented in any string literal:
FILE* f = fopen("E:\\", "rb");
// ^
Also all that filesystem path style you are presenting to access a particular disk, is about accessing a windows file path/disk.
No linux file system has notion about drive characters, and the file path delimiter value used is '/', not '\\'.

To recover deleted files, you can't use fopen or fstream::open because the file was deleted. Check the return value from the function or test the stream state.
The way to recover deleted files is:
Get the Master File Table as raw data.
Search for the record containing a string similar to the deleted
filename.
Change the entry in the Master File Table to "undeleted".
Write the Master File Table back to the drive.
The above usually requires platform specific API, which is different on Linux and Windows platforms.

Related

Downloading my programs data from a webserver (Its basically just a .exe turned into .txt) but when I put it into a .exe it does not run?

So currently I am using a basic Http request to pull the exe data from my server weblink.com/Program.exe
it returns my program in .txt form but when I put it into a file it will not run.
I assume this is because I need metadata but have no clue how to find that process or even how to google something as specific as that... So I am either asking for a solution (how to add proper .exe metadata) or if there is a better way to download files like that in C++
*Note I cannot use basic windows functions such as DownloadToFileA or External Library's (Like LibCurl/Curl)
OutFile.open(XorStr("C:\\Users\\Program.exe").c_str(), std::ios::out);
if (OutFile.is_open())
{
OutFile << Output;
//Initialize .exe Meta Data???
}
OutFile.close();
You need to open your file in binary mode otherwise newline translation will screw up your executable:
OutFile.open(XorStr("C:\\Users\\Program.exe").c_str(), std::ios::out | std::ios::binary);

How to read a file name containing 'œ' as character in C/C++ on windows

This post is not a duplicate of this one: dirent not working with unicode
Because here I'm using it on a different OS and I also don't want to do the same thing. The other thread is trying to simply count the files, and I want to access the file name which is more complex.
I'm trying to retrieve data information through files names on a windows 10 OS.
For this purpose I use dirent.h(external c library, but still very usefull also in c++).
DIR* directory = opendir(path);
struct dirent* direntStruct;
if (directory != NULL)
{
while (direntStruct = readdir(directory))
{
cout << direntStruct->d_name << endl;
}
}
This code is able to retrieve all files names located in a specific folder (one by one). And it works pretty well!
But when it encounter a file containing the character 'œ' then things are going crazy:
Example:
grosse blessure au cœur.txt
is read in my program as:
GUODU0~6.TXT
I'm not able to find the original data in the string name because as you can see my string variable has nothing to do with the current file name!
I can rename the file and it works, but I don't want to do this, I just need to read the data from that file name and it seems impossible. How can I do this?
On Windows you can use FindFirstFile() or FindFirstFileEx() followed by FindNextFile() to read the contents of a directory with Unicode in the returned file names.
Short File Name
The name you receive is the 8.3 short file name NTFS generates for non-ascii file names, so they can be accessed by programs that don't support unicode.
clinging to dirent
If dirent doesn't support UTF-16, your best bet may be to change your library.
However, depending on the implementation of the library you may have luck with:
adding / changing the manifest of your application to support UTF-8 in char-based Windows API's. This requires a very recent version of Windows 10.
see MSDN:
Use the UTF-8 code page under Windows - Apps - UWP - Design and UI - Usability - Globalization and localization.
setting the C++ Runtime's code page to UTF-8 using setlocale
I do not recommend this, and I don't know if this will work.
life is change
Use std::filesystem to enumerate directory content.
A simple example can be found here (see the "Update 2017").
Windows only
You can use FindFirstFileW and FindNextFileW as platform API's that support UTF16 strings. However, with std::filesystem there's little reason to do so (at least for your use case).
If you're in C, use the OS functions directly, specifically FindFirstFileW and FindNextFileW. Note the W at the end, you want to use the wide versions of these functions to get back the full non-ASCII name.
In C++ you have more options, specifically with Boost. You have classes like recursive_directory_iterator which allow cross-platform file searching, and they provide UTF-8/UTF-16 file names.
Edit: Just to be absolutely clear, the file name you get back from your original code is correct. Due to backwards compatibility in Windows filesystems (FAT32 and NTFS), every file has two names: the "full", Unicode aware name, and the "old" 8.3 name from DOS days.
You can absolutely use the 8.3 name if you want, just don't show it to your users or they'll be (correctly) confused. Or just use the proper, modern API to get the real name.

How to create an uncleared file?

I am a beginner C++ programmer.
I want to create a binary file, that is uncleared with the previous information that was in it. This is easy to do with RAM, simply by making an array, but how do I do this on a hard drive?
How do I create a uncleared file?
In other words how do I retrieve data that was not "cleared" but just marked "empty".
However, if the OS does not allow it, can I launch linux from USB and run my software?
To keep the content of a file to be written on, you can open a file in append mode with:
[ofstream ofs ("filename", ios::binary | ios::app);][1]
All output operations append at the end of the file. Alternatively, you could also use ios::ate so that the output position starts at the end of the file (but afterwards it's up to you).
With the usual read operations you can retrieve preexisting content, by first positionning yourself using seekp().

iOS file size during write using only C/C++ APIs

Purpose: I am monitoring file writes in a particular directory on iOS using BSD kernel queues, and poll for file sizes to determine write ends (when the size stops changing). The basic idea is to refresh a folder only after any number of file copies coming from iTunes sync. I have a completely working Objective-C implementation for this but I have my reasons for needing to implement the same thing in C++ only.
Problem: The one thing stopping me is that I can't find a C or C++ API that will get the correct file size during a write. Presumably, one must exist because Objective-C's [NSFileManager attributesOfItemAtPath:] seems to work and we all know it is just calling a C API underneath.
Failed Solutions:
I have tried using stat() and lstat() to get st_size and even st_blocks for allocated block count, and they return correct sizes for most files in a directory, but when there is a file write happening that file's size never changes between poll intervals, and every subsequent file iterated in that directory have a bad size.
I have tried using fseek and ftell but they are also resulting in a very similar issue.
I have also tried modified date instead of size using stat() and st_mtimespec, and the date doesn't appear to change during a write - not that I expected it to.
Going back to NSFileManager's ability to give me the right values, does anyone have an idea what C API call that [NSFileManager attributesOfItemAtPath:] is actually using underneath?
Thanks in advance.
Update:
It appears that this has less to do with in-progress write operations and more with specific files. After closer inspection there are some files which always return a size, and other files that never return a size when using the C API (but will work fine with the Objective-C API). Even creating a copy of the "good" files the C API does not want to give a size for the copy but works fine with the original "good" file. I have both failures and successes with text (xml) files and binary (zip) files. I am using iTunes to add these files to the iPad's app's Documents directory. It is an iPad Mini Retina.
Update 2 - Answer:
Probably any of the above file size methods will work, if your path isn't invisibly trashed, like mine was. See accepted answer on why the path was trashed.
Well this weird behavior turned out to be a problem with the paths, which result in strings that will print normally, but are likely trashed in memory enough that file descriptors sometimes didn't like it (thus only occurring in certain file paths). I was using the dirent API to iterate over the files in a directory and concatenating the dir path and file name erroneously.
Bad Path Concatenation: Obviously (or apparently not-so-obvious at runtime) str-copying over three times is not going to end well.
char* fullPath = (char*)malloc(strlen(dir) + strlen(file) + 2);
strcpy(fullPath, dir);
strcpy(fullPath, "/");
strcpy(fullPath, file);
long sizeBytes = getSize(fullPath);
free(fullPath);
Correct Path Concatenation: Use proper str-concatenation.
char* fullPath = (char*)malloc(strlen(dir) + strlen(file) + 2);
strcpy(fullPath, dir);
strcat(fullPath, "/");
strcat(fullPath, file);
long sizeBytes = getSize(fullPath);
free(fullPath);
Long story short, it was sloppy work on my part, via two typos.

C++ - Can't open file from network path in Windows

I'm having problems using native C++ to open a file located on a network drive on a Windows box. My code works fine if the file is local, but fails if the file is on a network share. I can read the file from Windows explorer perfectly fine.
ifstream ifs(cFilename);
if(ifs.is_open())
{
// Read file here. (This never works for a network path)
}
I've also tried this:
struct stat sb;
if (stat(cFilename, &sb) == 0)
{
// Read file here. (This never works for a network path)
}
My path is formatted correctly (e.g. "\\server\filename.ext"), but I still can't open it. Any ideas?
If the name is in the form \\server\filename, then it seems that might not be correct. I believe that typically it needs a share name as well:
\\server\share\filename
Also, make sure that in the code, you escape the backslashes (e.g., \\\\server\\share\\filename).