+ NTSTATUS Status = STATUS_INVALID_PARAMETER;
+
+ if((NULL != ThreadHandle)&&(NULL != ObjectAttributes))
+ {
+ PETHREAD EThread = NULL;
+
+ if((ClientId)
+ && (ClientId->UniqueProcess)
+ && (ClientId->UniqueThread))
+ {
+ // It is an error to specify both
+ // ObjectAttributes.ObjectName
+ // and ClientId.
+ if((ObjectAttributes)
+ && (ObjectAttributes->ObjectName)
+ && (0 < ObjectAttributes->ObjectName->Length))
+ {
+ return(STATUS_INVALID_PARAMETER_MIX);
+ }
+ // Parameters mix OK
+ Status = PsLookupProcessThreadByCid(ClientId,
+ NULL,
+ & EThread);
+ }
+ else if((ObjectAttributes)
+ && (ObjectAttributes->ObjectName)
+ && (0 < ObjectAttributes->ObjectName->Length))
+ {
+ // Three Ob attributes are forbidden
+ if(!(ObjectAttributes->Attributes &
+ (OBJ_PERMANENT | OBJ_EXCLUSIVE | OBJ_OPENIF)))
+ {
+ Status = ObReferenceObjectByName(ObjectAttributes->ObjectName,
+ ObjectAttributes->Attributes,
+ NULL,
+ DesiredAccess,
+ PsThreadType,
+ UserMode,
+ NULL,
+ (PVOID*) & EThread);
+ }
+ }
+ // EThread may be OK...
+ if(STATUS_SUCCESS == Status)
+ {
+ Status = ObCreateHandle(PsGetCurrentProcess(),
+ EThread,
+ DesiredAccess,
+ FALSE,
+ ThreadHandle);
+ ObDereferenceObject(EThread);
+ }
+ }
+ return(Status);