commit 41a52acef812eb13523cbf28b5d630baa38d3c26 Author: Cyd Date: Wed Jul 1 10:42:42 2026 -0500 Deconstruct VncThumbnailViewer 1.4.2 and add self-contained build The shipped VncThumbnailViewerWin1.4.2.exe is a native launcher stub with a Java JAR appended. This commit adds: - src/: full Java source recovered from the bundled .class files (CFR), plus src/summary.txt with decompiler caveats - ANALYSIS.md: architecture, data flow, hosts-file format, and security notes - build-app-image.ps1: reproducible jpackage build that repackages the original classes and bundles a slim jlinked runtime (java.base + java.desktop) into a self-contained native app-image (no Java required on the target) The 74 MB app-image is shipped as a release asset rather than tracked. Co-Authored-By: Claude Opus 4.8 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5926745 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +# Build output (self-contained app-image is shipped as a release asset, not tracked) +/dist/ +/build-tmp/ +*.zip diff --git a/ANALYSIS.md b/ANALYSIS.md new file mode 100644 index 0000000..5c5f319 --- /dev/null +++ b/ANALYSIS.md @@ -0,0 +1,88 @@ +# VncThumbnailViewer 1.4.2 — Deconstruction + +## What it is +A Windows executable (`VncThumbnailViewerWin1.4.2.exe`) that is really a **self-running +Java application**: a native launcher stub with a JAR (ZIP) appended to it. It is a +multi-host **VNC viewer** that shows many remote desktops as a live grid of thumbnails, +and lets you double-click one to open it full size ("solo"). It is derived from the +**TightVNC Java viewer** (2008 vintage), with a custom thumbnail/grid front-end bolted on. + +- Built: 2008-05-19, `Created-By: 1.5.0_13 (Apple Computer)` — targets Java 1.5, AWT UI. +- `Main-Class: VncThumbnailViewer` +- Window title in code: **"DJC Thumbnail Viewer"**. + +## How it was packaged +`file` reports *"Zip archive, with extra data prepended"*. The `.exe` is a launcher stub +followed by a standard JAR. Extracting the ZIP yields 52 entries: the app classes (default +package), plus the bundled `net.n3.nanoxml` XML library. No source shipped — only `.class` +bytecode, which was decompiled with CFR into [src/](src/). + +## Component map (decompiled sources in `src/`) + +### Thumbnail front-end (the custom part) +- **VncThumbnailViewer** — `main()` + top-level `Frame`. Parses CLI args + (`host/port/password/username/encpassword`, repeatable), builds a `GridLayout` whose row + count is `sqrt(n)+1`, rescales all canvases to fit their cell, and manages the "solo" + full-screen frame (double-click a thumbnail → `soloHost`). Also owns the File menu + (Add Host / Load / Save / Exit). +- **VncViewersList** (`extends Vector`) — collection of live viewers + host-list + persistence to/from **XML** via nanoxml. Handles per-connection security types and + optional encryption of saved credentials. `launchViewer(...)` constructs each `VncViewer` + in embedded (non-applet, view-only, auto-scaled) mode. +- **AddHostDialog** — modal add-host dialog; auth choice of none / Password / + *VNC Enc. Password* / MS-Logon. Contains `readEncPassword()`. + +### VNC engine (inherited from TightVNC viewer) +- **VncViewer** — the viewer applet/app: connection setup, handshake, options. +- **RfbProto** (largest, ~1k LOC) — the RFB/VNC wire protocol: handshake, security + negotiation, framebuffer updates, encodings, session recording hooks. +- **VncCanvas** / **VncCanvas2** — draws the framebuffer, decodes encodings (Raw, CopyRect, + RRE, Hextile, ZRLE/Zlib, Tight), handles scaling and input. +- **OptionsFrame**, **ButtonPanel**, **AuthPanel**, **ClipboardFrame**, **ReloginPanel** — UI. +- **RecordingFrame** / **SessionRecorder** — record a session to an `.fbs` file. +- **InStream / MemInStream / ZlibInStream**, **CapabilityInfo / CapsContainer** — protocol + I/O and TightVNC capability negotiation. +- **DesCipher**, **DiffieHellman** — crypto (see below). +- **HTTPConnectSocket(Factory)**, **SocketFactory** — proxy/socket plumbing. +- **net.n3.nanoxml.\*** — third-party XML parser/writer for the hosts file. + +## Data / control flow +1. `main()` (or the Add-Host dialog, or "Load list of hosts") produces `(host, port, + password, username, userdomain)` tuples. +2. `VncViewersList.launchViewer` spins up a `VncViewer` per host, embedded in the grid, + `viewOnly=true`, `autoScale=true`, `scalingFactor=10`. +3. Each `VncViewer`/`RfbProto` connects, authenticates, and streams framebuffer updates + into its `VncCanvas`, which is scaled down to fit its thumbnail cell. +4. Double-click → `soloHost` moves that canvas to a full-screen frame and re-enables input. + +## Hosts file (persistence) format +XML `` containing `` elements with +`Host, Port, SecType, Password, Username`. `SecType`: `1`=none, `2`=VncAuth, +`-6`=MS-Logon; several TightVNC sec-types (5/6/16-19) are recognized but rejected as +"incomplete". If `Encrypted="1"`, the credential fields are DES-encrypted under a +user-supplied passphrase (`HostsFilePasswordDialog`). + +## Security notes (this is a 2008 codebase — expect weak crypto) +- **"VNC Enc. Password"** (`AddHostDialog.readEncPassword`) is the classic VNC password + obfuscation, **not real security**: it DES-*decrypts* the 16-hex-char stored value with + the well-known fixed key `{0x17,0x52,0x6B,0x06,0x23,0x4E,0x58,0x07}`. Anyone with this + key (it's public and right here in the binary) can recover the plaintext password. This + is the same fixed key TightVNC/RealVNC use for `.vnc` files. +- Encrypted hosts files use single **DES** (56-bit, broken) keyed off the user passphrase — + weak by modern standards. +- VncAuth itself is DES challenge-response, inherently weak. +- Passwords are held in plaintext `String`s in memory and passed on the command line + (visible in process listings). Treat any stored credentials as effectively public. + +## To rebuild / run from source +Needs a JDK 1.5–1.8 (uses removed AWT calls like `Component.enable(...)`, `Dialog.show()` +— will warn/fail on modern JDKs without `--release 8`-style tweaks). Roughly: +``` +javac -d out src/*.java src/net/n3/nanoxml/*.java +java -cp out VncThumbnailViewer host port 5900 +``` +Or just run the original: `java -cp VncThumbnailViewerWin1.4.2.exe VncThumbnailViewer` (the +exe is a valid JAR despite the prepended stub, though the stub also lets Windows run it +directly). +``` +``` diff --git a/VncThumbnailViewerWin1.4.2.exe b/VncThumbnailViewerWin1.4.2.exe new file mode 100644 index 0000000..bfe079c Binary files /dev/null and b/VncThumbnailViewerWin1.4.2.exe differ diff --git a/build-app-image.ps1 b/build-app-image.ps1 new file mode 100644 index 0000000..c215635 --- /dev/null +++ b/build-app-image.ps1 @@ -0,0 +1,38 @@ +# Builds a self-contained native app-image (bundled JRE, no Java required on target). +# Requires a JDK 17+ on PATH (needs jar, jdeps, jpackage). Tested with Temurin 21. +# Reuses the ORIGINAL compiled .class files from the shipped exe (identical behavior). +# +# Usage: powershell -ExecutionPolicy Bypass -File build-app-image.ps1 + +$ErrorActionPreference = "Stop" +$root = $PSScriptRoot +$work = Join-Path $root "build-tmp" +$classes = Join-Path $work "classes" +$dist = Join-Path $root "dist" + +Remove-Item $work, $dist -Recurse -Force -ErrorAction SilentlyContinue +New-Item -ItemType Directory -Force $classes | Out-Null + +# 1. Extract the class files (the .exe is a launcher stub + a ZIP/JAR). +Copy-Item (Join-Path $root "VncThumbnailViewerWin1.4.2.exe") (Join-Path $work "app.zip") +Expand-Archive -Path (Join-Path $work "app.zip") -DestinationPath $classes -Force + +# 2. Repackage into a runnable JAR, preserving the original manifest (Main-Class). +$jar = Join-Path $work "VncThumbnailViewer.jar" +$jarInput = Join-Path $work "jarinput" +New-Item -ItemType Directory -Force $jarInput | Out-Null +& jar --create --file $jar --manifest (Join-Path $classes "META-INF\MANIFEST.MF") -C $classes . + +# 3. Determine the minimal module set for a slim runtime. +$mods = (& jdeps --multi-release 21 --ignore-missing-deps --print-module-deps $jar).Trim() +Write-Host "Modules: $mods" + +# 4. Build the native app-image with a jlinked, bundled runtime. +Move-Item $jar $jarInput +& jpackage --type app-image ` + --name "VncThumbnailViewer" --app-version "1.4.2" --vendor "DJC" ` + --input $jarInput --main-jar "VncThumbnailViewer.jar" --main-class "VncThumbnailViewer" ` + --add-modules $mods --dest $dist + +Remove-Item $work -Recurse -Force -ErrorAction SilentlyContinue +Write-Host "Done -> $dist\VncThumbnailViewer\VncThumbnailViewer.exe" diff --git a/src/AddHostDialog.java b/src/AddHostDialog.java new file mode 100644 index 0000000..80869e9 --- /dev/null +++ b/src/AddHostDialog.java @@ -0,0 +1,141 @@ +/* + * Decompiled with CFR 0.152. + */ +import java.awt.Button; +import java.awt.Choice; +import java.awt.Component; +import java.awt.Dialog; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.Frame; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Label; +import java.awt.Point; +import java.awt.TextField; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; + +class AddHostDialog +extends Dialog +implements ActionListener, +ItemListener { + VncThumbnailViewer tnviewer; + TextField hostField; + TextField portField; + TextField usernameField; + TextField passwordField; + Choice authChoice; + Button connectButton; + Button cancelButton; + + static String readEncPassword(String string) { + Object object; + if (string.length() != 16) { + System.out.println("VNC Enc. Passwords must be 16 chars"); + return string; + } + byte[] byArray = new byte[]{0, 0, 0, 0, 0, 0, 0, 0}; + int n = string.length() / 2; + if (n > 8) { + n = 8; + } + for (int i = 0; i < n; ++i) { + object = string.substring(i * 2, i * 2 + 2); + Integer n2 = new Integer(Integer.parseInt((String)object, 16)); + byArray[i] = n2.byteValue(); + } + byte[] byArray2 = new byte[]{23, 82, 107, 6, 35, 78, 88, 7}; + object = new DesCipher(byArray2); + ((DesCipher)object).decrypt(byArray, 0, byArray, 0); + return new String(byArray); + } + + public AddHostDialog(VncThumbnailViewer vncThumbnailViewer) { + super((Frame)vncThumbnailViewer, true); + this.tnviewer = vncThumbnailViewer; + this.setResizable(false); + GridBagLayout gridBagLayout = new GridBagLayout(); + GridBagConstraints gridBagConstraints = new GridBagConstraints(); + this.setLayout(gridBagLayout); + this.setFont(new Font("Helvetica", 0, 14)); + this.hostField = new TextField("", 10); + this.portField = new TextField("5900", 10); + this.usernameField = new TextField("", 10); + this.usernameField.enable(false); + this.passwordField = new TextField("", 10); + this.passwordField.setEchoChar('*'); + this.passwordField.enable(false); + this.authChoice = new Choice(); + this.authChoice.addItemListener(this); + this.authChoice.add("(none)"); + this.authChoice.add("Password"); + this.authChoice.add("VNC Enc. Password"); + this.authChoice.add("MS-Logon"); + this.connectButton = new Button("Connect..."); + this.cancelButton = new Button("Cancel"); + this.connectButton.addActionListener(this); + this.cancelButton.addActionListener(this); + gridBagConstraints.gridwidth = 0; + gridBagLayout.setConstraints(this.authChoice, gridBagConstraints); + gridBagLayout.setConstraints(this.hostField, gridBagConstraints); + gridBagLayout.setConstraints(this.portField, gridBagConstraints); + gridBagLayout.setConstraints(this.usernameField, gridBagConstraints); + gridBagLayout.setConstraints(this.passwordField, gridBagConstraints); + gridBagLayout.setConstraints(this.connectButton, gridBagConstraints); + this.add(new Label("Host", 2)); + this.add(this.hostField); + this.add(new Label("Port", 2)); + this.add(this.portField); + this.add(new Label("Authentication:", 2)); + this.add(this.authChoice); + this.add(new Label("Username", 2)); + this.add(this.usernameField); + this.add(new Label("Password", 2)); + this.add(this.passwordField); + this.add(this.cancelButton); + this.add(this.connectButton); + Point point = vncThumbnailViewer.getLocation(); + Dimension dimension = vncThumbnailViewer.getSize(); + point.x += dimension.width / 2 - 50; + point.y += dimension.height / 2 - 50; + ((Component)this).setLocation(point); + this.pack(); + this.validate(); + ((Component)this).setVisible(true); + } + + void callAddHost() { + String string = this.hostField.getText(); + int n = Integer.parseInt(this.portField.getText()); + String string2 = this.passwordField.getText(); + String string3 = this.usernameField.getText(); + if (this.authChoice.getSelectedItem() == "VNC Enc. Password") { + string2 = AddHostDialog.readEncPassword(string2); + } + this.tnviewer.launchViewer(string, n, string2, string3); + } + + public void actionPerformed(ActionEvent actionEvent) { + if (actionEvent.getSource() == this.connectButton) { + this.callAddHost(); + } + this.dispose(); + } + + public void itemStateChanged(ItemEvent itemEvent) { + if (this.authChoice.getSelectedItem() == "(none)") { + this.passwordField.enable(false); + } else { + this.passwordField.enable(true); + } + if (this.authChoice.getSelectedItem() == "MS-Logon") { + this.usernameField.enable(true); + } else { + this.usernameField.enable(false); + } + } +} + diff --git a/src/AuthPanel.java b/src/AuthPanel.java new file mode 100644 index 0000000..d46a122 --- /dev/null +++ b/src/AuthPanel.java @@ -0,0 +1,76 @@ +/* + * Decompiled with CFR 0.152. + */ +import java.awt.Button; +import java.awt.Color; +import java.awt.Font; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.awt.Label; +import java.awt.Panel; +import java.awt.TextField; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +class AuthPanel +extends Panel +implements ActionListener { + TextField passwordField; + Button okButton; + + public AuthPanel(VncViewer vncViewer) { + Label label = new Label("VNC Authentication", 1); + label.setFont(new Font("Helvetica", 1, 18)); + Label label2 = new Label("Password:", 1); + this.passwordField = new TextField(10); + this.passwordField.setForeground(Color.black); + this.passwordField.setBackground(Color.white); + this.passwordField.setEchoChar('*'); + this.okButton = new Button("OK"); + GridBagLayout gridBagLayout = new GridBagLayout(); + GridBagConstraints gridBagConstraints = new GridBagConstraints(); + this.setLayout(gridBagLayout); + gridBagConstraints.gridwidth = 0; + gridBagConstraints.insets = new Insets(0, 0, 20, 0); + gridBagLayout.setConstraints(label, gridBagConstraints); + this.add(label); + gridBagConstraints.fill = 0; + gridBagConstraints.gridwidth = 1; + gridBagConstraints.insets = new Insets(0, 0, 0, 0); + gridBagLayout.setConstraints(label2, gridBagConstraints); + this.add(label2); + gridBagLayout.setConstraints(this.passwordField, gridBagConstraints); + this.add(this.passwordField); + this.passwordField.addActionListener(this); + gridBagConstraints.gridwidth = 0; + gridBagConstraints.fill = 1; + gridBagConstraints.insets = new Insets(0, 20, 0, 0); + gridBagConstraints.ipadx = 30; + gridBagLayout.setConstraints(this.okButton, gridBagConstraints); + this.add(this.okButton); + this.okButton.addActionListener(this); + } + + public void moveFocusToDefaultField() { + this.passwordField.requestFocus(); + } + + public synchronized void actionPerformed(ActionEvent actionEvent) { + if (actionEvent.getSource() == this.passwordField || actionEvent.getSource() == this.okButton) { + this.passwordField.setEnabled(false); + this.notify(); + } + } + + public synchronized String getPassword() throws Exception { + try { + this.wait(); + } + catch (InterruptedException interruptedException) { + // empty catch block + } + return this.passwordField.getText(); + } +} + diff --git a/src/ButtonPanel.java b/src/ButtonPanel.java new file mode 100644 index 0000000..4c55d0b --- /dev/null +++ b/src/ButtonPanel.java @@ -0,0 +1,107 @@ +/* + * Decompiled with CFR 0.152. + */ +import java.awt.Button; +import java.awt.Component; +import java.awt.FlowLayout; +import java.awt.Panel; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import java.io.IOException; + +class ButtonPanel +extends Panel +implements ActionListener { + VncViewer viewer; + Button disconnectButton; + Button optionsButton; + Button recordButton; + Button clipboardButton; + Button ctrlAltDelButton; + Button refreshButton; + + ButtonPanel(VncViewer vncViewer) { + this.viewer = vncViewer; + this.setLayout(new FlowLayout(0, 0, 0)); + this.disconnectButton = new Button("Disconnect"); + this.disconnectButton.setEnabled(false); + this.add(this.disconnectButton); + this.disconnectButton.addActionListener(this); + this.optionsButton = new Button("Options"); + this.add(this.optionsButton); + this.optionsButton.addActionListener(this); + this.clipboardButton = new Button("Clipboard"); + this.clipboardButton.setEnabled(false); + this.add(this.clipboardButton); + this.clipboardButton.addActionListener(this); + if (this.viewer.rec != null) { + this.recordButton = new Button("Record"); + this.add(this.recordButton); + this.recordButton.addActionListener(this); + } + this.ctrlAltDelButton = new Button("Send Ctrl-Alt-Del"); + this.ctrlAltDelButton.setEnabled(false); + this.add(this.ctrlAltDelButton); + this.ctrlAltDelButton.addActionListener(this); + this.refreshButton = new Button("Refresh"); + this.refreshButton.setEnabled(false); + this.add(this.refreshButton); + this.refreshButton.addActionListener(this); + } + + public void enableButtons() { + this.disconnectButton.setEnabled(true); + this.clipboardButton.setEnabled(true); + this.refreshButton.setEnabled(true); + } + + public void disableButtonsOnDisconnect() { + this.remove(this.disconnectButton); + this.disconnectButton = new Button("Hide desktop"); + this.disconnectButton.setEnabled(true); + this.add((Component)this.disconnectButton, 0); + this.disconnectButton.addActionListener(this); + this.optionsButton.setEnabled(false); + this.clipboardButton.setEnabled(false); + this.ctrlAltDelButton.setEnabled(false); + this.refreshButton.setEnabled(false); + this.validate(); + } + + public void enableRemoteAccessControls(boolean bl) { + this.ctrlAltDelButton.setEnabled(bl); + } + + public void actionPerformed(ActionEvent actionEvent) { + this.viewer.moveFocusToDesktop(); + if (actionEvent.getSource() == this.disconnectButton) { + this.viewer.disconnect(); + } else if (actionEvent.getSource() == this.optionsButton) { + ((Component)this.viewer.options).setVisible(!this.viewer.options.isVisible()); + } else if (actionEvent.getSource() == this.recordButton) { + ((Component)this.viewer.rec).setVisible(!this.viewer.rec.isVisible()); + } else if (actionEvent.getSource() == this.clipboardButton) { + ((Component)this.viewer.clipboard).setVisible(!this.viewer.clipboard.isVisible()); + } else if (actionEvent.getSource() == this.ctrlAltDelButton) { + try { + KeyEvent keyEvent = new KeyEvent(this, 401, 0L, 10, 127); + this.viewer.rfb.writeKeyEvent(keyEvent); + keyEvent = new KeyEvent(this, 402, 0L, 10, 127); + this.viewer.rfb.writeKeyEvent(keyEvent); + } + catch (IOException iOException) { + iOException.printStackTrace(); + } + } else if (actionEvent.getSource() == this.refreshButton) { + try { + RfbProto rfbProto = this.viewer.rfb; + rfbProto.writeFramebufferUpdateRequest(0, 0, rfbProto.framebufferWidth, rfbProto.framebufferHeight, false); + } + catch (IOException iOException) { + iOException.printStackTrace(); + } + } + } +} + diff --git a/src/CapabilityInfo.java b/src/CapabilityInfo.java new file mode 100644 index 0000000..685746c --- /dev/null +++ b/src/CapabilityInfo.java @@ -0,0 +1,54 @@ +/* + * Decompiled with CFR 0.152. + */ +class CapabilityInfo { + protected int code; + protected String vendorSignature; + protected String nameSignature; + protected String description; + protected boolean enabled; + + public CapabilityInfo(int n, String string, String string2, String string3) { + this.code = n; + this.vendorSignature = string; + this.nameSignature = string2; + this.description = string3; + this.enabled = false; + } + + public CapabilityInfo(int n, byte[] byArray, byte[] byArray2) { + this.code = n; + this.vendorSignature = new String(byArray); + this.nameSignature = new String(byArray2); + this.description = null; + this.enabled = false; + } + + public int getCode() { + return this.code; + } + + public String getDescription() { + return this.description; + } + + public boolean isEnabled() { + return this.enabled; + } + + public void enable() { + this.enabled = true; + } + + public boolean equals(CapabilityInfo capabilityInfo) { + return capabilityInfo != null && this.code == capabilityInfo.code && this.vendorSignature.equals(capabilityInfo.vendorSignature) && this.nameSignature.equals(capabilityInfo.nameSignature); + } + + public boolean enableIfEquals(CapabilityInfo capabilityInfo) { + if (this.equals(capabilityInfo)) { + this.enable(); + } + return this.isEnabled(); + } +} + diff --git a/src/CapsContainer.java b/src/CapsContainer.java new file mode 100644 index 0000000..0479323 --- /dev/null +++ b/src/CapsContainer.java @@ -0,0 +1,73 @@ +/* + * Decompiled with CFR 0.152. + */ +import java.util.Hashtable; +import java.util.Vector; + +class CapsContainer { + protected Hashtable infoMap = new Hashtable(64, 0.25f); + protected Vector orderedList = new Vector(32, 8); + + public void add(CapabilityInfo capabilityInfo) { + Integer n = new Integer(capabilityInfo.getCode()); + this.infoMap.put(n, capabilityInfo); + } + + public void add(int n, String string, String string2, String string3) { + Integer n2 = new Integer(n); + this.infoMap.put(n2, new CapabilityInfo(n, string, string2, string3)); + } + + public boolean isKnown(int n) { + return this.infoMap.containsKey(new Integer(n)); + } + + public CapabilityInfo getInfo(int n) { + return (CapabilityInfo)this.infoMap.get(new Integer(n)); + } + + public String getDescription(int n) { + CapabilityInfo capabilityInfo = (CapabilityInfo)this.infoMap.get(new Integer(n)); + if (capabilityInfo == null) { + return null; + } + return capabilityInfo.getDescription(); + } + + public boolean enable(CapabilityInfo capabilityInfo) { + Integer n = new Integer(capabilityInfo.getCode()); + CapabilityInfo capabilityInfo2 = (CapabilityInfo)this.infoMap.get(n); + if (capabilityInfo2 == null) { + return false; + } + boolean bl = capabilityInfo2.enableIfEquals(capabilityInfo); + if (bl) { + this.orderedList.addElement(n); + } + return bl; + } + + public boolean isEnabled(int n) { + CapabilityInfo capabilityInfo = (CapabilityInfo)this.infoMap.get(new Integer(n)); + if (capabilityInfo == null) { + return false; + } + return capabilityInfo.isEnabled(); + } + + public int numEnabled() { + return this.orderedList.size(); + } + + public int getByOrder(int n) { + int n2; + try { + n2 = (Integer)this.orderedList.elementAt(n); + } + catch (ArrayIndexOutOfBoundsException arrayIndexOutOfBoundsException) { + n2 = 0; + } + return n2; + } +} + diff --git a/src/ClipboardFrame.java b/src/ClipboardFrame.java new file mode 100644 index 0000000..95f9dbf --- /dev/null +++ b/src/ClipboardFrame.java @@ -0,0 +1,95 @@ +/* + * Decompiled with CFR 0.152. + */ +import java.awt.Button; +import java.awt.Component; +import java.awt.Frame; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.TextArea; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.WindowEvent; +import java.awt.event.WindowListener; + +class ClipboardFrame +extends Frame +implements WindowListener, +ActionListener { + TextArea textArea; + Button clearButton; + Button closeButton; + String selection; + VncViewer viewer; + + ClipboardFrame(VncViewer vncViewer) { + super("TightVNC Clipboard"); + this.viewer = vncViewer; + GridBagLayout gridBagLayout = new GridBagLayout(); + this.setLayout(gridBagLayout); + GridBagConstraints gridBagConstraints = new GridBagConstraints(); + gridBagConstraints.gridwidth = 0; + gridBagConstraints.fill = 1; + gridBagConstraints.weighty = 1.0; + this.textArea = new TextArea(5, 40); + gridBagLayout.setConstraints(this.textArea, gridBagConstraints); + this.add(this.textArea); + gridBagConstraints.fill = 2; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 0.0; + gridBagConstraints.gridwidth = 1; + this.clearButton = new Button("Clear"); + gridBagLayout.setConstraints(this.clearButton, gridBagConstraints); + this.add(this.clearButton); + this.clearButton.addActionListener(this); + this.closeButton = new Button("Close"); + gridBagLayout.setConstraints(this.closeButton, gridBagConstraints); + this.add(this.closeButton); + this.closeButton.addActionListener(this); + this.pack(); + this.addWindowListener(this); + } + + void setCutText(String string) { + this.selection = string; + this.textArea.setText(string); + if (this.isVisible()) { + this.textArea.selectAll(); + } + } + + public void windowDeactivated(WindowEvent windowEvent) { + if (this.selection != null && !this.selection.equals(this.textArea.getText())) { + this.selection = this.textArea.getText(); + this.viewer.setCutText(this.selection); + } + } + + public void windowClosing(WindowEvent windowEvent) { + ((Component)this).setVisible(false); + } + + public void windowActivated(WindowEvent windowEvent) { + } + + public void windowOpened(WindowEvent windowEvent) { + } + + public void windowClosed(WindowEvent windowEvent) { + } + + public void windowIconified(WindowEvent windowEvent) { + } + + public void windowDeiconified(WindowEvent windowEvent) { + } + + public void actionPerformed(ActionEvent actionEvent) { + if (actionEvent.getSource() == this.clearButton) { + this.textArea.setText(""); + } else if (actionEvent.getSource() == this.closeButton) { + ((Component)this).setVisible(false); + } + } +} + diff --git a/src/DesCipher.java b/src/DesCipher.java new file mode 100644 index 0000000..b08bb35 --- /dev/null +++ b/src/DesCipher.java @@ -0,0 +1,264 @@ +/* + * Decompiled with CFR 0.152. + */ +public class DesCipher { + private int[] encryptKeys = new int[32]; + private int[] decryptKeys = new int[32]; + private int[] tempInts = new int[2]; + private static byte[] bytebit = new byte[]{1, 2, 4, 8, 16, 32, 64, -128}; + private static int[] bigbyte = new int[]{0x800000, 0x400000, 0x200000, 0x100000, 524288, 262144, 131072, 65536, 32768, 16384, 8192, 4096, 2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1}; + private static byte[] pc1 = new byte[]{56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3}; + private static int[] totrot = new int[]{1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28}; + private static byte[] pc2 = new byte[]{13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31}; + private static int[] SP1 = new int[]{0x1010400, 0, 65536, 0x1010404, 0x1010004, 66564, 4, 65536, 1024, 0x1010400, 0x1010404, 1024, 0x1000404, 0x1010004, 0x1000000, 4, 1028, 0x1000400, 0x1000400, 66560, 66560, 0x1010000, 0x1010000, 0x1000404, 65540, 0x1000004, 0x1000004, 65540, 0, 1028, 66564, 0x1000000, 65536, 0x1010404, 4, 0x1010000, 0x1010400, 0x1000000, 0x1000000, 1024, 0x1010004, 65536, 66560, 0x1000004, 1024, 4, 0x1000404, 66564, 0x1010404, 65540, 0x1010000, 0x1000404, 0x1000004, 1028, 66564, 0x1010400, 1028, 0x1000400, 0x1000400, 0, 65540, 66560, 0, 0x1010004}; + private static int[] SP2 = new int[]{-2146402272, -2147450880, 32768, 1081376, 0x100000, 32, -2146435040, -2147450848, -2147483616, -2146402272, -2146402304, Integer.MIN_VALUE, -2147450880, 0x100000, 32, -2146435040, 0x108000, 0x100020, -2147450848, 0, Integer.MIN_VALUE, 32768, 1081376, -2146435072, 0x100020, -2147483616, 0, 0x108000, 32800, -2146402304, -2146435072, 32800, 0, 1081376, -2146435040, 0x100000, -2147450848, -2146435072, -2146402304, 32768, -2146435072, -2147450880, 32, -2146402272, 1081376, 32, 32768, Integer.MIN_VALUE, 32800, -2146402304, 0x100000, -2147483616, 0x100020, -2147450848, -2147483616, 0x100020, 0x108000, 0, -2147450880, 32800, Integer.MIN_VALUE, -2146435040, -2146402272, 0x108000}; + private static int[] SP3 = new int[]{520, 0x8020200, 0, 0x8020008, 0x8000200, 0, 131592, 0x8000200, 131080, 0x8000008, 0x8000008, 131072, 0x8020208, 131080, 0x8020000, 520, 0x8000000, 8, 0x8020200, 512, 131584, 0x8020000, 0x8020008, 131592, 0x8000208, 131584, 131072, 0x8000208, 8, 0x8020208, 512, 0x8000000, 0x8020200, 0x8000000, 131080, 520, 131072, 0x8020200, 0x8000200, 0, 512, 131080, 0x8020208, 0x8000200, 0x8000008, 512, 0, 0x8020008, 0x8000208, 131072, 0x8000000, 0x8020208, 8, 131592, 131584, 0x8000008, 0x8020000, 0x8000208, 520, 0x8020000, 131592, 8, 0x8020008, 131584}; + private static int[] SP4 = new int[]{8396801, 8321, 8321, 128, 0x802080, 0x800081, 0x800001, 8193, 0, 0x802000, 0x802000, 8396929, 129, 0, 0x800080, 0x800001, 1, 8192, 0x800000, 8396801, 128, 0x800000, 8193, 8320, 0x800081, 1, 8320, 0x800080, 8192, 0x802080, 8396929, 129, 0x800080, 0x800001, 0x802000, 8396929, 129, 0, 0, 0x802000, 8320, 0x800080, 0x800081, 1, 8396801, 8321, 8321, 128, 8396929, 129, 1, 8192, 0x800001, 8193, 0x802080, 0x800081, 8193, 8320, 0x800000, 8396801, 128, 0x800000, 8192, 0x802080}; + private static int[] SP5 = new int[]{256, 34078976, 0x2080000, 1107296512, 524288, 256, 0x40000000, 0x2080000, 1074266368, 524288, 0x2000100, 1074266368, 1107296512, 1107820544, 524544, 0x40000000, 0x2000000, 0x40080000, 0x40080000, 0, 0x40000100, 1107820800, 1107820800, 0x2000100, 1107820544, 0x40000100, 0, 0x42000000, 34078976, 0x2000000, 0x42000000, 524544, 524288, 1107296512, 256, 0x2000000, 0x40000000, 0x2080000, 1107296512, 1074266368, 0x2000100, 0x40000000, 1107820544, 34078976, 1074266368, 256, 0x2000000, 1107820544, 1107820800, 524544, 0x42000000, 1107820800, 0x2080000, 0, 0x40080000, 0x42000000, 524544, 0x2000100, 0x40000100, 524288, 0, 0x40080000, 34078976, 0x40000100}; + private static int[] SP6 = new int[]{0x20000010, 0x20400000, 16384, 541081616, 0x20400000, 16, 541081616, 0x400000, 0x20004000, 0x404010, 0x400000, 0x20000010, 0x400010, 0x20004000, 0x20000000, 16400, 0, 0x400010, 536887312, 16384, 0x404000, 536887312, 16, 541065232, 541065232, 0, 0x404010, 0x20404000, 16400, 0x404000, 0x20404000, 0x20000000, 0x20004000, 16, 541065232, 0x404000, 541081616, 0x400000, 16400, 0x20000010, 0x400000, 0x20004000, 0x20000000, 16400, 0x20000010, 541081616, 0x404000, 0x20400000, 0x404010, 0x20404000, 0, 541065232, 16, 16384, 0x20400000, 0x404010, 16384, 0x400010, 536887312, 0, 0x20404000, 0x20000000, 0x400010, 536887312}; + private static int[] SP7 = new int[]{0x200000, 0x4200002, 67110914, 0, 2048, 67110914, 0x200802, 69208064, 69208066, 0x200000, 0, 0x4000002, 2, 0x4000000, 0x4200002, 2050, 0x4000800, 0x200802, 0x200002, 0x4000800, 0x4000002, 0x4200000, 69208064, 0x200002, 0x4200000, 2048, 2050, 69208066, 0x200800, 2, 0x4000000, 0x200800, 0x4000000, 0x200800, 0x200000, 67110914, 67110914, 0x4200002, 0x4200002, 2, 0x200002, 0x4000000, 0x4000800, 0x200000, 69208064, 2050, 0x200802, 69208064, 2050, 0x4000002, 69208066, 0x4200000, 0x200800, 0, 2, 69208066, 0, 0x200802, 0x4200000, 2048, 0x4000002, 0x4000800, 2048, 0x200002}; + private static int[] SP8 = new int[]{0x10001040, 4096, 262144, 0x10041040, 0x10000000, 0x10001040, 64, 0x10000000, 262208, 0x10040000, 0x10041040, 266240, 0x10041000, 266304, 4096, 64, 0x10040000, 0x10000040, 0x10001000, 4160, 266240, 262208, 0x10040040, 0x10041000, 4160, 0, 0, 0x10040040, 0x10000040, 0x10001000, 266304, 262144, 266304, 262144, 0x10041000, 4096, 64, 0x10040040, 4096, 266304, 0x10001000, 64, 0x10000040, 0x10040000, 0x10040040, 0x10000000, 262144, 0x10001040, 0, 0x10041040, 262208, 0x10000040, 0x10040000, 0x10001000, 0x10001040, 0, 0x10041040, 266240, 266240, 4160, 4160, 262208, 0x10000000, 0x10041000}; + + public DesCipher(byte[] byArray) { + this.setKey(byArray); + } + + public void setKey(byte[] byArray) { + this.deskey(byArray, true, this.encryptKeys); + this.deskey(byArray, false, this.decryptKeys); + } + + private void deskey(byte[] byArray, boolean bl, int[] nArray) { + int n; + int n2; + int n3; + int[] nArray2 = new int[56]; + int[] nArray3 = new int[56]; + int[] nArray4 = new int[32]; + for (n3 = 0; n3 < 56; ++n3) { + n2 = pc1[n3]; + n = n2 & 7; + nArray2[n3] = (byArray[n2 >>> 3] & bytebit[n]) != 0 ? 1 : 0; + } + for (int i = 0; i < 16; ++i) { + n = bl ? i << 1 : 15 - i << 1; + int n4 = n + 1; + nArray4[n4] = 0; + nArray4[n] = 0; + for (n3 = 0; n3 < 28; ++n3) { + n2 = n3 + totrot[i]; + nArray3[n3] = n2 < 28 ? nArray2[n2] : nArray2[n2 - 28]; + } + for (n3 = 28; n3 < 56; ++n3) { + n2 = n3 + totrot[i]; + nArray3[n3] = n2 < 56 ? nArray2[n2] : nArray2[n2 - 28]; + } + for (n3 = 0; n3 < 24; ++n3) { + if (nArray3[pc2[n3]] != 0) { + int n5 = n; + nArray4[n5] = nArray4[n5] | bigbyte[n3]; + } + if (nArray3[pc2[n3 + 24]] == 0) continue; + int n6 = n4; + nArray4[n6] = nArray4[n6] | bigbyte[n3]; + } + } + this.cookey(nArray4, nArray); + } + + private void cookey(int[] nArray, int[] nArray2) { + int n = 0; + int n2 = 0; + for (int i = 0; i < 16; ++i) { + int n3 = nArray[n++]; + int n4 = nArray[n++]; + nArray2[n2] = (n3 & 0xFC0000) << 6; + int n5 = n2; + nArray2[n5] = nArray2[n5] | (n3 & 0xFC0) << 10; + int n6 = n2; + nArray2[n6] = nArray2[n6] | (n4 & 0xFC0000) >>> 10; + int n7 = n2++; + nArray2[n7] = nArray2[n7] | (n4 & 0xFC0) >>> 6; + nArray2[n2] = (n3 & 0x3F000) << 12; + int n8 = n2; + nArray2[n8] = nArray2[n8] | (n3 & 0x3F) << 16; + int n9 = n2; + nArray2[n9] = nArray2[n9] | (n4 & 0x3F000) >>> 4; + int n10 = n2++; + nArray2[n10] = nArray2[n10] | n4 & 0x3F; + } + } + + public void encrypt(byte[] byArray, int n, byte[] byArray2, int n2) { + DesCipher.squashBytesToInts(byArray, n, this.tempInts, 0, 2); + this.des(this.tempInts, this.tempInts, this.encryptKeys); + DesCipher.spreadIntsToBytes(this.tempInts, 0, byArray2, n2, 2); + } + + public void decrypt(byte[] byArray, int n, byte[] byArray2, int n2) { + DesCipher.squashBytesToInts(byArray, n, this.tempInts, 0, 2); + this.des(this.tempInts, this.tempInts, this.decryptKeys); + DesCipher.spreadIntsToBytes(this.tempInts, 0, byArray2, n2, 2); + } + + public void encryptText(byte[] byArray, byte[] byArray2, byte[] byArray3) { + int n; + for (n = 0; n < 8; ++n) { + int n2 = n; + byArray[n2] = (byte)(byArray[n2] ^ byArray3[n]); + } + this.encrypt(byArray, 0, byArray2, 0); + for (n = 8; n < byArray.length; n += 8) { + for (int i = 0; i < 8; ++i) { + int n3 = n + i; + byArray[n3] = (byte)(byArray[n3] ^ byArray2[n + i - 8]); + } + this.encrypt(byArray, n, byArray2, n); + } + } + + public void decryptText(byte[] byArray, byte[] byArray2, byte[] byArray3) { + int n; + for (n = byArray.length - 8; n > 0; n -= 8) { + this.decrypt(byArray, n, byArray2, n); + for (int i = 0; i < 8; ++i) { + int n2 = n + i; + byArray2[n2] = (byte)(byArray2[n2] ^ byArray[n + i - 8]); + } + } + this.decrypt(byArray, 0, byArray2, 0); + for (n = 0; n < 8; ++n) { + int n3 = n; + byArray2[n3] = (byte)(byArray2[n3] ^ byArray3[n]); + } + } + + private static String bytesToHexString(byte[] byArray) { + String string = ""; + for (int i = 0; i < 8; ++i) { + int n = byArray[i] & 0xFF; + String string2 = Integer.toHexString(n); + if (string2.length() != 2) { + string2 = "0" + string2; + } + string = string + string2; + } + return string; + } + + public static String encryptData(String string, String string2) { + string2 = (string2 + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000").substring(0, 8); + DesCipher desCipher = new DesCipher(string2.getBytes()); + String string3 = ""; + String string4 = string; + while (string4.length() != 0) { + for (int i = string4.length(); i < 8; ++i) { + string4 = string4 + '\u0000'; + } + byte[] byArray = new byte[8]; + desCipher.encrypt(string4.substring(0, 8).getBytes(), 0, byArray, 0); + string3 = string3 + DesCipher.bytesToHexString(byArray); + string4 = string4.substring(8); + } + return string3; + } + + public static String decryptData(String string, String string2) { + int n; + if (string.length() % 8 != 0) { + System.out.println("Error decrypting data, length not multiple of 8"); + return ""; + } + string2 = (string2 + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000").substring(0, 8); + DesCipher desCipher = new DesCipher(string2.getBytes()); + int n2 = string.length() / 2; + byte[] byArray = new byte[n2]; + for (n = 0; n < n2; ++n) { + String string3 = string.substring(n * 2, n * 2 + 2); + Integer n3 = new Integer(Integer.parseInt(string3, 16)); + byArray[n] = n3.byteValue(); + } + for (n = 0; n < n2 / 8; ++n) { + desCipher.decrypt(byArray, n * 8, byArray, n * 8); + } + return new String(byArray); + } + + private void des(int[] nArray, int[] nArray2, int[] nArray3) { + int n = 0; + int n2 = nArray[0]; + int n3 = nArray[1]; + int n4 = (n2 >>> 4 ^ n3) & 0xF0F0F0F; + n3 ^= n4; + n2 ^= n4 << 4; + n4 = (n2 >>> 16 ^ n3) & 0xFFFF; + n3 ^= n4; + n2 ^= n4 << 16; + n4 = (n3 >>> 2 ^ n2) & 0x33333333; + n2 ^= n4; + n3 ^= n4 << 2; + n4 = (n3 >>> 8 ^ n2) & 0xFF00FF; + n2 ^= n4; + n3 ^= n4 << 8; + n3 = n3 << 1 | n3 >>> 31 & 1; + n4 = (n2 ^ n3) & 0xAAAAAAAA; + n2 ^= n4; + n3 ^= n4; + n2 = n2 << 1 | n2 >>> 31 & 1; + for (int i = 0; i < 8; ++i) { + n4 = n3 << 28 | n3 >>> 4; + int n5 = SP7[(n4 ^= nArray3[n++]) & 0x3F]; + n5 |= SP5[n4 >>> 8 & 0x3F]; + n5 |= SP3[n4 >>> 16 & 0x3F]; + n5 |= SP1[n4 >>> 24 & 0x3F]; + n4 = n3 ^ nArray3[n++]; + n5 |= SP8[n4 & 0x3F]; + n5 |= SP6[n4 >>> 8 & 0x3F]; + n5 |= SP4[n4 >>> 16 & 0x3F]; + n2 ^= (n5 |= SP2[n4 >>> 24 & 0x3F]); + n4 = n2 << 28 | n2 >>> 4; + n5 = SP7[(n4 ^= nArray3[n++]) & 0x3F]; + n5 |= SP5[n4 >>> 8 & 0x3F]; + n5 |= SP3[n4 >>> 16 & 0x3F]; + n5 |= SP1[n4 >>> 24 & 0x3F]; + n4 = n2 ^ nArray3[n++]; + n5 |= SP8[n4 & 0x3F]; + n5 |= SP6[n4 >>> 8 & 0x3F]; + n5 |= SP4[n4 >>> 16 & 0x3F]; + n3 ^= (n5 |= SP2[n4 >>> 24 & 0x3F]); + } + n3 = n3 << 31 | n3 >>> 1; + n4 = (n2 ^ n3) & 0xAAAAAAAA; + n2 ^= n4; + n3 ^= n4; + n2 = n2 << 31 | n2 >>> 1; + n4 = (n2 >>> 8 ^ n3) & 0xFF00FF; + n3 ^= n4; + n2 ^= n4 << 8; + n4 = (n2 >>> 2 ^ n3) & 0x33333333; + n3 ^= n4; + n2 ^= n4 << 2; + n4 = (n3 >>> 16 ^ n2) & 0xFFFF; + n2 ^= n4; + n3 ^= n4 << 16; + n4 = (n3 >>> 4 ^ n2) & 0xF0F0F0F; + nArray2[0] = n3 ^= n4 << 4; + nArray2[1] = n2 ^= n4; + } + + public static void squashBytesToInts(byte[] byArray, int n, int[] nArray, int n2, int n3) { + for (int i = 0; i < n3; ++i) { + nArray[n2 + i] = (byArray[n + i * 4] & 0xFF) << 24 | (byArray[n + i * 4 + 1] & 0xFF) << 16 | (byArray[n + i * 4 + 2] & 0xFF) << 8 | byArray[n + i * 4 + 3] & 0xFF; + } + } + + public static void spreadIntsToBytes(int[] nArray, int n, byte[] byArray, int n2, int n3) { + for (int i = 0; i < n3; ++i) { + byArray[n2 + i * 4] = (byte)(nArray[n + i] >>> 24); + byArray[n2 + i * 4 + 1] = (byte)(nArray[n + i] >>> 16); + byArray[n2 + i * 4 + 2] = (byte)(nArray[n + i] >>> 8); + byArray[n2 + i * 4 + 3] = (byte)nArray[n + i]; + } + } +} + diff --git a/src/DiffieHellman.java b/src/DiffieHellman.java new file mode 100644 index 0000000..01f847d --- /dev/null +++ b/src/DiffieHellman.java @@ -0,0 +1,146 @@ +/* + * Decompiled with CFR 0.152. + */ +public class DiffieHellman { + private long gen; + private long mod; + private long priv; + private long pub; + private long key; + private long maxNum = Integer.MAX_VALUE; + private static final int DH_MAX_BITS = 31; + private static final int DH_RANGE = 100; + private static final int DH_MOD = 1; + private static final int DH_GEN = 2; + private static final int DH_PRIV = 3; + private static final int DH_PUB = 4; + private static final int DH_KEY = 5; + + public DiffieHellman() { + } + + public DiffieHellman(long l, long l2) throws Exception { + if (l >= this.maxNum || l2 >= this.maxNum) { + throw new Exception("Modulus or generator too large."); + } + this.gen = l; + this.mod = l2; + } + + private long rng(long l) { + return (long)(Math.random() * (double)l); + } + + private boolean millerRabin(long l, int n) { + long l2 = 0L; + for (int i = 0; i < n; ++i) { + l2 = this.rng(l - 3L) + 2L; + if (this.XpowYmodN(l2, l - 1L, l) == 1L) continue; + return false; + } + return true; + } + + private long generatePrime() { + long l; + long l2 = 0L; + while ((l2 = this.tryToGeneratePrime(l = this.rng(this.maxNum))) == 0L) { + } + return l2; + } + + private long tryToGeneratePrime(long l) { + if ((l & 1L) == 0L) { + ++l; + } + long l2 = 0L; + while (!this.millerRabin(l, 25) && l2++ < 100L && l < this.maxNum) { + if ((l += 2L) % 3L != 0L) continue; + l += 2L; + } + return l2 >= 100L || l >= this.maxNum ? 0L : l; + } + + private long XpowYmodN(long l, long l2, long l3) { + long l4 = 1L; + for (int i = 0; i < 64; ++i) { + l4 = l4 * l4 % l3; + if ((l2 & Long.MIN_VALUE) != 0L) { + l4 = l4 * l % l3; + } + l2 <<= 1; + } + return l4; + } + + public void createKeys() { + this.gen = this.generatePrime(); + this.mod = this.generatePrime(); + if (this.gen > this.mod) { + long l = this.gen; + this.gen = this.mod; + this.mod = l; + } + } + + public long createInterKey() { + this.priv = this.rng(this.maxNum); + this.pub = this.XpowYmodN(this.gen, this.priv, this.mod); + return this.pub; + } + + public long createEncryptionKey(long l) throws Exception { + if (l >= this.maxNum) { + throw new Exception("interKey too large"); + } + this.key = this.XpowYmodN(l, this.priv, this.mod); + return this.key; + } + + public long getValue(int n) { + switch (n) { + case 1: { + return this.mod; + } + case 2: { + return this.gen; + } + case 3: { + return this.priv; + } + case 4: { + return this.pub; + } + case 5: { + return this.key; + } + } + return 0L; + } + + public int bits(long l) { + for (int i = 0; i < 64; ++i) { + if ((l /= 2L) >= 2L) continue; + return i; + } + return 0; + } + + public static byte[] longToBytes(long l) { + byte[] byArray = new byte[8]; + for (int i = 0; i < 8; ++i) { + byArray[i] = (byte)(0xFFL & l >> 8 * (7 - i)); + } + return byArray; + } + + public static long bytesToLong(byte[] byArray) { + long l = 0L; + for (int i = 0; i < 8; ++i) { + l <<= 8; + l += (long)byArray[i]; + } + return l; + } +} + diff --git a/src/HTTPConnectSocket.java b/src/HTTPConnectSocket.java new file mode 100644 index 0000000..6241f96 --- /dev/null +++ b/src/HTTPConnectSocket.java @@ -0,0 +1,25 @@ +/* + * Decompiled with CFR 0.152. + */ +import java.io.DataInputStream; +import java.io.IOException; +import java.net.Socket; + +class HTTPConnectSocket +extends Socket { + public HTTPConnectSocket(String string, int n, String string2, int n2) throws IOException { + super(string2, n2); + this.getOutputStream().write(("CONNECT " + string + ":" + n + " HTTP/1.0\r\n\r\n").getBytes()); + DataInputStream dataInputStream = new DataInputStream(this.getInputStream()); + String string3 = dataInputStream.readLine(); + if (!string3.startsWith("HTTP/1.0 200 ")) { + if (string3.startsWith("HTTP/1.0 ")) { + string3 = string3.substring(9); + } + throw new IOException("Proxy reports \"" + string3 + "\""); + } + while ((string3 = dataInputStream.readLine()).length() != 0) { + } + } +} + diff --git a/src/HTTPConnectSocketFactory.java b/src/HTTPConnectSocketFactory.java new file mode 100644 index 0000000..56ab010 --- /dev/null +++ b/src/HTTPConnectSocketFactory.java @@ -0,0 +1,53 @@ +/* + * Decompiled with CFR 0.152. + */ +import java.applet.Applet; +import java.io.IOException; +import java.net.Socket; + +class HTTPConnectSocketFactory +implements SocketFactory { + HTTPConnectSocketFactory() { + } + + public Socket createSocket(String string, int n, Applet applet) throws IOException { + return this.createSocket(string, n, applet.getParameter("PROXYHOST1"), applet.getParameter("PROXYPORT1")); + } + + public Socket createSocket(String string, int n, String[] stringArray) throws IOException { + return this.createSocket(string, n, this.readArg(stringArray, "PROXYHOST1"), this.readArg(stringArray, "PROXYPORT1")); + } + + public Socket createSocket(String string, int n, String string2, String string3) throws IOException { + int n2 = 0; + if (string3 != null) { + try { + n2 = Integer.parseInt(string3); + } + catch (NumberFormatException numberFormatException) { + // empty catch block + } + } + if (string2 == null || n2 == 0) { + System.out.println("Incomplete parameter list for HTTPConnectSocket"); + return new Socket(string, n); + } + System.out.println("HTTP CONNECT via proxy " + string2 + " port " + n2); + HTTPConnectSocket hTTPConnectSocket = new HTTPConnectSocket(string, n, string2, n2); + return hTTPConnectSocket; + } + + private String readArg(String[] stringArray, String string) { + for (int i = 0; i < stringArray.length; i += 2) { + if (!stringArray[i].equalsIgnoreCase(string)) continue; + try { + return stringArray[i + 1]; + } + catch (Exception exception) { + return null; + } + } + return null; + } +} + diff --git a/src/HostsFilePasswordDialog.java b/src/HostsFilePasswordDialog.java new file mode 100644 index 0000000..d3296d3 --- /dev/null +++ b/src/HostsFilePasswordDialog.java @@ -0,0 +1,99 @@ +/* + * Decompiled with CFR 0.152. + */ +import java.awt.Button; +import java.awt.Component; +import java.awt.Dialog; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.Frame; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Label; +import java.awt.Point; +import java.awt.TextField; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class HostsFilePasswordDialog +extends Dialog +implements ActionListener { + private Button ok; + private Button cancel; + private TextField passField; + private String password = null; + private boolean result = false; + + public HostsFilePasswordDialog(Frame frame, boolean bl) { + super(frame); + GridBagLayout gridBagLayout = new GridBagLayout(); + GridBagConstraints gridBagConstraints = new GridBagConstraints(); + this.setLayout(gridBagLayout); + this.setModal(true); + this.setResizable(false); + Point point = frame.getLocation(); + Dimension dimension = frame.getSize(); + point.x += dimension.width / 2 - 50; + point.y += dimension.height / 2 - 50; + ((Component)this).setLocation(point); + Label label = new Label("Password:", 1); + label.setFont(new Font(null, 1, 24)); + gridBagConstraints.gridwidth = 0; + gridBagLayout.setConstraints(label, gridBagConstraints); + this.add(label); + if (bl) { + Label label2 = new Label("To protect login information", 1); + Label label3 = new Label("enter a password to encrypt", 1); + Label label4 = new Label("this file with. (To leave file", 1); + Label label5 = new Label("unencrypted, click NONE)", 1); + gridBagConstraints.gridwidth = 0; + gridBagLayout.setConstraints(label2, gridBagConstraints); + gridBagLayout.setConstraints(label3, gridBagConstraints); + gridBagLayout.setConstraints(label4, gridBagConstraints); + gridBagLayout.setConstraints(label5, gridBagConstraints); + this.add(label2); + this.add(label3); + this.add(label4); + this.add(label5); + } + this.passField = new TextField(20); + this.passField.setEchoChar('*'); + gridBagConstraints.gridwidth = 0; + gridBagLayout.setConstraints(this.passField, gridBagConstraints); + this.add(this.passField); + if (bl) { + this.cancel = new Button("None"); + this.cancel.addActionListener(this); + gridBagConstraints.anchor = 10; + gridBagConstraints.fill = 0; + gridBagConstraints.gridwidth = 1; + gridBagLayout.setConstraints(this.cancel, gridBagConstraints); + this.add(this.cancel); + } + this.ok = new Button("OK"); + this.ok.addActionListener(this); + gridBagConstraints.anchor = 10; + gridBagConstraints.fill = 0; + gridBagConstraints.gridwidth = 0; + gridBagLayout.setConstraints(this.ok, gridBagConstraints); + this.add(this.ok); + this.pack(); + ((Component)this).setVisible(true); + } + + public boolean getResult() { + return this.result; + } + + public String getPassword() { + return this.password; + } + + public void actionPerformed(ActionEvent actionEvent) { + this.result = actionEvent.getSource() == this.ok; + this.password = this.passField.getText(); + ((Component)this).setVisible(false); + this.dispose(); + } +} + diff --git a/src/InStream.java b/src/InStream.java new file mode 100644 index 0000000..62fb310 --- /dev/null +++ b/src/InStream.java @@ -0,0 +1,148 @@ +/* + * Decompiled with CFR 0.152. + */ +public abstract class InStream { + public static int maxStringLength = 65535; + protected byte[] b; + protected int ptr; + protected int end; + + public final int check(int n, int n2) throws Exception { + if (this.ptr + n * n2 > this.end) { + if (this.ptr + n > this.end) { + return this.overrun(n, n2); + } + n2 = (this.end - this.ptr) / n; + } + return n2; + } + + public final void check(int n) throws Exception { + if (this.ptr + n > this.end) { + this.overrun(n, 1); + } + } + + public final int readS8() throws Exception { + this.check(1); + return this.b[this.ptr++]; + } + + public final int readS16() throws Exception { + this.check(2); + byte by = this.b[this.ptr++]; + int n = this.b[this.ptr++] & 0xFF; + return by << 8 | n; + } + + public final int readS32() throws Exception { + this.check(4); + byte by = this.b[this.ptr++]; + int n = this.b[this.ptr++] & 0xFF; + int n2 = this.b[this.ptr++] & 0xFF; + int n3 = this.b[this.ptr++] & 0xFF; + return by << 24 | n << 16 | n2 << 8 | n3; + } + + public final int readU8() throws Exception { + return this.readS8() & 0xFF; + } + + public final int readU16() throws Exception { + return this.readS16() & 0xFFFF; + } + + public final int readU32() throws Exception { + return this.readS32() & 0xFFFFFFFF; + } + + public final String readString() throws Exception { + int n = this.readU32(); + if (n > maxStringLength) { + throw new Exception("InStream max string length exceeded"); + } + char[] cArray = new char[n]; + int n2 = 0; + while (n2 < n) { + int n3 = n2 + this.check(1, n - n2); + while (n2 < n3) { + cArray[n2++] = (char)this.b[this.ptr++]; + } + } + return new String(cArray); + } + + public final void skip(int n) throws Exception { + while (n > 0) { + int n2 = this.check(1, n); + this.ptr += n2; + n -= n2; + } + } + + public void readBytes(byte[] byArray, int n, int n2) throws Exception { + int n3 = n + n2; + while (n < n3) { + int n4 = this.check(1, n3 - n); + System.arraycopy(this.b, this.ptr, byArray, n, n4); + this.ptr += n4; + n += n4; + } + } + + public final int readOpaque8() throws Exception { + return this.readU8(); + } + + public final int readOpaque16() throws Exception { + return this.readU16(); + } + + public final int readOpaque32() throws Exception { + return this.readU32(); + } + + public final int readOpaque24A() throws Exception { + this.check(3); + byte by = this.b[this.ptr++]; + byte by2 = this.b[this.ptr++]; + byte by3 = this.b[this.ptr++]; + return by << 24 | by2 << 16 | by3 << 8; + } + + public final int readOpaque24B() throws Exception { + this.check(3); + byte by = this.b[this.ptr++]; + byte by2 = this.b[this.ptr++]; + byte by3 = this.b[this.ptr++]; + return by << 16 | by2 << 8 | by3; + } + + public abstract int pos(); + + public boolean bytesAvailable() { + return this.end != this.ptr; + } + + public final byte[] getbuf() { + return this.b; + } + + public final int getptr() { + return this.ptr; + } + + public final int getend() { + return this.end; + } + + public final void setptr(int n) { + this.ptr = n; + } + + protected abstract int overrun(int var1, int var2) throws Exception; + + protected InStream() { + } +} + diff --git a/src/MemInStream.java b/src/MemInStream.java new file mode 100644 index 0000000..75b0bde --- /dev/null +++ b/src/MemInStream.java @@ -0,0 +1,20 @@ +/* + * Decompiled with CFR 0.152. + */ +public class MemInStream +extends InStream { + public MemInStream(byte[] byArray, int n, int n2) { + this.b = byArray; + this.ptr = n; + this.end = n + n2; + } + + public int pos() { + return this.ptr; + } + + protected int overrun(int n, int n2) throws Exception { + throw new Exception("MemInStream overrun: end of stream"); + } +} + diff --git a/src/OptionsFrame.java b/src/OptionsFrame.java new file mode 100644 index 0000000..a711d50 --- /dev/null +++ b/src/OptionsFrame.java @@ -0,0 +1,267 @@ +/* + * Decompiled with CFR 0.152. + */ +import java.awt.Button; +import java.awt.Choice; +import java.awt.Component; +import java.awt.Frame; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Label; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.awt.event.WindowEvent; +import java.awt.event.WindowListener; + +class OptionsFrame +extends Frame +implements WindowListener, +ActionListener, +ItemListener { + static String[] names = new String[]{"Encoding", "Compression level", "JPEG image quality", "Cursor shape updates", "Use CopyRect", "Restricted colors", "Mouse buttons 2 and 3", "View only", "Scale remote cursor", "Share desktop"}; + static String[][] values = new String[][]{{"Auto", "Raw", "RRE", "CoRRE", "Hextile", "Zlib", "Tight", "ZRLE"}, {"Default", "1", "2", "3", "4", "5", "6", "7", "8", "9"}, {"JPEG off", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"}, {"Enable", "Ignore", "Disable"}, {"Yes", "No"}, {"Yes", "No"}, {"Normal", "Reversed"}, {"Yes", "No"}, {"No", "50%", "75%", "125%", "150%"}, {"Yes", "No"}}; + final int encodingIndex = 0; + final int compressLevelIndex = 1; + final int jpegQualityIndex = 2; + final int cursorUpdatesIndex = 3; + final int useCopyRectIndex = 4; + final int eightBitColorsIndex = 5; + final int mouseButtonIndex = 6; + final int viewOnlyIndex = 7; + final int scaleCursorIndex = 8; + final int shareDesktopIndex = 9; + Label[] labels = new Label[names.length]; + Choice[] choices = new Choice[names.length]; + Button closeButton; + VncViewer viewer; + int preferredEncoding; + int compressLevel; + int jpegQuality; + boolean useCopyRect; + boolean requestCursorUpdates; + boolean ignoreCursorUpdates; + boolean eightBitColors; + boolean reverseMouseButtons2And3; + boolean shareDesktop; + boolean viewOnly; + int scaleCursor; + boolean autoScale; + int scalingFactor; + + OptionsFrame(VncViewer vncViewer) { + super("TightVNC Options"); + int n; + this.viewer = vncViewer; + GridBagLayout gridBagLayout = new GridBagLayout(); + this.setLayout(gridBagLayout); + GridBagConstraints gridBagConstraints = new GridBagConstraints(); + gridBagConstraints.fill = 1; + for (n = 0; n < names.length; ++n) { + this.labels[n] = new Label(names[n]); + gridBagConstraints.gridwidth = 1; + gridBagLayout.setConstraints(this.labels[n], gridBagConstraints); + this.add(this.labels[n]); + this.choices[n] = new Choice(); + gridBagConstraints.gridwidth = 0; + gridBagLayout.setConstraints(this.choices[n], gridBagConstraints); + this.add(this.choices[n]); + this.choices[n].addItemListener(this); + for (int i = 0; i < values[n].length; ++i) { + this.choices[n].addItem(values[n][i]); + } + } + this.closeButton = new Button("Close"); + gridBagConstraints.gridwidth = 0; + gridBagLayout.setConstraints(this.closeButton, gridBagConstraints); + this.add(this.closeButton); + this.closeButton.addActionListener(this); + this.pack(); + this.addWindowListener(this); + this.choices[0].select("Auto"); + this.choices[1].select("Default"); + this.choices[2].select("6"); + this.choices[3].select("Enable"); + this.choices[4].select("Yes"); + this.choices[5].select("No"); + this.choices[6].select("Normal"); + this.choices[7].select("No"); + this.choices[8].select("No"); + this.choices[9].select("Yes"); + for (n = 0; n < names.length; ++n) { + String string = this.viewer.readParameter(names[n], false); + if (string == null) continue; + for (int i = 0; i < values[n].length; ++i) { + if (!string.equalsIgnoreCase(values[n][i])) continue; + this.choices[n].select(i); + } + } + this.autoScale = false; + this.scalingFactor = 100; + String string = this.viewer.readParameter("Scaling Factor", false); + if (string != null) { + if (string.equalsIgnoreCase("Auto")) { + this.autoScale = true; + } else { + if (string.charAt(string.length() - 1) == '%') { + string = string.substring(0, string.length() - 1); + } + try { + this.scalingFactor = Integer.parseInt(string); + } + catch (NumberFormatException numberFormatException) { + this.scalingFactor = 100; + } + if (this.scalingFactor < 1) { + this.scalingFactor = 1; + } else if (this.scalingFactor > 1000) { + this.scalingFactor = 1000; + } + } + } + this.setEncodings(); + this.setColorFormat(); + this.setOtherOptions(); + } + + void disableShareDesktop() { + this.labels[9].setEnabled(false); + this.choices[9].setEnabled(false); + } + + void setEncodings() { + this.useCopyRect = this.choices[4].getSelectedItem().equals("Yes"); + this.preferredEncoding = 0; + boolean bl = false; + boolean bl2 = false; + if (this.choices[0].getSelectedItem().equals("RRE")) { + this.preferredEncoding = 2; + } else if (this.choices[0].getSelectedItem().equals("CoRRE")) { + this.preferredEncoding = 4; + } else if (this.choices[0].getSelectedItem().equals("Hextile")) { + this.preferredEncoding = 5; + } else if (this.choices[0].getSelectedItem().equals("ZRLE")) { + this.preferredEncoding = 16; + } else if (this.choices[0].getSelectedItem().equals("Zlib")) { + this.preferredEncoding = 6; + bl = true; + } else if (this.choices[0].getSelectedItem().equals("Tight")) { + this.preferredEncoding = 7; + bl = true; + bl2 = !this.eightBitColors; + } else if (this.choices[0].getSelectedItem().equals("Auto")) { + this.preferredEncoding = -1; + bl2 = !this.eightBitColors; + } + try { + this.compressLevel = Integer.parseInt(this.choices[1].getSelectedItem()); + } + catch (NumberFormatException numberFormatException) { + this.compressLevel = -1; + } + if (this.compressLevel < 1 || this.compressLevel > 9) { + this.compressLevel = -1; + } + this.labels[1].setEnabled(bl); + this.choices[1].setEnabled(bl); + try { + this.jpegQuality = Integer.parseInt(this.choices[2].getSelectedItem()); + } + catch (NumberFormatException numberFormatException) { + this.jpegQuality = -1; + } + if (this.jpegQuality < 0 || this.jpegQuality > 9) { + this.jpegQuality = -1; + } + this.labels[2].setEnabled(bl2); + this.choices[2].setEnabled(bl2); + boolean bl3 = this.requestCursorUpdates = !this.choices[3].getSelectedItem().equals("Disable"); + if (this.requestCursorUpdates) { + this.ignoreCursorUpdates = this.choices[3].getSelectedItem().equals("Ignore"); + } + this.viewer.setEncodings(); + } + + void setColorFormat() { + this.eightBitColors = this.choices[5].getSelectedItem().equals("Yes"); + boolean bl = !this.eightBitColors && (this.choices[0].getSelectedItem().equals("Tight") || this.choices[0].getSelectedItem().equals("Auto")); + this.labels[2].setEnabled(bl); + this.choices[2].setEnabled(bl); + } + + void setOtherOptions() { + this.reverseMouseButtons2And3 = this.choices[6].getSelectedItem().equals("Reversed"); + this.viewOnly = this.choices[7].getSelectedItem().equals("Yes"); + if (this.viewer.vc != null) { + this.viewer.vc.enableInput(!this.viewOnly); + } + this.shareDesktop = this.choices[9].getSelectedItem().equals("Yes"); + String string = this.choices[8].getSelectedItem(); + if (string.endsWith("%")) { + string = string.substring(0, string.length() - 1); + } + try { + this.scaleCursor = Integer.parseInt(string); + } + catch (NumberFormatException numberFormatException) { + this.scaleCursor = 0; + } + if (this.scaleCursor < 10 || this.scaleCursor > 500) { + this.scaleCursor = 0; + } + if (this.requestCursorUpdates && !this.ignoreCursorUpdates && !this.viewOnly) { + this.labels[8].setEnabled(true); + this.choices[8].setEnabled(true); + } else { + this.labels[8].setEnabled(false); + this.choices[8].setEnabled(false); + } + if (this.viewer.vc != null) { + this.viewer.vc.createSoftCursor(); + } + } + + public void itemStateChanged(ItemEvent itemEvent) { + Object object = itemEvent.getSource(); + if (object == this.choices[0] || object == this.choices[1] || object == this.choices[2] || object == this.choices[3] || object == this.choices[4]) { + this.setEncodings(); + if (object == this.choices[3]) { + this.setOtherOptions(); + } + } else if (object == this.choices[5]) { + this.setColorFormat(); + } else if (object == this.choices[6] || object == this.choices[9] || object == this.choices[7] || object == this.choices[8]) { + this.setOtherOptions(); + } + } + + public void actionPerformed(ActionEvent actionEvent) { + if (actionEvent.getSource() == this.closeButton) { + ((Component)this).setVisible(false); + } + } + + public void windowClosing(WindowEvent windowEvent) { + ((Component)this).setVisible(false); + } + + public void windowActivated(WindowEvent windowEvent) { + } + + public void windowDeactivated(WindowEvent windowEvent) { + } + + public void windowOpened(WindowEvent windowEvent) { + } + + public void windowClosed(WindowEvent windowEvent) { + } + + public void windowIconified(WindowEvent windowEvent) { + } + + public void windowDeiconified(WindowEvent windowEvent) { + } +} + diff --git a/src/RecordingFrame.java b/src/RecordingFrame.java new file mode 100644 index 0000000..17146c2 --- /dev/null +++ b/src/RecordingFrame.java @@ -0,0 +1,231 @@ +/* + * Decompiled with CFR 0.152. + */ +import java.awt.Button; +import java.awt.Color; +import java.awt.Component; +import java.awt.FileDialog; +import java.awt.Font; +import java.awt.Frame; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.awt.Label; +import java.awt.Panel; +import java.awt.TextField; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.WindowEvent; +import java.awt.event.WindowListener; +import java.io.File; + +class RecordingFrame +extends Frame +implements WindowListener, +ActionListener { + boolean recording; + TextField fnameField; + Button browseButton; + Label statusLabel; + Button recordButton; + Button nextButton; + Button closeButton; + VncViewer viewer; + + public static boolean checkSecurity() { + SecurityManager securityManager = System.getSecurityManager(); + if (securityManager != null) { + try { + securityManager.checkPropertyAccess("user.dir"); + securityManager.checkPropertyAccess("file.separator"); + System.getProperty("user.dir"); + } + catch (SecurityException securityException) { + System.out.println("SecurityManager restricts session recording."); + return false; + } + } + return true; + } + + RecordingFrame(VncViewer vncViewer) { + super("TightVNC Session Recording"); + this.viewer = vncViewer; + String string = this.nextNewFilename(System.getProperty("user.dir") + System.getProperty("file.separator") + "vncsession.fbs"); + Panel panel = new Panel(); + GridBagLayout gridBagLayout = new GridBagLayout(); + panel.setLayout(gridBagLayout); + GridBagConstraints gridBagConstraints = new GridBagConstraints(); + gridBagConstraints.gridwidth = -1; + gridBagConstraints.fill = 1; + gridBagConstraints.weightx = 4.0; + this.fnameField = new TextField(string, 64); + gridBagLayout.setConstraints(this.fnameField, gridBagConstraints); + panel.add(this.fnameField); + this.fnameField.addActionListener(this); + gridBagConstraints.gridwidth = 0; + gridBagConstraints.weightx = 1.0; + this.browseButton = new Button("Browse"); + gridBagLayout.setConstraints(this.browseButton, gridBagConstraints); + panel.add(this.browseButton); + this.browseButton.addActionListener(this); + GridBagLayout gridBagLayout2 = new GridBagLayout(); + this.setLayout(gridBagLayout2); + GridBagConstraints gridBagConstraints2 = new GridBagConstraints(); + gridBagConstraints2.gridwidth = 0; + gridBagConstraints2.fill = 1; + gridBagConstraints2.weighty = 1.0; + gridBagConstraints2.insets = new Insets(10, 0, 0, 0); + Label label = new Label("File name to save next recorded session in:", 1); + gridBagLayout2.setConstraints(label, gridBagConstraints2); + this.add(label); + gridBagConstraints2.fill = 2; + gridBagConstraints2.weighty = 0.0; + gridBagConstraints2.insets = new Insets(0, 0, 0, 0); + gridBagLayout2.setConstraints(panel, gridBagConstraints2); + this.add(panel); + gridBagConstraints2.fill = 1; + gridBagConstraints2.weighty = 1.0; + gridBagConstraints2.insets = new Insets(10, 0, 10, 0); + this.statusLabel = new Label("", 1); + gridBagLayout2.setConstraints(this.statusLabel, gridBagConstraints2); + this.add(this.statusLabel); + gridBagConstraints2.fill = 2; + gridBagConstraints2.weightx = 1.0; + gridBagConstraints2.weighty = 0.0; + gridBagConstraints2.gridwidth = 1; + gridBagConstraints2.insets = new Insets(0, 0, 0, 0); + this.recordButton = new Button("Record"); + gridBagLayout2.setConstraints(this.recordButton, gridBagConstraints2); + this.add(this.recordButton); + this.recordButton.addActionListener(this); + this.nextButton = new Button("Next file"); + gridBagLayout2.setConstraints(this.nextButton, gridBagConstraints2); + this.add(this.nextButton); + this.nextButton.addActionListener(this); + this.closeButton = new Button("Close"); + gridBagLayout2.setConstraints(this.closeButton, gridBagConstraints2); + this.add(this.closeButton); + this.closeButton.addActionListener(this); + this.stopRecording(); + this.pack(); + this.addWindowListener(this); + } + + protected String nextFilename(String string) { + int n; + int n2 = n = string.length(); + int n3 = 1; + if (n > 4 && string.charAt(n - 4) == '.') { + try { + n3 = Integer.parseInt(string.substring(n - 3, n)) + 1; + n2 = n - 4; + } + catch (NumberFormatException numberFormatException) { + // empty catch block + } + } + char[] cArray = new char[]{'0', '0', '0'}; + String string2 = String.valueOf(n3); + if (string2.length() < 3) { + string2 = new String(cArray, 0, 3 - string2.length()) + string2; + } + return string.substring(0, n2) + '.' + string2; + } + + protected String nextNewFilename(String string) { + String string2 = string; + try { + File file; + while ((file = new File(string2 = this.nextFilename(string2))).exists()) { + } + } + catch (SecurityException securityException) { + // empty catch block + } + return string2; + } + + protected boolean browseFile() { + File file = new File(this.fnameField.getText()); + FileDialog fileDialog = new FileDialog((Frame)this, "Save next session as...", 1); + fileDialog.setDirectory(file.getParent()); + ((Component)fileDialog).setVisible(true); + if (fileDialog.getFile() != null) { + String string; + String string2 = fileDialog.getDirectory(); + String string3 = System.getProperty("file.separator"); + if (string2.length() > 0 && !string3.equals(string2.substring(string2.length() - string3.length()))) { + string2 = string2 + string3; + } + if ((string = string2 + fileDialog.getFile()).equals(this.fnameField.getText())) { + this.fnameField.setText(string); + return true; + } + } + return false; + } + + public void startRecording() { + this.statusLabel.setText("Status: Recording..."); + this.statusLabel.setFont(new Font("Helvetica", 1, 12)); + this.statusLabel.setForeground(Color.red); + this.recordButton.setLabel("Stop recording"); + this.recording = true; + this.viewer.setRecordingStatus(this.fnameField.getText()); + } + + public void stopRecording() { + this.statusLabel.setText("Status: Not recording."); + this.statusLabel.setFont(new Font("Helvetica", 0, 12)); + this.statusLabel.setForeground(Color.black); + this.recordButton.setLabel("Record"); + this.recording = false; + this.viewer.setRecordingStatus(null); + } + + public void windowClosing(WindowEvent windowEvent) { + ((Component)this).setVisible(false); + } + + public void windowActivated(WindowEvent windowEvent) { + } + + public void windowDeactivated(WindowEvent windowEvent) { + } + + public void windowOpened(WindowEvent windowEvent) { + } + + public void windowClosed(WindowEvent windowEvent) { + } + + public void windowIconified(WindowEvent windowEvent) { + } + + public void windowDeiconified(WindowEvent windowEvent) { + } + + public void actionPerformed(ActionEvent actionEvent) { + if (actionEvent.getSource() == this.browseButton) { + if (this.browseFile() && this.recording) { + this.startRecording(); + } + } else if (actionEvent.getSource() == this.recordButton) { + if (!this.recording) { + this.startRecording(); + } else { + this.stopRecording(); + this.fnameField.setText(this.nextNewFilename(this.fnameField.getText())); + } + } else if (actionEvent.getSource() == this.nextButton) { + this.fnameField.setText(this.nextNewFilename(this.fnameField.getText())); + if (this.recording) { + this.startRecording(); + } + } else if (actionEvent.getSource() == this.closeButton) { + ((Component)this).setVisible(false); + } + } +} + diff --git a/src/ReloginPanel.java b/src/ReloginPanel.java new file mode 100644 index 0000000..b0afa06 --- /dev/null +++ b/src/ReloginPanel.java @@ -0,0 +1,39 @@ +/* + * Decompiled with CFR 0.152. + */ +import java.awt.Button; +import java.awt.FlowLayout; +import java.awt.Panel; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +class ReloginPanel +extends Panel +implements ActionListener { + Button reloginButton; + Button closeButton; + VncViewer viewer; + + public ReloginPanel(VncViewer vncViewer) { + this.viewer = vncViewer; + this.setLayout(new FlowLayout(1)); + this.reloginButton = new Button("Login again"); + this.add(this.reloginButton); + this.reloginButton.addActionListener(this); + if (this.viewer.inSeparateFrame) { + this.closeButton = new Button("Close window"); + this.add(this.closeButton); + this.closeButton.addActionListener(this); + } + } + + public synchronized void actionPerformed(ActionEvent actionEvent) { + if (this.viewer.inSeparateFrame) { + this.viewer.vncFrame.dispose(); + } + if (actionEvent.getSource() == this.reloginButton) { + this.viewer.getAppletContext().showDocument(this.viewer.getDocumentBase()); + } + } +} + diff --git a/src/RfbProto.java b/src/RfbProto.java new file mode 100644 index 0000000..c06b95d --- /dev/null +++ b/src/RfbProto.java @@ -0,0 +1,1027 @@ +/* + * Decompiled with CFR 0.152. + */ +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; +import java.io.BufferedInputStream; +import java.io.DataInputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.net.Socket; +import java.util.zip.Deflater; + +class RfbProto { + static final String versionMsg_3_3 = "RFB 003.003\n"; + static final String versionMsg_3_4 = "RFB 003.004\n"; + static final String versionMsg_3_7 = "RFB 003.007\n"; + static final String versionMsg_3_8 = "RFB 003.008\n"; + static final String StandardVendor = "STDV"; + static final String TridiaVncVendor = "TRDV"; + static final String UltraVncVendor = "UVNC"; + static final String TightVncVendor = "TGHT"; + static final int SecTypeInvalid = 0; + static final int SecTypeNone = 1; + static final int SecTypeVncAuth = 2; + static final int SecTypeTight = 16; + static final int SecTypeMsLogon = -6; + static final int NoTunneling = 0; + static final String SigNoTunneling = "NOTUNNEL"; + static final int AuthNone = 1; + static final int AuthVNC = 2; + static final int AuthMSL = -6; + static final int AuthUnixLogin = 129; + static final String SigAuthNone = "NOAUTH__"; + static final String SigAuthVNC = "VNCAUTH_"; + static final String SigAuthMSLogon = "MSLOGON_"; + static final String SigAuthUnixLogin = "ULGNAUTH"; + static final int VncAuthOK = 0; + static final int VncAuthFailed = 1; + static final int VncAuthTooMany = 2; + static final int FramebufferUpdate = 0; + static final int SetColourMapEntries = 1; + static final int Bell = 2; + static final int ServerCutText = 3; + static final int SetPixelFormat = 0; + static final int FixColourMapEntries = 1; + static final int SetEncodings = 2; + static final int FramebufferUpdateRequest = 3; + static final int KeyboardEvent = 4; + static final int PointerEvent = 5; + static final int ClientCutText = 6; + static final int EncodingRaw = 0; + static final int EncodingCopyRect = 1; + static final int EncodingRRE = 2; + static final int EncodingCoRRE = 4; + static final int EncodingHextile = 5; + static final int EncodingZlib = 6; + static final int EncodingTight = 7; + static final int EncodingZRLE = 16; + static final int EncodingCompressLevel0 = -256; + static final int EncodingQualityLevel0 = -32; + static final int EncodingXCursor = -240; + static final int EncodingRichCursor = -239; + static final int EncodingPointerPos = -232; + static final int EncodingLastRect = -224; + static final int EncodingNewFBSize = -223; + static final String SigEncodingRaw = "RAW_____"; + static final String SigEncodingCopyRect = "COPYRECT"; + static final String SigEncodingRRE = "RRE_____"; + static final String SigEncodingCoRRE = "CORRE___"; + static final String SigEncodingHextile = "HEXTILE_"; + static final String SigEncodingZlib = "ZLIB____"; + static final String SigEncodingTight = "TIGHT___"; + static final String SigEncodingZRLE = "ZRLE____"; + static final String SigEncodingCompressLevel0 = "COMPRLVL"; + static final String SigEncodingQualityLevel0 = "JPEGQLVL"; + static final String SigEncodingXCursor = "X11CURSR"; + static final String SigEncodingRichCursor = "RCHCURSR"; + static final String SigEncodingPointerPos = "POINTPOS"; + static final String SigEncodingLastRect = "LASTRECT"; + static final String SigEncodingNewFBSize = "NEWFBSIZ"; + static final int MaxNormalEncoding = 255; + static final int HextileRaw = 1; + static final int HextileBackgroundSpecified = 2; + static final int HextileForegroundSpecified = 4; + static final int HextileAnySubrects = 8; + static final int HextileSubrectsColoured = 16; + static final int TightMinToCompress = 12; + static final int TightExplicitFilter = 4; + static final int TightFill = 8; + static final int TightJpeg = 9; + static final int TightMaxSubencoding = 9; + static final int TightFilterCopy = 0; + static final int TightFilterPalette = 1; + static final int TightFilterGradient = 2; + String host; + int port; + Socket sock; + DataInputStream is; + OutputStream os; + SessionRecorder rec; + boolean inNormalProtocol = false; + VncViewer viewer; + boolean brokenKeyPressed = false; + boolean wereZlibUpdates = false; + boolean recordFromBeginning = true; + boolean zlibWarningShown; + boolean tightWarningShown; + int numUpdatesInSession; + boolean timing; + long timeWaitedIn100us; + long timedKbits; + int serverMajor; + int serverMinor; + int clientMajor; + int clientMinor; + boolean protocolTightVNC; + CapsContainer tunnelCaps; + CapsContainer authCaps; + CapsContainer serverMsgCaps; + CapsContainer clientMsgCaps; + CapsContainer encodingCaps; + private boolean closed; + String desktopName; + int framebufferWidth; + int framebufferHeight; + int bitsPerPixel; + int depth; + boolean bigEndian; + boolean trueColour; + int redMax; + int greenMax; + int blueMax; + int redShift; + int greenShift; + int blueShift; + int updateNRects; + int updateRectX; + int updateRectY; + int updateRectW; + int updateRectH; + int updateRectEncoding; + int copyRectSrcX; + int copyRectSrcY; + byte[] eventBuf = new byte[72]; + int eventBufLen; + static final int CTRL_MASK = 2; + static final int SHIFT_MASK = 1; + static final int META_MASK = 4; + static final int ALT_MASK = 8; + int pointerMask = 0; + int oldModifiers = 0; + + RfbProto(String string, int n, VncViewer vncViewer) throws IOException { + this.viewer = vncViewer; + this.host = string; + this.port = n; + if (this.viewer.socketFactory == null) { + this.sock = new Socket(this.host, this.port); + } else { + try { + Class clazz = Class.forName(this.viewer.socketFactory); + SocketFactory socketFactory = (SocketFactory)clazz.newInstance(); + this.sock = this.viewer.inAnApplet ? socketFactory.createSocket(this.host, this.port, this.viewer) : socketFactory.createSocket(this.host, this.port, this.viewer.mainArgs); + } + catch (Exception exception) { + exception.printStackTrace(); + throw new IOException(exception.getMessage()); + } + } + this.is = new DataInputStream(new BufferedInputStream(this.sock.getInputStream(), 16384)); + this.os = this.sock.getOutputStream(); + this.timing = false; + this.timeWaitedIn100us = 5L; + this.timedKbits = 0L; + } + + synchronized void close() { + try { + this.sock.close(); + this.closed = true; + System.out.println("RFB socket closed"); + if (this.rec != null) { + this.rec.close(); + this.rec = null; + } + } + catch (Exception exception) { + exception.printStackTrace(); + } + } + + synchronized boolean closed() { + return this.closed; + } + + void readVersionMsg() throws Exception { + byte[] byArray = new byte[12]; + this.readFully(byArray); + if (byArray[0] != 82 || byArray[1] != 70 || byArray[2] != 66 || byArray[3] != 32 || byArray[4] < 48 || byArray[4] > 57 || byArray[5] < 48 || byArray[5] > 57 || byArray[6] < 48 || byArray[6] > 57 || byArray[7] != 46 || byArray[8] < 48 || byArray[8] > 57 || byArray[9] < 48 || byArray[9] > 57 || byArray[10] < 48 || byArray[10] > 57 || byArray[11] != 10) { + throw new Exception("Host " + this.host + " port " + this.port + " is not an RFB server"); + } + this.serverMajor = (byArray[4] - 48) * 100 + (byArray[5] - 48) * 10 + (byArray[6] - 48); + this.serverMinor = (byArray[8] - 48) * 100 + (byArray[9] - 48) * 10 + (byArray[10] - 48); + if (this.serverMajor < 3) { + throw new Exception("RFB server does not support protocol version 3"); + } + } + + void writeVersionMsg() throws IOException { + this.clientMajor = 3; + if (this.serverMajor > 3 || this.serverMinor >= 8) { + this.clientMinor = 8; + this.os.write(versionMsg_3_8.getBytes()); + } else if (this.serverMinor >= 7) { + this.clientMinor = 7; + this.os.write(versionMsg_3_7.getBytes()); + } else { + this.clientMinor = 3; + this.os.write(versionMsg_3_3.getBytes()); + } + this.protocolTightVNC = false; + } + + int negotiateSecurity() throws Exception { + return this.clientMinor >= 7 ? this.selectSecurityType() : this.readSecurityType(); + } + + int readSecurityType() throws Exception { + int n = this.is.readInt(); + switch (n) { + case 0: { + this.readConnFailedReason(); + return 0; + } + case -6: + case 1: + case 2: { + return n; + } + } + throw new Exception("Unknown security type from RFB server: " + n); + } + + int selectSecurityType() throws Exception { + int n; + int n2 = 0; + int n3 = this.is.readUnsignedByte(); + if (n3 == 0) { + this.readConnFailedReason(); + return 0; + } + byte[] byArray = new byte[n3]; + this.readFully(byArray); + for (n = 0; n < n3; ++n) { + if (byArray[n] != 16) continue; + this.protocolTightVNC = true; + this.os.write(16); + return 16; + } + for (n = 0; n < n3; ++n) { + if (byArray[n] != 1 && byArray[n] != 2 && byArray[n] != -6) continue; + n2 = byArray[n]; + break; + } + if (n2 == 0) { + throw new Exception("Server did not offer supported security type"); + } + this.os.write(n2); + return n2; + } + + void authenticateNone() throws Exception { + if (this.clientMinor >= 8) { + this.readSecurityResult("No authentication"); + } + } + + void authenticateVNC(String string) throws Exception { + int n; + byte[] byArray = new byte[16]; + this.readFully(byArray); + if (string.length() > 8) { + string = string.substring(0, 8); + } + if ((n = string.indexOf(0)) != -1) { + string = string.substring(0, n); + } + byte[] byArray2 = new byte[]{0, 0, 0, 0, 0, 0, 0, 0}; + System.arraycopy(string.getBytes(), 0, byArray2, 0, string.length()); + DesCipher desCipher = new DesCipher(byArray2); + desCipher.encrypt(byArray, 0, byArray, 0); + desCipher.encrypt(byArray, 8, byArray, 8); + this.os.write(byArray); + this.readSecurityResult("VNC authentication"); + } + + void authenticateMSLogonI(String string, String string2) throws Exception { + int n; + int n2; + byte[] byArray = new byte[256]; + byte[] byArray2 = new byte[256]; + byte[] byArray3 = new byte[256]; + byte[] byArray4 = new byte[64]; + byte[] byArray5 = new byte[16]; + System.arraycopy(string2.getBytes(), 0, byArray, 0, string2.length()); + if (string2.length() < 256) { + for (int i = string2.length(); i < 256; ++i) { + byArray[i] = 0; + } + } + String string3 = "."; + System.arraycopy(string3.getBytes(), 0, byArray2, 0, string3.length()); + if (string3.length() < 256) { + for (n2 = string3.length(); n2 < 256; ++n2) { + byArray2[n2] = 0; + } + } + System.arraycopy(string.getBytes(), 0, byArray3, 0, string.length()); + if (string.length() < 32) { + for (n2 = string.length(); n2 < 32; ++n2) { + byArray3[n2] = 0; + } + } + byte[] byArray6 = new byte[]{23, 82, 107, 6, 35, 78, 88, 7}; + DesCipher desCipher = new DesCipher(byArray6); + desCipher.encrypt(byArray3, 0, byArray3, 0); + this.is.readFully(byArray4); + this.is.readFully(byArray5); + if (string.length() > 8) { + string = string.substring(0, 8); + } + if ((n = string.indexOf(0)) != -1) { + string = string.substring(0, n); + } + for (int i = 0; i < 32; ++i) { + byArray4[i] = (byte)(byArray3[i] ^ byArray4[i]); + } + this.os.write(byArray); + this.os.write(byArray2); + this.os.write(byArray4); + byte[] byArray7 = new byte[]{0, 0, 0, 0, 0, 0, 0, 0}; + System.arraycopy(string.getBytes(), 0, byArray7, 0, string.length()); + DesCipher desCipher2 = new DesCipher(byArray7); + desCipher2.encrypt(byArray5, 0, byArray5, 0); + desCipher2.encrypt(byArray5, 8, byArray5, 8); + this.os.write(byArray5); + this.readSecurityResult("VNC+MS authentication"); + } + + void authenticateMSLogon(String string, String string2) throws Exception { + int n; + byte[] byArray = new byte[256]; + byte[] byArray2 = new byte[64]; + long l = this.is.readLong(); + long l2 = this.is.readLong(); + long l3 = this.is.readLong(); + DiffieHellman diffieHellman = new DiffieHellman(l, l2); + long l4 = diffieHellman.createInterKey(); + this.os.write(DiffieHellman.longToBytes(l4)); + long l5 = diffieHellman.createEncryptionKey(l3); + System.out.println("gen=" + l + ", mod=" + l2 + ", pub=" + l4 + ", key=" + l5); + DesCipher desCipher = new DesCipher(DiffieHellman.longToBytes(l5)); + System.arraycopy(string2.getBytes(), 0, byArray, 0, string2.length()); + if (string2.length() < 256) { + for (n = string2.length(); n < 256; ++n) { + byArray[n] = 0; + } + } + System.arraycopy(string.getBytes(), 0, byArray2, 0, string.length()); + if (string.length() < 32) { + for (n = string.length(); n < 32; ++n) { + byArray2[n] = 0; + } + } + desCipher.encryptText(byArray, byArray, DiffieHellman.longToBytes(l5)); + desCipher.encryptText(byArray2, byArray2, DiffieHellman.longToBytes(l5)); + this.os.write(byArray); + this.os.write(byArray2); + this.readSecurityResult("MS-Logon authentication"); + } + + void readSecurityResult(String string) throws Exception { + int n = this.is.readInt(); + switch (n) { + case 0: { + System.out.println(string + ": success"); + break; + } + case 1: { + if (this.clientMinor >= 8) { + this.readConnFailedReason(); + } + throw new Exception(string + ": failed"); + } + case 2: { + throw new Exception(string + ": failed, too many tries"); + } + default: { + throw new Exception(string + ": unknown result " + n); + } + } + } + + void readConnFailedReason() throws Exception { + int n = this.is.readInt(); + byte[] byArray = new byte[n]; + this.readFully(byArray); + throw new Exception(new String(byArray)); + } + + void initCapabilities() { + this.tunnelCaps = new CapsContainer(); + this.authCaps = new CapsContainer(); + this.serverMsgCaps = new CapsContainer(); + this.clientMsgCaps = new CapsContainer(); + this.encodingCaps = new CapsContainer(); + this.authCaps.add(1, StandardVendor, SigAuthNone, "No authentication"); + this.authCaps.add(2, StandardVendor, SigAuthVNC, "Standard VNC password authentication"); + this.authCaps.add(-6, UltraVncVendor, SigAuthMSLogon, "MS-Logon authentication"); + this.encodingCaps.add(1, StandardVendor, SigEncodingCopyRect, "Standard CopyRect encoding"); + this.encodingCaps.add(2, StandardVendor, SigEncodingRRE, "Standard RRE encoding"); + this.encodingCaps.add(4, StandardVendor, SigEncodingCoRRE, "Standard CoRRE encoding"); + this.encodingCaps.add(5, StandardVendor, SigEncodingHextile, "Standard Hextile encoding"); + this.encodingCaps.add(16, StandardVendor, SigEncodingZRLE, "Standard ZRLE encoding"); + this.encodingCaps.add(6, TridiaVncVendor, SigEncodingZlib, "Zlib encoding"); + this.encodingCaps.add(7, TightVncVendor, SigEncodingTight, "Tight encoding"); + this.encodingCaps.add(-256, TightVncVendor, SigEncodingCompressLevel0, "Compression level"); + this.encodingCaps.add(-32, TightVncVendor, SigEncodingQualityLevel0, "JPEG quality level"); + this.encodingCaps.add(-240, TightVncVendor, SigEncodingXCursor, "X-style cursor shape update"); + this.encodingCaps.add(-239, TightVncVendor, SigEncodingRichCursor, "Rich-color cursor shape update"); + this.encodingCaps.add(-232, TightVncVendor, SigEncodingPointerPos, "Pointer position update"); + this.encodingCaps.add(-224, TightVncVendor, SigEncodingLastRect, "LastRect protocol extension"); + this.encodingCaps.add(-223, TightVncVendor, SigEncodingNewFBSize, "Framebuffer size change"); + } + + void setupTunneling() throws IOException { + int n = this.is.readInt(); + if (n != 0) { + this.readCapabilityList(this.tunnelCaps, n); + this.writeInt(0); + } + } + + int negotiateAuthenticationTight() throws Exception { + int n = this.is.readInt(); + if (n == 0) { + return 1; + } + this.readCapabilityList(this.authCaps, n); + for (int i = 0; i < this.authCaps.numEnabled(); ++i) { + int n2 = this.authCaps.getByOrder(i); + if (n2 != 1 && n2 != 2 && n2 != -6) continue; + this.writeInt(n2); + return n2; + } + throw new Exception("No suitable authentication scheme found"); + } + + void readCapabilityList(CapsContainer capsContainer, int n) throws IOException { + byte[] byArray = new byte[4]; + byte[] byArray2 = new byte[8]; + for (int i = 0; i < n; ++i) { + int n2 = this.is.readInt(); + this.readFully(byArray); + this.readFully(byArray2); + capsContainer.enable(new CapabilityInfo(n2, byArray, byArray2)); + } + } + + void writeInt(int n) throws IOException { + byte[] byArray = new byte[]{(byte)(n >> 24 & 0xFF), (byte)(n >> 16 & 0xFF), (byte)(n >> 8 & 0xFF), (byte)(n & 0xFF)}; + this.os.write(byArray); + } + + void writeClientInit() throws IOException { + if (this.viewer.options.shareDesktop) { + this.os.write(1); + } else { + this.os.write(0); + } + this.viewer.options.disableShareDesktop(); + } + + void readServerInit() throws IOException { + this.framebufferWidth = this.is.readUnsignedShort(); + this.framebufferHeight = this.is.readUnsignedShort(); + this.bitsPerPixel = this.is.readUnsignedByte(); + this.depth = this.is.readUnsignedByte(); + this.bigEndian = this.is.readUnsignedByte() != 0; + this.trueColour = this.is.readUnsignedByte() != 0; + this.redMax = this.is.readUnsignedShort(); + this.greenMax = this.is.readUnsignedShort(); + this.blueMax = this.is.readUnsignedShort(); + this.redShift = this.is.readUnsignedByte(); + this.greenShift = this.is.readUnsignedByte(); + this.blueShift = this.is.readUnsignedByte(); + byte[] byArray = new byte[3]; + this.readFully(byArray); + int n = this.is.readInt(); + byte[] byArray2 = new byte[n]; + this.readFully(byArray2); + this.desktopName = new String(byArray2); + if (this.protocolTightVNC) { + int n2 = this.is.readUnsignedShort(); + int n3 = this.is.readUnsignedShort(); + int n4 = this.is.readUnsignedShort(); + this.is.readUnsignedShort(); + this.readCapabilityList(this.serverMsgCaps, n2); + this.readCapabilityList(this.clientMsgCaps, n3); + this.readCapabilityList(this.encodingCaps, n4); + } + this.inNormalProtocol = true; + } + + void startSession(String string) throws IOException { + this.rec = new SessionRecorder(string); + this.rec.writeHeader(); + this.rec.write(versionMsg_3_3.getBytes()); + this.rec.writeIntBE(1); + this.rec.writeShortBE(this.framebufferWidth); + this.rec.writeShortBE(this.framebufferHeight); + byte[] byArray = new byte[]{32, 24, 0, 1, 0, -1, 0, -1, 0, -1, 16, 8, 0, 0, 0, 0}; + this.rec.write(byArray); + this.rec.writeIntBE(this.desktopName.length()); + this.rec.write(this.desktopName.getBytes()); + this.numUpdatesInSession = 0; + if (this.wereZlibUpdates) { + this.recordFromBeginning = false; + } + this.zlibWarningShown = false; + this.tightWarningShown = false; + } + + void closeSession() throws IOException { + if (this.rec != null) { + this.rec.close(); + this.rec = null; + } + } + + void setFramebufferSize(int n, int n2) { + this.framebufferWidth = n; + this.framebufferHeight = n2; + } + + int readServerMessageType() throws IOException { + int n = this.is.readUnsignedByte(); + if (this.rec != null && n == 2) { + this.rec.writeByte(n); + if (this.numUpdatesInSession > 0) { + this.rec.flush(); + } + } + return n; + } + + void readFramebufferUpdate() throws IOException { + this.is.readByte(); + this.updateNRects = this.is.readUnsignedShort(); + if (this.rec != null) { + this.rec.writeByte(0); + this.rec.writeByte(0); + this.rec.writeShortBE(this.updateNRects); + } + ++this.numUpdatesInSession; + } + + void readFramebufferUpdateRectHdr() throws Exception { + this.updateRectX = this.is.readUnsignedShort(); + this.updateRectY = this.is.readUnsignedShort(); + this.updateRectW = this.is.readUnsignedShort(); + this.updateRectH = this.is.readUnsignedShort(); + this.updateRectEncoding = this.is.readInt(); + if (this.updateRectEncoding == 6 || this.updateRectEncoding == 16 || this.updateRectEncoding == 7) { + this.wereZlibUpdates = true; + } + if (this.rec != null) { + if (this.numUpdatesInSession > 1) { + this.rec.flush(); + } + this.rec.writeShortBE(this.updateRectX); + this.rec.writeShortBE(this.updateRectY); + this.rec.writeShortBE(this.updateRectW); + this.rec.writeShortBE(this.updateRectH); + if (this.updateRectEncoding == 6 && !this.recordFromBeginning) { + if (!this.zlibWarningShown) { + System.out.println("Warning: Raw encoding will be used instead of Zlib in recorded session."); + this.zlibWarningShown = true; + } + this.rec.writeIntBE(0); + } else { + this.rec.writeIntBE(this.updateRectEncoding); + if (this.updateRectEncoding == 7 && !this.recordFromBeginning && !this.tightWarningShown) { + System.out.println("Warning: Re-compressing Tight-encoded updates for session recording."); + this.tightWarningShown = true; + } + } + } + if (this.updateRectEncoding < 0 || this.updateRectEncoding > 255) { + return; + } + if (this.updateRectX + this.updateRectW > this.framebufferWidth || this.updateRectY + this.updateRectH > this.framebufferHeight) { + throw new Exception("Framebuffer update rectangle too large: " + this.updateRectW + "x" + this.updateRectH + " at (" + this.updateRectX + "," + this.updateRectY + ")"); + } + } + + void readCopyRect() throws IOException { + this.copyRectSrcX = this.is.readUnsignedShort(); + this.copyRectSrcY = this.is.readUnsignedShort(); + if (this.rec != null) { + this.rec.writeShortBE(this.copyRectSrcX); + this.rec.writeShortBE(this.copyRectSrcY); + } + } + + String readServerCutText() throws IOException { + byte[] byArray = new byte[3]; + this.readFully(byArray); + int n = this.is.readInt(); + byte[] byArray2 = new byte[n]; + this.readFully(byArray2); + return new String(byArray2); + } + + int readCompactLen() throws IOException { + int[] nArray = new int[3]; + nArray[0] = this.is.readUnsignedByte(); + int n = 1; + int n2 = nArray[0] & 0x7F; + if ((nArray[0] & 0x80) != 0) { + nArray[1] = this.is.readUnsignedByte(); + ++n; + n2 |= (nArray[1] & 0x7F) << 7; + if ((nArray[1] & 0x80) != 0) { + nArray[2] = this.is.readUnsignedByte(); + ++n; + n2 |= (nArray[2] & 0xFF) << 14; + } + } + if (this.rec != null && this.recordFromBeginning) { + for (int i = 0; i < n; ++i) { + this.rec.writeByte(nArray[i]); + } + } + return n2; + } + + void writeFramebufferUpdateRequest(int n, int n2, int n3, int n4, boolean bl) throws IOException { + byte[] byArray = new byte[]{3, (byte)(bl ? 1 : 0), (byte)(n >> 8 & 0xFF), (byte)(n & 0xFF), (byte)(n2 >> 8 & 0xFF), (byte)(n2 & 0xFF), (byte)(n3 >> 8 & 0xFF), (byte)(n3 & 0xFF), (byte)(n4 >> 8 & 0xFF), (byte)(n4 & 0xFF)}; + this.os.write(byArray); + } + + void writeSetPixelFormat(int n, int n2, boolean bl, boolean bl2, int n3, int n4, int n5, int n6, int n7, int n8) throws IOException { + byte[] byArray = new byte[20]; + byArray[0] = 0; + byArray[4] = (byte)n; + byArray[5] = (byte)n2; + byArray[6] = (byte)(bl ? 1 : 0); + byArray[7] = (byte)(bl2 ? 1 : 0); + byArray[8] = (byte)(n3 >> 8 & 0xFF); + byArray[9] = (byte)(n3 & 0xFF); + byArray[10] = (byte)(n4 >> 8 & 0xFF); + byArray[11] = (byte)(n4 & 0xFF); + byArray[12] = (byte)(n5 >> 8 & 0xFF); + byArray[13] = (byte)(n5 & 0xFF); + byArray[14] = (byte)n6; + byArray[15] = (byte)n7; + byArray[16] = (byte)n8; + this.os.write(byArray); + } + + void writeFixColourMapEntries(int n, int n2, int[] nArray, int[] nArray2, int[] nArray3) throws IOException { + byte[] byArray = new byte[6 + n2 * 6]; + byArray[0] = 1; + byArray[2] = (byte)(n >> 8 & 0xFF); + byArray[3] = (byte)(n & 0xFF); + byArray[4] = (byte)(n2 >> 8 & 0xFF); + byArray[5] = (byte)(n2 & 0xFF); + for (int i = 0; i < n2; ++i) { + byArray[6 + i * 6] = (byte)(nArray[i] >> 8 & 0xFF); + byArray[6 + i * 6 + 1] = (byte)(nArray[i] & 0xFF); + byArray[6 + i * 6 + 2] = (byte)(nArray2[i] >> 8 & 0xFF); + byArray[6 + i * 6 + 3] = (byte)(nArray2[i] & 0xFF); + byArray[6 + i * 6 + 4] = (byte)(nArray3[i] >> 8 & 0xFF); + byArray[6 + i * 6 + 5] = (byte)(nArray3[i] & 0xFF); + } + this.os.write(byArray); + } + + void writeSetEncodings(int[] nArray, int n) throws IOException { + byte[] byArray = new byte[4 + 4 * n]; + byArray[0] = 2; + byArray[2] = (byte)(n >> 8 & 0xFF); + byArray[3] = (byte)(n & 0xFF); + for (int i = 0; i < n; ++i) { + byArray[4 + 4 * i] = (byte)(nArray[i] >> 24 & 0xFF); + byArray[5 + 4 * i] = (byte)(nArray[i] >> 16 & 0xFF); + byArray[6 + 4 * i] = (byte)(nArray[i] >> 8 & 0xFF); + byArray[7 + 4 * i] = (byte)(nArray[i] & 0xFF); + } + this.os.write(byArray); + } + + void writeClientCutText(String string) throws IOException { + byte[] byArray = new byte[8 + string.length()]; + byArray[0] = 6; + byArray[4] = (byte)(string.length() >> 24 & 0xFF); + byArray[5] = (byte)(string.length() >> 16 & 0xFF); + byArray[6] = (byte)(string.length() >> 8 & 0xFF); + byArray[7] = (byte)(string.length() & 0xFF); + System.arraycopy(string.getBytes(), 0, byArray, 8, string.length()); + this.os.write(byArray); + } + + void writePointerEvent(MouseEvent mouseEvent) throws IOException { + int n = mouseEvent.getModifiers(); + int n2 = 2; + int n3 = 4; + if (this.viewer.options.reverseMouseButtons2And3) { + n2 = 4; + n3 = 2; + } + if (mouseEvent.getID() == 501) { + if ((n & 8) != 0) { + this.pointerMask = n2; + n &= 0xFFFFFFF7; + } else if ((n & 4) != 0) { + this.pointerMask = n3; + n &= 0xFFFFFFFB; + } else { + this.pointerMask = 1; + } + } else if (mouseEvent.getID() == 502) { + this.pointerMask = 0; + if ((n & 8) != 0) { + n &= 0xFFFFFFF7; + } else if ((n & 4) != 0) { + n &= 0xFFFFFFFB; + } + } + this.eventBufLen = 0; + this.writeModifierKeyEvents(n); + int n4 = mouseEvent.getX(); + int n5 = mouseEvent.getY(); + if (n4 < 0) { + n4 = 0; + } + if (n5 < 0) { + n5 = 0; + } + this.eventBuf[this.eventBufLen++] = 5; + this.eventBuf[this.eventBufLen++] = (byte)this.pointerMask; + this.eventBuf[this.eventBufLen++] = (byte)(n4 >> 8 & 0xFF); + this.eventBuf[this.eventBufLen++] = (byte)(n4 & 0xFF); + this.eventBuf[this.eventBufLen++] = (byte)(n5 >> 8 & 0xFF); + this.eventBuf[this.eventBufLen++] = (byte)(n5 & 0xFF); + if (this.pointerMask == 0) { + this.writeModifierKeyEvents(0); + } + this.os.write(this.eventBuf, 0, this.eventBufLen); + } + + void writeKeyEvent(KeyEvent keyEvent) throws IOException { + int n; + boolean bl; + block44: { + int n2; + block43: { + n2 = keyEvent.getKeyChar(); + if (n2 == 0) { + n2 = 65535; + } + if (n2 == 65535 && ((bl = keyEvent.getKeyCode()) || bl || bl || bl)) { + return; + } + boolean bl2 = bl = keyEvent.getID() == 401; + if (!keyEvent.isActionKey()) break block43; + switch (keyEvent.getKeyCode()) { + case 36: { + n = 65360; + break block44; + } + case 37: { + n = 65361; + break block44; + } + case 38: { + n = 65362; + break block44; + } + case 39: { + n = 65363; + break block44; + } + case 40: { + n = 65364; + break block44; + } + case 33: { + n = 65365; + break block44; + } + case 34: { + n = 65366; + break block44; + } + case 35: { + n = 65367; + break block44; + } + case 155: { + n = 65379; + break block44; + } + case 112: { + n = 65470; + break block44; + } + case 113: { + n = 65471; + break block44; + } + case 114: { + n = 65472; + break block44; + } + case 115: { + n = 65473; + break block44; + } + case 116: { + n = 65474; + break block44; + } + case 117: { + n = 65475; + break block44; + } + case 118: { + n = 65476; + break block44; + } + case 119: { + n = 65477; + break block44; + } + case 120: { + n = 65478; + break block44; + } + case 121: { + n = 65479; + break block44; + } + case 122: { + n = 65480; + break block44; + } + case 123: { + n = 65481; + break block44; + } + default: { + return; + } + } + } + n = n2; + if (n < 32) { + if (keyEvent.isControlDown()) { + n += 96; + } else { + switch (n) { + case 8: { + n = 65288; + break; + } + case 9: { + n = 65289; + break; + } + case 10: { + n = 65293; + break; + } + case 27: { + n = 65307; + } + } + } + } else if (n == 127) { + n = 65535; + } else if (!(n <= 255 || n >= 65280 && n <= 65535 || n >= 8352 && n <= 8367)) { + return; + } + } + if (n == 229 || n == 197 || n == 228 || n == 196 || n == 246 || n == 214 || n == 167 || n == 189 || n == 163) { + if (bl) { + this.brokenKeyPressed = true; + } + if (!bl && !this.brokenKeyPressed) { + this.eventBufLen = 0; + this.writeModifierKeyEvents(keyEvent.getModifiers()); + this.writeKeyEvent(n, true); + this.os.write(this.eventBuf, 0, this.eventBufLen); + } + if (!bl) { + this.brokenKeyPressed = false; + } + } + this.eventBufLen = 0; + this.writeModifierKeyEvents(keyEvent.getModifiers()); + this.writeKeyEvent(n, bl); + if (!bl) { + this.writeModifierKeyEvents(0); + } + this.os.write(this.eventBuf, 0, this.eventBufLen); + } + + void writeKeyEvent(int n, boolean bl) { + this.eventBuf[this.eventBufLen++] = 4; + this.eventBuf[this.eventBufLen++] = (byte)(bl ? 1 : 0); + this.eventBuf[this.eventBufLen++] = 0; + this.eventBuf[this.eventBufLen++] = 0; + this.eventBuf[this.eventBufLen++] = (byte)(n >> 24 & 0xFF); + this.eventBuf[this.eventBufLen++] = (byte)(n >> 16 & 0xFF); + this.eventBuf[this.eventBufLen++] = (byte)(n >> 8 & 0xFF); + this.eventBuf[this.eventBufLen++] = (byte)(n & 0xFF); + } + + void writeModifierKeyEvents(int n) { + if ((n & 2) != (this.oldModifiers & 2)) { + this.writeKeyEvent(65507, (n & 2) != 0); + } + if ((n & 1) != (this.oldModifiers & 1)) { + this.writeKeyEvent(65505, (n & 1) != 0); + } + if ((n & 4) != (this.oldModifiers & 4)) { + this.writeKeyEvent(65511, (n & 4) != 0); + } + if ((n & 8) != (this.oldModifiers & 8)) { + this.writeKeyEvent(65513, (n & 8) != 0); + } + this.oldModifiers = n; + } + + void recordCompressedData(byte[] byArray, int n, int n2) throws IOException { + Deflater deflater = new Deflater(); + deflater.setInput(byArray, n, n2); + int n3 = n2 + n2 / 100 + 12; + byte[] byArray2 = new byte[n3]; + deflater.finish(); + int n4 = deflater.deflate(byArray2); + this.recordCompactLen(n4); + this.rec.write(byArray2, 0, n4); + } + + void recordCompressedData(byte[] byArray) throws IOException { + this.recordCompressedData(byArray, 0, byArray.length); + } + + void recordCompactLen(int n) throws IOException { + byte[] byArray = new byte[3]; + int n2 = 0; + byArray[n2++] = (byte)(n & 0x7F); + if (n > 127) { + int n3 = n2 - 1; + byArray[n3] = (byte)(byArray[n3] | 0x80); + byArray[n2++] = (byte)(n >> 7 & 0x7F); + if (n > 16383) { + int n4 = n2 - 1; + byArray[n4] = (byte)(byArray[n4] | 0x80); + byArray[n2++] = (byte)(n >> 14 & 0xFF); + } + } + this.rec.write(byArray, 0, n2); + } + + public void startTiming() { + this.timing = true; + if (this.timeWaitedIn100us > 10000L) { + this.timedKbits = this.timedKbits * 10000L / this.timeWaitedIn100us; + this.timeWaitedIn100us = 10000L; + } + } + + public void stopTiming() { + this.timing = false; + if (this.timeWaitedIn100us < this.timedKbits / 2L) { + this.timeWaitedIn100us = this.timedKbits / 2L; + } + } + + public long kbitsPerSecond() { + return this.timedKbits * 10000L / this.timeWaitedIn100us; + } + + public long timeWaited() { + return this.timeWaitedIn100us; + } + + public void readFully(byte[] byArray) throws IOException { + this.readFully(byArray, 0, byArray.length); + } + + public void readFully(byte[] byArray, int n, int n2) throws IOException { + long l = 0L; + if (this.timing) { + l = System.currentTimeMillis(); + } + this.is.readFully(byArray, n, n2); + if (this.timing) { + int n3; + long l2 = System.currentTimeMillis(); + long l3 = (l2 - l) * 10L; + if (l3 > (long)((n3 = n2 * 8 / 1000) * 1000)) { + l3 = n3 * 1000; + } + if (l3 < (long)(n3 / 4)) { + l3 = n3 / 4; + } + this.timeWaitedIn100us += l3; + this.timedKbits += (long)n3; + } + } +} + diff --git a/src/SessionRecorder.java b/src/SessionRecorder.java new file mode 100644 index 0000000..a638658 --- /dev/null +++ b/src/SessionRecorder.java @@ -0,0 +1,126 @@ +/* + * Decompiled with CFR 0.152. + */ +import java.io.DataOutputStream; +import java.io.FileOutputStream; +import java.io.IOException; + +class SessionRecorder { + protected FileOutputStream f; + protected DataOutputStream df; + protected long startTime; + protected long lastTimeOffset; + protected byte[] buffer; + protected int bufferSize; + protected int bufferBytes; + + public SessionRecorder(String string, int n) throws IOException { + this.f = new FileOutputStream(string); + this.df = new DataOutputStream(this.f); + this.startTime = System.currentTimeMillis(); + this.lastTimeOffset = 0L; + this.bufferSize = n; + this.bufferBytes = 0; + this.buffer = new byte[this.bufferSize]; + } + + public SessionRecorder(String string) throws IOException { + this(string, 65536); + } + + public void close() throws IOException { + try { + this.flush(); + } + catch (IOException iOException) { + // empty catch block + } + this.df = null; + this.f.close(); + this.f = null; + this.buffer = null; + } + + public void writeHeader() throws IOException { + this.df.write("FBS 001.000\n".getBytes()); + } + + public void writeByte(int n) throws IOException { + this.prepareWriting(); + this.buffer[this.bufferBytes++] = (byte)n; + } + + public void writeShortBE(int n) throws IOException { + this.prepareWriting(); + this.buffer[this.bufferBytes++] = (byte)(n >> 8); + this.buffer[this.bufferBytes++] = (byte)n; + } + + public void writeIntBE(int n) throws IOException { + this.prepareWriting(); + this.buffer[this.bufferBytes] = (byte)(n >> 24); + this.buffer[this.bufferBytes + 1] = (byte)(n >> 16); + this.buffer[this.bufferBytes + 2] = (byte)(n >> 8); + this.buffer[this.bufferBytes + 3] = (byte)n; + this.bufferBytes += 4; + } + + public void writeShortLE(int n) throws IOException { + this.prepareWriting(); + this.buffer[this.bufferBytes++] = (byte)n; + this.buffer[this.bufferBytes++] = (byte)(n >> 8); + } + + public void writeIntLE(int n) throws IOException { + this.prepareWriting(); + this.buffer[this.bufferBytes] = (byte)n; + this.buffer[this.bufferBytes + 1] = (byte)(n >> 8); + this.buffer[this.bufferBytes + 2] = (byte)(n >> 16); + this.buffer[this.bufferBytes + 3] = (byte)(n >> 24); + this.bufferBytes += 4; + } + + public void write(byte[] byArray, int n, int n2) throws IOException { + this.prepareWriting(); + while (n2 > 0) { + if (this.bufferBytes > this.bufferSize - 4) { + this.flush(false); + } + int n3 = this.bufferBytes + n2 > this.bufferSize ? this.bufferSize - this.bufferBytes : n2; + System.arraycopy(byArray, n, this.buffer, this.bufferBytes, n3); + this.bufferBytes += n3; + n += n3; + n2 -= n3; + } + } + + public void write(byte[] byArray) throws IOException { + this.write(byArray, 0, byArray.length); + } + + public void flush(boolean bl) throws IOException { + if (this.bufferBytes > 0) { + this.df.writeInt(this.bufferBytes); + this.df.write(this.buffer, 0, this.bufferBytes + 3 & 0x7FFFFFFC); + this.df.writeInt((int)this.lastTimeOffset); + this.bufferBytes = 0; + if (bl) { + this.lastTimeOffset = -1L; + } + } + } + + public void flush() throws IOException { + this.flush(true); + } + + protected void prepareWriting() throws IOException { + if (this.lastTimeOffset == -1L) { + this.lastTimeOffset = System.currentTimeMillis() - this.startTime; + } + if (this.bufferBytes > this.bufferSize - 4) { + this.flush(false); + } + } +} + diff --git a/src/SocketFactory.java b/src/SocketFactory.java new file mode 100644 index 0000000..81cddba --- /dev/null +++ b/src/SocketFactory.java @@ -0,0 +1,13 @@ +/* + * Decompiled with CFR 0.152. + */ +import java.applet.Applet; +import java.io.IOException; +import java.net.Socket; + +public interface SocketFactory { + public Socket createSocket(String var1, int var2, Applet var3) throws IOException; + + public Socket createSocket(String var1, int var2, String[] var3) throws IOException; +} + diff --git a/src/VncCanvas.java b/src/VncCanvas.java new file mode 100644 index 0000000..71241dd --- /dev/null +++ b/src/VncCanvas.java @@ -0,0 +1,1352 @@ +/* + * Decompiled with CFR 0.152. + */ +import java.awt.Canvas; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.Insets; +import java.awt.Rectangle; +import java.awt.Toolkit; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionListener; +import java.awt.image.ColorModel; +import java.awt.image.DirectColorModel; +import java.awt.image.MemoryImageSource; +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; +import java.io.IOException; +import java.util.zip.Inflater; + +class VncCanvas +extends Canvas +implements KeyListener, +MouseListener, +MouseMotionListener { + VncViewer viewer; + RfbProto rfb; + ColorModel cm8; + ColorModel cm24; + Color[] colors; + int bytesPixel; + int maxWidth = 0; + int maxHeight = 0; + int scalingFactor; + int scaledWidth; + int scaledHeight; + Image memImage; + Graphics memGraphics; + Image rawPixelsImage; + MemoryImageSource pixelsSource; + byte[] pixels8; + int[] pixels24; + byte[] zrleBuf; + int zrleBufLen = 0; + byte[] zrleTilePixels8; + int[] zrleTilePixels24; + ZlibInStream zrleInStream; + boolean zrleRecWarningShown = false; + byte[] zlibBuf; + int zlibBufLen = 0; + Inflater zlibInflater; + static final int tightZlibBufferSize = 512; + Inflater[] tightInflaters; + Rectangle jpegRect; + boolean inputEnabled; + private Color hextile_bg; + private Color hextile_fg; + boolean showSoftCursor = false; + MemoryImageSource softCursorSource; + Image softCursor; + int cursorX = 0; + int cursorY = 0; + int cursorWidth; + int cursorHeight; + int origCursorWidth; + int origCursorHeight; + int hotX; + int hotY; + int origHotX; + int origHotY; + + public VncCanvas(VncViewer vncViewer, int n, int n2) throws IOException { + this.viewer = vncViewer; + this.maxWidth = n; + this.maxHeight = n2; + this.rfb = this.viewer.rfb; + this.scalingFactor = this.viewer.options.scalingFactor; + this.tightInflaters = new Inflater[4]; + this.cm8 = new DirectColorModel(8, 7, 56, 192); + this.cm24 = new DirectColorModel(24, 0xFF0000, 65280, 255); + this.colors = new Color[256]; + for (int i = 0; i < 256; ++i) { + this.colors[i] = new Color(this.cm8.getRGB(i)); + } + this.setPixelFormat(); + this.inputEnabled = false; + if (!this.viewer.options.viewOnly) { + this.enableInput(true); + } + this.addKeyListener(this); + } + + public VncCanvas(VncViewer vncViewer) throws IOException { + this(vncViewer, 0, 0); + } + + public Dimension getPreferredSize() { + return new Dimension(this.scaledWidth, this.scaledHeight); + } + + public Dimension getMinimumSize() { + return new Dimension(this.scaledWidth, this.scaledHeight); + } + + public Dimension getMaximumSize() { + return new Dimension(this.scaledWidth, this.scaledHeight); + } + + public void update(Graphics graphics) { + this.paint(graphics); + } + + /* + * WARNING - Removed try catching itself - possible behaviour change. + */ + public void paint(Graphics graphics) { + int n; + int n2; + Rectangle rectangle; + Image image = this.memImage; + synchronized (image) { + if (this.rfb.framebufferWidth == this.scaledWidth) { + graphics.drawImage(this.memImage, 0, 0, null); + } else { + this.paintScaledFrameBuffer(graphics); + } + } + if (this.showSoftCursor && (rectangle = new Rectangle(n2 = this.cursorX - this.hotX, n = this.cursorY - this.hotY, this.cursorWidth, this.cursorHeight)).intersects(graphics.getClipBounds())) { + graphics.drawImage(this.softCursor, n2, n, null); + } + } + + public void paintScaledFrameBuffer(Graphics graphics) { + graphics.drawImage(this.memImage, 0, 0, this.scaledWidth, this.scaledHeight, null); + } + + /* + * WARNING - Removed try catching itself - possible behaviour change. + */ + public boolean imageUpdate(Image image, int n, int n2, int n3, int n4, int n5) { + if ((n & 0xA0) == 0) { + return true; + } + if ((n & 0x20) != 0 && this.jpegRect != null) { + Rectangle rectangle = this.jpegRect; + synchronized (rectangle) { + this.memGraphics.drawImage(image, this.jpegRect.x, this.jpegRect.y, null); + this.scheduleRepaint(this.jpegRect.x, this.jpegRect.y, this.jpegRect.width, this.jpegRect.height); + this.jpegRect.notify(); + } + } + return false; + } + + public synchronized void enableInput(boolean bl) { + if (bl && !this.inputEnabled) { + this.inputEnabled = true; + this.addMouseListener(this); + this.addMouseMotionListener(this); + if (this.viewer.showControls) { + this.viewer.buttonPanel.enableRemoteAccessControls(true); + } + this.createSoftCursor(); + } else if (!bl && this.inputEnabled) { + this.inputEnabled = false; + this.removeMouseListener(this); + this.removeMouseMotionListener(this); + if (this.viewer.showControls) { + this.viewer.buttonPanel.enableRemoteAccessControls(false); + } + this.createSoftCursor(); + } + } + + public void setPixelFormat() throws IOException { + if (this.viewer.options.eightBitColors) { + this.rfb.writeSetPixelFormat(8, 8, false, true, 7, 7, 3, 0, 3, 6); + this.bytesPixel = 1; + } else { + this.rfb.writeSetPixelFormat(32, 24, false, true, 255, 255, 255, 16, 8, 0); + this.bytesPixel = 4; + } + this.updateFramebufferSize(); + } + + /* + * WARNING - Removed try catching itself - possible behaviour change. + */ + void updateFramebufferSize() { + int n = this.rfb.framebufferWidth; + int n2 = this.rfb.framebufferHeight; + if (this.maxWidth > 0 && this.maxHeight > 0) { + int n3 = this.maxWidth * 100 / n; + int n4 = this.maxHeight * 100 / n2; + this.scalingFactor = Math.min(n3, n4); + if (this.scalingFactor > 100) { + this.scalingFactor = 100; + } + System.out.println("Scaling desktop at " + this.scalingFactor + "%"); + } + this.scaledWidth = (n * this.scalingFactor + 50) / 100; + this.scaledHeight = (n2 * this.scalingFactor + 50) / 100; + if (this.memImage == null) { + this.memImage = this.viewer.vncContainer.createImage(n, n2); + this.memGraphics = this.memImage.getGraphics(); + } else if (this.memImage.getWidth(null) != n || this.memImage.getHeight(null) != n2) { + Image image = this.memImage; + synchronized (image) { + this.memImage = this.viewer.vncContainer.createImage(n, n2); + this.memGraphics = this.memImage.getGraphics(); + } + } + if (this.bytesPixel == 1) { + this.pixels24 = null; + this.pixels8 = new byte[n * n2]; + this.pixelsSource = new MemoryImageSource(n, n2, this.cm8, this.pixels8, 0, n); + this.zrleTilePixels24 = null; + this.zrleTilePixels8 = new byte[4096]; + } else { + this.pixels8 = null; + this.pixels24 = new int[n * n2]; + this.pixelsSource = new MemoryImageSource(n, n2, this.cm24, this.pixels24, 0, n); + this.zrleTilePixels8 = null; + this.zrleTilePixels24 = new int[4096]; + } + this.pixelsSource.setAnimated(true); + this.rawPixelsImage = Toolkit.getDefaultToolkit().createImage(this.pixelsSource); + if (this.viewer.inSeparateFrame) { + if (this.viewer.desktopScrollPane != null) { + this.resizeDesktopFrame(); + } + } else { + this.setSize(this.scaledWidth, this.scaledHeight); + } + this.viewer.moveFocusToDesktop(); + } + + void resizeDesktopFrame() { + Dimension dimension; + this.setSize(this.scaledWidth, this.scaledHeight); + Insets insets = this.viewer.desktopScrollPane.getInsets(); + this.viewer.desktopScrollPane.setSize(this.scaledWidth + 2 * Math.min(insets.left, insets.right), this.scaledHeight + 2 * Math.min(insets.top, insets.bottom)); + this.viewer.vncFrame.pack(); + Dimension dimension2 = this.viewer.vncFrame.getToolkit().getScreenSize(); + Dimension dimension3 = dimension = this.viewer.vncFrame.getSize(); + dimension2.height -= 30; + dimension2.width -= 30; + boolean bl = false; + if (dimension.height > dimension2.height) { + dimension3.height = dimension2.height; + bl = true; + } + if (dimension.width > dimension2.width) { + dimension3.width = dimension2.width; + bl = true; + } + if (bl) { + ((Component)this.viewer.vncFrame).setSize(dimension3); + } + this.viewer.desktopScrollPane.doLayout(); + } + + /* + * WARNING - Removed try catching itself - possible behaviour change. + * Unable to fully structure code + */ + public void processNormalProtocol() throws Exception { + this.viewer.checkRecordingStatus(); + this.rfb.writeFramebufferUpdateRequest(0, 0, this.rfb.framebufferWidth, this.rfb.framebufferHeight, false); + block21: while (true) { + var1_1 = this.rfb.readServerMessageType(); + switch (var1_1) { + case 0: { + this.rfb.readFramebufferUpdate(); + var2_2 = false; + for (var3_3 = 0; var3_3 < this.rfb.updateNRects; ++var3_3) { + this.rfb.readFramebufferUpdateRectHdr(); + var4_4 = this.rfb.updateRectX; + var5_7 = this.rfb.updateRectY; + var6_9 = this.rfb.updateRectW; + var7_10 = this.rfb.updateRectH; + if (this.rfb.updateRectEncoding == -224) break; + if (this.rfb.updateRectEncoding == -223) { + this.rfb.setFramebufferSize(var6_9, var7_10); + this.updateFramebufferSize(); + break; + } + if (this.rfb.updateRectEncoding == -240) ** GOTO lbl26 + if (this.rfb.updateRectEncoding != -239) ** GOTO lbl28 +lbl26: + // 2 sources + + this.handleCursorShapeUpdate(this.rfb.updateRectEncoding, var4_4, var5_7, var6_9, var7_10); + continue; +lbl28: + // 1 sources + + if (this.rfb.updateRectEncoding == -232) { + this.softCursorMove(var4_4, var5_7); + var2_2 = true; + continue; + } + this.rfb.startTiming(); + switch (this.rfb.updateRectEncoding) { + case 0: { + this.handleRawRect(var4_4, var5_7, var6_9, var7_10); + break; + } + case 1: { + this.handleCopyRect(var4_4, var5_7, var6_9, var7_10); + break; + } + case 2: { + this.handleRRERect(var4_4, var5_7, var6_9, var7_10); + break; + } + case 4: { + this.handleCoRRERect(var4_4, var5_7, var6_9, var7_10); + break; + } + case 5: { + this.handleHextileRect(var4_4, var5_7, var6_9, var7_10); + break; + } + case 16: { + this.handleZRLERect(var4_4, var5_7, var6_9, var7_10); + break; + } + case 6: { + this.handleZlibRect(var4_4, var5_7, var6_9, var7_10); + break; + } + case 7: { + this.handleTightRect(var4_4, var5_7, var6_9, var7_10); + break; + } + default: { + throw new Exception("Unknown RFB rectangle encoding " + this.rfb.updateRectEncoding); + } + } + this.rfb.stopTiming(); + } + var3_3 = 0; + if (this.viewer.checkRecordingStatus()) { + var3_3 = 1; + } + if (this.viewer.deferUpdateRequests > 0 && this.rfb.is.available() == 0 && !var2_2) { + var4_5 = this.rfb; + synchronized (var4_5) { + try { + this.rfb.wait(this.viewer.deferUpdateRequests); + } + catch (InterruptedException var5_8) { + // empty catch block + } + } + } + if (this.viewer.options.eightBitColors != (this.bytesPixel == 1)) { + this.setPixelFormat(); + var3_3 = 1; + } + this.viewer.autoSelectEncodings(); + this.rfb.writeFramebufferUpdateRequest(0, 0, this.rfb.framebufferWidth, this.rfb.framebufferHeight, var3_3 == 0); + continue block21; + } + case 1: { + throw new Exception("Can't handle SetColourMapEntries message"); + } + case 2: { + Toolkit.getDefaultToolkit().beep(); + continue block21; + } + case 3: { + var4_6 = this.rfb.readServerCutText(); + this.viewer.clipboard.setCutText(var4_6); + continue block21; + } + } + break; + } + throw new Exception("Unknown RFB message type " + var1_1); + } + + void handleRawRect(int n, int n2, int n3, int n4) throws IOException { + this.handleRawRect(n, n2, n3, n4, true); + } + + void handleRawRect(int n, int n2, int n3, int n4, boolean bl) throws IOException { + if (this.bytesPixel == 1) { + for (int i = n2; i < n2 + n4; ++i) { + this.rfb.readFully(this.pixels8, i * this.rfb.framebufferWidth + n, n3); + if (this.rfb.rec == null) continue; + this.rfb.rec.write(this.pixels8, i * this.rfb.framebufferWidth + n, n3); + } + } else { + byte[] byArray = new byte[n3 * 4]; + for (int i = n2; i < n2 + n4; ++i) { + this.rfb.readFully(byArray); + if (this.rfb.rec != null) { + this.rfb.rec.write(byArray); + } + int n5 = i * this.rfb.framebufferWidth + n; + for (int j = 0; j < n3; ++j) { + this.pixels24[n5 + j] = (byArray[j * 4 + 2] & 0xFF) << 16 | (byArray[j * 4 + 1] & 0xFF) << 8 | byArray[j * 4] & 0xFF; + } + } + } + this.handleUpdatedPixels(n, n2, n3, n4); + if (bl) { + this.scheduleRepaint(n, n2, n3, n4); + } + } + + void handleCopyRect(int n, int n2, int n3, int n4) throws IOException { + this.rfb.readCopyRect(); + this.memGraphics.copyArea(this.rfb.copyRectSrcX, this.rfb.copyRectSrcY, n3, n4, n - this.rfb.copyRectSrcX, n2 - this.rfb.copyRectSrcY); + this.scheduleRepaint(n, n2, n3, n4); + } + + void handleRRERect(int n, int n2, int n3, int n4) throws IOException { + int n5 = this.rfb.is.readInt(); + byte[] byArray = new byte[this.bytesPixel]; + this.rfb.readFully(byArray); + Color color = this.bytesPixel == 1 ? this.colors[byArray[0] & 0xFF] : new Color(byArray[2] & 0xFF, byArray[1] & 0xFF, byArray[0] & 0xFF); + this.memGraphics.setColor(color); + this.memGraphics.fillRect(n, n2, n3, n4); + byte[] byArray2 = new byte[n5 * (this.bytesPixel + 8)]; + this.rfb.readFully(byArray2); + DataInputStream dataInputStream = new DataInputStream(new ByteArrayInputStream(byArray2)); + if (this.rfb.rec != null) { + this.rfb.rec.writeIntBE(n5); + this.rfb.rec.write(byArray); + this.rfb.rec.write(byArray2); + } + for (int i = 0; i < n5; ++i) { + if (this.bytesPixel == 1) { + color = this.colors[dataInputStream.readUnsignedByte()]; + } else { + dataInputStream.skip(4L); + color = new Color(byArray2[i * 12 + 2] & 0xFF, byArray2[i * 12 + 1] & 0xFF, byArray2[i * 12] & 0xFF); + } + int n6 = n + dataInputStream.readUnsignedShort(); + int n7 = n2 + dataInputStream.readUnsignedShort(); + int n8 = dataInputStream.readUnsignedShort(); + int n9 = dataInputStream.readUnsignedShort(); + this.memGraphics.setColor(color); + this.memGraphics.fillRect(n6, n7, n8, n9); + } + this.scheduleRepaint(n, n2, n3, n4); + } + + void handleCoRRERect(int n, int n2, int n3, int n4) throws IOException { + int n5 = this.rfb.is.readInt(); + byte[] byArray = new byte[this.bytesPixel]; + this.rfb.readFully(byArray); + Color color = this.bytesPixel == 1 ? this.colors[byArray[0] & 0xFF] : new Color(byArray[2] & 0xFF, byArray[1] & 0xFF, byArray[0] & 0xFF); + this.memGraphics.setColor(color); + this.memGraphics.fillRect(n, n2, n3, n4); + byte[] byArray2 = new byte[n5 * (this.bytesPixel + 4)]; + this.rfb.readFully(byArray2); + if (this.rfb.rec != null) { + this.rfb.rec.writeIntBE(n5); + this.rfb.rec.write(byArray); + this.rfb.rec.write(byArray2); + } + int n6 = 0; + for (int i = 0; i < n5; ++i) { + if (this.bytesPixel == 1) { + color = this.colors[byArray2[n6++] & 0xFF]; + } else { + color = new Color(byArray2[n6 + 2] & 0xFF, byArray2[n6 + 1] & 0xFF, byArray2[n6] & 0xFF); + n6 += 4; + } + int n7 = n + (byArray2[n6++] & 0xFF); + int n8 = n2 + (byArray2[n6++] & 0xFF); + int n9 = byArray2[n6++] & 0xFF; + int n10 = byArray2[n6++] & 0xFF; + this.memGraphics.setColor(color); + this.memGraphics.fillRect(n7, n8, n9, n10); + } + this.scheduleRepaint(n, n2, n3, n4); + } + + void handleHextileRect(int n, int n2, int n3, int n4) throws IOException { + this.hextile_bg = new Color(0); + this.hextile_fg = new Color(0); + for (int i = n2; i < n2 + n4; i += 16) { + int n5 = 16; + if (n2 + n4 - i < 16) { + n5 = n2 + n4 - i; + } + for (int j = n; j < n + n3; j += 16) { + int n6 = 16; + if (n + n3 - j < 16) { + n6 = n + n3 - j; + } + this.handleHextileSubrect(j, i, n6, n5); + } + this.scheduleRepaint(n, n2, n3, n4); + } + } + + void handleHextileSubrect(int n, int n2, int n3, int n4) throws IOException { + int n5 = this.rfb.is.readUnsignedByte(); + if (this.rfb.rec != null) { + this.rfb.rec.writeByte(n5); + } + if ((n5 & 1) != 0) { + this.handleRawRect(n, n2, n3, n4, false); + return; + } + byte[] byArray = new byte[this.bytesPixel]; + if ((n5 & 2) != 0) { + this.rfb.readFully(byArray); + this.hextile_bg = this.bytesPixel == 1 ? this.colors[byArray[0] & 0xFF] : new Color(byArray[2] & 0xFF, byArray[1] & 0xFF, byArray[0] & 0xFF); + if (this.rfb.rec != null) { + this.rfb.rec.write(byArray); + } + } + this.memGraphics.setColor(this.hextile_bg); + this.memGraphics.fillRect(n, n2, n3, n4); + if ((n5 & 4) != 0) { + this.rfb.readFully(byArray); + this.hextile_fg = this.bytesPixel == 1 ? this.colors[byArray[0] & 0xFF] : new Color(byArray[2] & 0xFF, byArray[1] & 0xFF, byArray[0] & 0xFF); + if (this.rfb.rec != null) { + this.rfb.rec.write(byArray); + } + } + if ((n5 & 8) == 0) { + return; + } + int n6 = this.rfb.is.readUnsignedByte(); + int n7 = n6 * 2; + if ((n5 & 0x10) != 0) { + n7 += n6 * this.bytesPixel; + } + byte[] byArray2 = new byte[n7]; + this.rfb.readFully(byArray2); + if (this.rfb.rec != null) { + this.rfb.rec.writeByte(n6); + this.rfb.rec.write(byArray2); + } + int n8 = 0; + if ((n5 & 0x10) == 0) { + this.memGraphics.setColor(this.hextile_fg); + for (int i = 0; i < n6; ++i) { + int n9 = byArray2[n8++] & 0xFF; + int n10 = byArray2[n8++] & 0xFF; + int n11 = n + (n9 >> 4); + int n12 = n2 + (n9 & 0xF); + int n13 = (n10 >> 4) + 1; + int n14 = (n10 & 0xF) + 1; + this.memGraphics.fillRect(n11, n12, n13, n14); + } + } else if (this.bytesPixel == 1) { + for (int i = 0; i < n6; ++i) { + this.hextile_fg = this.colors[byArray2[n8++] & 0xFF]; + int n15 = byArray2[n8++] & 0xFF; + int n16 = byArray2[n8++] & 0xFF; + int n17 = n + (n15 >> 4); + int n18 = n2 + (n15 & 0xF); + int n19 = (n16 >> 4) + 1; + int n20 = (n16 & 0xF) + 1; + this.memGraphics.setColor(this.hextile_fg); + this.memGraphics.fillRect(n17, n18, n19, n20); + } + } else { + for (int i = 0; i < n6; ++i) { + this.hextile_fg = new Color(byArray2[n8 + 2] & 0xFF, byArray2[n8 + 1] & 0xFF, byArray2[n8] & 0xFF); + n8 += 4; + int n21 = byArray2[n8++] & 0xFF; + int n22 = byArray2[n8++] & 0xFF; + int n23 = n + (n21 >> 4); + int n24 = n2 + (n21 & 0xF); + int n25 = (n22 >> 4) + 1; + int n26 = (n22 & 0xF) + 1; + this.memGraphics.setColor(this.hextile_fg); + this.memGraphics.fillRect(n23, n24, n25, n26); + } + } + } + + void handleZRLERect(int n, int n2, int n3, int n4) throws Exception { + int n5; + if (this.zrleInStream == null) { + this.zrleInStream = new ZlibInStream(); + } + if ((n5 = this.rfb.is.readInt()) > 0x4000000) { + throw new Exception("ZRLE decoder: illegal compressed data size"); + } + if (this.zrleBuf == null || this.zrleBufLen < n5) { + this.zrleBufLen = n5 + 4096; + this.zrleBuf = new byte[this.zrleBufLen]; + } + this.rfb.readFully(this.zrleBuf, 0, n5); + if (this.rfb.rec != null) { + if (this.rfb.recordFromBeginning) { + this.rfb.rec.writeIntBE(n5); + this.rfb.rec.write(this.zrleBuf, 0, n5); + } else if (!this.zrleRecWarningShown) { + System.out.println("Warning: ZRLE session can be recorded only from the beginning"); + System.out.println("Warning: Recorded file may be corrupted"); + this.zrleRecWarningShown = true; + } + } + this.zrleInStream.setUnderlying(new MemInStream(this.zrleBuf, 0, n5), n5); + for (int i = n2; i < n2 + n4; i += 64) { + int n6 = Math.min(n2 + n4 - i, 64); + for (int j = n; j < n + n3; j += 64) { + int n7 = Math.min(n + n3 - j, 64); + int n8 = this.zrleInStream.readU8(); + boolean bl = (n8 & 0x80) != 0; + int n9 = n8 & 0x7F; + int[] nArray = new int[128]; + this.readZrlePalette(nArray, n9); + if (n9 == 1) { + int n10 = nArray[0]; + Color color = this.bytesPixel == 1 ? this.colors[n10] : new Color(0xFF000000 | n10); + this.memGraphics.setColor(color); + this.memGraphics.fillRect(j, i, n7, n6); + continue; + } + if (!bl) { + if (n9 == 0) { + this.readZrleRawPixels(n7, n6); + } else { + this.readZrlePackedPixels(n7, n6, nArray, n9); + } + } else if (n9 == 0) { + this.readZrlePlainRLEPixels(n7, n6); + } else { + this.readZrlePackedRLEPixels(n7, n6, nArray); + } + this.handleUpdatedZrleTile(j, i, n7, n6); + } + } + this.zrleInStream.reset(); + this.scheduleRepaint(n, n2, n3, n4); + } + + int readPixel(InStream inStream) throws Exception { + int n; + if (this.bytesPixel == 1) { + n = inStream.readU8(); + } else { + int n2 = inStream.readU8(); + int n3 = inStream.readU8(); + int n4 = inStream.readU8(); + n = (n4 & 0xFF) << 16 | (n3 & 0xFF) << 8 | n2 & 0xFF; + } + return n; + } + + void readPixels(InStream inStream, int[] nArray, int n) throws Exception { + if (this.bytesPixel == 1) { + byte[] byArray = new byte[n]; + inStream.readBytes(byArray, 0, n); + for (int i = 0; i < n; ++i) { + nArray[i] = byArray[i] & 0xFF; + } + } else { + byte[] byArray = new byte[n * 3]; + inStream.readBytes(byArray, 0, n * 3); + for (int i = 0; i < n; ++i) { + nArray[i] = (byArray[i * 3 + 2] & 0xFF) << 16 | (byArray[i * 3 + 1] & 0xFF) << 8 | byArray[i * 3] & 0xFF; + } + } + } + + void readZrlePalette(int[] nArray, int n) throws Exception { + this.readPixels(this.zrleInStream, nArray, n); + } + + void readZrleRawPixels(int n, int n2) throws Exception { + if (this.bytesPixel == 1) { + this.zrleInStream.readBytes(this.zrleTilePixels8, 0, n * n2); + } else { + this.readPixels(this.zrleInStream, this.zrleTilePixels24, n * n2); + } + } + + void readZrlePackedPixels(int n, int n2, int[] nArray, int n3) throws Exception { + int n4 = n3 > 16 ? 8 : (n3 > 4 ? 4 : (n3 > 2 ? 2 : 1)); + int n5 = 0; + for (int i = 0; i < n2; ++i) { + int n6 = n5 + n; + int n7 = 0; + int n8 = 0; + while (n5 < n6) { + if (n8 == 0) { + n7 = this.zrleInStream.readU8(); + n8 = 8; + } + int n9 = n7 >> (n8 -= n4) & (1 << n4) - 1 & 0x7F; + if (this.bytesPixel == 1) { + this.zrleTilePixels8[n5++] = (byte)nArray[n9]; + continue; + } + this.zrleTilePixels24[n5++] = nArray[n9]; + } + } + } + + void readZrlePlainRLEPixels(int n, int n2) throws Exception { + int n3 = 0; + int n4 = n3 + n * n2; + while (n3 < n4) { + int n5; + int n6 = this.readPixel(this.zrleInStream); + int n7 = 1; + do { + n5 = this.zrleInStream.readU8(); + n7 += n5; + } while (n5 == 255); + if (n7 > n4 - n3) { + throw new Exception("ZRLE decoder: assertion failed (len <= end-ptr)"); + } + if (this.bytesPixel == 1) { + while (n7-- > 0) { + this.zrleTilePixels8[n3++] = (byte)n6; + } + continue; + } + while (n7-- > 0) { + this.zrleTilePixels24[n3++] = n6; + } + } + } + + void readZrlePackedRLEPixels(int n, int n2, int[] nArray) throws Exception { + int n3 = 0; + int n4 = n3 + n * n2; + while (n3 < n4) { + int n5; + int n6 = this.zrleInStream.readU8(); + int n7 = 1; + if ((n6 & 0x80) != 0) { + do { + n5 = this.zrleInStream.readU8(); + n7 += n5; + } while (n5 == 255); + if (n7 > n4 - n3) { + throw new Exception("ZRLE decoder: assertion failed (len <= end - ptr)"); + } + } + n5 = nArray[n6 &= 0x7F]; + if (this.bytesPixel == 1) { + while (n7-- > 0) { + this.zrleTilePixels8[n3++] = (byte)n5; + } + continue; + } + while (n7-- > 0) { + this.zrleTilePixels24[n3++] = n5; + } + } + } + + void handleUpdatedZrleTile(int n, int n2, int n3, int n4) { + Object[] objectArray; + Object[] objectArray2; + if (this.bytesPixel == 1) { + objectArray2 = this.zrleTilePixels8; + objectArray = this.pixels8; + } else { + objectArray2 = this.zrleTilePixels24; + objectArray = this.pixels24; + } + int n5 = 0; + int n6 = n2 * this.rfb.framebufferWidth + n; + for (int i = 0; i < n4; ++i) { + System.arraycopy(objectArray2, n5, objectArray, n6, n3); + n5 += n3; + n6 += this.rfb.framebufferWidth; + } + this.handleUpdatedPixels(n, n2, n3, n4); + } + + void handleZlibRect(int n, int n2, int n3, int n4) throws Exception { + int n5 = this.rfb.is.readInt(); + if (this.zlibBuf == null || this.zlibBufLen < n5) { + this.zlibBufLen = n5 * 2; + this.zlibBuf = new byte[this.zlibBufLen]; + } + this.rfb.readFully(this.zlibBuf, 0, n5); + if (this.rfb.rec != null && this.rfb.recordFromBeginning) { + this.rfb.rec.writeIntBE(n5); + this.rfb.rec.write(this.zlibBuf, 0, n5); + } + if (this.zlibInflater == null) { + this.zlibInflater = new Inflater(); + } + this.zlibInflater.setInput(this.zlibBuf, 0, n5); + if (this.bytesPixel == 1) { + for (int i = n2; i < n2 + n4; ++i) { + this.zlibInflater.inflate(this.pixels8, i * this.rfb.framebufferWidth + n, n3); + if (this.rfb.rec == null || this.rfb.recordFromBeginning) continue; + this.rfb.rec.write(this.pixels8, i * this.rfb.framebufferWidth + n, n3); + } + } else { + byte[] byArray = new byte[n3 * 4]; + for (int i = n2; i < n2 + n4; ++i) { + this.zlibInflater.inflate(byArray); + int n6 = i * this.rfb.framebufferWidth + n; + for (int j = 0; j < n3; ++j) { + this.pixels24[n6 + j] = (byArray[j * 4 + 2] & 0xFF) << 16 | (byArray[j * 4 + 1] & 0xFF) << 8 | byArray[j * 4] & 0xFF; + } + if (this.rfb.rec == null || this.rfb.recordFromBeginning) continue; + this.rfb.rec.write(byArray); + } + } + this.handleUpdatedPixels(n, n2, n3, n4); + this.scheduleRepaint(n, n2, n3, n4); + } + + /* + * WARNING - Removed try catching itself - possible behaviour change. + * Unable to fully structure code + */ + void handleTightRect(int var1_1, int var2_2, int var3_3, int var4_4) throws Exception { + block72: { + var5_5 = this.rfb.is.readUnsignedByte(); + if (this.rfb.rec == null) break block72; + if (this.rfb.recordFromBeginning) ** GOTO lbl-1000 + if (var5_5 == 8 << 4) ** GOTO lbl-1000 + if (var5_5 == 9 << 4) lbl-1000: + // 3 sources + + { + this.rfb.rec.writeByte(var5_5); + } else { + this.rfb.rec.writeByte(var5_5 | 15); + } + } + for (var6_6 = 0; var6_6 < 4; ++var6_6) { + if ((var5_5 & 1) != 0 && this.tightInflaters[var6_6] != null) { + this.tightInflaters[var6_6] = null; + } + var5_5 >>= 1; + } + if (var5_5 > 9) { + throw new Exception("Incorrect tight subencoding: " + var5_5); + } + if (var5_5 == 8) { + if (this.bytesPixel == 1) { + var6_6 = this.rfb.is.readUnsignedByte(); + this.memGraphics.setColor(this.colors[var6_6]); + if (this.rfb.rec != null) { + this.rfb.rec.writeByte(var6_6); + } + } else { + var6_7 = new byte[3]; + this.rfb.readFully(var6_7); + if (this.rfb.rec != null) { + this.rfb.rec.write(var6_7); + } + var7_9 = new Color(-16777216 | (var6_7[0] & 255) << 16 | (var6_7[1] & 255) << 8 | var6_7[2] & 255); + this.memGraphics.setColor(var7_9); + } + this.memGraphics.fillRect(var1_1, var2_2, var3_3, var4_4); + this.scheduleRepaint(var1_1, var2_2, var3_3, var4_4); + return; + } + if (var5_5 == 9) { + var6_8 = new byte[this.rfb.readCompactLen()]; + this.rfb.readFully(var6_8); + if (this.rfb.rec != null) { + if (!this.rfb.recordFromBeginning) { + this.rfb.recordCompactLen(var6_8.length); + } + this.rfb.rec.write(var6_8); + } + var7_10 = Toolkit.getDefaultToolkit().createImage(var6_8); + var8_12 = this.jpegRect = new Rectangle(var1_1, var2_2, var3_3, var4_4); + synchronized (var8_12) { + Toolkit.getDefaultToolkit().prepareImage(var7_10, -1, -1, this); + try { + this.jpegRect.wait(3000L); + } + catch (InterruptedException var9_14) { + throw new Exception("Interrupted while decoding JPEG image"); + } + } + this.jpegRect = null; + return; + } + var6_6 = 0; + var7_11 = var3_3; + var8_13 = new byte[2]; + var9_15 = new int[256]; + var10_17 = false; + if ((var5_5 & 4) != 0) { + var11_18 = this.rfb.is.readUnsignedByte(); + if (this.rfb.rec != null) { + this.rfb.rec.writeByte(var11_18); + } + if (var11_18 == 1) { + var6_6 = this.rfb.is.readUnsignedByte() + 1; + if (this.rfb.rec != null) { + this.rfb.rec.writeByte(var6_6 - 1); + } + if (this.bytesPixel == 1) { + if (var6_6 != 2) { + throw new Exception("Incorrect tight palette size: " + var6_6); + } + this.rfb.readFully(var8_13); + if (this.rfb.rec != null) { + this.rfb.rec.write(var8_13); + } + } else { + var12_19 = new byte[var6_6 * 3]; + this.rfb.readFully(var12_19); + if (this.rfb.rec != null) { + this.rfb.rec.write(var12_19); + } + for (var13_22 = 0; var13_22 < var6_6; ++var13_22) { + var9_15[var13_22] = (var12_19[var13_22 * 3] & 255) << 16 | (var12_19[var13_22 * 3 + 1] & 255) << 8 | var12_19[var13_22 * 3 + 2] & 255; + } + } + if (var6_6 == 2) { + var7_11 = (var3_3 + 7) / 8; + } + } else if (var11_18 == 2) { + var10_17 = true; + } else if (var11_18 != 0) { + throw new Exception("Incorrect tight filter id: " + var11_18); + } + } + if (var6_6 == 0 && this.bytesPixel == 4) { + var7_11 *= 3; + } + var11_18 = var4_4 * var7_11; + if (var11_18 < 12) { + if (var6_6 != 0) { + var12_19 = new byte[var11_18]; + this.rfb.readFully(var12_19); + if (this.rfb.rec != null) { + this.rfb.rec.write(var12_19); + } + if (var6_6 == 2) { + if (this.bytesPixel == 1) { + this.decodeMonoData(var1_1, var2_2, var3_3, var4_4, var12_19, var8_13); + } else { + this.decodeMonoData(var1_1, var2_2, var3_3, var4_4, var12_19, var9_15); + } + } else { + var13_22 = 0; + for (var14_24 = var2_2; var14_24 < var2_2 + var4_4; ++var14_24) { + for (var15_27 = var1_1; var15_27 < var1_1 + var3_3; ++var15_27) { + this.pixels24[var14_24 * this.rfb.framebufferWidth + var15_27] = var9_15[var12_19[var13_22++] & 255]; + } + } + } + } else if (var10_17) { + var12_19 = new byte[var3_3 * var4_4 * 3]; + this.rfb.readFully(var12_19); + if (this.rfb.rec != null) { + this.rfb.rec.write(var12_19); + } + this.decodeGradientData(var1_1, var2_2, var3_3, var4_4, var12_19); + } else if (this.bytesPixel == 1) { + for (var12_20 = var2_2; var12_20 < var2_2 + var4_4; ++var12_20) { + this.rfb.readFully(this.pixels8, var12_20 * this.rfb.framebufferWidth + var1_1, var3_3); + if (this.rfb.rec == null) continue; + this.rfb.rec.write(this.pixels8, var12_20 * this.rfb.framebufferWidth + var1_1, var3_3); + } + } else { + var12_19 = new byte[var3_3 * 3]; + for (var15_28 = var2_2; var15_28 < var2_2 + var4_4; ++var15_28) { + this.rfb.readFully(var12_19); + if (this.rfb.rec != null) { + this.rfb.rec.write(var12_19); + } + var14_25 = var15_28 * this.rfb.framebufferWidth + var1_1; + for (var13_22 = 0; var13_22 < var3_3; ++var13_22) { + this.pixels24[var14_25 + var13_22] = (var12_19[var13_22 * 3] & 255) << 16 | (var12_19[var13_22 * 3 + 1] & 255) << 8 | var12_19[var13_22 * 3 + 2] & 255; + } + } + } + } else { + var12_21 = this.rfb.readCompactLen(); + var13_23 = new byte[var12_21]; + this.rfb.readFully(var13_23); + if (this.rfb.rec != null && this.rfb.recordFromBeginning) { + this.rfb.rec.write(var13_23); + } + if (this.tightInflaters[var14_26 = var5_5 & 3] == null) { + this.tightInflaters[var14_26] = new Inflater(); + } + var15_29 = this.tightInflaters[var14_26]; + var15_29.setInput(var13_23); + var16_30 = new byte[var11_18]; + var15_29.inflate(var16_30); + if (this.rfb.rec != null && !this.rfb.recordFromBeginning) { + this.rfb.recordCompressedData(var16_30); + } + if (var6_6 != 0) { + if (var6_6 == 2) { + if (this.bytesPixel == 1) { + this.decodeMonoData(var1_1, var2_2, var3_3, var4_4, var16_30, var8_13); + } else { + this.decodeMonoData(var1_1, var2_2, var3_3, var4_4, var16_30, var9_15); + } + } else { + var17_31 = 0; + for (var18_34 = var2_2; var18_34 < var2_2 + var4_4; ++var18_34) { + for (var19_37 = var1_1; var19_37 < var1_1 + var3_3; ++var19_37) { + this.pixels24[var18_34 * this.rfb.framebufferWidth + var19_37] = var9_15[var16_30[var17_31++] & 255]; + } + } + } + } else if (var10_17) { + this.decodeGradientData(var1_1, var2_2, var3_3, var4_4, var16_30); + } else if (this.bytesPixel == 1) { + var17_32 = var2_2 * this.rfb.framebufferWidth + var1_1; + for (var18_35 = 0; var18_35 < var4_4; ++var18_35) { + System.arraycopy(var16_30, var18_35 * var3_3, this.pixels8, var17_32, var3_3); + var17_32 += this.rfb.framebufferWidth; + } + } else { + var17_33 = 0; + for (var20_39 = 0; var20_39 < var4_4; ++var20_39) { + var15_29.inflate(var16_30); + var18_36 = (var2_2 + var20_39) * this.rfb.framebufferWidth + var1_1; + for (var19_38 = 0; var19_38 < var3_3; ++var19_38) { + this.pixels24[var18_36 + var19_38] = (var16_30[var17_33] & 255) << 16 | (var16_30[var17_33 + 1] & 255) << 8 | var16_30[var17_33 + 2] & 255; + var17_33 += 3; + } + } + } + } + this.handleUpdatedPixels(var1_1, var2_2, var3_3, var4_4); + this.scheduleRepaint(var1_1, var2_2, var3_3, var4_4); + } + + void decodeMonoData(int n, int n2, int n3, int n4, byte[] byArray, byte[] byArray2) { + int n5 = n2 * this.rfb.framebufferWidth + n; + int n6 = (n3 + 7) / 8; + for (int i = 0; i < n4; ++i) { + int n7; + int n8; + for (n8 = 0; n8 < n3 / 8; ++n8) { + byte by = byArray[i * n6 + n8]; + for (n7 = 7; n7 >= 0; --n7) { + this.pixels8[n5++] = byArray2[by >> n7 & 1]; + } + } + for (n7 = 7; n7 >= 8 - n3 % 8; --n7) { + this.pixels8[n5++] = byArray2[byArray[i * n6 + n8] >> n7 & 1]; + } + n5 += this.rfb.framebufferWidth - n3; + } + } + + void decodeMonoData(int n, int n2, int n3, int n4, byte[] byArray, int[] nArray) { + int n5 = n2 * this.rfb.framebufferWidth + n; + int n6 = (n3 + 7) / 8; + for (int i = 0; i < n4; ++i) { + int n7; + int n8; + for (n8 = 0; n8 < n3 / 8; ++n8) { + byte by = byArray[i * n6 + n8]; + for (n7 = 7; n7 >= 0; --n7) { + this.pixels24[n5++] = nArray[by >> n7 & 1]; + } + } + for (n7 = 7; n7 >= 8 - n3 % 8; --n7) { + this.pixels24[n5++] = nArray[byArray[i * n6 + n8] >> n7 & 1]; + } + n5 += this.rfb.framebufferWidth - n3; + } + } + + void decodeGradientData(int n, int n2, int n3, int n4, byte[] byArray) { + byte[] byArray2 = new byte[n3 * 3]; + byte[] byArray3 = new byte[n3 * 3]; + byte[] byArray4 = new byte[3]; + int[] nArray = new int[3]; + int n5 = n2 * this.rfb.framebufferWidth + n; + for (int i = 0; i < n4; ++i) { + int n6; + for (n6 = 0; n6 < 3; ++n6) { + byArray4[n6] = (byte)(byArray2[n6] + byArray[i * n3 * 3 + n6]); + byArray3[n6] = byArray4[n6]; + } + this.pixels24[n5++] = (byArray4[0] & 0xFF) << 16 | (byArray4[1] & 0xFF) << 8 | byArray4[2] & 0xFF; + for (int j = 1; j < n3; ++j) { + for (n6 = 0; n6 < 3; ++n6) { + nArray[n6] = (byArray2[j * 3 + n6] & 0xFF) + (byArray4[n6] & 0xFF) - (byArray2[(j - 1) * 3 + n6] & 0xFF); + if (nArray[n6] > 255) { + nArray[n6] = 255; + } else if (nArray[n6] < 0) { + nArray[n6] = 0; + } + byArray4[n6] = (byte)(nArray[n6] + byArray[(i * n3 + j) * 3 + n6]); + byArray3[j * 3 + n6] = byArray4[n6]; + } + this.pixels24[n5++] = (byArray4[0] & 0xFF) << 16 | (byArray4[1] & 0xFF) << 8 | byArray4[2] & 0xFF; + } + System.arraycopy(byArray3, 0, byArray2, 0, n3 * 3); + n5 += this.rfb.framebufferWidth - n3; + } + } + + void handleUpdatedPixels(int n, int n2, int n3, int n4) { + this.pixelsSource.newPixels(n, n2, n3, n4); + this.memGraphics.setClip(n, n2, n3, n4); + this.memGraphics.drawImage(this.rawPixelsImage, 0, 0, null); + this.memGraphics.setClip(0, 0, this.rfb.framebufferWidth, this.rfb.framebufferHeight); + } + + void scheduleRepaint(int n, int n2, int n3, int n4) { + if (this.rfb.framebufferWidth == this.scaledWidth) { + this.repaint(this.viewer.deferScreenUpdates, n, n2, n3, n4); + } else { + int n5 = n * this.scalingFactor / 100; + int n6 = n2 * this.scalingFactor / 100; + int n7 = ((n + n3) * this.scalingFactor + 49) / 100 - n5 + 1; + int n8 = ((n2 + n4) * this.scalingFactor + 49) / 100 - n6 + 1; + this.repaint(this.viewer.deferScreenUpdates, n5, n6, n7, n8); + } + } + + public void keyPressed(KeyEvent keyEvent) { + this.processLocalKeyEvent(keyEvent); + } + + public void keyReleased(KeyEvent keyEvent) { + this.processLocalKeyEvent(keyEvent); + } + + public void keyTyped(KeyEvent keyEvent) { + keyEvent.consume(); + } + + public void mousePressed(MouseEvent mouseEvent) { + this.processLocalMouseEvent(mouseEvent, false); + } + + public void mouseReleased(MouseEvent mouseEvent) { + this.processLocalMouseEvent(mouseEvent, false); + } + + public void mouseMoved(MouseEvent mouseEvent) { + this.processLocalMouseEvent(mouseEvent, true); + } + + public void mouseDragged(MouseEvent mouseEvent) { + this.processLocalMouseEvent(mouseEvent, true); + } + + /* + * WARNING - Removed try catching itself - possible behaviour change. + */ + public void processLocalKeyEvent(KeyEvent keyEvent) { + if (this.viewer.rfb != null && this.rfb.inNormalProtocol) { + if (!this.inputEnabled) { + if ((keyEvent.getKeyChar() == 'r' || keyEvent.getKeyChar() == 'R') && keyEvent.getID() == 401) { + try { + this.rfb.writeFramebufferUpdateRequest(0, 0, this.rfb.framebufferWidth, this.rfb.framebufferHeight, false); + } + catch (IOException iOException) { + iOException.printStackTrace(); + } + } + } else { + RfbProto rfbProto = this.rfb; + synchronized (rfbProto) { + try { + this.rfb.writeKeyEvent(keyEvent); + } + catch (Exception exception) { + exception.printStackTrace(); + } + this.rfb.notify(); + } + } + } + keyEvent.consume(); + } + + /* + * WARNING - Removed try catching itself - possible behaviour change. + */ + public void processLocalMouseEvent(MouseEvent mouseEvent, boolean bl) { + if (this.viewer.rfb != null && this.rfb.inNormalProtocol) { + if (bl) { + this.softCursorMove(mouseEvent.getX(), mouseEvent.getY()); + } + if (this.rfb.framebufferWidth != this.scaledWidth) { + int n = (mouseEvent.getX() * 100 + this.scalingFactor / 2) / this.scalingFactor; + int n2 = (mouseEvent.getY() * 100 + this.scalingFactor / 2) / this.scalingFactor; + mouseEvent.translatePoint(n - mouseEvent.getX(), n2 - mouseEvent.getY()); + } + RfbProto rfbProto = this.rfb; + synchronized (rfbProto) { + try { + this.rfb.writePointerEvent(mouseEvent); + } + catch (Exception exception) { + exception.printStackTrace(); + } + this.rfb.notify(); + } + } + } + + public void mouseClicked(MouseEvent mouseEvent) { + } + + public void mouseEntered(MouseEvent mouseEvent) { + } + + public void mouseExited(MouseEvent mouseEvent) { + } + + synchronized void handleCursorShapeUpdate(int n, int n2, int n3, int n4, int n5) throws IOException { + this.softCursorFree(); + if (n4 * n5 == 0) { + return; + } + if (this.viewer.options.ignoreCursorUpdates) { + int n6 = (n4 + 7) / 8; + int n7 = n6 * n5; + if (n == -240) { + this.rfb.is.skipBytes(6 + n7 * 2); + } else { + this.rfb.is.skipBytes(n4 * n5 + n7); + } + return; + } + this.softCursorSource = this.decodeCursorShape(n, n4, n5); + this.origCursorWidth = n4; + this.origCursorHeight = n5; + this.origHotX = n2; + this.origHotY = n3; + this.createSoftCursor(); + this.showSoftCursor = true; + this.repaint(this.viewer.deferCursorUpdates, this.cursorX - this.hotX, this.cursorY - this.hotY, this.cursorWidth, this.cursorHeight); + } + + synchronized MemoryImageSource decodeCursorShape(int n, int n2, int n3) throws IOException { + int n4 = (n2 + 7) / 8; + int n5 = n4 * n3; + int[] nArray = new int[n2 * n3]; + if (n == -240) { + byte[] byArray = new byte[6]; + this.rfb.readFully(byArray); + int[] nArray2 = new int[]{0xFF000000 | (byArray[3] & 0xFF) << 16 | (byArray[4] & 0xFF) << 8 | byArray[5] & 0xFF, 0xFF000000 | (byArray[0] & 0xFF) << 16 | (byArray[1] & 0xFF) << 8 | byArray[2] & 0xFF}; + byte[] byArray2 = new byte[n5]; + this.rfb.readFully(byArray2); + byte[] byArray3 = new byte[n5]; + this.rfb.readFully(byArray3); + int n6 = 0; + for (int i = 0; i < n3; ++i) { + int n7; + int n8; + int n9; + for (n9 = 0; n9 < n2 / 8; ++n9) { + byte by = byArray2[i * n4 + n9]; + byte by2 = byArray3[i * n4 + n9]; + for (n8 = 7; n8 >= 0; --n8) { + n7 = (by2 >> n8 & 1) != 0 ? nArray2[by >> n8 & 1] : 0; + nArray[n6++] = n7; + } + } + for (n8 = 7; n8 >= 8 - n2 % 8; --n8) { + n7 = (byArray3[i * n4 + n9] >> n8 & 1) != 0 ? nArray2[byArray2[i * n4 + n9] >> n8 & 1] : 0; + nArray[n6++] = n7; + } + } + } else { + byte[] byArray = new byte[n2 * n3 * this.bytesPixel]; + this.rfb.readFully(byArray); + byte[] byArray4 = new byte[n5]; + this.rfb.readFully(byArray4); + int n10 = 0; + for (int i = 0; i < n3; ++i) { + int n11; + int n12; + int n13; + for (n13 = 0; n13 < n2 / 8; ++n13) { + byte by = byArray4[i * n4 + n13]; + for (n12 = 7; n12 >= 0; --n12) { + n11 = (by >> n12 & 1) != 0 ? (this.bytesPixel == 1 ? this.cm8.getRGB(byArray[n10]) : 0xFF000000 | (byArray[n10 * 4 + 2] & 0xFF) << 16 | (byArray[n10 * 4 + 1] & 0xFF) << 8 | byArray[n10 * 4] & 0xFF) : 0; + nArray[n10++] = n11; + } + } + for (n12 = 7; n12 >= 8 - n2 % 8; --n12) { + n11 = (byArray4[i * n4 + n13] >> n12 & 1) != 0 ? (this.bytesPixel == 1 ? this.cm8.getRGB(byArray[n10]) : 0xFF000000 | (byArray[n10 * 4 + 2] & 0xFF) << 16 | (byArray[n10 * 4 + 1] & 0xFF) << 8 | byArray[n10 * 4] & 0xFF) : 0; + nArray[n10++] = n11; + } + } + } + return new MemoryImageSource(n2, n3, nArray, 0, n2); + } + + synchronized void createSoftCursor() { + if (this.softCursorSource == null) { + return; + } + int n = this.viewer.options.scaleCursor; + if (n == 0 || !this.inputEnabled) { + n = 100; + } + int n2 = this.cursorX - this.hotX; + int n3 = this.cursorY - this.hotY; + int n4 = this.cursorWidth; + int n5 = this.cursorHeight; + this.cursorWidth = (this.origCursorWidth * n + 50) / 100; + this.cursorHeight = (this.origCursorHeight * n + 50) / 100; + this.hotX = (this.origHotX * n + 50) / 100; + this.hotY = (this.origHotY * n + 50) / 100; + this.softCursor = Toolkit.getDefaultToolkit().createImage(this.softCursorSource); + if (n != 100) { + this.softCursor = this.softCursor.getScaledInstance(this.cursorWidth, this.cursorHeight, 4); + } + if (this.showSoftCursor) { + n2 = Math.min(n2, this.cursorX - this.hotX); + n3 = Math.min(n3, this.cursorY - this.hotY); + n4 = Math.max(n4, this.cursorWidth); + n5 = Math.max(n5, this.cursorHeight); + this.repaint(this.viewer.deferCursorUpdates, n2, n3, n4, n5); + } + } + + synchronized void softCursorMove(int n, int n2) { + int n3 = this.cursorX; + int n4 = this.cursorY; + this.cursorX = n; + this.cursorY = n2; + if (this.showSoftCursor) { + this.repaint(this.viewer.deferCursorUpdates, n3 - this.hotX, n4 - this.hotY, this.cursorWidth, this.cursorHeight); + this.repaint(this.viewer.deferCursorUpdates, this.cursorX - this.hotX, this.cursorY - this.hotY, this.cursorWidth, this.cursorHeight); + } + } + + synchronized void softCursorFree() { + if (this.showSoftCursor) { + this.showSoftCursor = false; + this.softCursor = null; + this.softCursorSource = null; + this.repaint(this.viewer.deferCursorUpdates, this.cursorX - this.hotX, this.cursorY - this.hotY, this.cursorWidth, this.cursorHeight); + } + } +} + diff --git a/src/VncCanvas2.java b/src/VncCanvas2.java new file mode 100644 index 0000000..866f8f0 --- /dev/null +++ b/src/VncCanvas2.java @@ -0,0 +1,40 @@ +/* + * Decompiled with CFR 0.152. + */ +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.io.IOException; +import java.lang.reflect.Method; + +class VncCanvas2 +extends VncCanvas { + public VncCanvas2(VncViewer vncViewer) throws IOException { + super(vncViewer); + this.disableFocusTraversalKeys(); + } + + public VncCanvas2(VncViewer vncViewer, int n, int n2) throws IOException { + super(vncViewer, n, n2); + this.disableFocusTraversalKeys(); + } + + public void paintScaledFrameBuffer(Graphics graphics) { + Graphics2D graphics2D = (Graphics2D)graphics; + graphics2D.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); + graphics2D.drawImage(this.memImage, 0, 0, this.scaledWidth, this.scaledHeight, null); + } + + private void disableFocusTraversalKeys() { + try { + Class[] classArray = new Class[]{Boolean.TYPE}; + Method method = this.getClass().getMethod("setFocusTraversalKeysEnabled", classArray); + Object[] objectArray = new Object[]{new Boolean(false)}; + method.invoke(this, objectArray); + } + catch (Exception exception) { + // empty catch block + } + } +} + diff --git a/src/VncThumbnailViewer.java b/src/VncThumbnailViewer.java new file mode 100644 index 0000000..3724184 --- /dev/null +++ b/src/VncThumbnailViewer.java @@ -0,0 +1,368 @@ +/* + * Decompiled with CFR 0.152. + */ +import java.awt.Button; +import java.awt.Component; +import java.awt.FileDialog; +import java.awt.Frame; +import java.awt.GraphicsEnvironment; +import java.awt.GridLayout; +import java.awt.Insets; +import java.awt.Menu; +import java.awt.MenuBar; +import java.awt.MenuItem; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.ComponentEvent; +import java.awt.event.ComponentListener; +import java.awt.event.ContainerEvent; +import java.awt.event.ContainerListener; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.WindowEvent; +import java.awt.event.WindowListener; +import java.util.AbstractList; +import java.util.ListIterator; + +public class VncThumbnailViewer +extends Frame +implements WindowListener, +ComponentListener, +ContainerListener, +MouseListener, +ActionListener { + static final float VERSION = 1.4f; + VncViewersList viewersList = new VncViewersList(this); + AddHostDialog hostDialog; + MenuItem newhostMenuItem; + MenuItem loadhostsMenuItem; + MenuItem savehostsMenuItem; + MenuItem exitMenuItem; + Frame soloViewer; + int widthPerThumbnail = 0; + int heightPerThumbnail = 0; + int thumbnailRowCount = 0; + + public static void main(String[] stringArray) { + VncThumbnailViewer vncThumbnailViewer = new VncThumbnailViewer(); + String string = new String(""); + String string2 = new String(""); + String string3 = new String(""); + int n = 0; + for (int i = 0; i < stringArray.length; i += 2) { + if (stringArray.length < i + 2) { + System.out.println("ERROR: No value found for parameter " + stringArray[i]); + break; + } + String string4 = stringArray[i]; + String string5 = stringArray[i + 1]; + if (string4.equalsIgnoreCase("host")) { + string = string5; + } + if (string4.equalsIgnoreCase("port")) { + n = Integer.parseInt(string5); + } + if (string4.equalsIgnoreCase("password")) { + string2 = string5; + } + if (string4.equalsIgnoreCase("username")) { + string3 = string5; + } + if (string4.equalsIgnoreCase("encpassword")) { + string2 = AddHostDialog.readEncPassword(string5); + } + if (i + 2 < stringArray.length && !stringArray[i + 2].equalsIgnoreCase("host")) continue; + if (string != "" && n != 0) { + System.out.println("Command-line: host " + string + " port " + n); + vncThumbnailViewer.launchViewer(string, n, string2, string3); + string = ""; + n = 0; + string2 = ""; + string3 = ""; + continue; + } + System.out.println("ERROR: No port specified for last host (" + string + ")"); + } + } + + VncThumbnailViewer() { + this.setTitle("DJC Thumbnail Viewer"); + this.addWindowListener(this); + this.addComponentListener(this); + this.addMouseListener(this); + GridLayout gridLayout = new GridLayout(); + this.setLayout(gridLayout); + ((Component)this).setSize(GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds().getSize()); + this.setMenuBar(new MenuBar()); + this.getMenuBar().add(this.createFileMenu()); + ((Component)this).setVisible(true); + this.soloViewer = new Frame(); + ((Component)this.soloViewer).setSize(GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds().getSize()); + this.soloViewer.addWindowListener(this); + this.soloViewer.addComponentListener(this); + this.soloViewer.validate(); + } + + public void launchViewer(String string, int n, String string2, String string3) { + this.launchViewer(string, n, string2, string3, ""); + } + + public void launchViewer(String string, int n, String string2, String string3, String string4) { + VncViewer vncViewer = this.viewersList.launchViewer(string, n, string2, string3, string4); + } + + void addViewer(VncViewer vncViewer) { + int n = (int)Math.sqrt(this.viewersList.size() - 1) + 1; + if (n != this.thumbnailRowCount) { + this.thumbnailRowCount = n; + ((GridLayout)this.getLayout()).setRows(this.thumbnailRowCount); + this.resizeThumbnails(); + } + this.add(vncViewer); + this.validate(); + } + + void removeViewer(VncViewer vncViewer) { + this.viewersList.remove(vncViewer); + this.remove(vncViewer); + this.validate(); + int n = (int)Math.sqrt(this.viewersList.size() - 1) + 1; + if (n != this.thumbnailRowCount) { + this.thumbnailRowCount = n; + ((GridLayout)this.getLayout()).setRows(this.thumbnailRowCount); + this.resizeThumbnails(); + } + } + + void soloHost(VncViewer vncViewer) { + if (vncViewer.vc == null) { + return; + } + if (this.soloViewer.getComponentCount() > 0) { + this.soloHostClose(); + } + ((Component)this.soloViewer).setVisible(true); + this.soloViewer.setTitle(vncViewer.host); + this.remove(vncViewer); + this.soloViewer.add(vncViewer); + vncViewer.vc.removeMouseListener(this); + this.validate(); + this.soloViewer.validate(); + if (!vncViewer.rfb.closed()) { + vncViewer.vc.enableInput(true); + } + this.updateCanvasScaling(vncViewer, VncThumbnailViewer.getWidthNoInsets(this.soloViewer), VncThumbnailViewer.getHeightNoInsets(this.soloViewer)); + } + + void soloHostClose() { + VncViewer vncViewer = (VncViewer)this.soloViewer.getComponent(0); + vncViewer.enableInput(false); + this.updateCanvasScaling(vncViewer, this.widthPerThumbnail, this.heightPerThumbnail); + this.soloViewer.removeAll(); + this.addViewer(vncViewer); + vncViewer.vc.addMouseListener(this); + ((Component)this.soloViewer).setVisible(false); + } + + private void updateCanvasScaling(VncViewer vncViewer, int n, int n2) { + int n3; + int n4 = vncViewer.vc.rfb.framebufferWidth; + int n5 = n * 100 / n4; + int n6 = (n2 -= vncViewer.buttonPanel.getHeight()) * 100 / (n3 = vncViewer.vc.rfb.framebufferHeight); + int n7 = Math.min(n5, n6); + if (n7 > 100) { + n7 = 100; + } + vncViewer.vc.maxWidth = n; + vncViewer.vc.maxHeight = n2; + vncViewer.vc.scalingFactor = n7; + vncViewer.vc.scaledWidth = (n4 * n7 + 50) / 100; + vncViewer.vc.scaledHeight = (n3 * n7 + 50) / 100; + } + + void resizeThumbnails() { + int n = VncThumbnailViewer.getWidthNoInsets(this) / this.thumbnailRowCount; + int n2 = VncThumbnailViewer.getHeightNoInsets(this) / this.thumbnailRowCount; + if (n != this.widthPerThumbnail || n2 != this.heightPerThumbnail) { + this.widthPerThumbnail = n; + this.heightPerThumbnail = n2; + ListIterator listIterator = ((AbstractList)this.viewersList).listIterator(); + while (listIterator.hasNext()) { + VncViewer vncViewer = (VncViewer)listIterator.next(); + if (this.soloViewer.isAncestorOf(vncViewer) || vncViewer.vc == null) continue; + this.updateCanvasScaling(vncViewer, this.widthPerThumbnail, this.heightPerThumbnail); + } + } + } + + private void loadsaveHosts(int n) { + FileDialog fileDialog = new FileDialog((Frame)this, "Load hosts file...", n); + if (n == 1) { + fileDialog.setTitle("Save hosts file..."); + } + fileDialog.show(); + String string = fileDialog.getFile(); + if (string != null) { + String string2 = fileDialog.getDirectory(); + if (n == 1) { + HostsFilePasswordDialog hostsFilePasswordDialog = new HostsFilePasswordDialog((Frame)this, true); + if (hostsFilePasswordDialog.getResult()) { + this.viewersList.saveToEncryptedFile(string2 + string, hostsFilePasswordDialog.getPassword()); + } else { + this.viewersList.saveToFile(string2 + string); + } + } else if (VncViewersList.isHostsFileEncrypted(string2 + string)) { + HostsFilePasswordDialog hostsFilePasswordDialog = new HostsFilePasswordDialog((Frame)this, false); + this.viewersList.loadHosts(string2 + string, hostsFilePasswordDialog.getPassword()); + } else { + this.viewersList.loadHosts(string2 + string, ""); + } + } + } + + private void quit() { + System.out.println("Closing window"); + ListIterator listIterator = ((AbstractList)this.viewersList).listIterator(); + while (listIterator.hasNext()) { + ((VncViewer)listIterator.next()).disconnect(); + } + this.dispose(); + System.exit(0); + } + + private static int getWidthNoInsets(Frame frame) { + Insets insets = frame.getInsets(); + int n = frame.getWidth() - (insets.left + insets.right); + return n; + } + + private static int getHeightNoInsets(Frame frame) { + Insets insets = frame.getInsets(); + int n = frame.getHeight() - (insets.top + insets.bottom); + return n; + } + + private Menu createFileMenu() { + Menu menu = new Menu("File"); + this.newhostMenuItem = new MenuItem("Add New Host"); + this.loadhostsMenuItem = new MenuItem("Load List of Hosts"); + this.savehostsMenuItem = new MenuItem("Save List of Hosts"); + this.exitMenuItem = new MenuItem("Exit"); + this.newhostMenuItem.addActionListener(this); + this.loadhostsMenuItem.addActionListener(this); + this.savehostsMenuItem.addActionListener(this); + this.exitMenuItem.addActionListener(this); + menu.add(this.newhostMenuItem); + menu.addSeparator(); + menu.add(this.loadhostsMenuItem); + menu.add(this.savehostsMenuItem); + menu.addSeparator(); + menu.add(this.exitMenuItem); + this.loadhostsMenuItem.enable(true); + this.savehostsMenuItem.enable(true); + return menu; + } + + public void windowClosing(WindowEvent windowEvent) { + if (this.soloViewer.isShowing()) { + this.soloHostClose(); + } + if (windowEvent.getComponent() == this) { + this.quit(); + } + } + + public void windowActivated(WindowEvent windowEvent) { + } + + public void windowDeactivated(WindowEvent windowEvent) { + } + + public void windowOpened(WindowEvent windowEvent) { + } + + public void windowClosed(WindowEvent windowEvent) { + } + + public void windowIconified(WindowEvent windowEvent) { + } + + public void windowDeiconified(WindowEvent windowEvent) { + } + + public void componentResized(ComponentEvent componentEvent) { + if (componentEvent.getComponent() == this) { + if (this.thumbnailRowCount > 0) { + this.resizeThumbnails(); + } + } else { + VncViewer vncViewer = (VncViewer)this.soloViewer.getComponent(0); + this.updateCanvasScaling(vncViewer, VncThumbnailViewer.getWidthNoInsets(this.soloViewer), VncThumbnailViewer.getHeightNoInsets(this.soloViewer)); + } + } + + public void componentHidden(ComponentEvent componentEvent) { + } + + public void componentMoved(ComponentEvent componentEvent) { + } + + public void componentShown(ComponentEvent componentEvent) { + } + + public void mouseClicked(MouseEvent mouseEvent) { + Component component; + if (mouseEvent.getClickCount() == 2 && (component = mouseEvent.getComponent()) instanceof VncCanvas) { + this.soloHost(((VncCanvas)component).viewer); + } + } + + public void mouseEntered(MouseEvent mouseEvent) { + } + + public void mouseExited(MouseEvent mouseEvent) { + } + + public void mousePressed(MouseEvent mouseEvent) { + } + + public void mouseReleased(MouseEvent mouseEvent) { + } + + public void componentAdded(ContainerEvent containerEvent) { + Button button; + if (containerEvent.getChild() instanceof VncCanvas) { + VncViewer vncViewer = (VncViewer)containerEvent.getContainer(); + vncViewer.vc.addMouseListener(this); + vncViewer.buttonPanel.addContainerListener(this); + vncViewer.buttonPanel.disconnectButton.addActionListener(this); + this.updateCanvasScaling(vncViewer, this.widthPerThumbnail, this.heightPerThumbnail); + } else if (containerEvent.getChild() instanceof Button && (button = (Button)containerEvent.getChild()).getLabel() == "Hide desktop") { + button.addActionListener(this); + } + } + + public void componentRemoved(ContainerEvent containerEvent) { + } + + public void actionPerformed(ActionEvent actionEvent) { + if (actionEvent.getSource() instanceof Button && ((Button)actionEvent.getSource()).getLabel() == "Hide desktop") { + VncViewer vncViewer = (VncViewer)((Component)actionEvent.getSource()).getParent().getParent(); + this.remove(vncViewer); + this.viewersList.remove(vncViewer); + } + if (actionEvent.getSource() == this.newhostMenuItem) { + this.hostDialog = new AddHostDialog(this); + } + if (actionEvent.getSource() == this.savehostsMenuItem) { + this.loadsaveHosts(1); + } + if (actionEvent.getSource() == this.loadhostsMenuItem) { + this.loadsaveHosts(0); + } + if (actionEvent.getSource() == this.exitMenuItem) { + this.quit(); + } + } +} + diff --git a/src/VncViewer.java b/src/VncViewer.java new file mode 100644 index 0000000..48db886 --- /dev/null +++ b/src/VncViewer.java @@ -0,0 +1,787 @@ +/* + * Decompiled with CFR 0.152. + */ +import java.applet.Applet; +import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Font; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.GridLayout; +import java.awt.Insets; +import java.awt.Label; +import java.awt.Panel; +import java.awt.ScrollPane; +import java.awt.event.WindowEvent; +import java.awt.event.WindowListener; +import java.io.EOFException; +import java.io.IOException; +import java.io.Serializable; +import java.lang.reflect.Constructor; +import java.net.ConnectException; +import java.net.NoRouteToHostException; +import java.net.UnknownHostException; + +public class VncViewer +extends Applet +implements Runnable, +WindowListener { + boolean inAnApplet = true; + boolean inSeparateFrame = false; + String[] mainArgs; + RfbProto rfb; + Thread rfbThread; + Frame vncFrame; + Container vncContainer; + ScrollPane desktopScrollPane; + GridBagLayout gridbag; + ButtonPanel buttonPanel; + Label connStatusLabel; + VncCanvas vc; + OptionsFrame options; + ClipboardFrame clipboard; + RecordingFrame rec; + Object recordingSync; + String sessionFileName; + boolean recordingActive; + boolean recordingStatusChanged; + String cursorUpdatesDef; + String eightBitColorsDef; + String socketFactory; + String host; + int port; + String passwordParam; + String usernameParam; + boolean showControls; + boolean offerRelogin; + boolean showOfflineDesktop; + int deferScreenUpdates; + int deferCursorUpdates; + int deferUpdateRequests; + public static Applet refApplet; + int[] encodingsSaved; + int nEncodingsSaved; + + public static void main(String[] stringArray) { + VncViewer vncViewer = new VncViewer(); + vncViewer.mainArgs = stringArray; + vncViewer.inAnApplet = false; + vncViewer.inSeparateFrame = true; + vncViewer.init(); + vncViewer.start(); + } + + public void init() { + this.readParameters(); + refApplet = this; + if (this.inSeparateFrame) { + this.vncFrame = new Frame("TightVNC"); + if (!this.inAnApplet) { + this.vncFrame.add("Center", this); + } + this.vncContainer = this.vncFrame; + } else { + this.vncContainer = this; + } + this.recordingSync = new Object(); + this.options = new OptionsFrame(this); + this.clipboard = new ClipboardFrame(this); + if (RecordingFrame.checkSecurity()) { + this.rec = new RecordingFrame(this); + } + this.sessionFileName = null; + this.recordingActive = false; + this.recordingStatusChanged = false; + this.cursorUpdatesDef = null; + this.eightBitColorsDef = null; + if (this.inSeparateFrame) { + this.vncFrame.addWindowListener(this); + } + this.rfbThread = new Thread(this); + this.rfbThread.start(); + } + + public void update(Graphics graphics) { + } + + public void run() { + this.gridbag = new GridBagLayout(); + this.vncContainer.setLayout(this.gridbag); + GridBagConstraints gridBagConstraints = new GridBagConstraints(); + gridBagConstraints.gridwidth = 0; + gridBagConstraints.anchor = 18; + gridBagConstraints.fill = 1; + if (this.showControls) { + this.buttonPanel = new ButtonPanel(this); + this.gridbag.setConstraints(this.buttonPanel, gridBagConstraints); + this.vncContainer.add(this.buttonPanel); + } + try { + Serializable serializable; + this.connectAndAuthenticate(); + this.doProtocolInitialisation(); + if (this.options.autoScale && this.inSeparateFrame) { + try { + serializable = this.vncContainer.getToolkit().getScreenSize(); + } + catch (Exception exception) { + serializable = new Dimension(0, 0); + } + this.createCanvas(((Dimension)serializable).width - 32, ((Dimension)serializable).height - 32); + } else { + this.createCanvas(0, 0); + } + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + if (this.inSeparateFrame) { + serializable = new Panel(); + ((Container)serializable).setLayout(new FlowLayout(0, 0, 0)); + ((Container)serializable).add(this.vc); + this.desktopScrollPane = new ScrollPane(0); + gridBagConstraints.fill = 1; + this.gridbag.setConstraints(this.desktopScrollPane, gridBagConstraints); + this.desktopScrollPane.add((Component)serializable); + this.vncFrame.add(this.desktopScrollPane); + this.vncFrame.setTitle(this.rfb.desktopName); + this.vncFrame.pack(); + this.vc.resizeDesktopFrame(); + } else { + this.gridbag.setConstraints(this.vc, gridBagConstraints); + this.add(this.vc); + this.validate(); + } + if (this.showControls) { + this.buttonPanel.enableButtons(); + } + this.moveFocusToDesktop(); + this.processNormalProtocol(); + } + catch (NoRouteToHostException noRouteToHostException) { + this.fatalError("Network error: no route to server: " + this.host, noRouteToHostException); + } + catch (UnknownHostException unknownHostException) { + this.fatalError("Network error: server name unknown: " + this.host, unknownHostException); + } + catch (ConnectException connectException) { + this.fatalError("Network error: could not connect to server: " + this.host + ":" + this.port, connectException); + } + catch (EOFException eOFException) { + if (this.showOfflineDesktop) { + eOFException.printStackTrace(); + System.out.println("Network error: remote side closed connection"); + if (this.vc != null) { + this.vc.enableInput(false); + } + if (this.inSeparateFrame) { + this.vncFrame.setTitle(this.rfb.desktopName + " [disconnected]"); + } + if (this.rfb != null && !this.rfb.closed()) { + this.rfb.close(); + } + if (this.showControls && this.buttonPanel != null) { + this.buttonPanel.disableButtonsOnDisconnect(); + if (this.inSeparateFrame) { + this.vncFrame.pack(); + } else { + this.validate(); + } + } + } else { + this.fatalError("Network error: remote side closed connection", eOFException); + } + } + catch (IOException iOException) { + String string = iOException.getMessage(); + if (string != null && string.length() != 0) { + this.fatalError("Network Error: " + string, iOException); + } else { + this.fatalError(iOException.toString(), iOException); + } + } + catch (Exception exception) { + String string = exception.getMessage(); + if (string != null && string.length() != 0) { + this.fatalError("Error: " + string, exception); + } + this.fatalError(exception.toString(), exception); + } + } + + void createCanvas(int n, int n2) throws IOException { + this.vc = null; + try { + Class clazz = Class.forName("java.awt.Graphics2D"); + clazz = Class.forName("VncCanvas2"); + Class[] classArray = new Class[]{this.getClass(), Integer.TYPE, Integer.TYPE}; + Constructor constructor = clazz.getConstructor(classArray); + Object[] objectArray = new Object[]{this, new Integer(n), new Integer(n2)}; + this.vc = (VncCanvas)constructor.newInstance(objectArray); + } + catch (Exception exception) { + System.out.println("Warning: Java 2D API is not available"); + } + if (this.vc == null) { + this.vc = new VncCanvas(this, n, n2); + } + } + + void processNormalProtocol() throws Exception { + try { + this.vc.processNormalProtocol(); + } + catch (Exception exception) { + if (this.rfbThread == null) { + System.out.println("Ignoring RFB socket exceptions because applet is stopping"); + } + throw exception; + } + } + + void connectAndAuthenticate() throws Exception { + int n; + this.showConnectionStatus("Initializing..."); + if (this.inSeparateFrame) { + this.vncFrame.pack(); + this.vncFrame.show(); + } else { + this.validate(); + } + this.showConnectionStatus("Connecting to " + this.host + ", port " + this.port + "..."); + this.rfb = new RfbProto(this.host, this.port, this); + this.showConnectionStatus("Connected to server"); + this.rfb.readVersionMsg(); + this.showConnectionStatus("RFB server supports protocol version " + this.rfb.serverMajor + "." + this.rfb.serverMinor); + this.rfb.writeVersionMsg(); + this.showConnectionStatus("Using RFB protocol version " + this.rfb.clientMajor + "." + this.rfb.clientMinor); + int n2 = this.rfb.negotiateSecurity(); + if (n2 == 16) { + this.showConnectionStatus("Enabling TightVNC protocol extensions"); + this.rfb.initCapabilities(); + this.rfb.setupTunneling(); + n = this.rfb.negotiateAuthenticationTight(); + } else { + n = n2; + } + switch (n) { + case 1: { + this.showConnectionStatus("No authentication needed"); + this.rfb.authenticateNone(); + break; + } + case 2: { + this.showConnectionStatus("Performing standard VNC authentication"); + String string = this.passwordParam; + if (string == null) { + string = this.askPassword(); + } + if (this.rfb.serverMinor == 4 && this.rfb.clientMinor == 4) { + this.showConnectionStatus("Performing VNC authentication... with Ultr@VNC MS-Logon I"); + String string2 = this.usernameParam; + if (string2 == null) { + throw new Exception("Username not specified, could not complete logon"); + } + this.rfb.authenticateMSLogonI(string, string2); + break; + } + this.rfb.authenticateVNC(string); + break; + } + case -6: { + this.showConnectionStatus("Performing MS-Logon authentication"); + if (this.passwordParam != null && this.usernameParam != null) { + this.rfb.authenticateMSLogon(this.passwordParam, this.usernameParam); + break; + } + throw new Exception("Username or Password not specified, could not complete MS-Logon"); + } + default: { + throw new Exception("Unknown authentication scheme " + n); + } + } + } + + void showConnectionStatus(String string) { + if (string == null) { + if (this.vncContainer.isAncestorOf(this.connStatusLabel)) { + this.vncContainer.remove(this.connStatusLabel); + } + return; + } + System.out.println(this.host + " Status: " + string); + if (this.connStatusLabel == null) { + this.connStatusLabel = new Label("Status: " + string); + this.connStatusLabel.setFont(new Font("Helvetica", 0, 12)); + } else { + this.connStatusLabel.setText("Status: " + string); + } + if (!this.vncContainer.isAncestorOf(this.connStatusLabel)) { + GridBagConstraints gridBagConstraints = new GridBagConstraints(); + gridBagConstraints.gridwidth = 0; + gridBagConstraints.fill = 2; + gridBagConstraints.anchor = 18; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + gridBagConstraints.insets = new Insets(20, 30, 20, 30); + this.gridbag.setConstraints(this.connStatusLabel, gridBagConstraints); + this.vncContainer.add(this.connStatusLabel); + } + if (this.inSeparateFrame) { + this.vncFrame.pack(); + } else { + this.validate(); + } + } + + String askPassword() throws Exception { + this.showConnectionStatus(null); + AuthPanel authPanel = new AuthPanel(this); + GridBagConstraints gridBagConstraints = new GridBagConstraints(); + gridBagConstraints.gridwidth = 0; + gridBagConstraints.anchor = 18; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + gridBagConstraints.ipadx = 100; + gridBagConstraints.ipady = 50; + this.gridbag.setConstraints(authPanel, gridBagConstraints); + this.vncContainer.add(authPanel); + if (this.inSeparateFrame) { + this.vncFrame.pack(); + } else { + this.validate(); + } + authPanel.moveFocusToDefaultField(); + String string = authPanel.getPassword(); + this.vncContainer.remove(authPanel); + return string; + } + + void doProtocolInitialisation() throws IOException { + this.rfb.writeClientInit(); + this.rfb.readServerInit(); + System.out.println("Desktop name is " + this.rfb.desktopName); + System.out.println("Desktop size is " + this.rfb.framebufferWidth + " x " + this.rfb.framebufferHeight); + this.setEncodings(); + this.showConnectionStatus(null); + } + + void setEncodings() { + this.setEncodings(false); + } + + void autoSelectEncodings() { + this.setEncodings(true); + } + + void setEncodings(boolean bl) { + if (this.options == null || this.rfb == null || !this.rfb.inNormalProtocol) { + return; + } + int n = this.options.preferredEncoding; + if (n == -1) { + long l = this.rfb.kbitsPerSecond(); + if (this.nEncodingsSaved < 1) { + System.out.println("Using Tight/ZRLE encodings"); + n = 7; + } else if (l > 2000L && this.encodingsSaved[0] != 5) { + System.out.println("Throughput " + l + " kbit/s - changing to Hextile encoding"); + n = 5; + } else if (l < 1000L && this.encodingsSaved[0] != 7) { + System.out.println("Throughput " + l + " kbit/s - changing to Tight/ZRLE encodings"); + n = 7; + } else { + if (bl) { + return; + } + n = this.encodingsSaved[0]; + } + } else if (bl) { + return; + } + int[] nArray = new int[20]; + int n2 = 0; + nArray[n2++] = n; + if (this.options.useCopyRect) { + nArray[n2++] = 1; + } + if (n != 7) { + nArray[n2++] = 7; + } + if (n != 16) { + nArray[n2++] = 16; + } + if (n != 5) { + nArray[n2++] = 5; + } + if (n != 6) { + nArray[n2++] = 6; + } + if (n != 4) { + nArray[n2++] = 4; + } + if (n != 2) { + nArray[n2++] = 2; + } + if (this.options.compressLevel >= 0 && this.options.compressLevel <= 9) { + nArray[n2++] = -256 + this.options.compressLevel; + } + if (this.options.jpegQuality >= 0 && this.options.jpegQuality <= 9) { + nArray[n2++] = -32 + this.options.jpegQuality; + } + if (this.options.requestCursorUpdates) { + nArray[n2++] = -240; + nArray[n2++] = -239; + if (!this.options.ignoreCursorUpdates) { + nArray[n2++] = -232; + } + } + nArray[n2++] = -224; + nArray[n2++] = -223; + boolean bl2 = false; + if (n2 != this.nEncodingsSaved) { + bl2 = true; + } else { + for (int i = 0; i < n2; ++i) { + if (nArray[i] == this.encodingsSaved[i]) continue; + bl2 = true; + break; + } + } + if (bl2) { + try { + this.rfb.writeSetEncodings(nArray, n2); + if (this.vc != null) { + this.vc.softCursorFree(); + } + } + catch (Exception exception) { + exception.printStackTrace(); + } + this.encodingsSaved = nArray; + this.nEncodingsSaved = n2; + } + } + + void setCutText(String string) { + try { + if (this.rfb != null && this.rfb.inNormalProtocol) { + this.rfb.writeClientCutText(string); + } + } + catch (Exception exception) { + exception.printStackTrace(); + } + } + + /* + * WARNING - Removed try catching itself - possible behaviour change. + */ + void setRecordingStatus(String string) { + Object object = this.recordingSync; + synchronized (object) { + this.sessionFileName = string; + this.recordingStatusChanged = true; + } + } + + /* + * WARNING - Removed try catching itself - possible behaviour change. + */ + boolean checkRecordingStatus() throws IOException { + Object object = this.recordingSync; + synchronized (object) { + if (this.recordingStatusChanged) { + this.recordingStatusChanged = false; + if (this.sessionFileName != null) { + this.startRecording(); + return true; + } + this.stopRecording(); + } + } + return false; + } + + /* + * WARNING - Removed try catching itself - possible behaviour change. + */ + protected void startRecording() throws IOException { + Object object = this.recordingSync; + synchronized (object) { + if (!this.recordingActive) { + this.cursorUpdatesDef = this.options.choices[this.options.cursorUpdatesIndex].getSelectedItem(); + this.eightBitColorsDef = this.options.choices[this.options.eightBitColorsIndex].getSelectedItem(); + this.options.choices[this.options.cursorUpdatesIndex].select("Disable"); + this.options.choices[this.options.cursorUpdatesIndex].setEnabled(false); + this.options.setEncodings(); + this.options.choices[this.options.eightBitColorsIndex].select("No"); + this.options.choices[this.options.eightBitColorsIndex].setEnabled(false); + this.options.setColorFormat(); + } else { + this.rfb.closeSession(); + } + System.out.println("Recording the session in " + this.sessionFileName); + this.rfb.startSession(this.sessionFileName); + this.recordingActive = true; + } + } + + /* + * WARNING - Removed try catching itself - possible behaviour change. + */ + protected void stopRecording() throws IOException { + Object object = this.recordingSync; + synchronized (object) { + if (this.recordingActive) { + this.options.choices[this.options.cursorUpdatesIndex].select(this.cursorUpdatesDef); + this.options.choices[this.options.cursorUpdatesIndex].setEnabled(true); + this.options.setEncodings(); + this.options.choices[this.options.eightBitColorsIndex].select(this.eightBitColorsDef); + this.options.choices[this.options.eightBitColorsIndex].setEnabled(true); + this.options.setColorFormat(); + this.rfb.closeSession(); + System.out.println("Session recording stopped."); + } + this.sessionFileName = null; + this.recordingActive = false; + } + } + + void readParameters() { + this.host = this.readParameter("HOST", !this.inAnApplet); + if (this.host == null) { + this.host = this.getCodeBase().getHost(); + if (this.host.equals("")) { + this.fatalError("HOST parameter not specified"); + } + } + String string = this.readParameter("PORT", true); + this.port = Integer.parseInt(string); + this.readPasswordParameters(); + this.usernameParam = this.readParameter("USERNAME", false); + if (this.inAnApplet && (string = this.readParameter("Open New Window", false)) != null && string.equalsIgnoreCase("Yes")) { + this.inSeparateFrame = true; + } + this.showControls = true; + string = this.readParameter("Show Controls", false); + if (string != null && string.equalsIgnoreCase("No")) { + this.showControls = false; + } + this.offerRelogin = true; + string = this.readParameter("Offer Relogin", false); + if (string != null && string.equalsIgnoreCase("No")) { + this.offerRelogin = false; + } + this.showOfflineDesktop = false; + string = this.readParameter("Show Offline Desktop", false); + if (string != null && string.equalsIgnoreCase("Yes")) { + this.showOfflineDesktop = true; + } + this.deferScreenUpdates = this.readIntParameter("Defer screen updates", 20); + this.deferCursorUpdates = this.readIntParameter("Defer cursor updates", 10); + this.deferUpdateRequests = this.readIntParameter("Defer update requests", 50); + this.socketFactory = this.readParameter("SocketFactory", false); + } + + private void readPasswordParameters() { + String string = this.readParameter("ENCPASSWORD", false); + if (string == null) { + this.passwordParam = this.readParameter("PASSWORD", false); + } else { + Object object; + byte[] byArray = new byte[]{0, 0, 0, 0, 0, 0, 0, 0}; + int n = string.length() / 2; + if (n > 8) { + n = 8; + } + for (int i = 0; i < n; ++i) { + object = string.substring(i * 2, i * 2 + 2); + Integer n2 = new Integer(Integer.parseInt((String)object, 16)); + byArray[i] = n2.byteValue(); + } + byte[] byArray2 = new byte[]{23, 82, 107, 6, 35, 78, 88, 7}; + object = new DesCipher(byArray2); + ((DesCipher)object).decrypt(byArray, 0, byArray, 0); + this.passwordParam = new String(byArray); + } + } + + public String readParameter(String string, boolean bl) { + if (this.inAnApplet) { + String string2 = this.getParameter(string); + if (string2 == null && bl) { + this.fatalError(string + " parameter not specified"); + } + return string2; + } + for (int i = 0; i < this.mainArgs.length; i += 2) { + if (!this.mainArgs[i].equalsIgnoreCase(string)) continue; + try { + return this.mainArgs[i + 1]; + } + catch (Exception exception) { + if (bl) { + this.fatalError(string + " parameter not specified"); + } + return null; + } + } + if (bl) { + this.fatalError(string + " parameter not specified"); + } + return null; + } + + int readIntParameter(String string, int n) { + String string2 = this.readParameter(string, false); + int n2 = n; + if (string2 != null) { + try { + n2 = Integer.parseInt(string2); + } + catch (NumberFormatException numberFormatException) { + // empty catch block + } + } + return n2; + } + + void moveFocusToDesktop() { + if (this.vncContainer != null && this.vc != null && this.vncContainer.isAncestorOf(this.vc)) { + this.vc.requestFocus(); + } + } + + public synchronized void disconnect() { + System.out.println("Disconnect"); + if (this.rfb != null && !this.rfb.closed()) { + this.rfb.close(); + } + this.options.dispose(); + this.clipboard.dispose(); + this.rfbThread = null; + if (this.rec != null) { + this.rec.dispose(); + } + if (this.inAnApplet) { + this.showMessage("Disconnected"); + } else if (this.inSeparateFrame) { + System.exit(0); + } else { + this.buttonPanel.disableButtonsOnDisconnect(); + } + } + + public synchronized void fatalError(String string) { + System.out.println(string); + if (this.inAnApplet) { + Thread.currentThread().stop(); + } else if (!this.inSeparateFrame) { + this.showConnectionStatus(string); + } else { + System.exit(1); + } + } + + public synchronized void fatalError(String string, Exception exception) { + if (this.rfb != null && this.rfb.closed()) { + System.out.println("RFB thread finished"); + return; + } + System.out.println(string); + exception.printStackTrace(); + if (this.rfb != null) { + this.rfb.close(); + } + if (this.inAnApplet) { + this.showMessage(string); + } else if (!this.inSeparateFrame) { + this.showConnectionStatus(string); + } else { + System.exit(1); + } + } + + void showMessage(String string) { + this.vncContainer.removeAll(); + Label label = new Label(string, 1); + label.setFont(new Font("Helvetica", 0, 12)); + if (this.offerRelogin) { + Panel panel = new Panel(new GridLayout(0, 1)); + Panel panel2 = new Panel(new FlowLayout(0)); + panel2.add(panel); + this.vncContainer.setLayout(new FlowLayout(0, 30, 16)); + this.vncContainer.add(panel2); + Panel panel3 = new Panel(new FlowLayout(1)); + panel3.add(label); + panel.add(panel3); + panel.add(new ReloginPanel(this)); + } else { + this.vncContainer.setLayout(new FlowLayout(0, 30, 30)); + this.vncContainer.add(label); + } + if (this.inSeparateFrame) { + this.vncFrame.pack(); + } else { + this.validate(); + } + } + + public void stop() { + System.out.println("Stopping applet"); + this.rfbThread = null; + } + + public void destroy() { + System.out.println("Destroying applet"); + this.vncContainer.removeAll(); + this.options.dispose(); + this.clipboard.dispose(); + if (this.rec != null) { + this.rec.dispose(); + } + if (this.rfb != null && !this.rfb.closed()) { + this.rfb.close(); + } + if (this.inSeparateFrame) { + this.vncFrame.dispose(); + } + } + + public void enableInput(boolean bl) { + this.vc.enableInput(bl); + } + + public void windowClosing(WindowEvent windowEvent) { + System.out.println("Closing window"); + if (this.rfb != null) { + this.disconnect(); + } + this.vncContainer.hide(); + if (!this.inAnApplet) { + System.exit(0); + } + } + + public void windowActivated(WindowEvent windowEvent) { + } + + public void windowDeactivated(WindowEvent windowEvent) { + } + + public void windowOpened(WindowEvent windowEvent) { + } + + public void windowClosed(WindowEvent windowEvent) { + } + + public void windowIconified(WindowEvent windowEvent) { + } + + public void windowDeiconified(WindowEvent windowEvent) { + } +} + diff --git a/src/VncViewersList.java b/src/VncViewersList.java new file mode 100644 index 0000000..9ada75e --- /dev/null +++ b/src/VncViewersList.java @@ -0,0 +1,315 @@ +/* + * Decompiled with CFR 0.152. + * + * Could not load the following classes: + * net.n3.nanoxml.IXMLElement + * net.n3.nanoxml.IXMLParser + * net.n3.nanoxml.IXMLReader + * net.n3.nanoxml.StdXMLReader + * net.n3.nanoxml.XMLElement + * net.n3.nanoxml.XMLParserFactory + * net.n3.nanoxml.XMLWriter + */ +import java.awt.Button; +import java.awt.Container; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintWriter; +import java.io.Writer; +import java.net.URL; +import java.util.AbstractList; +import java.util.Enumeration; +import java.util.ListIterator; +import java.util.Vector; +import net.n3.nanoxml.IXMLElement; +import net.n3.nanoxml.IXMLParser; +import net.n3.nanoxml.IXMLReader; +import net.n3.nanoxml.StdXMLReader; +import net.n3.nanoxml.XMLElement; +import net.n3.nanoxml.XMLParserFactory; +import net.n3.nanoxml.XMLWriter; + +class VncViewersList +extends Vector { + private VncThumbnailViewer tnViewer; + + public VncViewersList(VncThumbnailViewer vncThumbnailViewer) { + this.tnViewer = vncThumbnailViewer; + } + + public static boolean isHostsFileEncrypted(String string) { + boolean bl = false; + try { + String string2; + File file = new File(string); + URL uRL = file.toURL(); + string = uRL.getPath(); + IXMLParser iXMLParser = XMLParserFactory.createDefaultXMLParser(); + IXMLReader iXMLReader = StdXMLReader.fileReader((String)string); + iXMLParser.setReader(iXMLReader); + IXMLElement iXMLElement = (IXMLElement)iXMLParser.parse(); + if (iXMLElement.getFullName().equalsIgnoreCase("Manifest") && Integer.parseInt(string2 = iXMLElement.getAttribute("Encrypted", "0")) == 1) { + bl = true; + } + } + catch (Exception exception) { + System.out.println("Error testing file for encryption."); + System.out.println(exception.getMessage()); + } + return bl; + } + + public void loadHosts(String string, String string2) { + try { + File file = new File(string); + URL uRL = file.toURL(); + string = uRL.getPath(); + IXMLParser iXMLParser = XMLParserFactory.createDefaultXMLParser(); + IXMLReader iXMLReader = StdXMLReader.fileReader((String)string); + iXMLParser.setReader(iXMLReader); + IXMLElement iXMLElement = (IXMLElement)iXMLParser.parse(); + if (iXMLElement.getFullName().equalsIgnoreCase("Manifest")) { + boolean bl = 1 == Integer.parseInt(iXMLElement.getAttribute("Encrypted", "0")); + float f = Float.parseFloat(iXMLElement.getAttribute("Version", "0.9")); + System.out.println("Loading file... file format version " + f + " encrypted(" + bl + ")"); + if (bl && string2 == null) { + System.out.println("ERROR: Password needed to properly read file."); + } + Enumeration enumeration = iXMLElement.enumerateChildren(); + while (enumeration.hasMoreElements()) { + IXMLElement iXMLElement2 = (IXMLElement)enumeration.nextElement(); + if (iXMLElement2.getFullName().equalsIgnoreCase("Connection")) { + boolean bl2 = this.parseConnection(iXMLElement2, bl, string2); + continue; + } + System.out.println("Load: Ignoring " + iXMLElement2.getFullName()); + } + } else { + System.out.println("Malformed file, missing manifest tag."); + System.out.println("Found " + iXMLElement.getFullName()); + } + } + catch (Exception exception) { + System.out.println("Error loading file.\n" + exception.getMessage()); + } + } + + private boolean parseConnection(IXMLElement iXMLElement, boolean bl, String string) { + String string2 = iXMLElement.getAttribute("Host", null); + String string3 = iXMLElement.getAttribute("Port", null); + boolean bl2 = true; + if (string3 == null || string2 == null) { + System.out.println("Missing Host or Port attribute"); + bl2 = false; + } else { + int n = Integer.parseInt(string3); + int n2 = Integer.parseInt(iXMLElement.getAttribute("SecType", "1")); + String string4 = iXMLElement.getAttribute("Password", null); + String string5 = iXMLElement.getAttribute("Username", null); + String string6 = iXMLElement.getAttribute("UserDomain", null); + String string7 = iXMLElement.getAttribute("CompName", null); + String string8 = iXMLElement.getAttribute("Comment", null); + if (bl) { + if (string4 != null) { + string4 = DesCipher.decryptData(string4, string); + } + if (string5 != null) { + string5 = DesCipher.decryptData(string5, string); + } + if (string6 != null) { + string6 = DesCipher.decryptData(string6, string); + } + if (string7 != null) { + string7 = DesCipher.decryptData(string7, string); + } + if (string8 != null) { + string8 = DesCipher.decryptData(string8, string); + } + } + switch (n2) { + case 1: { + if (string4 != null || string5 != null) { + System.out.println("WARNING: Password or Username specified for NoAuth"); + } + } + case 2: { + if (string4 == null) { + System.out.println("ERROR: Password missing for VncAuth"); + bl2 = false; + } + if (string5 == null) break; + System.out.println("WARNING: Username specified for VncAuth"); + break; + } + case -6: { + if (string4 != null && string5 == null) break; + System.out.println("ERROR: Password or Username missing for MsAuth"); + bl2 = false; + break; + } + case 5: + case 6: + case 16: + case 17: + case 18: + case 19: { + System.out.println("ERROR: Incomplete security type (" + n2 + ") for Host: " + string2 + " Port: " + n); + } + default: { + bl2 = false; + } + } + System.out.println("LOAD Host: " + string2 + " Port: " + n + " SecType: " + n2); + if (bl2 && this.getViewer(string2, n) == null) { + VncViewer vncViewer = this.launchViewer(string2, n, string4, string5, string6); + } + } + return bl2; + } + + public void saveToEncryptedFile(String string, String string2) { + if (string2 == null || string2.length() == 0) { + System.out.println("WARNING: Saving to encrypted file with empty passkey"); + } + this.saveHosts(true, string, string2); + } + + public void saveToFile(String string) { + this.saveHosts(false, string, null); + } + + private void saveHosts(boolean bl, String string, String string2) { + String string3; + Object object; + XMLElement xMLElement = new XMLElement("Manifest"); + xMLElement.setAttribute("Encrypted", bl ? "1" : "0"); + xMLElement.setAttribute("Version", Float.toString(1.4f)); + ListIterator listIterator = ((AbstractList)this).listIterator(); + while (listIterator.hasNext()) { + object = (VncViewer)listIterator.next(); + string3 = ((VncViewer)object).host; + String string4 = Integer.toString(((VncViewer)object).port); + String string5 = ((VncViewer)object).passwordParam; + String string6 = ((VncViewer)object).usernameParam; + String string7 = "1"; + if (string5 != null && string5.length() != 0) { + string7 = "2"; + if (string6 != null && string6.length() != 0) { + string7 = "-6"; + } + } + if (bl) { + if (string7 != "1") { + string5 = DesCipher.encryptData(string5, string2); + } + if (string7 == "-6") { + string6 = DesCipher.encryptData(string6, string2); + } + } + IXMLElement iXMLElement = xMLElement.createElement("Connection"); + xMLElement.addChild(iXMLElement); + iXMLElement.setAttribute("Host", string3); + iXMLElement.setAttribute("Port", string4); + iXMLElement.setAttribute("SecType", string7); + if (string7 != "2" && string7 != "-6") continue; + iXMLElement.setAttribute("Password", string5); + if (string7 != "-6") continue; + iXMLElement.setAttribute("Username", string6); + } + try { + object = new PrintWriter(new FileOutputStream(string)); + string3 = new XMLWriter((Writer)object); + ((PrintWriter)object).println(""); + string3.write((IXMLElement)xMLElement, true); + } + catch (IOException iOException) { + System.out.print("Error saving file.\n" + iOException.getMessage()); + } + } + + public VncViewer launchViewer(String string, int n, String string2, String string3, String string4) { + VncViewer vncViewer = VncViewersList.launchViewer(this.tnViewer, string, n, string2, string3, string4); + this.add(vncViewer); + this.tnViewer.addViewer(vncViewer); + return vncViewer; + } + + public static VncViewer launchViewer(VncThumbnailViewer vncThumbnailViewer, String string, int n, String string2, String string3, String string4) { + String[] stringArray; + int n2; + String[] stringArray2 = new String[]{"host", string, "port", Integer.toString(n)}; + if (string2 != null && string2.length() != 0) { + n2 = stringArray2.length + 2; + stringArray = new String[n2]; + System.arraycopy(stringArray2, 0, stringArray, 0, n2 - 2); + stringArray[n2 - 2] = "password"; + stringArray[n2 - 1] = string2; + stringArray2 = stringArray; + } + if (string3 != null && string3.length() != 0) { + n2 = stringArray2.length + 2; + stringArray = new String[n2]; + System.arraycopy(stringArray2, 0, stringArray, 0, n2 - 2); + stringArray[n2 - 2] = "username"; + stringArray[n2 - 1] = string3; + stringArray2 = stringArray; + } + if (string4 != null && string4.length() != 0) { + n2 = stringArray2.length + 2; + stringArray = new String[n2]; + System.arraycopy(stringArray2, 0, stringArray, 0, n2 - 2); + stringArray[n2 - 2] = "userdomain"; + stringArray[n2 - 1] = string4; + stringArray2 = stringArray; + } + System.out.println("Launch Host: " + string + ":" + n); + VncViewer vncViewer = new VncViewer(); + vncViewer.mainArgs = stringArray2; + vncViewer.inAnApplet = false; + vncViewer.inSeparateFrame = false; + vncViewer.showControls = true; + vncViewer.showOfflineDesktop = true; + vncViewer.vncFrame = vncThumbnailViewer; + vncViewer.init(); + vncViewer.options.viewOnly = true; + vncViewer.options.autoScale = true; + vncViewer.options.scalingFactor = 10; + vncViewer.addContainerListener(vncThumbnailViewer); + vncViewer.start(); + return vncViewer; + } + + public VncViewer getViewer(String string, int n) { + VncViewer vncViewer = null; + ListIterator listIterator = ((AbstractList)this).listIterator(); + while (listIterator.hasNext()) { + vncViewer = (VncViewer)listIterator.next(); + if (vncViewer.host != string || vncViewer.port != n) continue; + return vncViewer; + } + return null; + } + + public VncViewer getViewer(Container container) { + VncViewer vncViewer = null; + ListIterator listIterator = ((AbstractList)this).listIterator(); + while (listIterator.hasNext()) { + vncViewer = (VncViewer)listIterator.next(); + if (!container.isAncestorOf(vncViewer)) continue; + return vncViewer; + } + return null; + } + + public VncViewer getViewer(Button button) { + ListIterator listIterator = ((AbstractList)this).listIterator(); + while (listIterator.hasNext()) { + VncViewer vncViewer = (VncViewer)listIterator.next(); + if (!vncViewer.getParent().isAncestorOf(button)) continue; + return vncViewer; + } + return null; + } +} + diff --git a/src/ZlibInStream.java b/src/ZlibInStream.java new file mode 100644 index 0000000..8c2523d --- /dev/null +++ b/src/ZlibInStream.java @@ -0,0 +1,97 @@ +/* + * Decompiled with CFR 0.152. + */ +import java.util.zip.DataFormatException; +import java.util.zip.Inflater; + +public class ZlibInStream +extends InStream { + static final int defaultBufSize = 16384; + private InStream underlying; + private int bufSize; + private int ptrOffset; + private Inflater inflater; + private int bytesIn; + + public ZlibInStream(int n) { + this.bufSize = n; + this.b = new byte[this.bufSize]; + this.ptrOffset = 0; + this.end = 0; + this.ptr = 0; + this.inflater = new Inflater(); + } + + public ZlibInStream() { + this(16384); + } + + public void setUnderlying(InStream inStream, int n) { + this.underlying = inStream; + this.bytesIn = n; + this.end = 0; + this.ptr = 0; + } + + public void reset() throws Exception { + this.end = 0; + this.ptr = 0; + if (this.underlying == null) { + return; + } + while (this.bytesIn > 0) { + this.decompress(); + this.end = 0; + } + this.underlying = null; + } + + public int pos() { + return this.ptrOffset + this.ptr; + } + + protected int overrun(int n, int n2) throws Exception { + if (n > this.bufSize) { + throw new Exception("ZlibInStream overrun: max itemSize exceeded"); + } + if (this.underlying == null) { + throw new Exception("ZlibInStream overrun: no underlying stream"); + } + if (this.end - this.ptr != 0) { + System.arraycopy(this.b, this.ptr, this.b, 0, this.end - this.ptr); + } + this.ptrOffset += this.ptr; + this.end -= this.ptr; + this.ptr = 0; + while (this.end < n) { + this.decompress(); + } + if (n * n2 > this.end) { + n2 = this.end / n; + } + return n2; + } + + private void decompress() throws Exception { + try { + this.underlying.check(1); + int n = this.underlying.getend() - this.underlying.getptr(); + if (n > this.bytesIn) { + n = this.bytesIn; + } + if (this.inflater.needsInput()) { + this.inflater.setInput(this.underlying.getbuf(), this.underlying.getptr(), n); + } + int n2 = this.inflater.inflate(this.b, this.end, this.bufSize - this.end); + this.end += n2; + if (this.inflater.needsInput()) { + this.bytesIn -= n; + this.underlying.setptr(this.underlying.getptr() + n); + } + } + catch (DataFormatException dataFormatException) { + throw new Exception("ZlibInStream: inflate failed"); + } + } +} + diff --git a/src/net/n3/nanoxml/CDATAReader.java b/src/net/n3/nanoxml/CDATAReader.java new file mode 100644 index 0000000..dc7f21d --- /dev/null +++ b/src/net/n3/nanoxml/CDATAReader.java @@ -0,0 +1,91 @@ +/* + * Decompiled with CFR 0.152. + * + * Could not load the following classes: + * net.n3.nanoxml.CDATAReader + * net.n3.nanoxml.IXMLReader + */ +package net.n3.nanoxml; + +import java.io.IOException; +import java.io.Reader; +import net.n3.nanoxml.IXMLReader; + +class CDATAReader +extends Reader { + private IXMLReader reader; + private char savedChar; + private boolean atEndOfData; + + CDATAReader(IXMLReader iXMLReader) { + this.reader = iXMLReader; + this.savedChar = '\u0000'; + this.atEndOfData = false; + } + + protected void finalize() throws Throwable { + this.reader = null; + super.finalize(); + } + + public int read(char[] cArray, int n, int n2) throws IOException { + int n3 = 0; + if (this.atEndOfData) { + return -1; + } + if (n + n2 > cArray.length) { + n2 = cArray.length - n; + } + while (n3 < n2) { + char c = this.savedChar; + if (c == '\u0000') { + c = this.reader.read(); + } else { + this.savedChar = '\u0000'; + } + if (c == ']') { + char c2 = this.reader.read(); + if (c2 == ']') { + char c3 = this.reader.read(); + if (c3 == '>') { + this.atEndOfData = true; + break; + } + this.savedChar = c2; + this.reader.unread(c3); + } else { + this.reader.unread(c2); + } + } + cArray[n3] = c; + ++n3; + } + if (n3 == 0) { + n3 = -1; + } + return n3; + } + + public void close() throws IOException { + while (!this.atEndOfData) { + char c = this.savedChar; + if (c == '\u0000') { + c = this.reader.read(); + } else { + this.savedChar = '\u0000'; + } + if (c != ']') continue; + char c2 = this.reader.read(); + if (c2 == ']') { + char c3 = this.reader.read(); + if (c3 == '>') break; + this.savedChar = c2; + this.reader.unread(c3); + continue; + } + this.reader.unread(c2); + } + this.atEndOfData = true; + } +} + diff --git a/src/net/n3/nanoxml/ContentReader.java b/src/net/n3/nanoxml/ContentReader.java new file mode 100644 index 0000000..a880c68 --- /dev/null +++ b/src/net/n3/nanoxml/ContentReader.java @@ -0,0 +1,111 @@ +/* + * Decompiled with CFR 0.152. + * + * Could not load the following classes: + * net.n3.nanoxml.ContentReader + * net.n3.nanoxml.IXMLEntityResolver + * net.n3.nanoxml.IXMLReader + * net.n3.nanoxml.XMLParseException + * net.n3.nanoxml.XMLUtil + */ +package net.n3.nanoxml; + +import java.io.IOException; +import java.io.Reader; +import net.n3.nanoxml.IXMLEntityResolver; +import net.n3.nanoxml.IXMLReader; +import net.n3.nanoxml.XMLParseException; +import net.n3.nanoxml.XMLUtil; + +class ContentReader +extends Reader { + private IXMLReader reader; + private String buffer; + private int bufferIndex; + private IXMLEntityResolver resolver; + + ContentReader(IXMLReader iXMLReader, IXMLEntityResolver iXMLEntityResolver, String string) { + this.reader = iXMLReader; + this.resolver = iXMLEntityResolver; + this.buffer = string; + this.bufferIndex = 0; + } + + protected void finalize() throws Throwable { + this.reader = null; + this.resolver = null; + this.buffer = null; + super.finalize(); + } + + public int read(char[] cArray, int n, int n2) throws IOException { + try { + int n3 = 0; + int n4 = this.buffer.length(); + if (n + n2 > cArray.length) { + n2 = cArray.length - n; + } + while (n3 < n2) { + char c; + String string = ""; + if (this.bufferIndex < n4) { + c = this.buffer.charAt(this.bufferIndex); + ++this.bufferIndex; + cArray[n3] = c; + ++n3; + continue; + } + string = XMLUtil.read((IXMLReader)this.reader, (char)'&'); + c = string.charAt(0); + if (c == '<') { + this.reader.unread(c); + break; + } + if (c == '&' && string.length() > 1) { + if (string.charAt(1) == '#') { + c = XMLUtil.processCharLiteral((String)string); + } else { + XMLUtil.processEntity((String)string, (IXMLReader)this.reader, (IXMLEntityResolver)this.resolver); + continue; + } + } + cArray[n3] = c; + ++n3; + } + if (n3 == 0) { + n3 = -1; + } + return n3; + } + catch (XMLParseException xMLParseException) { + throw new IOException(xMLParseException.getMessage()); + } + } + + public void close() throws IOException { + try { + int n = this.buffer.length(); + while (true) { + char c; + String string = ""; + if (this.bufferIndex < n) { + c = this.buffer.charAt(this.bufferIndex); + ++this.bufferIndex; + continue; + } + string = XMLUtil.read((IXMLReader)this.reader, (char)'&'); + c = string.charAt(0); + if (c == '<') { + this.reader.unread(c); + break; + } + if (c != '&' || string.length() <= 1 || string.charAt(1) == '#') continue; + XMLUtil.processEntity((String)string, (IXMLReader)this.reader, (IXMLEntityResolver)this.resolver); + } + } + catch (XMLParseException xMLParseException) { + throw new IOException(xMLParseException.getMessage()); + } + } +} + diff --git a/src/net/n3/nanoxml/IXMLBuilder.java b/src/net/n3/nanoxml/IXMLBuilder.java new file mode 100644 index 0000000..8a7c504 --- /dev/null +++ b/src/net/n3/nanoxml/IXMLBuilder.java @@ -0,0 +1,28 @@ +/* + * Decompiled with CFR 0.152. + * + * Could not load the following classes: + * net.n3.nanoxml.IXMLBuilder + */ +package net.n3.nanoxml; + +import java.io.Reader; + +public interface IXMLBuilder { + public void startBuilding(String var1, int var2) throws Exception; + + public void newProcessingInstruction(String var1, Reader var2) throws Exception; + + public void startElement(String var1, String var2, String var3, String var4, int var5) throws Exception; + + public void addAttribute(String var1, String var2, String var3, String var4, String var5) throws Exception; + + public void elementAttributesProcessed(String var1, String var2, String var3) throws Exception; + + public void endElement(String var1, String var2, String var3) throws Exception; + + public void addPCData(Reader var1, String var2, int var3) throws Exception; + + public Object getResult() throws Exception; +} + diff --git a/src/net/n3/nanoxml/IXMLElement.java b/src/net/n3/nanoxml/IXMLElement.java new file mode 100644 index 0000000..58bc50f --- /dev/null +++ b/src/net/n3/nanoxml/IXMLElement.java @@ -0,0 +1,112 @@ +/* + * Decompiled with CFR 0.152. + * + * Could not load the following classes: + * net.n3.nanoxml.IXMLElement + */ +package net.n3.nanoxml; + +import java.util.Enumeration; +import java.util.Properties; +import java.util.Vector; + +public interface IXMLElement { + public static final int NO_LINE = -1; + + public IXMLElement createPCDataElement(); + + public IXMLElement createElement(String var1); + + public IXMLElement createElement(String var1, String var2, int var3); + + public IXMLElement createElement(String var1, String var2); + + public IXMLElement createElement(String var1, String var2, String var3, int var4); + + public IXMLElement getParent(); + + public String getFullName(); + + public String getName(); + + public String getNamespace(); + + public void setName(String var1); + + public void setName(String var1, String var2); + + public void addChild(IXMLElement var1); + + public void removeChild(IXMLElement var1); + + public void removeChildAtIndex(int var1); + + public Enumeration enumerateChildren(); + + public boolean isLeaf(); + + public boolean hasChildren(); + + public int getChildrenCount(); + + public Vector getChildren(); + + public IXMLElement getChildAtIndex(int var1) throws ArrayIndexOutOfBoundsException; + + public IXMLElement getFirstChildNamed(String var1); + + public IXMLElement getFirstChildNamed(String var1, String var2); + + public Vector getChildrenNamed(String var1); + + public Vector getChildrenNamed(String var1, String var2); + + public int getAttributeCount(); + + public String getAttribute(String var1); + + public String getAttribute(String var1, String var2); + + public String getAttribute(String var1, String var2, String var3); + + public int getAttribute(String var1, int var2); + + public int getAttribute(String var1, String var2, int var3); + + public String getAttributeType(String var1); + + public String getAttributeNamespace(String var1); + + public String getAttributeType(String var1, String var2); + + public void setAttribute(String var1, String var2); + + public void setAttribute(String var1, String var2, String var3); + + public void removeAttribute(String var1); + + public void removeAttribute(String var1, String var2); + + public Enumeration enumerateAttributeNames(); + + public boolean hasAttribute(String var1); + + public boolean hasAttribute(String var1, String var2); + + public Properties getAttributes(); + + public Properties getAttributesInNamespace(String var1); + + public String getSystemID(); + + public int getLineNr(); + + public String getContent(); + + public void setContent(String var1); + + public boolean equals(Object var1); + + public boolean equalsXMLElement(IXMLElement var1); +} + diff --git a/src/net/n3/nanoxml/IXMLEntityResolver.java b/src/net/n3/nanoxml/IXMLEntityResolver.java new file mode 100644 index 0000000..0123f3f --- /dev/null +++ b/src/net/n3/nanoxml/IXMLEntityResolver.java @@ -0,0 +1,24 @@ +/* + * Decompiled with CFR 0.152. + * + * Could not load the following classes: + * net.n3.nanoxml.IXMLEntityResolver + * net.n3.nanoxml.IXMLReader + * net.n3.nanoxml.XMLParseException + */ +package net.n3.nanoxml; + +import java.io.Reader; +import net.n3.nanoxml.IXMLReader; +import net.n3.nanoxml.XMLParseException; + +public interface IXMLEntityResolver { + public void addInternalEntity(String var1, String var2); + + public void addExternalEntity(String var1, String var2, String var3); + + public Reader getEntity(IXMLReader var1, String var2) throws XMLParseException; + + public boolean isExternalEntity(String var1); +} + diff --git a/src/net/n3/nanoxml/IXMLParser.java b/src/net/n3/nanoxml/IXMLParser.java new file mode 100644 index 0000000..86b4ded --- /dev/null +++ b/src/net/n3/nanoxml/IXMLParser.java @@ -0,0 +1,39 @@ +/* + * Decompiled with CFR 0.152. + * + * Could not load the following classes: + * net.n3.nanoxml.IXMLBuilder + * net.n3.nanoxml.IXMLEntityResolver + * net.n3.nanoxml.IXMLParser + * net.n3.nanoxml.IXMLReader + * net.n3.nanoxml.IXMLValidator + * net.n3.nanoxml.XMLException + */ +package net.n3.nanoxml; + +import net.n3.nanoxml.IXMLBuilder; +import net.n3.nanoxml.IXMLEntityResolver; +import net.n3.nanoxml.IXMLReader; +import net.n3.nanoxml.IXMLValidator; +import net.n3.nanoxml.XMLException; + +public interface IXMLParser { + public void setReader(IXMLReader var1); + + public IXMLReader getReader(); + + public void setBuilder(IXMLBuilder var1); + + public IXMLBuilder getBuilder(); + + public void setValidator(IXMLValidator var1); + + public IXMLValidator getValidator(); + + public void setResolver(IXMLEntityResolver var1); + + public IXMLEntityResolver getResolver(); + + public Object parse() throws XMLException; +} + diff --git a/src/net/n3/nanoxml/IXMLReader.java b/src/net/n3/nanoxml/IXMLReader.java new file mode 100644 index 0000000..f0c41b1 --- /dev/null +++ b/src/net/n3/nanoxml/IXMLReader.java @@ -0,0 +1,41 @@ +/* + * Decompiled with CFR 0.152. + * + * Could not load the following classes: + * net.n3.nanoxml.IXMLReader + */ +package net.n3.nanoxml; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.Reader; +import java.net.MalformedURLException; + +public interface IXMLReader { + public char read() throws IOException; + + public boolean atEOFOfCurrentStream() throws IOException; + + public boolean atEOF() throws IOException; + + public void unread(char var1) throws IOException; + + public int getLineNr(); + + public Reader openStream(String var1, String var2) throws MalformedURLException, FileNotFoundException, IOException; + + public void startNewStream(Reader var1); + + public void startNewStream(Reader var1, boolean var2); + + public int getStreamLevel(); + + public void setSystemID(String var1) throws MalformedURLException; + + public void setPublicID(String var1); + + public String getSystemID(); + + public String getPublicID(); +} + diff --git a/src/net/n3/nanoxml/IXMLValidator.java b/src/net/n3/nanoxml/IXMLValidator.java new file mode 100644 index 0000000..7468f42 --- /dev/null +++ b/src/net/n3/nanoxml/IXMLValidator.java @@ -0,0 +1,32 @@ +/* + * Decompiled with CFR 0.152. + * + * Could not load the following classes: + * net.n3.nanoxml.IXMLEntityResolver + * net.n3.nanoxml.IXMLReader + * net.n3.nanoxml.IXMLValidator + */ +package net.n3.nanoxml; + +import java.util.Properties; +import net.n3.nanoxml.IXMLEntityResolver; +import net.n3.nanoxml.IXMLReader; + +public interface IXMLValidator { + public void setParameterEntityResolver(IXMLEntityResolver var1); + + public IXMLEntityResolver getParameterEntityResolver(); + + public void parseDTD(String var1, IXMLReader var2, IXMLEntityResolver var3, boolean var4) throws Exception; + + public void elementStarted(String var1, String var2, int var3) throws Exception; + + public void elementEnded(String var1, String var2, int var3) throws Exception; + + public void attributeAdded(String var1, String var2, String var3, int var4) throws Exception; + + public void elementAttributesProcessed(String var1, Properties var2, String var3, int var4) throws Exception; + + public void PCDataAdded(String var1, int var2) throws Exception; +} + diff --git a/src/net/n3/nanoxml/NonValidator.java b/src/net/n3/nanoxml/NonValidator.java new file mode 100644 index 0000000..a38ede0 --- /dev/null +++ b/src/net/n3/nanoxml/NonValidator.java @@ -0,0 +1,354 @@ +/* + * Decompiled with CFR 0.152. + * + * Could not load the following classes: + * net.n3.nanoxml.CDATAReader + * net.n3.nanoxml.IXMLEntityResolver + * net.n3.nanoxml.IXMLReader + * net.n3.nanoxml.IXMLValidator + * net.n3.nanoxml.NonValidator + * net.n3.nanoxml.XMLEntityResolver + * net.n3.nanoxml.XMLUtil + */ +package net.n3.nanoxml; + +import java.io.Reader; +import java.io.StringReader; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Properties; +import java.util.Stack; +import net.n3.nanoxml.CDATAReader; +import net.n3.nanoxml.IXMLEntityResolver; +import net.n3.nanoxml.IXMLReader; +import net.n3.nanoxml.IXMLValidator; +import net.n3.nanoxml.XMLEntityResolver; +import net.n3.nanoxml.XMLUtil; + +public class NonValidator +implements IXMLValidator { + protected IXMLEntityResolver parameterEntityResolver; + protected Hashtable attributeDefaultValues = new Hashtable(); + protected Stack currentElements = new Stack(); + + public NonValidator() { + this.parameterEntityResolver = new XMLEntityResolver(); + } + + protected void finalize() throws Throwable { + this.parameterEntityResolver = null; + this.attributeDefaultValues.clear(); + this.attributeDefaultValues = null; + this.currentElements.clear(); + this.currentElements = null; + super.finalize(); + } + + public void setParameterEntityResolver(IXMLEntityResolver iXMLEntityResolver) { + this.parameterEntityResolver = iXMLEntityResolver; + } + + public IXMLEntityResolver getParameterEntityResolver() { + return this.parameterEntityResolver; + } + + public void parseDTD(String string, IXMLReader iXMLReader, IXMLEntityResolver iXMLEntityResolver, boolean bl) throws Exception { + XMLUtil.skipWhitespace((IXMLReader)iXMLReader, null); + int n = iXMLReader.getStreamLevel(); + while (true) { + String string2; + char c; + if ((c = (string2 = XMLUtil.read((IXMLReader)iXMLReader, (char)'%')).charAt(0)) == '%') { + XMLUtil.processEntity((String)string2, (IXMLReader)iXMLReader, (IXMLEntityResolver)this.parameterEntityResolver); + continue; + } + if (c == '<') { + this.processElement(iXMLReader, iXMLEntityResolver); + } else { + if (c == ']') { + return; + } + XMLUtil.errorInvalidInput((String)iXMLReader.getSystemID(), (int)iXMLReader.getLineNr(), (String)string2); + } + do { + c = iXMLReader.read(); + if (!bl || iXMLReader.getStreamLevel() >= n) continue; + iXMLReader.unread(c); + return; + } while (c == ' ' || c == '\t' || c == '\n' || c == '\r'); + iXMLReader.unread(c); + } + } + + protected void processElement(IXMLReader iXMLReader, IXMLEntityResolver iXMLEntityResolver) throws Exception { + String string = XMLUtil.read((IXMLReader)iXMLReader, (char)'%'); + char c = string.charAt(0); + if (c != '!') { + XMLUtil.skipTag((IXMLReader)iXMLReader); + return; + } + string = XMLUtil.read((IXMLReader)iXMLReader, (char)'%'); + c = string.charAt(0); + switch (c) { + case '-': { + XMLUtil.skipComment((IXMLReader)iXMLReader); + break; + } + case '[': { + this.processConditionalSection(iXMLReader, iXMLEntityResolver); + break; + } + case 'E': { + this.processEntity(iXMLReader, iXMLEntityResolver); + break; + } + case 'A': { + this.processAttList(iXMLReader, iXMLEntityResolver); + break; + } + default: { + XMLUtil.skipTag((IXMLReader)iXMLReader); + } + } + } + + protected void processConditionalSection(IXMLReader iXMLReader, IXMLEntityResolver iXMLEntityResolver) throws Exception { + int n; + XMLUtil.skipWhitespace((IXMLReader)iXMLReader, null); + String string = XMLUtil.read((IXMLReader)iXMLReader, (char)'%'); + char c = string.charAt(0); + if (c != 'I') { + XMLUtil.skipTag((IXMLReader)iXMLReader); + return; + } + string = XMLUtil.read((IXMLReader)iXMLReader, (char)'%'); + c = string.charAt(0); + switch (c) { + case 'G': { + this.processIgnoreSection(iXMLReader, iXMLEntityResolver); + return; + } + case 'N': { + break; + } + default: { + XMLUtil.skipTag((IXMLReader)iXMLReader); + return; + } + } + if (!XMLUtil.checkLiteral((IXMLReader)iXMLReader, (String)"CLUDE")) { + XMLUtil.skipTag((IXMLReader)iXMLReader); + return; + } + XMLUtil.skipWhitespace((IXMLReader)iXMLReader, null); + string = XMLUtil.read((IXMLReader)iXMLReader, (char)'%'); + c = string.charAt(0); + if (c != '[') { + XMLUtil.skipTag((IXMLReader)iXMLReader); + return; + } + CDATAReader cDATAReader = new CDATAReader(iXMLReader); + StringBuffer stringBuffer = new StringBuffer(1024); + while ((n = cDATAReader.read()) >= 0) { + stringBuffer.append((char)n); + } + cDATAReader.close(); + iXMLReader.startNewStream((Reader)new StringReader(stringBuffer.toString())); + } + + protected void processIgnoreSection(IXMLReader iXMLReader, IXMLEntityResolver iXMLEntityResolver) throws Exception { + if (!XMLUtil.checkLiteral((IXMLReader)iXMLReader, (String)"NORE")) { + XMLUtil.skipTag((IXMLReader)iXMLReader); + return; + } + XMLUtil.skipWhitespace((IXMLReader)iXMLReader, null); + String string = XMLUtil.read((IXMLReader)iXMLReader, (char)'%'); + char c = string.charAt(0); + if (c != '[') { + XMLUtil.skipTag((IXMLReader)iXMLReader); + return; + } + CDATAReader cDATAReader = new CDATAReader(iXMLReader); + cDATAReader.close(); + } + + protected void processAttList(IXMLReader iXMLReader, IXMLEntityResolver iXMLEntityResolver) throws Exception { + if (!XMLUtil.checkLiteral((IXMLReader)iXMLReader, (String)"TTLIST")) { + XMLUtil.skipTag((IXMLReader)iXMLReader); + return; + } + XMLUtil.skipWhitespace((IXMLReader)iXMLReader, null); + String string = XMLUtil.read((IXMLReader)iXMLReader, (char)'%'); + char c = string.charAt(0); + while (c == '%') { + XMLUtil.processEntity((String)string, (IXMLReader)iXMLReader, (IXMLEntityResolver)this.parameterEntityResolver); + string = XMLUtil.read((IXMLReader)iXMLReader, (char)'%'); + c = string.charAt(0); + } + iXMLReader.unread(c); + String string2 = XMLUtil.scanIdentifier((IXMLReader)iXMLReader); + XMLUtil.skipWhitespace((IXMLReader)iXMLReader, null); + string = XMLUtil.read((IXMLReader)iXMLReader, (char)'%'); + c = string.charAt(0); + while (c == '%') { + XMLUtil.processEntity((String)string, (IXMLReader)iXMLReader, (IXMLEntityResolver)this.parameterEntityResolver); + string = XMLUtil.read((IXMLReader)iXMLReader, (char)'%'); + c = string.charAt(0); + } + Properties properties = new Properties(); + while (c != '>') { + iXMLReader.unread(c); + String string3 = XMLUtil.scanIdentifier((IXMLReader)iXMLReader); + XMLUtil.skipWhitespace((IXMLReader)iXMLReader, null); + string = XMLUtil.read((IXMLReader)iXMLReader, (char)'%'); + c = string.charAt(0); + while (c == '%') { + XMLUtil.processEntity((String)string, (IXMLReader)iXMLReader, (IXMLEntityResolver)this.parameterEntityResolver); + string = XMLUtil.read((IXMLReader)iXMLReader, (char)'%'); + c = string.charAt(0); + } + if (c == '(') { + while (c != ')') { + string = XMLUtil.read((IXMLReader)iXMLReader, (char)'%'); + c = string.charAt(0); + while (c == '%') { + XMLUtil.processEntity((String)string, (IXMLReader)iXMLReader, (IXMLEntityResolver)this.parameterEntityResolver); + string = XMLUtil.read((IXMLReader)iXMLReader, (char)'%'); + c = string.charAt(0); + } + } + } else { + iXMLReader.unread(c); + XMLUtil.scanIdentifier((IXMLReader)iXMLReader); + } + XMLUtil.skipWhitespace((IXMLReader)iXMLReader, null); + string = XMLUtil.read((IXMLReader)iXMLReader, (char)'%'); + c = string.charAt(0); + while (c == '%') { + XMLUtil.processEntity((String)string, (IXMLReader)iXMLReader, (IXMLEntityResolver)this.parameterEntityResolver); + string = XMLUtil.read((IXMLReader)iXMLReader, (char)'%'); + c = string.charAt(0); + } + if (c == '#') { + string = XMLUtil.scanIdentifier((IXMLReader)iXMLReader); + XMLUtil.skipWhitespace((IXMLReader)iXMLReader, null); + if (!string.equals("FIXED")) { + XMLUtil.skipWhitespace((IXMLReader)iXMLReader, null); + string = XMLUtil.read((IXMLReader)iXMLReader, (char)'%'); + c = string.charAt(0); + while (c == '%') { + XMLUtil.processEntity((String)string, (IXMLReader)iXMLReader, (IXMLEntityResolver)this.parameterEntityResolver); + string = XMLUtil.read((IXMLReader)iXMLReader, (char)'%'); + c = string.charAt(0); + } + continue; + } + } else { + iXMLReader.unread(c); + } + String string4 = XMLUtil.scanString((IXMLReader)iXMLReader, (char)'%', (IXMLEntityResolver)this.parameterEntityResolver); + properties.put(string3, string4); + XMLUtil.skipWhitespace((IXMLReader)iXMLReader, null); + string = XMLUtil.read((IXMLReader)iXMLReader, (char)'%'); + c = string.charAt(0); + while (c == '%') { + XMLUtil.processEntity((String)string, (IXMLReader)iXMLReader, (IXMLEntityResolver)this.parameterEntityResolver); + string = XMLUtil.read((IXMLReader)iXMLReader, (char)'%'); + c = string.charAt(0); + } + } + if (!properties.isEmpty()) { + this.attributeDefaultValues.put(string2, properties); + } + } + + protected void processEntity(IXMLReader iXMLReader, IXMLEntityResolver iXMLEntityResolver) throws Exception { + if (!XMLUtil.checkLiteral((IXMLReader)iXMLReader, (String)"NTITY")) { + XMLUtil.skipTag((IXMLReader)iXMLReader); + return; + } + XMLUtil.skipWhitespace((IXMLReader)iXMLReader, null); + char c = XMLUtil.readChar((IXMLReader)iXMLReader, (char)'\u0000'); + if (c == '%') { + XMLUtil.skipWhitespace((IXMLReader)iXMLReader, null); + iXMLEntityResolver = this.parameterEntityResolver; + } else { + iXMLReader.unread(c); + } + String string = XMLUtil.scanIdentifier((IXMLReader)iXMLReader); + XMLUtil.skipWhitespace((IXMLReader)iXMLReader, null); + c = XMLUtil.readChar((IXMLReader)iXMLReader, (char)'%'); + String string2 = null; + String string3 = null; + switch (c) { + case 'P': { + if (!XMLUtil.checkLiteral((IXMLReader)iXMLReader, (String)"UBLIC")) { + XMLUtil.skipTag((IXMLReader)iXMLReader); + return; + } + XMLUtil.skipWhitespace((IXMLReader)iXMLReader, null); + string3 = XMLUtil.scanString((IXMLReader)iXMLReader, (char)'%', (IXMLEntityResolver)this.parameterEntityResolver); + XMLUtil.skipWhitespace((IXMLReader)iXMLReader, null); + string2 = XMLUtil.scanString((IXMLReader)iXMLReader, (char)'%', (IXMLEntityResolver)this.parameterEntityResolver); + XMLUtil.skipWhitespace((IXMLReader)iXMLReader, null); + XMLUtil.readChar((IXMLReader)iXMLReader, (char)'%'); + break; + } + case 'S': { + if (!XMLUtil.checkLiteral((IXMLReader)iXMLReader, (String)"YSTEM")) { + XMLUtil.skipTag((IXMLReader)iXMLReader); + return; + } + XMLUtil.skipWhitespace((IXMLReader)iXMLReader, null); + string2 = XMLUtil.scanString((IXMLReader)iXMLReader, (char)'%', (IXMLEntityResolver)this.parameterEntityResolver); + XMLUtil.skipWhitespace((IXMLReader)iXMLReader, null); + XMLUtil.readChar((IXMLReader)iXMLReader, (char)'%'); + break; + } + case '\"': + case '\'': { + iXMLReader.unread(c); + String string4 = XMLUtil.scanString((IXMLReader)iXMLReader, (char)'%', (IXMLEntityResolver)this.parameterEntityResolver); + iXMLEntityResolver.addInternalEntity(string, string4); + XMLUtil.skipWhitespace((IXMLReader)iXMLReader, null); + XMLUtil.readChar((IXMLReader)iXMLReader, (char)'%'); + break; + } + default: { + XMLUtil.skipTag((IXMLReader)iXMLReader); + } + } + if (string2 != null) { + iXMLEntityResolver.addExternalEntity(string, string3, string2); + } + } + + public void elementStarted(String string, String string2, int n) { + Properties properties = (Properties)this.attributeDefaultValues.get(string); + properties = properties == null ? new Properties() : (Properties)properties.clone(); + this.currentElements.push(properties); + } + + public void elementEnded(String string, String string2, int n) { + } + + public void elementAttributesProcessed(String string, Properties properties, String string2, int n) { + Properties properties2 = (Properties)this.currentElements.pop(); + Enumeration enumeration = properties2.keys(); + while (enumeration.hasMoreElements()) { + String string3 = (String)enumeration.nextElement(); + properties.put(string3, properties2.get(string3)); + } + } + + public void attributeAdded(String string, String string2, String string3, int n) { + Properties properties = (Properties)this.currentElements.peek(); + if (properties.containsKey(string)) { + properties.remove(string); + } + } + + public void PCDataAdded(String string, int n) { + } +} + diff --git a/src/net/n3/nanoxml/PIReader.java b/src/net/n3/nanoxml/PIReader.java new file mode 100644 index 0000000..77c5135 --- /dev/null +++ b/src/net/n3/nanoxml/PIReader.java @@ -0,0 +1,65 @@ +/* + * Decompiled with CFR 0.152. + * + * Could not load the following classes: + * net.n3.nanoxml.IXMLReader + * net.n3.nanoxml.PIReader + */ +package net.n3.nanoxml; + +import java.io.IOException; +import java.io.Reader; +import net.n3.nanoxml.IXMLReader; + +class PIReader +extends Reader { + private IXMLReader reader; + private boolean atEndOfData; + + PIReader(IXMLReader iXMLReader) { + this.reader = iXMLReader; + this.atEndOfData = false; + } + + protected void finalize() throws Throwable { + this.reader = null; + super.finalize(); + } + + public int read(char[] cArray, int n, int n2) throws IOException { + if (this.atEndOfData) { + return -1; + } + int n3 = 0; + if (n + n2 > cArray.length) { + n2 = cArray.length - n; + } + while (n3 < n2) { + char c = this.reader.read(); + if (c == '?') { + char c2 = this.reader.read(); + if (c2 == '>') { + this.atEndOfData = true; + break; + } + this.reader.unread(c2); + } + cArray[n3] = c; + ++n3; + } + if (n3 == 0) { + n3 = -1; + } + return n3; + } + + public void close() throws IOException { + while (!this.atEndOfData) { + char c; + char c2 = this.reader.read(); + if (c2 != '?' || (c = this.reader.read()) != '>') continue; + this.atEndOfData = true; + } + } +} + diff --git a/src/net/n3/nanoxml/StdXMLBuilder.java b/src/net/n3/nanoxml/StdXMLBuilder.java new file mode 100644 index 0000000..bc1efec --- /dev/null +++ b/src/net/n3/nanoxml/StdXMLBuilder.java @@ -0,0 +1,126 @@ +/* + * Decompiled with CFR 0.152. + * + * Could not load the following classes: + * net.n3.nanoxml.IXMLBuilder + * net.n3.nanoxml.IXMLElement + * net.n3.nanoxml.StdXMLBuilder + * net.n3.nanoxml.XMLElement + * net.n3.nanoxml.XMLParseException + */ +package net.n3.nanoxml; + +import java.io.IOException; +import java.io.Reader; +import java.util.Stack; +import net.n3.nanoxml.IXMLBuilder; +import net.n3.nanoxml.IXMLElement; +import net.n3.nanoxml.XMLElement; +import net.n3.nanoxml.XMLParseException; + +public class StdXMLBuilder +implements IXMLBuilder { + private Stack stack = null; + private IXMLElement root = null; + private IXMLElement prototype; + + public StdXMLBuilder() { + this((IXMLElement)new XMLElement()); + } + + public StdXMLBuilder(IXMLElement iXMLElement) { + this.prototype = iXMLElement; + } + + protected void finalize() throws Throwable { + this.prototype = null; + this.root = null; + this.stack.clear(); + this.stack = null; + super.finalize(); + } + + public void startBuilding(String string, int n) { + this.stack = new Stack(); + this.root = null; + } + + public void newProcessingInstruction(String string, Reader reader) { + } + + public void startElement(String string, String string2, String string3, String string4, int n) { + String string5 = string; + if (string2 != null) { + string5 = string2 + ':' + string; + } + IXMLElement iXMLElement = this.prototype.createElement(string5, string3, string4, n); + if (this.stack.empty()) { + this.root = iXMLElement; + } else { + IXMLElement iXMLElement2 = (IXMLElement)this.stack.peek(); + iXMLElement2.addChild(iXMLElement); + } + this.stack.push(iXMLElement); + } + + public void elementAttributesProcessed(String string, String string2, String string3) { + } + + public void endElement(String string, String string2, String string3) { + IXMLElement iXMLElement; + IXMLElement iXMLElement2 = (IXMLElement)this.stack.pop(); + if (iXMLElement2.getChildrenCount() == 1 && (iXMLElement = iXMLElement2.getChildAtIndex(0)).getName() == null) { + iXMLElement2.setContent(iXMLElement.getContent()); + iXMLElement2.removeChildAtIndex(0); + } + } + + public void addAttribute(String string, String string2, String string3, String string4, String string5) throws Exception { + IXMLElement iXMLElement; + String string6 = string; + if (string2 != null) { + string6 = string2 + ':' + string; + } + if ((iXMLElement = (IXMLElement)this.stack.peek()).hasAttribute(string6)) { + throw new XMLParseException(iXMLElement.getSystemID(), iXMLElement.getLineNr(), "Duplicate attribute: " + string); + } + if (string2 != null) { + iXMLElement.setAttribute(string6, string3, string4); + } else { + iXMLElement.setAttribute(string6, string4); + } + } + + public void addPCData(Reader reader, String string, int n) { + int n2 = 2048; + int n3 = 0; + StringBuffer stringBuffer = new StringBuffer(n2); + char[] cArray = new char[n2]; + while (true) { + int n4; + if (n3 >= n2) { + stringBuffer.ensureCapacity(n2 *= 2); + } + try { + n4 = reader.read(cArray); + } + catch (IOException iOException) { + break; + } + if (n4 < 0) break; + stringBuffer.append(cArray, 0, n4); + n3 += n4; + } + IXMLElement iXMLElement = this.prototype.createElement(null, string, n); + iXMLElement.setContent(stringBuffer.toString()); + if (!this.stack.empty()) { + IXMLElement iXMLElement2 = (IXMLElement)this.stack.peek(); + iXMLElement2.addChild(iXMLElement); + } + } + + public Object getResult() { + return this.root; + } +} + diff --git a/src/net/n3/nanoxml/StdXMLParser.java b/src/net/n3/nanoxml/StdXMLParser.java new file mode 100644 index 0000000..856d558 --- /dev/null +++ b/src/net/n3/nanoxml/StdXMLParser.java @@ -0,0 +1,368 @@ +/* + * Decompiled with CFR 0.152. + * + * Could not load the following classes: + * net.n3.nanoxml.CDATAReader + * net.n3.nanoxml.ContentReader + * net.n3.nanoxml.IXMLBuilder + * net.n3.nanoxml.IXMLEntityResolver + * net.n3.nanoxml.IXMLParser + * net.n3.nanoxml.IXMLReader + * net.n3.nanoxml.IXMLValidator + * net.n3.nanoxml.PIReader + * net.n3.nanoxml.StdXMLParser + * net.n3.nanoxml.XMLEntityResolver + * net.n3.nanoxml.XMLException + * net.n3.nanoxml.XMLUtil + */ +package net.n3.nanoxml; + +import java.io.Reader; +import java.util.Enumeration; +import java.util.Properties; +import java.util.Vector; +import net.n3.nanoxml.CDATAReader; +import net.n3.nanoxml.ContentReader; +import net.n3.nanoxml.IXMLBuilder; +import net.n3.nanoxml.IXMLEntityResolver; +import net.n3.nanoxml.IXMLParser; +import net.n3.nanoxml.IXMLReader; +import net.n3.nanoxml.IXMLValidator; +import net.n3.nanoxml.PIReader; +import net.n3.nanoxml.XMLEntityResolver; +import net.n3.nanoxml.XMLException; +import net.n3.nanoxml.XMLUtil; + +public class StdXMLParser +implements IXMLParser { + private IXMLBuilder builder = null; + private IXMLReader reader = null; + private IXMLEntityResolver entityResolver = new XMLEntityResolver(); + private IXMLValidator validator = null; + + protected void finalize() throws Throwable { + this.builder = null; + this.reader = null; + this.entityResolver = null; + this.validator = null; + super.finalize(); + } + + public void setBuilder(IXMLBuilder iXMLBuilder) { + this.builder = iXMLBuilder; + } + + public IXMLBuilder getBuilder() { + return this.builder; + } + + public void setValidator(IXMLValidator iXMLValidator) { + this.validator = iXMLValidator; + } + + public IXMLValidator getValidator() { + return this.validator; + } + + public void setResolver(IXMLEntityResolver iXMLEntityResolver) { + this.entityResolver = iXMLEntityResolver; + } + + public IXMLEntityResolver getResolver() { + return this.entityResolver; + } + + public void setReader(IXMLReader iXMLReader) { + this.reader = iXMLReader; + } + + public IXMLReader getReader() { + return this.reader; + } + + public Object parse() throws XMLException { + try { + this.builder.startBuilding(this.reader.getSystemID(), this.reader.getLineNr()); + this.scanData(); + return this.builder.getResult(); + } + catch (XMLException xMLException) { + throw xMLException; + } + catch (Exception exception) { + throw new XMLException(exception); + } + } + + protected void scanData() throws Exception { + block4: while (!this.reader.atEOF() && this.builder.getResult() == null) { + String string = XMLUtil.read((IXMLReader)this.reader, (char)'&'); + char c = string.charAt(0); + if (c == '&') { + XMLUtil.processEntity((String)string, (IXMLReader)this.reader, (IXMLEntityResolver)this.entityResolver); + continue; + } + switch (c) { + case '<': { + this.scanSomeTag(false, null, new Properties()); + continue block4; + } + case '\t': + case '\n': + case '\r': + case ' ': { + continue block4; + } + } + XMLUtil.errorInvalidInput((String)this.reader.getSystemID(), (int)this.reader.getLineNr(), (String)("`" + c + "' (0x" + Integer.toHexString(c) + ')')); + } + } + + protected void scanSomeTag(boolean bl, String string, Properties properties) throws Exception { + String string2 = XMLUtil.read((IXMLReader)this.reader, (char)'&'); + char c = string2.charAt(0); + if (c == '&') { + XMLUtil.errorUnexpectedEntity((String)this.reader.getSystemID(), (int)this.reader.getLineNr(), (String)string2); + } + switch (c) { + case '?': { + this.processPI(); + break; + } + case '!': { + this.processSpecialTag(bl); + break; + } + default: { + this.reader.unread(c); + this.processElement(string, properties); + } + } + } + + protected void processPI() throws Exception { + XMLUtil.skipWhitespace((IXMLReader)this.reader, null); + String string = XMLUtil.scanIdentifier((IXMLReader)this.reader); + XMLUtil.skipWhitespace((IXMLReader)this.reader, null); + PIReader pIReader = new PIReader(this.reader); + if (!string.equalsIgnoreCase("xml")) { + this.builder.newProcessingInstruction(string, (Reader)pIReader); + } + pIReader.close(); + } + + protected void processSpecialTag(boolean bl) throws Exception { + String string = XMLUtil.read((IXMLReader)this.reader, (char)'&'); + char c = string.charAt(0); + if (c == '&') { + XMLUtil.errorUnexpectedEntity((String)this.reader.getSystemID(), (int)this.reader.getLineNr(), (String)string); + } + switch (c) { + case '[': { + if (bl) { + this.processCDATA(); + } else { + XMLUtil.errorUnexpectedCDATA((String)this.reader.getSystemID(), (int)this.reader.getLineNr()); + } + return; + } + case 'D': { + this.processDocType(); + return; + } + case '-': { + XMLUtil.skipComment((IXMLReader)this.reader); + return; + } + } + } + + protected void processCDATA() throws Exception { + if (!XMLUtil.checkLiteral((IXMLReader)this.reader, (String)"CDATA[")) { + XMLUtil.errorExpectedInput((String)this.reader.getSystemID(), (int)this.reader.getLineNr(), (String)"') { + XMLUtil.errorExpectedInput((String)this.reader.getSystemID(), (int)this.reader.getLineNr(), (String)"`>'"); + } + if (string != null) { + Reader reader = this.reader.openStream(stringBuffer.toString(), string); + this.reader.startNewStream(reader); + this.reader.setSystemID(string); + this.reader.setPublicID(stringBuffer.toString()); + this.validator.parseDTD(stringBuffer.toString(), this.reader, this.entityResolver, true); + } + } + + protected void processElement(String string, Properties properties) throws Exception { + String string2; + String string3; + int n; + String string4; + char c; + String string5; + String string6 = string5 = XMLUtil.scanIdentifier((IXMLReader)this.reader); + XMLUtil.skipWhitespace((IXMLReader)this.reader, null); + String string7 = null; + int n2 = string6.indexOf(58); + if (n2 > 0) { + string7 = string6.substring(0, n2); + string6 = string6.substring(n2 + 1); + } + Vector vector = new Vector(); + Vector vector2 = new Vector(); + Vector vector3 = new Vector(); + this.validator.elementStarted(string5, this.reader.getSystemID(), this.reader.getLineNr()); + while ((c = this.reader.read()) != '/' && c != '>') { + this.reader.unread(c); + this.processAttribute(vector, vector2, vector3); + XMLUtil.skipWhitespace((IXMLReader)this.reader, null); + } + Properties properties2 = new Properties(); + this.validator.elementAttributesProcessed(string5, properties2, this.reader.getSystemID(), this.reader.getLineNr()); + Enumeration enumeration = properties2.keys(); + while (enumeration.hasMoreElements()) { + String string8 = (String)enumeration.nextElement(); + string4 = properties2.getProperty(string8); + vector.addElement(string8); + vector2.addElement(string4); + vector3.addElement("CDATA"); + } + for (n = 0; n < vector.size(); ++n) { + string4 = (String)vector.elementAt(n); + string3 = (String)vector2.elementAt(n); + string2 = (String)vector3.elementAt(n); + if (string4.equals("xmlns")) { + string = string3; + continue; + } + if (!string4.startsWith("xmlns:")) continue; + properties.put(string4.substring(6), string3); + } + if (string7 == null) { + this.builder.startElement(string6, string7, string, this.reader.getSystemID(), this.reader.getLineNr()); + } else { + this.builder.startElement(string6, string7, properties.getProperty(string7), this.reader.getSystemID(), this.reader.getLineNr()); + } + for (n = 0; n < vector.size(); ++n) { + string4 = (String)vector.elementAt(n); + if (string4.startsWith("xmlns")) continue; + string3 = (String)vector2.elementAt(n); + string2 = (String)vector3.elementAt(n); + n2 = string4.indexOf(58); + if (n2 > 0) { + String string9 = string4.substring(0, n2); + string4 = string4.substring(n2 + 1); + this.builder.addAttribute(string4, string9, properties.getProperty(string9), string3, string2); + continue; + } + this.builder.addAttribute(string4, null, null, string3, string2); + } + if (string7 == null) { + this.builder.elementAttributesProcessed(string6, string7, string); + } else { + this.builder.elementAttributesProcessed(string6, string7, properties.getProperty(string7)); + } + if (c == '/') { + if (this.reader.read() != '>') { + XMLUtil.errorExpectedInput((String)this.reader.getSystemID(), (int)this.reader.getLineNr(), (String)"`>'"); + } + this.validator.elementEnded(string6, this.reader.getSystemID(), this.reader.getLineNr()); + if (string7 == null) { + this.builder.endElement(string6, string7, string); + } else { + this.builder.endElement(string6, string7, properties.getProperty(string7)); + } + return; + } + StringBuffer stringBuffer = new StringBuffer(16); + while (true) { + stringBuffer.setLength(0); + while (true) { + XMLUtil.skipWhitespace((IXMLReader)this.reader, (StringBuffer)stringBuffer); + string4 = XMLUtil.read((IXMLReader)this.reader, (char)'&'); + if (string4.charAt(0) != '&' || string4.charAt(1) == '#') break; + XMLUtil.processEntity((String)string4, (IXMLReader)this.reader, (IXMLEntityResolver)this.entityResolver); + } + if (string4.charAt(0) == '<') { + string4 = XMLUtil.read((IXMLReader)this.reader, (char)'\u0000'); + if (string4.charAt(0) == '/') { + XMLUtil.skipWhitespace((IXMLReader)this.reader, null); + string4 = XMLUtil.scanIdentifier((IXMLReader)this.reader); + if (!string4.equals(string5)) { + XMLUtil.errorWrongClosingTag((String)this.reader.getSystemID(), (int)this.reader.getLineNr(), (String)string6, (String)string4); + } + XMLUtil.skipWhitespace((IXMLReader)this.reader, null); + if (this.reader.read() != '>') { + XMLUtil.errorClosingTagNotEmpty((String)this.reader.getSystemID(), (int)this.reader.getLineNr()); + } + this.validator.elementEnded(string5, this.reader.getSystemID(), this.reader.getLineNr()); + if (string7 == null) { + this.builder.endElement(string6, string7, string); + break; + } + this.builder.endElement(string6, string7, properties.getProperty(string7)); + break; + } + this.reader.unread(string4.charAt(0)); + this.scanSomeTag(true, string, (Properties)properties.clone()); + continue; + } + if (string4.charAt(0) == '&') { + c = XMLUtil.processCharLiteral((String)string4); + stringBuffer.append(c); + } else { + this.reader.unread(string4.charAt(0)); + } + this.validator.PCDataAdded(this.reader.getSystemID(), this.reader.getLineNr()); + string3 = new ContentReader(this.reader, this.entityResolver, stringBuffer.toString()); + this.builder.addPCData((Reader)((Object)string3), this.reader.getSystemID(), this.reader.getLineNr()); + ((Reader)((Object)string3)).close(); + } + } + + protected void processAttribute(Vector vector, Vector vector2, Vector vector3) throws Exception { + String string = XMLUtil.scanIdentifier((IXMLReader)this.reader); + XMLUtil.skipWhitespace((IXMLReader)this.reader, null); + if (!XMLUtil.read((IXMLReader)this.reader, (char)'&').equals("=")) { + XMLUtil.errorExpectedInput((String)this.reader.getSystemID(), (int)this.reader.getLineNr(), (String)"`='"); + } + XMLUtil.skipWhitespace((IXMLReader)this.reader, null); + String string2 = XMLUtil.scanString((IXMLReader)this.reader, (char)'&', (IXMLEntityResolver)this.entityResolver); + vector.addElement(string); + vector2.addElement(string2); + vector3.addElement("CDATA"); + this.validator.attributeAdded(string, string2, this.reader.getSystemID(), this.reader.getLineNr()); + } +} + diff --git a/src/net/n3/nanoxml/StdXMLReader.java b/src/net/n3/nanoxml/StdXMLReader.java new file mode 100644 index 0000000..e9bde3a --- /dev/null +++ b/src/net/n3/nanoxml/StdXMLReader.java @@ -0,0 +1,315 @@ +/* + * Decompiled with CFR 0.152. + * + * Could not load the following classes: + * net.n3.nanoxml.IXMLReader + * net.n3.nanoxml.StdXMLReader + * net.n3.nanoxml.StdXMLReader$StackedReader + */ +package net.n3.nanoxml; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.LineNumberReader; +import java.io.PushbackInputStream; +import java.io.PushbackReader; +import java.io.Reader; +import java.io.StringReader; +import java.io.UnsupportedEncodingException; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Stack; +import net.n3.nanoxml.IXMLReader; +import net.n3.nanoxml.StdXMLReader; + +/* + * Exception performing whole class analysis ignored. + */ +public class StdXMLReader +implements IXMLReader { + private Stack readers; + private StackedReader currentReader; + static /* synthetic */ Class class$net$n3$nanoxml$StdXMLReader; + + public static IXMLReader stringReader(String string) { + return new StdXMLReader((Reader)new StringReader(string)); + } + + public static IXMLReader fileReader(String string) throws FileNotFoundException, IOException { + StdXMLReader stdXMLReader = new StdXMLReader((InputStream)new FileInputStream(string)); + stdXMLReader.setSystemID(string); + for (int i = 0; i < stdXMLReader.readers.size(); ++i) { + StackedReader stackedReader = (StackedReader)stdXMLReader.readers.elementAt(i); + stackedReader.systemId = stdXMLReader.currentReader.systemId; + } + return stdXMLReader; + } + + public StdXMLReader(String string, String string2) throws MalformedURLException, FileNotFoundException, IOException { + URL uRL = null; + try { + uRL = new URL(string2); + } + catch (MalformedURLException malformedURLException) { + string2 = "file:" + string2; + try { + uRL = new URL(string2); + } + catch (MalformedURLException malformedURLException2) { + throw malformedURLException; + } + } + this.currentReader = new StackedReader(this, null); + this.readers = new Stack(); + Reader reader = this.openStream(string, uRL.toString()); + this.currentReader.lineReader = new LineNumberReader(reader); + this.currentReader.pbReader = new PushbackReader(this.currentReader.lineReader, 2); + } + + public StdXMLReader(Reader reader) { + this.currentReader = new StackedReader(this, null); + this.readers = new Stack(); + this.currentReader.lineReader = new LineNumberReader(reader); + this.currentReader.pbReader = new PushbackReader(this.currentReader.lineReader, 2); + this.currentReader.publicId = ""; + try { + this.currentReader.systemId = new URL("file:."); + } + catch (MalformedURLException malformedURLException) { + // empty catch block + } + } + + protected void finalize() throws Throwable { + this.currentReader.lineReader = null; + this.currentReader.pbReader = null; + this.currentReader.systemId = null; + this.currentReader.publicId = null; + this.currentReader = null; + this.readers.clear(); + super.finalize(); + } + + protected String getEncoding(String string) { + if (!string.startsWith("= 'a' && string.charAt(n) <= 'z') { + stringBuffer.append(string.charAt(n)); + ++n; + } + while (n < string.length() && string.charAt(n) <= ' ') { + ++n; + } + if (n >= string.length() || string.charAt(n) != '=') break; + while (n < string.length() && string.charAt(n) != '\'' && string.charAt(n) != '\"') { + ++n; + } + if (n >= string.length() || (n2 = string.indexOf(c = string.charAt(n), ++n)) < 0) break; + if (stringBuffer.toString().equals("encoding")) { + return string.substring(n, n2); + } + n = n2 + 1; + } + return null; + } + + protected Reader stream2reader(InputStream inputStream, StringBuffer stringBuffer) throws IOException { + PushbackInputStream pushbackInputStream = new PushbackInputStream(inputStream); + int n = pushbackInputStream.read(); + switch (n) { + case 0: + case 254: + case 255: { + pushbackInputStream.unread(n); + return new InputStreamReader((InputStream)pushbackInputStream, "UTF-16"); + } + case 239: { + for (int i = 0; i < 2; ++i) { + pushbackInputStream.read(); + } + return new InputStreamReader((InputStream)pushbackInputStream, "UTF-8"); + } + case 60: { + String string; + n = pushbackInputStream.read(); + stringBuffer.append('<'); + while (n > 0 && n != 62) { + stringBuffer.append((char)n); + n = pushbackInputStream.read(); + } + if (n > 0) { + stringBuffer.append((char)n); + } + if ((string = this.getEncoding(stringBuffer.toString())) == null) { + return new InputStreamReader((InputStream)pushbackInputStream, "UTF-8"); + } + stringBuffer.setLength(0); + try { + return new InputStreamReader((InputStream)pushbackInputStream, string); + } + catch (UnsupportedEncodingException unsupportedEncodingException) { + return new InputStreamReader((InputStream)pushbackInputStream, "UTF-8"); + } + } + } + stringBuffer.append((char)n); + return new InputStreamReader((InputStream)pushbackInputStream, "UTF-8"); + } + + public StdXMLReader(InputStream inputStream) throws IOException { + PushbackInputStream pushbackInputStream = new PushbackInputStream(inputStream); + StringBuffer stringBuffer = new StringBuffer(); + Reader reader = this.stream2reader(inputStream, stringBuffer); + this.currentReader = new StackedReader(this, null); + this.readers = new Stack(); + this.currentReader.lineReader = new LineNumberReader(reader); + this.currentReader.pbReader = new PushbackReader(this.currentReader.lineReader, 2); + this.currentReader.publicId = ""; + try { + this.currentReader.systemId = new URL("file:."); + } + catch (MalformedURLException malformedURLException) { + // empty catch block + } + this.startNewStream((Reader)new StringReader(stringBuffer.toString())); + } + + public char read() throws IOException { + int n = this.currentReader.pbReader.read(); + while (n < 0) { + if (this.readers.empty()) { + throw new IOException("Unexpected EOF"); + } + this.currentReader.pbReader.close(); + this.currentReader = (StackedReader)this.readers.pop(); + n = this.currentReader.pbReader.read(); + } + return (char)n; + } + + public boolean atEOFOfCurrentStream() throws IOException { + int n = this.currentReader.pbReader.read(); + if (n < 0) { + return true; + } + this.currentReader.pbReader.unread(n); + return false; + } + + public boolean atEOF() throws IOException { + int n = this.currentReader.pbReader.read(); + while (n < 0) { + if (this.readers.empty()) { + return true; + } + this.currentReader.pbReader.close(); + this.currentReader = (StackedReader)this.readers.pop(); + n = this.currentReader.pbReader.read(); + } + this.currentReader.pbReader.unread(n); + return false; + } + + public void unread(char c) throws IOException { + this.currentReader.pbReader.unread(c); + } + + public Reader openStream(String string, String string2) throws MalformedURLException, FileNotFoundException, IOException { + CharSequence charSequence; + URL uRL = new URL(this.currentReader.systemId, string2); + if (uRL.getRef() != null) { + charSequence = uRL.getRef(); + if (uRL.getFile().length() > 0) { + uRL = new URL(uRL.getProtocol(), uRL.getHost(), uRL.getPort(), uRL.getFile()); + uRL = new URL("jar:" + uRL + '!' + (String)charSequence); + } else { + uRL = (class$net$n3$nanoxml$StdXMLReader == null ? (class$net$n3$nanoxml$StdXMLReader = StdXMLReader.class$((String)"net.n3.nanoxml.StdXMLReader")) : class$net$n3$nanoxml$StdXMLReader).getResource((String)charSequence); + } + } + this.currentReader.publicId = string; + this.currentReader.systemId = uRL; + charSequence = new StringBuffer(); + Reader reader = this.stream2reader(uRL.openStream(), (StringBuffer)charSequence); + if (((StringBuffer)charSequence).length() == 0) { + return reader; + } + String string3 = ((StringBuffer)charSequence).toString(); + PushbackReader pushbackReader = new PushbackReader(reader, string3.length()); + for (int i = string3.length() - 1; i >= 0; --i) { + pushbackReader.unread(string3.charAt(i)); + } + return pushbackReader; + } + + public void startNewStream(Reader reader) { + this.startNewStream(reader, false); + } + + public void startNewStream(Reader reader, boolean bl) { + StackedReader stackedReader = this.currentReader; + this.readers.push(this.currentReader); + this.currentReader = new StackedReader(this, null); + if (bl) { + this.currentReader.lineReader = null; + this.currentReader.pbReader = new PushbackReader(reader, 2); + } else { + this.currentReader.lineReader = new LineNumberReader(reader); + this.currentReader.pbReader = new PushbackReader(this.currentReader.lineReader, 2); + } + this.currentReader.systemId = stackedReader.systemId; + this.currentReader.publicId = stackedReader.publicId; + } + + public int getStreamLevel() { + return this.readers.size(); + } + + public int getLineNr() { + if (this.currentReader.lineReader == null) { + StackedReader stackedReader = (StackedReader)this.readers.peek(); + if (stackedReader.lineReader == null) { + return 0; + } + return stackedReader.lineReader.getLineNumber() + 1; + } + return this.currentReader.lineReader.getLineNumber() + 1; + } + + public void setSystemID(String string) throws MalformedURLException { + this.currentReader.systemId = new URL(this.currentReader.systemId, string); + } + + public void setPublicID(String string) { + this.currentReader.publicId = string; + } + + public String getSystemID() { + return this.currentReader.systemId.toString(); + } + + public String getPublicID() { + return this.currentReader.publicId; + } + + static /* synthetic */ Class class$(String string) { + try { + return Class.forName(string); + } + catch (ClassNotFoundException classNotFoundException) { + throw new NoClassDefFoundError(classNotFoundException.getMessage()); + } + } +} + diff --git a/src/net/n3/nanoxml/ValidatorPlugin.java b/src/net/n3/nanoxml/ValidatorPlugin.java new file mode 100644 index 0000000..486a454 --- /dev/null +++ b/src/net/n3/nanoxml/ValidatorPlugin.java @@ -0,0 +1,102 @@ +/* + * Decompiled with CFR 0.152. + * + * Could not load the following classes: + * net.n3.nanoxml.IXMLEntityResolver + * net.n3.nanoxml.IXMLReader + * net.n3.nanoxml.IXMLValidator + * net.n3.nanoxml.ValidatorPlugin + * net.n3.nanoxml.XMLUtil + * net.n3.nanoxml.XMLValidationException + */ +package net.n3.nanoxml; + +import java.util.Properties; +import net.n3.nanoxml.IXMLEntityResolver; +import net.n3.nanoxml.IXMLReader; +import net.n3.nanoxml.IXMLValidator; +import net.n3.nanoxml.XMLUtil; +import net.n3.nanoxml.XMLValidationException; + +public class ValidatorPlugin +implements IXMLValidator { + private IXMLValidator delegate = null; + + protected void finalize() throws Throwable { + this.delegate = null; + super.finalize(); + } + + public IXMLValidator getDelegate() { + return this.delegate; + } + + public void setDelegate(IXMLValidator iXMLValidator) { + this.delegate = iXMLValidator; + } + + public void setParameterEntityResolver(IXMLEntityResolver iXMLEntityResolver) { + this.delegate.setParameterEntityResolver(iXMLEntityResolver); + } + + public IXMLEntityResolver getParameterEntityResolver() { + return this.delegate.getParameterEntityResolver(); + } + + public void parseDTD(String string, IXMLReader iXMLReader, IXMLEntityResolver iXMLEntityResolver, boolean bl) throws Exception { + this.delegate.parseDTD(string, iXMLReader, iXMLEntityResolver, bl); + } + + public void elementStarted(String string, String string2, int n) throws Exception { + this.delegate.elementStarted(string, string2, n); + } + + public void elementEnded(String string, String string2, int n) throws Exception { + this.delegate.elementEnded(string, string2, n); + } + + public void elementAttributesProcessed(String string, Properties properties, String string2, int n) throws Exception { + this.delegate.elementAttributesProcessed(string, properties, string2, n); + } + + public void attributeAdded(String string, String string2, String string3, int n) throws Exception { + this.delegate.attributeAdded(string, string2, string3, n); + } + + public void PCDataAdded(String string, int n) throws Exception { + this.delegate.PCDataAdded(string, n); + } + + public void missingElement(String string, int n, String string2, String string3) throws XMLValidationException { + XMLUtil.errorMissingElement((String)string, (int)n, (String)string2, (String)string3); + } + + public void unexpectedElement(String string, int n, String string2, String string3) throws XMLValidationException { + XMLUtil.errorUnexpectedElement((String)string, (int)n, (String)string2, (String)string3); + } + + public void missingAttribute(String string, int n, String string2, String string3) throws XMLValidationException { + XMLUtil.errorMissingAttribute((String)string, (int)n, (String)string2, (String)string3); + } + + public void unexpectedAttribute(String string, int n, String string2, String string3) throws XMLValidationException { + XMLUtil.errorUnexpectedAttribute((String)string, (int)n, (String)string2, (String)string3); + } + + public void invalidAttributeValue(String string, int n, String string2, String string3, String string4) throws XMLValidationException { + XMLUtil.errorInvalidAttributeValue((String)string, (int)n, (String)string2, (String)string3, (String)string4); + } + + public void missingPCData(String string, int n, String string2) throws XMLValidationException { + XMLUtil.errorMissingPCData((String)string, (int)n, (String)string2); + } + + public void unexpectedPCData(String string, int n, String string2) throws XMLValidationException { + XMLUtil.errorUnexpectedPCData((String)string, (int)n, (String)string2); + } + + public void validationError(String string, int n, String string2, String string3, String string4, String string5) throws XMLValidationException { + XMLUtil.validationError((String)string, (int)n, (String)string2, (String)string3, (String)string4, (String)string5); + } +} + diff --git a/src/net/n3/nanoxml/XMLAttribute.java b/src/net/n3/nanoxml/XMLAttribute.java new file mode 100644 index 0000000..edf3bfa --- /dev/null +++ b/src/net/n3/nanoxml/XMLAttribute.java @@ -0,0 +1,48 @@ +/* + * Decompiled with CFR 0.152. + * + * Could not load the following classes: + * net.n3.nanoxml.XMLAttribute + */ +package net.n3.nanoxml; + +class XMLAttribute { + private String fullName; + private String name; + private String namespace; + private String value; + private String type; + + XMLAttribute(String string, String string2, String string3, String string4, String string5) { + this.fullName = string; + this.name = string2; + this.namespace = string3; + this.value = string4; + this.type = string5; + } + + String getFullName() { + return this.fullName; + } + + String getName() { + return this.name; + } + + String getNamespace() { + return this.namespace; + } + + String getValue() { + return this.value; + } + + void setValue(String string) { + this.value = string; + } + + String getType() { + return this.type; + } +} + diff --git a/src/net/n3/nanoxml/XMLElement.java b/src/net/n3/nanoxml/XMLElement.java new file mode 100644 index 0000000..3be67f4 --- /dev/null +++ b/src/net/n3/nanoxml/XMLElement.java @@ -0,0 +1,460 @@ +/* + * Decompiled with CFR 0.152. + * + * Could not load the following classes: + * net.n3.nanoxml.IXMLElement + * net.n3.nanoxml.XMLAttribute + * net.n3.nanoxml.XMLElement + */ +package net.n3.nanoxml; + +import java.io.Serializable; +import java.util.Enumeration; +import java.util.Properties; +import java.util.Vector; +import net.n3.nanoxml.IXMLElement; +import net.n3.nanoxml.XMLAttribute; + +public class XMLElement +implements IXMLElement, +Serializable { + static final long serialVersionUID = -2383376380548624920L; + public static final int NO_LINE = -1; + private IXMLElement parent; + private Vector attributes = new Vector(); + private Vector children = new Vector(8); + private String name; + private String fullName; + private String namespace; + private String content; + private String systemID; + private int lineNr; + + public XMLElement() { + this(null, null, null, -1); + } + + public XMLElement(String string) { + this(string, null, null, -1); + } + + public XMLElement(String string, String string2, int n) { + this(string, null, string2, n); + } + + public XMLElement(String string, String string2) { + this(string, string2, null, -1); + } + + public XMLElement(String string, String string2, String string3, int n) { + int n2; + this.fullName = string; + this.name = string2 == null ? string : ((n2 = string.indexOf(58)) >= 0 ? string.substring(n2 + 1) : string); + this.namespace = string2; + this.content = null; + this.lineNr = n; + this.systemID = string3; + this.parent = null; + } + + public IXMLElement createPCDataElement() { + return new XMLElement(); + } + + public IXMLElement createElement(String string) { + return new XMLElement(string); + } + + public IXMLElement createElement(String string, String string2, int n) { + return new XMLElement(string, string2, n); + } + + public IXMLElement createElement(String string, String string2) { + return new XMLElement(string, string2); + } + + public IXMLElement createElement(String string, String string2, String string3, int n) { + return new XMLElement(string, string2, string3, n); + } + + protected void finalize() throws Throwable { + this.attributes.clear(); + this.attributes = null; + this.children = null; + this.fullName = null; + this.name = null; + this.namespace = null; + this.content = null; + this.systemID = null; + this.parent = null; + super.finalize(); + } + + public IXMLElement getParent() { + return this.parent; + } + + public String getFullName() { + return this.fullName; + } + + public String getName() { + return this.name; + } + + public String getNamespace() { + return this.namespace; + } + + public void setName(String string) { + this.name = string; + this.fullName = string; + this.namespace = null; + } + + public void setName(String string, String string2) { + int n = string.indexOf(58); + this.name = string2 == null || n < 0 ? string : string.substring(n + 1); + this.fullName = string; + this.namespace = string2; + } + + public void addChild(IXMLElement iXMLElement) { + IXMLElement iXMLElement2; + if (iXMLElement == null) { + throw new IllegalArgumentException("child must not be null"); + } + if (iXMLElement.getName() == null && !this.children.isEmpty() && (iXMLElement2 = (IXMLElement)this.children.lastElement()).getName() == null) { + iXMLElement2.setContent(iXMLElement2.getContent() + iXMLElement.getContent()); + return; + } + ((XMLElement)iXMLElement).parent = this; + this.children.addElement(iXMLElement); + } + + public void insertChild(IXMLElement iXMLElement, int n) { + IXMLElement iXMLElement2; + if (iXMLElement == null) { + throw new IllegalArgumentException("child must not be null"); + } + if (iXMLElement.getName() == null && !this.children.isEmpty() && (iXMLElement2 = (IXMLElement)this.children.lastElement()).getName() == null) { + iXMLElement2.setContent(iXMLElement2.getContent() + iXMLElement.getContent()); + return; + } + ((XMLElement)iXMLElement).parent = this; + this.children.insertElementAt(iXMLElement, n); + } + + public void removeChild(IXMLElement iXMLElement) { + if (iXMLElement == null) { + throw new IllegalArgumentException("child must not be null"); + } + this.children.removeElement(iXMLElement); + } + + public void removeChildAtIndex(int n) { + this.children.removeElementAt(n); + } + + public Enumeration enumerateChildren() { + return this.children.elements(); + } + + public boolean isLeaf() { + return this.children.isEmpty(); + } + + public boolean hasChildren() { + return !this.children.isEmpty(); + } + + public int getChildrenCount() { + return this.children.size(); + } + + public Vector getChildren() { + return this.children; + } + + public IXMLElement getChildAtIndex(int n) throws ArrayIndexOutOfBoundsException { + return (IXMLElement)this.children.elementAt(n); + } + + public IXMLElement getFirstChildNamed(String string) { + Enumeration enumeration = this.children.elements(); + while (enumeration.hasMoreElements()) { + IXMLElement iXMLElement = (IXMLElement)enumeration.nextElement(); + String string2 = iXMLElement.getFullName(); + if (string2 == null || !string2.equals(string)) continue; + return iXMLElement; + } + return null; + } + + public IXMLElement getFirstChildNamed(String string, String string2) { + Enumeration enumeration = this.children.elements(); + while (enumeration.hasMoreElements()) { + IXMLElement iXMLElement = (IXMLElement)enumeration.nextElement(); + String string3 = iXMLElement.getName(); + boolean bl = string3 != null && string3.equals(string); + string3 = iXMLElement.getNamespace(); + bl = string3 == null ? (bl &= string == null) : (bl &= string3.equals(string2)); + if (!bl) continue; + return iXMLElement; + } + return null; + } + + public Vector getChildrenNamed(String string) { + Vector vector = new Vector(this.children.size()); + Enumeration enumeration = this.children.elements(); + while (enumeration.hasMoreElements()) { + IXMLElement iXMLElement = (IXMLElement)enumeration.nextElement(); + String string2 = iXMLElement.getFullName(); + if (string2 == null || !string2.equals(string)) continue; + vector.addElement(iXMLElement); + } + return vector; + } + + public Vector getChildrenNamed(String string, String string2) { + Vector vector = new Vector(this.children.size()); + Enumeration enumeration = this.children.elements(); + while (enumeration.hasMoreElements()) { + IXMLElement iXMLElement = (IXMLElement)enumeration.nextElement(); + String string3 = iXMLElement.getName(); + boolean bl = string3 != null && string3.equals(string); + string3 = iXMLElement.getNamespace(); + bl = string3 == null ? (bl &= string == null) : (bl &= string3.equals(string2)); + if (!bl) continue; + vector.addElement(iXMLElement); + } + return vector; + } + + private XMLAttribute findAttribute(String string) { + Enumeration enumeration = this.attributes.elements(); + while (enumeration.hasMoreElements()) { + XMLAttribute xMLAttribute = (XMLAttribute)enumeration.nextElement(); + if (!xMLAttribute.getFullName().equalsIgnoreCase(string)) continue; + return xMLAttribute; + } + return null; + } + + private XMLAttribute findAttribute(String string, String string2) { + Enumeration enumeration = this.attributes.elements(); + while (enumeration.hasMoreElements()) { + XMLAttribute xMLAttribute = (XMLAttribute)enumeration.nextElement(); + boolean bl = xMLAttribute.getName().equals(string); + bl = string2 == null ? (bl &= xMLAttribute.getNamespace() == null) : (bl &= string2.equalsIgnoreCase(xMLAttribute.getNamespace())); + if (!bl) continue; + return xMLAttribute; + } + return null; + } + + public int getAttributeCount() { + return this.attributes.size(); + } + + public String getAttribute(String string) { + return this.getAttribute(string, null); + } + + public String getAttribute(String string, String string2) { + XMLAttribute xMLAttribute = this.findAttribute(string); + if (xMLAttribute == null) { + return string2; + } + return xMLAttribute.getValue(); + } + + public String getAttribute(String string, String string2, String string3) { + XMLAttribute xMLAttribute = this.findAttribute(string, string2); + if (xMLAttribute == null) { + return string3; + } + return xMLAttribute.getValue(); + } + + public int getAttribute(String string, int n) { + String string2 = this.getAttribute(string, Integer.toString(n)); + return Integer.parseInt(string2); + } + + public int getAttribute(String string, String string2, int n) { + String string3 = this.getAttribute(string, string2, Integer.toString(n)); + return Integer.parseInt(string3); + } + + public String getAttributeType(String string) { + XMLAttribute xMLAttribute = this.findAttribute(string); + if (xMLAttribute == null) { + return null; + } + return xMLAttribute.getType(); + } + + public String getAttributeNamespace(String string) { + XMLAttribute xMLAttribute = this.findAttribute(string); + if (xMLAttribute == null) { + return null; + } + return xMLAttribute.getNamespace(); + } + + public String getAttributeType(String string, String string2) { + XMLAttribute xMLAttribute = this.findAttribute(string, string2); + if (xMLAttribute == null) { + return null; + } + return xMLAttribute.getType(); + } + + public void setAttribute(String string, String string2) { + XMLAttribute xMLAttribute = this.findAttribute(string); + if (xMLAttribute == null) { + xMLAttribute = new XMLAttribute(string, string, null, string2, "CDATA"); + this.attributes.addElement(xMLAttribute); + } else { + xMLAttribute.setValue(string2); + } + } + + public void setAttribute(String string, String string2, String string3) { + int n = string.indexOf(58); + String string4 = string.substring(n + 1); + XMLAttribute xMLAttribute = this.findAttribute(string4, string2); + if (xMLAttribute == null) { + xMLAttribute = new XMLAttribute(string, string4, string2, string3, "CDATA"); + this.attributes.addElement(xMLAttribute); + } else { + xMLAttribute.setValue(string3); + } + } + + public void removeAttribute(String string) { + for (int i = 0; i < this.attributes.size(); ++i) { + XMLAttribute xMLAttribute = (XMLAttribute)this.attributes.elementAt(i); + if (!xMLAttribute.getFullName().equals(string)) continue; + this.attributes.removeElementAt(i); + return; + } + } + + public void removeAttribute(String string, String string2) { + for (int i = 0; i < this.attributes.size(); ++i) { + XMLAttribute xMLAttribute = (XMLAttribute)this.attributes.elementAt(i); + boolean bl = xMLAttribute.getName().equals(string); + bl = string2 == null ? (bl &= xMLAttribute.getNamespace() == null) : (bl &= xMLAttribute.getNamespace().equals(string2)); + if (!bl) continue; + this.attributes.removeElementAt(i); + return; + } + } + + public Enumeration enumerateAttributeNames() { + Vector vector = new Vector(); + Enumeration enumeration = this.attributes.elements(); + while (enumeration.hasMoreElements()) { + XMLAttribute xMLAttribute = (XMLAttribute)enumeration.nextElement(); + vector.addElement(xMLAttribute.getFullName()); + } + return vector.elements(); + } + + public boolean hasAttribute(String string) { + return this.findAttribute(string) != null; + } + + public boolean hasAttribute(String string, String string2) { + return this.findAttribute(string, string2) != null; + } + + public Properties getAttributes() { + Properties properties = new Properties(); + Enumeration enumeration = this.attributes.elements(); + while (enumeration.hasMoreElements()) { + XMLAttribute xMLAttribute = (XMLAttribute)enumeration.nextElement(); + properties.put(xMLAttribute.getFullName(), xMLAttribute.getValue()); + } + return properties; + } + + public Properties getAttributesInNamespace(String string) { + Properties properties = new Properties(); + Enumeration enumeration = this.attributes.elements(); + while (enumeration.hasMoreElements()) { + XMLAttribute xMLAttribute = (XMLAttribute)enumeration.nextElement(); + if (string == null) { + if (xMLAttribute.getNamespace() != null) continue; + properties.put(xMLAttribute.getName(), xMLAttribute.getValue()); + continue; + } + if (!string.equals(xMLAttribute.getNamespace())) continue; + properties.put(xMLAttribute.getName(), xMLAttribute.getValue()); + } + return properties; + } + + public String getSystemID() { + return this.systemID; + } + + public int getLineNr() { + return this.lineNr; + } + + public String getContent() { + return this.content; + } + + public void setContent(String string) { + this.content = string; + } + + public boolean equals(Object object) { + try { + return this.equalsXMLElement((IXMLElement)object); + } + catch (ClassCastException classCastException) { + return false; + } + } + + public boolean equalsXMLElement(IXMLElement iXMLElement) { + Object object; + Object object2; + if (!this.name.equals(iXMLElement.getName())) { + return false; + } + if (this.attributes.size() != iXMLElement.getAttributeCount()) { + return false; + } + Enumeration enumeration = this.attributes.elements(); + while (enumeration.hasMoreElements()) { + XMLAttribute xMLAttribute = (XMLAttribute)enumeration.nextElement(); + if (!iXMLElement.hasAttribute(xMLAttribute.getName(), xMLAttribute.getNamespace())) { + return false; + } + object2 = iXMLElement.getAttribute(xMLAttribute.getName(), xMLAttribute.getNamespace(), null); + if (!xMLAttribute.getValue().equals(object2)) { + return false; + } + object = iXMLElement.getAttributeType(xMLAttribute.getName(), xMLAttribute.getNamespace()); + if (xMLAttribute.getType().equals(object)) continue; + return false; + } + if (this.children.size() != iXMLElement.getChildrenCount()) { + return false; + } + for (int i = 0; i < this.children.size(); ++i) { + object2 = this.getChildAtIndex(i); + if (object2.equalsXMLElement(object = iXMLElement.getChildAtIndex(i))) continue; + return false; + } + return true; + } +} + diff --git a/src/net/n3/nanoxml/XMLEntityResolver.java b/src/net/n3/nanoxml/XMLEntityResolver.java new file mode 100644 index 0000000..7f1f235 --- /dev/null +++ b/src/net/n3/nanoxml/XMLEntityResolver.java @@ -0,0 +1,76 @@ +/* + * Decompiled with CFR 0.152. + * + * Could not load the following classes: + * net.n3.nanoxml.IXMLEntityResolver + * net.n3.nanoxml.IXMLReader + * net.n3.nanoxml.XMLEntityResolver + * net.n3.nanoxml.XMLParseException + */ +package net.n3.nanoxml; + +import java.io.Reader; +import java.io.StringReader; +import java.util.Hashtable; +import net.n3.nanoxml.IXMLEntityResolver; +import net.n3.nanoxml.IXMLReader; +import net.n3.nanoxml.XMLParseException; + +public class XMLEntityResolver +implements IXMLEntityResolver { + private Hashtable entities = new Hashtable(); + + public XMLEntityResolver() { + this.entities.put("amp", "&"); + this.entities.put("quot", """); + this.entities.put("apos", "'"); + this.entities.put("lt", "<"); + this.entities.put("gt", ">"); + } + + protected void finalize() throws Throwable { + this.entities.clear(); + this.entities = null; + super.finalize(); + } + + public void addInternalEntity(String string, String string2) { + if (!this.entities.containsKey(string)) { + this.entities.put(string, string2); + } + } + + public void addExternalEntity(String string, String string2, String string3) { + if (!this.entities.containsKey(string)) { + this.entities.put(string, new String[]{string2, string3}); + } + } + + public Reader getEntity(IXMLReader iXMLReader, String string) throws XMLParseException { + Object v = this.entities.get(string); + if (v == null) { + return null; + } + if (v instanceof String) { + return new StringReader((String)v); + } + String[] stringArray = (String[])v; + return this.openExternalEntity(iXMLReader, stringArray[0], stringArray[1]); + } + + public boolean isExternalEntity(String string) { + Object v = this.entities.get(string); + return !(v instanceof String); + } + + protected Reader openExternalEntity(IXMLReader iXMLReader, String string, String string2) throws XMLParseException { + String string3 = iXMLReader.getSystemID(); + try { + return iXMLReader.openStream(string, string2); + } + catch (Exception exception) { + throw new XMLParseException(string3, iXMLReader.getLineNr(), "Could not open external entity at system ID: " + string2); + } + } +} + diff --git a/src/net/n3/nanoxml/XMLException.java b/src/net/n3/nanoxml/XMLException.java new file mode 100644 index 0000000..d797d65 --- /dev/null +++ b/src/net/n3/nanoxml/XMLException.java @@ -0,0 +1,108 @@ +/* + * Decompiled with CFR 0.152. + * + * Could not load the following classes: + * net.n3.nanoxml.XMLException + */ +package net.n3.nanoxml; + +import java.io.PrintStream; +import java.io.PrintWriter; + +/* + * Exception performing whole class analysis ignored. + */ +public class XMLException +extends Exception { + private String msg; + private String systemID; + private int lineNr; + private Exception encapsulatedException; + + public XMLException(String string) { + this(null, -1, null, string, false); + } + + public XMLException(Exception exception) { + this(null, -1, exception, "Nested Exception", false); + } + + public XMLException(String string, int n, Exception exception) { + this(string, n, exception, "Nested Exception", true); + } + + public XMLException(String string, int n, String string2) { + this(string, n, null, string2, true); + } + + public XMLException(String string, int n, Exception exception, String string2, boolean bl) { + super(XMLException.buildMessage((String)string, (int)n, (Exception)exception, (String)string2, (boolean)bl)); + this.systemID = string; + this.lineNr = n; + this.encapsulatedException = exception; + this.msg = XMLException.buildMessage((String)string, (int)n, (Exception)exception, (String)string2, (boolean)bl); + } + + private static String buildMessage(String string, int n, Exception exception, String string2, boolean bl) { + String string3 = string2; + if (bl) { + if (string != null) { + string3 = string3 + ", SystemID='" + string + "'"; + } + if (n >= 0) { + string3 = string3 + ", Line=" + n; + } + if (exception != null) { + string3 = string3 + ", Exception: " + exception; + } + } + return string3; + } + + protected void finalize() throws Throwable { + this.systemID = null; + this.encapsulatedException = null; + super.finalize(); + } + + public String getSystemID() { + return this.systemID; + } + + public int getLineNr() { + return this.lineNr; + } + + public Exception getException() { + return this.encapsulatedException; + } + + public void printStackTrace(PrintWriter printWriter) { + super.printStackTrace(printWriter); + if (this.encapsulatedException != null) { + printWriter.println("*** Nested Exception:"); + this.encapsulatedException.printStackTrace(printWriter); + } + } + + public void printStackTrace(PrintStream printStream) { + super.printStackTrace(printStream); + if (this.encapsulatedException != null) { + printStream.println("*** Nested Exception:"); + this.encapsulatedException.printStackTrace(printStream); + } + } + + public void printStackTrace() { + super.printStackTrace(); + if (this.encapsulatedException != null) { + System.err.println("*** Nested Exception:"); + this.encapsulatedException.printStackTrace(); + } + } + + public String toString() { + return this.msg; + } +} + diff --git a/src/net/n3/nanoxml/XMLParseException.java b/src/net/n3/nanoxml/XMLParseException.java new file mode 100644 index 0000000..ae91ed3 --- /dev/null +++ b/src/net/n3/nanoxml/XMLParseException.java @@ -0,0 +1,22 @@ +/* + * Decompiled with CFR 0.152. + * + * Could not load the following classes: + * net.n3.nanoxml.XMLException + * net.n3.nanoxml.XMLParseException + */ +package net.n3.nanoxml; + +import net.n3.nanoxml.XMLException; + +public class XMLParseException +extends XMLException { + public XMLParseException(String string) { + super(string); + } + + public XMLParseException(String string, int n, String string2) { + super(string, n, null, string2, true); + } +} + diff --git a/src/net/n3/nanoxml/XMLParserFactory.java b/src/net/n3/nanoxml/XMLParserFactory.java new file mode 100644 index 0000000..3ccc797 --- /dev/null +++ b/src/net/n3/nanoxml/XMLParserFactory.java @@ -0,0 +1,45 @@ +/* + * Decompiled with CFR 0.152. + * + * Could not load the following classes: + * net.n3.nanoxml.IXMLBuilder + * net.n3.nanoxml.IXMLParser + * net.n3.nanoxml.IXMLValidator + * net.n3.nanoxml.NonValidator + * net.n3.nanoxml.StdXMLBuilder + * net.n3.nanoxml.XMLParserFactory + */ +package net.n3.nanoxml; + +import net.n3.nanoxml.IXMLBuilder; +import net.n3.nanoxml.IXMLParser; +import net.n3.nanoxml.IXMLValidator; +import net.n3.nanoxml.NonValidator; +import net.n3.nanoxml.StdXMLBuilder; + +/* + * Exception performing whole class analysis ignored. + */ +public class XMLParserFactory { + public static final String DEFAULT_CLASS = "net.n3.nanoxml.StdXMLParser"; + public static final String CLASS_KEY = "net.n3.nanoxml.XMLParser"; + + public static IXMLParser createDefaultXMLParser() throws ClassNotFoundException, InstantiationException, IllegalAccessException { + String string = System.getProperty("net.n3.nanoxml.XMLParser", "net.n3.nanoxml.StdXMLParser"); + return XMLParserFactory.createXMLParser((String)string, (IXMLBuilder)new StdXMLBuilder()); + } + + public static IXMLParser createDefaultXMLParser(IXMLBuilder iXMLBuilder) throws ClassNotFoundException, InstantiationException, IllegalAccessException { + String string = System.getProperty("net.n3.nanoxml.XMLParser", "net.n3.nanoxml.StdXMLParser"); + return XMLParserFactory.createXMLParser((String)string, (IXMLBuilder)iXMLBuilder); + } + + public static IXMLParser createXMLParser(String string, IXMLBuilder iXMLBuilder) throws ClassNotFoundException, InstantiationException, IllegalAccessException { + Class clazz = Class.forName(string); + IXMLParser iXMLParser = (IXMLParser)clazz.newInstance(); + iXMLParser.setBuilder(iXMLBuilder); + iXMLParser.setValidator((IXMLValidator)new NonValidator()); + return iXMLParser; + } +} + diff --git a/src/net/n3/nanoxml/XMLUtil.java b/src/net/n3/nanoxml/XMLUtil.java new file mode 100644 index 0000000..8fd072a --- /dev/null +++ b/src/net/n3/nanoxml/XMLUtil.java @@ -0,0 +1,259 @@ +/* + * Decompiled with CFR 0.152. + * + * Could not load the following classes: + * net.n3.nanoxml.IXMLEntityResolver + * net.n3.nanoxml.IXMLReader + * net.n3.nanoxml.XMLParseException + * net.n3.nanoxml.XMLUtil + * net.n3.nanoxml.XMLValidationException + */ +package net.n3.nanoxml; + +import java.io.IOException; +import java.io.Reader; +import net.n3.nanoxml.IXMLEntityResolver; +import net.n3.nanoxml.IXMLReader; +import net.n3.nanoxml.XMLParseException; +import net.n3.nanoxml.XMLValidationException; + +/* + * Exception performing whole class analysis ignored. + */ +class XMLUtil { + XMLUtil() { + } + + static void skipComment(IXMLReader iXMLReader) throws IOException, XMLParseException { + if (iXMLReader.read() != '-') { + XMLUtil.errorExpectedInput((String)iXMLReader.getSystemID(), (int)iXMLReader.getLineNr(), (String)"