MODULE ComKoalaDll;
(**

   project   = "BlackBox"
   organization   = "www.oberon.ch"
   contributors   = "Oberon microsystems"
   version   = "System/Rsrc/About"
   copyright   = "System/Rsrc/About"
   license   = "Docu/BB-License"
   references   = "adapted from Koala sample in "Inside OLE", 2nd ed."
   changes   = ""
   issues   = ""

**)

   IMPORT COM, WinApi, WinOle;


   
   
   CONST
      KoalaId = "{00021146-0000-0000-C000-000000000046}";
      
   
   TYPE
      Koala = POINTER TO RECORD (COM.IUnknown) END;
      KoalaFactory = POINTER TO RECORD (WinOle.IClassFactory) END;
   
   
   VAR
      locks: INTEGER;
      objects: INTEGER;
      
      
   (* ---------- Koala ---------- *)
   
   (* use default QueryInterface implementation *)
   
   (* AddRef & Release implemented implicitly by the compiler *)
   
   PROCEDURE (this: Koala) RELEASE;   (* called when last com reference is removed *)
   BEGIN
      DEC(objects)
   END RELEASE;
   
   
   (* ---------- KoalaFactory ---------- *)
   
   (* use default QueryInterface implementation *)
   
   (* AddRef & Release implemented implicitly by the compiler *)
   
   PROCEDURE (this: KoalaFactory) CreateInstance (outer: COM.IUnknown; IN [iid] iid: COM.GUID;
                                                         OUT [new] int: COM.IUnknown): COM.RESULT;
      VAR res: COM.RESULT; new: Koala;
   BEGIN
      IF outer # NIL THEN RETURN WinApi.CLASS_E_NOAGGREGATION END;
      NEW(new);
      IF new # NIL THEN
         res := new.QueryInterface(iid, int);
         IF res >= 0 THEN INC(objects) END;
         RETURN res
      ELSE RETURN WinApi.E_OUTOFMEMORY
      END
   END CreateInstance;
   
   PROCEDURE (this: KoalaFactory) LockServer (lock: WinApi.BOOL): COM.RESULT;
   BEGIN
      IF lock # 0 THEN INC(locks) ELSE DEC(locks) END;
      RETURN WinApi.S_OK
   END LockServer;
   
   (* ---------- dll interface ---------- *)

   
   PROCEDURE DllGetClassObject* (IN clsid: COM.GUID;
                                    IN [iid] iid: COM.GUID; OUT [new] int: COM.IUnknown): COM.RESULT;
      VAR obj: KoalaFactory;
   BEGIN
      IF clsid = KoalaId THEN
         NEW(obj);
         IF obj # NIL THEN RETURN obj.QueryInterface(iid, int)
         ELSE RETURN WinApi.E_OUTOFMEMORY;
         END
      ELSE RETURN WinApi.E_FAIL
      END
   END DllGetClassObject;
   
   PROCEDURE DllCanUnloadNow* (): COM.RESULT;
   BEGIN
      IF (objects = 0) & (locks = 0) THEN RETURN WinApi.S_OK ELSE RETURN WinApi.S_FALSE END
   END DllCanUnloadNow;
   
BEGIN   

   locks := 0; objects := 0
END ComKoalaDll.
DevLinker.LinkDll DKoala1.dll := Kernel+ ComKoalaDll# ~


-----------------------------------------------------------------------------------------------------------------


REGEDIT
HKEY_CLASSES_ROOT\Koala1.0 = Koala Object Chapter 5
HKEY_CLASSES_ROOT\Koala1.0\CLSID = {00021146-0000-0000-C000-000000000046}
HKEY_CLASSES_ROOT\Koala = Koala Object Chapter 5
HKEY_CLASSES_ROOT\Koala\CurVer = Koala1.0
HKEY_CLASSES_ROOT\Koala\CLSID = {00021146-0000-0000-C000-000000000046}
HKEY_CLASSES_ROOT\CLSID\{00021146-0000-0000-C000-000000000046} = Koala Object Chapter 5

HKEY_CLASSES_ROOT\CLSID\{00021146-0000-0000-C000-000000000046}\ProgID = Koala1.0
HKEY_CLASSES_ROOT\CLSID\{00021146-0000-0000-C000-000000000046}\VersionIndependentProgID = Koala
HKEY_CLASSES_ROOT\CLSID\{00021146-0000-0000-C000-000000000046}\InprocServer32 = C:\BlackBox\Com\DKoala1.dll
HKEY_CLASSES_ROOT\CLSID\{00021146-0000-0000-C000-000000000046}\NotInsertable
-----------------------------------------------------------------------------------------------------------------