CreateFile() Failed With GetLastError() = 5 - c++

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?

Related

Windows 8: CreateFile() returns INVALID_HANDLE_VALUE, immediate GetLastError shows 0

I am opening a file with CreateFile on Windows 8 from within a printer filter environment. The code is effectively straight C, even though the filter is built in C++. CreateFile returns INVALID_HANDLE_VALUE but an immediate call to GetLastError returns 0. I have seen this before, back in the old NT4 days (and through to Windows 7) if a directory of the same name as the file existed, a file open attempt would fail with error 0; but I have checked and the file name is different from any subdirectories in the destination directory.
Code:
io_buf[fh].fh = CreateFile(name, GENERIC_READ|GENERIC_WRITE, 0, p_sa,
CREATE_ALWAYS, 0, (HANDLE)0);
io_buf[fh].read_mode = FALSE;
io_buf[fh].file_start = 0L;
io_buf[fh].folder = 0;
if (io_buf[fh].fh == INVALID_HANDLE_VALUE)
{
LogMsg("BufCreate: CreateFile failed (%ld); retrying with SharedWrite\r\n", GetLastError());
io_buf[fh].fh = CreateFile(name, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, p_sa,
CREATE_ALWAYS, 0, (HANDLE) 0);
}
if (io_buf[fh].fh == INVALID_HANDLE_VALUE)
{
LogMsg("BufCreate: CreateFile failed (%ld)\r\n", GetLastError());
return (Vers_FAILURE);
}
LogMsg output:
Render 15:41:46.715: BufCreate: CreateFile failed (0); retrying with SharedWrite
Render 15:41:46.715: BufCreate: CreateFile failed (0)
Because this occurs relatively randomly, sending it to MS would not work; they'd fire it back to me with a "no rep" and I'd get dinged for the SRX. Has anyone got any clue on how I would proceed?
This is vexing. Turns out that I was not writing the file where I thought I was, and that's why it failed. But it should have returned error 5 (Access denied), and I was led up a stump because of this bedamned 0 in GetLastError.
For what it's worth: I had created a path to a temp directory. Because my security context at the time was LocalSystem (I'm in the PrinterPipeline service), that file was in c:\Windows\System32\Services\LocalService\AppData\Local\Temp. No ordinary user can reach that space, and the attempt will quite possibly leave your OS hooped. I had changed to user security context to write to C:\Temp, and was getting a failure because I had forgotten to change my filename to C:\Temp. The error 0 made it look like possibly I was faced with file system redirection mapping c:\temp into LocalService space.
Correcting that so that I was actually writing where I thought I was got rid of the failure... but I still don't understand why Windows was handing me back an error 0.

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.

INVALID_HANDLE_VALUE when calling CreateFileA several times

I'm using CreateFileA and the first time I call it, it works as expected. But when i call it the second time, it returns handle INVALID_HANDLE_VALUE. What could be the problem? Just for information, I'm calling it every time I need to check if my USB device is connected..
int port = 500;
char port_name [MAX_CAR] = {0};
sprintf_s (port_name, MAX_CAR, "\\\\.\\COM%d", port);
com->id = CreateFileA (port_name,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL);
EDIT: I did try to use CloseHandle like CloseHandle(com->id); but it doesn't help.
From the documentation:
When an application is finished using the object handle returned by
CreateFile, use the CloseHandle function to close the handle. This not
only frees up system resources, but can have wider influence on things
like sharing the file or device and committing data to disk. Specifics
are noted within this topic as appropriate.
Use GetLastError to get the error code, and use the FormatMessage to get a human readable error description, or just simply Google the error code.
There are many reasons can cause the same error (CreateFile returns INVALID_HANDLE_VALUE), without the GetLastError, you will very hard to find out what is the real reason.

DeleteFile fails on recently closed file

