+
+struct dll_spec ntdll_spec = {
+ .name = L"ntdll.dll",
+ .syms = {
+ DLL_SYM(RtlNtStatusToDosError, true),
+ DLL_SYM(NtQueryInformationFile, true),
+ DLL_SYM(NtQuerySecurityObject, true),
+ DLL_SYM(NtQueryDirectoryFile, true),
+ DLL_SYM(NtSetSecurityObject, true),
+ DLL_SYM(RtlCreateSystemVolumeInformationFolder, false),
+ {NULL, NULL},
+ },
+};
+
+struct dll_spec kernel32_spec = {
+ .name = L"kernel32.dll",
+ .syms = {
+ DLL_SYM(CreateSymbolicLinkW, false),
+ {NULL, NULL},
+ },
+};
+
+static int
+init_dll(struct dll_spec *spec)
+{
+ 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;
+}
+
+static void
+cleanup_dll(struct dll_spec *spec)
+{
+ const struct dll_sym *sym;
+
+ if (spec->handle) {
+ FreeLibrary(spec->handle);
+ spec->handle = NULL;
+
+ for_each_sym(sym, spec)
+ *(sym->func_ptr) = NULL;
+ }
+}