[VCDROM] Implement the virtual CD-ROM class driver.
[reactos.git] / ntoskrnl / ob / devicemap.c
1 /*
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)
8 */
9
10 /* INCLUDES ***************************************************************/
11
12 #include <ntoskrnl.h>
13 #define NDEBUG
14 #include <debug.h>
15
16 /* PRIVATE FUNCTIONS ******************************************************/
17
18 NTSTATUS
19 NTAPI
20 ObpCreateDeviceMap(IN HANDLE DirectoryHandle)
21 {
22 POBJECT_DIRECTORY DirectoryObject = NULL;
23 PDEVICE_MAP DeviceMap = NULL;
24 NTSTATUS Status;
25
26 Status = ObReferenceObjectByHandle(DirectoryHandle,
27 DIRECTORY_TRAVERSE,
28 ObDirectoryType,
29 KeGetPreviousMode(),
30 (PVOID*)&DirectoryObject,
31 NULL);
32 if (!NT_SUCCESS(Status))
33 {
34 DPRINT("ObReferenceObjectByHandle() failed (Status 0x%08lx)\n", Status);
35 return Status;
36 }
37
38 /* Allocate and initialize a new device map */
39 DeviceMap = ExAllocatePoolWithTag(NonPagedPool,
40 sizeof(*DeviceMap),
41 'mDbO');
42 if (DeviceMap == NULL)
43 {
44 ObDereferenceObject(DirectoryObject);
45 return STATUS_INSUFFICIENT_RESOURCES;
46 }
47
48 /* Initialize the device map */
49 RtlZeroMemory(DeviceMap, sizeof(*DeviceMap));
50 DeviceMap->ReferenceCount = 1;
51 DeviceMap->DosDevicesDirectory = DirectoryObject;
52
53 /* Acquire the device map lock */
54 KeAcquireGuardedMutex(&ObpDeviceMapLock);
55
56 /* Attach the device map to the directory object */
57 DirectoryObject->DeviceMap = DeviceMap;
58
59 /* Attach the device map to the process */
60 ObSystemDeviceMap = DeviceMap;
61 PsGetCurrentProcess()->DeviceMap = DeviceMap;
62
63 /* Release the device map lock */
64 KeReleaseGuardedMutex(&ObpDeviceMapLock);
65
66 return STATUS_SUCCESS;
67 }
68
69
70 VOID
71 NTAPI
72 ObDereferenceDeviceMap(IN PEPROCESS Process)
73 {
74 PDEVICE_MAP DeviceMap;
75
76 DPRINT("ObDereferenceDeviceMap()\n");
77
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);
84
85 /* Continue only if there is a device map */
86 if (DeviceMap == NULL)
87 return;
88
89 /* Acquire the device map lock again */
90 KeAcquireGuardedMutex(&ObpDeviceMapLock);
91
92 /* Decrement the reference counter */
93 DeviceMap->ReferenceCount--;
94 DPRINT("ReferenceCount: %lu\n", DeviceMap->ReferenceCount);
95
96 /* Leave, if there are still references to this device map */
97 if (DeviceMap->ReferenceCount != 0)
98 {
99 /* Release the device map lock and leave */
100 KeReleaseGuardedMutex(&ObpDeviceMapLock);
101 return;
102 }
103
104 /* Nobody is referencing it anymore, unlink the DOS directory */
105 DeviceMap->DosDevicesDirectory->DeviceMap = NULL;
106
107 /* Release the device map lock */
108 KeReleaseGuardedMutex(&ObpDeviceMapLock);
109
110 /* Dereference the DOS Devices Directory and free the DeviceMap */
111 ObDereferenceObject(DeviceMap->DosDevicesDirectory);
112 ExFreePoolWithTag(DeviceMap, 'mDbO');
113 }
114
115
116 VOID
117 FASTCALL
118 ObfDereferenceDeviceMap(IN PDEVICE_MAP DeviceMap)
119 {
120 DPRINT("ObfDereferenceDeviceMap()\n");
121
122 /* Acquire the device map lock */
123 KeAcquireGuardedMutex(&ObpDeviceMapLock);
124
125 /* Decrement the reference counter */
126 DeviceMap->ReferenceCount--;
127 DPRINT("ReferenceCount: %lu\n", DeviceMap->ReferenceCount);
128
129 /* Leave, if there are still references to this device map */
130 if (DeviceMap->ReferenceCount != 0)
131 {
132 /* Release the device map lock and leave */
133 KeReleaseGuardedMutex(&ObpDeviceMapLock);
134 return;
135 }
136
137 /* Nobody is referencing it anymore, unlink the DOS directory */
138 DeviceMap->DosDevicesDirectory->DeviceMap = NULL;
139
140 /* Release the devicemap lock */
141 KeReleaseGuardedMutex(&ObpDeviceMapLock);
142
143 /* Dereference the DOS Devices Directory and free the Device Map */
144 ObDereferenceObject(DeviceMap->DosDevicesDirectory );
145 ExFreePoolWithTag(DeviceMap, 'mDbO');
146 }
147
148
149 VOID
150 NTAPI
151 ObInheritDeviceMap(IN PEPROCESS Parent,
152 IN PEPROCESS Process)
153 {
154 PDEVICE_MAP DeviceMap;
155
156 DPRINT("ObInheritDeviceMap()\n");
157
158 /* Acquire the device map lock */
159 KeAcquireGuardedMutex(&ObpDeviceMapLock);
160
161 /* Get the parent process device map or the system device map */
162 DeviceMap = (Parent != NULL) ? Parent->DeviceMap : ObSystemDeviceMap;
163 if (DeviceMap != NULL)
164 {
165 /* Reference the device map and attach it to the new process */
166 DeviceMap->ReferenceCount++;
167 DPRINT("ReferenceCount: %lu\n", DeviceMap->ReferenceCount);
168
169 Process->DeviceMap = DeviceMap;
170 }
171
172 /* Release the device map lock */
173 KeReleaseGuardedMutex(&ObpDeviceMapLock);
174 }
175
176
177 VOID
178 NTAPI
179 ObQueryDeviceMapInformation(IN PEPROCESS Process,
180 IN PPROCESS_DEVICEMAP_INFORMATION DeviceMapInfo)
181 {
182 PDEVICE_MAP DeviceMap;
183
184 /* Acquire the device map lock */
185 KeAcquireGuardedMutex(&ObpDeviceMapLock);
186
187 /* Get the process device map or the system device map */
188 DeviceMap = (Process != NULL) ? Process->DeviceMap : ObSystemDeviceMap;
189 if (DeviceMap != NULL)
190 {
191 /* Make a copy */
192 DeviceMapInfo->Query.DriveMap = DeviceMap->DriveMap;
193 RtlCopyMemory(DeviceMapInfo->Query.DriveType,
194 DeviceMap->DriveType,
195 sizeof(DeviceMap->DriveType));
196 }
197
198 /* Release the device map lock */
199 KeReleaseGuardedMutex(&ObpDeviceMapLock);
200 }
201
202
203 #if 0
204 NTSTATUS
205 NTAPI
206 ObIsDosDeviceLocallyMapped(
207 IN ULONG Index,
208 OUT PUCHAR DosDeviceState)
209 {
210 /* Check the index */
211 if (Index < 1 || Index > 26)
212 return STATUS_INVALID_PARAMETER;
213
214 /* Acquire the device map lock */
215 KeAcquireGuardedMutex(&ObpDeviceMapLock);
216
217 /* Get drive mapping status */
218 *DosDeviceState = (ObSystemDeviceMap->DriveMap & (1 << Index)) != 0;
219
220 /* Release the device map lock */
221 KeReleaseGuardedMutex(&ObpDeviceMapLock);
222
223 return STATUS_SUCCESS;
224 }
225 #endif
226
227 /* EOF */