Существует ряд проблем с вашим кодом.
problemFunction()
принимает указатель HANDLE*
в качестве ввода, но он не разыменовывает этот указатель при передаче его в GetFileSize()
или CloseHandle()
, Но он разыменовывает указатель при передаче его на ReadFile()
.
Вы должны компилировать свой код с отключенной проверкой типа STRICT , иначе ваш код не сможет скомпилироваться. Вы всегда должны компилировать с включенным STRICT.
HANDLE
- это тип указателя, поэтому нет необходимости передавать его по указателю, если только вы не собираетесь изменять его значение, чего не делает этот код. Таким образом, вы должны изменить problemFunction()
, чтобы принимать HANDLE
как есть, а не указатель HANDLE*
.
Кроме того, GetFileSize()
не возвращает 0 в случае сбоя, как предполагает ваш код. На самом деле возвращается INVALID_FILE_SIZE
, что равно -1, ie 0XFFFFFFFF
как DWORD
. Это четко указано в документации :
Если функция завершается ошибкой и lpFileSizeHigh равен NULL, возвращаемое значение равно INVALID_FILE_SIZE. Чтобы получить расширенную информацию об ошибке, вызовите GetLastError.
Но, что наиболее важно, ваш второй вызов ReadFile()
внутри main()
не читает то, что вы ожидаете, поскольку первый вызов ReadFile()
внутри problemFunction()
уже прочитал данные (и слил их!), но вы не ищете HANDLE
назад к началу файла после того, как прочитали, так что второй вызов ReadFile()
может прочитать его снова. Вы правы, что вам нужно использовать SetFilePointer()
для этого.
С учетом сказанного, попробуйте что-то вроде этого:
#include <Windows.h>
#include <winternl.h>
bool test(HANDLE fh) {
DWORD fileSize = GetFileSize(fh, NULL);
if (fileSize == INVALID_FILE_SIZE) {
return false;
}
BYTE* pByte = new BYTE[fileSize];
DWORD dw;
if (!ReadFile(fh, pByte, fileSize, &dw, NULL)) {
delete[] pByte;
return false;
}
// use pByte as needed...
delete[] pByte;
if (SetFilePointer(fh, 0, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER) {
return false;
}
return true;
}
int main() {
const char* filepath = "C:\\windows\\file\\path\\to\\exe";
HANDLE fh = CreateFileA(filepath, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (fh == INVALID_HANDLE_VALUE) {
return 1;
}
if (!test(fh)) {
CloseHandle(fh);
return 1;
}
DWORD fileSize = GetFileSize(fh, NULL);
if (fileSize == INVALID_FILE_SIZE) {
CloseHandle(fh);
return 1;
}
BYTE* pByte = new BYTE[fileSize];
DWORD dw;
if (!ReadFile(fh, pByte, fileSize, &dw, NULL) || dw < sizeof(IMAGE_DOS_HEADER)) {
CloseHandle(fh);
return 1;
}
PIMAGE_DOS_HEADER dos = (PIMAGE_DOS_HEADER)pByte;
if (dos->e_magic != IMAGE_DOS_SIGNATURE) {
delete[] pByte;
CloseHandle(fh);
return 1;
}
...
delete[] pByte;
CloseHandle(fh);
return 0;
}