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
)
160 ObfDereferenceDeviceMap(DeviceMap
);
166 ObfDereferenceDeviceMap(IN PDEVICE_MAP DeviceMap
)
168 DPRINT("ObfDereferenceDeviceMap()\n");
170 /* Acquire the device map lock */
171 KeAcquireGuardedMutex(&ObpDeviceMapLock
);
173 /* Decrement the reference counter */
174 DeviceMap
->ReferenceCount
--;
175 DPRINT("ReferenceCount: %lu\n", DeviceMap
->ReferenceCount
);
177 /* Leave, if there are still references to this device map */
178 if (DeviceMap
->ReferenceCount
!= 0)
180 /* Release the device map lock and leave */
181 KeReleaseGuardedMutex(&ObpDeviceMapLock
);
185 /* Nobody is referencing it anymore, unlink the DOS directory */
186 DeviceMap
->DosDevicesDirectory
->DeviceMap
= NULL
;
188 /* Release the devicemap lock */
189 KeReleaseGuardedMutex(&ObpDeviceMapLock
);
191 /* Dereference the DOS Devices Directory and free the Device Map */
192 ObDereferenceObject(DeviceMap
->DosDevicesDirectory
);
193 ExFreePoolWithTag(DeviceMap
, 'mDbO');
199 ObInheritDeviceMap(IN PEPROCESS Parent
,
200 IN PEPROCESS Process
)
202 PDEVICE_MAP DeviceMap
;
204 DPRINT("ObInheritDeviceMap()\n");
206 /* Acquire the device map lock */
207 KeAcquireGuardedMutex(&ObpDeviceMapLock
);
209 /* Get the parent process device map or the system device map */
210 DeviceMap
= (Parent
!= NULL
) ? Parent
->DeviceMap
: ObSystemDeviceMap
;
211 if (DeviceMap
!= NULL
)
213 /* Reference the device map and attach it to the new process */
214 DeviceMap
->ReferenceCount
++;
215 DPRINT("ReferenceCount: %lu\n", DeviceMap
->ReferenceCount
);
217 Process
->DeviceMap
= DeviceMap
;
220 /* Release the device map lock */
221 KeReleaseGuardedMutex(&ObpDeviceMapLock
);
227 ObQueryDeviceMapInformation(IN PEPROCESS Process
,
228 IN PPROCESS_DEVICEMAP_INFORMATION DeviceMapInfo
)
230 PDEVICE_MAP DeviceMap
;
232 /* Acquire the device map lock */
233 KeAcquireGuardedMutex(&ObpDeviceMapLock
);
235 /* Get the process device map or the system device map */
236 DeviceMap
= (Process
!= NULL
) ? Process
->DeviceMap
: ObSystemDeviceMap
;
237 if (DeviceMap
!= NULL
)
240 DeviceMapInfo
->Query
.DriveMap
= DeviceMap
->DriveMap
;
241 RtlCopyMemory(DeviceMapInfo
->Query
.DriveType
,
242 DeviceMap
->DriveType
,
243 sizeof(DeviceMap
->DriveType
));
246 /* Release the device map lock */
247 KeReleaseGuardedMutex(&ObpDeviceMapLock
);
254 ObIsDosDeviceLocallyMapped(
256 OUT PUCHAR DosDeviceState
)
258 /* Check the index */
259 if (Index
< 1 || Index
> 26)
260 return STATUS_INVALID_PARAMETER
;
262 /* Acquire the device map lock */
263 KeAcquireGuardedMutex(&ObpDeviceMapLock
);
265 /* Get drive mapping status */
266 *DosDeviceState
= (ObSystemDeviceMap
->DriveMap
& (1 << Index
)) != 0;
268 /* Release the device map lock */
269 KeReleaseGuardedMutex(&ObpDeviceMapLock
);
271 return STATUS_SUCCESS
;