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
00088
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
00105
00106
00107 ExAcquireSpinLock( &ObpDeviceMapLock, &OldIrql );
00108
00109 DeviceMap = DosDevicesDirectory->
DeviceMap;
00110
00111
00112
00113
00114
00115
if (DeviceMap !=
NULL) {
00116
00117
00118
00119
00120
00121
00122
if (DeviceMap->
ReferenceCount != 0) {
00123
00124
00125
00126
00127
00128
00129
PEPROCESS Target = TargetProcess;
00130
00131
if (Target ==
NULL) {
00132
00133 Target =
PsGetCurrentProcess();
00134 }
00135
00136
00137
00138
00139
00140
00141
if (Target->
DeviceMap == DeviceMap) {
00142
00143 ExReleaseSpinLock( &ObpDeviceMapLock, OldIrql );
00144
00145
ObDereferenceObject( DosDevicesDirectory );
00146
00147
return Status;
00148 }
00149
00150
00151
00152
00153
00154
00155
00156 DeviceMap->
ReferenceCount++;
00157
00158 ExReleaseSpinLock( &ObpDeviceMapLock, OldIrql );
00159
00160
00161
00162
00163
00164
00165
ObDereferenceDeviceMap ( Target );
00166
00167
00168
00169
00170
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
00189
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
00210
00211
00212
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 }