#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(NTSTATUS status)
+{
+ set_errno_from_win32_error((*func_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;
}
HANDLE
win32_open_existing_file(const wchar_t *path, DWORD dwDesiredAccess)
{
- return CreateFileW(path,
- dwDesiredAccess,
- FILE_SHARE_READ,
- NULL, /* lpSecurityAttributes */
- OPEN_EXISTING,
- FILE_FLAG_BACKUP_SEMANTICS |
- FILE_FLAG_OPEN_REPARSE_POINT,
- NULL /* hTemplateFile */);
-}
-
-HANDLE
-win32_open_file_data_only(const wchar_t *path)
-{
- return win32_open_existing_file(path, FILE_READ_DATA);
+ return CreateFile(path,
+ dwDesiredAccess,
+ FILE_SHARE_READ,
+ NULL, /* lpSecurityAttributes */
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS |
+ FILE_FLAG_OPEN_REPARSE_POINT,
+ NULL /* hTemplateFile */);
}
/* Pointers to functions that are not available on all targetted versions of
BOOL (WINAPI *win32func_FindNextStreamW)(HANDLE hFindStream,
LPVOID lpFindStreamData) = NULL;
+/* Vista and later */
+BOOL (WINAPI *win32func_CreateSymbolicLinkW)(const wchar_t *lpSymlinkFileName,
+ const wchar_t *lpTargetFileName,
+ DWORD dwFlags) = NULL;
+
+#ifdef WITH_NTDLL
+
+DWORD (WINAPI *func_RtlNtStatusToDosError)(NTSTATUS status);
+
+NTSTATUS (WINAPI *func_NtQueryInformationFile)(HANDLE FileHandle,
+ PIO_STATUS_BLOCK IoStatusBlock,
+ PVOID FileInformation,
+ ULONG Length,
+ FILE_INFORMATION_CLASS FileInformationClass);
+
+NTSTATUS (WINAPI *func_NtQuerySecurityObject)(HANDLE handle,
+ SECURITY_INFORMATION SecurityInformation,
+ PSECURITY_DESCRIPTOR SecurityDescriptor,
+ ULONG Length,
+ PULONG LengthNeeded);
+
+NTSTATUS (WINAPI *func_NtQueryDirectoryFile) (HANDLE FileHandle,
+ HANDLE Event,
+ PIO_APC_ROUTINE ApcRoutine,
+ PVOID ApcContext,
+ PIO_STATUS_BLOCK IoStatusBlock,
+ PVOID FileInformation,
+ ULONG Length,
+ FILE_INFORMATION_CLASS FileInformationClass,
+ BOOLEAN ReturnSingleEntry,
+ PUNICODE_STRING FileName,
+ BOOLEAN RestartScan);
+
+NTSTATUS (WINAPI *func_NtSetSecurityObject)(HANDLE Handle,
+ SECURITY_INFORMATION SecurityInformation,
+ PSECURITY_DESCRIPTOR SecurityDescriptor);
+
+#endif /* WITH_NTDLL */
+
static OSVERSIONINFO windows_version_info = {
.dwOSVersionInfoSize = sizeof(OSVERSIONINFO),
};
static HMODULE hKernel32 = NULL;
+#ifdef WITH_NTDLL
+static HMODULE hNtdll = NULL;
+#endif
+
static bool acquired_privileges = false;
bool
if (!win32func_FindNextStreamW)
win32func_FindFirstStreamW = NULL;
}
+ win32func_CreateSymbolicLinkW = (void*)GetProcAddress(hKernel32,
+ "CreateSymbolicLinkW");
+ }
+
+#ifdef WITH_NTDLL
+ if (hNtdll == NULL)
+ hNtdll = LoadLibrary(L"ntdll.dll");
+
+ if (hNtdll) {
+ func_RtlNtStatusToDosError =
+ (void*)GetProcAddress(hNtdll, "RtlNtStatusToDosError");
+ if (func_RtlNtStatusToDosError) {
+
+ func_NtQuerySecurityObject =
+ (void*)GetProcAddress(hNtdll, "NtQuerySecurityObject");
+
+ func_NtQueryDirectoryFile =
+ (void*)GetProcAddress(hNtdll, "NtQueryDirectoryFile");
+
+ func_NtQueryInformationFile =
+ (void*)GetProcAddress(hNtdll, "NtQueryInformationFile");
+
+ func_NtSetSecurityObject =
+ (void*)GetProcAddress(hNtdll, "NtSetSecurityObject");
+ }
}
+
+ DEBUG("FindFirstStreamW @ %p", win32func_FindFirstStreamW);
+ DEBUG("FindNextStreamW @ %p", win32func_FindNextStreamW);
+ DEBUG("CreateSymbolicLinkW @ %p", win32func_CreateSymbolicLinkW);
+ DEBUG("RtlNtStatusToDosError @ %p", func_RtlNtStatusToDosError);
+ DEBUG("NtQuerySecurityObject @ %p", func_NtQuerySecurityObject);
+ DEBUG("NtQueryDirectoryFile @ %p", func_NtQueryDirectoryFile);
+ DEBUG("NtQueryInformationFile @ %p", func_NtQueryInformationFile);
+ DEBUG("NtSetSecurityObject @ %p", func_NtSetSecurityObject);
+#endif
+
return 0;
insufficient_privileges:
FreeLibrary(hKernel32);
hKernel32 = NULL;
}
+#ifdef WITH_NTDLL
+ if (hNtdll != NULL) {
+ FreeLibrary(hNtdll);
+ hNtdll = NULL;
+ }
+#endif
}
#endif /* __WIN32__ */