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