diff options
Diffstat (limited to 'win32/statfs.c')
| -rw-r--r-- | win32/statfs.c | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/win32/statfs.c b/win32/statfs.c new file mode 100644 index 000000000..97b3ce679 --- /dev/null +++ b/win32/statfs.c | |||
| @@ -0,0 +1,70 @@ | |||
| 1 | #include <sys/statfs.h> | ||
| 2 | #include "libbb.h" | ||
| 3 | |||
| 4 | /* | ||
| 5 | * Code from libguestfs (with addition of GetVolumeInformation call) | ||
| 6 | */ | ||
| 7 | int statfs(const char *file, struct statfs *buf) | ||
| 8 | { | ||
| 9 | ULONGLONG free_bytes_available; /* for user - similar to bavail */ | ||
| 10 | ULONGLONG total_number_of_bytes; | ||
| 11 | ULONGLONG total_number_of_free_bytes; /* for everyone - bfree */ | ||
| 12 | DWORD serial, namelen, flags; | ||
| 13 | char fsname[100]; | ||
| 14 | struct mntent *mnt; | ||
| 15 | /* Valid filesystem names don't seem to be documented. The following | ||
| 16 | * are present in Wine (dlls/kernel32/volume.c). */ | ||
| 17 | #define FS_NAMES "NTFS\0FAT\0FAT32\0CDFS\0UDF\0" | ||
| 18 | int fstypes[] = {0, 0x5346544e, 0x4006, 0x4006, 0x9660, 0x15013346}; | ||
| 19 | |||
| 20 | if ( (mnt=find_mount_point(file, 0)) == NULL ) { | ||
| 21 | return -1; | ||
| 22 | } | ||
| 23 | |||
| 24 | file = mnt->mnt_dir; | ||
| 25 | if ( !GetDiskFreeSpaceEx(file, (PULARGE_INTEGER) &free_bytes_available, | ||
| 26 | (PULARGE_INTEGER) &total_number_of_bytes, | ||
| 27 | (PULARGE_INTEGER) &total_number_of_free_bytes) ) { | ||
| 28 | errno = err_win_to_posix(); | ||
| 29 | return -1; | ||
| 30 | } | ||
| 31 | |||
| 32 | if ( !GetVolumeInformation(file, NULL, 0, &serial, &namelen, &flags, | ||
| 33 | fsname, 100) ) { | ||
| 34 | errno = err_win_to_posix(); | ||
| 35 | return -1; | ||
| 36 | } | ||
| 37 | |||
| 38 | memset(buf, 0, sizeof(*buf)); | ||
| 39 | |||
| 40 | /* XXX I couldn't determine how to get block size. MSDN has a | ||
| 41 | * unhelpful hard-coded list here: | ||
| 42 | * http://support.microsoft.com/kb/140365 | ||
| 43 | * but this depends on the filesystem type, the size of the disk and | ||
| 44 | * the version of Windows. So this code assumes the disk is NTFS | ||
| 45 | * and the version of Windows is >= Win2K. | ||
| 46 | */ | ||
| 47 | if (total_number_of_bytes < UINT64_C(16) * 1024 * 1024 * 1024 * 1024) | ||
| 48 | buf->f_bsize = 4096; | ||
| 49 | else if (total_number_of_bytes < UINT64_C(32) * 1024 * 1024 * 1024 * 1024) | ||
| 50 | buf->f_bsize = 8192; | ||
| 51 | else if (total_number_of_bytes < UINT64_C(64) * 1024 * 1024 * 1024 * 1024) | ||
| 52 | buf->f_bsize = 16384; | ||
| 53 | else if (total_number_of_bytes < UINT64_C(128) * 1024 * 1024 * 1024 * 1024) | ||
| 54 | buf->f_bsize = 32768; | ||
| 55 | else | ||
| 56 | buf->f_bsize = 65536; | ||
| 57 | |||
| 58 | buf->f_type = fstypes[index_in_strings(FS_NAMES, fsname)+1]; | ||
| 59 | buf->f_frsize = buf->f_bsize; | ||
| 60 | buf->f_blocks = total_number_of_bytes / buf->f_bsize; | ||
| 61 | buf->f_bfree = total_number_of_free_bytes / buf->f_bsize; | ||
| 62 | buf->f_bavail = free_bytes_available / buf->f_bsize; | ||
| 63 | //buf->f_files = 0; | ||
| 64 | //buf->f_ffree = 0; | ||
| 65 | buf->f_fsid = serial; | ||
| 66 | //buf->f_flag = 0; | ||
| 67 | buf->f_namelen = namelen; | ||
| 68 | |||
| 69 | return 0; | ||
| 70 | } | ||
