Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/** j-Interop (Pure Java implementation of DCOM protocol)
* Copyright (C) 2006 Vikram Roopchand
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* Though a sincere effort has been made to deliver a professional,
* quality product,the library itself is distributed WITHOUT ANY WARRANTY;
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*/
package org.jinterop.dcom.core;
import com.iwombat.foundation.IdentifierFactory;
import com.iwombat.util.GUIDUtil;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.channels.ClosedByInterruptException;
import java.nio.channels.ServerSocketChannel;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Random;
import java.util.logging.Level;
import jcifs.smb.SmbAuthException;
import jcifs.smb.SmbException;
import ndr.NdrBuffer;
import ndr.NdrException;
import ndr.NdrObject;
import ndr.NetworkDataRepresentation;
import org.jinterop.dcom.common.IJICOMRuntimeWorker;
import org.jinterop.dcom.common.JIErrorCodes;
import org.jinterop.dcom.common.JIException;
import org.jinterop.dcom.common.JIRuntimeException;
import org.jinterop.dcom.common.JISystem;
import org.jinterop.dcom.transport.JIComRuntimeEndpoint;
import org.jinterop.dcom.transport.JIComRuntimeTransportFactory;
import rpc.Stub;
import rpc.core.UUID;
/**
* Used to manipulate Oxid details. one instance is created per binding call to
* the oxid resolver.
*
* @since 1.0
*
*/
final class JIComOxidRuntimeHelper extends Stub {
JIComOxidRuntimeHelper(Properties properties) {
super.setTransportFactory(JIComRuntimeTransportFactory.getSingleTon());
super.setProperties(properties);
super.setAddress("127.0.0.1[135]");//this is never consulted so , putting localhost here.
}
@Override
protected String getSyntax() {
//return "99fcfec4-5260-101b-bbcb-00aa0021347a:0.0";//IOxidResolver IID
return UUID.NIL_UUID + ":0.0"; //returning nothing
}
void startOxid(int portNumLocal, int portNumRemote) throws IOException {
Thread oxidResolverThread = new Thread(new Runnable() {
@Override
public void run() {
try {
if (JISystem.getLogger().isLoggable(Level.INFO)) {
JISystem.getLogger().log(Level.INFO, "started startOxid thread: {0}", Thread.currentThread().getName());
}
attach();
((JIComRuntimeEndpoint) getEndpoint()).processRequests(new OxidResolverImpl(getProperties()), null, new ArrayList());
} catch (Exception e) {
if (JISystem.getLogger().isLoggable(Level.WARNING)) {
JISystem.getLogger().throwing("Oxid Resolver Thread", "run", e);
JISystem.getLogger().log(Level.WARNING, "Oxid Resolver Thread: {0} , on thread Id: {1}", new Object[]{e.getMessage(), Thread.currentThread().getName()});
}
} finally {
try {
getEndpoint().detach();
} catch (IOException e) {
}
}
if (JISystem.getLogger().isLoggable(Level.INFO)) {
JISystem.getLogger().log(Level.INFO, "terminating startOxid thread: {0}", Thread.currentThread().getName());
}
}
}, "jI_OxidResolver_Client[" + portNumLocal + " , " + portNumRemote + "]");
oxidResolverThread.setDaemon(true);
oxidResolverThread.start();
}
//returns the port to which the server is listening.
Object[] startRemUnknown(final String baseIID, final String ipidOfRemUnknown, final String ipidOfComponent, final List listOfSupportedInterfaces) throws IOException {
final ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
final ServerSocket serverSocket = serverSocketChannel.socket();//new ServerSocket(0);
// serverSocket.setSoTimeout(120*1000); //2 min timeout.
serverSocket.bind(null);
int remUnknownPort = serverSocket.getLocalPort();
//have to pick up a random name so adding the ipid of remunknown this is a uuid so the string is quite random.
final ThreadGroup remUnknownForThisListener = new ThreadGroup("ThreadGroup - " + baseIID + "[" + ipidOfRemUnknown + "]");
remUnknownForThisListener.setDaemon(true);
Thread remUnknownThread = new Thread(remUnknownForThisListener, new Runnable() {
@Override
public void run() {
if (JISystem.getLogger().isLoggable(Level.INFO)) {
JISystem.getLogger().log(Level.INFO, "started RemUnknown listener thread for : {0}", Thread.currentThread().getName());
}
try {
while (true) {
final Socket socket = serverSocket.accept();
if (JISystem.getLogger().isLoggable(Level.INFO)) {
JISystem.getLogger().log(Level.INFO, "RemUnknown listener: Got Connection from {0}", socket.getPort());
}
//now create the JIComOxidRuntimeHelper Object and start it. We need a new one since the old one is already attached to the listener.
final JIComOxidRuntimeHelper remUnknownHelper = new JIComOxidRuntimeHelper(getProperties());
synchronized (JIComOxidRuntime.mutex) {
JISystem.internal_setSocket(socket);
remUnknownHelper.attach();
}
//now start a new thread with this socket
Thread remUnknown = new Thread(remUnknownForThisListener, new Runnable() {
@Override
public void run() {
try {
((JIComRuntimeEndpoint) remUnknownHelper.getEndpoint()).processRequests(new RemUnknownObject(ipidOfRemUnknown, ipidOfComponent), baseIID, listOfSupportedInterfaces);
} catch (SmbAuthException e) {
JISystem.getLogger().log(Level.WARNING, "JIComOxidRuntimeHelper RemUnknownThread (not listener)", e);
throw new JIRuntimeException(JIErrorCodes.JI_CALLBACK_AUTH_FAILURE);
} catch (SmbException e) {
//System.out.println(e.getMessage());
JISystem.getLogger().log(Level.WARNING, "JIComOxidRuntimeHelper RemUnknownThread (not listener)", e);
throw new JIRuntimeException(JIErrorCodes.JI_CALLBACK_SMB_FAILURE);
} catch (ClosedByInterruptException e) {
JISystem.getLogger().log(Level.INFO, "JIComOxidRuntimeHelper RemUnknownThread (not listener){0} is purposefully closed by interruption.", Thread.currentThread().getName());
} catch (IOException e) {
JISystem.getLogger().log(Level.WARNING, "JIComOxidRuntimeHelper RemUnknownThread (not listener)", e);
} finally {
try {
remUnknownHelper.detach();
} catch (IOException e) {
}
}
}
}, "jI_RemUnknown[" + baseIID + " , L(" + socket.getLocalPort() + "):R(" + socket.getPort() + ")]");
remUnknown.setDaemon(true);
remUnknown.start();
}
} catch (ClosedByInterruptException e) {
JISystem.getLogger().log(Level.INFO, "JIComOxidRuntimeHelper RemUnknownListener{0} is purposefully closed by interruption.", Thread.currentThread().getName());
} catch (IOException e) {
if (JISystem.getLogger().isLoggable(Level.WARNING)) {
JISystem.getLogger().log(Level.WARNING, "JIComOxidRuntimeHelper RemUnknownListener", e);
JISystem.getLogger().log(Level.WARNING, "RemUnknownListener Thread: {0} , on thread Id: {1}", new Object[]{e.getMessage(), Thread.currentThread().getName()});
}
//e.printStackTrace();
} catch (Throwable e) {
if (JISystem.getLogger().isLoggable(Level.WARNING)) {
JISystem.getLogger().log(Level.WARNING, "JIComOxidRuntimeHelper RemUnknownListener", e);
}
}
if (JISystem.getLogger().isLoggable(Level.INFO)) {
JISystem.getLogger().log(Level.INFO, "terminating RemUnknownListener thread: {0}", Thread.currentThread().getName());
}
}
}, "jI_RemUnknownListener[" + baseIID + " , " + remUnknownPort + "]");
remUnknownThread.setDaemon(true);
remUnknownThread.start();
return new Object[]{new Integer(remUnknownPort), remUnknownForThisListener};
}
}
//This object should have serialized access only , i.e at a time only 1 read --> write , cycle should happen
// it is not multithreaded safe.
class OxidResolverImpl extends NdrObject implements IJICOMRuntimeWorker {
//override read\write\opnum etc. here, use the util apis to decompose this.
private int opnum = -1;
private NdrBuffer buffer = null;
private Properties p = null;
OxidResolverImpl(Properties p) {
super();
this.p = p;
}
@Override
public void setCurrentObjectID(UUID objectId) {
//does nothing.
}
// public void setCurrentJavaInstanceFromIID(String iid)
// {
// //does nothing.
// }
@Override
public void setOpnum(int opnum) {
this.opnum = opnum;
}
@Override
public int getOpnum() {
return opnum;
}
@Override
public void write(NetworkDataRepresentation ndr) {
ndr.setBuffer(buffer); //this buffer is prepared via read.
}
@Override
public void read(NetworkDataRepresentation ndr) {
//will read according to the opnum. The setOpnum should have been called before this
//call.
switch (opnum) {
case 1:
buffer = SimplePing(ndr);
break;
case 2:
buffer = ComplexPing(ndr);
break;
case 3: //ServerAlive
buffer = ServerAlive(ndr);
break;
case 5: //This is ServerAlive2
buffer = ServerAlive2(ndr);
break;
case 4: //This is ResolveOxid2
buffer = ResolveOxid2(ndr);
break;
default: //should not have arrived here.
if (JISystem.getLogger().isLoggable(Level.WARNING)) {
JISystem.getLogger().warning("Oxid Object: DEFAULTED !!!");
}
throw new JIRuntimeException(JIErrorCodes.RPC_S_PROCNUM_OUT_OF_RANGE);
}
}
private Random random = new Random(System.currentTimeMillis());
private NdrBuffer SimplePing(NetworkDataRepresentation ndr) {
if (JISystem.getLogger().isLoggable(Level.INFO)) {
JISystem.getLogger().info("Oxid Object: SimplePing");
}
byte b[] = JIMarshalUnMarshalHelper.readOctetArrayLE(ndr, 8);//setid
JIComOxidRuntime.addUpdateSets(new JISetId(b), new ArrayList(), new ArrayList());
buffer = new NdrBuffer(new byte[16], 0);
buffer.enc_ndr_long(0);
buffer.enc_ndr_long(0);
buffer.enc_ndr_long(0);
buffer.enc_ndr_long(0);
return buffer;
}
private NdrBuffer ComplexPing(NetworkDataRepresentation ndr) {
if (JISystem.getLogger().isLoggable(Level.INFO)) {
JISystem.getLogger().info("Oxid Object: ComplexPing");
}
byte b[] = JIMarshalUnMarshalHelper.readOctetArrayLE(ndr, 8);//setid
JIMarshalUnMarshalHelper.deSerialize(ndr, Short.class, null, JIFlags.FLAG_NULL, null);//seqId.
Short lengthAdds = (Short) JIMarshalUnMarshalHelper.deSerialize(ndr, Short.class, null, JIFlags.FLAG_NULL, null);//
Short lengthDels = (Short) JIMarshalUnMarshalHelper.deSerialize(ndr, Short.class, null, JIFlags.FLAG_NULL, null);//
JIMarshalUnMarshalHelper.deSerialize(ndr, Integer.class, null, JIFlags.FLAG_NULL, null);//
JIMarshalUnMarshalHelper.deSerialize(ndr, Integer.class, null, JIFlags.FLAG_NULL, null);//length
ArrayList listOfAdds = new ArrayList();
for (int i = 0; i < lengthAdds.intValue(); i++) {
listOfAdds.add(new JIObjectId(JIMarshalUnMarshalHelper.readOctetArrayLE(ndr, 8), false));
}
JIMarshalUnMarshalHelper.deSerialize(ndr, Integer.class, null, JIFlags.FLAG_NULL, null);//length
ArrayList listOfDels = new ArrayList();
for (int i = 0; i < lengthDels.intValue(); i++) {
listOfDels.add(new JIObjectId(JIMarshalUnMarshalHelper.readOctetArrayLE(ndr, 8), false));
}
if (Arrays.equals(b, new byte[]{0, 0, 0, 0, 0, 0, 0, 0})) {
random.nextBytes(b);
}
JIComOxidRuntime.addUpdateSets(new JISetId(b), listOfAdds, listOfDels);
buffer = new NdrBuffer(new byte[32], 0);
NetworkDataRepresentation ndr2 = new NetworkDataRepresentation();
ndr2.setBuffer(buffer);
JIMarshalUnMarshalHelper.writeOctetArrayLE(ndr2, b);
JIMarshalUnMarshalHelper.serialize(ndr2, Short.class, new Short((short) 0), null, JIFlags.FLAG_NULL);
JIMarshalUnMarshalHelper.serialize(ndr2, Integer.class, new Integer(0), null, JIFlags.FLAG_NULL);//hresult
return buffer;
}
private NdrBuffer ServerAlive(NetworkDataRepresentation ndr) {
if (JISystem.getLogger().isLoggable(Level.INFO)) {
JISystem.getLogger().info("Oxid Object: ServerAlive");
}
byte[] buffer = new byte[32]; //16 + 16=just in case
NdrBuffer ndrBuffer = new NdrBuffer(buffer, 0);
ndrBuffer.enc_ndr_long(0);
ndrBuffer.enc_ndr_long(0);
ndrBuffer.enc_ndr_long(0);
ndrBuffer.enc_ndr_long(0);
return ndrBuffer;
}
private NdrBuffer ServerAlive2(NetworkDataRepresentation ndr) {
if (JISystem.getLogger().isLoggable(Level.INFO)) {
JISystem.getLogger().info("Oxid Object: ServerAlive2");
}
//there is no in params for this.
//only out params
//want no port information associated with this.
// byte[] buffer = new byte[120];
// FileInputStream inputStream;
// try {
// inputStream = new FileInputStream("c:/serveralive2");
// inputStream.read(buffer,0,120);
// } catch (Exception e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
//
// NdrBuffer ndrBuffer = new NdrBuffer(buffer,0);
JIDualStringArray dualStringArray = new JIDualStringArray(-1);
byte[] buffer = new byte[dualStringArray.getLength() + 4 /* COMVERSION */ + 16 /* 2 unknown 8 bytes */ + 16/* just in case */];
NdrBuffer ndrBuffer = new NdrBuffer(buffer, 0);
NetworkDataRepresentation ndr2 = new NetworkDataRepresentation();
ndr2.setBuffer(ndrBuffer);
//serialize COMVERSION
JIMarshalUnMarshalHelper.serialize(ndr2, Short.class, new Short((short) JISystem.getCOMVersion().getMajorVersion()), null, JIFlags.FLAG_NULL);
JIMarshalUnMarshalHelper.serialize(ndr2, Short.class, new Short((short) JISystem.getCOMVersion().getMinorVersion()), null, JIFlags.FLAG_NULL);
JIMarshalUnMarshalHelper.serialize(ndr2, Integer.class, new Integer(0), null, JIFlags.FLAG_NULL);
JIMarshalUnMarshalHelper.serialize(ndr2, Integer.class, new Integer(dualStringArray.getLength()), null, JIFlags.FLAG_NULL);
dualStringArray.encode(ndr2);
JIMarshalUnMarshalHelper.serialize(ndr2, Integer.class, new Integer(0), null, JIFlags.FLAG_NULL);
JIMarshalUnMarshalHelper.serialize(ndr2, Integer.class, new Integer(0), null, JIFlags.FLAG_NULL);
return ndrBuffer;
}
//will prepare a NdrBuffer for reply to this call
private NdrBuffer ResolveOxid2(NetworkDataRepresentation ndr) {
if (JISystem.getLogger().isLoggable(Level.INFO)) {
JISystem.getLogger().info("Oxid Object: ResolveOxid2");
}
//System.err.println("VIKRAM: resolve oxid thread Id = " + Thread.currentThread().getId());
//first read the OXID, then consult the oxid master about it's details.
JIOxid oxid = new JIOxid(JIMarshalUnMarshalHelper.readOctetArrayLE(ndr, 8));
//now get the RequestedProtoSeq length.
int length = ((Number) JIMarshalUnMarshalHelper.deSerialize(ndr, Short.class, null, JIFlags.FLAG_NULL, null)).intValue();
//now for the array.
JIArray array = (JIArray) JIMarshalUnMarshalHelper.deSerialize(ndr, new JIArray(Short.class, null, 1, true), null, JIFlags.FLAG_REPRESENTATION_ARRAY, null);
//now query the Resolver master for this data.
JIComOxidDetails details = JIComOxidRuntime.getOxidDetails(oxid);
if (details == null) {
//not found, now throw an JIRuntimeException , so that a FaultPdu could be sent.
throw new JIRuntimeException(JIErrorCodes.RPC_E_INVALID_OXID);
}
// byte[] buffer = new byte[424];
// FileInputStream inputStream;
// try {
// inputStream = new FileInputStream("c:/resolveoxid2");
// inputStream.read(buffer,0,424);
// } catch (Exception e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
//
// try {
// details.getCOMRuntimeHelper().startRemUnknown();
// } catch (IOException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
//
// NdrBuffer ndrBuffer = new NdrBuffer(buffer,0);
//
//randomly create IPID and send, this is the ipid of the remunknown, we store it with remunknown object
UUID uuid = details.getRemUnknownIpid() == null ? new UUID(GUIDUtil.guidStringFromHexString(IdentifierFactory.createUniqueIdentifier().toHexString())) : new UUID(details.getRemUnknownIpid());
//create the bindings for this Java Object.
//this port will go in the new bindings sent to the COM client.
int port = -1;
try {
//this is so that repeated calls for Oxid resolution return the same rem unknwon.
port = details.getPortForRemUnknown();
if (port == -1) {
String remunknownipid = uuid.toString();
Object[] portandthread = details.getCOMRuntimeHelper().startRemUnknown(details.getIID(), remunknownipid, details.getIpid(), details.getReferent().getSupportedInterfaces());
port = ((Number) portandthread[0]).intValue();
details.setRemUnknownThreadGroup((ThreadGroup) portandthread[1]);
details.setRemUnknownIpid(remunknownipid);
}
details.setPortForRemUnknown(port);
} catch (IOException e) {
throw new JIRuntimeException(JIErrorCodes.E_UNEXPECTED);
}
//can support only TCP connections
//JIDualStringArray.test = true;
JIDualStringArray dualStringArray = new JIDualStringArray(port);
Integer authnHint = new Integer(details.getProtectionLevel());
byte[] buffer = new byte[4 + 4 + dualStringArray.getLength() + 16 + 4 + 2 + 2 + 4 + 16];
//have all data now prepare the response
//the response expected here is defines the byte array size.
NdrBuffer ndrBuffer = new NdrBuffer(buffer, 0);
NetworkDataRepresentation ndr2 = new NetworkDataRepresentation();
ndr2.setBuffer(ndrBuffer);
JIMarshalUnMarshalHelper.serialize(ndr2, Integer.class, new Integer(new Object().hashCode()), null, JIFlags.FLAG_NULL);
JIMarshalUnMarshalHelper.serialize(ndr2, Integer.class, new Integer((dualStringArray.getLength() - 4) / 2), null, JIFlags.FLAG_NULL);
dualStringArray.encode(ndr2);
JIMarshalUnMarshalHelper.serialize(ndr2, UUID.class, uuid, null, JIFlags.FLAG_NULL);
JIMarshalUnMarshalHelper.serialize(ndr2, Integer.class, authnHint, null, JIFlags.FLAG_NULL);
JIMarshalUnMarshalHelper.serialize(ndr2, Short.class, new Short((short) JISystem.getCOMVersion().getMajorVersion()), null, JIFlags.FLAG_NULL);
JIMarshalUnMarshalHelper.serialize(ndr2, Short.class, new Short((short) JISystem.getCOMVersion().getMinorVersion()), null, JIFlags.FLAG_NULL);
JIMarshalUnMarshalHelper.serialize(ndr2, Integer.class, new Integer(0), null, JIFlags.FLAG_NULL); //hresult
return ndrBuffer;
}
@Override
public List getQIedIIDs() {
return null;
}
@Override
public UUID getCurrentObjectID() {
return null;
}
@Override
public boolean isResolver() {
return true;
}
@Override
public void setCurrentIID(String iid) {
//does nothing
}
@Override
public boolean workerOver() {
//oxid resolver gets over when the client connected to it releases socket.
return false;
}
}
//This object should have serialized access only , i.e at a time only 1 read --> write , cycle should happen
//it is not multithreaded safe.
class RemUnknownObject extends NdrObject implements IJICOMRuntimeWorker {
//override read\write\opnum etc. here, use the util apis to decompose this.
private int opnum = -1;
private NdrBuffer buffer = null;
//component tells you the JILocalCoClass to act on , sent via the AlterContext calls
//for all Altercontexts with IRemUnknown , this will be null.
private JILocalCoClass component = null; //will hold the current instance to act on.
/* the component and object id duo work together. 1 component could export many ipids.
*
*/
//ObjectID tells you the IPID to act on, sent via the Request calls
private UUID objectId = null;
//this would be the ipid of this RemUnknownObject
private final String selfIPID;
private String currentIID = null;
private List listOfIIDsQIed = new ArrayList();
RemUnknownObject(String ipidOfme, String ipidOfComponent) {
selfIPID = ipidOfme;
mapOfIpidsVsRef.put(ipidOfComponent.toUpperCase(), new Integer(5));
}
//this list will get cleared after this call.
@Override
public List getQIedIIDs() {
return listOfIIDsQIed;
}
@Override
public boolean isResolver() {
return false;
}
@Override
public void setOpnum(int opnum) {
this.opnum = opnum;
}
@Override
public int getOpnum() {
return opnum;
}
@Override
public void write(NetworkDataRepresentation ndr) {
ndr.setBuffer(buffer); //this buffer is prepared via read.
}
private static final JIStruct remInterfaceRef = new JIStruct();
static {
try {
remInterfaceRef.addMember(UUID.class);
remInterfaceRef.addMember(Integer.class);
remInterfaceRef.addMember(Integer.class);
} catch (JIException shouldnothappen) {
JISystem.getLogger().throwing("RemUnknownObject", "Static Initialiser", shouldnothappen);
}
}
private static final JIArray remInterfaceRefArray = new JIArray(remInterfaceRef, null, 1, true);
private Map mapOfIpidsVsRef = new HashMap();
private boolean workerOver = false;
@Override
public void read(NetworkDataRepresentation ndr) {
//will read according to the opnum. The setOpnum should have been called before this
//call.
String ipid = objectId.toString();
// if (!mapOfIpidsVsRef.containsKey(ipid.toUpperCase()))
// {
// System.out.println(Thread.currentThread() + " -->> " + ipid.toUpperCase());
// //we always give 5 references
// mapOfIpidsVsRef.put(ipid.toUpperCase(),new Integer(5));
// }
//this means the call came for IRemUnknown apis, since selfIpid is null or matches the objectID
//if (selfIPID == null || selfIPID.equalsIgnoreCase(ipid))
// if ("00000131-0000-0000-C000-000000000046".equalsIgnoreCase(currentIID))
if (selfIPID.equalsIgnoreCase(ipid)) {
switch (opnum) {
case 3: //IRemUnknown QI.
buffer = QueryInterface(ndr);
break;
case 4: //addref
JIOrpcThis.decode(ndr);
int length = ndr.readUnsignedShort();
int[] retvals = new int[length];
JIArray array = (JIArray) JIMarshalUnMarshalHelper.deSerialize(ndr, remInterfaceRefArray, new ArrayList(), JIFlags.FLAG_REPRESENTATION_ARRAY, new HashMap());
//saving the ipids with there references. considering public + private references together for now.
JIStruct[] structs = (JIStruct[]) array.getArrayInstance();
for (int i = 0; i < length; i++) {
String ipidref = structs[i].getMember(0).toString().toUpperCase();
int publicRefs = ((Number) structs[i].getMember(1)).intValue();
int privateRefs = ((Number) structs[i].getMember(2)).intValue();
if (!mapOfIpidsVsRef.containsKey(ipidref)) {
//this would be strange, since all the ipids we give should be part of the map already.
//have to set 0x80000003 (INVALID ARG here)
retvals[i] = 0x80000003;
continue;
}
int total = ((Number) mapOfIpidsVsRef.get(ipidref)).intValue() + publicRefs + privateRefs;
mapOfIpidsVsRef.put(ipidref, new Integer(total));
}
//preparing the response
buffer = new NdrBuffer(new byte[length * 4 + 16], 0);
NetworkDataRepresentation ndr2 = new NetworkDataRepresentation();
ndr2.setBuffer(buffer);
JIOrpcThat.encode(ndr2);
for (int i = 0; i < length; i++) {
buffer.enc_ndr_long(retvals[i]);
}
buffer.enc_ndr_long(0);
buffer.enc_ndr_long(0);
break;
case 5: //release
JIOrpcThis.decode(ndr);
length = ndr.readUnsignedShort();
array = (JIArray) JIMarshalUnMarshalHelper.deSerialize(ndr, remInterfaceRefArray, new ArrayList(), JIFlags.FLAG_REPRESENTATION_ARRAY, new HashMap());
//saving the ipids with there references. considering public + private references together for now.
structs = (JIStruct[]) array.getArrayInstance();
for (int i = 0; i < length; i++) {
String ipidref = structs[i].getMember(0).toString().toUpperCase();
int publicRefs = ((Number) structs[i].getMember(1)).intValue();
int privateRefs = ((Number) structs[i].getMember(2)).intValue();
if (!mapOfIpidsVsRef.containsKey(ipidref)) {
continue;
}
int total = ((Number) mapOfIpidsVsRef.get(ipidref)).intValue() - publicRefs - privateRefs;
if (total == 0) {
mapOfIpidsVsRef.remove(ipidref);
} else {
mapOfIpidsVsRef.put(ipidref, new Integer(total));
}
}
//all references to all IPIDs exported are over, this is now done.
if (mapOfIpidsVsRef.isEmpty()) {
workerOver = true;
}
//I have 1 OID == 1 IPID == 1 java instance.
buffer = new NdrBuffer(new byte[32], 0);
ndr2 = new NetworkDataRepresentation();
ndr2.setBuffer(buffer);
JIOrpcThat.encode(ndr2);
buffer.enc_ndr_long(0);
buffer.enc_ndr_long(0);
break;
default:
throw new JIRuntimeException(JIErrorCodes.RPC_S_PROCNUM_OUT_OF_RANGE);
}
} else {
//now use the objectId , just set in before this call to read. That objectId is the IPID on which the
//call is being made , and was previously exported during Q.I. The component value was filled during an
//alter context or bind, again made some calls before.
if (component == null) {
JISystem.getLogger().log(Level.SEVERE, "JIComOxidRuntimeHelper RemUnknownObject read(): component is null , opnum is {0} , IPID is {1} , selfIpid is {2}", new Object[]{opnum, ipid, selfIPID});
}
byte b[] = null;
Object result = null;
NetworkDataRepresentation ndr2 = new NetworkDataRepresentation();
int hresult = 0;
Object[] retArray = null;
try {
result = component.invokeMethod(ipid, opnum, ndr);
} catch (JIException e) {
hresult = e.getErrorCode();
JISystem.getLogger().log(Level.SEVERE, "Exception occured: {0}", e.getErrorCode());
JISystem.getLogger().throwing("RemUnknownObject", "read", e);
}
//now if opnum was 6 then this is a dispatch call , so response has to be dispatch response
//not the normal one.
if (component.getInterfaceDefinitionFromIPID(ipid).isDispInterface() && opnum == 6) {
Object result2 = result;
//orpcthat
//[out] VARIANT * pVarResult,
//[out] EXCEPINFO * pExcepInfo,
//[out] UINT * pArgErr,
//[in, out, size_is(cVarRef)] VARIANTARG * rgVarRef
result = new Object[4]; //orpcthat gets filled outside
JIStruct excepInfo = new JIStruct();
try {
excepInfo.addMember(new Short((short) 0));
excepInfo.addMember(new Short((short) 0));
excepInfo.addMember(new JIString(""));
excepInfo.addMember(new JIString(""));
excepInfo.addMember(new JIString(""));
excepInfo.addMember(new Integer(0));
excepInfo.addMember(new JIPointer(null, true));
excepInfo.addMember(new JIPointer(null, true));
excepInfo.addMember(new Integer(0));
} catch (JIException e) {//not expecting any here
e.printStackTrace();
}
if (result2 == null) {
((Object[]) result)[0] = JIVariant.EMPTY();
} else {
//now check whether the variant is by ref or not.
JIVariant variant = (JIVariant) ((Object[]) result2)[0];
try {
if (variant.isByRefFlagSet()) {
//add empty inplace of this.
((Object[]) result)[0] = JIVariant.EMPTY();
//now update the array at the end.
((Object[]) result)[3] = new JIArray(new JIVariant[]{variant}, true);
} else {
((Object[]) result)[0] = ((Object[]) result2)[0]; //will have only a single index.
((Object[]) result)[3] = new Integer(0); //Array
}
} catch (JIException e) {
throw new JIRuntimeException(e.getErrorCode());
}
}
((Object[]) result)[1] = excepInfo;
((Object[]) result)[2] = new Integer(0); //argErr is null, for now.
retArray = (Object[]) result;
}
buffer = new NdrBuffer(b, 0);
ndr2.setBuffer(buffer);
//JIOrpcThat.encode(ndr2);
//have to create a call Object, since these return types could be structs , unions etc. having deffered pointers
JICallBuilder callObject = new JICallBuilder();
callObject.attachSession(component.getSession());
if (result != null) {
if (retArray != null) {
//serialize all members sequentially.
for (int i = 0; i < retArray.length; i++) {
callObject.addInParamAsObject(retArray[i], JIFlags.FLAG_NULL);
}
} else {
//serialize all members sequentially.
for (int i = 0; i < ((Object[]) result).length; i++) {
callObject.addInParamAsObject(((Object[]) result)[i], JIFlags.FLAG_NULL);
}
}
}
callObject.write2(ndr2);
JIMarshalUnMarshalHelper.serialize(ndr2, Integer.class, new Integer(hresult), null, JIFlags.FLAG_NULL);
}
}
private NdrBuffer QueryInterface(NetworkDataRepresentation ndr) {
//now to decompose all
if (JISystem.getLogger().isLoggable(Level.FINEST)) {
JISystem.getLogger().finest("Within RemUnknownObject: QueryInterface");
JISystem.getLogger().log(Level.FINEST, "RemUnknownObject: [QI] Before call terminated listOfIIDsQIed are: {0}", listOfIIDsQIed);
}
JIOrpcThis.decode(ndr);
//now get the IPID and export the component with a new IPID and IID.
UUID ipid = new rpc.core.UUID();
try {
ipid.decode(ndr, ndr.getBuffer());
} catch (NdrException e) {
JISystem.getLogger().throwing("JIComOxidRuntimeHelper", "QueryInterface", e);
}
if (JISystem.getLogger().isLoggable(Level.FINEST)) {
JISystem.getLogger().log(Level.FINEST, "RemUnknownObject: [QI] IPID is {0}", ipid);
}
//set the JILocalCoClass., the ipid should not be null in this call.
JIComOxidDetails details = JIComOxidRuntime.getComponentFromIPID(ipid.toString());
if (details == null) {
//not found, now throw an JIRuntimeException , so that a FaultPdu could be sent.
throw new JIRuntimeException(JIErrorCodes.RPC_E_INVALID_OXID);
}
JILocalCoClass component = details.getReferent();
if (JISystem.getLogger().isLoggable(Level.FINEST)) {
JISystem.getLogger().log(Level.FINEST, "RemUnknownObject: [QI] JIJavcCoClass is {0}", component.getCoClassIID());
}
((Number) (JIMarshalUnMarshalHelper.deSerialize(ndr, Integer.class, null, JIFlags.FLAG_NULL, null))).intValue();//refs , don't really care about this.
int length = ((Number) (JIMarshalUnMarshalHelper.deSerialize(ndr, Short.class, null, JIFlags.FLAG_NULL, null))).intValue();//length of the requested Interfaces
JIArray array = (JIArray) JIMarshalUnMarshalHelper.deSerialize(ndr, new JIArray(UUID.class, null, 1, true), null, JIFlags.FLAG_REPRESENTATION_ARRAY, null);
//now to build the buffer and export the IIDs with new IPIDs
byte[] b = new byte[8 + 4 + 4 + length * (4 + 4 + 40) + 16];
NdrBuffer buffer = new NdrBuffer(b, 0);
//start with response
NetworkDataRepresentation ndr2 = new NetworkDataRepresentation();
ndr2.setBuffer(buffer);
JIOrpcThat.encode(ndr2);
//pointer
JIMarshalUnMarshalHelper.serialize(ndr2, Integer.class, new Integer(new Object().hashCode()), null, JIFlags.FLAG_NULL);
//length of array
JIMarshalUnMarshalHelper.serialize(ndr2, Integer.class, new Integer(length), null, JIFlags.FLAG_NULL);
Object[] arrayOfUUIDs = (Object[]) array.getArrayInstance();
for (int i = 0; i < arrayOfUUIDs.length; i++) {
UUID iid = (UUID) arrayOfUUIDs[i];
if (JISystem.getLogger().isLoggable(Level.FINEST)) {
JISystem.getLogger().log(Level.FINEST, "RemUnknownObject: [QI] Array iid[{0}] is {1}", new Object[]{i, iid});
}
//now for each QueryResult
try {
int hresult = 0;
String ipid2 = GUIDUtil.guidStringFromHexString(IdentifierFactory.createUniqueIdentifier().toHexString());
if (!component.isPresent(iid.toString())) {
hresult = JIErrorCodes.E_NOINTERFACE;
} else {
String tmpIpid = null;
try {
tmpIpid = component.getIpidFromIID(iid.toString());
} catch (Exception e) {
JISystem.getLogger().throwing("JIComOxidRuntimeHelper", "QueryInterface", e);
}
if (tmpIpid == null) {
if (JISystem.getLogger().isLoggable(Level.FINEST)) {
JISystem.getLogger().log(Level.FINEST, "RemUnknownObject: [QI] tmpIpid is null for iid {0}", iid);
}
component.exportInstance(iid.toString(), ipid2);
} else {
if (JISystem.getLogger().isLoggable(Level.FINEST)) {
JISystem.getLogger().log(Level.FINEST, "RemUnknownObject: [QI] tmpIpid is NOT null for iid {0} and ipid sent back is {1}", new Object[]{iid, ipid2});
}
ipid2 = tmpIpid;
}
}
//hresult
JIMarshalUnMarshalHelper.serialize(ndr2, Integer.class, new Integer(hresult), null, JIFlags.FLAG_NULL);
JIMarshalUnMarshalHelper.serialize(ndr2, Integer.class, new Integer(0xCCCCCCCC), null, JIFlags.FLAG_NULL);
//now generate the IPID and export a java instance with this.
JIStdObjRef objRef = new JIStdObjRef(ipid2, details.getOxid(), details.getOid());
objRef.encode(ndr2);
//add it to the exported Ipids map
mapOfIpidsVsRef.put(ipid2.toUpperCase(), new Integer(objRef.getPublicRefs()));
if (JISystem.getLogger().isLoggable(Level.FINEST)) {
JISystem.getLogger().log(Level.FINEST, "RemUnknownObject: [QI] for which the stdObjRef is {0}", objRef);
}
} catch (IllegalAccessException e) {
JISystem.getLogger().throwing("JIComOxidRuntimeHelper", "QueryInterface", e);
} catch (InstantiationException e) {
JISystem.getLogger().throwing("JIComOxidRuntimeHelper", "QueryInterface", e);
}
String iidtemp = iid.toString().toUpperCase() + ":0.0";
if (!listOfIIDsQIed.contains(iidtemp)) {
listOfIIDsQIed.add(iidtemp);
}
}
if (JISystem.getLogger().isLoggable(Level.FINEST)) {
JISystem.getLogger().log(Level.FINEST, "RemUnknownObject: [QI] After call terminated listOfIIDsQIed are: {0}", listOfIIDsQIed);
}
return buffer;
}
//for all remunknown methods and calls component is null, alter context for IRemUnknown will make this
//null.
// public void setCurrentJavaInstanceFromIID(String iid)
// {
// int i = iid.indexOf(":");
// if (i != -1)
// {
// iid = iid.substring(0,i);
// }
// this.component = JIComOxidRuntime.getJavaComponentForIID(iid);
// if (component == null)
// {
// objectId = null;
// }
// }
@Override
public void setCurrentObjectID(UUID objectId) {
this.objectId = objectId;
component = JIComOxidRuntime.getJavaComponentFromIPID(objectId.toString());
}
@Override
public UUID getCurrentObjectID() {
return objectId;
}
@Override
public void setCurrentIID(String iid) {
this.currentIID = iid;
}
@Override
public boolean workerOver() {
return workerOver;
}
}