Using File Mapping to read data from file - c++

I want to read data from a file (.txt) and push into Edit box.
I'm writing C++ with pure API.
HANDLE hFile;
HANDLE hMapFile;
LPVOID pMemory;
and
case IDM_OPEN:
hFile = CreateFile((LPCWSTR)szFileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, NULL);
hMapFile = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
pMemory = MapViewOfFile(hMapFile, FILE_MAP_READ | FILE_MAP_WRITE, 0,0,0);
FileSize = GetFileSize(hFile, NULL);
SendMessage(hWndEdit, WM_SETTEXT, 0, (LPARAM)(LPCWSTR)pMemory);
MessageBox(hWnd, (LPCWSTR)pMemory, L"Caption", MB_OK);
UnmapViewOfFile(pMemory);
CloseHandle(hMapFile);
CloseHandle(hFile);
break;
Result: Blank, nothing in Edit box
I search some page but not solved.
When I try debug by set breakpoint like this image:
http://i8.upanh.com/2013/1103/02//57993893.untitled.png
(Sorry I can't post image)
hFile is 0xffffffff, so I think error is CreateFile, but I don't understand !!
Please help me solve this. Thanks !!!

hFile = CreateFile((LPCWSTR)szFileName,....
Why the cast to LPCWSTR? If you need that cast you are doing something wrong. Investigate each step with a debugger to learn more about what is wrong.

Related

How to read something to the RAW disk and then write it some further in C++?

I'd like to first write something to a disk device, then read the same data and write it some further. My code looks like this:
std::string devicePath = "\\\\.\\PhysicalDrive0"; //'0' is only example here
HANDLE source = CreateFile(disk.c_str(), GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, NULL, NULL);
BOOST_TEST_REQUIRE(source, "Failed to create file handle.");
std::unique_ptr<CHAR[]> primaryBuffer(new CHAR[DEFAULT_FILESIZE]);
std::unique_ptr<CHAR[]> checkBuffer(new CHAR[DEFAULT_FILESIZE]);
for (auto i = 0; i < DEFAULT_FILESIZE; ++i) {
primaryBuffer[i] = 'x';
checkBuffer[i] = ' ';
}
WriteFile(source, primaryBuffer.get(), DEFAULT_FILESIZE, NULL, NULL);
//Here I move the pointer to write data in new place.
DWORD destination = SetFilePointer(source, DEFAULT_FILESIZE, NULL, FILE_BEGIN);
WriteFile(&destination, source, DEFAULT_FILESIZE, NULL, NULL);
ReadFile(source, primaryBuffer.get(), DEFAULT_FILESIZE, NULL, NULL);
ReadFile(&destination, checkBuffer.get(), DEFAULT_FILESIZE, NULL, NULL);
BOOST_TEST_MESSAGE(checkBuffer.get());
BOOST_TEST_MESSAGE(primaryBuffer.get());
Unfortunately, both buffers are different and I've tried almost everything to check what's wrong. Maybe somebody has any idea what I'm doing wrong?

When error 1224: ERROR_USER_MAPPED_FILE occurs?

I want to really understand when the ERROR_USER_MAPPED_FILE occurs. So I wrote some snippets. To reproduce the error. But it did not work. Please help me fix my code
Process 1:
HANDLE hFile = CreateFile("C:\\test\\full.exe", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
return GetLastError();
HANDLE hMapFile = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 0, NULL);
if (hMapFile == INVALID_HANDLE_VALUE)
return GetLastError();
mapHandles.push_back(hMapFile);
viewHandles.push_back(MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, 0));
I am Halting the process and I have not closed any view of the map and file handles yet in this process so that when the other process tries to open the file. I thought error 1224 will be thrown.
Process 2:
HANDLE hFile = CreateFile("C:\\test\\full.exe", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
cout << "Error Code : " << GetLastError() << endl;
char buffer[1025];
DWORD bytesRead;
if (!ReadFile(hFile, buffer, 1024, &bytesRead, 0))
cout << "Error Code : " << GetLastError() << endl;
The CreateFile and ReadFile succeeds in the process 2.
Actually I am trying to handle this error 1224 separately. Which means when the file fails with error 32 I want to do something. and if the file fails with error 1224 I want to do something.
Now I must test those cases. In order to test those scenarios I should reproduce the error 1224.
I want to really understand when the ERROR_USER_MAPPED_FILE occurs
if really understand let some extra info.
at first this error returned from kernel. so it was initially NTSTATUS error code, which than translated to win32 error by RtlNtStatusToDosError. api for reverse translation not exist - because it not uniquely, but possible yourself write code, which create reverse translation map. two NTSTATUS codes is translated to ERROR_USER_MAPPED_FILE : STATUS_USER_MAPPED_FILE and STATUS_PURGE_FAILED:
if (
RtlNtStatusToDosError(STATUS_USER_MAPPED_FILE) != ERROR_USER_MAPPED_FILE
||
RtlNtStatusToDosError(STATUS_PURGE_FAILED) != ERROR_USER_MAPPED_FILE
)
{
__debugbreak();
}
for completely understand when this codes returned need look File System source code. we have fastfat example. if search for STATUS_USER_MAPPED_FILE - we can found that this code returned from 4 place:
FatSupersedeOrOverwriteFile - when we try call
ZwCreateFile with FILE_OVERWRITE_IF or FILE_SUPERSEDE
CreateOption or when we call CreateFile with CREATE_ALWAYS
FatSetEndOfFileInfo - when we call ZwSetInformationFile
with FileEndOfFileInformation or SetEndOfFile function
FatSetValidDataLengthInfo- when we call
ZwSetInformationFile with
FileValidDataLengthInformation or SetFileValidData
function (we need have SE_MANAGE_VOLUME_PRIVILEGE for this)
FatSetAllocationInfo - when we use ZwSetInformationFile
with FileAllocationInformation (no win32 api shell)
and you can note common pattern here:
if (!MmCanFileBeTruncated()) return STATUS_USER_MAPPED_FILE;
about demo code for reproduce this error - for what you need two processes ?!? single routine in single process - more than enough.
void test()
{
// for simplicity, i have access to this location as admin
STATIC_OBJECT_ATTRIBUTES(oa, "\\systemroot\\temp\\.tmp");
HANDLE hFile, hSection, hFile2;
IO_STATUS_BLOCK iosb;
LARGE_INTEGER AllocationSize = { PAGE_SIZE };
NTSTATUS status;
if (0 <= NtCreateFile(&hFile, FILE_GENERIC_WRITE|FILE_GENERIC_READ, &oa, &iosb, &AllocationSize, 0,
FILE_SHARE_VALID_FLAGS, FILE_OPEN_IF, FILE_SYNCHRONOUS_IO_NONALERT, 0, 0))
{
status = NtCreateSection(&hSection, SECTION_MAP_READ|SECTION_MAP_WRITE, 0, &AllocationSize, PAGE_READWRITE, SEC_COMMIT, hFile);
if (0 <= status)
{
PVOID BaseAddress = 0;
SIZE_T ViewSize = 0;
status = ZwMapViewOfSection(hSection, NtCurrentProcess(), &BaseAddress, 0, 0, 0, &ViewSize, ViewUnmap, 0, PAGE_READONLY);
NtClose(hSection);
if (0 <= status)
{
LARGE_INTEGER Eof = {};
// SetEndOfFile win32 api
status = ZwSetInformationFile(hFile, &iosb, &Eof, sizeof(Eof), FileEndOfFileInformation);
if (status != STATUS_USER_MAPPED_FILE) __debugbreak();
// no win32 api
status = ZwSetInformationFile(hFile, &iosb, &Eof, sizeof(Eof), FileAllocationInformation);
if (status != STATUS_USER_MAPPED_FILE) __debugbreak();
// SetFileValidData win32 api
// we need have SE_MANAGE_VOLUME_NAME privilege, otherwise STATUS_PRIVILEGE_NOT_HELD
status = ZwSetInformationFile(hFile, &iosb, &Eof, sizeof(Eof), FileValidDataLengthInformation);
switch (status)
{
case STATUS_USER_MAPPED_FILE:
case STATUS_PRIVILEGE_NOT_HELD:
break;
default: __debugbreak();
}
//CreateFileW(L"\\\\?\\c:\\windows\\temp\\.tmp", FILE_GENERIC_READ|FILE_GENERIC_WRITE, FILE_SHARE_VALID_FLAGS, 0, CREATE_ALWAYS, 0, 0);
status = NtCreateFile(&hFile2, FILE_GENERIC_WRITE|FILE_GENERIC_READ, &oa, &iosb, 0, 0,
FILE_SHARE_VALID_FLAGS, FILE_OVERWRITE_IF, FILE_SYNCHRONOUS_IO_NONALERT, 0, 0);
if (status != STATUS_USER_MAPPED_FILE) __debugbreak();
status = NtCreateFile(&hFile2, FILE_GENERIC_WRITE|FILE_GENERIC_READ, &oa, &iosb, 0, 0,
FILE_SHARE_VALID_FLAGS, FILE_SUPERSEDE, FILE_SYNCHRONOUS_IO_NONALERT, 0, 0);
if (status != STATUS_USER_MAPPED_FILE) __debugbreak();
ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress);
}
}
NtClose(hFile);
}
}
about STATUS_PURGE_FAILED - look like in can be returned when we call WriteFile - look here - but i can not reproduce it in test. however very rarely this error can occur - "STATUS_PURGE_FAILED" error when you perform VM replications by using SCVMM in Windows Server 2012 R2
ERROR_USER_MAPPED_FILE or error 1224 occurs when you try to delete or overwrite a file which has been mapped by other process.
Process #1
HANDLE hFile = CreateFile("C:\\test\\full.exe", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
return GetLastError();
HANDLE hMapFile = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 0, NULL);
if (hMapFile == INVALID_HANDLE_VALUE)
return GetLastError();
mapHandles.push_back(hMapFile);
viewHandles.push_back(MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, 0));
Process #2
HANDLE hFile = CreateFile("C:\\test\\full.exe", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
if(GetLastError() == 1224)
// File has been mapped by other process
else
// some other issue
}
In Process #2, CREATE_ALWAYS tries to overwrite a file which has been mapped. So it ends up throwing error 1224.

