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->Chkdsk = (PULIB_CHKDSK)GetProcAddress(hMod, "Chkdsk"); 70 //Provider->ChkdskEx = (PULIB_CHKDSKEX)GetProcAddress(hMod, "ChkdskEx"); 71 //Provider->Extend = (PULIB_EXTEND)GetProcAddress(hMod, "Extend"); 72 Provider->Format = (PULIB_FORMAT)GetProcAddress(hMod, "Format"); 73 //Provider->FormatEx = (PULIB_FORMATEX)GetProcAddress(hMod, "FormatEx"); 74 75 RtlCopyMemory(Provider->Name, FileSystem->Buffer, FileSystem->Length); 76 77 InsertTailList(&ProviderListHead, &Provider->ListEntry); 78 ret = TRUE; 79 80 cleanup: 81 if (!ret) 82 { 83 if (hMod) 84 FreeLibrary(hMod); 85 if (Provider) 86 RtlFreeHeap(RtlGetProcessHeap(), 0, Provider); 87 } 88 return ret; 89 } 90 91 static 92 BOOLEAN 93 InitializeFmIfsOnce(VOID) 94 { 95 OBJECT_ATTRIBUTES ObjectAttributes; 96 UNICODE_STRING RegistryPath 97 = RTL_CONSTANT_STRING(L"\\REGISTRY\\Machine\\SOFTWARE\\ReactOS\\ReactOS\\CurrentVersion\\IFS"); 98 HANDLE hKey = NULL; 99 PKEY_VALUE_FULL_INFORMATION Buffer; 100 ULONG BufferSize = sizeof(KEY_VALUE_FULL_INFORMATION) + MAX_PATH; 101 ULONG RequiredSize; 102 ULONG i = 0; 103 UNICODE_STRING Name; 104 UNICODE_STRING Data; 105 NTSTATUS Status; 106 107 InitializeListHead(&ProviderListHead); 108 109 /* Read IFS providers from HKLM\SOFTWARE\ReactOS\ReactOS\CurrentVersion\IFS */ 110 InitializeObjectAttributes(&ObjectAttributes, &RegistryPath, 0, NULL, NULL); 111 Status = NtOpenKey(&hKey, KEY_QUERY_VALUE, &ObjectAttributes); 112 if (Status == STATUS_OBJECT_NAME_NOT_FOUND) 113 return TRUE; 114 else if (!NT_SUCCESS(Status)) 115 return FALSE; 116 117 Buffer = (PKEY_VALUE_FULL_INFORMATION)RtlAllocateHeap( 118 RtlGetProcessHeap(), 119 0, 120 BufferSize); 121 if (!Buffer) 122 { 123 NtClose(hKey); 124 return FALSE; 125 } 126 127 while (TRUE) 128 { 129 Status = NtEnumerateValueKey( 130 hKey, 131 i++, 132 KeyValueFullInformation, 133 Buffer, 134 BufferSize, 135 &RequiredSize); 136 if (Status == STATUS_BUFFER_OVERFLOW) 137 continue; 138 else if (!NT_SUCCESS(Status)) 139 break; 140 else if (Buffer->Type != REG_SZ) 141 continue; 142 143 Name.Length = Name.MaximumLength = Buffer->NameLength; 144 Name.Buffer = Buffer->Name; 145 Data.Length = Data.MaximumLength = Buffer->DataLength; 146 Data.Buffer = (PWCHAR)((ULONG_PTR)Buffer + Buffer->DataOffset); 147 if (Data.Length > sizeof(WCHAR) && Data.Buffer[Data.Length / sizeof(WCHAR) - 1] == UNICODE_NULL) 148 Data.Length -= sizeof(WCHAR); 149 150 AddProvider(&Name, Data.Buffer); 151 } 152 153 NtClose(hKey); 154 RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer); 155 return TRUE; 156 } 157 158 /* FMIFS.8 */ 159 BOOLEAN 160 NTAPI 161 InitializeFmIfs( 162 IN PVOID hinstDll, 163 IN DWORD dwReason, 164 IN PVOID reserved) 165 { 166 switch (dwReason) 167 { 168 case DLL_PROCESS_ATTACH: 169 if (FmIfsInitialized == FALSE) 170 { 171 if (InitializeFmIfsOnce() == FALSE) 172 return FALSE; 173 174 FmIfsInitialized = TRUE; 175 } 176 break; 177 178 case DLL_THREAD_ATTACH: 179 break; 180 181 case DLL_THREAD_DETACH: 182 break; 183 184 case DLL_PROCESS_DETACH: 185 break; 186 } 187 188 return TRUE; 189 } 190 191 /* EOF */ 192