xref: /reactos/ntoskrnl/ob/devicemap.c (revision 45fd48bd)
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                                        ObpDirectoryObjectType,
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 */
228