diff --git a/CMakeLists.txt b/CMakeLists.txt index c23855bf5..de7d36a6f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -342,7 +342,7 @@ if(WIN_MSYS) src/detection/users/users_windows.cpp src/detection/os/os_windows.cpp src/detection/processes/processes_windows.cpp - src/detection/disk/disk_windows.cpp + src/detection/disk/disk_windows.c src/detection/cpuUsage/cpuUsage_windows.c src/detection/cpuUsage/cpuUsage_nowait_windows.cpp src/detection/memory/memory_windows.cpp diff --git a/src/data/help.txt b/src/data/help.txt index f24242ec4..181f24671 100644 --- a/src/data/help.txt +++ b/src/data/help.txt @@ -90,7 +90,7 @@ Module specific options: --title-fqdn : Sets if the title should use fully qualified domain name. Default is false. --separator-string : Set the string printed by the separator module --os-file : Set the path to the file containing OS informations - --disk-folders : A colon separated list of folder paths for the disk output. Default is "/:/home" + --disk-folders : A colon (semicolon on Windows) separated list of folder paths for the disk output. Default is "/:/home" ("C:\\;D:\\ ..." on Windows) --disk-removable : Sets if removable volume should be printed. Default is false --battery-dir : The directory where the battery folders are. Standard: /sys/class/power_supply/ --cpu-temp : Detect and display CPU temperature if supported. Default is false diff --git a/src/detection/disk/disk_windows.c b/src/detection/disk/disk_windows.c new file mode 100644 index 000000000..27117a017 --- /dev/null +++ b/src/detection/disk/disk_windows.c @@ -0,0 +1,66 @@ +#include "disk.h" + +#define WIN32_LEAN_AND_MEAN 1 +#include + +static void detectDrive(const char* folderPath, uint32_t pathLen, FFDiskResult* result) +{ + ffStrbufInitNS(&result->path, pathLen, folderPath); + result->removable = false; //To be set at other place + result->files = 0; //Unsupported + + //According to https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getdiskfreespaceexa + //GetDiskFreeSpaceExA does not have to specify the root directory on a disk. The function accepts any directory on a disk. + uint64_t freeBytes; + if(GetDiskFreeSpaceExA(folderPath, NULL, (PULARGE_INTEGER)&result->total, (PULARGE_INTEGER)&freeBytes)) { + result->used = result->total - freeBytes; + ffStrbufInit(&result->error); + } + else + ffStrbufInitS(&result->error, "GetDiskFreeSpaceExA() failed"); +} + +const char* ffDiskAutodetectFolders(FFinstance* instance, FFlist* folders) +{ + FF_UNUSED(instance); + + char buf[128]; // "C:\\\0D:\\\0" + uint32_t length = GetLogicalDriveStringsA(sizeof(buf) / sizeof(*buf), buf); + + for(size_t i = 0; i < length;) + { + const char* drive = buf + i; + uint32_t driveLen = (uint32_t) strlen(drive); + i += driveLen + 1; + + bool removable = GetDriveTypeA(drive) == DRIVE_REMOVABLE; + if(removable && !instance->config.diskRemovable) + continue; + + FFDiskResult* folder = (FFDiskResult*)ffListAdd(folders); + detectDrive(drive, driveLen, folder); + folder->removable = removable; + } + + return NULL; +} + +bool ffDiskDetectDiskFolders(FFinstance* instance, FFlist* folders) +{ + ffStrbufTrim(&instance->config.diskFolders, ';'); + if(instance->config.diskFolders.length == 0) + return false; + + uint32_t startIndex = 0; + while(startIndex < instance->config.diskFolders.length) + { + uint32_t colonIndex = ffStrbufNextIndexC(&instance->config.diskFolders, startIndex, ';'); + instance->config.diskFolders.chars[colonIndex] = '\0'; + + detectDrive(instance->config.diskFolders.chars + startIndex, colonIndex - startIndex, (FFDiskResult*)ffListAdd(folders)); + + startIndex = colonIndex + 1; + } + + return true; +} diff --git a/src/detection/disk/disk_windows.cpp b/src/detection/disk/disk_windows.cpp deleted file mode 100644 index dce2f92eb..000000000 --- a/src/detection/disk/disk_windows.cpp +++ /dev/null @@ -1,55 +0,0 @@ -extern "C" { -#include "disk.h" -} -#include "util/windows/wmi.hpp" - -const char* ffDiskAutodetectFolders(FFinstance* instance, FFlist* folders) -{ - FF_UNUSED(instance); - - const wchar_t* query = instance->config.diskRemovable - ? L"SELECT Name, DriveType, FreeSpace, Size FROM Win32_LogicalDisk" - : L"SELECT Name, FreeSpace, Size FROM Win32_LogicalDisk WHERE DriveType != 2"; - IEnumWbemClassObject* pEnumerator = ffQueryWmi(query, nullptr); - - if(!pEnumerator) - return "Query WMI service failed"; - - IWbemClassObject *pclsObj = NULL; - ULONG uReturn = 0; - - while(SUCCEEDED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) && uReturn != 0) - { - FFDiskResult* folder = (FFDiskResult*)ffListAdd(folders); - - ffStrbufInit(&folder->path); - ffGetWmiObjString(pclsObj, L"Name", &folder->path); - - uint64_t free; - ffGetWmiObjUnsigned(pclsObj, L"Size", &folder->total); - ffGetWmiObjUnsigned(pclsObj, L"FreeSpace", &free); - folder->used = folder->total - free; - - if(instance->config.diskRemovable) - { - uint64_t driveType; - ffGetWmiObjUnsigned(pclsObj, L"DriveType", &driveType); - folder->removable = driveType == 2; - } - else - folder->removable = false; - - folder->files = 0; //Unsupported - - ffStrbufInit(&folder->error); - } - - pclsObj->Release(); - pEnumerator->Release(); - return nullptr; -} - -bool ffDiskDetectDiskFolders(FFinstance*, FFlist*) -{ - return false; // Unsupported -}