C++ fopen() returns NULL pointer on some Windows - c++

I'm developing a little updater for my framework. In particular the file is written in C++ and when i try to download a file using the following code the fopen function returns NULL. But the thing is that i tested this software on different machines with the same OS (Windows 10) and on few of them they returns NULL, the others just download and write the file correctly. Do you have any ideas? I've also tried to TRIM the filename to avoid invisible characters. Here's the code to download the file i used:
std::vector<unsigned char> resp = http_request(url, "GET", NULL, NULL, "", user_agent);
if (resp.empty()) {
send_output("ERROR: No response while downloading: " + url);
return;
}
string filename = url.substr(url.rfind("/") + 1);
filename = trim(filename);
if (filename.empty()) {
filename = "downloaded";
}
FILE* f = fopen(filename.c_str(), "wb");
if (f == NULL) {
log("ERROR: Could not open file for writing: " + filename);
return;
}
fwrite(&resp[0], 1, resp.size(), f);
fclose(f);
Thanks guys for the help!

Related

Downloading a file from a webserver error (C++)

As the title says, I want to download a file from a webserver (eg. localhost/file.txt), but there is a problem. When I use "URLDownloadToFileW", "URLDownloadToFile" and "URLDownloadToFileA", the function return true, but the file doesn't download.
Here is the function that downloads the file:
void MyFunction() {
const char* url_to_download = "localhost/file.txt";
const char* file_dest = "C:\\fileDownloaded.txt";
if (S_OK != URLDownloadToFile(NULL, url_to_download, file_dest, 0, NULL)) {
system("cls");
std::cout << "Failed to get dll!";
system("pause");
exit(1);
}
}
Again, my problem is that the file doesn't download (i can't find the file where I told the URLDownload function to save), but URLDownloadToFile function return true (it returns S_OK but for the sake of this post, let's say that it returns true)
Thanks!

FindNextFile Faild with Space Character

I wrote a simple code to do some operation on every file in every folder (subfolders).
It's perfectly works until the path comes with 'SPACE
' character program crashs and INVALID_HANDLE_VALUE has been called. This is function:
int dirListFiles(char* startDir)
{
HANDLE hFind;
WIN32_FIND_DATAA wfd;
char path[MAX_PATH];
sprintf(path, "%s\\*", startDir);
std::string fileName;
std::string s_path = startDir;
std::string fullPath;
fprintf(stdout, "In Directory \"%s\"\n\n", startDir);
if ((hFind = FindFirstFileA(path, &wfd)) == INVALID_HANDLE_VALUE)
{
printf("FindFirstFIle failed on path = \"%s\"\n", path);
abort();
}
BOOL cont = TRUE;
while (cont == TRUE)
{
if ((strncmp(".", wfd.cFileName, 1) != 0) && (strncmp("..", wfd.cFileName, 2) != 0))
{
if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
sprintf(path, "%s\\%s", startDir, wfd.cFileName);
dirListFiles(path);
}
else
{
fileName = wfd.cFileName;
fullPath = s_path + "\\" + fileName;
std::string fileExt = PathFindExtension(fullPath.c_str());
if (fileExt == ".cpp")
{
... Some operation on file
}
}
}
cont = FindNextFile(hFind, &wfd);
}
FindClose(hFind);
For example, If FindNextFile wants to Open Program Files (x86) which has space between file name cause error and program exit. What Can I do for supporting spaces? What Is Problem?
Space is legal character in directory and file names.
First I propose to modify slightly your code:
if ((hFind = FindFirstFileA(path, &wfd)) == INVALID_HANDLE_VALUE)
{
printf("FindFirstFIle failed on path = \"%s\". Error %d\n", path, GetLastError());
return 0; // I think you shouldn't abort on error, just skip this dir.
}
Now check error codes reported by your program.
For some paths I have got error #5 (access denied). Examples:
c:\Program Files (x86)\Google\CrashReports\*
c:\ProgramData\Microsoft\Windows Defender\Clean Store\*
c:\Windows\System32\config\*
Got two cases with code #123 (Invalid name) for path names unmanageable by FindFirstFileA. To correct this behavior it would be better to use wide version of function FindFirstFileW. See both answers for c++ folder only search. For new Windows applications you should use wide version of API, converting with MultiByteToWideChar and WideCharToMultiByte if needed.
You have also logic error. Code skips all directories and files starting with dot.

PathFileExists returns false when executing application through RemoteApp

My executable built in C++/WinAPI will check for a file placed in the same folder and I use PathFileExists for that. When I run it on a normal computer it finds the file but when I publish the executable on RemoteApp and I run it from Web Access the file is not found. What would I be missing?
// This is the file I want to find (located in the same directory as the EXE)
wstring myfile = L"myfile.conf";
BOOL abspath = FALSE;
// Trying to get the absolute path first
DWORD nBufferLength = MAX_PATH;
wchar_t szCurrentDirectory[MAX_PATH + 1];
if (GetCurrentDirectory(nBufferLength, szCurrentDirectory) == 0) {
szCurrentDirectory[MAX_PATH + 1] = '\0';
} else {
abspath = true;
}
if (abspath) {
// Create the absolute path to the file
myfile = L'\\' + myfile;
myfile = szCurrentDirectory + myfile ;
MessageBox(hWnd, ConvertToUNC(myfile).c_str(), L"Absolute Path", MB_ICONINFORMATION);
} else {
// Get the UNC path
myfile = ConvertToUNC(myfile);
MessageBox(hWnd, myfile.c_str(), L"UNC Path", MB_ICONINFORMATION);
}
// Try to find file
int retval = PathFileExists(myfile.c_str());
if (retval == 1) {
// Do something
} else {
// File not found
}
The ConvertToUNC function is copied from here.
What I see is that, although the executable lies somewhere else, the absolute path is considered to be C:\Windows. I really don't know what is causing this. The server is Windows 2012 R2 and, like I said, applications are run through RemoteApp Web Access. The returned UNC path is just the name of the file (no volume or folder)

Optimize Disk Enumeration and File Listing C++

I am writing C++ code to enumerate whole HDD and drive listing, however it takes more than 15 minutes to complete the disk enumeration of all drives (HDD capacity 500GB). and compile the response in Binary file.
However, I have a 3rd party Executable which gives me the listing of whole Disk in just less than two minutes ... Can you please look into my code and suggest me some performance improvement techniques.
EnumFiles(CString FolderPath, CString SearchParameter,WIN32_FIND_DATAW *FileInfoData)
{
CString SearchFile = FolderPath + SearchParameter;
CString FileName;
hFile = FindFirstFileW(SearchFile, FileInfoData); // \\?\C:\*
if (hFile == INVALID_HANDLE_VALUE)
{
// Error
}
else
{
do
{
FileName = FileInfoData->cFileName;
if (FileInfoData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
if (! (FileName == L"." || FileName == L".."))
{
// Save the Folder Information
EnumFiles(FolderPath + FileName +(L"\\"), SearchParameter,FileInfoData);
}
}
else
{
// Save the File Parameters
}
} while (FindNextFileW(hFile, FileInfoData));
}
FindClose(hFile);
}

Interacting with a servlet from a C++ code

Good day, I'm trying to call a java servlet from a C++ code. So far I've gotten to this:
execl( "/usr/bin/lynx", "lynx", "-dump", url.c_str(), (char *) 0);
where "url" is the url encoded string holding the address and parameters.
However I haven't found a way to let execl to return the servlet response in order for me to analyze it within the code. Is there an alternate more efficient way to calling a servlet and handling the answer?
Thank you!
You can do it with pipe:
string cmd = "lynx -dump ";
cmd += url;
FILE* pipe = popen(cmd.c_str(), "r");
if (!pipe)
{
cout << "Couldn't open pipe";
return;
}
char buffer[128];
string result = "";
while(!feof(pipe))
{
if(fgets(buffer, 128, pipe) != NULL)
result += buffer;
}
pclose(pipe);