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 ULONG ObpLUIDDeviceMapsDisabled
;
17 ULONG ObpLUIDDeviceMapsEnabled
;
19 /* PRIVATE FUNCTIONS ******************************************************/
23 ObSetDeviceMap(IN PEPROCESS Process
,
24 IN HANDLE DirectoryHandle
)
26 POBJECT_DIRECTORY DirectoryObject
= NULL
;
27 PDEVICE_MAP DeviceMap
= NULL
, NewDeviceMap
= NULL
, OldDeviceMap
;
29 PEPROCESS WorkProcess
;
30 BOOLEAN MakePermanant
= FALSE
;
32 Status
= ObReferenceObjectByHandle(DirectoryHandle
,
34 ObpDirectoryObjectType
,
36 (PVOID
*)&DirectoryObject
,
38 if (!NT_SUCCESS(Status
))
40 DPRINT("ObReferenceObjectByHandle() failed (Status 0x%08lx)\n", Status
);
44 /* Allocate and initialize a new device map */
45 DeviceMap
= ExAllocatePoolWithTag(PagedPool
,
48 if (DeviceMap
== NULL
)
50 ObDereferenceObject(DirectoryObject
);
51 return STATUS_INSUFFICIENT_RESOURCES
;
54 /* Initialize the device map */
55 RtlZeroMemory(DeviceMap
, sizeof(*DeviceMap
));
56 DeviceMap
->ReferenceCount
= 1;
57 DeviceMap
->DosDevicesDirectory
= DirectoryObject
;
59 /* Acquire the device map lock */
60 KeAcquireGuardedMutex(&ObpDeviceMapLock
);
62 /* Attach the device map to the directory object */
63 if (DirectoryObject
->DeviceMap
== NULL
)
65 DirectoryObject
->DeviceMap
= DeviceMap
;
69 NewDeviceMap
= DeviceMap
;
71 /* There's already a device map,
73 DeviceMap
= DirectoryObject
->DeviceMap
;
74 ++DeviceMap
->ReferenceCount
;
77 /* Caller gave a process, use it */
80 WorkProcess
= Process
;
82 /* If no process given, use current and
83 * set system device map */
86 WorkProcess
= PsGetCurrentProcess();
87 ObSystemDeviceMap
= DeviceMap
;
90 /* If current object isn't system one, save system one in current
92 if (DirectoryObject
!= ObSystemDeviceMap
->DosDevicesDirectory
)
94 /* We also need to make the object permanant */
95 DeviceMap
->GlobalDosDevicesDirectory
= ObSystemDeviceMap
->DosDevicesDirectory
;
99 /* Save old process device map */
100 OldDeviceMap
= WorkProcess
->DeviceMap
;
101 /* Attach the device map to the process */
102 WorkProcess
->DeviceMap
= DeviceMap
;
104 /* Release the device map lock */
105 KeReleaseGuardedMutex(&ObpDeviceMapLock
);
107 /* If we have to make the object permamant, do it now */
110 POBJECT_HEADER ObjectHeader
;
111 POBJECT_HEADER_NAME_INFO HeaderNameInfo
;
113 ObjectHeader
= OBJECT_TO_OBJECT_HEADER(DirectoryObject
);
114 HeaderNameInfo
= ObpReferenceNameInfo(ObjectHeader
);
116 ObpEnterObjectTypeMutex(ObjectHeader
->Type
);
117 if (HeaderNameInfo
!= NULL
&& HeaderNameInfo
->Directory
!= NULL
)
119 ObjectHeader
->Flags
|= OB_FLAG_PERMANENT
;
121 ObpLeaveObjectTypeMutex(ObjectHeader
->Type
);
123 if (HeaderNameInfo
!= NULL
)
125 ObpDereferenceNameInfo(HeaderNameInfo
);
129 /* Release useless device map if required */
130 if (NewDeviceMap
!= NULL
)
132 ObfDereferenceObject(DirectoryObject
);
133 ExFreePoolWithTag(NewDeviceMap
, 'mDbO');
136 /* And dereference previous process device map */
137 if (OldDeviceMap
!= NULL
)
139 ObfDereferenceDeviceMap(OldDeviceMap
);
142 return STATUS_SUCCESS
;
148 ObDereferenceDeviceMap(IN PEPROCESS Process
)
150 PDEVICE_MAP DeviceMap
;
152 DPRINT("ObDereferenceDeviceMap()\n");
154 /* Get the pointer to this process devicemap and reset it
155 holding the device map lock */
156 KeAcquireGuardedMutex(&ObpDeviceMapLock
);
157 DeviceMap
= Process
->DeviceMap
;
158 Process
->DeviceMap
= NULL
;
159 KeReleaseGuardedMutex(&ObpDeviceMapLock
);
161 /* Continue only if there is a device map */
162 if (DeviceMap
!= NULL
)
163 ObfDereferenceDeviceMap(DeviceMap
);
169 ObfDereferenceDeviceMap(IN PDEVICE_MAP DeviceMap
)
171 DPRINT("ObfDereferenceDeviceMap()\n");
173 /* Acquire the device map lock */
174 KeAcquireGuardedMutex(&ObpDeviceMapLock
);
176 /* Decrement the reference counter */
177 DeviceMap
->ReferenceCount
--;
178 DPRINT("ReferenceCount: %lu\n", DeviceMap
->ReferenceCount
);
180 /* Leave, if there are still references to this device map */
181 if (DeviceMap
->ReferenceCount
!= 0)
183 /* Release the device map lock and leave */
184 KeReleaseGuardedMutex(&ObpDeviceMapLock
);
188 /* Nobody is referencing it anymore, unlink the DOS directory */
189 DeviceMap
->DosDevicesDirectory
->DeviceMap
= NULL
;
191 /* Release the devicemap lock */
192 KeReleaseGuardedMutex(&ObpDeviceMapLock
);
194 /* Dereference the DOS Devices Directory and free the Device Map */
195 ObMakeTemporaryObject(DeviceMap
->DosDevicesDirectory
);
196 ObDereferenceObject(DeviceMap
->DosDevicesDirectory
);
197 ExFreePoolWithTag(DeviceMap
, 'mDbO');
203 ObInheritDeviceMap(IN PEPROCESS Parent
,
204 IN PEPROCESS Process
)
206 PDEVICE_MAP DeviceMap
;
208 DPRINT("ObInheritDeviceMap()\n");
210 /* Acquire the device map lock */
211 KeAcquireGuardedMutex(&ObpDeviceMapLock
);
213 /* Get the parent process device map or the system device map */
214 DeviceMap
= (Parent
!= NULL
) ? Parent
->DeviceMap
: ObSystemDeviceMap
;
215 if (DeviceMap
!= NULL
)
217 /* Reference the device map and attach it to the new process */
218 DeviceMap
->ReferenceCount
++;
219 DPRINT("ReferenceCount: %lu\n", DeviceMap
->ReferenceCount
);
221 Process
->DeviceMap
= DeviceMap
;
224 /* Release the device map lock */
225 KeReleaseGuardedMutex(&ObpDeviceMapLock
);
231 ObQueryDeviceMapInformation(IN PEPROCESS Process
,
232 IN PPROCESS_DEVICEMAP_INFORMATION DeviceMapInfo
)
234 PDEVICE_MAP DeviceMap
;
236 /* Acquire the device map lock */
237 KeAcquireGuardedMutex(&ObpDeviceMapLock
);
239 /* Get the process device map or the system device map */
240 DeviceMap
= (Process
!= NULL
) ? Process
->DeviceMap
: ObSystemDeviceMap
;
241 if (DeviceMap
!= NULL
)
244 DeviceMapInfo
->Query
.DriveMap
= DeviceMap
->DriveMap
;
245 RtlCopyMemory(DeviceMapInfo
->Query
.DriveType
,
246 DeviceMap
->DriveType
,
247 sizeof(DeviceMap
->DriveType
));
250 /* Release the device map lock */
251 KeReleaseGuardedMutex(&ObpDeviceMapLock
);
257 ObIsLUIDDeviceMapsEnabled(VOID
)
259 return ObpLUIDDeviceMapsEnabled
;
266 ObIsDosDeviceLocallyMapped(
268 OUT PUCHAR DosDeviceState
)
270 /* Check the index */
271 if (Index
< 1 || Index
> 26)
272 return STATUS_INVALID_PARAMETER
;
274 /* Acquire the device map lock */
275 KeAcquireGuardedMutex(&ObpDeviceMapLock
);
277 /* Get drive mapping status */
278 *DosDeviceState
= (ObSystemDeviceMap
->DriveMap
& (1 << Index
)) != 0;
280 /* Release the device map lock */
281 KeReleaseGuardedMutex(&ObpDeviceMapLock
);
283 return STATUS_SUCCESS
;