5 #define WIN32_LEAN_AND_MEAN
7 static WSADATA wsaData;
9 #elif defined(__unix__) || defined(__APPLE__)
16 #include <netinet/in.h>
18 #include <sys/socket.h>
20 #include <sys/types.h>
22 #include <arpa/inet.h>
27 typedef struct hostent HOSTENT;
28 typedef struct sockaddr SOCKADDR;
29 typedef struct sockaddr_in SOCKADDR_IN;
30 typedef struct in_addr IN_ADDR;
31 #define closesocket(s) close(s)
39 static enum DCOMPacketType
41 dcom_CreateInstance = 3,
43 dcom_CallVirtualMethod = 6,
44 dcom_InstanceCreated = 9,
45 dcom_VirtualMethodReturned = 10,
46 dcom_MethodReturned = 11
49 static class DCOMPacket : Packet
53 static class CreateInstancePacket : DCOMPacket
59 static class ObjectCreatedPacket : DCOMPacket
61 unsigned int objectID;
64 static class CallMethodPacket : DCOMPacket
68 unsigned int argsSize;
72 static class CallVirtualMethodPacket : DCOMPacket
75 unsigned int argsSize;
79 static class MethodReturnedPacket : DCOMPacket
81 unsigned int argsSize;
85 static class VirtualMethodReturnedPacket : DCOMPacket
87 unsigned int objectID;
89 unsigned int argsSize;
93 public class DCOMServerObject
98 virtual void CallMethod(unsigned int __ecereMethodID, SerialBuffer __ecereBuffer);
100 dllexport bool CallVirtualMethod(unsigned int methodID)
102 if(serverSocket && serverSocket.connected)
104 unsigned int size = (uint)&((CallVirtualMethodPacket)0).args + virtualsBuffer.size; // sizeof(class CallVirtualMethodPacket) + virtualsBuffer.size - 1;
105 CallVirtualMethodPacket packet = (CallVirtualMethodPacket)new0 byte[size];
106 packet.type = (DCOMPacketType)htoled((DCOMPacketType)dcom_CallVirtualMethod);
108 packet.methodID = htoled(methodID);
109 packet.argsSize = htoled(virtualsBuffer.size);
110 virtualsBuffer.ReadData(packet.args, virtualsBuffer.size);
113 serverSocket.SendPacket(packet);
116 while(serverSocket && !answered)
118 if(GetCurrentThreadID() == serverSocket.thread.id)
119 serverSocket.Process();
121 serverSocket.thread.semaphore.Wait();
123 return overridden == true;
128 DCOMServerSocket serverSocket;
130 SerialBuffer buffer { };
131 SerialBuffer virtualsBuffer { };
132 bool answered, overridden;
135 #define GETLEDWORD(b) (uint32)(((b)[3] << 24) | ((b)[2] << 16) | ((b)[1] << 8) | (b)[0])
137 #define PUTLEDWORD(b, d) \
138 (b)[3] = (byte)(((d) >> 24) & 0xFF); \
139 (b)[2] = (byte)(((d) >> 16) & 0xFF); \
140 (b)[1] = (byte)(((d) >> 8) & 0xFF); \
141 (b)[0] = (byte)( (d) & 0xFF);
143 static uint32 htoled(uint32 value)
146 PUTLEDWORD((byte *)&result, value);
150 static uint32 letohd(uint32 value)
152 return GETLEDWORD((byte *)&value);
155 class DCOMServerThread : Thread
158 Semaphore semaphore { };
173 class DCOMClientThread : Thread
176 Semaphore semaphore { };
191 /*static */public class DCOMServerSocket : Socket
194 DCOMServerObject * objects;
196 DCOMServerThread thread
198 socket = this, connected = true;
201 void OnReceivePacket(DCOMPacket packet)
203 switch((DCOMPacketType)letohd(packet.type))
205 case dcom_CreateInstance:
207 CreateInstancePacket createInstance = (CreateInstancePacket)packet;
208 Class _class = eSystem_FindClass(__thisModule.application, createInstance.className);
209 Class runClass = eSystem_FindClass(__thisModule.application, createInstance.className + 4);
210 DCOMServerObject object;
214 _class = eSystem_FindClass(runClass.module, createInstance.className);
216 objects = renew objects DCOMServerObject[numObjects+1];
217 object = objects[numObjects] = eInstance_New(_class);
218 object.serverSocket = this;
219 object.id = numObjects++;
220 object.instance = eInstance_New(runClass);
221 object.instance._vTbl = new void *[object.instance._class.vTblSize + 1];
222 object.instance._vTbl++;
223 object.instance._vTbl[-1] = (void *)object;
224 memcpy(object.instance._vTbl, object.instance._class._vTbl, sizeof(int(*)()) * object.instance._class.vTblSize);
225 for(vid = runClass.base.vTblSize; vid < runClass.vTblSize; vid++)
227 object.instance._vTbl[vid] = object._vTbl[vid - runClass.base.vTblSize + 11];
231 ObjectCreatedPacket sendPacket = ObjectCreatedPacket { };
232 sendPacket.type = (DCOMPacketType)htoled((DCOMPacketType)dcom_InstanceCreated);
233 sendPacket.size = sizeof(class ObjectCreatedPacket);
234 sendPacket.objectID = htoled(object.id);
235 SendPacket(sendPacket);
240 case dcom_CallMethod:
242 CallMethodPacket callMethod = (CallMethodPacket)packet;
243 callMethod.objectID = letohd(callMethod.objectID);
244 callMethod.argsSize = letohd(callMethod.argsSize);
245 if(callMethod.objectID < numObjects /*&& callMethod.methodID < numMethods*/)
247 DCOMServerObject object = objects[callMethod.objectID];
249 MethodReturnedPacket packet;
251 SerialBuffer buffer = object.buffer;
253 buffer.WriteData(callMethod.args, callMethod.argsSize);
254 // TOFIX: Hardcoded VTBL ID
255 object._vTbl[10](object, callMethod.methodID, buffer);
257 size = (uint)&((MethodReturnedPacket)0).args + buffer.size; // sizeof(class MethodReturnedPacket) + buffer.size - 1;
258 packet = (MethodReturnedPacket)new0 byte[size];
259 packet.type = (DCOMPacketType)htoled((DCOMPacketType)dcom_MethodReturned);
261 packet.argsSize = htoled(buffer.size);
262 buffer.ReadData(packet.args, buffer.size);
269 case dcom_VirtualMethodReturned:
271 VirtualMethodReturnedPacket methodReturned = (VirtualMethodReturnedPacket)packet;
272 if(methodReturned.objectID < numObjects)
274 DCOMServerObject object = objects[methodReturned.objectID];
275 object.virtualsBuffer.WriteData(methodReturned.args, letohd(methodReturned.argsSize));
276 object.answered = true;
277 object.overridden = methodReturned.overridden;
284 void OnDisconnect(int code)
287 thread.connected = false;
288 for(c = 0; c<numObjects; c++)
290 objects[c].instance._vTbl--;
291 delete objects[c].instance._vTbl;
292 delete objects[c].instance;
300 if(thread.started && GetCurrentThreadID() != thread.id)
305 class DCOMServiceThread : Thread
311 DCOMService service = this.service;
322 public class DCOMService : Service
326 DCOMServiceThread thread
328 service = this, connected = true;
332 if(thread.started && GetCurrentThreadID() != thread.id)
338 bool result = Service::Start();
341 thread.connected = true;
350 DCOMServerSocket socket;
351 thread.connected = false;
352 result = Service::Stop();
353 if(thread.started && GetCurrentThreadID() != thread.id)
359 DCOMServerSocket socket { };
361 socket.service = this;
363 socket.thread.Create();
369 public class DCOMClientObject : Socket
372 unsigned int objectID;
374 SerialBuffer __ecereBuffer { };
375 SerialBuffer virtualsBuffer { };
377 private DCOMClientThread thread
379 socket = this, connected = true;
382 bool Connect(char * server, int port)
385 if(Socket::Connect(server, port))
387 int len = strlen(_class.name) + 4 - strlen("DCOMClient_");
388 unsigned int size = sizeof(class CreateInstancePacket) + len;
389 CreateInstancePacket packet = (CreateInstancePacket)new0 byte[size];
390 packet.type = (DCOMPacketType)htoled((DCOMPacketType)dcom_CreateInstance);
392 CopyBytes(packet.className, "DCOM", 4);
393 CopyBytes(packet.className + 4, _class.name + strlen("DCOMClient_"), len-4+1);
397 thread.socket = this;
398 thread.connected = true;
400 while(!answered && thread)
402 //guiApp.WaitNetworkEvent();
403 //guiApp.ProcessNetworkEvents();
406 if(GetCurrentThreadID() == thread.id)
409 thread.semaphore.Wait();
416 virtual void CallVirtualMethod(unsigned int __ecereMethodID, SerialBuffer __ecereBuffer);
418 void OnReceivePacket(DCOMPacket p)
420 switch((DCOMPacketType)letohd(p.type))
422 case dcom_InstanceCreated:
424 ObjectCreatedPacket packet = (ObjectCreatedPacket)p;
425 objectID = letohd(packet.objectID);
429 case dcom_MethodReturned:
431 MethodReturnedPacket packet = (MethodReturnedPacket)p;
432 __ecereBuffer.WriteData(packet.args, letohd(packet.argsSize));
436 // Virtual Method Called
437 case dcom_CallVirtualMethod:
439 CallVirtualMethodPacket callMethod = (CallVirtualMethodPacket)p;
440 VirtualMethodReturnedPacket packet;
441 unsigned int size = (uint)&((VirtualMethodReturnedPacket)0).args; // sizeof(class VirtualMethodReturnedPacket);
442 SerialBuffer buffer = virtualsBuffer;
443 // TOFIX: Hardcoded VTBL ID
444 bool overridden = _vTbl[18 + callMethod.methodID] != _class._vTbl[18 + callMethod.methodID];
445 callMethod.argsSize = letohd(callMethod.argsSize);
448 buffer.WriteData(callMethod.args, callMethod.argsSize);
449 // TOFIX: Hardcoded VTBL ID
450 _vTbl[17](this, callMethod.methodID, buffer);
451 size += buffer.size; // - 1;
453 packet = (VirtualMethodReturnedPacket)new0 byte[size];
454 packet.overridden = overridden;
455 packet.objectID = objectID;
456 packet.type = (DCOMPacketType)htoled((DCOMPacketType)dcom_VirtualMethodReturned);
458 packet.argsSize = htoled(buffer.size);
459 buffer.ReadData(packet.args, buffer.size);
468 void OnDisconnect(int code)
471 thread.connected = false;
475 dllexport bool CallMethod(unsigned int methodID)
479 unsigned int size = (uint)&((CallMethodPacket)0).args + __ecereBuffer.size; // sizeof(class CallMethodPacket) + __ecereBuffer.size - 1;
480 CallMethodPacket packet = (CallMethodPacket)new0 byte[size];
481 packet.type = (DCOMPacketType)htoled((DCOMPacketType)dcom_CallMethod);
483 packet.objectID = htoled(objectID);
484 packet.methodID = htoled(methodID);
485 packet.argsSize = htoled(__ecereBuffer.size);
486 __ecereBuffer.ReadData(packet.args, __ecereBuffer.size);
491 while(!answered && thread)
493 //guiApp.WaitNetworkEvent();
494 //guiApp.ProcessNetworkEvents();
496 if(GetCurrentThreadID() == thread.id)
499 thread.semaphore.Wait();
501 return answered == true;
510 if(GetCurrentThreadID() != thread.id)