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 ObMakeTemporaryObject(DeviceMap
->DosDevicesDirectory
);
193 ObDereferenceObject(DeviceMap
->DosDevicesDirectory
);
194 ExFreePoolWithTag(DeviceMap
, 'mDbO');
200 ObInheritDeviceMap(IN PEPROCESS Parent
,
201 IN PEPROCESS Process
)
203 PDEVICE_MAP DeviceMap
;
205 DPRINT("ObInheritDeviceMap()\n");
207 /* Acquire the device map lock */
208 KeAcquireGuardedMutex(&ObpDeviceMapLock
);
210 /* Get the parent process device map or the system device map */
211 DeviceMap
= (Parent
!= NULL
) ? Parent
->DeviceMap
: ObSystemDeviceMap
;
212 if (DeviceMap
!= NULL
)
214 /* Reference the device map and attach it to the new process */
215 DeviceMap
->ReferenceCount
++;
216 DPRINT("ReferenceCount: %lu\n", DeviceMap
->ReferenceCount
);
218 Process
->DeviceMap
= DeviceMap
;
221 /* Release the device map lock */
222 KeReleaseGuardedMutex(&ObpDeviceMapLock
);
228 ObQueryDeviceMapInformation(IN PEPROCESS Process
,
229 IN PPROCESS_DEVICEMAP_INFORMATION DeviceMapInfo
)
231 PDEVICE_MAP DeviceMap
;
233 /* Acquire the device map lock */
234 KeAcquireGuardedMutex(&ObpDeviceMapLock
);
236 /* Get the process device map or the system device map */
237 DeviceMap
= (Process
!= NULL
) ? Process
->DeviceMap
: ObSystemDeviceMap
;
238 if (DeviceMap
!= NULL
)
241 DeviceMapInfo
->Query
.DriveMap
= DeviceMap
->DriveMap
;
242 RtlCopyMemory(DeviceMapInfo
->Query
.DriveType
,
243 DeviceMap
->DriveType
,
244 sizeof(DeviceMap
->DriveType
));
247 /* Release the device map lock */
248 KeReleaseGuardedMutex(&ObpDeviceMapLock
);
255 ObIsDosDeviceLocallyMapped(
257 OUT PUCHAR DosDeviceState
)
259 /* Check the index */
260 if (Index
< 1 || Index
> 26)
261 return STATUS_INVALID_PARAMETER
;
263 /* Acquire the device map lock */
264 KeAcquireGuardedMutex(&ObpDeviceMapLock
);
266 /* Get drive mapping status */
267 *DosDeviceState
= (ObSystemDeviceMap
->DriveMap
& (1 << Index
)) != 0;
269 /* Release the device map lock */
270 KeReleaseGuardedMutex(&ObpDeviceMapLock
);
272 return STATUS_SUCCESS
;