Can GetFileAttributesW handle url-encoded spaces (%20) in file paths? - c++

Function call:
OS_WRAPI::GetFileAttributesW(file_name_str); // file_name_str value is L"C:\\Test%20Tool\\test.exe"
returns INVALID_FILE_ATTRIBUTES.
Function call:
OS_WRAPI::GetFileAttributesW(file_name_str); // file_name_str value is L"C:\\TestTool\\test.exe"
returns valid attributes.
Both paths exist.
How can I get the file attributes in the case of url-encoded spaces (%20) in the file path?

Can GetFileAttributesW handle spaces in filepaths?
Yes.
Note that L"C:\\Test%20Tool\\test.exe" does not contain a space. Probably you should be passing L"C:\\Test Tool\\test.exe".
The documentation says:
If the function fails, the return value is INVALID_FILE_ATTRIBUTES. To get extended error information, call GetLastError.
So you should, in case INVALID_FILE_ATTRIBUTES is returned, call GetLastError. I'd expect that to return ERROR_PATH_NOT_FOUND.
If the question is actually
Can GetFileAttributesW handle L"%20" in filepaths?
The answer is still yes. If that path really exists, and GetFileAttributesW is returning INVALID_FILE_ATTRIBUTES, then there must be some other problem, but the presence of L"%20" in a file name presents no problems for the Windows API. Again start by calling GetLastError.
Perhaps what's really at issue here, is that you think that Windows uses L"%20" to encode a string in the file system. It does not. On the file system, L"%20" and L" " are two distinct names.

Related

C++: How do I use memory address with a .exe base instead of a .dll base

getting into game manipulation, I've always used
DWORD ClientBase = (DWORD)GetModuleHandle("thing.dll");
and now I have a base that uses an .exe, what do I do, the address is always reading 0 no matter what I do.
The call is failing. Check that you have the correct path to the file you're trying to open.
From: https://learn.microsoft.com/en-us/previous-versions/ms908443(v=msdn.10)
Return Values
A handle to the specified module indicates success. NULL indicates failure. To get extended error information, call GetLastError.

Unreadable file attributes on windows

Consider a following snippet of code
#include <iostream>
#include <windows.h>
int main()
{
WIN32_FILE_ATTRIBUTE_DATA wfad;
GetFileAttributesEx(("C:\\TEMP\\noreadfile"), GetFileExInfoStandard, &wfad); //"noreadfile" is unreadable file
std::cout << wfad.dwFileAttributes; // 128
return 0;
}
For an unreadable file (File that does not have read permissions or file that has its read permissions set as "Deny" in its properties -> security tab) on Windows, GetFileAttributesEx returns FILE_ATTRIBUTE_NORMAL, which means that no other attribute is set for that file.
This attribute is also returned for a writeable as well as non-readonly files.
We use this information to set the permissions for files in our product code.
We concluded that GetFileAttributesEx might be returning incorrect attribute in case of unreadable files. We wonder if our conclusion is right or not.
If yes, then is this a known issue with GetFileAttributesEx ?
If not then
What is the correct way to get the file attributes (file permissions perhaps ?) for an unreadable file using Windows API or if possible using Boost or standard C++ filesystem libraries ?
It's probably not succeeding at all. If you look at the documentation for GetFileAttributesEx, it actually returns a BOOL.
Return value If the function succeeds, the return value is a nonzero
value.
If the function fails, the return value is zero (0). To get extended
error information, call GetLastError.
My guess is that "fwad" is undefined if the call fails. Try checking the return value for a failure indication. My guess is that GetLastError will return something like ERROR_ACCESS_DENIED.
The Windows API doesn't throw exceptions, so unfortunately you'll have to check just about every return value.

CaptureStackBackTrace with file information