C++ CreateFile cant read file ERROR_ACCESS_DENIED [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I'm trying to read file content, but despite it's able to write to same file. I can't read from it! The program is running as Adminstator.
I have Tried to give " FILE_SHARE_WRITE | FILE_SHARE_READ " rights, but still not work.
DWORD dwBytesWritten = 0;
unsigned long BytesRead = 0;
HANDLE hFile = INVALID_HANDLE_VALUE;
wchar_t text_file[MAX_PATH] = { 0 };
TCHAR *save_text(void) {
OPENFILENAME ofn = { 0 };
TCHAR filename[512] = _T("C://Windows/EXAMPLE.txt");
ofn.lStructSize = sizeof(ofn);
ofn.lpstrFilter = L"Txt files (*.txt)\0*.txt\0All Files\0*.*\0";
ofn.lpstrFile = filename;
ofn.nMaxFile = sizeof(filename);
ofn.Flags = OFN_NONETWORKBUTTON | OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST | OFN_LONGNAMES | OFN_EXPLORER | OFN_HIDEREADONLY;
ofn.nFilterIndex = 1;
return(filename);
}
void WriteToFile(TCHAR *wText)
{
wchar_t loginchar[1000];
hFile = CreateFile(text_file, FILE_APPEND_DATA, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_HIDDEN, NULL);
WriteFile(hFile, wText, wcslen(wText) * sizeof(wchar_t), &dwBytesWritten, NULL); // its writing without problem
ReadFile(hFile, loginchar, wcslen(loginchar) * sizeof(wchar_t), &BytesRead, NULL); // accses denied
ResultInFile(GetLastError()); // ResultInFile funcitons writes paramater to the file
//ResultInFile(BytesRead); // to see how many bytes read, but of course doesnt work..
CloseHandle(hFile);
}
// this is the how file created at main function :
hFile = CreateFile(txt_file, FILE_APPEND_DATA, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_HIDDEN, NULL);
try:
hFile = CreateFile(text_file, FILE_APPEND_DATA | FILE_READ_DATA, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_HIDDEN, NULL);
instead of:
hFile = CreateFile(text_file, FILE_APPEND_DATA, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_HIDDEN, NULL);
Note that FILE_SHARE_READ allows other calls of CreateFile ask for read permissions, it does not affect the read permissions of your file handle.

UnmapViewOfFile does not release file. Unable to access File after function is executed.

I am trying to upload a file to a cloud service using winhttp, however after running the below code, i am unable to access the same file anymore. It seems like the program is not closing its file handle properly:
HANDLE hFile = CreateFileW(MultiByteToWideChar(filePath), GENERIC_READ, FILE_SHARE_READ+FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
DWORD dwFileSize = GetFileSize(hFile, NULL);
HANDLE hFileMappingObject = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, dwFileSize, NULL);
HANDLE file = MapViewOfFile(hFileMappingObject, FILE_MAP_READ, 0, 0, 0);
bool result = WinHttpSendRequest( hRequest,
WINHTTP_NO_ADDITIONAL_HEADERS,
0, WINHTTP_NO_REQUEST_DATA, 0,
dwFileSize, 0);
result = WinHttpWriteData( hRequest, file, dwFileSize, &dwBytesWritten);
FlushViewOfFile(file, dwFileSize);
FlushFileBuffers(hFile);
UnmapViewOfFile(file);
CloseHandle(hFileMappingObject);
CloseHandle(hFile);

Can't get ReadFile to read from the file i just wrote to

Im writing to a file using WriteFile. That works fine. Its just a simple string:
"Test string, testing windows functions".
Im trying to read from the file now and compare with the string i write just to ensure its working properly. I have:
DWORD dwBytesRead;
char buff[128];
ReadFile(hFile, buff, 128, &dwBytesRead, NULL)
But its returning false for me. hFile is the handle I use when writing to the file. Can have any ideas about what might be going on?
EDIT (updated from comment):
I'm getting E_ACCESSDENIED from GetLastError(). Here is how i got hFile:
hFile = CreateFile (TEXT(movedFileName.c_str()),
GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
hFile has been opened for GENERIC_WRITE only. It needs to be opened with GENERIC_READ if you want to read from it as well as write to it:
hFile = CreateFile (TEXT(movedFileName.c_str()),
GENERIC_WRITE | GENERIC_READ,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);