Win32 API - 尝试读取文件,它被截断 - 为什么?

时间:2012-07-01 00:26:33

标签: c winapi executable readfile

我正在尝试读取文件,然后以ASCII或HEX格式将文件显示到hEdit中。最终我将在文件信息上运行其他计算,但现在我只想看到它。

目前代码显示第一位 - “MZ” - 但就是这样。不知怎的,我不小心截断了pszFileText变量,我希望能够在我的窗口中查看整个可执行文件。

BOOL ReadInEXEFile(HWND hEdit, LPCTSTR pszFileName)
{
HANDLE hFile;
BOOL bSuccess = FALSE;

hFile = CreateFile(pszFileName, GENERIC_READ, FILE_SHARE_READ, NULL,
    OPEN_EXISTING, 0, NULL);
if(hFile != INVALID_HANDLE_VALUE)
{
    DWORD dwFileSize;

    dwFileSize = GetFileSize(hFile, NULL);
    if(dwFileSize != 0xFFFFFFFF)
    {
        LPSTR pszFileText;

        pszFileText = GlobalAlloc(GPTR, dwFileSize + 1);
        if(pszFileText != NULL)
        {
            DWORD dwRead;
            if(ReadFile(hFile, pszFileText, dwFileSize, &dwRead, NULL))
            {
                pszFileText[dwFileSize] = 0; // Add null terminator
                if(SetWindowText(hEdit, pszFileText))
                {
                    bSuccess = TRUE; // It worked!
                }
            }
            GlobalFree(pszFileText);
        }
    }
    CloseHandle(hFile);
}
return bSuccess;

}

3 个答案:

答案 0 :(得分:7)

EXE文件是二进制文件,但您是在尝试按原样显示原始二进制数据,这不起作用。你是在正确的轨道上认为你需要在显示它之前将二进制数据编码为十六进制。二进制数据不可显示,但十六进制是。

请改为尝试:

static const TCHAR Hex[] = TEXT("0123456789ABCDEF");

BOOL ReadInEXEFile(HWND hEdit, LPCTSTR pszFileName) 
{ 
    BOOL bSuccess = FALSE; 

    HANDLE hFile = CreateFile(pszFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); 
    if (hFile != INVALID_HANDLE_VALUE) 
    { 
        DWORD dwFileSize = GetFileSize(hFile, NULL); 
        if (dwFileSize != INVALID_FILE_SIZE)
        { 
            LPTSTR pszFileText = (LPTSTR) LocalAlloc(LMEM_FIXED, ((dwFileSize * 3) + 1) * sizeof(TCHAR)); 
            if (pszFileText != NULL)
            {
                BYTE buffer[1024];
                DWORD dwOffset = 0;
                DWORD dwRead; 

                for (DWORD dwFilePos = 0; dwFilePos < dwFileSize; dwFilePos += dwRead)
                {
                    if (!ReadFile(hFile, buffer, sizeof(buffer), &dwRead, NULL)) 
                    {
                        CloseHandle(hFile);
                        return FALSE;
                    }

                    if (dwRead == 0)
                        break;

                    for (DWORD idx = 0; idx < dwRead; ++idx)
                    {
                        pszFileText[dwOffset++] = Hex[(buffer[idx] & 0xF0) >> 4];
                        pszFileText[dwOffset++] = Hex[buffer[idx] & 0x0F];
                        pszFileText[dwOffset++] = TEXT(' ');
                    }
                }

                pszFileText[dwOffset] = 0; // Add null terminator 

                bSuccess = SetWindowText(hEdit, pszFileText);
                LocalFree(pszFileText);
            } 
        } 

        CloseHandle(hFile); 
    } 

    return bSuccess; 
}

答案 1 :(得分:2)

有两个原因:

1)如果您正在读取可执行文件,则第三个字节可能为零,即使您将长度传递给SetWindowText,也可能会终止该字符串。

2)这一行是错误的:pszFileText[dwFileSize + 1] = 0;。它应该是pszFileText[dwFileSize] = 0;。你正在写一个错误的零字节,不知道那可能在做什么。

答案 2 :(得分:1)

您显示它的方式可能取决于数据是NUL终止的字符串,而二进制数据中嵌入了NUL,因此您只显示数据直到第一个NUL。

您需要自己打印并使用数据长度来了解打印的数量,而不是取决于它是否为NUL终止的C字符串。