I have a single threaded program (C++, Win32, NTFS) which first creates a quite long temporary file, closes it, opens for read, reads, closes again and tries to delete using DeleteFile().
Usually it goes smoothly, but sometimes DeleteFile() fails, and GetLastError() returns ERROR_ACCESS_DENIED. File is not read-only for sure. It happens on files on any size, but the probability grows with the file size.
Any ideas what may be locking the file? I tried WinInternals tools to check and found nothing suspicious.
Windows is notorious for this issue. SQLite handles the problem by retrying the delete operation every 100 milliseconds up to a maximum number.
I believe if you are sure that you have no open handles, doing this in your implementation will save you some headaches when things like antivirus software open the file.
For reference, the comment from SQLite source:
/*
** Delete the named file.
**
** Note that windows does not allow a file to be deleted if some other
** process has it open. Sometimes a virus scanner or indexing program
** will open a journal file shortly after it is created in order to do
** whatever it does. While this other process is holding the
** file open, we will be unable to delete it. To work around this
** problem, we delay 100 milliseconds and try to delete again. Up
** to MX_DELETION_ATTEMPTs deletion attempts are run before giving
** up and returning an error.
*/
Just a wild guess - do you have any anti-virus software installed? Have you tried disabling any real-time protection features in it, if you do?
I believe this is covered in Windows Internals. The short story is that even though you've called CloseHandle on the file handle, the kernel may still have outstanding references that take a few milliseconds to close.
A more reliable way to delete the file when you're done is to use the FILE_FLAG_DELETE_ON_CLOSE flag when opening the last handle. This works even better if you can avoid closing the file between reads/writes.
#include <windows.h>
#include <stdio.h>
int wmain(int argc, wchar_t** argv)
{
LPCWSTR fileName = L"c:\\temp\\test1234.bin";
HANDLE h1 = CreateFileW(
fileName,
GENERIC_WRITE,
// make sure the next call to CreateFile can succeed if this handle hasn't been closed yet
FILE_SHARE_READ | FILE_SHARE_DELETE,
NULL,
CREATE_ALWAYS,
FILE_FLAG_SEQUENTIAL_SCAN | FILE_ATTRIBUTE_TEMPORARY,
NULL);
if (h1 == INVALID_HANDLE_VALUE)
{
fprintf(stderr, "h1 failed: 0x%x\n", GetLastError());
return GetLastError();
}
HANDLE h2 = CreateFileW(
fileName,
GENERIC_READ,
// FILE_SHARE_WRITE is required in case h1 with GENERIC_WRITE access is still open
FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE,
NULL,
OPEN_EXISTING,
// tell the OS to delete the file as soon as it is closed, no DeleteFile call needed
FILE_FLAG_DELETE_ON_CLOSE | FILE_FLAG_SEQUENTIAL_SCAN | FILE_ATTRIBUTE_TEMPORARY,
NULL);
if (h2 == INVALID_HANDLE_VALUE)
{
fprintf(stderr, "h2 failed: 0x%x\n", GetLastError());
return GetLastError();
}
return 0;
}
Add a MessageBox() call before you invoke DeleteFile(), When it shows up, run the sysinternals tool Process Explorer.
Search for an open handle to the file. In all probability you have not closed all handles to the file...
Maybe the changes are still cached and haven't been saved yet?
You can check this by adding a WaitForSingleObject on the file handle to be sure.
You may have a race condition.
1. Operating system is requested to write data.
2. Operating system is requested to close file. This prompts final buffer flushing. The file will not be closed until the buffer flushing is done. Meanwhile The OS will return control to the program while working on buffer flushing.
3. Operating system is requested to delete the file. If the flushing is not done yet then the file will still be open and the request rejected.
#include <iostream>
#include <windows.h>
int main(int argc, const char * argv[])
{
// Get a pointer to the file name/path
const char * pFileToDelete = "h:\\myfile.txt";
bool RemoveDirectory("h:\\myfile.txt");
// try deleting it using DeleteFile
if(DeleteFile(pFileToDelete ))
{
// succeeded
std::cout << "Deleted file" << std::endl;
}
else
{
// failed
std::cout << "Failed to delete the file" << std::endl;
}
std::cin.get();
return 0;
}

