[NTOSKRNL] Drop the useless Timestamp field
[reactos.git] / dll / win32 / fmifs / init.c
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 */