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