I'm using CaptureStackBackTrace and SymFromAddr to identify the functions in the callstack.
Is there a way to find the source file of each symbol with this (i can't find any documentation for this)? Or i have to use StackWalk ?
The solution was to use SymGetLineFromAddr which gives the file path and the line number. In order to do this you must set SYMOPT_LOAD_LINES flag before calling SymInitialize. Also the 3'rd argument of SymGetLineFromAddr must be not NULL, otherwise it will crash.
Raxvan.

when would failbit be set while executing a getline function call in c++

when would getline in c++ fail?
I have a big snippet of code which I am unable to paste in its entirety for multifarious reasons. I am trying to read from a file , which I know exists and contains data, using getline in C++. But getline fails returning error 123-invalid name(output of getlasterror). I looked up the error code which baffles me even more.
I do error check while opening the file. So I am positive that I have the handle to the file.
Please bear with me for not pasting the code. I am new to c++ and especially in windows. Any suggestions or insights about getline would help. I am trying to read a file which is dumped by a compiler.
This is an extract from the code
ifstream inFile("C:\...\ash.txt",ios::in);
string singleLine;
getline(inFile,singleLine);
singleLine is empty ! I am doing something silly..pls point that out to me! appreciate it
IMPORTANT EDIT:
I checked for the ios members and found that fail bit is set. Why would the fail bit be set? the file does exist and also I was wondering if how windows exposes file extensions could cause a problem . That doesnt seem to the problem. What am i missing?
GetLastError only tells you about Win32 API calls, which std::getline is not.
Check the members of the iostream that failed, e.g. rdstate().
Calling ios::exceptions(eofbit | failbit | badbit) before getline and catching the resulting exception might or might not get you a more descriptive error message.
If the fail bit is set, it is probably because you didn't successfully open the file. Check whether ifFile.is_open() returns true; if not, then then probably indicates that the file is not open correctly. You might not have permissions, or you may need to escape the string properly, or the file may be locked.
You should also check if fail is set both before and after the call to getline. If it's before, that probably means that the file isn't open. If it's after, it could mean that the file is empty.
It may be the case that Windows is hiding the true file extension from you. The file name might actually be named ash.txt.txt, for example, if you have Explorer configured to hide file extensions. That might be worth investigating if the file isn't open.
Do you need to escape the backslashes in the file path?
It failed to open the file.
This is becuase you did not specify the correct path.
This is because you used the ancient windows convention of \ as a path separator.
Which also happens to be the escape character in C.
Which is why Windows lets you use / as a path separator (and has done for over a decade) because the use of '/' is so error prone.
Your path should be:
ifstream inFile("C:\\...\\ash.txt");
// Or my preference
ifstream inFile("C:/.../ash.txt");
Or even better use boost.
Getline IIRC is meant for c_strings and the string is the first argument, not the second.
http://www.cplusplus.com/reference/iostream/istream/getline/
You're attempting to use a normal string, which (I could be wrong) doesn't work with getline.

CInternetSession::OpenURL exception if headers are defined. Works fine if not. Why?

Trying to log the application version details in our weblogs using the headers:
Should be a one liner..but for some reason whenever I specify anything but NULL for the headers it causes an exception (InternetOpenUrl() call returns NULL) - anyone able to explain why?
CInternetSession internet;
CHttpFile * pHttpFile;
CString headers;// = APPLICATION_SUITE_NAME;
DWORD dwHeadersLength = -1;
headers.Format("%s %s %s\n",APPLICATION_SUITE_NAME,SHORT_APPLICATION_VERSION,BUILDNO_STR);
pHttpFile =(CHttpFile *) internet.OpenURL(lpszURL, 1, INTERNET_FLAG_TRANSFER_ASCII|INTERNET_FLAG_DONT_CACHE, headers, dwHeadersLength);
Without the headers, dwHeadersLength parameter (eg. pass in NULL,-1) then it goes through fine and I see the request come through to our website. But why does it fail if I pass in custom headers?
Does your CString resolve to CStringA or CStringW? If the latter (i.e. wide-char), here's a bit from MSDN (http://msdn.microsoft.com/en-us/library/aa384247%28VS.85%29.aspx):
If
dwHeadersLength is -1L and lpszHeaders
is not NULL, the following will
happen: If HttpSendRequestA is called,
the function assumes that lpszHeaders
is zero-terminated (ASCIIZ), and the
length is calculated. If
HttpSendRequestW is called, the
function fails with
ERROR_INVALID_PARAMETER.
I'm mentioning HttpSendRequest() because, in fact, CInternetSession::OpenURL() calls InternetOpenUrl(), whose documentation for the lpszHeaders parameters sends you to the doc page for HttpSendRequest().
EDIT: Another possibility is that the call fails because the headers do not seem to be in canonical format: according to the HTTP 1.1 spec, they ought to be in "name: value" format, and each header should be separated from the next one by CRLF.