1 /* 2 * PROJECT: ReactOS Kernel 3 * LICENSE: GPL - See COPYING in the top level directory 4 * FILE: ntoskrnl/ob/devicemap.c 5 * PURPOSE: Device map implementation 6 * PROGRAMMERS: Eric Kohl (eric.kohl@reactos.org) 7 * Alex Ionescu (alex.ionescu@reactos.org) 8 */ 9 10 /* INCLUDES ***************************************************************/ 11 12 #include <ntoskrnl.h> 13 #define NDEBUG 14 #include <debug.h> 15 16 /* PRIVATE FUNCTIONS ******************************************************/ 17 18 NTSTATUS 19 NTAPI 20 ObpCreateDeviceMap(IN HANDLE DirectoryHandle) 21 { 22 POBJECT_DIRECTORY DirectoryObject = NULL; 23 PDEVICE_MAP DeviceMap = NULL; 24 NTSTATUS Status; 25 26 Status = ObReferenceObjectByHandle(DirectoryHandle, 27 DIRECTORY_TRAVERSE, 28 ObpDirectoryObjectType, 29 KeGetPreviousMode(), 30 (PVOID*)&DirectoryObject, 31 NULL); 32 if (!NT_SUCCESS(Status)) 33 { 34 DPRINT("ObReferenceObjectByHandle() failed (Status 0x%08lx)\n", Status); 35 return Status; 36 } 37 38 /* Allocate and initialize a new device map */ 39 DeviceMap = ExAllocatePoolWithTag(NonPagedPool, 40 sizeof(*DeviceMap), 41 'mDbO'); 42 if (DeviceMap == NULL) 43 { 44 ObDereferenceObject(DirectoryObject); 45 return STATUS_INSUFFICIENT_RESOURCES; 46 } 47 48 /* Initialize the device map */ 49 RtlZeroMemory(DeviceMap, sizeof(*DeviceMap)); 50 DeviceMap->ReferenceCount = 1; 51 DeviceMap->DosDevicesDirectory = DirectoryObject; 52 53 /* Acquire the device map lock */ 54 KeAcquireGuardedMutex(&ObpDeviceMapLock); 55 56 /* Attach the device map to the directory object */ 57 DirectoryObject->DeviceMap = DeviceMap; 58 59 /* Attach the device map to the process */ 60 ObSystemDeviceMap = DeviceMap; 61 PsGetCurrentProcess()->DeviceMap = DeviceMap; 62 63 /* Release the device map lock */ 64 KeReleaseGuardedMutex(&ObpDeviceMapLock); 65 66 return STATUS_SUCCESS; 67 } 68 69 70 VOID 71 NTAPI 72 ObDereferenceDeviceMap(IN PEPROCESS Process) 73 { 74 PDEVICE_MAP DeviceMap; 75 76 DPRINT("ObDereferenceDeviceMap()\n"); 77 78 /* Get the pointer to this process devicemap and reset it 79 holding the device map lock */ 80 KeAcquireGuardedMutex(&ObpDeviceMapLock); 81 DeviceMap = Process->DeviceMap; 82 Process->DeviceMap = NULL; 83 KeReleaseGuardedMutex(&ObpDeviceMapLock); 84 85 /* Continue only if there is a device map */ 86 if (DeviceMap == NULL) 87 return; 88 89 /* Acquire the device map lock again */ 90 KeAcquireGuardedMutex(&ObpDeviceMapLock); 91 92 /* Decrement the reference counter */ 93 DeviceMap->ReferenceCount--; 94 DPRINT("ReferenceCount: %lu\n", DeviceMap->ReferenceCount); 95 96 /* Leave, if there are still references to this device map */ 97 if (DeviceMap->ReferenceCount != 0) 98 { 99 /* Release the device map lock and leave */ 100 KeReleaseGuardedMutex(&ObpDeviceMapLock); 101 return; 102 } 103 104 /* Nobody is referencing it anymore, unlink the DOS directory */ 105 DeviceMap->DosDevicesDirectory->DeviceMap = NULL; 106 107 /* Release the device map lock */ 108 KeReleaseGuardedMutex(&ObpDeviceMapLock); 109 110 /* Dereference the DOS Devices Directory and free the DeviceMap */ 111 ObDereferenceObject(DeviceMap->DosDevicesDirectory); 112 ExFreePoolWithTag(DeviceMap, 'mDbO'); 113 } 114 115 116 VOID 117 FASTCALL 118 ObfDereferenceDeviceMap(IN PDEVICE_MAP DeviceMap) 119 { 120 DPRINT("ObfDereferenceDeviceMap()\n"); 121 122 /* Acquire the device map lock */ 123 KeAcquireGuardedMutex(&ObpDeviceMapLock); 124 125 /* Decrement the reference counter */ 126 DeviceMap->ReferenceCount--; 127 DPRINT("ReferenceCount: %lu\n", DeviceMap->ReferenceCount); 128 129 /* Leave, if there are still references to this device map */ 130 if (DeviceMap->ReferenceCount != 0) 131 { 132 /* Release the device map lock and leave */ 133 KeReleaseGuardedMutex(&ObpDeviceMapLock); 134 return; 135 } 136 137 /* Nobody is referencing it anymore, unlink the DOS directory */ 138 DeviceMap->DosDevicesDirectory->DeviceMap = NULL; 139 140 /* Release the devicemap lock */ 141 KeReleaseGuardedMutex(&ObpDeviceMapLock); 142 143 /* Dereference the DOS Devices Directory and free the Device Map */ 144 ObDereferenceObject(DeviceMap->DosDevicesDirectory ); 145 ExFreePoolWithTag(DeviceMap, 'mDbO'); 146 } 147 148 149 VOID 150 NTAPI 151 ObInheritDeviceMap(IN PEPROCESS Parent, 152 IN PEPROCESS Process) 153 { 154 PDEVICE_MAP DeviceMap; 155 156 DPRINT("ObInheritDeviceMap()\n"); 157 158 /* Acquire the device map lock */ 159 KeAcquireGuardedMutex(&ObpDeviceMapLock); 160 161 /* Get the parent process device map or the system device map */ 162 DeviceMap = (Parent != NULL) ? Parent->DeviceMap : ObSystemDeviceMap; 163 if (DeviceMap != NULL) 164 { 165 /* Reference the device map and attach it to the new process */ 166 DeviceMap->ReferenceCount++; 167 DPRINT("ReferenceCount: %lu\n", DeviceMap->ReferenceCount); 168 169 Process->DeviceMap = DeviceMap; 170 } 171 172 /* Release the device map lock */ 173 KeReleaseGuardedMutex(&ObpDeviceMapLock); 174 } 175 176 177 VOID 178 NTAPI 179 ObQueryDeviceMapInformation(IN PEPROCESS Process, 180 IN PPROCESS_DEVICEMAP_INFORMATION DeviceMapInfo) 181 { 182 PDEVICE_MAP DeviceMap; 183 184 /* Acquire the device map lock */ 185 KeAcquireGuardedMutex(&ObpDeviceMapLock); 186 187 /* Get the process device map or the system device map */ 188 DeviceMap = (Process != NULL) ? Process->DeviceMap : ObSystemDeviceMap; 189 if (DeviceMap != NULL) 190 { 191 /* Make a copy */ 192 DeviceMapInfo->Query.DriveMap = DeviceMap->DriveMap; 193 RtlCopyMemory(DeviceMapInfo->Query.DriveType, 194 DeviceMap->DriveType, 195 sizeof(DeviceMap->DriveType)); 196 } 197 198 /* Release the device map lock */ 199 KeReleaseGuardedMutex(&ObpDeviceMapLock); 200 } 201 202 203 #if 0 204 NTSTATUS 205 NTAPI 206 ObIsDosDeviceLocallyMapped( 207 IN ULONG Index, 208 OUT PUCHAR DosDeviceState) 209 { 210 /* Check the index */ 211 if (Index < 1 || Index > 26) 212 return STATUS_INVALID_PARAMETER; 213 214 /* Acquire the device map lock */ 215 KeAcquireGuardedMutex(&ObpDeviceMapLock); 216 217 /* Get drive mapping status */ 218 *DosDeviceState = (ObSystemDeviceMap->DriveMap & (1 << Index)) != 0; 219 220 /* Release the device map lock */ 221 KeReleaseGuardedMutex(&ObpDeviceMapLock); 222 223 return STATUS_SUCCESS; 224 } 225 #endif 226 227 /* EOF */ 228