]> wimlib.net Git - wimlib/blobdiff - src/win32_replacements.c
read_wim_header(): Check return value of lseek()
[wimlib] / src / win32_replacements.c
index 41706382ad83b7c4c9fca3344071e52826011a49..3082255033b3123cec78f70d965df4cb16e9c39c 100644 (file)
 
 #include <errno.h>
 #include <pthread.h>
-#include <shlwapi.h> /* for PathMatchSpecW() */
+#include <io.h>        /* for _get_osfhandle()  */
+#include <fcntl.h>
+
 #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"
@@ -57,7 +58,7 @@ err:
        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)
 {
@@ -66,6 +67,17 @@ 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. */
@@ -177,51 +189,10 @@ err_set_errno:
        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;
@@ -299,61 +270,6 @@ pwrite(int fd, const void *buf, size_t count, off_t offset)
        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
@@ -366,6 +282,7 @@ win32_wglob(const wchar_t *pattern, int flags,
        HANDLE hFind;
        int ret;
        size_t nspaces;
+       int errno_save;
 
        const wchar_t *backslash, *end_slash;
        size_t prefix_len;
@@ -395,9 +312,7 @@ win32_wglob(const wchar_t *pattern, int flags,
                        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;
                }
        }
@@ -431,22 +346,21 @@ win32_wglob(const wchar_t *pattern, int flags,
        } 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;
 }
 
@@ -459,4 +373,33 @@ globfree(glob_t *pglob)
        FREE(pglob->gl_pathv);
 }
 
+/* Replacement for fopen(path, "a") that doesn't prevent other processes from
+ * reading the file  */
+FILE *
+win32_open_logfile(const wchar_t *path)
+{
+       HANDLE h;
+       int fd;
+       FILE *fp;
+
+       h = CreateFile(path, FILE_APPEND_DATA, FILE_SHARE_VALID_FLAGS,
+                      NULL, OPEN_ALWAYS, 0, NULL);
+       if (h == INVALID_HANDLE_VALUE)
+               return NULL;
+
+       fd = _open_osfhandle((intptr_t)h, O_APPEND);
+       if (fd < 0) {
+               CloseHandle(h);
+               return NULL;
+       }
+
+       fp = fdopen(fd, "a");
+       if (!fp) {
+               close(fd);
+               return NULL;
+       }
+
+       return fp;
+}
+
 #endif /* __WIN32__ */