コード例 #1
0
ファイル: kill.c プロジェクト: CSRedRat/reactos-playground
VOID
NTAPI
PspDeleteProcess(IN PVOID ObjectBody)
{
    PEPROCESS Process = (PEPROCESS)ObjectBody;
    KAPC_STATE ApcState;
    PAGED_CODE();
    PSTRACE(PS_KILL_DEBUG, "ObjectBody: %p\n", ObjectBody);
    PSREFTRACE(Process);

    /* Check if it has an Active Process Link */
    if (Process->ActiveProcessLinks.Flink)
    {
        /* Remove it from the Active List */
        KeAcquireGuardedMutex(&PspActiveProcessMutex);
        RemoveEntryList(&Process->ActiveProcessLinks);
        Process->ActiveProcessLinks.Flink = NULL;
        Process->ActiveProcessLinks.Blink = NULL;
        KeReleaseGuardedMutex(&PspActiveProcessMutex);
    }

    /* Check for Auditing information */
    if (Process->SeAuditProcessCreationInfo.ImageFileName)
    {
        /* Free it */
        ExFreePoolWithTag(Process->SeAuditProcessCreationInfo.ImageFileName,
                          TAG_SEPA);
        Process->SeAuditProcessCreationInfo.ImageFileName = NULL;
    }

    /* Check if we have a job */
    if (Process->Job)
    {
        /* Remove the process from the job */
        PspRemoveProcessFromJob(Process, Process->Job);

        /* Dereference it */
        ObDereferenceObject(Process->Job);
        Process->Job = NULL;
    }

    /* Increase the stack count */
    Process->Pcb.StackCount++;

    /* Check if we have a debug port */
    if (Process->DebugPort)
    {
        /* Deference the Debug Port */
        ObDereferenceObject(Process->DebugPort);
        Process->DebugPort = NULL;
    }

    /* Check if we have an exception port */
    if (Process->ExceptionPort)
    {
        /* Deference the Exception Port */
        ObDereferenceObject(Process->ExceptionPort);
        Process->ExceptionPort = NULL;
    }

    /* Check if we have a section object */
    if (Process->SectionObject)
    {
        /* Deference the Section Object */
        ObDereferenceObject(Process->SectionObject);
        Process->SectionObject = NULL;
    }

#if defined(_X86_)
    /* Clean Ldt and Vdm objects */
    PspDeleteLdt(Process);
    PspDeleteVdmObjects(Process);
#endif

    /* Delete the Object Table */
    if (Process->ObjectTable)
    {
        /* Attach to the process */
        KeStackAttachProcess(&Process->Pcb, &ApcState);

        /* Kill the Object Info */
        ObKillProcess(Process);

        /* Detach */
        KeUnstackDetachProcess(&ApcState);
    }

    /* Check if we have an address space, and clean it */
    if (Process->HasAddressSpace)
    {
        /* Attach to the process */
        KeStackAttachProcess(&Process->Pcb, &ApcState);

        /* Clean the Address Space */
        PspExitProcess(FALSE, Process);

        /* Detach */
        KeUnstackDetachProcess(&ApcState);

        /* Completely delete the Address Space */
        MmDeleteProcessAddressSpace(Process);
    }

    /* See if we have a PID */
    if (Process->UniqueProcessId)
    {
        /* Delete the PID */
        if (!(ExDestroyHandle(PspCidTable, Process->UniqueProcessId, NULL)))
        {
            /* Something wrong happened, bugcheck */
            KeBugCheck(CID_HANDLE_DELETION);
        }
    }

    /* Cleanup security information */
    PspDeleteProcessSecurity(Process);

    /* Check if we have kept information on the Working Set */
    if (Process->WorkingSetWatch)
    {
        /* Free it */
        ExFreePool(Process->WorkingSetWatch);

        /* And return the quota it was taking up */
        PsReturnProcessNonPagedPoolQuota(Process, 0x2000);
    }

    /* Dereference the Device Map */
    ObDereferenceDeviceMap(Process);

    /* Destroy the Quota Block */
    PspDestroyQuotaBlock(Process);
}
コード例 #2
0
ファイル: obdevmap.c プロジェクト: conioh/os-design
NTSTATUS
ObSetDeviceMap (
    IN PEPROCESS TargetProcess OPTIONAL,
    IN HANDLE DirectoryHandle
    )

