/* Pointers to dynamically loaded functions */
-/* ntdll.dll */
-
-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,
- 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_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);
-
-static 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);
-
-static NTSTATUS (WINAPI *func_NtWaitForSingleObject) (HANDLE Handle,
- BOOLEAN Alertable,
- PLARGE_INTEGER Timeout);
-
-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,
static bool acquired_privileges = false;
-struct dll_sym {
- void **func_ptr;
- const char *name;
- bool required;
-};
-
-#define DLL_SYM(name, required) { (void **)&func_##name, #name, required }
-
-#define for_each_sym(sym, spec) \
- for ((sym) = (spec)->syms; (sym)->name; (sym)++)
-
-struct dll_spec {
- const wchar_t *name;
- HMODULE handle;
- const struct dll_sym syms[];
-};
-
-struct dll_spec ntdll_spec = {
- .name = L"ntdll.dll",
- .syms = {
- 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(NtWaitForSingleObject, true),
- DLL_SYM(NtClose, true),
- DLL_SYM(RtlNtStatusToDosError, true),
- DLL_SYM(RtlCreateSystemVolumeInformationFolder, false),
- DLL_SYM(RtlDosPathNameToNtPathName_U, true),
- DLL_SYM(RtlDosPathNameToNtPathName_U_WithStatus, false), /* Not present on XP */
- {NULL, NULL},
- },
-};
+static HMODULE ntdll_handle = NULL;
static int
-init_dll(struct dll_spec *spec)
+init_ntdll(void)
{
- const struct dll_sym *sym;
- void *addr;
-
- if (!spec->handle)
- spec->handle = LoadLibrary(spec->name);
- if (!spec->handle) {
- for_each_sym(sym, spec) {
- if (sym->required) {
- ERROR("%ls could not be loaded!", spec->name);
- return WIMLIB_ERR_UNSUPPORTED;
- }
- }
- return 0;
- }
- for_each_sym(sym, spec) {
- addr = (void *)GetProcAddress(spec->handle, sym->name);
- if (addr) {
- *(sym->func_ptr) = addr;
- } else if (sym->required) {
- ERROR("Can't find %s in %ls", sym->name, spec->name);
- return WIMLIB_ERR_UNSUPPORTED;
- }
- }
- return 0;
-}
+ ntdll_handle = LoadLibrary(L"ntdll.dll");
-static void
-cleanup_dll(struct dll_spec *spec)
-{
- const struct dll_sym *sym;
+ if (!ntdll_handle) {
+ ERROR("Unable to load ntdll.dll");
+ return WIMLIB_ERR_UNSUPPORTED;
+ }
- if (spec->handle) {
- FreeLibrary(spec->handle);
- spec->handle = NULL;
+ func_RtlDosPathNameToNtPathName_U_WithStatus =
+ (void *)GetProcAddress(ntdll_handle,
+ "RtlDosPathNameToNtPathName_U_WithStatus");
- for_each_sym(sym, spec)
- *(sym->func_ptr) = NULL;
- }
+ func_RtlCreateSystemVolumeInformationFolder =
+ (void *)GetProcAddress(ntdll_handle,
+ "RtlCreateSystemVolumeInformationFolder");
+ return 0;
}
/* One-time initialization for Windows capture/apply code. */
acquired_privileges = true;
}
- ret = init_dll(&ntdll_spec);
+ ret = init_ntdll();
if (ret)
goto out_drop_privs;
if (acquired_privileges)
win32_release_capture_and_apply_privileges();
- cleanup_dll(&ntdll_spec);
+ FreeLibrary(ntdll_handle);
+ ntdll_handle = NULL;
}
/*
nt_path,
NULL, NULL);
} else {
- if ((*func_RtlDosPathNameToNtPathName_U)(win32_path, nt_path,
- NULL, NULL))
+ if (RtlDosPathNameToNtPathName_U(win32_path, nt_path, NULL, NULL))
status = STATUS_SUCCESS;
else
status = STATUS_NO_MEMORY;
ret = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS |
(is_ntstatus ? FORMAT_MESSAGE_FROM_HMODULE : 0),
- (is_ntstatus ? ntdll_spec.handle : NULL),
+ (is_ntstatus ? ntdll_handle : NULL),
code,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
&buf[n],
IO_STATUS_BLOCK iosb;
NTSTATUS status;
- status = (*func_NtFsControlFile)(h, NULL, NULL, NULL, &iosb, code,
- (void *)in, in_size,
- out, out_size_avail);
+ status = NtFsControlFile(h, NULL, NULL, NULL, &iosb, code,
+ (void *)in, in_size, out, out_size_avail);
if (status == STATUS_PENDING) {
/* Beware: this case is often encountered with remote
* filesystems, but rarely with local filesystems. */
- status = (*func_NtWaitForSingleObject)(h, FALSE, NULL);
+ status = NtWaitForSingleObject(h, FALSE, NULL);
if (NT_SUCCESS(status)) {
status = iosb.Status;
} else {