CreateFile() failed with error code 32 while reading pendrive - windows

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.

Related

Can I memory map a file and still allow other processes to write to it?

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?

CreateFile fails to open domain printer (ERROR_FILE_NOT_FOUND)

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.

How Can I Get Exclusive Lock On Drive / Partition Win-Api 32?

How to lock lock on specific drive till i perform some operation(read/write) on that drive.
When i have captured lock on drive, no other process should able to write on that drive unitl I release lock on that drive, I have found one API i.e. DeviceIoControl(),
but I want access on drive for my process only, but the above API 'MAY' block access of all the processes. I'm not quite sure how lockfile() and lockfileex() works. Please help me find some way / API/ Logic to do this!
...
...
UPDATED :-
with referrance to your answer i have tried this :-->
HANDLE hdest,hf;
DWORD b,write;
hdest = CreateFile("\\\\?\\E:",
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
NULL,
NULL);
if (hdest == INVALID_HANDLE_VALUE)
{
MessageBox(NULL,TEXT("NOT OK"),TEXT("NOT OK"),0);
}
if (DeviceIoControl( hdest,FSCTL_LOCK_VOLUME,NULL,0,NULL,0,&b,NULL))
{
MessageBox(NULL,TEXT("OK"),TEXT("OK"),0);
hf = CreateFile(TEXT("E:\\M_lucky.txt"), GENERIC_WRITE, 0, NULL,CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if (hf == INVALID_HANDLE_VALUE)
{
MessageBox(NULL,TEXT("NOT OK AFTER LOCK I"),TEXT("NOT OK AFTRE LOCK"),0);
}
WriteFile(hf, TEXT("M very lucky"), 13, &write, NULL);
}
CloseHandle((HANDLE)hdest);
CloseHandle((HANDLE)hf);
DeviceIoControl( hdest,FSCTL_UNLOCK_VOLUME,NULL,0,NULL,0,&b,NULL);
hf = CreateFile(TEXT("E:\\MNOT_lucky.txt"), GENERIC_WRITE, 0, NULL,CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if (hf == INVALID_HANDLE_VALUE)
{
MessageBox(NULL,TEXT("NOT OK AFTER LOCK"),TEXT("NOT OK AFTRE LOCK"),0);
}
WriteFile(hf, TEXT("M lucky"), 8, &write, NULL);
CloseHandle((HANDLE)hf);
""but........""
after getting exclusive lock on E drive, i am unable to create file.
(i have read that : only hdest(HANDLE) gets exclusive lock on that drive. )
here..!!! i want to create M_LUCKY.txt file..!!
(I need EXLUSIVE access on drive with context to PROCESS)
plz help! thanks a lottt!!
is there any other method for doing this??
Use DeviceIoControl with FSCTL_LOCK_VOLUME control code.
http://msdn.microsoft.com/en-us/library/windows/desktop/aa364575(v=vs.85).aspx

Ways to synchronize write access to a file on a network share

I'm writing a program using C++ under Windows that needs to synchronize write access to a file via a local network. I was thinking to use the following approach:
//Create or open it using 0 for sharing mode
HANDLE hFile = CreateFile(L"\\\\server\\share\\path\\file", GENERIC_READ | GENERIC_WRITE, 0, , OPEN_ALWAYS, , ,);
if(hFile == INVALID_HANDLE_VALUE && ::GetLastError() == ERROR_SHARING_VIOLATION)
{
//Try again later
}
Can someone confirm that it's a workable solution?

How to detect if media is inserted into a removable drive/card reader

I have a card reader ( no memory stick is inserted ).
When i insert into my compter it shows an empty drive in My Computer...
Is it possible to know whether a drive is having a media ( sorry i am not sure how to call it ) or not...
I find the suggestion of MSalters to use IOCTL_STORAGE_CHECK_VERIFY very good. There are a small trick in the usage of IOCTL_STORAGE_CHECK_VERIFY. Before the usage of IOCTL code in the function DeviceIoControl one need to open the corresponding device with respect of CreateFile function:
HANDLE hDevice = CreateFile (szDeviceName, // like "\\.\E:"
0, // no access to the drive
FILE_SHARE_READ | FILE_SHARE_WRITE, // share mode
NULL, OPEN_EXISTING, 0, NULL);
For the usage of DeviceIoControl one can use 0 as a second parameter of CreateFile, because we will not use ReadFile, WriteFile etc functions to access the device. The implementation of IOCTL_STORAGE_CHECK_VERIFY do follow to some read of data requests. So to be able to use IOCTL_STORAGE_CHECK_VERIFY without having ERROR_ACCESS_DENIED (5) error we have to open the device as following
HANDLE hDevice = CreateFile (szDeviceName, // like "\\.\E:"
FILE_READ_DATA, // read access to the data
FILE_SHARE_READ | FILE_SHARE_WRITE, // share mode
NULL, OPEN_EXISTING, 0, NULL);
There exist another version of IOCTL_STORAGE_CHECK_VERIFY - IOCTL_STORAGE_CHECK_VERIFY2 which works absolutely the same as IOCTL_STORAGE_CHECK_VERIFY but much more quickly (see http://msdn.microsoft.com/en-us/library/ff560538.aspx). To use IOCTL_STORAGE_CHECK_VERIFY2 one can open device with only FILE_READ_ATTRIBUTES access:
HANDLE hDevice = CreateFile (szDeviceName, // like "\\.\E:"
FILE_READ_ATTRIBUTES, // read access to the attributes
FILE_SHARE_READ | FILE_SHARE_WRITE, // share mode
NULL, OPEN_EXISTING, 0, NULL);
The code which test the existence of the media in the drive can look like following
DWORD cbBytesReturned;
bSuccess = DeviceIoControl (hDevice, // device to be queried
IOCTL_STORAGE_CHECK_VERIFY2,
NULL, 0, // no input buffer
NULL, 0, // no output buffer
&cbBytesReturned, // # bytes returned
(LPOVERLAPPED) NULL); // synchronous I/O
if (bSuccess)
_tprintf (TEXT("the device media are accessible\n"));
else if (GetLastError() == ERROR_NOT_READY)
_tprintf (TEXT("the device media are not accessible\n"));
The reason for this behavior is historical, and dates back to floppy drives and MS-DOS. The A: drive would still be the A: drive even if there was no floppy in it.
It is sometimes possible to check whether a drive with removable media is empty. Card readers and CD drives usually support this, floppy drives don't. You would send the drive a IOCTL_STORAGE_CHECK_VERIFY .

Resources