Task 608: .RDP File Format

Task 608: .RDP File Format

File Format Specifications for .RDP

The .RDP file format is a text-based configuration file used by Microsoft's Remote Desktop Connection. It is essentially an INI-like format with lines in the structure propertyname:type:value, where:

  • propertyname is the key (e.g., "full address").
  • type is s for string or i for integer (some advanced properties may use b for binary, but they are rare and not listed in the official supported properties).
  • value is the setting value.

The file is plain text, UTF-8 encoded, and can be opened with any text editor. It does not have a magic number or binary header; it's purely key-value pairs. The specifications are documented by Microsoft for supported properties, and the format is not encrypted or compressed.

  1. List of all the properties of this file format intrinsic to its file system:

Based on the official Microsoft documentation for supported RDP properties, here is a comprehensive list of properties. These are the keys intrinsic to the file format, along with their types, default values, possible values, and descriptions. Properties are grouped by category for clarity. Note that "intrinsic to its file system" is interpreted as the configuration properties defined in the file format itself, as .RDP is not a binary file system format but a configuration file.

Connections

  • alternate full address: type=s, default=None, possible values=valid hostname/IPv4/IPv6 address, description=Alternate name or IP of the remote computer.
  • alternate shell: type=s, default=None, possible values=valid executable path, description=Program to start as shell instead of explorer.
  • authentication level: type=i, default=3, possible values=0-3, description=Server authentication level settings.
  • disableconnectionsharing: type=i, default=0, possible values=0-1, description=Whether to reconnect to existing session or start new.
  • domain: type=s, default=None, possible values=valid domain name, description=Active Directory domain for user account.
  • enablecredsspsupport: type=i, default=1, possible values=0-1, description=Use CredSSP for authentication if available.
  • enablerdsaadauth: type=i, default=0, possible values=0-1, description=Use Microsoft Entra authentication for remote PC.
  • full address: type=s, default=None, possible values=valid hostname/IPv4/IPv6 address, description=Hostname or IP of the remote computer (mandatory).
  • gatewaycredentialssource: type=i, default=0, possible values=0-5, description=Authentication method for Remote Desktop gateway.
  • gatewayhostname: type=s, default=None, possible values=valid hostname/IPv4/IPv6 address, description=Host name of Remote Desktop gateway.
  • gatewayprofileusagemethod: type=i, default=0, possible values=0-1, description=Use default or explicit Remote Desktop gateway settings.
  • gatewayusagemethod: type=i, default=0, possible values=0-4, description=Whether to use Remote Desktop gateway and how.
  • kdcproxyname: type=s, default=None, possible values=valid KDC proxy FQDN, description=Fully qualified domain name of KDC proxy.
  • promptcredentialonce: type=i, default=1, possible values=0-1, description=Save credentials for both gateway and remote computer.
  • targetisaadjoined: type=i, default=0, possible values=0-1, description=Allow connections to Microsoft Entra joined hosts with username/password.
  • username: type=s, default=None, possible values=valid username, description=User account name for sign-in.

Session behavior

  • autoreconnection enabled: type=i, default=1, possible values=0-1, description=Automatically reconnect if connection drops.
  • bandwidthautodetect: type=i, default=1, possible values=0-1, description=Use automatic network bandwidth detection.
  • compression: type=i, default=1, possible values=0-1, description=Enable bulk compression for data transmission.
  • networkautodetect: type=i, default=1, possible values=0-1, description=Enable automatic network type detection.
  • videoplaybackmode: type=i, default=1, possible values=0-1, description=Use RDP-efficient multimedia streaming for video playback.

Device redirection

  • audiocapturemode: type=i, default=0, possible values=0-1, description=Enable audio input redirection.
  • audiomode: type=i, default=0, possible values=0-2, description=Where to play audio (local, remote, or none).
  • camerastoredirect: type=s, default=None, possible values=*, device path, or -, description=Which cameras to redirect.
  • devicestoredirect: type=s, default=, possible values=, device path, or DynamicDevices, description=Redirect MTP/PTP peripherals like cameras.
  • drivestoredirect: type=s, default=Empty, possible values=*, DynamicDrives, or drive letters, description=Which drives to redirect.
  • encode redirected video capture: type=i, default=1, possible values=0-1, description=Enable encoding of redirected video.
  • keyboardhook: type=i, default=2, possible values=0-3, description=How Windows key combinations are handled.
  • redirectclipboard: type=i, default=0, possible values=0-1, description=Redirect clipboard.
  • redirectcomports: type=i, default=1, possible values=0-1, description=Redirect serial/COM ports.
  • redirected video capture encoding quality: type=i, default=0, possible values=0-2, description=Quality of encoded video.
  • redirectlocation: type=i, default=0, possible values=0-1, description=Redirect location.
  • redirectprinters: type=i, default=0, possible values=0-1, description=Redirect printers.
  • redirectsmartcards: type=i, default=1, possible values=0-1, description=Redirect smart cards.
  • redirectwebauthn: type=i, default=1, possible values=0-1, description=Redirect WebAuthn requests.
  • usbdevicestoredirect: type=s, default=Empty, possible values=*, GUID, or USBInstanceID, description=Redirect USB devices.

