|
I didn't feed correctly the buffer. After I setup correctly that parameter, ReadFile return TRUE.
|
|
|
|
|
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.
|
|
|
|
|
_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 use void* unless you are trying to allocate nothing.
You can allocate space either of the following ways.
unsigned char* pBuffer = new unsigned char[dwLen]; unsigned char buffer[dwLen]; ReadFile(hVolume, buffer, dwLen, &dwNum, NULL);
|
|
|
|
|
Is not accepted:
unsigned char buffer[dwLen];
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
|
|
|
|
|
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.
|
|
|
|
|
If you are writing MFC code then you should be using CFile to handle all your I/O.
|
|
|
|
|
|
|
|
I should know that ... thank you.
|
|
|
|
|
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);
file.Open(_T("F:"), CFile::modeRead | CFile::osSequentialScan);
file.Open(_T("F:\\"), CFile::modeRead | CFile::osSequentialScan);
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);
|
|
|
|
|
When using CFile::Open you should pass the CFileException* parameter to get the failure cause if CFile::Open fails.
See the example in CFile::Open
|
|
|
|
|
It is just the same as OpenFile behind the scenes so nothing to do with CFile . Your call probably fails because you are not including the share flags in your call to CFile::Open(), which are required when trying to access a device.
|
|
|
|
|
|
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 a LONG variable.
PLONG does not declare a LONG variable. It's only a pointer to a LONG variable.
Here SetFilePointer will actually try to write to memory 0 .
What you need to do is declare a LONG 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) Polymorphism in C
|
|
|
|
|
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.
|
|
|
|
|
Understood now, I didn't paid attention on that function (lpDistanceToMoveHigh , is obviously now, or, at least I think is obviously).
|
|
|
|
|
struct TestStruct
{
int x;
int z;
};
TestStruct S;
TestStruct Funct()
{
return S;
}
Funct().x = 100;
Will this work?
|
|
|
|
|
Yes, but Func() is not really necessary, since you have already declared S . You can just say S.x = 100;
Creating a function to return a structure (or anything else) is usually necessary when you cannot declare the relevant object at compile time, but need to create it dynamically. Something like:
TestStruct* Funct()
{
TestStruct* pS = new TestStruct;
pS->x = 0;
ps->z = 0;
return pS;
}
TestStruct* pNewStruct = Funct();
pNewStruct->x = 100;
|
|
|
|
|
Hello,
the code itself will work, but will not do what I suppose you expect.
Here, Funct returns a copy of the TestStruct S.
So Funct().x = 100 will affect 100 in a temporary TestStruct that you can not use after that.
I don't know why you want to use a function to access your S structure, but the behavior you look for is probably :
TestStruct& Funct()
{
return S;
}
|
|
|
|
|
my actual code:
ChartNode Chart[100];
ChartNode NodeCoord(int x, int z)
{
return Chart[z * 10 + x];
}
if(NodeCoord(4,4).access)
NodeCoord(4,4).access = false;
The result I`m looking for is the same as the result achieved with this function:
void NodeCoord(int x, int z, bool writetobool)
{
Chart[z * 10 + x].access = writetobool;
}
modified 3-May-20 5:10am.
|
|
|
|
|
So you probably need to return a reference :
ChartNode& NodeCoord(int x, int z)
{
return Chart[z * 10 + x];
}
else the NodeCoord(4,4).access = false will assign a temporary copy of your ChartNode struct and not the one in your array.
|
|
|
|
|
ChartNode& NodeCoord() will work for both read and write?
|
|
|
|