Package com.lixia.rdp.rdp5

Source Code of com.lixia.rdp.rdp5.VChannels

/* VChannels.java
* Component: ProperJavaRDP
*
* Revision: $Revision: 1.1.1.1 $
* Author: $Author: suvarov $
* Date: $Date: 2007/03/08 00:26:39 $
*
* Copyright (c) 2005 Propero Limited
*
* Purpose: Static store for all registered channels
*/
package com.lixia.rdp.rdp5;

import com.alssoftrd.utils.RDPConnection;
import java.io.IOException;
import java.lang.reflect.Array;


import com.lixia.rdp.MCS;
import com.lixia.rdp.RdesktopException;
import com.lixia.rdp.crypto.CryptoException;
import com.lixia.rdp.Package.RdpPackage;

public class VChannels {

//    protected static Logger logger = Logger.getLogger("InputJPanel");

    /* Sound format constants */
    public static final int WAVE_FORMAT_PCM = 1;

    public static final int WAVE_FORMAT_ADPCM = 2;

    public static final int WAVE_FORMAT_ALAW = 6;

    public static final int WAVE_FORMAT_MULAW = 7;

    /* Virtual channel options */
    public static final int CHANNEL_OPTION_INITIALIZED = 0x80000000;

    public static final int CHANNEL_OPTION_ENCRYPT_RDP = 0x40000000;

    public static final int CHANNEL_OPTION_COMPRESS_RDP = 0x00800000;

    public static final int CHANNEL_OPTION_SHOW_PROTOCOL = 0x00200000;

    /* NT status codes for RDPDR */
    public static final int STATUS_SUCCESS = 0x00000000;

    public static final int STATUS_INVALID_PARAMETER = 0xc000000d;

    public static final int STATUS_INVALID_DEVICE_REQUEST = 0xc0000010;

    public static final int STATUS_ACCESS_DENIED = 0xc0000022;

    public static final int MAX_CHANNELS = 6;

    public static final int CHANNEL_CHUNK_LENGTH = 1600;//the value is 1600,don't change by lijanaan 2009.12.14

    public static final int CHANNEL_FLAG_FIRST = 0x01;

    public static final int CHANNEL_FLAG_LAST = 0x02;

    public static final int CHANNEL_FLAG_SHOW_PROTOCOL = 0x10;

    private VChannel channels[] = new VChannel[MAX_CHANNELS];

    private int num_channels;

    public int num_channels() {
        return num_channels;
    }

    private byte[] fragment_buffer = null;

    /**
     * Obtain the MCS ID for a specific numbered channel
     *
     * @param c Channel number for which to obtain MCS ID
     * @return MCS ID associated with the supplied channel number
     */
    public int mcs_id(int c) {
        return MCS.MCS_GLOBAL_CHANNEL + 1 + c;
    }

    /**
     * Initialise the maximum number of Virtual Channels
     */
    public VChannels() {
        channels = new VChannel[MAX_CHANNELS];
    }

    /**
     * Retrieve the VChannel object for the numbered channel
     *
     * @param c Channel number
     * @return The requested Virtual Channel
     */
    public VChannel channel(int c) {
        if (c < num_channels) {
            return channels[c];
        } else {
            return null;
        }
    }

    /**
     * Retrieve the VChannel object for the specified MCS channel ID
     *
     * @param channelno MCS ID for the required channel
     * @return Virtual Channel associated with the supplied MCS ID
     */
    public VChannel find_channel_by_channelno(int channelno) {
        if (channelno > MCS.MCS_GLOBAL_CHANNEL + num_channels) {
//            logger.warn("Channel " + channelno + " not defined. Highest channel defined is " + MCS.MCS_GLOBAL_CHANNEL + num_channels);
            return null;
        } else {
            return channels[channelno - MCS.MCS_GLOBAL_CHANNEL - 1];
        }
    }

    /**
     * Remove all registered virtual channels
     */
    public void clear() {
        channels = new VChannel[MAX_CHANNELS];
        num_channels = 0;
    }

    /**
     * Register a new virtual channel
     *
     * @param v Virtual channel to be registered
     * @return True if successful
     * @throws RdesktopException
     */
    public boolean register(VChannel v) throws RdesktopException {
        if (!RDPConnection.conf.use_rdp5) {
            return false;
        }
        if (num_channels >= MAX_CHANNELS) {
            throw new RdesktopException("Channel table full. Could not register channel.");
        }
        channels[num_channels] = v;
        v.set_mcs_id(MCS.MCS_GLOBAL_CHANNEL + 1 + num_channels);
        num_channels++;

        return true;
    }

    /**
     * Process a packet sent on a numbered channel
     *
     * @param data Packet sent to channel
     * @param mcsChannel Number specified for channel
     * @throws RdesktopException
     * @throws IOException
     * @throws CryptoException
     */
    public void channel_process(RdpPackage data, int mcsChannel) throws RdesktopException, IOException, CryptoException {
        int length, flags;
        int thislength = 0;
        VChannel channel = null;
        int i;
        for (i = 0; i < num_channels; i++) {
            if (mcs_id(i) == mcsChannel) {
                channel = channels[i];
                break;
            }
        }
        if (i >= num_channels) {
            return;
        }
        length = data.getLittleEndian32();
        flags = data.getLittleEndian32();
        if (((flags & CHANNEL_FLAG_FIRST) != 0) && ((flags & CHANNEL_FLAG_LAST) != 0)) {
            // single fragment - pass straight up
            channel.process(data);
        } else {
            // append to the defragmentation buffer
            byte[] content = new byte[data.getEnd() - data.getPosition()];
            data.copyToByteArray(content, 0, data.getPosition(), content.length);
            fragment_buffer = append(fragment_buffer, content);
            if ((flags & CHANNEL_FLAG_LAST) != 0) {
                RdpPackage fullpacket = new RdpPackage(fragment_buffer.length);
                fullpacket.copyFromByteArray(fragment_buffer, 0, 0, fragment_buffer.length);
                // process the entire reconstructed packet
                channel.process(fullpacket);
                fragment_buffer = null;
            }

        }
    }

    /**
     * Increase the size of an array
     *
     * @param a Array to expand
     * @param amount Number of elements to add to the array
     * @return Expanded array
     */
    static Object arrayExpand(Object a, int amount) {
        Class cl = a.getClass();
        if (!cl.isArray()) {
            return null;
        }
        int length = Array.getLength(a);
        int newLength = length + amount; // 50% more

        Class componentType = a.getClass().getComponentType();
        Object newArray = Array.newInstance(componentType, newLength);
        System.arraycopy(a, 0, newArray, 0, length);
        return newArray;
    }

    /**
     * Concatenate two byte arrays
     *
     * @param target Contains initial bytes in output
     * @param source Appended to target array
     * @return Concatenation of arrays, target+source
     */
    static byte[] append(byte[] target, byte[] source) {
        if (target == null || target.length <= 0) {
            return source;
        } else if (source == null || source.length <= 0) {
            return target;
        } else {
            byte[] out = (byte[]) arrayExpand(target, source.length);
            System.arraycopy(source, 0, out, target.length, source.length);
            return out;
        }
    }
}
TOP

Related Classes of com.lixia.rdp.rdp5.VChannels

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.