/*++

Routine Description:

    This function sets the device map for the specified process, using
    the specified object directory.  A device map is a structure
    associated with an object directory and a process.  When the object
    manager sees a references to a name beginning with \??\ or just \??,
    then it follows the device map object in the calling process's
    EPROCESS structure to get to the object directory to use for that
    reference.  This allows multiple virtual \??  object directories on
    a per process basis.  The WindowStation logic will use this
    functionality to allocate devices unique to each WindowStation.

Arguments:

    TargetProcess - Specifies the target process to associate the device map
        with.  If null then the current process is used and the directory
        becomes the system default dos device map.

    DirectoryHandle - Specifies the object directory to associate with the
        device map.


Return Value:

    Returns one of the following status codes:

        STATUS_SUCCESS - normal, successful completion.

        STATUS_SHARING_VIOLATION - The specified object directory is already
            associated with a device map.

        STATUS_INSUFFICIENT_RESOURCES - Unable to allocate pool for the device
            map data structure;

        STATUS_ACCESS_DENIED - Caller did not have DIRECTORY_TRAVERSE access
            to the specified object directory.

--*/

{
    NTSTATUS Status;
    POBJECT_DIRECTORY DosDevicesDirectory;
    PDEVICE_MAP DeviceMap;
    PVOID Object;
    HANDLE Handle;
    KIRQL OldIrql;

    PAGED_CODE();

    //
    //  Reference the object directory handle and see if it is already
    //  associated with a device map structure.  If so, fail this call.
    //

    Status = ObReferenceObjectByHandle( DirectoryHandle,
                                        DIRECTORY_TRAVERSE,
                                        ObpDirectoryObjectType,
                                        KeGetPreviousMode(),
                                        &DosDevicesDirectory,
                                        NULL );

    if (!NT_SUCCESS( Status )) {

        return( Status );
    }

    //
    //  Capture the device map
    //
    
    ExAcquireSpinLock( &ObpDeviceMapLock, &OldIrql );
    
    DeviceMap = DosDevicesDirectory->DeviceMap;
    
    //
    //  Check if the directory already has a dos device map
    //
    
    if (DeviceMap != NULL) {
        
        //
        //  Test if the DeviceMap is about to delete and has the
        //  ReferenceCount 0
        //
    
        if (DeviceMap->ReferenceCount != 0) {
        
            //
            //  We have a dos device map, so setup the target process to be either
            //  what the caller specified or the current process
            //

            PEPROCESS Target = TargetProcess;

            if (Target == NULL) {

                Target = PsGetCurrentProcess();
            }

            //
            //  If the current process already has the exact same dos device map
            //  then everything is already done and nothing left for us to do.
            //

            if (Target->DeviceMap == DeviceMap) {

                ExReleaseSpinLock( &ObpDeviceMapLock, OldIrql );
                
                ObDereferenceObject( DosDevicesDirectory );

                return Status;
            }

            //
            //  Add a new reference before releasing the spinlock
            //  to make sure nobody will release the devicemap while
            //  we try to attach to the process.
            //
            
            DeviceMap->ReferenceCount++;

            ExReleaseSpinLock( &ObpDeviceMapLock, OldIrql );
        
            //
            //  We can dereference the target processes device map because it
            //  no longer will have it's old dos device map.
            //

            ObDereferenceDeviceMap ( Target );

            //
            //  Now setup the new device map that we were feed in.  We lock it
            //  bump its ref count, make the targe process point to it, unlock it,
            //  and return to our caller
            //

            ExAcquireSpinLock( &ObpDeviceMapLock, &OldIrql );

            Target->DeviceMap = DeviceMap;

            ExReleaseSpinLock( &ObpDeviceMapLock, OldIrql );

            ObDereferenceObject( DosDevicesDirectory );

            return Status;
        }
    }

    ExReleaseSpinLock( &ObpDeviceMapLock, OldIrql );
    
    //
    //  The input directory does not have a dos device map. so we'll
    //  allocate and initialize a new device map structure.
    //

    DeviceMap = ExAllocatePoolWithTag( NonPagedPool, sizeof( *DeviceMap ), 'mDbO' );

    if (DeviceMap == NULL) {

        ObDereferenceObject( DosDevicesDirectory );
        Status = STATUS_INSUFFICIENT_RESOURCES;

    } else {

        RtlZeroMemory( DeviceMap, sizeof( *DeviceMap ) );

        DeviceMap->ReferenceCount = 1;
        DeviceMap->DosDevicesDirectory = DosDevicesDirectory;

        DosDevicesDirectory->DeviceMap = DeviceMap;

        //
        //  If the caller specified a target process then remove the
        //  processes device map if in use and replace it with the new
        //  one, otherwise set this new device map to the system wide one
        //  and put it into the current process
        //

        if (TargetProcess != NULL) {

            ObDereferenceDeviceMap ( TargetProcess );

            TargetProcess->DeviceMap = DeviceMap;

        } else {

            ObSystemDeviceMap = DeviceMap;

            ObDereferenceDeviceMap ( PsGetCurrentProcess() );

            PsGetCurrentProcess()->DeviceMap = DeviceMap;
        }
    }

    return( Status );
}