2017-03-02 20 views
-1

私はプログラミング、特にWindowsシステムプログラミングでは新しいですし、関連する本を読んでいます。現在私は、ファイルのファイルサイズを取得するために、GetFileSizeEx、SetFilePointerSetFilePointerExでarroundを再生しています。SetFilePointerExファイルサイズを取得

サイズを取得するためにSetFilePointerExを取得できない65行目まで動作するこのコードを作成しました。

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

#define BUFF_SIZE 0x100 

// program to test file size 

int _tmain(DWORD argc, LPTSTR argv[]) 
{ 
    HANDLE hIn; 
    HANDLE hOut; 
    LARGE_INTEGER liSize; 
    LONG lSize, lDistance = 0; 
    TCHAR szMsgGetFile[BUFF_SIZE]; 
    TCHAR szMsgSetFile[BUFF_SIZE]; 
    DWORD nIn; 
    LARGE_INTEGER liPt; 
    PLARGE_INTEGER pLi; 
    pLi = &liPt; 

    SecureZeroMemory(&liSize, sizeof(LARGE_INTEGER)); 
    SecureZeroMemory(&pLi, sizeof(LARGE_INTEGER)); 
    SecureZeroMemory(szMsgGetFile, _tcslen(szMsgGetFile)); 
    SecureZeroMemory(szMsgSetFile, _tcslen(szMsgSetFile)); 


    //get input and output handles 
    hIn = CreateFile(argv[1], GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 
    if (hIn == INVALID_HANDLE_VALUE) 
     _tprintf(_T("[ERROR] CreateFile to get file input handle failed. Error code %d.\n"), GetLastError()); 
    hOut = CreateFile(_T("CONOUT$"), GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 
    if (hOut == INVALID_HANDLE_VALUE) 
     _tprintf(_T("[ERROR] CreateFile to get file output handle failed. Error code %d.\n"), GetLastError()); 

    //get the size of the file with GetFileSizeEx, acquired from hIn that is argv1 
    if (!GetFileSizeEx(hIn, &liSize)) 
     _tprintf(_T("[ERROR] GetFileSizeEx failed. Error code %d\n"), GetLastError()); 

    //get the size of the file with SetFilePointer 
    //You can obtain the file length by specifying a zero-length move from the end of 
    //file, although the file pointer is changed as a side effect 
    lSize = SetFilePointer(hIn, lDistance, NULL, FILE_END); 
    if (lSize == INVALID_SET_FILE_POINTER) 
     _tprintf(_T("[ERROR] SetFilePointer failed. Error code %d\n"), GetLastError()); 

    //output the size with WriteConsole (and sprintf) 
    //and with _tprintf. Notice the usage of the liSize LARGE_INTEGER 
    _stprintf_s(szMsgGetFile, BUFF_SIZE, "[*] GetFileSizeEx (WriteConsole): The size is %I64d Bytes.\n", liSize.QuadPart); 
    if (!WriteConsole(hOut, szMsgGetFile, _tcslen(szMsgGetFile), &nIn, NULL)) 
     _tprintf(_T("[ERROR] WriteConsole failed. Error code %d\n"), GetLastError()); 
    _tprintf(_T("[*] GetFileSizeEx (tprintf): The size is %I64d Bytes.\n"), liSize.QuadPart); 

    //output the size with WriteConsole (and sprintf) 
    //and _tprintf 
    _stprintf_s(szMsgSetFile, BUFF_SIZE, "[*] SetFilePointer (WriteConsole): The size is %ld Bytes.\n", lSize); 
    if (!WriteConsole(hOut, szMsgSetFile, _tcslen(szMsgSetFile), &nIn, NULL)) 
     _tprintf(_T("[ERROR] WriteConsole failed. Error code %d\n"), GetLastError()); 
    _tprintf(_T("[*] SetFilePointer (tprintf): The size is %ld Bytes.\n"), lSize); 

    //get the size of the file with SetFilePointerEx 
    //Determine a file’s size by positioning 0 bytes from the end and using the file 
    //pointer value returned by SetFilePointerEx. 
    SecureZeroMemory(&liPt, sizeof(LARGE_INTEGER)); 
    SetFilePointerEx(hIn, liPt, pLi, FILE_END); 
    _tprintf(_T("[*] SetFilePointerEx: %lld Bytes.\n"), pLi->QuadPart); 
    return 0; 
} 

MSDNは

あなたは、ファイルの長さを決定するためにSetFilePointerExを使用できることを述べています。これを行うには、dwMoveMethodにFILE_ENDを使用し、位置ゼロを探します。返されるファイルオフセットは、ファイルの長さです。

ただし、SetFilePointerExはBOOL型です。 「Windowsシステムプログラミング」の本では、「最後から0バイトの位置を特定し、SetFilePointerExによって返されたファイルポインタ値を使用してファイルのサイズを決定する」と記載されています。私はこのパラメータがMSDNによると_Out_opt_ PLARGE_INTEGER lpNewFilePointerだと推測しています。

SetFilePointerExを使用してファイルのファイルサイズを取得する方法についてのヘルプが必要です。

+1

あなたのコードで 'SetFilePointerEx'の使用が正しいと思います。ファイルサイズは 'pLI-> QuadPart'でなければなりません。 –

+0

あなたは速いです:)ありがとう - 確かに私は持っていました – stukov

+0

SetFilePointerのtprintf出力を表示した後にプログラムがクラッシュしました。それをデバッグしようとすると(vsデバッガを使用するときの悩み)、pLiがNULLptr – stukov

答えて

1

コードにいくつかのエラーがあります。以下は、動作するSetFilePointerExの例です。一般に、Win32関数は、出力を格納するためにメモリを割り当てません(何らかの方法)。呼び出し元はメモリを割り当てる必要があります。この場合、SetFilePointerExの出力のメモリは、size2LARGE_INTEGERと宣言することによってスタックに割り当てられます。そのLARGE_INTEGERへのポインタは、SetFilePointerExに提供されます。

auto hIn = CreateFile(_T("C:\\foo"), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); 
/* check for errors */ 

LARGE_INTEGER size; 
GetFileSizeEx(hIn, &size); 
/* check for errors */ 

LARGE_INTEGER size2; 
LARGE_INTEGER offset; 
ZeroMemory(&offset, sizeof offset); 
SetFilePointerEx(hIn, offset, &size2, FILE_END); 
/* check for errors */ 
+0

あなたのコードは、ありがとう!私はあなたが好きなら、私のエラーに関するいくつかのより多くの情報が欲しいです。 – stukov

0

必要に応じて、DWORD dwFileSize = GetFileSize(hFile, NULL);HANDLE hFile = CreateFileA/W(...);で開かれたファイルのサイズを取得することができます。

関連する問題