#include <errno.h>
#include <pthread.h>
-#include <shlwapi.h> /* for PathMatchSpecW() */
+#include <io.h> /* for _get_osfhandle() */
+
#include "wimlib/win32_common.h"
#include "wimlib/assert.h"
-#include "wimlib/file_io.h"
#include "wimlib/glob.h"
#include "wimlib/error.h"
#include "wimlib/util.h"
return -1;
}
-/* Use the Win32 API to get the number of processors */
+/* Use the Win32 API to get the number of processors. */
unsigned
win32_get_number_of_processors(void)
{
return sysinfo.dwNumberOfProcessors;
}
+/* Use the Win32 API to get the amount of available memory. */
+u64
+win32_get_avail_memory(void)
+{
+ MEMORYSTATUSEX status = {
+ .dwLength = sizeof(status),
+ };
+ GlobalMemoryStatusEx(&status);
+ return status.ullTotalPhys;
+}
+
/* Replacement for POSIX-2008 realpath(). Warning: partial functionality only
* (resolved_path must be NULL). Also I highly doubt that GetFullPathName
* really does the right thing under all circumstances. */
ret = GetFullPathNameW(path, ret, resolved_path, NULL);
if (!ret) {
err = GetLastError();
- free(resolved_path);
+ FREE(resolved_path);
resolved_path = NULL;
goto fail_win32;
}
return -1;
}
-/* Replacement for POSIX fnmatch() (partial functionality only) */
-int
-fnmatch(const wchar_t *pattern, const wchar_t *string, int flags)
-{
- if (PathMatchSpecW(string, pattern))
- return 0;
- else
- return FNM_NOMATCH;
-}
-
-/* truncate() replacement */
-int
-win32_truncate_replacement(const wchar_t *path, off_t size)
-{
- DWORD err = NO_ERROR;
- LARGE_INTEGER liOffset;
-
- HANDLE h = win32_open_existing_file(path, GENERIC_WRITE);
- if (h == INVALID_HANDLE_VALUE)
- goto fail;
-
- liOffset.QuadPart = size;
- if (!SetFilePointerEx(h, liOffset, NULL, FILE_BEGIN))
- goto fail_close_handle;
-
- if (!SetEndOfFile(h))
- goto fail_close_handle;
- CloseHandle(h);
- return 0;
-
-fail_close_handle:
- err = GetLastError();
- CloseHandle(h);
-fail:
- if (err == NO_ERROR)
- err = GetLastError();
- set_errno_from_win32_error(err);
- return -1;
-}
-
-
/* This really could be replaced with _wcserror_s, but this doesn't seem to
* actually be available in MSVCRT.DLL on Windows XP (perhaps it's statically
* linked in by Visual Studio...?). */
-extern int
+int
win32_strerror_r_replacement(int errnum, wchar_t *buf, size_t buflen)
{
static pthread_mutex_t strerror_lock = PTHREAD_MUTEX_INITIALIZER;
return do_pread_or_pwrite(fd, (void*)buf, count, offset, true);
}
-/* Dumb Windows implementation of writev(). It writes the vectors one at a
- * time. */
-ssize_t writev(int fd, const struct iovec *iov, int iovcnt)
-{
- ssize_t total_bytes_written = 0;
-
- if (iovcnt <= 0) {
- errno = EINVAL;
- return -1;
- }
- for (int i = 0; i < iovcnt; i++) {
- ssize_t bytes_written;
-
- bytes_written = write(fd, iov[i].iov_base, iov[i].iov_len);
- if (bytes_written >= 0)
- total_bytes_written += bytes_written;
- if (bytes_written != iov[i].iov_len) {
- if (total_bytes_written == 0)
- total_bytes_written = -1;
- break;
- }
- }
- return total_bytes_written;
-}
-
-int
-win32_get_file_and_vol_ids(const wchar_t *path, u64 *ino_ret, u64 *dev_ret)
-{
- HANDLE h;
- BY_HANDLE_FILE_INFORMATION file_info;
- int ret;
- DWORD err;
-
- h = win32_open_existing_file(path, FILE_READ_ATTRIBUTES);
- if (h == INVALID_HANDLE_VALUE) {
- ret = WIMLIB_ERR_OPEN;
- goto out;
- }
-
- if (!GetFileInformationByHandle(h, &file_info)) {
- ret = WIMLIB_ERR_STAT;
- } else {
- *ino_ret = ((u64)file_info.nFileIndexHigh << 32) |
- (u64)file_info.nFileIndexLow;
- *dev_ret = file_info.dwVolumeSerialNumber;
- ret = 0;
- }
- err = GetLastError();
- CloseHandle(h);
- SetLastError(err);
-out:
- set_errno_from_GetLastError();
- return ret;
-}
-
/* Replacement for glob() in Windows native builds that operates on wide
* characters. */
int
HANDLE hFind;
int ret;
size_t nspaces;
+ int errno_save;
const wchar_t *backslash, *end_slash;
size_t prefix_len;
errno = 0;
return GLOB_NOMATCH;
} else {
- /* The other possible error codes for FindFirstFile()
- * are undocumented. */
- errno = EIO;
+ set_errno_from_win32_error(err);
return GLOB_ABORTED;
}
}
} while (FindNextFileW(hFind, &dat));
err = GetLastError();
CloseHandle(hFind);
- if (err == ERROR_NO_MORE_FILES) {
- errno = 0;
- return 0;
- } else {
- /* Other possible error codes for FindNextFile() are
- * undocumented */
- errno = EIO;
+ if (err != ERROR_NO_MORE_FILES) {
+ set_errno_from_win32_error(err);
ret = GLOB_ABORTED;
goto fail_globfree;
}
+ return 0;
+
oom:
CloseHandle(hFind);
errno = ENOMEM;
ret = GLOB_NOSPACE;
fail_globfree:
+ errno_save = errno;
globfree(pglob);
+ errno = errno_save;
return ret;
}
{
size_t i;
for (i = 0; i < pglob->gl_pathc; i++)
- free(pglob->gl_pathv[i]);
- free(pglob->gl_pathv);
+ FREE(pglob->gl_pathv[i]);
+ FREE(pglob->gl_pathv);
}
#endif /* __WIN32__ */