Attempts to add support for MSCOM via jni4net

Also only building the necessary modules
This commit is contained in:
Norbi Peti 2020-10-16 03:19:34 +02:00
parent 26d8cc1ff0
commit d68ddb3418
22 changed files with 212 additions and 174 deletions

View file

@ -37,14 +37,6 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>9</source>
<target>9</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
@ -52,6 +44,8 @@
<groupId>org.virtualbox</groupId>
<artifactId>VirtualBox-MSCOM</artifactId>
<version>6.1</version>
<scope>system</scope>
<systemPath>${project.basedir}/../VirtualComputerMSCOM/src/main/resources/Interop.VirtualBox.j4n.jar</systemPath>
</dependency>
<dependency>
<groupId>com.aparapi</groupId>

View file

@ -20,11 +20,22 @@
<version>6.1</version>
<optional>true
</optional> <!-- https://maven.apache.org/guides/introduction/introduction-to-optional-and-excludes-dependencies.html -->
<scope>system</scope>
<systemPath>${project.basedir}/src/main/resources/Interop.VirtualBox.j4n.jar</systemPath>
</dependency>
<dependency>
<groupId>net.sf.jacob-project</groupId>
<artifactId>jacob</artifactId>
<version>1.19</version>
<groupId>net.sf.jni4net</groupId>
<artifactId>clr</artifactId>
<version>0.8.9.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/resources/jni4net.j-0.8.9.0.jar</systemPath>
</dependency>
<dependency>
<groupId>io.github.NorbiPeti</groupId>
<artifactId>VirtualComputer-Windows</artifactId>
<version>0.8.9.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/resources/VirtualComputerWindows.j4n.jar</systemPath>
</dependency>
</dependencies>

View file

@ -0,0 +1,77 @@
// ------------------------------------------------------------------------------
// <autogenerated>
// This code was generated by jni4net. See http://jni4net.sourceforge.net/
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </autogenerated>
// ------------------------------------------------------------------------------
package org.virtualbox_6_1;
@net.sf.jni4net.attributes.ClrInterface
public interface ISession {
//<generated-interface>
@net.sf.jni4net.attributes.ClrMethod("()Lorg/virtualbox_6_1/SessionState;")
org.virtualbox_6_1.SessionState getState_FixIt();
default org.virtualbox_6_1.SessionState getState() {
return SessionState.Locked;
}
@net.sf.jni4net.attributes.ClrMethod("()Lorg/virtualbox_6_1/SessionType;")
org.virtualbox_6_1.SessionType getType_FixIt();
@net.sf.jni4net.attributes.ClrMethod("()LSystem/String;")
java.lang.String getName();
@net.sf.jni4net.attributes.ClrMethod("(LSystem/String;)V")
void setName(java.lang.String aName);
@net.sf.jni4net.attributes.ClrMethod("()Lorg/virtualbox_6_1/IMachine;")
org.virtualbox_6_1.IMachine getMachine();
@net.sf.jni4net.attributes.ClrMethod("()Lorg/virtualbox_6_1/IConsole;")
org.virtualbox_6_1.IConsole getConsole();
@net.sf.jni4net.attributes.ClrMethod("()LSystem/UInt32;")
int getInternalAndReservedAttribute1ISession();
@net.sf.jni4net.attributes.ClrMethod("()LSystem/UInt32;")
int getInternalAndReservedAttribute2ISession();
@net.sf.jni4net.attributes.ClrMethod("()LSystem/UInt32;")
int getInternalAndReservedAttribute3ISession();
@net.sf.jni4net.attributes.ClrMethod("()LSystem/UInt32;")
int getInternalAndReservedAttribute4ISession();
@net.sf.jni4net.attributes.ClrMethod("()LSystem/UInt32;")
int getInternalAndReservedAttribute5ISession();
@net.sf.jni4net.attributes.ClrMethod("()LSystem/UInt32;")
int getInternalAndReservedAttribute6ISession();
@net.sf.jni4net.attributes.ClrMethod("()LSystem/UInt32;")
int getInternalAndReservedAttribute7ISession();
@net.sf.jni4net.attributes.ClrMethod("()LSystem/UInt32;")
int getInternalAndReservedAttribute8ISession();
@net.sf.jni4net.attributes.ClrMethod("()V")
void unlockMachine();
@net.sf.jni4net.attributes.ClrMethod("()V")
void internalAndReservedMethod1ISession();
@net.sf.jni4net.attributes.ClrMethod("()V")
void internalAndReservedMethod2ISession();
@net.sf.jni4net.attributes.ClrMethod("()V")
void internalAndReservedMethod3ISession();
@net.sf.jni4net.attributes.ClrMethod("()V")
void internalAndReservedMethod4ISession();
//</generated-interface>
}

