1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: File Management IFS Utility functions 4 * FILE: reactos/dll/win32/fmifs/init.c 5 * PURPOSE: Initialisation 6 * 7 * PROGRAMMERS: Emanuele Aliberti 8 * Herv� Poussineau (hpoussin@reactos.org) 9 */ 10 11 #include "precomp.h" 12 13 #include <winreg.h> 14 15 #define NTOS_MODE_USER 16 #include <ndk/cmfuncs.h> 17 #include <ndk/obfuncs.h> 18 19 static BOOLEAN FmIfsInitialized = FALSE; 20 LIST_ENTRY ProviderListHead; 21 22 PIFS_PROVIDER 23 GetProvider( 24 IN PWCHAR FileSystem) 25 { 26 PLIST_ENTRY ListEntry; 27 PIFS_PROVIDER Provider; 28 29 ListEntry = ProviderListHead.Flink; 30 while (ListEntry != &ProviderListHead) 31 { 32 Provider = CONTAINING_RECORD(ListEntry, IFS_PROVIDER, ListEntry); 33 if (_wcsicmp(Provider->Name, FileSystem) == 0) 34 return Provider; 35 ListEntry = ListEntry->Flink; 36 } 37 38 /* Provider not found */ 39 return NULL; 40 } 41 42 43 static 44 BOOLEAN 45 AddProvider( 46 IN PCUNICODE_STRING FileSystem, 47 IN PWCHAR DllFile) 48 { 49 PIFS_PROVIDER Provider = NULL; 50 ULONG RequiredSize; 51 HMODULE hMod = NULL; 52 BOOLEAN ret = FALSE; 53 54 hMod = LoadLibraryW(DllFile); 55 if (!hMod) 56 goto cleanup; 57 58 RequiredSize = FIELD_OFFSET(IFS_PROVIDER, Name) 59 + FileSystem->Length + sizeof(UNICODE_NULL); 60 Provider = (PIFS_PROVIDER)RtlAllocateHeap( 61 RtlGetProcessHeap(), 62 0, 63 RequiredSize); 64 if (!Provider) 65 goto cleanup; 66 RtlZeroMemory(Provider, RequiredSize); 67 68 /* Get function pointers */ 69 Provider->ChkdskEx = (CHKDSKEX)GetProcAddress(hMod, "ChkdskEx"); 70 //Provider->Extend = (EXTEND)GetProcAddress(hMod, "Extend"); 71 Provider->FormatEx = (FORMATEX)GetProcAddress(hMod, "FormatEx"); 72 73 RtlCopyMemory(Provider->Name, FileSystem->Buffer, FileSystem->Length); 74 75 InsertTailList(&ProviderListHead, &Provider->ListEntry); 76 ret = TRUE; 77 78 cleanup: 79 if (!ret) 80 { 81 if (hMod) 82 FreeLibrary(hMod); 83 if (Provider) 84 RtlFreeHeap(RtlGetProcessHeap(), 0, Provider); 85 } 86 return ret; 87 } 88 89 static 90 BOOLEAN 91 InitializeFmIfsOnce(VOID) 92 { 93 OBJECT_ATTRIBUTES ObjectAttributes; 94 UNICODE_STRING RegistryPath 95 = RTL_CONSTANT_STRING(L"\\REGISTRY\\Machine\\SOFTWARE\\ReactOS\\ReactOS\\CurrentVersion\\IFS"); 96 HANDLE hKey = NULL; 97 PKEY_VALUE_FULL_INFORMATION Buffer; 98 ULONG BufferSize = sizeof(KEY_VALUE_FULL_INFORMATION) + MAX_PATH; 99 ULONG RequiredSize; 100 ULONG i = 0; 101 UNICODE_STRING Name; 102 UNICODE_STRING Data; 103 NTSTATUS Status; 104 105 InitializeListHead(&ProviderListHead); 106 107 /* Read IFS providers from HKLM\SOFTWARE\ReactOS\ReactOS\CurrentVersion\IFS */ 108 InitializeObjectAttributes(&ObjectAttributes, &RegistryPath, 0, NULL, NULL); 109 Status = NtOpenKey(&hKey, KEY_QUERY_VALUE, &ObjectAttributes); 110 if (Status == STATUS_OBJECT_NAME_NOT_FOUND) 111 return TRUE; 112 else if (!NT_SUCCESS(Status)) 113 return FALSE; 114 115 Buffer = (PKEY_VALUE_FULL_INFORMATION)RtlAllocateHeap( 116 RtlGetProcessHeap(), 117 0, 118 BufferSize); 119 if (!Buffer) 120 { 121 NtClose(hKey); 122 return FALSE; 123 } 124 125 while (TRUE) 126 { 127 Status = NtEnumerateValueKey( 128 hKey, 129 i++, 130 KeyValueFullInformation, 131 Buffer, 132 BufferSize, 133 &RequiredSize); 134 if (Status == STATUS_BUFFER_OVERFLOW) 135 continue; 136 else if (!NT_SUCCESS(Status)) 137 break; 138 else if (Buffer->Type != REG_SZ) 139 continue; 140 141 Name.Length = Name.MaximumLength = Buffer->NameLength; 142 Name.Buffer = Buffer->Name; 143 Data.Length = Data.MaximumLength = Buffer->DataLength; 144 Data.Buffer = (PWCHAR)((ULONG_PTR)Buffer + Buffer->DataOffset); 145 if (Data.Length > sizeof(WCHAR) && Data.Buffer[Data.Length / sizeof(WCHAR) - 1] == UNICODE_NULL) 146 Data.Length -= sizeof(WCHAR); 147 148 AddProvider(&Name, Data.Buffer); 149 } 150 151 NtClose(hKey); 152 RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer); 153 return TRUE; 154 } 155 156 /* FMIFS.8 */ 157 BOOLEAN 158 NTAPI 159 InitializeFmIfs( 160 IN PVOID hinstDll, 161 IN DWORD dwReason, 162 IN PVOID reserved) 163 { 164 switch (dwReason) 165 { 166 case DLL_PROCESS_ATTACH: 167 if (FmIfsInitialized == FALSE) 168 { 169 if (InitializeFmIfsOnce() == FALSE) 170 return FALSE; 171 172 FmIfsInitialized = TRUE; 173 } 174 break; 175 176 case DLL_THREAD_ATTACH: 177 break; 178 179 case DLL_THREAD_DETACH: 180 break; 181 182 case DLL_PROCESS_DETACH: 183 break; 184 } 185 186 return TRUE; 187 } 188 189 /* EOF */ 190