xref: /reactos/drivers/storage/mountmgr/mntmgr.h (revision 7e89227a)
1 #ifndef _MNTMGR_H_
2 #define _MNTMGR_H_
3 
4 #include <ntifs.h>
5 #include <mountdev.h>
6 #include <ntddvol.h>
7 #include <ntdddisk.h>
8 #include <wdmguid.h>
9 #include <ndk/psfuncs.h>
10 #include <ntdddisk.h>
11 #include <section_attribs.h>
12 
13 typedef struct _DEVICE_EXTENSION
14 {
15     PDEVICE_OBJECT DeviceObject;
16     PDRIVER_OBJECT DriverObject;
17     LIST_ENTRY DeviceListHead;
18     LIST_ENTRY OfflineDeviceListHead;
19     PVOID NotificationEntry;
20     KSEMAPHORE DeviceLock;
21     KSEMAPHORE RemoteDatabaseLock;
22     BOOLEAN AutomaticDriveLetter;
23     LIST_ENTRY IrpListHead;
24     ULONG EpicNumber;
25     LIST_ENTRY SavedLinksListHead;
26     BOOLEAN ProcessedSuggestions;
27     BOOLEAN NoAutoMount;
28     LIST_ENTRY WorkerQueueListHead;
29     KSEMAPHORE WorkerSemaphore;
30     LONG WorkerReferences;
31     KSPIN_LOCK WorkerLock;
32     LIST_ENTRY UniqueIdWorkerItemListHead;
33     PMOUNTDEV_UNIQUE_ID DriveLetterData;
34     UNICODE_STRING RegistryPath;
35     LONG WorkerThreadStatus;
36     LIST_ENTRY OnlineNotificationListHead;
37     ULONG OnlineNotificationWorkerActive;
38     ULONG OnlineNotificationCount;
39     KEVENT OnlineNotificationEvent;
40 } DEVICE_EXTENSION, *PDEVICE_EXTENSION;
41 
42 typedef struct _DEVICE_INFORMATION
43 {
44     LIST_ENTRY DeviceListEntry;
45     LIST_ENTRY SymbolicLinksListHead;
46     LIST_ENTRY ReplicatedUniqueIdsListHead;
47     LIST_ENTRY AssociatedDevicesHead;
48     UNICODE_STRING SymbolicName;
49     PMOUNTDEV_UNIQUE_ID UniqueId;
50     UNICODE_STRING DeviceName;
51     BOOLEAN KeepLinks;
52     UCHAR SuggestedDriveLetter;
53     BOOLEAN ManuallyRegistered;
54     BOOLEAN Removable;
55     BOOLEAN LetterAssigned;
56     BOOLEAN NeedsReconcile;
57     BOOLEAN NoDatabase;
58     BOOLEAN SkipNotifications;
59     ULONG Migrated;
60     LONG MountState;
61     PVOID TargetDeviceNotificationEntry;
62     PDEVICE_EXTENSION DeviceExtension;
63 } DEVICE_INFORMATION, *PDEVICE_INFORMATION;
64 
65 typedef struct _SYMLINK_INFORMATION
66 {
67     LIST_ENTRY SymbolicLinksListEntry;
68     UNICODE_STRING Name;
69     BOOLEAN Online;
70 } SYMLINK_INFORMATION, *PSYMLINK_INFORMATION;
71 
72 typedef struct _SAVED_LINK_INFORMATION
73 {
74     LIST_ENTRY SavedLinksListEntry;
75     LIST_ENTRY SymbolicLinksListHead;
76     PMOUNTDEV_UNIQUE_ID UniqueId;
77 } SAVED_LINK_INFORMATION, *PSAVED_LINK_INFORMATION;
78 
79 typedef struct _UNIQUE_ID_REPLICATE
80 {
81     LIST_ENTRY ReplicatedUniqueIdsListEntry;
82     PMOUNTDEV_UNIQUE_ID UniqueId;
83 } UNIQUE_ID_REPLICATE, *PUNIQUE_ID_REPLICATE;
84 
85 typedef struct _DATABASE_ENTRY
86 {
87     ULONG EntrySize;
88     ULONG EntryReferences;
89     USHORT SymbolicNameOffset;
90     USHORT SymbolicNameLength;
91     USHORT UniqueIdOffset;
92     USHORT UniqueIdLength;
93 } DATABASE_ENTRY, *PDATABASE_ENTRY;
94 
95 typedef struct _ASSOCIATED_DEVICE_ENTRY
96 {
97     LIST_ENTRY AssociatedDevicesEntry;
98     PDEVICE_INFORMATION DeviceInformation;
99     UNICODE_STRING String;
100 } ASSOCIATED_DEVICE_ENTRY, *PASSOCIATED_DEVICE_ENTRY;
101 
102 typedef struct _DEVICE_INFORMATION_ENTRY
103 {
104     LIST_ENTRY DeviceInformationEntry;
105     PDEVICE_INFORMATION DeviceInformation;
106 } DEVICE_INFORMATION_ENTRY, *PDEVICE_INFORMATION_ENTRY;
107 
108 typedef struct _ONLINE_NOTIFICATION_WORK_ITEM
109 {
110     WORK_QUEUE_ITEM WorkItem;
111     PDEVICE_EXTENSION DeviceExtension;
112     UNICODE_STRING SymbolicName;
113 } ONLINE_NOTIFICATION_WORK_ITEM, *PONLINE_NOTIFICATION_WORK_ITEM;
114 
115 typedef struct _RECONCILE_WORK_ITEM_CONTEXT
116 {
117     PDEVICE_EXTENSION DeviceExtension;
118     PDEVICE_INFORMATION DeviceInformation;
119 } RECONCILE_WORK_ITEM_CONTEXT, *PRECONCILE_WORK_ITEM_CONTEXT;
120 
121 typedef struct _RECONCILE_WORK_ITEM
122 {
123     LIST_ENTRY WorkerQueueListEntry;
124     PIO_WORKITEM WorkItem;
125     PWORKER_THREAD_ROUTINE WorkerRoutine;
126     PVOID Context;
127     RECONCILE_WORK_ITEM_CONTEXT;
128 } RECONCILE_WORK_ITEM, *PRECONCILE_WORK_ITEM;
129 
130 typedef struct _MIGRATE_WORK_ITEM
131 {
132     PIO_WORKITEM WorkItem;
133     PDEVICE_INFORMATION DeviceInformation;
134     PKEVENT Event;
135     NTSTATUS Status;
136     HANDLE Database;
137 } MIGRATE_WORK_ITEM, *PMIGRATE_WORK_ITEM;
138 
139 typedef struct _UNIQUE_ID_WORK_ITEM
140 {
141     LIST_ENTRY UniqueIdWorkerItemListEntry;
142     PIO_WORKITEM WorkItem;
143     PDEVICE_EXTENSION DeviceExtension;
144     PIRP Irp;
145     PVOID IrpBuffer;
146     PKEVENT Event;
147     UNICODE_STRING DeviceName;
148     ULONG IrpBufferLength;
149     ULONG StackSize;
150 } UNIQUE_ID_WORK_ITEM, *PUNIQUE_ID_WORK_ITEM;
151 
152 /* Memory allocation helpers */
153 #define AllocatePool(Size) ExAllocatePoolWithTag(PagedPool, Size, 'AtnM')
154 #define FreePool(P)        ExFreePoolWithTag(P, 'AtnM')
155 
156 /* Misc macros */
157 #define MAX(a, b)          ((a > b) ? a : b)
158 
159 #define LETTER_POSITION     0xC
160 #define COLON_POSITION      0xD
161 #define DRIVE_LETTER_LENGTH 0x1C
162 
163 /* mountmgr.c */
164 
165 extern UNICODE_STRING DosDevicesMount;
166 extern PDEVICE_OBJECT gdeviceObject;
167 extern UNICODE_STRING ReparseIndex;
168 extern UNICODE_STRING DeviceFloppy;
169 extern UNICODE_STRING DeviceMount;
170 extern UNICODE_STRING DeviceCdRom;
171 extern UNICODE_STRING SafeVolumes;
172 extern UNICODE_STRING DosDevices;
173 extern UNICODE_STRING DosGlobal;
174 extern UNICODE_STRING Global;
175 extern UNICODE_STRING Volume;
176 extern KEVENT UnloadEvent;
177 extern LONG Unloading;
178 
179 CODE_SEG("INIT")
180 DRIVER_INITIALIZE DriverEntry;
181 
182 _IRQL_requires_(PASSIVE_LEVEL)
183 NTSTATUS
184 MountMgrSendSyncDeviceIoCtl(
185     _In_ ULONG IoControlCode,
186     _In_ PDEVICE_OBJECT DeviceObject,
187     _In_reads_bytes_opt_(InputBufferLength) PVOID InputBuffer,
188     _In_ ULONG InputBufferLength,
189     _Out_writes_bytes_opt_(OutputBufferLength) PVOID OutputBuffer,
190     _In_ ULONG OutputBufferLength,
191     _In_opt_ PFILE_OBJECT FileObject);
192 
193 VOID
194 NTAPI
195 MountMgrCancel(
196     IN PDEVICE_OBJECT DeviceObject,
197     IN PIRP Irp
198 );
199 
200 NTSTATUS
201 MountMgrMountedDeviceArrival(
202     IN PDEVICE_EXTENSION Extension,
203     IN PUNICODE_STRING SymbolicName,
204     IN BOOLEAN FromVolume
205 );
206 
207 VOID
208 MountMgrMountedDeviceRemoval(
209     IN PDEVICE_EXTENSION Extension,
210     IN PUNICODE_STRING DeviceName
211 );
212 
213 NTSTATUS
214 FindDeviceInfo(
215     IN PDEVICE_EXTENSION DeviceExtension,
216     IN PUNICODE_STRING SymbolicName,
217     IN BOOLEAN DeviceNameGiven,
218     OUT PDEVICE_INFORMATION * DeviceInformation
219 );
220 
221 VOID
222 MountMgrFreeDeadDeviceInfo(
223     IN PDEVICE_INFORMATION DeviceInformation
224 );
225 
226 NTSTATUS
227 QueryDeviceInformation(
228     _In_ PUNICODE_STRING SymbolicName,
229     _Out_opt_ PUNICODE_STRING DeviceName,
230     _Out_opt_ PMOUNTDEV_UNIQUE_ID* UniqueId,
231     _Out_opt_ PBOOLEAN Removable,
232     _Out_opt_ PBOOLEAN GptDriveLetter,
233     _Out_opt_ PBOOLEAN HasGuid,
234     _Inout_opt_ LPGUID StableGuid,
235     _Out_opt_ PBOOLEAN IsFT);
236 
237 BOOLEAN
238 HasDriveLetter(
239     IN PDEVICE_INFORMATION DeviceInformation
240 );
241 
242 /* database.c */
243 
244 extern PWSTR DatabasePath;
245 extern PWSTR OfflinePath;
246 
247 VOID
248 ReconcileThisDatabaseWithMaster(
249     IN PDEVICE_EXTENSION DeviceExtension,
250     IN PDEVICE_INFORMATION DeviceInformation
251 );
252 
253 NTSTATUS
254 WaitForRemoteDatabaseSemaphore(
255     IN PDEVICE_EXTENSION DeviceExtension
256 );
257 
258 VOID
259 ReleaseRemoteDatabaseSemaphore(
260     IN PDEVICE_EXTENSION DeviceExtension
261 );
262 
263 VOID
264 ChangeRemoteDatabaseUniqueId(
265     IN PDEVICE_INFORMATION DeviceInformation,
266     IN PMOUNTDEV_UNIQUE_ID OldUniqueId,
267     IN PMOUNTDEV_UNIQUE_ID NewUniqueId
268 );
269 
270 VOID
271 ReconcileAllDatabasesWithMaster(
272     IN PDEVICE_EXTENSION DeviceExtension
273 );
274 
275 VOID
276 DeleteFromLocalDatabase(
277     IN PUNICODE_STRING SymbolicLink,
278     IN PMOUNTDEV_UNIQUE_ID UniqueId
279 );
280 
281 VOID
282 DeleteRegistryDriveLetter(
283     IN PMOUNTDEV_UNIQUE_ID UniqueId
284 );
285 
286 VOID
287 DeleteNoDriveLetterEntry(
288     IN PMOUNTDEV_UNIQUE_ID UniqueId
289 );
290 
291 NTSTATUS
292 QueryVolumeName(
293     IN HANDLE RootDirectory,
294     IN PFILE_REPARSE_POINT_INFORMATION ReparsePointInformation,
295     IN PUNICODE_STRING FileName OPTIONAL,
296     OUT PUNICODE_STRING SymbolicName,
297     OUT PUNICODE_STRING VolumeName
298 );
299 
300 HANDLE
301 OpenRemoteDatabase(
302     IN PDEVICE_INFORMATION DeviceInformation,
303     IN BOOLEAN MigrateDatabase
304 );
305 
306 PDATABASE_ENTRY
307 GetRemoteDatabaseEntry(
308     IN HANDLE Database,
309     IN LONG StartingOffset
310 );
311 
312 NTSTATUS
313 WriteRemoteDatabaseEntry(
314     IN HANDLE Database,
315     IN LONG Offset,
316     IN PDATABASE_ENTRY Entry
317 );
318 
319 NTSTATUS
320 CloseRemoteDatabase(
321     IN HANDLE Database
322 );
323 
324 NTSTATUS
325 AddRemoteDatabaseEntry(
326     IN HANDLE Database,
327     IN PDATABASE_ENTRY Entry
328 );
329 
330 NTSTATUS
331 DeleteRemoteDatabaseEntry(
332     IN HANDLE Database,
333     IN LONG StartingOffset
334 );
335 
336 VOID
337 NTAPI
338 ReconcileThisDatabaseWithMasterWorker(
339     IN PVOID Parameter
340 );
341 
342 /* device.c */
343 
344 DRIVER_DISPATCH MountMgrDeviceControl;
345 
346 /* notify.c */
347 VOID
348 IssueUniqueIdChangeNotifyWorker(
349     IN PUNIQUE_ID_WORK_ITEM WorkItem,
350     IN PMOUNTDEV_UNIQUE_ID UniqueId
351 );
352 
353 VOID
354 WaitForOnlinesToComplete(
355     IN PDEVICE_EXTENSION DeviceExtension
356 );
357 
358 VOID
359 RegisterForTargetDeviceNotification(
360     IN PDEVICE_EXTENSION DeviceExtension,
361     IN PDEVICE_INFORMATION DeviceInformation
362 );
363 
364 VOID
365 SendOnlineNotification(
366     IN PUNICODE_STRING SymbolicName
367 );
368 
369 VOID
370 IssueUniqueIdChangeNotify(
371     IN PDEVICE_EXTENSION DeviceExtension,
372     IN PUNICODE_STRING DeviceName,
373     IN PMOUNTDEV_UNIQUE_ID UniqueId
374 );
375 
376 VOID
377 PostOnlineNotification(
378     IN PDEVICE_EXTENSION DeviceExtension,
379     IN PUNICODE_STRING SymbolicName
380 );
381 
382 VOID
383 MountMgrNotify(
384     IN PDEVICE_EXTENSION DeviceExtension
385 );
386 
387 VOID
388 MountMgrNotifyNameChange(
389     IN PDEVICE_EXTENSION DeviceExtension,
390     IN PUNICODE_STRING DeviceName,
391     IN BOOLEAN ValidateVolume
392 );
393 
394 /* uniqueid.c */
395 VOID
396 MountMgrUniqueIdChangeRoutine(
397     IN PDEVICE_EXTENSION DeviceExtension,
398     IN PMOUNTDEV_UNIQUE_ID OldUniqueId,
399     IN PMOUNTDEV_UNIQUE_ID NewUniqueId
400 );
401 
402 VOID
403 CreateNoDriveLetterEntry(
404     IN PMOUNTDEV_UNIQUE_ID UniqueId
405 );
406 
407 BOOLEAN
408 HasNoDriveLetterEntry(
409     IN PMOUNTDEV_UNIQUE_ID UniqueId
410 );
411 
412 VOID
413 UpdateReplicatedUniqueIds(
414     IN PDEVICE_INFORMATION DeviceInformation,
415     IN PDATABASE_ENTRY DatabaseEntry
416 );
417 
418 BOOLEAN
419 IsUniqueIdPresent(
420     IN PDEVICE_EXTENSION DeviceExtension,
421     IN PDATABASE_ENTRY DatabaseEntry
422 );
423 
424 /* point.c */
425 NTSTATUS
426 MountMgrCreatePointWorker(
427     IN PDEVICE_EXTENSION DeviceExtension,
428     IN PUNICODE_STRING SymbolicLinkName,
429     IN PUNICODE_STRING DeviceName
430 );
431 
432 NTSTATUS
433 QueryPointsFromSymbolicLinkName(
434     IN PDEVICE_EXTENSION DeviceExtension,
435     IN PUNICODE_STRING SymbolicName,
436     IN PIRP Irp
437 );
438 
439 NTSTATUS
440 QueryPointsFromMemory(
441     IN PDEVICE_EXTENSION DeviceExtension,
442     IN PIRP Irp,
443     IN PMOUNTDEV_UNIQUE_ID UniqueId OPTIONAL,
444     IN PUNICODE_STRING SymbolicName OPTIONAL
445 );
446 
447 /* symlink.c */
448 NTSTATUS
449 GlobalCreateSymbolicLink(
450     IN PUNICODE_STRING DosName,
451     IN PUNICODE_STRING DeviceName
452 );
453 
454 NTSTATUS
455 GlobalDeleteSymbolicLink(
456     IN PUNICODE_STRING DosName
457 );
458 
459 NTSTATUS
460 QuerySuggestedLinkName(
461     IN PUNICODE_STRING SymbolicName,
462     OUT PUNICODE_STRING SuggestedLinkName,
463     OUT PBOOLEAN UseOnlyIfThereAreNoOtherLinks
464 );
465 
466 NTSTATUS
467 QuerySymbolicLinkNamesFromStorage(
468     IN PDEVICE_EXTENSION DeviceExtension,
469     IN PDEVICE_INFORMATION DeviceInformation,
470     IN PUNICODE_STRING SuggestedLinkName,
471     IN BOOLEAN UseOnlyIfThereAreNoOtherLinks,
472     OUT PUNICODE_STRING * SymLinks,
473     OUT PULONG SymLinkCount,
474     IN BOOLEAN HasGuid,
475     IN LPGUID Guid
476 );
477 
478 PSAVED_LINK_INFORMATION
479 RemoveSavedLinks(
480     IN PDEVICE_EXTENSION DeviceExtension,
481     IN PMOUNTDEV_UNIQUE_ID UniqueId
482 );
483 
484 BOOLEAN
485 RedirectSavedLink(
486     IN PSAVED_LINK_INFORMATION SavedLinkInformation,
487     IN PUNICODE_STRING DosName,
488     IN PUNICODE_STRING NewLink
489 );
490 
491 VOID
492 SendLinkCreated(
493     IN PUNICODE_STRING SymbolicName
494 );
495 
496 NTSTATUS
497 CreateNewVolumeName(
498     OUT PUNICODE_STRING VolumeName,
499     IN PGUID VolumeGuid OPTIONAL
500 );
501 
502 BOOLEAN
503 IsDriveLetter(
504     PUNICODE_STRING SymbolicName
505 );
506 
507 VOID
508 DeleteSymbolicLinkNameFromMemory(
509     IN PDEVICE_EXTENSION DeviceExtension,
510     IN PUNICODE_STRING SymbolicLink,
511     IN BOOLEAN MarkOffline
512 );
513 
514 NTSTATUS
515 MountMgrQuerySymbolicLink(
516     IN PUNICODE_STRING SymbolicName,
517     IN OUT PUNICODE_STRING LinkTarget
518 );
519 
520 #endif /* _MNTMGR_H_ */
521