Opening a network file using CreateFile fails with FILE_NOT_FOUND - c++

So I'm trying to simulate a distant file opening, which is pointing back to my computer, however i keep failing with error 3 (FILE_NOT_FOUND). I went through the following documentation regarding network usage, but it didn't work either.
hFile1 = ::CreateFile(LR"(\\172.17.12.172\C$\Develop\Code\File.txt)", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
if (INVALID_HANDLE_VALUE == hFile1)
{
LOG_ERROR(L"Failed opening file with: " << GetLastError());
break;
}
The FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE flags are for the GetFileInformationByHandle which is used later on, i compare file paths.
I tried opening \\172.17.12.172\C$\Develop\Code\File.txt using notepad, it worked.
172.17.12.172 is my local ip address.

The syntax of your file name is fine. That the error code is FILE_NOT_FOUND rather than some other error means that the directory is found, but no file within that directory can be located.
You should be able to open a file with a path of that form using CreateFile. If you really can open the file with that path using Notepad, then you will be able to do the same using CreateFile, so long as you pass the same file name.
So the most plausible explanation is that you simply made a typographical error. I see no reason to look beyond the obvious conclusion suggested by FILE_NOT_FOUND. There is no file of that name.

Related

OpenFileById fails with ERROR_ACCESS_DENIED

I'm working on a product where OpenFileById() fails with ERROR_ACCESS_DENIED on files and folders that are otherwise accessible (meaning a CreateFile() on the same file or folder specified by path with the same access level / share mode, etc. succeeds).
I'm using backup semantics so I could also get a handle to folders; SE_BACKUP_NAME and SE_RESTORE_NAME privileges are enabled. This code works everywhere else other than this one machine (Windows 8.1).
The process is running as a service under local system, I tried having them change that to a different account with admin privileges and that didn't work either. Files / folders in question haven't been open for deletion (which is one case when this function will fail with ERROR_ACCESS_DENIED as per documentation).
I don't have physical access to this machine so can't kernel debug or anything like that. Has anyone run into this before?
Here's what I'm trying to do in a nutshell:
hRoot = ::CreateFileA(szRootPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
if (hRoot != INVALID_HANDLE_VALUE)
{
FILE_ID_DESCRIPTOR fileId;
fileId.dwSize = sizeof(fileId);
fileId.Type = FileIdType;
fileId.FileId.QuadPart = nId;
hFile = ::OpenFileById(hRoot, &fileId, SYNCHRONIZE | FILE_READ_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, FILE_FLAG_BACKUP_SEMANTICS);
if (hFile != INVALID_HANDLE_VALUE)
{
...
::CloseHandle(hFile);
}
::CloseHandle(hRoot);
}
Apparently this is caused by a third party software product's kernel components (can't really go into specifics)

CreateFileA returns error 20, "The system cannot find the device specified" intermittently

I am debugging a custom exe during the compiling of my code using the msbuild exec task.
It runs the following code:
HANDLE hFile = CreateFileA(szFile, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE)
Fatal(szFile, 1, "unable to open file (%x)", GetLastError());
szFile is the dll/exe that was compiled by msbuild, which is passed to program as an argument.
I am seeing the following error sometimes:
unable to open file (20)
After rebuilding the error doesn't happen again. According the the windows codes, error code 20 is:
ERROR_BAD_UNIT20 (0x14)
The system cannot find the device specified.
I'm not sure what this mean though. It doesn't seem to be that the file in question doesn't exist, because it does. If it didn't the error code would be "2", I've tried. Do you know what can cause this error? Thanks.
Couple of things:
const char *szFile = nullptr;
...
szFile = argv[i]; // it loops over the arguments, parses them and finds the right argment for the file.
....
SetFileAttributes(szFile, FILE_ATTRIBUTE_NORMAL);
HANDLE hFile = CreateFileA(szFile, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE)
Fatal(szFile, 1, "unable to open file (%x)", GetLastError());
Fatal() just does a printf of the file name and message.
You're printing the error code in hexadecimal (%x) rather than in decimal.
Error code 0x20 (32 decimal) is ERROR_SHARING_VIOLATION ("The process cannot access the file because it is being used by another process.") So, yes, your guess about another process having the file open was correct.
In these circumstances, I suspect a race condition, possibly affected by virus scanning. Consider having your code detect this particular error and retry after a short wait.

Get modification time of locked folder with boost::filesystem::last_write_time

When I'm using
time_t t = last_write_time("C:\\System Volume Information");
I get the following exception:
boost::filesystem::last_write_time: Access denied: "C:\System Volume Information"
Nevertheless, Windows Explorer is able to get access to that information. It looks like Boost requires extra access to the folder, and that's the reason the code doesn't work.
Is it possible to make a workaround somehow?
Edit. Here's a citation from libs\filesystem\src\operations.cpp:1312:
handle_wrapper hw(
create_file_handle(p.c_str(), 0,
FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, 0,
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0));
I don't see what's wrong with it yet.
That folder is off limits even to users with an Admin account, it contains restore points. Not that you couldn't change the ACL with such an account but that is of course not the correct solution. Trying to open a handle on the directory is too heavy-handed, use FindFirstFile() instead. Like this:
WIN32_FIND_DATA info;
auto hdl = FindFirstFile(L"C:\\System Volume Information", &info);
if (hdl == INVALID_HANDLE_VALUE) throw win32_error(GetLastError());
SYSTEMTIME time;
FileTimeToSystemTime(&info.ftLastWriteTime, &time);
// etc..
//...
FindClose(hdl);

Using CreateFile To Access a Drive Partition

I have admin rights and have no problem getting a valid handle and ultimately reading an entire hard drive via:
IntPtr handle = CreateFile(#"\\.\PHYSICALDRIVE1", GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
I can also get a valid handle when I try to open a directory of that drive:
IntPtr handle = CreateFile(#"\\.\Z:\\", GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
But I cannot get a valid handle when I try to simply open a partition of that drive:
IntPtr handle = CreateFile(#"\\.\Z:", GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
GetLastWin32Error returns access denied (5).
Of course if I offline the drive, then I get "The system cannot find the file specified."
I've tried everything I could think of with different partitions, different options etc. to no available.
I found the answer myself. Let me correct myself in pointing out that CreateFile(#"\.\Z:" is opening a Volume, not necessarily a partition. However, I could not even open a volume.
Until I added FILE_SHARE_WRITE to the options as follows:
IntPtr handle = CreateFile(#"\.\Z:", GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
That was the key to getting a valid handle. This is certainly not intuitive!
Why this should be the case is only known by Microsoft I guess.
I would like to point out that the documentation of CreateFile says the following about FILE_SHARE_WRITE:
Enables subsequent open operations on a file or device to request write access.
Otherwise, other processes cannot open the file or device if they request write access.
If this flag is not specified, but the file or device has been opened for write access or has a file mapping with write access, the function fails.

CreateFile() Failed With GetLastError() = 5

I have written a sample application to read the file from the other file. When I run this application form virtual machine I am getting Access denied. Below is the code.
int _tmain(int argc, _TCHAR* argv[])
{
WCHAR *wcsPath = L"\\\\150.160.130.22\\share\\123.XML";
HANDLE hFile = CreateFileW(wcsPath,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
0,
0);
if (NULL == hFile)
{
printf("failed - %d", GetLastError());
}
return 0;
}
Please let me know any changes.
Error code 5 stands for "Access is Denied". You should check your user's access rights.
I believe the documentation for CreateFile holds the answer.
It may be that your dwShareMode is causing the problem. Using FILE_SHARE_READ there says, "allow other openers to open the file for READ access". If you do not specify FILE_SHARE_WRITE` , then other openers will not be able to open the file for writing - your call would prevent that.
But, CreateFile, I believe, also fails when the sharemode would be violated by prior openers. If this is true, then if another application already has the file open for write access, then your call to CreateFile will fail, if you specify dwShareMode = FILE_SHARE_READ. Do you see? You may need to specify FILE_SHARE_WRITE | FILE_SHARE_READ for that dwShareMode parameter.
Try it.
The error output of CreateFileW() is INVALID_HANDLE_VALUE, not NULL. Now, NULL definitely sounds like a wrong value for a file handle too, but still.
Is the pasted code snippet exactly the content of your program, or a retelling?
EDIT: I see there's a VM involved. Can you open the file in Notepad from the virtual machine where the program is running and erroring out?