CreateFile Win32 API Call with OPEN_ALWAYS failed in an Odd Way

We had a line of code
if( !CreateFile( m_hFile, szFile, GENERIC_READ|GENERIC_WRITE, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL ) )
{
DWORD dwErr = GetLastError();
CString czInfo;
czInfo.Format ("CMemoryMapFile::OpenAppend SetFilePointer call failed - GetLastError returned %d", dwErr);
LOG(czInfo);
return false;
}
This code worked great for many years. A few weeks ago, we had a customer with a problem. Turns out, the problem could be traced to this line of code, where the function would return a INVALID_HANDLE_VALUE handle and GetLastError() returned ERROR_FILE_NOT_FOUND(2).
Now, this is very confusing to us. OPEN_ALWAYS should direct the file to be created if it does not exist. So, why are we getting a ERROR_FILE_NOT_FOUND?
More confusion: For this customer, this only happened on one network share point (we were using a UNC path). Other UNC paths to other machines for this customer worked. Local paths worked. All our other customers (10000+ installs) have no problem at all.
The customer was using XP as the client OS, and the servers were running what appeared to be standard Windows Server 2003 (I think the Small Business Server version). We could not replicate their errors in our test lab using the same OS's. They could repeat the problem with several XP clients, but the problem was only on one server (other Server 2003 servers did not exhibit the problem).
We fixed the problem by nesting two CreateFile calls, the first with OPEN_EXISTING, and the second with CREATE_ALWAYS if OPEN_EXISTING failed. So, we have no immediate need for a fix.
My question: Does anyone have any idea why this API call would fail in this particular way? We are puzzled.
Addendum:
The CreateFile function above is a wrapper on the Windows API function. Here's the code:
bool CMemoryMapFile::CreateFile( HANDLE & hFile, LPCSTR szFile, DWORD dwDesiredAccess, DWORD dwShareMode, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes )
{
hFile = ::CreateFile (szFile, dwDesiredAccess, dwShareMode, NULL,
dwCreationDisposition, dwFlagsAndAttributes, NULL);
return (hFile != INVALID_HANDLE_VALUE)
}
First, you should always check for success of the CreateFile() API like this:
if (CreateFile(...) == INVALID_HANDLE_VALUE)
{
// handle the error
}
because CreateFile() doesn't return !=0 in case of success, but anything other than INVALID_HANDLE_VALUE (which is -1).
Then, the CreateFile() can fail in the situation you described if either the directory doesn't exist where you want to create/open the file in, or it can fail if the user has the rights to open and write files in that directory, but no rights to create new files.
Maybe the directory you wanted to create the file in did not exist?
Are you sure you fixed it by using 2 CreateFile calls? Or did you just not reproduce it?
We have also seen this problem when a file is accessed by a UNC share. None of the ideas and suggestions applied in our case - the directory always exists, the parameters to CreateFile are correct, we are checking the return correctly.
We believe this to be a shares issue. We solved the problem with a simple retry loop:
If a CreateFile with OPEN_ALWAYS fails with ERROR_FILE_NOT_FOUND, we simply sleep for a few ms and try again. It always works second time (if it failed first time).
If CreateFile fails, it will return INVALID_HANDLE_VALUE which is non-zero (I think it's negative 1). So CreateFile might be succeeding and returning zero as the handle.
It's only safe to check GetLastError() after a function fails but it looks like you might be checking the last error when CreateFile has succeeded (returned zero).
According to this article, some functions set the "last error" if they succeed:
My guesses would be something server related like the server not implementing support correctly for that filesystem operation. Maybe a linux server compared to a windows server?
Your arguments to create file are incorrect, so I assume that this is some sort of CreateFile helper function.
A call to CreateFile should look like:
m_hFile = CreateFile( szFile, GENERIC_READ|GENERIC_WRITE, 0, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0 );
if(m_hFile == INVALID_HANDLE_VALUE)