2013-04-04 46 views
1

我有一個基本的C++程序。其目標是顯示包含在特定文件夾中的文件名。 C++代碼如下:lstrcat在MASM程序中無法正常工作

#include <Windows.h> 
#include <iostream> 
#include <stdio.h> 
#include <tchar.h> 
#include <strsafe.h> 

int      _tmain(int ac, TCHAR **av) 
{ 
    HANDLE    hFile; 
    WIN32_FIND_DATA  findFileData; 
    BOOL    retFindNextFile; 
    TCHAR    FilePathPattern[] = TEXT("C:\\Users\\Bloodsucker94\\Desktop\\TestASM\\*.txt"); 

    if ((hFile = FindFirstFile(FilePathPattern, &findFileData)) == INVALID_HANDLE_VALUE) 
     _tprintf(TEXT("FindFirstFile() failed with code %d\n"), GetLastError()); 
    else { 
     _tprintf(TEXT("hFile=%d, addr=0x%08X\n"), hFile, &findFileData); 
     do { 
      TCHAR  beginPath[] = TEXT("C:\\Users\\Bloodsucker94\\Desktop\\TestASM\\"); 

      lstrcat(beginPath, findFileData.cFileName); 
      _tprintf(TEXT("%s\n"), beginPath); 
      //printf("%s\n", beginPath); 
      retFindNextFile = FindNextFile(hFile, &findFileData); 

     } while (retFindNextFile == TRUE); 
    } 
    getchar(); 
    return (EXIT_SUCCESS); 
} 

我想生產使用MASM同一程序:

.386 
.model       flat, stdcall 
option       casemap :none 

include       \masm32\include\windows.inc 
include       \masm32\include\kernel32.inc 
include       \masm32\include\masm32.inc 
include       \masm32\include\masm32rt.inc 
includelib      \masm32\lib\kernel32.lib 
includelib      \masm32\lib\masm32.lib 
include       \masm32\include\msvcrt.inc 
includelib      \masm32\lib\msvcrt.lib 
includelib      \masm32\lib\crtdll.lib 

_tprintf PROTO C :VARARG 

.data 

FolderPath      TCHAR      "C:\Users\Bloodsucker94\Desktop\TestASM\*.txt", 0 
BeginFolderPath     TCHAR      "C:\Users\Bloodsucker94\Desktop\TestASM\", 0 
FileName      TCHAR      "ta_mere.txt", 0 

LstrcatFailed     BYTE      "lstrcat failed", 0 
FormatPrintString    BYTE      "%s\n", 0 

FindFirstFileError    BYTE      "FindFirstFile() failed with code %d", 0 
FindFirstFileSuccess   BYTE      "First file found with success - hfile=%d", 0 
PrintStructAddr     BYTE      "addr=Ox%08X", 0 
PrintFileName     BYTE      "%s", 0 

.data? 

hFile       HANDLE      ? 
findFileData     WIN32_FIND_DATA    <> 
retFindNextFile     BOOL      ? 
ErrorCode      DWORD      ? 
FinalFilePath     LPTSTR      ? 

.code 

start: 

    ;-------------------------------------------------------- 

    invoke FindFirstFile,  ADDR FolderPath,   \ 
           ADDR findFileData 

    mov  hFile,    eax 

    .IF hFile == INVALID_HANDLE_VALUE 
     invoke GetLastError 
     mov  ErrorCode,  eax 
     printf("%d\n", ErrorCode) 
     jmp      _quit         
    .ENDIF 

    ;-------------------------------------------------------- 

_loop: 
    invoke lstrcat,   ADDR BeginFolderPath, 
           ADDR findFileData.cFileName 

    mov  FinalFilePath,  eax 

    .IF FinalFilePath == NULL 
     invoke MessageBox,  NULL,      \ 
           ADDR LstrcatFailed,   \ 
           ADDR LstrcatFailed,   \ 
           MB_OK 
    .endif  

    ;invoke crt_printf,   ADDR FormatPrintString,  \ 
    ;       findFileData.cFileName 

    invoke MessageBox,   NULL,      \ 
           ADDR FinalFilePath,   \ 
           ADDR FinalFilePath,   \ 
           MB_OK 

    ;-------------------------------------------------------- 

    invoke FindNextFile,  hFile,      \ 
           ADDR findFileData  

    .IF eax == NULL 
     jmp      _quit 
    .ELSE 
     jmp      _loop      
    .ENDIF 

    ;-------------------------------------------------------- 

_quit: 
    invoke ExitProcess,  0 

end start 

編譯完美。 lstrcat函數也不會失敗。但在執行時,消息框顯示字符串「-O @」。當我想用printf打印而不是_tprintf時,我注意到了C++程序中的相同行爲(因爲打印TCHAR Windows類型不適用於printf)。也許問題來自MessageBox函數或TCHAR類型不是好的。只有c + +程序的作品。我迷路了。

有人可以幫助我嗎?

在此先感謝您的幫助。

回答

0

首先,您致電lstrcat將會覆蓋BeginFolderPath之後的內存。因此,您對FileName的價值肯定會被覆蓋,並且如果文件名非常長,則不會告知您的數據段的哪些部分將被該調用拋棄。緩衝區溢出不是lstrcat唯一可能的問題。請參閱文檔http://msdn.microsoft.com/en-us/library/windows/desktop/ms647487(v=vs.85).aspx

您可能會考慮在調試器中運行此函數,並在調用lstrcat返回後查看內存。

此外,你正在混合TCHAR和​​你的字符串,這有點混淆。我不清楚你是否想讓這個程序使用Unicode或ANSI字符串。正如它目前所寫,這是不可能告訴的。在這個程序中是TCHAR一個字節,還是一個字?如果是一個字,那麼你需要撥打MessageBoxW

設置輸出彙編列表文件的編譯器開關並編譯C++程序會很有幫助。看看生成的彙編代碼。

+0

感謝您的完整答案。我發現我的問題的來源:它來自顯示功能。我通過crt_printf更改了MessageBox調用:調用crt_printf,ADDR FormatPrintString,ADDR BeginFolderPath。所以lstrcat工作。再見。 – user1364743 2013-04-04 16:02:45