00039 :
00040
00041 This function opens a handle to a process object with
the specified
00042 desired access.
00043
00044 The object
is located either by name, or by locating a thread whose
00045 Client
ID matches
the specified Client
ID and then opening that thread's
00046 process.
00047
00048 Arguments:
00049
00050 ProcessHandle - Supplies a pointer to a variable that will receive
00051
the process object handle.
00052
00053 DesiredAccess - Supplies
the desired types of access
for the process
00054 object.
00055
00056
ObjectAttributes - Supplies a pointer to an object attributes structure.
00057 If
the ObjectName field
is specified, then ClientId must not be
00058 specified.
00059
00060 ClientId - Supplies a pointer to a ClientId that
if supplied
00061 specifies
the thread whose process
is to be opened. If
this
00062 argument
is specified, then ObjectName field of
the ObjectAttributes
00063 structure must not be specified.
00064
00065 Return Value:
00066
00067 TBS
00068
00069 --*/
00070
00071 {
00072
00073 HANDLE
Handle;
00074
KPROCESSOR_MODE PreviousMode;
00075
NTSTATUS Status;
00076
PEPROCESS Process;
00077
PETHREAD Thread;
00078 CLIENT_ID CapturedCid;
00079 BOOLEAN ObjectNamePresent;
00080 BOOLEAN ClientIdPresent;
00081
ACCESS_STATE AccessState;
00082
AUX_ACCESS_DATA AuxData;
00083 ULONG Attributes;
00084
00085
PAGED_CODE();
00086
00087
00088
00089
00090
00091
00092 PreviousMode = KeGetPreviousMode();
00093
if (PreviousMode !=
KernelMode) {
00094
00095
00096
00097
00098
00099
00100
try {
00101
00102
ProbeForWriteHandle(ProcessHandle);
00103
00104
ProbeForRead(ObjectAttributes,
00105
sizeof(OBJECT_ATTRIBUTES),
00106
sizeof(ULONG));
00107 ObjectNamePresent = (BOOLEAN)ARGUMENT_PRESENT(
ObjectAttributes->ObjectName);
00108 Attributes =
ObjectAttributes->Attributes;
00109
00110
if (ARGUMENT_PRESENT(ClientId)) {
00111
ProbeForRead(ClientId,
sizeof(CLIENT_ID),
sizeof(ULONG));
00112 CapturedCid = *ClientId;
00113 ClientIdPresent =
TRUE;
00114 }
00115
else {
00116 ClientIdPresent =
FALSE;
00117 }
00118 }
00119 except(EXCEPTION_EXECUTE_HANDLER) {
00120
return GetExceptionCode();
00121 }
00122 }
00123
else {
00124 ObjectNamePresent = (BOOLEAN)ARGUMENT_PRESENT(
ObjectAttributes->ObjectName);
00125 Attributes =
ObjectAttributes->Attributes;
00126
if (ARGUMENT_PRESENT(ClientId)) {
00127 CapturedCid = *ClientId;
00128 ClientIdPresent =
TRUE;
00129 }
00130
else {
00131 ClientIdPresent =
FALSE;
00132 }
00133 }
00134
00135
if ( ObjectNamePresent && ClientIdPresent ) {
00136
return STATUS_INVALID_PARAMETER_MIX;
00137 }
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
Status =
SeCreateAccessState(
00148 &AccessState,
00149 &AuxData,
00150 DesiredAccess,
00151 &
PsProcessType->
TypeInfo.
GenericMapping
00152 );
00153
00154
if ( !
NT_SUCCESS(Status) ) {
00155
00156
return Status;
00157 }
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
if (
SeSinglePrivilegeCheck( SeDebugPrivilege, PreviousMode )) {
00170
00171
if ( AccessState.
RemainingDesiredAccess & MAXIMUM_ALLOWED ) {
00172 AccessState.
PreviouslyGrantedAccess |= PROCESS_ALL_ACCESS;
00173
00174 }
else {
00175
00176 AccessState.
PreviouslyGrantedAccess |= ( AccessState.
RemainingDesiredAccess );
00177 }
00178
00179 AccessState.
RemainingDesiredAccess = 0;
00180
00181 }
00182
00183
if ( ObjectNamePresent ) {
00184
00185
00186
00187
00188
00189
00190
Status =
ObOpenObjectByName(
00191 ObjectAttributes,
00192 PsProcessType,
00193 PreviousMode,
00194 &AccessState,
00195 0,
00196 NULL,
00197 &Handle
00198 );
00199
00200
SeDeleteAccessState( &AccessState );
00201
00202
if (
NT_SUCCESS(Status) ) {
00203
try {
00204 *ProcessHandle =
Handle;
00205 }
00206 except(EXCEPTION_EXECUTE_HANDLER) {
00207
return Status;
00208 }
00209 }
00210
00211
return Status;
00212 }
00213
00214
if ( ClientIdPresent ) {
00215
00216 Thread =
NULL;
00217
if (CapturedCid.UniqueThread) {
00218
Status =
PsLookupProcessThreadByCid(
00219 &CapturedCid,
00220 &Process,
00221 &Thread
00222 );
00223
00224
if ( !
NT_SUCCESS(Status) ) {
00225
SeDeleteAccessState( &AccessState );
00226
return Status;
00227 }
00228 }
00229
else {
00230
Status =
PsLookupProcessByProcessId(
00231 CapturedCid.UniqueProcess,
00232 &Process
00233 );
00234
00235
if ( !
NT_SUCCESS(Status) ) {
00236
SeDeleteAccessState( &AccessState );
00237
return Status;
00238 }
00239 }
00240
00241
00242
00243
00244
00245
Status =
ObOpenObjectByPointer(
00246 Process,
00247 Attributes,
00248 &AccessState,
00249 0,
00250 PsProcessType,
00251 PreviousMode,
00252 &Handle
00253 );
00254
00255
SeDeleteAccessState( &AccessState );
00256
00257
if ( Thread ) {
00258
ObDereferenceObject(Thread);
00259 }
00260
ObDereferenceObject(Process);
00261
00262
if (
NT_SUCCESS(Status) ) {
00263
00264
try {
00265 *ProcessHandle =
Handle;
00266 }
00267 except(EXCEPTION_EXECUTE_HANDLER) {
00268
return Status;
00269 }
00270 }
00271
00272
return Status;
00273
00274 }
00275
00276
return STATUS_INVALID_PARAMETER_MIX;
00277 }