I'm a beginner with the Windows API and C Programming, I am trying to get the file size from my files, but my output is not so as expected.
That's my code:
#include <Windows.h>
#include <wchar.h>
#include <stdio.h>
#pragma warning(disable : 4996)
#define ANSI_RESET "\x1b[0m"
#define ANSI_GREEN "\x1b[32m"
#define ANSI_BRIGHT_MAGENTA "\x1b[95m"
int wmain() {
WIN32_FIND_DATAW fd;
wprintf(L"Pfad zum Lesen: ");
wchar_t inputPath[MAX_PATH];
fgetws(inputPath, MAX_PATH, stdin);
size_t len = wcslen(inputPath);
if (len > 0 && inputPath[len - 1] == L'\n') {
inputPath[--len] = L'\0';
}
if (len > 0 && inputPath[len - 1] == L'\r') {
inputPath[--len] = L'\0';
}
if (len > 0 && inputPath[len - 1] != L'\\') {
wcscat(inputPath, L"\\");
}
//wcscat fügt ein zeichen hinzu
wcscat(inputPath, "*");
wprintf(L"Debug: %ls\n", inputPath);
HANDLE hFirstFile = FindFirstFileW(
inputPath,
&fd
);
if (hFirstFile == INVALID_HANDLE_VALUE) {
wprintf(L"hFirstFile Fehlgeshlagen mit: %lu", GetLastError());
return 1;
}
do {
wprintf(L"Name: "ANSI_BRIGHT_MAGENTA"%ls\n"ANSI_RESET, fd.cFileName);
wprintf(L"Groesse: %lu\n", fd.nFileSizeHigh);
wprintf(L"\n");
} while (FindNextFileW(hFirstFile, &fd));
FindClose(hFirstFile);
return 0;
}
and this is my output:
Name: .
Groesse: 0
Name: . .
Groesse: 0
Name: vorlage.docx
Groesse: 0
Name: Seite 3 Lernaufgabe 1.docx
Groesse: 0
Name: Seite 3 Lernaufgabe 2.docx
Groesse: 0
The reason why you are getting zeros for file sizes is because you are only printing the nFileSizeHigh field, which contains the high-order 32-bit component of the whole 64-bit file size:
wprintf(L"Groesse: %lu\n", fd.nFileSizeHigh);
You have to combine both the 32-bit high-order and 32-bit low-order components of the file size into a single 64-bit value.
The Microsoft documentation for the WIN32_FIND_DATAW structure contains this description about the nFileSizeHigh field:
nFileSizeHighThe high-order DWORD value of the file size, in bytes.
This value is zero unless the file size is greater than MAXDWORD.
The size of the file is equal to (nFileSizeHigh * (MAXDWORD+1)) + nFileSizeLow.
So, it basically already gave you the formula for computing the total file size, expressed as a 64-bit integer, in terms of the two 32-bit "size component" fields nFileSizeLow and nFileSizeHigh.
You can also use the ULARGE_INTEGER union, setting "as input" its HighPart and LowPart 32-bit fields, and reading back "as output" the whole 64-bit QuadPart field:
WIN32_FIND_DATAW findData;
// ...
ULARGE_INTEGER uliFileSize;
// Set the two 32-bit size components
uliFileSize.HighPart = findData.nFileSizeHigh;
uliFileSize.LowPart = findData.nFileSizeLow;
// Read back the whole 64-bit size
ULONGLONG ullFileSize = uliFileSize.QuadPart;
To print the file size as an unsigned 64-bit integer, you can use the format specifier %I64u, as described in the Format Specification Syntax documentation page for printf and wprintf:
wprintf(L"File size: %I64u bytes.\n", ullFileSize);
I64 is the size prefix, meaning that you are passing a 64-bit integer argument, and u is the type field specifying that this is an unsigned decimal integer.