花了几年时间,但我终于开始投入VC ++了。我需要能够读取物理设备的x个扇区(即硬盘驱动器)。我正在使用CreateFile()和SetFilePointerEx()和ReadFile()API。
我在所有主要论坛上都有很多关于这个主题的在线阅读。我已经用尽了我的研究,现在我觉得是时候让专家来解决这个两难问题了。由于这是我关于这个话题的第一篇文章,请在我的上面轻松一下:)
我还应该指出,这是一个用简单的C#app消费的.DLL。管道一切正常。这是导致我悲痛的SetFilePointer(Ex)()API。
我可以让代码工作到大约LONG(4,xxx,xxx)的大小 - 我不记得确切的值。可以说我可以阅读包括#4,000,000部门在内的所有内容,但不包括5,000,000或以上。问题在于SetFilePointer()和SetFilePointerEx()API参数的“大小”。我已经尝试过两次,到目前为止,SetFilePointerEx()似乎是我应该用来在64位系统上工作的。
SetFilePointer的第2和第3个参数定义如下:
BOOL WINAPI SetFilePointerEx(
__in HANDLE hFile,
__in LARGE_INTEGER liDistanceToMove,
__out_opt PLARGE_INTEGER lpNewFilePointer,
__in DWORD dwMoveMethod
);
请注意,我尝试将LowPart和HighPart作为第2和第3个参数传递但没有成功,因为我得到了一个CAN NOT CONVERT LARGE_INTEGER TO PLARGE_INTEGER(参数3)。
这是我的代码。我使用CODE-BREAK来查看buff [0]等。我想读过4,xxx,xxx限制。显然我做错了什么。每次读取超过此限制都会将我的文件指针重置为扇区0。
#include "stdafx.h"
#include <windows.h>
#include <conio.h>
extern "C"
__declspec(dllexport) int ReadSectors(long startSector, long numSectors)
{
HANDLE hFile;
const int SECTOR_SIZE = 512;
const int BUFFER_SIZE = 512;
LARGE_INTEGER liDistanceToMove;
PLARGE_INTEGER newFilePtr = NULL; // not used in this context.
// just reading from START to END
liDistanceToMove.QuadPart = startSector * SECTOR_SIZE;
DWORD dwBytesRead, dwPos;
LPCWSTR fname = L"\\\\.\\PHYSICALDRIVE0";
char buff[BUFFER_SIZE];
// Open the PHYSICALDEVICE as a file.
hFile = CreateFile(fname,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
// Here's the API definition
/*BOOL WINAPI SetFilePointerEx(
__in HANDLE hFile,
__in LARGE_INTEGER liDistanceToMove,
__out_opt PLARGE_INTEGER lpNewFilePointer,
__in DWORD dwMoveMethod
);*/
dwPos = SetFilePointerEx(hFile, liDistanceToMove, NULL, FILE_BEGIN);
if(ReadFile(hFile, buff, BUFFER_SIZE, &dwBytesRead, NULL))
{
if(dwBytesRead > 5)
{
BYTE x1 = buff[0];
BYTE x2 = buff[1];
BYTE x3 = buff[2];
BYTE x4 = buff[3];
BYTE x5 = buff[4];
}
}
// Close both files.
CloseHandle(hFile);
return 0;
}
答案 0 :(得分:3)
startSector * SECTOR_SIZE;
startSector是long
(32位),SECTOR_SIZE是int
(也是32位),乘以这两个家伙,中间结果将是一个很长的,这会溢出然后你的东西它进入__int64
的{{1}},为时已晚。你想在LARGE_INTEGER
上操作,比如
__int64
例如。