ReadFile fails with ERROR_INVALID_FUNCTION when trying to read volume
-
Wednesday, December 21, 2011 8:47 PM
Hi,
I am writing a application which copies the one volume to another (Volume Copy). When we try to read from volume using ReadFile API we get a error code ERROR_INVALID_FUNCTION. What are the reasons ans solution to this problem?
I am using W2k3 system
I am having Admin access(I can open the volume. CreateFile returns success)
Memory allocated using VirtualAlloc which is aligned
// VolumeRead.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <windows.h> #include <conio.h> #include <iostream> #include <string> using namespace std; HANDLE gvolumehandle; int gbuffsize = 1024*1024*10;// 10 MB data read for test // This function enables backup and restore priviliges for this process. If // the priviliges are not granted that is silently ignored. BOOL EnableBackupPrivileges() { HANDLE hToken; BYTE buf[sizeof(TOKEN_PRIVILEGES) * 3]; TOKEN_PRIVILEGES *tkp = (TOKEN_PRIVILEGES *) buf; if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) return FALSE; if (!LookupPrivilegeValue(NULL, SE_BACKUP_NAME, &tkp->Privileges[0].Luid)) return FALSE; if (!LookupPrivilegeValue(NULL, SE_RESTORE_NAME, &tkp->Privileges[1].Luid)) return FALSE; if (!LookupPrivilegeValue(NULL, SE_SECURITY_NAME, &tkp->Privileges[2].Luid)) return FALSE; tkp->PrivilegeCount = 3; tkp->Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; tkp->Privileges[1].Attributes = SE_PRIVILEGE_ENABLED; tkp->Privileges[2].Attributes = SE_PRIVILEGE_ENABLED; return AdjustTokenPrivileges(hToken, FALSE, tkp, sizeof buf, NULL, NULL); } int OpenVolume(wstring volumename) { DWORD accessflags = GENERIC_READ|FILE_GENERIC_READ; DWORD sharemode = FILE_SHARE_READ|FILE_SHARE_WRITE; DWORD creationflags = OPEN_EXISTING; DWORD attributes = FILE_FLAG_BACKUP_SEMANTICS |FILE_FLAG_SEQUENTIAL_SCAN; wstring volname = volumename; volname += L":"; volname += L"\\"; WCHAR volumenamebuffer[1024] = {0}; int volumenamebufferlength = 1024; wcout << L"Getting volume name for volume " << volumename << L"\n"; if( 0 == GetVolumeNameForVolumeMountPoint(volname.c_str(),volumenamebuffer,volumenamebufferlength)) { DWORD status = ::GetLastError(); cout << "Getting volume name for volume " << volumename.c_str() << " failed. Error code = " <<status << "\n"; return FALSE; } volname = volumenamebuffer; wcout << L"Opening volume " << volname << L"\n"; HANDLE temphandle = INVALID_HANDLE_VALUE; gvolumehandle = CreateFile(volname.c_str(),accessflags,sharemode,NULL,creationflags,attributes,temphandle); if(INVALID_HANDLE_VALUE == gvolumehandle) { DWORD status = ::GetLastError(); wcout << L"Opening volume " << volname<< L" failed. Error code = " <<status<< L"\n"; return FALSE; } wcout << L"Opening volume " << volname << L" completed." << L"\n"; return TRUE; } int ReadVolume(BYTE* buffstart, int buffsize) { DWORD bytestoread = buffsize; DWORD actualbytesread = 0; DWORD totalbytesread = 0; while(1) { int status = ReadFile(gvolumehandle, buffstart+totalbytesread, bytestoread, &actualbytesread, NULL); // update remaining bytes bytestoread -= actualbytesread; // update total bytes totalbytesread += actualbytesread; // check for read complete if(status != 0) { //read successfull if(totalbytesread == buffsize) { //successfully read all bytes return true; } else { // we read some bytes only so continue reading continue; } } else { // read failed DWORD errorcode = ::GetLastError(); if(errorcode == ERROR_HANDLE_EOF) { cout << "ReadFile failed. no more data to read. Error code = " << errorcode << "\n"; return true; } return false; } } return false; } int ReadVolume(wstring sourcevolume) { cout << "Opening volume.\n"; if(TRUE != OpenVolume(sourcevolume)) { cout << "Opening volume failed.\n"; return false; } cout << "Opening volume completed.\n"; BYTE* buff = (BYTE*)VirtualAlloc(NULL,gbuffsize,MEM_COMMIT | MEM_RESERVE,PAGE_EXECUTE_READWRITE); cout << "Reading volume .\n"; ReadVolume(buff,gbuffsize); cout << "Reading volume completed.\n"; return 0; } int _tmain(int argc, _TCHAR* argv[]) { gvolumehandle = INVALID_HANDLE_VALUE; wstring sourcevolume; cout << "Please enter source volume. (only name of volume single char) "; wcin >> sourcevolume; BOOL prv = EnableBackupPrivileges(); ReadVolume(sourcevolume); return 0; }
All Replies
-
Monday, April 02, 2012 8:51 PM
I fixed the error.
The main reason to get this error was invalid path. I was opening the volume where volume name was ended with \e.g c:\.
This opens file system on volume not volume itself(create file does not return error if u end volume name with \). Changing volume name fixed the problem
- Marked As Answer by HemantKulkarni Monday, April 02, 2012 8:51 PM


