#include <errno.h>
-#include "wimlib/win32_common.h"
+#ifdef WITH_NTDLL
+# include <winternl.h>
+#endif
+#include "wimlib/win32_common.h"
#include "wimlib/assert.h"
#include "wimlib/error.h"
#include "wimlib/util.h"
-#ifdef ENABLE_ERROR_MESSAGES
-void
-win32_error(DWORD err_code)
-{
- wchar_t *buffer;
- DWORD nchars;
- nchars = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_ALLOCATE_BUFFER,
- NULL, err_code, 0,
- (wchar_t*)&buffer, 0, NULL);
- if (nchars == 0) {
- ERROR("Error printing error message! "
- "Computer will self-destruct in 3 seconds.");
- } else {
- ERROR("Win32 error: %ls", buffer);
- LocalFree(buffer);
- }
-}
-#endif /* ENABLE_ERROR_MESSAGES */
-
-int
+static int
win32_error_to_errno(DWORD err_code)
{
/* This mapping is that used in Cygwin.
}
}
+
+void
+set_errno_from_win32_error(DWORD err)
+{
+ errno = win32_error_to_errno(err);
+}
+
void
set_errno_from_GetLastError(void)
{
- errno = win32_error_to_errno(GetLastError());
+ set_errno_from_win32_error(GetLastError());
+}
+
+#ifdef WITH_NTDLL
+void
+set_errno_from_nt_status(DWORD status)
+{
+ set_errno_from_win32_error(RtlNtStatusToDosError(status));
}
+#endif
/* Given a Windows-style path, return the number of characters of the prefix
* that specify the path to the root directory of a drive, or return 0 if the
filesystem_name, /* lpFileSystemNameBuffer */
ARRAY_LEN(filesystem_name)); /* nFileSystemNameSize */
if (!bret) {
- DWORD err = GetLastError();
- WARNING("Failed to get volume information for path \"%ls\"", path);
- win32_error(err);
+ set_errno_from_GetLastError();
+ WARNING_WITH_ERRNO("Failed to get volume information for "
+ "path \"%ls\"", path);
vol_flags = 0xffffffff;
goto out;
}
return ret;
}
-static void
+static bool
win32_modify_capture_privileges(bool enable)
{
- win32_modify_privilege(SE_BACKUP_NAME, enable);
- win32_modify_privilege(SE_SECURITY_NAME, enable);
+ return win32_modify_privilege(SE_BACKUP_NAME, enable)
+ && win32_modify_privilege(SE_SECURITY_NAME, enable);
}
-static void
+static bool
win32_modify_apply_privileges(bool enable)
{
- win32_modify_privilege(SE_RESTORE_NAME, enable);
- win32_modify_privilege(SE_SECURITY_NAME, enable);
- win32_modify_privilege(SE_TAKE_OWNERSHIP_NAME, enable);
-}
-
-static void
-win32_modify_capture_and_apply_privileges(bool enable)
-{
- win32_modify_capture_privileges(enable);
- win32_modify_apply_privileges(enable);
-}
-
-static void
-win32_acquire_capture_and_apply_privileges(void)
-{
- win32_modify_capture_and_apply_privileges(true);
+ return win32_modify_privilege(SE_RESTORE_NAME, enable)
+ && win32_modify_privilege(SE_SECURITY_NAME, enable)
+ && win32_modify_privilege(SE_TAKE_OWNERSHIP_NAME, enable);
}
static void
win32_release_capture_and_apply_privileges(void)
{
- win32_modify_capture_and_apply_privileges(false);
+ win32_modify_capture_privileges(false);
+ win32_modify_apply_privileges(false);
}
HANDLE
return win32_open_existing_file(path, FILE_READ_DATA);
}
+#ifndef WITH_NTDLL
/* Pointers to functions that are not available on all targetted versions of
* Windows (XP and later). NOTE: The WINAPI annotations seem to be important; I
* assume it specifies a certain calling convention. */
/* Vista and later */
BOOL (WINAPI *win32func_FindNextStreamW)(HANDLE hFindStream,
LPVOID lpFindStreamData) = NULL;
+#endif /* !WITH_NTDLL */
+
+/* Vista and later */
+BOOL (WINAPI *win32func_CreateSymbolicLinkW)(const wchar_t *lpSymlinkFileName,
+ const wchar_t *lpTargetFileName,
+ DWORD dwFlags) = NULL;
static OSVERSIONINFO windows_version_info = {
.dwOSVersionInfoSize = sizeof(OSVERSIONINFO),
}
/* One-time initialization for Windows capture/apply code. */
-void
+int
win32_global_init(int init_flags)
{
/* Try to acquire useful privileges. */
if (!(init_flags & WIMLIB_INIT_FLAG_DONT_ACQUIRE_PRIVILEGES)) {
- win32_acquire_capture_and_apply_privileges();
+ if (!win32_modify_capture_privileges(true))
+ if (init_flags & WIMLIB_INIT_FLAG_STRICT_CAPTURE_PRIVILEGES)
+ goto insufficient_privileges;
+ if (!win32_modify_apply_privileges(true))
+ if (init_flags & WIMLIB_INIT_FLAG_STRICT_APPLY_PRIVILEGES)
+ goto insufficient_privileges;
acquired_privileges = true;
}
hKernel32 = LoadLibrary(L"Kernel32.dll");
if (hKernel32) {
+ #ifndef WITH_NTDLL
win32func_FindFirstStreamW = (void*)GetProcAddress(hKernel32,
"FindFirstStreamW");
if (win32func_FindFirstStreamW) {
if (!win32func_FindNextStreamW)
win32func_FindFirstStreamW = NULL;
}
+ #endif /* !WITH_NTDLL */
+ win32func_CreateSymbolicLinkW = (void*)GetProcAddress(hKernel32,
+ "CreateSymbolicLinkW");
}
+ return 0;
+
+insufficient_privileges:
+ win32_release_capture_and_apply_privileges();
+ return WIMLIB_ERR_INSUFFICIENT_PRIVILEGES;
}
void