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 ObSetDeviceMap(IN PEPROCESS Process
,
21 IN HANDLE DirectoryHandle
)
23 POBJECT_DIRECTORY DirectoryObject
= NULL
;
24 PDEVICE_MAP DeviceMap
= NULL
, NewDeviceMap
= NULL
, OldDeviceMap
;
26 PEPROCESS WorkProcess
;
27 BOOLEAN MakePermanant
= FALSE
;
29 Status
= ObReferenceObjectByHandle(DirectoryHandle
,
31 ObpDirectoryObjectType
,
33 (PVOID
*)&DirectoryObject
,
35 if (!NT_SUCCESS(Status
))
37 DPRINT("ObReferenceObjectByHandle() failed (Status 0x%08lx)\n", Status
);
41 /* Allocate and initialize a new device map */
42 DeviceMap
= ExAllocatePoolWithTag(PagedPool
,
45 if (DeviceMap
== NULL
)
47 ObDereferenceObject(DirectoryObject
);
48 return STATUS_INSUFFICIENT_RESOURCES
;
51 /* Initialize the device map */
52 RtlZeroMemory(DeviceMap
, sizeof(*DeviceMap
));
53 DeviceMap
->ReferenceCount
= 1;
54 DeviceMap
->DosDevicesDirectory
= DirectoryObject
;
56 /* Acquire the device map lock */
57 KeAcquireGuardedMutex(&ObpDeviceMapLock
);
59 /* Attach the device map to the directory object */
60 if (DirectoryObject
->DeviceMap
== NULL
)
62 DirectoryObject
->DeviceMap
= DeviceMap
;
66 NewDeviceMap
= DeviceMap
;
68 /* There's already a device map,
70 DeviceMap
= DirectoryObject
->DeviceMap
;
71 ++DeviceMap
->ReferenceCount
;
74 /* Caller gave a process, use it */
77 WorkProcess
= Process
;
79 /* If no process given, use current and
80 * set system device map */
83 WorkProcess
= PsGetCurrentProcess();
84 ObSystemDeviceMap
= DeviceMap
;
87 /* If current object isn't system one, save system one in current
89 if (DirectoryObject
!= ObSystemDeviceMap
->DosDevicesDirectory
)
91 /* We also need to make the object permanant */
92 DeviceMap
->GlobalDosDevicesDirectory
= ObSystemDeviceMap
->DosDevicesDirectory
;
96 /* Save old process device map */
97 OldDeviceMap
= WorkProcess
->DeviceMap
;
98 /* Attach the device map to the process */
99 WorkProcess
->DeviceMap
= DeviceMap
;
101 /* Release the device map lock */
102 KeReleaseGuardedMutex(&ObpDeviceMapLock
);
104 /* If we have to make the object permamant, do it now */
107 POBJECT_HEADER ObjectHeader
;
108 POBJECT_HEADER_NAME_INFO HeaderNameInfo
;
110 ObjectHeader
= OBJECT_TO_OBJECT_HEADER(DirectoryObject
);
111 HeaderNameInfo
= ObpReferenceNameInfo(ObjectHeader
);
113 ObpEnterObjectTypeMutex(ObjectHeader
->Type
);
114 if (HeaderNameInfo
!= NULL
&& HeaderNameInfo
->Directory
!= NULL
)
116 ObjectHeader
->Flags
|= OB_FLAG_PERMANENT
;
118 ObpLeaveObjectTypeMutex(ObjectHeader
->Type
);
120 if (HeaderNameInfo
!= NULL
)
122 ObpDereferenceNameInfo(HeaderNameInfo
);
126 /* Release useless device map if required */
127 if (NewDeviceMap
!= NULL
)
129 ObfDereferenceObject(DirectoryObject
);
130 ExFreePoolWithTag(NewDeviceMap
, 'mDbO');
133 /* And dereference previous process device map */
134 if (OldDeviceMap
!= NULL
)
136 ObfDereferenceDeviceMap(OldDeviceMap
);
139 return STATUS_SUCCESS
;
145 ObDereferenceDeviceMap(IN PEPROCESS Process
)
147 PDEVICE_MAP DeviceMap
;
149 DPRINT("ObDereferenceDeviceMap()\n");
151 /* Get the pointer to this process devicemap and reset it
152 holding the device map lock */
153 KeAcquireGuardedMutex(&ObpDeviceMapLock
);
154 DeviceMap
= Process
->DeviceMap
;
155 Process
->DeviceMap
= NULL
;
156 KeReleaseGuardedMutex(&ObpDeviceMapLock
);
158 /* Continue only if there is a device map */
159 if (DeviceMap
== NULL
)
162 /* Acquire the device map lock again */
163 KeAcquireGuardedMutex(&ObpDeviceMapLock
);
165 /* Decrement the reference counter */
166 DeviceMap
->ReferenceCount
--;
167 DPRINT("ReferenceCount: %lu\n", DeviceMap
->ReferenceCount
);
169 /* Leave, if there are still references to this device map */
170 if (DeviceMap
->ReferenceCount
!= 0)
172 /* Release the device map lock and leave */
173 KeReleaseGuardedMutex(&ObpDeviceMapLock
);
177 /* Nobody is referencing it anymore, unlink the DOS directory */
178 DeviceMap
->DosDevicesDirectory
->DeviceMap
= NULL
;
180 /* Release the device map lock */
181 KeReleaseGuardedMutex(&ObpDeviceMapLock
);
183 /* Dereference the DOS Devices Directory and free the DeviceMap */
184 ObDereferenceObject(DeviceMap
->DosDevicesDirectory
);
185 ExFreePoolWithTag(DeviceMap
, 'mDbO');
191 ObfDereferenceDeviceMap(IN PDEVICE_MAP DeviceMap
)
193 DPRINT("ObfDereferenceDeviceMap()\n");
195 /* Acquire the device map lock */
196 KeAcquireGuardedMutex(&ObpDeviceMapLock
);
198 /* Decrement the reference counter */
199 DeviceMap
->ReferenceCount
--;
200 DPRINT("ReferenceCount: %lu\n", DeviceMap
->ReferenceCount
);
202 /* Leave, if there are still references to this device map */
203 if (DeviceMap
->ReferenceCount
!= 0)
205 /* Release the device map lock and leave */
206 KeReleaseGuardedMutex(&ObpDeviceMapLock
);
210 /* Nobody is referencing it anymore, unlink the DOS directory */
211 DeviceMap
->DosDevicesDirectory
->DeviceMap
= NULL
;
213 /* Release the devicemap lock */
214 KeReleaseGuardedMutex(&ObpDeviceMapLock
);
216 /* Dereference the DOS Devices Directory and free the Device Map */
217 ObDereferenceObject(DeviceMap
->DosDevicesDirectory
);
218 ExFreePoolWithTag(DeviceMap
, 'mDbO');
224 ObInheritDeviceMap(IN PEPROCESS Parent
,
225 IN PEPROCESS Process
)
227 PDEVICE_MAP DeviceMap
;
229 DPRINT("ObInheritDeviceMap()\n");
231 /* Acquire the device map lock */
232 KeAcquireGuardedMutex(&ObpDeviceMapLock
);
234 /* Get the parent process device map or the system device map */
235 DeviceMap
= (Parent
!= NULL
) ? Parent
->DeviceMap
: ObSystemDeviceMap
;
236 if (DeviceMap
!= NULL
)
238 /* Reference the device map and attach it to the new process */
239 DeviceMap
->ReferenceCount
++;
240 DPRINT("ReferenceCount: %lu\n", DeviceMap
->ReferenceCount
);
242 Process
->DeviceMap
= DeviceMap
;
245 /* Release the device map lock */
246 KeReleaseGuardedMutex(&ObpDeviceMapLock
);
252 ObQueryDeviceMapInformation(IN PEPROCESS Process
,
253 IN PPROCESS_DEVICEMAP_INFORMATION DeviceMapInfo
)
255 PDEVICE_MAP DeviceMap
;
257 /* Acquire the device map lock */
258 KeAcquireGuardedMutex(&ObpDeviceMapLock
);
260 /* Get the process device map or the system device map */
261 DeviceMap
= (Process
!= NULL
) ? Process
->DeviceMap
: ObSystemDeviceMap
;
262 if (DeviceMap
!= NULL
)
265 DeviceMapInfo
->Query
.DriveMap
= DeviceMap
->DriveMap
;
266 RtlCopyMemory(DeviceMapInfo
->Query
.DriveType
,
267 DeviceMap
->DriveType
,
268 sizeof(DeviceMap
->DriveType
));
271 /* Release the device map lock */
272 KeReleaseGuardedMutex(&ObpDeviceMapLock
);
279 ObIsDosDeviceLocallyMapped(
281 OUT PUCHAR DosDeviceState
)
283 /* Check the index */
284 if (Index
< 1 || Index
> 26)
285 return STATUS_INVALID_PARAMETER
;
287 /* Acquire the device map lock */
288 KeAcquireGuardedMutex(&ObpDeviceMapLock
);
290 /* Get drive mapping status */
291 *DosDeviceState
= (ObSystemDeviceMap
->DriveMap
& (1 << Index
)) != 0;
293 /* Release the device map lock */
294 KeReleaseGuardedMutex(&ObpDeviceMapLock
);
296 return STATUS_SUCCESS
;