View file

@ -0,0 +1,5 @@
package org.virtualbox_6_1;
public enum SessionState {
Locked
}

View file

@ -1,41 +1,44 @@
package sznp.virtualcomputer;
import lombok.RequiredArgsConstructor;
import net.sf.jni4net.Ref;
import org.virtualbox_6_1.BitmapFormat;
import org.virtualbox_6_1.FramebufferCapabilities;
import org.virtualbox_6_1.IFramebuffer;
import org.virtualbox_6_1.IFramebufferOverlay;
import system.Array;
import sznp.virtualcomputer.util.IMCFrameBuffer;
import virtualcomputerwindows.Exports;
import java.util.Arrays;
@RequiredArgsConstructor
public class COMFrameBuffer {
public class COMFrameBuffer implements IFramebuffer {
private final IMCFrameBuffer frameBuffer;
public long getBitsPerPixel() {
public int getBitsPerPixel() {
return 32;
}
public long getBytesPerLine() {
return 640L;
public int getBytesPerLine() {
return 640;
}
public long[] getCapabilities(long[] arg0) {
public Array getCapabilities_FixIt() {
try {
System.out.println("Capabilities queried");
System.out.println("Capabilities: " + Arrays.toString(arg0));
return new long[]{FramebufferCapabilities.UpdateImage.value()};
//return new long[]{FramebufferCapabilities.UpdateImage.value()};
return Array.CreateInstance(system.Type.GetType("System.Int32"), 0);
} catch (Exception e) {
e.printStackTrace();
return new long[]{};
return Array.CreateInstance(system.Type.GetType("System.Int32"), 0);
}
}
public long getHeight() {
public int getHeight() {
return 480;
}
public long getHeightReduction() {
public int getHeightReduction() {
return 0;
}
@ -43,15 +46,16 @@ public class COMFrameBuffer {
return null;
}
public long getPixelFormat() {
return BitmapFormat.BGRA.value();
public BitmapFormat getPixelFormat_FixIt() {
//return BitmapFormat.BGRA.value();
return null;
}
public long getVisibleRegion(byte arg0, long arg1) {
public int getVisibleRegion(Ref<Byte> arg0, int arg1) {
return 0;
}
public long getWidth() {
public int getWidth() {
return 640;
}
@ -59,23 +63,23 @@ public class COMFrameBuffer {
return 0; // Zero means no win id
}
public void notify3DEvent(long type, byte[] data) {
System.out.println("3D event! " + type + " - " + Arrays.toString(data));
public void notify3DEvent_FixIt(int type, Array data) {
System.out.println("3D event! " + type + " - " + Arrays.toString(Exports.ConvertArrayByte(data)));
}
public void notifyChange(long screenId, long xOrigin, long yOrigin, long width, long height) {
public void notifyChange(int screenId, int xOrigin, int yOrigin, int width, int height) {
frameBuffer.notifyChange(screenId, xOrigin, yOrigin, width, height);
}
public void notifyUpdate(long x, long y, long width, long height) {
public void notifyUpdate(int x, int y, int width, int height) {
frameBuffer.notifyUpdate(x, y, width, height);
}
public void notifyUpdateImage(long arg0, long arg1, long arg2, long arg3, byte[] arg4) {
frameBuffer.notifyUpdateImage(arg0, arg1, arg2, arg3, arg4);
public void notifyUpdateImage_FixIt(int arg0, int arg1, int arg2, int arg3, Array arg4) {
frameBuffer.notifyUpdateImage(arg0, arg1, arg2, arg3, Exports.ConvertArrayByte(arg4));
}
public void setVisibleRegion(byte arg0, long arg1) {
public void setVisibleRegion(Ref<Byte> arg0, int arg1) {
}
/**
@ -87,11 +91,11 @@ public class COMFrameBuffer {
* @param enmCmd The validated VBOXVHWACMD::enmCmd value from the command.
* @param fromGuest Set when the command origins from the guest, clear if host.
*/ //https://www.virtualbox.org/browser/vbox/trunk/src/VBox/Frontends/VirtualBox/src/VBoxFBOverlay.cpp#L4645
public void processVHWACommand(byte command, int enmCmd, boolean fromGuest) {
public void processVHWACommand(Ref<Byte> command, int enmCmd, int fromGuest) {
}
public boolean videoModeSupported(long arg0, long arg1, long arg2) {
return true;
public int videoModeSupported(int arg0, int arg1, int arg2) {
return 1;
}
}

View file

@ -1,13 +1,13 @@
package sznp.virtualcomputer;
import org.virtualbox_6_1.IEvent;
import sznp.virtualcomputer.util.COMObjectBase;
import org.virtualbox_6_1.IEventListener;
import sznp.virtualcomputer.util.IEventHandler;
/**
* A Bukkit-like event system which calls the appropriate methods on an event.
*/
public final class EventHandler extends COMObjectBase {
public final class EventHandler implements IEventListener {
private final IEventHandler handler;
private boolean enabled = true;
@ -20,6 +20,7 @@ public final class EventHandler extends COMObjectBase {
this.handler = handler;
}
@Override
public final void handleEvent(IEvent iEvent) {
if (!enabled)
return;

View file

@ -1,10 +0,0 @@
package sznp.virtualcomputer.util;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
public abstract class COMObjectBase extends Dispatch {
public COMObjectBase() {
super("clsid:{67099191-32E7-4F6C-85EE-422304C71B90}");
}
}

View file

@ -1,52 +1,55 @@
package sznp.virtualcomputer.util;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.*;
import lombok.val;
import net.sf.jni4net.Out;
import org.virtualbox_6_1.*;
import org.virtualbox_6_1.mscom.Helper;
import org.virtualbox_6_1.mscom.IUnknown;
import sznp.virtualcomputer.COMFrameBuffer;
import sznp.virtualcomputer.EventHandler;
import virtualcomputerwindows.Exports;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
public final class COMUtils {
private COMUtils() {
}
private COMUtils() {
}
//public static void registerListener(IEventSource source, IEventListener listener, VBoxEventType... types) {
public static org.virtualbox_6_1.IEventListener registerListener(IEventSource source, IEventHandler listener, List<VBoxEventType> types) {
//new DispatchEvents(source.getTypedWrapped(), listener);
val ret = new org.virtualbox_6_1.IEventListener(new EventHandler(listener));
//public static void registerListener(IEventSource source, IEventListener listener, VBoxEventType... types) {
public static IEventListener registerListener(IEventSource source, IEventHandler listener, List<VBoxEventType> types) {
//new DispatchEvents(source.getTypedWrapped(), listener);
val ret = new EventHandler(listener);
/*com.jacob.activeX.ActiveXComponent.createNewInstance("IEventListener");
new ActiveXComponent("");
source.registerListener(ret, types, true);*/
//registerListener(source, new EventHandler(listener), types, true);
System.out.println("Testing listener...");
ret.handleEvent(null);
System.out.println("Tested");
return ret;
//return null;
}
//registerListener(source, new EventHandler(listener), types, true);
System.out.println("Testing listener...");
ret.handleEvent(null);
System.out.println("Tested");
return ret;
//return null;
}
@SuppressWarnings("unchecked")
public static <T extends IEvent> T getEvent(IEvent event, Class<T> cl) {
try {
val method = cl.getMethod("queryInterface", IUnknown.class);
return (T) method.invoke(null, event);
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
return null;
}
}
@SuppressWarnings("unchecked")
public static <T extends IEvent> T getEvent(IEvent event, Class<T> cl) {
//val method = cl.getMethod("queryInterface", IUnknown.class);
//return (T) method.invoke(null, event);
return null; //TODO
}
public static IFramebuffer gimmeAFramebuffer(IMCFrameBuffer frameBuffer) {
return new IFramebuffer(new Variant(new COMFrameBuffer(frameBuffer)).getDispatch());
}
public static IFramebuffer gimmeAFramebuffer(IMCFrameBuffer frameBuffer) {
return new COMFrameBuffer(frameBuffer);
}
public static void queryBitmapInfo(IDisplaySourceBitmap bitmap, long[] ptr, long[] w, long[] h, long[] bpp, long[] bpl, long[] pf) {
Dispatch.call(bitmap.getTypedWrapped(), "queryBitmapInfo", ptr, w, h, bpp, bpl, pf);
}
public static void queryBitmapInfo(IDisplaySourceBitmap bitmap, long[] ptr, long[] w, long[] h, long[] bpp, long[] bpl, long[] pf) {
Out<Integer> wo = new Out<>(), ho = new Out<>(), bppo = new Out<>(), bplo = new Out<>();
val pfo = new Out<BitmapFormat>();
val ptro = new Out<Long>();
bitmap.queryBitmapInfo(ptro, wo, ho, bppo, bplo, pfo);
ptr[0] = ptro.getValue();
w[0] = wo.getValue();
h[0] = ho.getValue();
bpp[0] = bppo.getValue();
bpl[0] = bplo.getValue();
pf[0] = Exports.ConvertEnum(pfo.getValue());
}
}

View file

@ -17,7 +17,7 @@ namespace VirtualComputerWindows
private static VirtualBoxClient vbc;
public static async Task<IVirtualBox> Init() => await Task.Run(() =>
public static void Init()
{
try
{
@ -27,7 +27,7 @@ namespace VirtualComputerWindows
//https://www.virtualbox.org/svn/vbox/trunk/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp
vbc = new VirtualBoxClientClass();
var vbox = vbc.VirtualBox;
RTR3InitExe(0, "", 0);
//RTR3InitExe(0, "", 0);
var ses = vbc.Session;
var machine = vbox.Machines.GetValue(0) as IMachine;
ses.Name = "minecraft";
@ -38,22 +38,39 @@ namespace VirtualComputerWindows
machine = ses.Machine;
Console.WriteLine("Powering up...");
ses.Console.PowerUp().WaitForCompletion(10000);
Console.WriteLine("Framebuffer attach");
ses.Console.Display.AttachFramebuffer(0, new VBFB(ses.Console.Display));
return vbox;
}
catch(Exception e)
{
Console.WriteLine(e);
Console.ReadLine();
return null;
}
});
}
public static void Main()
{
Init();
Console.ReadLine();
}
public static int[] ConvertArrayInt(Array array)
{
return (int[]) array;
}
public static byte[] ConvertArrayByte(Array array)
{
return (byte[]) array;
}
public static uint[] ConvertArrayUint(Array array)
{
return (uint[]) array;
}
public static int ConvertEnum(object someEnum)
{
BitmapFormat.BitmapFormat_RGBA;
return (int) someEnum;
}
}
}

View file

@ -1,75 +0,0 @@
using System;
using VirtualBox;
namespace VirtualComputerWindows
{
internal class VBFB : IFramebuffer
{
private IDisplay display;
public VBFB(IDisplay display)
{
this.display = display;
}
public void NotifyUpdate(uint aX, uint aY, uint aWidth, uint aHeight)
{
Console.WriteLine("Update: " + aX + " " + aY + " " + aWidth + " " + aHeight);
}
public void NotifyUpdateImage(uint aX, uint aY, uint aWidth, uint aHeight, Array aImage)
{
Console.WriteLine("UpdateImage: " + aX + " " + aY + " " + aWidth + " " + aHeight);
}
public void NotifyChange(uint aScreenId, uint aXOrigin, uint aYOrigin, uint aWidth, uint aHeight)
{
Console.WriteLine("Change: " + aXOrigin + " " + aYOrigin + " " + aWidth + " " + aHeight);
display.QuerySourceBitmap(0, out var isd);
var addr = new IntPtr();
isd.QueryBitmapInfo(addr, out var w, out var h, out var bpp, out var bpl, out var bf);
Console.WriteLine("Bitmap info: " + addr + " " + w + " " + h + " " + bpp + " " + bpl + " " + bf);
}
public int VideoModeSupported(uint aWidth, uint aHeight, uint aBpp)
{
return 1;
}
public uint GetVisibleRegion(ref byte aRectangles, uint aCount)
{
return aCount;
}
public void SetVisibleRegion(ref byte aRectangles, uint aCount)
{
}
public void ProcessVHWACommand(ref byte aCommand, int aEnmCmd, int aFromGuest)
{
}
public void Notify3DEvent(uint aType, Array aData)
{
}
public uint Width => 640;
public uint Height => 480;
public uint BitsPerPixel => 32;
public uint BytesPerLine => 640 * 4;
public BitmapFormat PixelFormat => BitmapFormat.BitmapFormat_BGRA;
public uint HeightReduction => 0;
public IFramebufferOverlay Overlay => null;
public long WinId => 0;
//public Array Capabilities => new[] { FramebufferCapabilities.FramebufferCapabilities_UpdateImage };
public Array Capabilities => new FramebufferCapabilities[] { };
}
}

View file

@ -9,7 +9,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>VirtualComputerWindows</RootNamespace>
<AssemblyName>VirtualComputerWindows</AssemblyName>
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
<DllExportNamespace>VirtualComputerWindows</DllExportNamespace>
@ -93,7 +93,6 @@
<ItemGroup>
<Compile Include="Exports.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="VBFB.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />

View file

@ -1,15 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Runtime" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.0.0" newVersion="4.1.0.0" />
<assemblyIdentity name="System.Runtime" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-4.1.0.0" newVersion="4.1.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime.InteropServices" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.0.0" newVersion="4.1.0.0" />
<assemblyIdentity name="System.Runtime.InteropServices" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-4.1.0.0" newVersion="4.1.0.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1"/></startup></configuration>

16
pom.xml
View file

@ -8,9 +8,7 @@
<artifactId>VirtualComputer</artifactId>
<version>2.1-SNAPSHOT</version>
<modules>
<module>VirtualComputerXPCOM</module>
<module>VirtualComputer-Core</module>
<module>VirtualComputerMSCOM</module>
</modules>
<packaging>pom</packaging>
@ -127,4 +125,18 @@
</plugins>
</pluginManagement>
</build>
<profiles>
<profile>
<id>XPCOM</id>
<modules>
<module>VirtualComputerXPCOM</module>
</modules>
</profile>
<profile>
<id>MSCOM</id>
<modules>
<module>VirtualComputerMSCOM</module>
</modules>
</profile>
</profiles>
</project>

View file

@ -7,6 +7,6 @@
<versions>
<version>1.19</version>
</versions>
<lastUpdated>20200811112851</lastUpdated>
<lastUpdated>20200811224130</lastUpdated>
</versioning>
</metadata>