X-Git-Url: https://wimlib.net/git/?p=wimlib;a=blobdiff_plain;f=src%2Fwin32_common.c;h=7016fe2a6c3d5644f29cdac1f995b9398b8486ed;hp=fa890c1c2b5cc4c09c4a205be5d6f35d67be3c34;hb=fe548d263d477a745dfa5057f540cc5c35ecce89;hpb=0b7ce8c18139e5883e11090e4974d41d2f03bd49 diff --git a/src/win32_common.c b/src/win32_common.c index fa890c1c..7016fe2a 100644 --- a/src/win32_common.c +++ b/src/win32_common.c @@ -29,10 +29,7 @@ #include -#include - #include "wimlib/win32_common.h" -#include "wimlib/assert.h" #include "wimlib/error.h" #include "wimlib/util.h" @@ -305,7 +302,6 @@ win32_error_to_errno(DWORD err_code) } } - void set_errno_from_win32_error(DWORD err) { @@ -324,126 +320,6 @@ set_errno_from_nt_status(NTSTATUS status) set_errno_from_win32_error((*func_RtlNtStatusToDosError)(status)); } -/* 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 - * drive is relative (or at least on the current drive, in the case of - * absolute-but-not-really-absolute paths like \Windows\System32) */ -static size_t -win32_path_drive_spec_len(const wchar_t *path) -{ - size_t n = 0; - - if (!wcsncmp(path, L"\\\\?\\", 4)) { - /* \\?\-prefixed path. Check for following drive letter and - * path separator. */ - if (path[4] != L'\0' && path[5] == L':' && - is_any_path_separator(path[6])) - n = 7; - } else { - /* Not a \\?\-prefixed path. Check for an initial drive letter - * and path separator. */ - if (path[0] != L'\0' && path[1] == L':' && - is_any_path_separator(path[2])) - n = 3; - } - /* Include any additional path separators.*/ - if (n > 0) - while (is_any_path_separator(path[n])) - n++; - return n; -} - -bool -win32_path_is_root_of_drive(const wchar_t *path) -{ - size_t drive_spec_len; - wchar_t full_path[32768]; - DWORD ret; - - ret = GetFullPathName(path, ARRAY_LEN(full_path), full_path, NULL); - if (ret > 0 && ret < ARRAY_LEN(full_path)) - path = full_path; - - /* Explicit drive letter and path separator? */ - drive_spec_len = win32_path_drive_spec_len(path); - if (drive_spec_len > 0 && path[drive_spec_len] == L'\0') - return true; - - /* All path separators? */ - for (const wchar_t *p = path; *p != L'\0'; p++) - if (!is_any_path_separator(*p)) - return false; - return true; -} - - -/* Given a path, which may not yet exist, get a set of flags that describe the - * features of the volume the path is on. */ -int -win32_get_vol_flags(const wchar_t *path, unsigned *vol_flags_ret, - bool *supports_SetFileShortName_ret) -{ - wchar_t *volume; - BOOL bret; - DWORD vol_flags; - size_t drive_spec_len; - wchar_t filesystem_name[MAX_PATH + 1]; - - if (supports_SetFileShortName_ret) - *supports_SetFileShortName_ret = false; - - drive_spec_len = win32_path_drive_spec_len(path); - - if (drive_spec_len == 0) - if (path[0] != L'\0' && path[1] == L':') /* Drive-relative path? */ - drive_spec_len = 2; - - if (drive_spec_len == 0) { - /* Path does not start with a drive letter; use the volume of - * the current working directory. */ - volume = NULL; - } else { - /* Path starts with a drive letter (or \\?\ followed by a drive - * letter); use it. */ - volume = alloca((drive_spec_len + 2) * sizeof(wchar_t)); - wmemcpy(volume, path, drive_spec_len); - /* Add trailing backslash in case this was a drive-relative - * path. */ - volume[drive_spec_len] = L'\\'; - volume[drive_spec_len + 1] = L'\0'; - } - bret = GetVolumeInformation( - volume, /* lpRootPathName */ - NULL, /* lpVolumeNameBuffer */ - 0, /* nVolumeNameSize */ - NULL, /* lpVolumeSerialNumber */ - NULL, /* lpMaximumComponentLength */ - &vol_flags, /* lpFileSystemFlags */ - filesystem_name, /* lpFileSystemNameBuffer */ - ARRAY_LEN(filesystem_name)); /* nFileSystemNameSize */ - if (!bret) { - set_errno_from_GetLastError(); - WARNING_WITH_ERRNO("Failed to get volume information for " - "path \"%ls\"", path); - vol_flags = 0xffffffff; - goto out; - } - - if (wcsstr(filesystem_name, L"NTFS")) { - /* FILE_SUPPORTS_HARD_LINKS is only supported on Windows 7 and later. - * Force it on anyway if filesystem is NTFS. */ - vol_flags |= FILE_SUPPORTS_HARD_LINKS; - - if (supports_SetFileShortName_ret) - *supports_SetFileShortName_ret = true; - } - -out: - DEBUG("using vol_flags = %x", vol_flags); - *vol_flags_ret = vol_flags; - return 0; -} - static bool win32_modify_privilege(const wchar_t *privilege, bool enable) { @@ -495,29 +371,48 @@ win32_release_capture_and_apply_privileges(void) win32_modify_apply_privileges(false); } -HANDLE -win32_open_existing_file(const wchar_t *path, DWORD dwDesiredAccess) -{ - return CreateFile(path, - dwDesiredAccess, - FILE_SHARE_READ, - NULL, /* lpSecurityAttributes */ - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS | - FILE_FLAG_OPEN_REPARSE_POINT, - NULL /* hTemplateFile */); -} - /* Pointers to dynamically loaded functions */ -/* kernel32.dll: Vista and later */ -BOOL (WINAPI *func_CreateSymbolicLinkW)(const wchar_t *lpSymlinkFileName, - const wchar_t *lpTargetFileName, - DWORD dwFlags); - /* ntdll.dll */ -DWORD (WINAPI *func_RtlNtStatusToDosError)(NTSTATUS status); +NTSTATUS (WINAPI *func_NtCreateFile)(PHANDLE FileHandle, + ACCESS_MASK DesiredAccess, + POBJECT_ATTRIBUTES ObjectAttributes, + PIO_STATUS_BLOCK IoStatusBlock, + PLARGE_INTEGER AllocationSize, + ULONG FileAttributes, + ULONG ShareAccess, + ULONG CreateDisposition, + ULONG CreateOptions, + PVOID EaBuffer, + ULONG EaLength); + +NTSTATUS (WINAPI *func_NtOpenFile) (PHANDLE FileHandle, + ACCESS_MASK DesiredAccess, + POBJECT_ATTRIBUTES ObjectAttributes, + PIO_STATUS_BLOCK IoStatusBlock, + ULONG ShareAccess, + ULONG OpenOptions); + +NTSTATUS (WINAPI *func_NtReadFile) (HANDLE FileHandle, + HANDLE Event, + PIO_APC_ROUTINE ApcRoutine, + PVOID ApcContext, + PIO_STATUS_BLOCK IoStatusBlock, + PVOID Buffer, + ULONG Length, + PLARGE_INTEGER ByteOffset, + PULONG Key); + +NTSTATUS (WINAPI *func_NtWriteFile) (HANDLE FileHandle, + HANDLE Event, + PIO_APC_ROUTINE ApcRoutine, + PVOID ApcContext, + PIO_STATUS_BLOCK IoStatusBlock, + PVOID Buffer, + ULONG Length, + PLARGE_INTEGER ByteOffset, + PULONG Key); NTSTATUS (WINAPI *func_NtQueryInformationFile)(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, @@ -543,10 +438,49 @@ NTSTATUS (WINAPI *func_NtQueryDirectoryFile) (HANDLE FileHandle, PUNICODE_STRING FileName, BOOLEAN RestartScan); +NTSTATUS (WINAPI *func_NtQueryVolumeInformationFile) (HANDLE FileHandle, + PIO_STATUS_BLOCK IoStatusBlock, + PVOID FsInformation, + ULONG Length, + FS_INFORMATION_CLASS FsInformationClass); + +NTSTATUS (WINAPI *func_NtSetInformationFile)(HANDLE FileHandle, + PIO_STATUS_BLOCK IoStatusBlock, + PVOID FileInformation, + ULONG Length, + FILE_INFORMATION_CLASS FileInformationClass); + NTSTATUS (WINAPI *func_NtSetSecurityObject)(HANDLE Handle, SECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR SecurityDescriptor); +NTSTATUS (WINAPI *func_NtFsControlFile) (HANDLE FileHandle, + HANDLE Event, + PIO_APC_ROUTINE ApcRoutine, + PVOID ApcContext, + PIO_STATUS_BLOCK IoStatusBlock, + ULONG FsControlCode, + PVOID InputBuffer, + ULONG InputBufferLength, + PVOID OutputBuffer, + ULONG OutputBufferLength); + +NTSTATUS (WINAPI *func_NtClose) (HANDLE Handle); + +DWORD (WINAPI *func_RtlNtStatusToDosError)(NTSTATUS status); + +BOOLEAN (WINAPI *func_RtlDosPathNameToNtPathName_U) + (IN PCWSTR DosName, + OUT PUNICODE_STRING NtName, + OUT PCWSTR *PartName, + OUT PRTL_RELATIVE_NAME_U RelativeName); + +NTSTATUS (WINAPI *func_RtlDosPathNameToNtPathName_U_WithStatus) + (IN PCWSTR DosName, + OUT PUNICODE_STRING NtName, + OUT PCWSTR *PartName, + OUT PRTL_RELATIVE_NAME_U RelativeName); + NTSTATUS (WINAPI *func_RtlCreateSystemVolumeInformationFolder) (PCUNICODE_STRING VolumeRootPath); @@ -584,20 +518,22 @@ struct dll_spec { struct dll_spec ntdll_spec = { .name = L"ntdll.dll", .syms = { - DLL_SYM(RtlNtStatusToDosError, true), + DLL_SYM(NtCreateFile, true), + DLL_SYM(NtOpenFile, true), + DLL_SYM(NtReadFile, true), + DLL_SYM(NtWriteFile, true), DLL_SYM(NtQueryInformationFile, true), DLL_SYM(NtQuerySecurityObject, true), DLL_SYM(NtQueryDirectoryFile, true), + DLL_SYM(NtQueryVolumeInformationFile, true), + DLL_SYM(NtSetInformationFile, true), DLL_SYM(NtSetSecurityObject, true), + DLL_SYM(NtFsControlFile, true), + DLL_SYM(NtClose, true), + DLL_SYM(RtlNtStatusToDosError, true), DLL_SYM(RtlCreateSystemVolumeInformationFolder, false), - {NULL, NULL}, - }, -}; - -struct dll_spec kernel32_spec = { - .name = L"kernel32.dll", - .syms = { - DLL_SYM(CreateSymbolicLinkW, false), + DLL_SYM(RtlDosPathNameToNtPathName_U, true), + DLL_SYM(RtlDosPathNameToNtPathName_U_WithStatus, false), /* Not present on XP */ {NULL, NULL}, }, }; @@ -666,19 +602,12 @@ win32_global_init(int init_flags) /* Get Windows version information. */ GetVersionEx(&windows_version_info); - /* Try to dynamically load some functions. */ - ret = init_dll(&kernel32_spec); - if (ret) - goto out_drop_privs; - ret = init_dll(&ntdll_spec); if (ret) - goto out_cleanup_kernel32; + goto out_drop_privs; return 0; -out_cleanup_kernel32: - cleanup_dll(&kernel32_spec); out_drop_privs: win32_release_capture_and_apply_privileges(); return ret; @@ -690,7 +619,6 @@ win32_global_cleanup(void) if (acquired_privileges) win32_release_capture_and_apply_privileges(); - cleanup_dll(&kernel32_spec); cleanup_dll(&ntdll_spec); }