#include "wimlib/assert.h"
#include "wimlib/glob.h"
#include "wimlib/error.h"
+#include "wimlib/timestamp.h"
#include "wimlib/util.h"
static int
p = tmpname;
p = wmempcpy(p, dstpath, dstlen);
p = wmempcpy(p, orig_suffix, ARRAY_LEN(orig_suffix));
- randomize_char_array_with_alnum(p, num_rand_chars);
+ get_random_alnum_chars(p, num_rand_chars);
p += num_rand_chars;
*p = L'\0';
}
return 0;
}
+#define MAX_IO_AMOUNT 1048576
+
static int
do_pread_or_pwrite(int fd, void *buf, size_t count, off_t offset,
bool is_pwrite)
{
HANDLE h;
LARGE_INTEGER orig_offset;
- DWORD bytes_read_or_written;
+ DWORD result = 0xFFFFFFFF;
LARGE_INTEGER relative_offset;
OVERLAPPED overlapped;
BOOL bret;
overlapped.OffsetHigh = offset >> 32;
/* Do the read or write at the specified offset */
+ count = min(count, MAX_IO_AMOUNT);
+ SetLastError(0);
if (is_pwrite)
- bret = WriteFile(h, buf, count, &bytes_read_or_written, &overlapped);
+ bret = WriteFile(h, buf, count, &result, &overlapped);
else
- bret = ReadFile(h, buf, count, &bytes_read_or_written, &overlapped);
+ bret = ReadFile(h, buf, count, &result, &overlapped);
if (!bret) {
err = GetLastError();
win32_error(err, L"Failed to %s %zu bytes at offset %"PRIu64,
goto error;
}
+ wimlib_assert(result <= count);
+
/* Restore the original position */
if (!SetFilePointerEx(h, orig_offset, NULL, FILE_BEGIN)) {
err = GetLastError();
goto error;
}
- return bytes_read_or_written;
+ return result;
error:
if (err)
* offset, so it is not safe to use with readers/writers on the same file
* descriptor. */
ssize_t
-pread(int fd, void *buf, size_t count, off_t offset)
+win32_pread(int fd, void *buf, size_t count, off_t offset)
{
return do_pread_or_pwrite(fd, buf, count, offset, false);
}
* offset, so it is not safe to use with readers/writers on the same file
* descriptor. */
ssize_t
-pwrite(int fd, const void *buf, size_t count, off_t offset)
+win32_pwrite(int fd, const void *buf, size_t count, off_t offset)
{
return do_pread_or_pwrite(fd, (void*)buf, count, offset, true);
}
+/* Replacement for read() which doesn't hide the Win32 error code */
+ssize_t
+win32_read(int fd, void *buf, size_t count)
+{
+ HANDLE h = (HANDLE)_get_osfhandle(fd);
+ DWORD result = 0xFFFFFFFF;
+
+ if (h == INVALID_HANDLE_VALUE)
+ return -1;
+
+ count = min(count, MAX_IO_AMOUNT);
+ SetLastError(0);
+ if (!ReadFile(h, buf, count, &result, NULL)) {
+ DWORD err = GetLastError();
+ win32_error(err,
+ L"Error reading %zu bytes from fd %d", count, fd);
+ set_errno_from_win32_error(err);
+ return -1;
+ }
+
+ wimlib_assert(result <= count);
+ return result;
+}
+
+/* Replacement for write() which doesn't hide the Win32 error code */
+ssize_t
+win32_write(int fd, const void *buf, size_t count)
+{
+ HANDLE h = (HANDLE)_get_osfhandle(fd);
+ DWORD result = 0xFFFFFFFF;
+
+ if (h == INVALID_HANDLE_VALUE)
+ return -1;
+
+ count = min(count, MAX_IO_AMOUNT);
+ SetLastError(0);
+ if (!WriteFile(h, buf, count, &result, NULL)) {
+ DWORD err = GetLastError();
+ win32_error(err,
+ L"Error writing %zu bytes to fd %d", count, fd);
+ set_errno_from_win32_error(err);
+ return -1;
+ }
+
+ wimlib_assert(result <= count);
+ return result;
+}
+
/* Replacement for glob() in Windows native builds that operates on wide
* characters. */
int
return fp;
}
+#define RtlGenRandom SystemFunction036
+BOOLEAN WINAPI RtlGenRandom(PVOID RandomBuffer, ULONG RandomBufferLength);
+
+/*
+ * Generate @n cryptographically secure random bytes (thread-safe)
+ *
+ * This is the Windows version. It uses RtlGenRandom() (actually called
+ * SystemFunction036) from advapi32.dll.
+ */
+void
+get_random_bytes(void *p, size_t n)
+{
+ while (n != 0) {
+ u32 count = min(n, UINT32_MAX);
+
+ if (!RtlGenRandom(p, count)) {
+ win32_error(GetLastError(),
+ L"RtlGenRandom() failed (count=%u)", count);
+ wimlib_assert(0);
+ count = 0;
+ }
+ p += count;
+ n -= count;
+ }
+}
+
+/* Retrieve the current time as a WIM timestamp. */
+u64
+now_as_wim_timestamp(void)
+{
+ FILETIME ft;
+
+ GetSystemTimeAsFileTime(&ft);
+
+ return ((u64)ft.dwHighDateTime << 32) | ft.dwLowDateTime;
+}
+
#endif /* __WIN32__ */