Display settings

  • desktop size id: type=i, default=None (match local), possible values=0-4, description=Predefined desktop dimensions.
  • desktopheight: type=i, default=None (match local), possible values=200-8192, description=Resolution height in pixels.
  • desktopscalefactor: type=i, default=None (match local), possible values=100/125/150/175/200/250/300/400/500, description=Scale factor (deprecated).
  • desktopwidth: type=i, default=None (match local), possible values=200-8192, description=Resolution width in pixels.
  • dynamic resolution: type=i, default=1, possible values=0-1, description=Update resolution on window resize.
  • maximizetocurrentdisplays: type=i, default=0, possible values=0-1, description=Which displays to use for full screen on maximize (multi-monitor).
  • screen mode id: type=i, default=2, possible values=1-2, description=Windowed or full screen.
  • selectedmonitors: type=s, default=None, possible values=comma-separated display IDs, description=Which local displays to use.
  • singlemoninwindowedmode: type=i, default=0, possible values=0-1, description=Switch to single display when exiting full screen (multi-monitor).
  • smart sizing: type=i, default=0, possible values=0-1, description=Scale content to fit window.
  • use multimon: type=i, default=1, possible values=0-1, description=Use multiple displays.

RemoteApp

  • remoteapplicationcmdline: type=s, default=None, possible values=valid command-line parameters, description=Optional command line for RemoteApp.
  • remoteapplicationexpandcmdline: type=i, default=1, possible values=0-1, description=Expand environment variables locally or remotely for command line.
  • remoteapplicationexpandworkingdir: type=i, default=1, possible values=0-1, description=Expand environment variables locally or remotely for working directory.
  • remoteapplicationfile: type=s, default=None, possible values=valid file path, description=File to open in RemoteApp.
  • remoteapplicationicon: type=s, default=None, possible values=.ico file path, description=Icon for RemoteApp.
  • remoteapplicationmode: type=i, default=1, possible values=0-1, description=Launch as RemoteApp session.
  • remoteapplicationname: type=s, default=None, possible values=valid application name, description=Name of RemoteApp.
  1. Two direct download links for files of format .RDP:
  1. Ghost blog embedded HTML JavaScript for drag and drop .RDP file to dump properties:

Here is a self-contained HTML page with embedded JavaScript. You can save this as an .html file and open it in a browser. It allows dragging and dropping a .RDP file, parses it, and dumps all properties to the screen.

RDP File Parser

Drag and Drop .RDP File Parser

Drag and drop .RDP file here
  1. Python class for .RDP file:
import os

class RdpFile:
    def __init__(self, filepath=None):
        self.properties = {}
        if filepath:
            self.read(filepath)

    def read(self, filepath):
        with open(filepath, 'r', encoding='utf-8') as f:
            for line in f:
                line = line.strip()
                if line:
                    parts = line.split(':')
                    if len(parts) == 3:
                        key = parts[0].strip()
                        type_ = parts[1].strip()
                        value = parts[2].strip()
                        if type_ == 'i':
                            value = int(value)
                        # For 's', keep as string; 'b' would be base64.decode, but not in list
                        self.properties[key] = value

    def write(self, filepath):
        with open(filepath, 'w', encoding='utf-8') as f:
            for key, value in self.properties.items():
                type_ = 's' if isinstance(value, str) else 'i'
                f.write(f"{key}:{type_}:{value}\n")

    def print_properties(self):
        for key, value in self.properties.items():
            print(f"{key}: {value}")

# Example usage:
# rdp = RdpFile('sample.rdp')
# rdp.print_properties()
# rdp.write('output.rdp')
  1. Java class for .RDP file:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

public class RdpFile {
    private Map<String, Object> properties = new HashMap<>();

    public RdpFile(String filepath) throws Exception {
        read(filepath);
    }

    public RdpFile() {}

    public void read(String filepath) throws Exception {
        try (BufferedReader br = new BufferedReader(new FileReader(filepath))) {
            String line;
            while ((line = br.readLine()) != null) {
                line = line.trim();
                if (!line.isEmpty()) {
                    String[] parts = line.split(":");
                    if (parts.length == 3) {
                        String key = parts[0].trim();
                        String type = parts[1].trim();
                        String value = parts[2].trim();
                        if ("i".equals(type)) {
                            properties.put(key, Integer.parseInt(value));
                        } else {
                            properties.put(key, value);
                        }
                    }
                }
            }
        }
    }

    public void write(String filepath) throws Exception {
        try (PrintWriter pw = new PrintWriter(filepath, "UTF-8")) {
            for (Map.Entry<String, Object> entry : properties.entrySet()) {
                String key = entry.getKey();
                Object value = entry.getValue();
                String type = (value instanceof String) ? "s" : "i";
                pw.println(key + ":" + type + ":" + value);
            }
        }
    }

