I ran into an interesting problem. A searched many ways but I coundn't found any solution.
The problem is that I'm trying to open a shared printer in a domain with CreateFile function but it returns ERROR_FILE_NOT_FOUND errorcode.
If I use prompt and type
copy file.txt \\computer\printer
than it successfully completes the copy with result
1 file copied.
The CreateFile parameters is the following:
HANDLE file = CreateFile(printer, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (file == ERROR_INVALID_HANDLE)
{
char buffer[256];
sprintf_s(buffer, sizeof(buffer), "ErrorCode: %i", GetLastError());
MessageBox(NULL, buffer, "Error opening the file", MB_ICONERROR);
}
or
HANDLE file = CreateFile(printer, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (file == ERROR_INVALID_HANDLE)
{
char buffer[256];
sprintf_s(buffer, sizeof(buffer), "ErrorCode: %i", GetLastError());
MessageBox(NULL, buffer, "Error opening the file", MB_ICONERROR);
}
where printer containing the '\\host\printer' string according to the debugger.
I build it with Visual Studio 2005 SP1.
I tried to add the printer as Local priter as found on many places but it just resulted that the CreateFile just returned immediately.
Edit: On Windows XP it work perfectly. Windows 7 is the issue.
Edit2: The FOPEN function solves the problem so very likely the windows 7 implementation of function will be the issue.
Related
I am trying to read raw bytes from a pen drive 'E:', but it gives error code 32 when trying to open the drive using CreateFIle(). My code is as follows:
wchar_t wszDrive[7];
wszDrive[0] = '\\';
wszDrive[1] = '\\';
wszDrive[2] = '.';
wszDrive[3] = '\\';
wszDrive[4] = 'e';
wszDrive[5] = ':';
wszDrive[6] = '\0';
hDevice = CreateFile(wszDrive, //drive name to open
GENERIC_READ | GENERIC_WRITE, ////must be opened with exclusive access(No Sharing)
0, // no access to the drive
NULL, // default security attributes
OPEN_EXISTING, // disposition i.e. if file already exist
0, // file attributes
NULL); // do not copy file attributes
if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive
{
printf("CreateFile() failed! from read with error %d.\n", GetLastError());// Program prints this line. with error code 32.
return (FALSE);
}
else
cout << "\nCreateFile() successful! in read";
Edit:
The CreateFile() runs fine without errors if I use FILE_SHARE_READ | FILE_SHARE_WRITE:
hDevice = CreateFile(wszDrive,
GENERIC_READ |
GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL);
Why cannot I run with exclusive access?
Error 32 is ERROR_SHARING_VIOLATION.
The process cannot access the file because it is being used by another process.
It means there is already an open handle to the drive, and that handle is using access/sharing rights which are not compatible with the access/sharing rights you are requesting.
That is why you can't open the drive for exclusive access, but you can open it for read/write sharing - the drive is already open elsewhere for reading/writing.
If you want to know where exactly, you can use a tool like SysInternals Process Explorer to see which processes have open handles to which files/folders, devices, etc.
I am using the following code to memory-map a file for reading in windows (Windows 10):
HANDLE windowsFileHdl = CreateFileA(filePath, GENERIC_READ, FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if (windowsFileHdl == INVALID_HANDLE_VALUE)
{
return false;
}
HANDLE fileMappedHdl = CreateFileMappingA(windowsFileHdl, 0, PAGE_READONLY, 0, 0, nullptr);
char* baseFileData = (char*)MapViewOfFile(fileMapedHdl, FILE_MAP_READ, 0, 0, 0);
I would still like others to write to this file while I am reading it. Is this possible?
Currently, I get an error like this:
The process cannot access the file because it is being used by another process.
The above error was received by trying to open the file in a separate program (Notepad) while I had it memory mapped.
Is this a limitation with how the OS maps the file to memory or am I missing some flag?
EDIT:
#zett42 pointed out that I am missing FILE_SHARE_READ adding this makes the code:
HANDLE windowsFileHdl = CreateFileA(filePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if (windowsFileHdl == INVALID_HANDLE_VALUE)
{
return false;
}
HANDLE fileMappedHdl = CreateFileMappingA(windowsFileHdl, 0, PAGE_READONLY, 0, 0, nullptr);
char* baseFileData = (char*)MapViewOfFile(fileMapedHdl, FILE_MAP_READ, 0, 0, 0);
Now, notepad is able to open and write to the file!
However other programs like Visual Studio, Notepad++, or Emacs still have errors when writing to the file.
Visual Studio error:
The process cannot access the file because it is being used by another process.
Notepad++ error:
The file cannot be saved and it may be protected. Do you want to launch Notepad++ in Administrator mode?
My code opens a virtual NIC device using CreateFile. After that I am calling SetHandleInformation on the handle returned by CreateFile to avoid leaking the handle to child processes. The problem is, SetHandleInformation fails with error code 5 (ERROR_ACCESS_DENIED).
Following is the piece of code where I am opening the device and calling SetHandleInformation:
handle = CreateFile(dev_name, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED,NULL);
if (handle != INVALID_HANDLE_VALUE) {
if (!(SetHandleInformation(handle, HANDLE_FLAG_INHERIT, 0))) {
printf("SetHandleInformation error, code: %u\n", GetLastError());
}
}
I am observing this failure on Windows 10. My application is running with Administrator privileges. I am able to successfully use the handle for read and write even after this failure, which indicates that CreateFile is working fine.
What could be the possible reason of this failure? I could not find much information on SetHandleInformation failure with error code 5.
Im trying to map the file to the memory and use MapViewOfFile(), but it failes with error code 6. I tried just about anything, I also read about big files being the problem, but the problem happens also with a 1kb file.
my code:
HANDLE hFile = CreateFile(pFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
e = GetLastError();
printf("CreateFile Errorcode %d\n", GetLastError());
if (hFile == INVALID_HANDLE_VALUE)
{
printf("Error: could not create handle to file");
printf("CreateFileMapping error code: %d", e)
return 1;
}
printf("successfully created a Handle to try.txt");
HANDLE pMap = CreateFileMapping(hFile, NULL, PAGE_EXECUTE_READWRITE,0 ,0 ,NULL);
e = GetLastError();
if (pMap == INVALID_HANDLE_VALUE)
{
printf("Error: Unable to CreateFileMapping\n");
printf("CreateFileMapping error code: %d", e)
return 1;
}
printf("CreateFileMapping successfull.")
LPVOID lpBase MapViewOfFile(pMap, FILE_MAP_ACCESS| FILE_MAP_EXECUTE, 0, 0, 0);
e = GetLastError();
if (!lpBase)
{
printf("Error: could not map file to memory");
printf("MapViewOfFile Errorcode %d\n", GetLastError());
CloseHandle(hFile);
UnmapViewOfFile(lpBase);
printf("closed hFile handle and unmapped lpBase.")
return 1;
}
the output is the following:
> successfully created a Handle to try.txt
> createFileMapping successfull
> Error: unable to MapViewOfFile
> MapViewOfFile errorcode: 6
> closed hFile handle and unmapped lpBase.
Here:
HANDLE hFile = CreateFile(pFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
Replace GENERIC_READ with GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE
Also there is no FILE_MAP_ACCESS, but FILE_MAP_ALL_ACCESS.
I tried this code and it maps test file with success, not sure what you want to do with it further. Also for inspecting problems you can also use: Procmon.exe from sysinternals - it will report you what problems occured during file manipulations.
I would like to ask for help with WINAPI function CreateFileMapping (), which returns constantly NULL. After GetLastError() I get 5 - "ERROR_ACCESS_DENIED 5 (0x5) Access is denied". The file has been created after CreateFile with no problem, but following CreateFileMapping never has bee succesful.
int MapDestFile(LPCWSTR fPath)
{
hDestFile = CreateFile(
fPath,
GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hSourceFile == NULL)
{
printf("%d\n", GetLastError());
}
hDestMapFile = CreateFileMapping(
hDestFile,
NULL,
PAGE_READWRITE,
0,
10,
NULL
);
if (hDestMapFile == NULL)
{
// here always tell error number 5
printf("%d\n", GetLastError());
}
lpMapAddressDestFile = MapViewOfFile(
hDestMapFile,
FILE_MAP_WRITE,
0,
0,
0);
if (lpMapAddressDestFile == NULL)
{
printf("%d\n", GetLastError());
}
return 1;
}
I would appreciate any suggestions.
Thanks
You need to create the file with GENERIC_WRITE | GENERIC_READ to match PAGE_READWRITE.
That seems self-evident when you think about it. How can you have memory that you can read from backed by a file that you cannot read from? The documentation does call this out explicitly in any case:
PAGE_READWRITE
The file handle that the hFile parameter specifies must be created with the GENERIC_READ and GENERIC_WRITE access rights.
On top of that your error checking on the call to CreateFile is wrong. Take another look at the documentations. Error is indicated by a return value of INVALID_FILE_HANDLE.