Create a file in sparse mode
| 60 | |
| 61 | // Create a file in sparse mode |
| 62 | bool PlatformSpecific::CreateSparseFile(const CPath& name, uint64_t size) |
| 63 | { |
| 64 | DWORD dwReturnedBytes=0; |
| 65 | |
| 66 | HANDLE hd = CreateFileW(name.GetRaw().c_str(), |
| 67 | GENERIC_READ | GENERIC_WRITE, |
| 68 | 0, // share - not shareable |
| 69 | NULL, // security - not inheritable |
| 70 | CREATE_ALWAYS, |
| 71 | FILE_ATTRIBUTE_ARCHIVE, |
| 72 | NULL); |
| 73 | if (hd == INVALID_HANDLE_VALUE) { |
| 74 | AddDebugLogLineC(logPartFile, CFormat("converting %s to sparse failed (OPEN): %s ") % name % SystemError()); |
| 75 | return false; |
| 76 | } |
| 77 | |
| 78 | if (!DeviceIoControl(hd, FSCTL_SET_SPARSE, NULL, 0, NULL, 0, &dwReturnedBytes, NULL)) { |
| 79 | AddDebugLogLineC(logPartFile, CFormat("converting %s to sparse failed (SET_SPARSE): %s ") % name % SystemError()); |
| 80 | } else { |
| 81 | // FILE_ZERO_DATA_INFORMATION is not defined here |
| 82 | struct { |
| 83 | uint64 FileOffset; |
| 84 | uint64 BeyondFinalZero; |
| 85 | } fzdi; |
| 86 | fzdi.FileOffset = 0; |
| 87 | fzdi.BeyondFinalZero = size; |
| 88 | LARGE_INTEGER largo; |
| 89 | largo.QuadPart = size; |
| 90 | |
| 91 | // zero the data |
| 92 | if (!DeviceIoControl(hd, FSCTL_SET_ZERO_DATA, (LPVOID) &fzdi, sizeof(fzdi), NULL, 0, &dwReturnedBytes, NULL)) { |
| 93 | AddDebugLogLineC(logPartFile, CFormat("converting %s to sparse failed (ZERO): %s") % name % SystemError()); |
| 94 | } else if (!SetFilePointerEx(hd, largo, NULL, FILE_BEGIN) || !SetEndOfFile(hd)) { |
| 95 | AddDebugLogLineC(logPartFile, CFormat("converting %s to sparse failed (SEEK): %s") % name % SystemError()); |
| 96 | } |
| 97 | } |
| 98 | CloseHandle(hd); |
| 99 | return true; |
| 100 | } |
| 101 | |
| 102 | #else // non Windows systems don't need all this |
| 103 | #include "CFile.h" |
nothing calls this directly
no test coverage detected