    public void printProperties() {
        for (Map.Entry<String, Object> entry : properties.entrySet()) {
            System.out.println(entry.getKey() + ": " + entry.getValue());
        }
    }

    // Example usage:
    // public static void main(String[] args) throws Exception {
    //     RdpFile rdp = new RdpFile("sample.rdp");
    //     rdp.printProperties();
    //     rdp.write("output.rdp");
    // }
}
  1. JavaScript class for .RDP file:
class RdpFile {
    constructor(filepath = null) {
        this.properties = {};
        if (filepath) {
            // Note: JS can't directly read local files without FileReader; this assumes async usage with File object.
            // For console, use with Node.js (requires fs module).
        }
    }

    async read(file) {
        const text = await file.text();
        const lines = text.split('\n');
        lines.forEach(line => {
            line = line.trim();
            if (line) {
                const parts = line.split(':');
                if (parts.length === 3) {
                    const key = parts[0].trim();
                    const type = parts[1].trim();
                    let value = parts[2].trim();
                    if (type === 'i') {
                        value = parseInt(value);
                    }
                    this.properties[key] = value;
                }
            }
        });
    }

    write() {
        let content = '';
        for (const [key, value] of Object.entries(this.properties)) {
            const type = typeof value === 'string' ? 's' : 'i';
            content += `${key}:${type}:${value}\n`;
        }
        return content; // Return string; can be saved via Blob or console.
    }

    printProperties() {
        for (const [key, value] of Object.entries(this.properties)) {
            console.log(`${key}: ${value}`);
        }
    }
}

// Example usage (browser with File):
// const input = document.getElementById('fileInput');
// input.addEventListener('change', async (e) => {
//     const rdp = new RdpFile();
//     await rdp.read(e.target.files[0]);
//     rdp.printProperties();
//     console.log(rdp.write());
// });
  1. C "class" for .RDP file:

Since C doesn't have classes, here's a struct with functions for read, write, and print. Use stdio for console.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_PROPERTIES 100
#define MAX_KEY_LEN 100
#define MAX_VALUE_LEN 256

typedef struct {
    char key[MAX_KEY_LEN];
    char type; // 'i' or 's'
    union {
        int i_val;
        char s_val[MAX_VALUE_LEN];
    } value;
} Property;

typedef struct {
    Property properties[MAX_PROPERTIES];
    int count;
} RdpFile;

void init_rdp(RdpFile *rdp) {
    rdp->count = 0;
}

void read_rdp(RdpFile *rdp, const char *filepath) {
    FILE *f = fopen(filepath, "r");
    if (!f) {
        perror("Failed to open file");
        return;
    }
    char line[512];
    while (fgets(line, sizeof(line), f)) {
        line[strcspn(line, "\n")] = 0; // Strip newline
        char *parts[3];
        char *token = strtok(line, ":");
        int i = 0;
        while (token && i < 3) {
            parts[i++] = token;
            token = strtok(NULL, ":");
        }
        if (i == 3) {
            strncpy(rdp->properties[rdp->count].key, parts[0], MAX_KEY_LEN);
            rdp->properties[rdp->count].type = parts[1][0];
            if (rdp->properties[rdp->count].type == 'i') {
                rdp->properties[rdp->count].value.i_val = atoi(parts[2]);
            } else {
                strncpy(rdp->properties[rdp->count].value.s_val, parts[2], MAX_VALUE_LEN);
            }
            rdp->count++;
        }
    }
    fclose(f);
}

void write_rdp(const RdpFile *rdp, const char *filepath) {
    FILE *f = fopen(filepath, "w");
    if (!f) {
        perror("Failed to open file");
        return;
    }
    for (int i = 0; i < rdp->count; i++) {
        if (rdp->properties[i].type == 'i') {
            fprintf(f, "%s:%c:%d\n", rdp->properties[i].key, rdp->properties[i].type, rdp->properties[i].value.i_val);
        } else {
            fprintf(f, "%s:%c:%s\n", rdp->properties[i].key, rdp->properties[i].type, rdp->properties[i].value.s_val);
        }
    }
    fclose(f);
}

void print_properties(const RdpFile *rdp) {
    for (int i = 0; i < rdp->count; i++) {
        if (rdp->properties[i].type == 'i') {
            printf("%s: %d\n", rdp->properties[i].key, rdp->properties[i].value.i_val);
        } else {
            printf("%s: %s\n", rdp->properties[i].key, rdp->properties[i].value.s_val);
        }
    }
}

// Example usage:
// int main() {
//     RdpFile rdp;
//     init_rdp(&rdp);
//     read_rdp(&rdp, "sample.rdp");
//     print_properties(&rdp);
//     write_rdp(&rdp, "output.rdp");
//     return 0;
// }