Example #1
0
VOID
KdpWriteIoSpace (
    IN PDBGKD_MANIPULATE_STATE m,
    IN PSTRING AdditionalData,
    IN PCONTEXT Context
    )

/*++

Routine Description:

    This function is called in response of a write io space state
    manipulation message.  Its function is to write to system io
    locations.

Arguments:

    m - Supplies the state manipulation message.

    AdditionalData - Supplies any additional data for the message.

    Context - Supplies the current context.

Return Value:

    None.

--*/

{
    PDBGKD_READ_WRITE_IO a = &m->u.ReadWriteIo;
    STRING MessageHeader;
    PUCHAR b;
    PUSHORT s;
    PULONG l;

    MessageHeader.Length = sizeof(*m);
    MessageHeader.Buffer = (PCHAR)m;

    ASSERT(AdditionalData->Length == 0);

    m->ReturnStatus = STATUS_SUCCESS;

    //
    // Check Size and Alignment
    //

    switch ( a->DataSize ) {
        case 1:
            b = (PUCHAR)MmDbgWriteCheck(a->IoAddress);
            if ( b ) {
                WRITE_REGISTER_UCHAR(b,(UCHAR)a->DataValue);
            } else {
                m->ReturnStatus = STATUS_ACCESS_VIOLATION;
            }
            break;
        case 2:
            if ((ULONG)a->IoAddress & 1 ) {
                m->ReturnStatus = STATUS_DATATYPE_MISALIGNMENT;
            } else {
                s = (PUSHORT)MmDbgWriteCheck(a->IoAddress);
                if ( s ) {
                    WRITE_REGISTER_USHORT(s,(USHORT)a->DataValue);
                } else {
                    m->ReturnStatus = STATUS_ACCESS_VIOLATION;
                }
            }
            break;
        case 4:
            if ((ULONG)a->IoAddress & 3 ) {
                m->ReturnStatus = STATUS_DATATYPE_MISALIGNMENT;
            } else {
                l = (PULONG)MmDbgWriteCheck(a->IoAddress);
                if ( l ) {
                    WRITE_REGISTER_ULONG(l,a->DataValue);
                } else {
                    m->ReturnStatus = STATUS_ACCESS_VIOLATION;
                }
            }
            break;
        default:
            m->ReturnStatus = STATUS_INVALID_PARAMETER;
    }

    KdpSendPacket(
        PACKET_TYPE_KD_STATE_MANIPULATE,
        &MessageHeader,
        NULL
        );
}
Example #2
0
ULONG
KdpMoveMemory (
    IN PCHAR Destination,
    IN PCHAR Source,
    IN ULONG Length
    )

/*++

Routine Description:

    This routine moves data to or from the message buffer and returns the
    actual length of the information that was moved. As data is moved, checks
    are made to ensure that the data is resident in memory and a page fault
    will not occur. If a page fault would occur, then the move is truncated.

Arguments:

    Destination  - Supplies a pointer to destination of the move operation.

    Source - Supplies a pointer to the source of the move operation.

    Length - Supplies the length of the move operation.

Return Value:

    The actual length of the move is returned as the fucntion value.

--*/

{

    PVOID Address1;
    PVOID Address2;
    ULONG ActualLength;
    ULONG_PTR Opaque;

    //
    // If the length is greater than the size of the message buffer, then
    // reduce the length to the size of the message buffer.
    //

    if (Length > KDP_MESSAGE_BUFFER_SIZE) {
        Length = KDP_MESSAGE_BUFFER_SIZE;
    }

    //
    // Move the source information to the destination address.
    //

    ActualLength = Length;

    while (((ULONG_PTR)Source & 3) && (Length > 0)) {

    //
    // Check to determine if the move will succeed before actually performing
    // the operation.
    //

        Address1 = MmDbgWriteCheck((PVOID)Destination, &Opaque);
        Address2 = MmDbgReadCheck((PVOID)Source);
        if ((Address1 == NULL) || (Address2 == NULL)) {
            break;
        }
        *(PCHAR)Address1 = *(PCHAR)Address2;
        MmDbgReleaseAddress((PVOID)Destination, Opaque);
        Destination += 1;
        Source += 1;
        Length -= 1;
    }

    while (Length > 3) {

    //
    // Check to determine if the move will succeed before actually performing
    // the operation.
    //

        Address1 = MmDbgWriteCheck((PVOID)Destination, &Opaque);
        Address2 = MmDbgReadCheck((PVOID)Source);
        if ((Address1 == NULL) || (Address2 == NULL)) {
            break;
        }
        *(ULONG UNALIGNED *)Address1 = *(PULONG)Address2;
        MmDbgReleaseAddress((PVOID)Destination, Opaque);
        Destination += 4;
        Source += 4;
        Length -= 4;

    }

    while (Length > 0) {

    //
    // Check to determine if the move will succeed before actually performing
    // the operation.
    //

        Address1 = MmDbgWriteCheck((PVOID)Destination, &Opaque);
        Address2 = MmDbgReadCheck((PVOID)Source);
        if ((Address1 == NULL) || (Address2 == NULL)) {
            break;
        }
        *(PCHAR)Address1 = *(PCHAR)Address2;
        MmDbgReleaseAddress((PVOID)Destination, Opaque);
        Destination += 1;
        Source += 1;
        Length -= 1;
    }

    //
    // Flush the instruction cache in case the write was into the instruction
    // stream.
    //

    KeSweepCurrentIcache();
    return ActualLength - Length;
}