std::tuple<std::string, std::string, unsigned long> ntfs::VolOps::getVolInfo() { std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> conv; wchar_t volNameBuf[MAX_PATH + 1] = { 0 }; wchar_t fsNameBuf[MAX_PATH + 1] = { 0 }; std::string volName; std::string fsName; unsigned long maxCompLen = 0; unsigned long serial = 0; unsigned long fsFlags = 0; if (!GetVolumeInformationByHandleW(vhandle.get(), volNameBuf, MAX_PATH, &serial, &maxCompLen, &fsFlags, fsNameBuf, MAX_PATH)) { throw VOL_API_INTERACTION_LASTERROR("Unable to query volume information!"); } volName = conv.to_bytes(volNameBuf); fsName = conv.to_bytes(fsNameBuf); return std::make_tuple(volName, fsName, maxCompLen); }
w_string_t *w_fstype(const char *path) { #ifdef __linux__ struct statfs sfs; const char *name = "unknown"; if (statfs(path, &sfs) == 0) { switch (sfs.f_type) { #ifdef CIFS_MAGIC_NUMBER case CIFS_MAGIC_NUMBER: name = "cifs"; break; #endif #ifdef NFS_SUPER_MAGIC case NFS_SUPER_MAGIC: name = "nfs"; break; #endif #ifdef SMB_SUPER_MAGIC case SMB_SUPER_MAGIC: name = "smb"; break; #endif default: name = "unknown"; } } return w_string_new(name); #elif STATVFS_HAS_FSTYPE_AS_STRING struct statvfs sfs; if (statvfs(path, &sfs) == 0) { #ifdef HAVE_STRUCT_STATVFS_F_FSTYPENAME return w_string_new(sfs.f_fstypename); #endif #ifdef HAVE_STRUCT_STATVFS_F_BASETYPE return w_string_new(sfs.f_basetype); #endif } #elif HAVE_STATFS struct statfs sfs; if (statfs(path, &sfs) == 0) { return w_string_new(sfs.f_fstypename); } #endif #ifdef _WIN32 WCHAR *wpath = w_utf8_to_win_unc(path, -1); w_string_t *fstype_name = NULL; if (wpath) { WCHAR fstype[MAX_PATH+1]; HANDLE h = CreateFileW(wpath, GENERIC_READ, FILE_SHARE_DELETE|FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); if (h) { if (GetVolumeInformationByHandleW(h, NULL, 0, 0, 0, 0, fstype, MAX_PATH+1)) { fstype_name = w_string_new_wchar(fstype, -1); } CloseHandle(h); } free(wpath); } if (fstype_name) { return fstype_name; } return w_string_new("unknown"); #else unused_parameter(path); return w_string_new("unknown"); #endif }
/* * create_sparse_file -- creates sparse file of given size */ static int create_sparse_file(const char *filename, size_t len) { /* create zero-length file */ DWORD create = Opt_force ? CREATE_ALWAYS : CREATE_NEW; HANDLE fh = CreateFileA(filename, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, create, FILE_ATTRIBUTE_NORMAL, NULL); if (fh == INVALID_HANDLE_VALUE) { out_err("CreateFile"); return -1; } SetLastError(0); /* check if sparse files are supported */ DWORD flags = 0; BOOL ret = GetVolumeInformationByHandleW(fh, NULL, 0, NULL, NULL, &flags, NULL, 0); if (ret == FALSE) { if (Opt_verbose || Opt_sparse) out_err("GetVolumeInformationByHandle"); } else if ((flags & FILE_SUPPORTS_SPARSE_FILES) == 0) { if (Opt_verbose || Opt_sparse) out_err("Volume does not support sparse files."); if (Opt_sparse) goto err; } /* mark file as sparse */ if (flags & FILE_SUPPORTS_SPARSE_FILES) { DWORD nbytes; ret = DeviceIoControl(fh, FSCTL_SET_SPARSE, NULL, 0, NULL, 0, &nbytes, NULL); if (ret == FALSE) { if (Opt_verbose || Opt_sparse) out_err("DeviceIoControl"); if (Opt_sparse) goto err; } } /* set file length */ LARGE_INTEGER llen; llen.QuadPart = len; DWORD ptr = SetFilePointerEx(fh, llen, NULL, FILE_BEGIN); if (ptr == INVALID_SET_FILE_POINTER) { out_err("SetFilePointerEx"); goto err; } ret = SetEndOfFile(fh); if (ret == FALSE) { out_err("SetEndOfFile"); goto err; } CloseHandle(fh); return 0; err: CloseHandle(fh); DeleteFileA(filename); return -1; }
int __cdecl wmain(int argc, PWSTR argv[]) { setlocale(LC_ALL, ""); for (int i = 1; i < argc; i++) { _putws(argv[i]); ATL::CHandle h(CreateFileW(argv[i], 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr, OPEN_EXISTING, 0, nullptr)); if (h == INVALID_HANDLE_VALUE) { pwerror(); h.Detach(); continue; } ULONG fs_flags; ATLENSURE(GetVolumeInformationByHandleW(h, nullptr, 0, nullptr, nullptr, &fs_flags, nullptr, 0)); if (!(fs_flags & FILE_SUPPORTS_BLOCK_REFCOUNTING)) { SetLastError(ERROR_NOT_CAPABLE); pwerror(); continue; } puts(" VCN Contiguous RefCount LCN"); STARTING_VCN_INPUT_BUFFER Vcn = {}; union { RETRIEVAL_POINTERS_AND_REFCOUNT_BUFFER refcount_buf; BYTE buf[offsetof(RETRIEVAL_POINTERS_AND_REFCOUNT_BUFFER, Extents) + sizeof(RETRIEVAL_POINTERS_AND_REFCOUNT_BUFFER::Extents) * 128]; }; ULONG junk; for (;;) { BOOL ret = DeviceIoControl(h, FSCTL_GET_RETRIEVAL_POINTERS_AND_REFCOUNT, &Vcn, sizeof Vcn, &refcount_buf, sizeof buf, &junk, nullptr); ULONG err = GetLastError(); if (ret || err == ERROR_MORE_DATA) { printf( "% 20llu % 20llu % 10lu % 20llu\n", refcount_buf.StartingVcn.QuadPart, refcount_buf.Extents[0].NextVcn.QuadPart - refcount_buf.StartingVcn.QuadPart, refcount_buf.Extents[0].ReferenceCount, refcount_buf.Extents[0].Lcn.QuadPart ); if (refcount_buf.ExtentCount > 1) { for (ULONG j = 1; j < refcount_buf.ExtentCount; j++) { printf( "% 20llu % 20llu % 10lu % 20llu\n", refcount_buf.Extents[j - 1].NextVcn.QuadPart, refcount_buf.Extents[j].NextVcn.QuadPart - refcount_buf.Extents[j - 1].NextVcn.QuadPart, refcount_buf.Extents[j].ReferenceCount, refcount_buf.Extents[j].Lcn.QuadPart ); } } Vcn.StartingVcn = refcount_buf.Extents[refcount_buf.ExtentCount - 1].NextVcn; } else { if (err != ERROR_HANDLE_EOF) { pwerror(); } break; } } } }