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
GetProvider(IN PWCHAR FileSystem)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
AddProvider(IN PCUNICODE_STRING FileSystem,IN PWCHAR DllFile)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
InitializeFmIfsOnce(VOID)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
InitializeFmIfs(IN PVOID hinstDll,IN DWORD dwReason,IN PVOID reserved)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