Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

obdevmap.c File Reference

#include "obp.h"

Go to the source code of this file.

Functions

NTSTATUS ObSetDeviceMap (IN PEPROCESS TargetProcess OPTIONAL, IN HANDLE DirectoryHandle)
NTSTATUS ObQueryDeviceMapInformation (IN PEPROCESS TargetProcess OPTIONAL, OUT PPROCESS_DEVICEMAP_INFORMATION DeviceMapInformation)
VOID ObInheritDeviceMap (IN PEPROCESS NewProcess, IN PEPROCESS ParentProcess OPTIONAL)
VOID ObDereferenceDeviceMap (IN PEPROCESS Process)


Function Documentation

VOID ObDereferenceDeviceMap IN PEPROCESS  Process  ) 
 

Definition at line 416 of file obdevmap.c.

References _OBJECT_DIRECTORY::DeviceMap, _DEVICE_MAP::DosDevicesDirectory, ExFreePool(), NULL, ObDereferenceObject, ObpDeviceMapLock, and _DEVICE_MAP::ReferenceCount.

Referenced by ObSetDeviceMap(), and PspProcessDelete().

00422 : 00423 00424 This function is called at process tear down time to decrement the 00425 reference count on a device map. When the reference count goes to 00426 zero, it means no more processes are using this, so it can be freed 00427 and the reference on the associated object directory can be released. 00428 00429 Arguments: 00430 00431 Process - Process being destroyed. 00432 00433 Return Value: 00434 00435 None. 00436 00437 --*/ 00438 00439 { 00440 PDEVICE_MAP DeviceMap; 00441 KIRQL OldIrql; 00442 00443 // 00444 // Grab the device map and then we only have work to do 00445 // it there is one 00446 // 00447 00448 DeviceMap = Process->DeviceMap; 00449 00450 if (DeviceMap != NULL) { 00451 00452 // 00453 // To dereference the device map we need to null out the 00454 // processes device map pointer, and decrement its ref count 00455 // If the ref count goes to zero we can free up the memory 00456 // and dereference the dos device directory object 00457 // 00458 00459 ExAcquireSpinLock( &ObpDeviceMapLock, &OldIrql ); 00460 00461 Process->DeviceMap = NULL; 00462 DeviceMap->ReferenceCount--; 00463 00464 if (DeviceMap->ReferenceCount == 0) { 00465 00466 DeviceMap->DosDevicesDirectory->DeviceMap = NULL; 00467 00468 ExReleaseSpinLock( &ObpDeviceMapLock, OldIrql ); 00469 00470 ObDereferenceObject( DeviceMap->DosDevicesDirectory ); 00471 00472 ExFreePool( DeviceMap ); 00473 00474 } else { 00475 00476 ExReleaseSpinLock( &ObpDeviceMapLock, OldIrql ); 00477 } 00478 } 00479 00480 // 00481 // And return to our caller 00482 // 00483 00484 return; 00485 }

VOID ObInheritDeviceMap IN PEPROCESS  NewProcess,
IN PEPROCESS ParentProcess  OPTIONAL
 

Definition at line 343 of file obdevmap.c.

References NULL, ObpDeviceMapLock, ObSystemDeviceMap, and _DEVICE_MAP::ReferenceCount.

Referenced by PspCreateProcess().

00350 : 00351 00352 This function is called at process initialization time to inherit the 00353 device map for a process. If no parent process, then inherits from 00354 the system device map. 00355 00356 Arguments: 00357 00358 NewProcess - Supplies the process being initialized that needs a new 00359 dos device map 00360 00361 ParentProcess - - Optionally specifies the parent process whose device 00362 map we inherit. This process if specified must have a device map 00363 00364 Return Value: 00365 00366 None. 00367 00368 --*/ 00369 00370 { 00371 PDEVICE_MAP DeviceMap; 00372 KIRQL OldIrql; 00373 00374 // 00375 // If we are called with a parent process then grab its device map 00376 // otherwise grab the system wide device map and check that is does 00377 // exist 00378 // 00379 00380 if (ParentProcess) { 00381 00382 DeviceMap = ParentProcess->DeviceMap; 00383 00384 } else { 00385 00386 // 00387 // Note: WindowStation guys may want a callout here to get the 00388 // device map to use for this case. 00389 // 00390 00391 DeviceMap = ObSystemDeviceMap; 00392 00393 if (DeviceMap == NULL) { 00394 00395 return; 00396 } 00397 } 00398 00399 // 00400 // With the device map bumps its reference count and add it to the 00401 // new process 00402 // 00403 00404 ExAcquireSpinLock( &ObpDeviceMapLock, &OldIrql ); 00405 00406 DeviceMap->ReferenceCount++; 00407 NewProcess->DeviceMap = DeviceMap; 00408 00409 ExReleaseSpinLock( &ObpDeviceMapLock, OldIrql ); 00410 00411 return; 00412 }

NTSTATUS ObQueryDeviceMapInformation IN PEPROCESS TargetProcess  OPTIONAL,
OUT PPROCESS_DEVICEMAP_INFORMATION  DeviceMapInformation
 

Definition at line 236 of file obdevmap.c.

References _DEVICE_MAP::DriveMap, EXCEPTION_EXECUTE_HANDLER, NTSTATUS(), NULL, ObpDeviceMapLock, ObSystemDeviceMap, and Status.

Referenced by NtQueryInformationProcess().

00243 : 00244 00245 This function queries information from the device map associated with the 00246 specified process. The returned information contains a bit map indicating 00247 which drive letters are defined in the associated object directory, along 00248 with an array of drive types that give the type of each drive letter. 00249 00250 Arguments: 00251 00252 TargetProcess - Specifies the target process to retreive the device map 00253 from. If not specified then we return the global default device map 00254 00255 DeviceMapInformation - Specifies the location where to store the results. 00256 00257 Return Value: 00258 00259 Returns one of the following status codes: 00260 00261 STATUS_SUCCESS - normal, successful completion. 00262 00263 STATUS_END_OF_FILE - The specified process was not associated with 00264 a device map. 00265 00266 STATUS_ACCESS_VIOLATION - The DeviceMapInformation buffer pointer 00267 value specified an invalid address. 00268 00269 --*/ 00270 00271 { 00272 NTSTATUS Status; 00273 PDEVICE_MAP DeviceMap; 00274 KIRQL OldIrql; 00275 PROCESS_DEVICEMAP_INFORMATION LocalMapInformation; 00276 00277 // 00278 // Check if the caller gave us a target process and if not then use 00279 // the globally defined one 00280 // 00281 00282 if (ARGUMENT_PRESENT( TargetProcess )) { 00283 00284 DeviceMap = TargetProcess->DeviceMap; 00285 00286 } else { 00287 00288 DeviceMap = ObSystemDeviceMap; 00289 } 00290 00291 // 00292 // If we do not have a device map then we'll return an error otherwise 00293 // we simply copy over the device map structure (bitmap and drive type 00294 // array) into the output buffer 00295 // 00296 00297 if (DeviceMap == NULL) { 00298 00299 Status = STATUS_END_OF_FILE; 00300 00301 } else { 00302 00303 Status = STATUS_SUCCESS; 00304 00305 // 00306 // First, while using a spinlock to protect the device map from 00307 // going away we will make local copy of the information. 00308 // 00309 00310 ExAcquireSpinLock( &ObpDeviceMapLock, &OldIrql ); 00311 00312 RtlMoveMemory( &LocalMapInformation.Query, 00313 &DeviceMap->DriveMap, 00314 sizeof( DeviceMapInformation->Query )); 00315 00316 ExReleaseSpinLock( &ObpDeviceMapLock, OldIrql ); 00317 00318 // 00319 // Now we can copy the information to the caller buffer using 00320 // a try-except to guard against the output buffer changing. 00321 // Note that the caller must have already probed the buffer 00322 // for write. 00323 // 00324 00325 try { 00326 00327 RtlMoveMemory( &DeviceMapInformation->Query, 00328 &LocalMapInformation.Query, 00329 sizeof( DeviceMapInformation->Query )); 00330 00331 } except( EXCEPTION_EXECUTE_HANDLER ) { 00332 00333 Status = GetExceptionCode(); 00334 } 00335 00336 } 00337 00338 return Status; 00339 }

NTSTATUS ObSetDeviceMap IN PEPROCESS TargetProcess  OPTIONAL,
IN HANDLE  DirectoryHandle
 

Definition at line 30 of file obdevmap.c.

References _EPROCESS::DeviceMap, _OBJECT_DIRECTORY::DeviceMap, DirectoryHandle, ExAllocatePoolWithTag, Handle, NonPagedPool, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceDeviceMap(), ObDereferenceObject, ObpDeviceMapLock, ObpDirectoryObjectType, ObReferenceObjectByHandle(), ObSystemDeviceMap, PAGED_CODE, PsGetCurrentProcess, _DEVICE_MAP::ReferenceCount, and Status.

Referenced by NtSetInformationProcess(), and ObpCreateDosDevicesDirectory().

00037 : 00038 00039 This function sets the device map for the specified process, using 00040 the specified object directory. A device map is a structure 00041 associated with an object directory and a process. When the object 00042 manager sees a references to a name beginning with \??\ or just \??, 00043 then it follows the device map object in the calling process's 00044 EPROCESS structure to get to the object directory to use for that 00045 reference. This allows multiple virtual \?? object directories on 00046 a per process basis. The WindowStation logic will use this 00047 functionality to allocate devices unique to each WindowStation. 00048 00049 Arguments: 00050 00051 TargetProcess - Specifies the target process to associate the device map 00052 with. If null then the current process is used and the directory 00053 becomes the system default dos device map. 00054 00055 DirectoryHandle - Specifies the object directory to associate with the 00056 device map. 00057 00058 00059 Return Value: 00060 00061 Returns one of the following status codes: 00062 00063 STATUS_SUCCESS - normal, successful completion. 00064 00065 STATUS_SHARING_VIOLATION - The specified object directory is already 00066 associated with a device map. 00067 00068 STATUS_INSUFFICIENT_RESOURCES - Unable to allocate pool for the device 00069 map data structure; 00070 00071 STATUS_ACCESS_DENIED - Caller did not have DIRECTORY_TRAVERSE access 00072 to the specified object directory. 00073 00074 --*/ 00075 00076 { 00077 NTSTATUS Status; 00078 POBJECT_DIRECTORY DosDevicesDirectory; 00079 PDEVICE_MAP DeviceMap; 00080 PVOID Object; 00081 HANDLE Handle; 00082 KIRQL OldIrql; 00083 00084 PAGED_CODE(); 00085 00086 // 00087 // Reference the object directory handle and see if it is already 00088 // associated with a device map structure. If so, fail this call. 00089 // 00090 00091 Status = ObReferenceObjectByHandle( DirectoryHandle, 00092 DIRECTORY_TRAVERSE, 00093 ObpDirectoryObjectType, 00094 KeGetPreviousMode(), 00095 &DosDevicesDirectory, 00096 NULL ); 00097 00098 if (!NT_SUCCESS( Status )) { 00099 00100 return( Status ); 00101 } 00102 00103 // 00104 // Capture the device map 00105 // 00106 00107 ExAcquireSpinLock( &ObpDeviceMapLock, &OldIrql ); 00108 00109 DeviceMap = DosDevicesDirectory->DeviceMap; 00110 00111 // 00112 // Check if the directory already has a dos device map 00113 // 00114 00115 if (DeviceMap != NULL) { 00116 00117 // 00118 // Test if the DeviceMap is about to delete and has the 00119 // ReferenceCount 0 00120 // 00121 00122 if (DeviceMap->ReferenceCount != 0) { 00123 00124 // 00125 // We have a dos device map, so setup the target process to be either 00126 // what the caller specified or the current process 00127 // 00128 00129 PEPROCESS Target = TargetProcess; 00130 00131 if (Target == NULL) { 00132 00133 Target = PsGetCurrentProcess(); 00134 } 00135 00136 // 00137 // If the current process already has the exact same dos device map 00138 // then everything is already done and nothing left for us to do. 00139 // 00140 00141 if (Target->DeviceMap == DeviceMap) { 00142 00143 ExReleaseSpinLock( &ObpDeviceMapLock, OldIrql ); 00144 00145 ObDereferenceObject( DosDevicesDirectory ); 00146 00147 return Status; 00148 } 00149 00150 // 00151 // Add a new reference before releasing the spinlock 00152 // to make sure nobody will release the devicemap while 00153 // we try to attach to the process. 00154 // 00155 00156 DeviceMap->ReferenceCount++; 00157 00158 ExReleaseSpinLock( &ObpDeviceMapLock, OldIrql ); 00159 00160 // 00161 // We can dereference the target processes device map because it 00162 // no longer will have it's old dos device map. 00163 // 00164 00165 ObDereferenceDeviceMap ( Target ); 00166 00167 // 00168 // Now setup the new device map that we were feed in. We lock it 00169 // bump its ref count, make the targe process point to it, unlock it, 00170 // and return to our caller 00171 // 00172 00173 ExAcquireSpinLock( &ObpDeviceMapLock, &OldIrql ); 00174 00175 Target->DeviceMap = DeviceMap; 00176 00177 ExReleaseSpinLock( &ObpDeviceMapLock, OldIrql ); 00178 00179 ObDereferenceObject( DosDevicesDirectory ); 00180 00181 return Status; 00182 } 00183 } 00184 00185 ExReleaseSpinLock( &ObpDeviceMapLock, OldIrql ); 00186 00187 // 00188 // The input directory does not have a dos device map. so we'll 00189 // allocate and initialize a new device map structure. 00190 // 00191 00192 DeviceMap = ExAllocatePoolWithTag( NonPagedPool, sizeof( *DeviceMap ), 'mDbO' ); 00193 00194 if (DeviceMap == NULL) { 00195 00196 ObDereferenceObject( DosDevicesDirectory ); 00197 Status = STATUS_INSUFFICIENT_RESOURCES; 00198 00199 } else { 00200 00201 RtlZeroMemory( DeviceMap, sizeof( *DeviceMap ) ); 00202 00203 DeviceMap->ReferenceCount = 1; 00204 DeviceMap->DosDevicesDirectory = DosDevicesDirectory; 00205 00206 DosDevicesDirectory->DeviceMap = DeviceMap; 00207 00208 // 00209 // If the caller specified a target process then remove the 00210 // processes device map if in use and replace it with the new 00211 // one, otherwise set this new device map to the system wide one 00212 // and put it into the current process 00213 // 00214 00215 if (TargetProcess != NULL) { 00216 00217 ObDereferenceDeviceMap ( TargetProcess ); 00218 00219 TargetProcess->DeviceMap = DeviceMap; 00220 00221 } else { 00222 00223 ObSystemDeviceMap = DeviceMap; 00224 00225 ObDereferenceDeviceMap ( PsGetCurrentProcess() ); 00226 00227 PsGetCurrentProcess()->DeviceMap = DeviceMap; 00228 } 00229 } 00230 00231 return( Status ); 00232 }


Generated on Sat May 15 19:44:57 2004 for test by doxygen 1.3.7