xref: /reactos/dll/win32/fmifs/init.c (revision 8a978a17)
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