2017-03-02 1 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를 사용하고 위치 0을 찾으십시오. 반환 된 파일 오프셋은 파일의 길이입니다.

그러나 SetFilePointerEx는 BOOL 유형입니다. "Windows 시스템 프로그래밍"책은 "끝에 0 바이트를 배치하고 SetFilePointerEx에서 반환 한 파일 포인터 값을 사용하여 파일 크기를 결정합니다."라고 말합니다. 이 매개 변수는 MSDN에 따라 _Out_opt_ PLARGE_INTEGER lpNewFilePointer이라고 추측합니다.

SetFilePointerEx를 사용하여 파일의 파일 크기를 얻는 방법에 대한 도움을 받고 싶습니다.

+1

당신의 코드에서'SetFilePointerEx'의 사용법이 정확하다고 봅니다. 파일 크기는 'pLI-> QuadPart'여야합니다. –

+0

당신은 빠릅니다 :) 감사합니다 - 실제로 제가 가지고 있습니다 – stukov

+0

SetprintPointer 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(...);에 의해 열린 파일의 크기를 얻을 수 있습니다.