Reading sectors
-
I have written a little piece of code to read few (first 512) bytes from USB drive. here is the code:
HANDLE hVolume = ::CreateFile(sVolume, GENERIC\_READ, FILE\_SHARE\_READ | FILE\_SHARE\_WRITE, NULL, OPEN\_EXISTING, FILE\_FLAG\_SEQUENTIAL\_SCAN, NULL); TRACE("Volume handle: %p\\n", hVolume); LONG lDistLow = 0; PLONG plDistHigh = 0; if (INVALID\_SET\_FILE\_POINTER == SetFilePointer(hVolume, lDistLow, plDistHigh, FILE\_BEGIN) && NO\_ERROR != GetLastError()) { TRACE("Error: %d\\n", GetLastError()); return FALSE; } else { TRACE("%d\\t%d\\n", lDistLow, plDistHigh); } DWORD dwLen = 512; DWORD dwNum = 0; void\* pBuffer = NULL; ReadFile(hVolume, pBuffer, dwLen, &dwNum, NULL); TRACE("%p\\t%d\\t%d\\n", pBuffer, dwLen, dwNum);
but the result is:
Volume handle: 00000438
0 0
00000000 512 0this pBuffer NULL tell me that I am not able to read that sectors ... why ? The program is running as admin and
sVolume
is feed by_T("\\\\.\\F:")
, firstTRACE
macro printed is a prove that is OK that part.SetFilePointer
is used to position the reading part, and I intend to setup offset to the beginning, right ? -
I have written a little piece of code to read few (first 512) bytes from USB drive. here is the code:
HANDLE hVolume = ::CreateFile(sVolume, GENERIC\_READ, FILE\_SHARE\_READ | FILE\_SHARE\_WRITE, NULL, OPEN\_EXISTING, FILE\_FLAG\_SEQUENTIAL\_SCAN, NULL); TRACE("Volume handle: %p\\n", hVolume); LONG lDistLow = 0; PLONG plDistHigh = 0; if (INVALID\_SET\_FILE\_POINTER == SetFilePointer(hVolume, lDistLow, plDistHigh, FILE\_BEGIN) && NO\_ERROR != GetLastError()) { TRACE("Error: %d\\n", GetLastError()); return FALSE; } else { TRACE("%d\\t%d\\n", lDistLow, plDistHigh); } DWORD dwLen = 512; DWORD dwNum = 0; void\* pBuffer = NULL; ReadFile(hVolume, pBuffer, dwLen, &dwNum, NULL); TRACE("%p\\t%d\\t%d\\n", pBuffer, dwLen, dwNum);
but the result is:
Volume handle: 00000438
0 0
00000000 512 0this pBuffer NULL tell me that I am not able to read that sectors ... why ? The program is running as admin and
sVolume
is feed by_T("\\\\.\\F:")
, firstTRACE
macro printed is a prove that is OK that part.SetFilePointer
is used to position the reading part, and I intend to setup offset to the beginning, right ?What does ReadFile return? TRUE or FALSE?
-
I have written a little piece of code to read few (first 512) bytes from USB drive. here is the code:
HANDLE hVolume = ::CreateFile(sVolume, GENERIC\_READ, FILE\_SHARE\_READ | FILE\_SHARE\_WRITE, NULL, OPEN\_EXISTING, FILE\_FLAG\_SEQUENTIAL\_SCAN, NULL); TRACE("Volume handle: %p\\n", hVolume); LONG lDistLow = 0; PLONG plDistHigh = 0; if (INVALID\_SET\_FILE\_POINTER == SetFilePointer(hVolume, lDistLow, plDistHigh, FILE\_BEGIN) && NO\_ERROR != GetLastError()) { TRACE("Error: %d\\n", GetLastError()); return FALSE; } else { TRACE("%d\\t%d\\n", lDistLow, plDistHigh); } DWORD dwLen = 512; DWORD dwNum = 0; void\* pBuffer = NULL; ReadFile(hVolume, pBuffer, dwLen, &dwNum, NULL); TRACE("%p\\t%d\\t%d\\n", pBuffer, dwLen, dwNum);
but the result is:
Volume handle: 00000438
0 0
00000000 512 0this pBuffer NULL tell me that I am not able to read that sectors ... why ? The program is running as admin and
sVolume
is feed by_T("\\\\.\\F:")
, firstTRACE
macro printed is a prove that is OK that part.SetFilePointer
is used to position the reading part, and I intend to setup offset to the beginning, right ?Your pBuffer value is NULL, so you are trying to read data into the memory address 0 - you have to allocate some space to read the data into and use that for your pBuffer value. For 512 bytes a stack-based array should do the trick.
-
I have written a little piece of code to read few (first 512) bytes from USB drive. here is the code:
HANDLE hVolume = ::CreateFile(sVolume, GENERIC\_READ, FILE\_SHARE\_READ | FILE\_SHARE\_WRITE, NULL, OPEN\_EXISTING, FILE\_FLAG\_SEQUENTIAL\_SCAN, NULL); TRACE("Volume handle: %p\\n", hVolume); LONG lDistLow = 0; PLONG plDistHigh = 0; if (INVALID\_SET\_FILE\_POINTER == SetFilePointer(hVolume, lDistLow, plDistHigh, FILE\_BEGIN) && NO\_ERROR != GetLastError()) { TRACE("Error: %d\\n", GetLastError()); return FALSE; } else { TRACE("%d\\t%d\\n", lDistLow, plDistHigh); } DWORD dwLen = 512; DWORD dwNum = 0; void\* pBuffer = NULL; ReadFile(hVolume, pBuffer, dwLen, &dwNum, NULL); TRACE("%p\\t%d\\t%d\\n", pBuffer, dwLen, dwNum);
but the result is:
Volume handle: 00000438
0 0
00000000 512 0this pBuffer NULL tell me that I am not able to read that sectors ... why ? The program is running as admin and
sVolume
is feed by_T("\\\\.\\F:")
, firstTRACE
macro printed is a prove that is OK that part.SetFilePointer
is used to position the reading part, and I intend to setup offset to the beginning, right ?_Flaviu wrote:
pBuffer NULL tell me that I am not able to read that sectors
No,
pBuffer = NULL;
tells you that you have not allocated any space to pBuffer. And don't usevoid*
unless you are trying to allocate nothing. You can allocate space either of the following ways.unsigned char* pBuffer = new unsigned char[dwLen]; // allocate some space for the data to be read into
// or
unsigned char buffer[dwLen]; // allocate on the stack
ReadFile(hVolume, buffer, dwLen, &dwNum, NULL); -
I have written a little piece of code to read few (first 512) bytes from USB drive. here is the code:
HANDLE hVolume = ::CreateFile(sVolume, GENERIC\_READ, FILE\_SHARE\_READ | FILE\_SHARE\_WRITE, NULL, OPEN\_EXISTING, FILE\_FLAG\_SEQUENTIAL\_SCAN, NULL); TRACE("Volume handle: %p\\n", hVolume); LONG lDistLow = 0; PLONG plDistHigh = 0; if (INVALID\_SET\_FILE\_POINTER == SetFilePointer(hVolume, lDistLow, plDistHigh, FILE\_BEGIN) && NO\_ERROR != GetLastError()) { TRACE("Error: %d\\n", GetLastError()); return FALSE; } else { TRACE("%d\\t%d\\n", lDistLow, plDistHigh); } DWORD dwLen = 512; DWORD dwNum = 0; void\* pBuffer = NULL; ReadFile(hVolume, pBuffer, dwLen, &dwNum, NULL); TRACE("%p\\t%d\\t%d\\n", pBuffer, dwLen, dwNum);
but the result is:
Volume handle: 00000438
0 0
00000000 512 0this pBuffer NULL tell me that I am not able to read that sectors ... why ? The program is running as admin and
sVolume
is feed by_T("\\\\.\\F:")
, firstTRACE
macro printed is a prove that is OK that part.SetFilePointer
is used to position the reading part, and I intend to setup offset to the beginning, right ?As others have pointed out, the issue is with
pBuffer
not associated with any allocated memory. In addition to this, I would like to point out one more flaw in your code, although it doesn't matter in this case. The third parameter to SetFilePointer[^] must be an address of aLONG
variable.PLONG
does not declare aLONG
variable. It's only a pointer to aLONG
variable. HereSetFilePointer
will actually try to write to memory0
. What you need to do is declare aLONG
variable and provide its address -LONG highValue; SetFilePointer(..., ..., &highValue, ...);
You can also pass a
nullptr
, if you're not intersted in that value.«_Superman_» _I love work. It gives me something to do between weekends.
_Microsoft MVP (Visual C++) (October 2009 - September 2013)
-
What does ReadFile return? TRUE or FALSE?
-
As others have pointed out, the issue is with
pBuffer
not associated with any allocated memory. In addition to this, I would like to point out one more flaw in your code, although it doesn't matter in this case. The third parameter to SetFilePointer[^] must be an address of aLONG
variable.PLONG
does not declare aLONG
variable. It's only a pointer to aLONG
variable. HereSetFilePointer
will actually try to write to memory0
. What you need to do is declare aLONG
variable and provide its address -LONG highValue; SetFilePointer(..., ..., &highValue, ...);
You can also pass a
nullptr
, if you're not intersted in that value.«_Superman_» _I love work. It gives me something to do between weekends.
_Microsoft MVP (Visual C++) (October 2009 - September 2013)
It will interest me, not this time, but in the real program. I modified the code like this:
LONG lValueLow = 0; LONG lValueHigh = 0; if (INVALID\_SET\_FILE\_POINTER == SetFilePointer(hVolume, lValueLow, &lValueHigh, FILE\_BEGIN) && NO\_ERROR != GetLastError()) { TRACE("Error: %d\\n", GetLastError()); return FALSE; } else { TRACE("%d\\t%d\\n", lValueLow, lValueHigh); }
Thank you Superman !
-
_Flaviu wrote:
pBuffer NULL tell me that I am not able to read that sectors
No,
pBuffer = NULL;
tells you that you have not allocated any space to pBuffer. And don't usevoid*
unless you are trying to allocate nothing. You can allocate space either of the following ways.unsigned char* pBuffer = new unsigned char[dwLen]; // allocate some space for the data to be read into
// or
unsigned char buffer[dwLen]; // allocate on the stack
ReadFile(hVolume, buffer, dwLen, &dwNum, NULL);Is not accepted:
unsigned char buffer[dwLen]; // error C2057: expected constant expression
Of course, putting 512 is ok, but I need to allocate that length of buffer through a variable. I prefer this option, on stack, as far as I know, is faster than heap.
-
In this case you have to call GetLastError to obtain the exact reason of the failure!
-
In this case you have to call GetLastError to obtain the exact reason of the failure!
-
Is not accepted:
unsigned char buffer[dwLen]; // error C2057: expected constant expression
Of course, putting 512 is ok, but I need to allocate that length of buffer through a variable. I prefer this option, on stack, as far as I know, is faster than heap.
You can fix that easily by doing it this way:
#define SECTOR_SIZE 512
DWORD dwLen = SECTOR_SIZE;
DWORD dwNum = 0;
char buffer[SECTOR_SIZE];
ReadFile(hVolume, buffer, dwLen, &dwNum, NULL);If you are using C++ then instead of
#define
you can use this:const int SECTOR_SIZE = 512
-
You can fix that easily by doing it this way:
#define SECTOR_SIZE 512
DWORD dwLen = SECTOR_SIZE;
DWORD dwNum = 0;
char buffer[SECTOR_SIZE];
ReadFile(hVolume, buffer, dwLen, &dwNum, NULL);If you are using C++ then instead of
#define
you can use this:const int SECTOR_SIZE = 512
-
It will interest me, not this time, but in the real program. I modified the code like this:
LONG lValueLow = 0; LONG lValueHigh = 0; if (INVALID\_SET\_FILE\_POINTER == SetFilePointer(hVolume, lValueLow, &lValueHigh, FILE\_BEGIN) && NO\_ERROR != GetLastError()) { TRACE("Error: %d\\n", GetLastError()); return FALSE; } else { TRACE("%d\\t%d\\n", lValueLow, lValueHigh); }
Thank you Superman !
-
You do not need
lValueHigh
unless the distance to move is a 64 bit value: just specify NULL instead. Also I suggest you study the difference between a variable and a pointer to a variable, you seem somewhat confused about it. -
Good idea. I have tried in this way:
CByteArray arrByte; arrByte.SetSize(512); BOOL bRet = ReadFile(hVolume, arrByte.GetData(), dwLen, &dwNum, NULL);
and seem to go well.
-
I'll try to use CFile Class | Microsoft Docs[^] Can I replace SetFilePointer as well with something from MFC yard ?
[CFile Class | Microsoft Docs](https://docs.microsoft.com/en-us/cpp/mfc/reference/cfile-class?view=vs-2019#seek)
-
I'll try to use CFile Class | Microsoft Docs[^] Can I replace SetFilePointer as well with something from MFC yard ?
-
CFile Class.Seek | Microsoft Docs[^]. You need to read through all the documentation for the class to see what is available.
-
Good idea. I have few troubles with accessing USB drive with CFile, but once I'll solve it, the code will be simple. Here is my trial, none on them has worked:
file.Open(_T("\\\\.\\F:"), CFile::modeRead | CFile::osSequentialScan); // return FALSE
file.Open(_T("F:"), CFile::modeRead | CFile::osSequentialScan); // return FALSE
file.Open(_T("F:\\"), CFile::modeRead | CFile::osSequentialScan); // return FALSE
HANDLE hVolume = ::CreateFile(sVolume, GENERIC\_READ, FILE\_SHARE\_READ | FILE\_SHARE\_WRITE, NULL, OPEN\_EXISTING, FILE\_FLAG\_SEQUENTIAL\_SCAN, NULL); CFile file(hVolume); CFileStatus status; file.GetStatus(status); // return FALSE