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)
10 /* INCLUDES ***************************************************************/
16 /* PRIVATE FUNCTIONS ******************************************************/
20 ObpCreateDeviceMap(IN HANDLE DirectoryHandle
)
22 POBJECT_DIRECTORY DirectoryObject
= NULL
;
23 PDEVICE_MAP DeviceMap
= NULL
;
26 Status
= ObReferenceObjectByHandle(DirectoryHandle
,
30 (PVOID
*)&DirectoryObject
,
32 if (!NT_SUCCESS(Status
))
34 DPRINT("ObReferenceObjectByHandle() failed (Status 0x%08lx)\n", Status
);
38 /* Allocate and initialize a new device map */
39 DeviceMap
= ExAllocatePoolWithTag(NonPagedPool
,
42 if (DeviceMap
== NULL
)
44 ObDereferenceObject(DirectoryObject
);
45 return STATUS_INSUFFICIENT_RESOURCES
;
48 /* Initialize the device map */
49 RtlZeroMemory(DeviceMap
, sizeof(*DeviceMap
));
50 DeviceMap
->ReferenceCount
= 1;
51 DeviceMap
->DosDevicesDirectory
= DirectoryObject
;
53 /* Acquire the device map lock */
54 KeAcquireGuardedMutex(&ObpDeviceMapLock
);
56 /* Attach the device map to the directory object */
57 DirectoryObject
->DeviceMap
= DeviceMap
;
59 /* Attach the device map to the process */
60 ObSystemDeviceMap
= DeviceMap
;
61 PsGetCurrentProcess()->DeviceMap
= DeviceMap
;
63 /* Release the device map lock */
64 KeReleaseGuardedMutex(&ObpDeviceMapLock
);
66 return STATUS_SUCCESS
;
72 ObDereferenceDeviceMap(IN PEPROCESS Process
)
74 PDEVICE_MAP DeviceMap
;
76 DPRINT("ObDereferenceDeviceMap()\n");
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
);
85 /* Continue only if there is a device map */
86 if (DeviceMap
== NULL
)
89 /* Acquire the device map lock again */
90 KeAcquireGuardedMutex(&ObpDeviceMapLock
);
92 /* Decrement the reference counter */
93 DeviceMap
->ReferenceCount
--;
94 DPRINT("ReferenceCount: %lu\n", DeviceMap
->ReferenceCount
);
96 /* Leave, if there are still references to this device map */
97 if (DeviceMap
->ReferenceCount
!= 0)
99 /* Release the device map lock and leave */
100 KeReleaseGuardedMutex(&ObpDeviceMapLock
);
104 /* Nobody is referencing it anymore, unlink the DOS directory */
105 DeviceMap
->DosDevicesDirectory
->DeviceMap
= NULL
;
107 /* Release the device map lock */
108 KeReleaseGuardedMutex(&ObpDeviceMapLock
);
110 /* Dereference the DOS Devices Directory and free the DeviceMap */
111 ObDereferenceObject(DeviceMap
->DosDevicesDirectory
);
112 ExFreePoolWithTag(DeviceMap
, 'mDbO');
118 ObfDereferenceDeviceMap(IN PDEVICE_MAP DeviceMap
)
120 DPRINT("ObfDereferenceDeviceMap()\n");
122 /* Acquire the device map lock */
123 KeAcquireGuardedMutex(&ObpDeviceMapLock
);
125 /* Decrement the reference counter */
126 DeviceMap
->ReferenceCount
--;
127 DPRINT("ReferenceCount: %lu\n", DeviceMap
->ReferenceCount
);
129 /* Leave, if there are still references to this device map */
130 if (DeviceMap
->ReferenceCount
!= 0)
132 /* Release the device map lock and leave */
133 KeReleaseGuardedMutex(&ObpDeviceMapLock
);
137 /* Nobody is referencing it anymore, unlink the DOS directory */
138 DeviceMap
->DosDevicesDirectory
->DeviceMap
= NULL
;
140 /* Release the devicemap lock */
141 KeReleaseGuardedMutex(&ObpDeviceMapLock
);
143 /* Dereference the DOS Devices Directory and free the Device Map */
144 ObDereferenceObject(DeviceMap
->DosDevicesDirectory
);
145 ExFreePoolWithTag(DeviceMap
, 'mDbO');
151 ObInheritDeviceMap(IN PEPROCESS Parent
,
152 IN PEPROCESS Process
)
154 PDEVICE_MAP DeviceMap
;
156 DPRINT("ObInheritDeviceMap()\n");
158 /* Acquire the device map lock */
159 KeAcquireGuardedMutex(&ObpDeviceMapLock
);
161 /* Get the parent process device map or the system device map */
162 DeviceMap
= (Parent
!= NULL
) ? Parent
->DeviceMap
: ObSystemDeviceMap
;
163 if (DeviceMap
!= NULL
)
165 /* Reference the device map and attach it to the new process */
166 DeviceMap
->ReferenceCount
++;
167 DPRINT("ReferenceCount: %lu\n", DeviceMap
->ReferenceCount
);
169 Process
->DeviceMap
= DeviceMap
;
172 /* Release the device map lock */
173 KeReleaseGuardedMutex(&ObpDeviceMapLock
);
179 ObQueryDeviceMapInformation(IN PEPROCESS Process
,
180 IN PPROCESS_DEVICEMAP_INFORMATION DeviceMapInfo
)
182 PDEVICE_MAP DeviceMap
;
184 /* Acquire the device map lock */
185 KeAcquireGuardedMutex(&ObpDeviceMapLock
);
187 /* Get the process device map or the system device map */
188 DeviceMap
= (Process
!= NULL
) ? Process
->DeviceMap
: ObSystemDeviceMap
;
189 if (DeviceMap
!= NULL
)
192 DeviceMapInfo
->Query
.DriveMap
= DeviceMap
->DriveMap
;
193 RtlCopyMemory(DeviceMapInfo
->Query
.DriveType
,
194 DeviceMap
->DriveType
,
195 sizeof(DeviceMap
->DriveType
));
198 /* Release the device map lock */
199 KeReleaseGuardedMutex(&ObpDeviceMapLock
);
206 ObIsDosDeviceLocallyMapped(
208 OUT PUCHAR DosDeviceState
)
210 /* Check the index */
211 if (Index
< 1 || Index
> 26)
212 return STATUS_INVALID_PARAMETER
;
214 /* Acquire the device map lock */
215 KeAcquireGuardedMutex(&ObpDeviceMapLock
);
217 /* Get drive mapping status */
218 *DosDeviceState
= (ObSystemDeviceMap
->DriveMap
& (1 << Index
)) != 0;
220 /* Release the device map lock */
221 KeReleaseGuardedMutex(&ObpDeviceMapLock
);
223 return STATUS_SUCCESS
;