Click to See Complete Forum and Search --> : DllRegisterServer and DllUnregisterServer
Eduardo A. Morcillo
03-15-2000, 07:32 AM
* Custom implementation of DllRegisterServer and DllUnregisterServer for
ActiveX DLLs and OCXs.
* Custom implementation of DllGetClassObject (to avoid object creation using
a custom license).
* And why not DllMain. Since it will support mult-threading it will be
usefull to know when the DLL is attached to a thread/process to initialize
data (instead of doing it each time an object is created).
--
Eduardo A. Morcillo
http://www.domaindlx.com/e_morcillo
Alan Gillott
03-15-2000, 09:38 AM
Eduardo
Can you come down from the stratosphere and explain what this is about,
please?
Eduardo A. Morcillo <edanmo@geocities.com> wrote in message
news:38cf732f@news.devx.com...
>
> * Custom implementation of DllRegisterServer and DllUnregisterServer for
> ActiveX DLLs and OCXs.
>
> * Custom implementation of DllGetClassObject (to avoid object creation
using
> a custom license).
>
> * And why not DllMain. Since it will support mult-threading it will be
> usefull to know when the DLL is attached to a thread/process to initialize
> data (instead of doing it each time an object is created).
>
> --
> Eduardo A. Morcillo
> http://www.domaindlx.com/e_morcillo
>
>
Michael \(michka\) Kaplan
03-15-2000, 11:04 AM
FWIW, you can do the first two items now with a designer you write yourself
(which is a tough solution to o yourself, I am hoping someone eventually
decides to just do it themselves and create one). If I were not so flipping
busy, I would have done this already to help with projects I am working on.
:-)
--
?MichKa
(insensitive fruitarian)
random junk of dubious value, a multilingual website, the
54-language TSI Form/Report to Data Access Page Wizard,
and lots of replication "stuff" at the (no scripts required!)
http://www.trigeminal.com/
?
"Eduardo A. Morcillo" <edanmo@geocities.com> wrote in message
news:38cf732f@news.devx.com...
>
> * Custom implementation of DllRegisterServer and DllUnregisterServer for
> ActiveX DLLs and OCXs.
>
> * Custom implementation of DllGetClassObject (to avoid object creation
using
> a custom license).
>
> * And why not DllMain. Since it will support mult-threading it will be
> usefull to know when the DLL is attached to a thread/process to initialize
> data (instead of doing it each time an object is created).
>
> --
> Eduardo A. Morcillo
> http://www.domaindlx.com/e_morcillo
>
>
Craig Clearman
03-15-2000, 11:11 AM
Alan,
>Can you come down from the stratosphere and explain what this is about,
>please?
The ones I'd really like to see would be:
>> * Custom implementation of DllRegisterServer and DllUnregisterServer for
>> ActiveX DLLs and OCXs.
The ability to run code inside your component whenever a user or
program registers or unregisters the component. This could be used to
store information into the registry or onto disk that would be used
when the component is invoked. Essentially, it becomes a method for
installing and uninstalling components, held internal to the
component.
>> * And why not DllMain. Since it will support mult-threading it will be
>> usefull to know when the DLL is attached to a thread/process to initialize
>> data (instead of doing it each time an object is created).
Two events for any component: Lib_Init() and Lib_Terminate(). These
would be fired whenever the library is loaded and unloaded. There are
workarounds for these capabilities, but they are ugly.
Ciao, Craig
Ed Pinto
03-15-2000, 11:18 AM
Hey Alan,
> > * Custom implementation of DllRegisterServer and DllUnregisterServer for
> > ActiveX DLLs and OCXs.
When RegSvr32 is run against an ActiveX dll, it fires either
DllRegisterServer or DllUnregisterServer. These are two functions with well
known entry points into the dll. A function with a well known entry point
is simply a function in a Dll that other programs know how to call (ex.
GetComputerName in the kernel32). These are the functions that handle
updating the registry with entries under CLSID etc. so COM knows how to
activate components when you run something like
CreateObject("YourServer.CYourClass"). VB takes care of these two functions
for us right now, I assume Eduardo would like to be able to customize his
registry settings to take advantage of the plethora of COM+ activation
possibilities.
> > * Custom implementation of DllGetClassObject (to avoid object creation
> using
> > a custom license).
Getting an instance of a class from a dll is not something that happens
without legwork. An ActiveX Dll is still only a Dll after all.
DllGetClassObject is another function with a well known entry point. It
returns a pointor to an implementation of the IClassFactory interface. The
most important function of the IClassFactory interface is the CreateInstance
function which is the actual function that creates the requested object and
returns the requested interface. This is the function that ultimately gets
called by CreateObject. IClassFactory has some successors (namely
IClassFactory2) that facilitate object instantiation with licensing. This
is what I believe Eduardo would like control over. Currently VB handles
this for us.
> > * And why not DllMain. Since it will support mult-threading it will be
> > usefull to know when the DLL is attached to a thread/process to
initialize
> > data (instead of doing it each time an object is created).
> >
DllMain is simply a function fired when a process or a thread is attached or
detached from the dll. It is used to initialize any resources that are
process or thread specific. Again, currently, this is handled for us by VB
Eduardo, let me know if I missed anything.
HTH,
Ed
Craig Clearman
03-15-2000, 11:19 AM
Hi Craig,
>Two events for any component: Lib_Init() and Lib_Terminate(). These
>would be fired whenever the library is loaded and unloaded. There are
>workarounds for these capabilities, but they are ugly.
More to the point: there is a kludge for the terminate, but the
initialize is fine. Just create a subroutine in a BAS module called
main and make it your startup object on your DLL. The terminate you
get by instantiating an object in your Sub Main()
Public Sub Main()
Static libEvent As CLibEvent
Set libEvent = New CLibEvent
End Sub
When libEvent's Terminate method is called, the library is being
unloaded.
Obviously, when Sub Main is called, the library is being loaded.
Ciao, Craig
Damit Senanayake
03-15-2000, 11:23 AM
Hi Alan,
: Can you come down from the stratosphere and explain what this is about,
: please?
This is just an explanation as I see it, Eduardo's may be different:
: > * Custom implementation of DllRegisterServer and DllUnregisterServer for
: > ActiveX DLLs and OCXs.
When you run 'regsvr32 <DLL or OCX name>', the regsvr32 utility loads your
DLL and calls the DllRegisterServer function. Similarly, when you run
'regsvr32 /u <DLL or OCX name>', the regsvr32 utility loads your DLL and
calls the DllUnregisterServer function. (pseudo VB code follows)
' DllRegisterServer is a Sub
' so is DllUnregisterServer
Sub Main()
Dim hMod As Long, pfnReg As Long, pfnUnreg As Long
hMod = LoadLibrary("<DLL or OCX name>")
If hMod = 0 Then MsgBox Err.LastDllError: Exit Sub
If InStr(1, Command$, "/u", vbTextCompare) Or InStr(1, Command$, "-u",
vbTextCompare) Then
' unregister
pfnUnreg = GetProcAddress(hMod, "DllUnregisterServer")
If pfnUnreg <> 0 Then CallEx(pfnUnreg) _' execute pfnUnreg
Else MsgBox Err.LastDllError: FreeLibrary(hMod): Exit Sub
Else
' register
pfnReg = GetProcAddress(hMod, "DllRegisterServer")
If pfnReg <> 0 Then CallEx(pfnReg) _ ' execute pfnReg
Else MsgBox Err.LastDllERror: FreeLibrary(hMod): Exit Sub
End If
FreeLibrary hMod
End Sub
VB provides implementations of DllRegisterServer and DllUnregisterServer by
default for every OCX and DLL project you create, and these default
implementations register your classes under the appropriate registry keys.
If you're curious, you can run the Dependency Walker (depends.exe) on your
OCX/DLL or run dumpbin /exports:
[D:\Projects\Menu] $ dumpbin /exports dsMenuCtl.ocx
Microsoft (R) COFF Binary File Dumper Version 5.12.8181
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.
Dump of file dsMenuCtl.ocx
File Type: DLL
Section contains the following exports for dsMenuCtl.ocx
0 characteristics
38C4F3FC time date stamp Tue Mar 07 20:20:12 2000
0.00 version
1 ordinal base
4 number of functions
4 number of names
ordinal hint RVA name
1 0 00003AAA DllCanUnloadNow
2 1 00003A7E DllGetClassObject
3 2 00003A94 DllRegisterServer
4 3 00003A68 DllUnregisterServer
Summary
1000 .data
1000 .idata
1000 .reloc
2000 .rsrc
7000 .text
However, there are additional things you can do in a Dll(un)RegisterServer
function, including accessing settings, initializing variables, etc. The
problem is that VB does not currently give you a way to modify the code it
generates.
: > * Custom implementation of DllGetClassObject (to avoid object creation
: using
: > a custom license).
DllGetClassObject is called when CoCreateInstance(Ex) or CoGetClassObject
try to create a new instance of the object.
It looks like this:
Public Exported Function DllGetClassObject(ByVal rclsid As IID, ByVal riid
As IID, ppv As Any) As Long
' rclsid [in] CLSID that will associate the correct data and code.
' riid [in] Reference to the identifier of the interface that the caller
is to use to communicate with the class object. Usually, this is
IID_IClassFactory (defined in the OLE headers as the interface identifier
for IClassFactory).
' ppv [out] Address of pointer variable that receives the interface
pointer requested in riid. Upon successful return, *ppv contains the
requested interface pointer. If an error occurs, the interface pointer is
NULL.
'Return Values
'This function supports the standard return values E_INVALIDARG,
E_OUTOFMEMORY and E_UNEXPECTED, as well as 'the following:
'S_OK The object was retrieved successfully.
'CLASS_E_CLASSNOTAVAILABLE The DLL does not support the class (object
definition).
'Remarks
'If a call to the CoGetClassObject function finds the class object that is
to be loaded in a DLL, CoGetClassObject 'uses the DLL's exported
DllGetClassObject function.
' Your code here
End Function
: > * And why not DllMain. Since it will support mult-threading it will be
: > usefull to know when the DLL is attached to a thread/process to
initialize
: > data (instead of doing it each time an object is created).
DllMain is the entry point to a (standard or otherwise) DLL. In a non-VB
ActiveX DLL, you don't have to supply a DllMain, but most people normally do
it for the reasons Eduardo mentions. In a standard DLL, you usually supply
it so that you can get an instance pointer.
The DllMain function receives 4 reasons: DLL_PROCESS_ATTACH,
DLL_PROCESS_DETACH, DLL_THREAD_ATTACH and DLL_THREAD_DETACH.
DLL_PROCESS_ATTACH is called when a new process loads the DLL. It is always
followed by DLL_THREAD_ATTACH as the main thread of the process loads the
DLL.
DLL_THREAD_ATTACH is called when a new thread from an existing process loads
the DLL.
DLL_PROCESS_DETACH is always called after all threads in the process have
unloaded the DLL (in the process raising DLL_THREAD_DETACH notifications) to
inform the DLL that it will be unloaded.
A DllMain function looks like this:
Private nProcessCounter As Long
Private nThreadCounter As Long
Public Exported Function DllMain(ByVal hInstance As Long, ByVal dwReason As
Long, ByVal fReserved As Long) As Long
Select Case dwReason
Case DLL_PROCESS_ATTACH
nProcessCounter = nProcessCounter + 1
Case DLL_THREAD_ATTACH
nThreadCounter = nThreadCounter + 1
Case DLL_PROCESS_DETACH
nProcessCounter = nProcessCounter - 1
Case DLL_THREAD_DETACH
nThreadCounter = nThreadCounter - 1
End Select
End Function
--
Damit Senanayake | damit@mvps.org
Please reply to newsgroups, not by e-mail.
http://members.xoom.com/damit | {http,ftp}://damit.dyndns.org (experimental)
ICQ: 6930718
Alan Gillott
03-15-2000, 12:30 PM
I was guessing that this is what it was about: for example, it would
simplify install a great deal if we could add additional registration to our
exe's over and above the default stuff VB does for us. I was intrigued by
Craig's description of calls associated with regular load/unload too.
Ed Pinto <epinto@autoadmin.com> wrote in message
news:38cfa799$1@news.devx.com...
> Hey Alan,
>
> > > * Custom implementation of DllRegisterServer and DllUnregisterServer
for
> > > ActiveX DLLs and OCXs.
>
>
> When RegSvr32 is run against an ActiveX dll, it fires either
> DllRegisterServer or DllUnregisterServer. These are two functions with
well
> known entry points into the dll. A function with a well known entry point
> is simply a function in a Dll that other programs know how to call (ex.
> GetComputerName in the kernel32). These are the functions that handle
> updating the registry with entries under CLSID etc. so COM knows how to
> activate components when you run something like
> CreateObject("YourServer.CYourClass"). VB takes care of these two
functions
> for us right now, I assume Eduardo would like to be able to customize his
> registry settings to take advantage of the plethora of COM+ activation
> possibilities.
>
> > > * Custom implementation of DllGetClassObject (to avoid object creation
> > using
> > > a custom license).
>
> Getting an instance of a class from a dll is not something that happens
> without legwork. An ActiveX Dll is still only a Dll after all.
> DllGetClassObject is another function with a well known entry point. It
> returns a pointor to an implementation of the IClassFactory interface.
The
> most important function of the IClassFactory interface is the
CreateInstance
> function which is the actual function that creates the requested object
and
> returns the requested interface. This is the function that ultimately
gets
> called by CreateObject. IClassFactory has some successors (namely
> IClassFactory2) that facilitate object instantiation with licensing. This
> is what I believe Eduardo would like control over. Currently VB handles
> this for us.
>
> > > * And why not DllMain. Since it will support mult-threading it will be
> > > usefull to know when the DLL is attached to a thread/process to
> initialize
> > > data (instead of doing it each time an object is created).
> > >
>
> DllMain is simply a function fired when a process or a thread is attached
or
> detached from the dll. It is used to initialize any resources that are
> process or thread specific. Again, currently, this is handled for us by
VB
>
> Eduardo, let me know if I missed anything.
>
> HTH,
> Ed
>
>
Karl E. Peterson
03-15-2000, 02:37 PM
That's *really* cool! Wish I'd thought of it. :-)
--
[This space intentionally left blank.]
Craig Clearman wrote in message ...
>Hi Craig,
>
>>Two events for any component: Lib_Init() and Lib_Terminate(). These
>>would be fired whenever the library is loaded and unloaded. There are
>>workarounds for these capabilities, but they are ugly.
>
>More to the point: there is a kludge for the terminate, but the
>initialize is fine. Just create a subroutine in a BAS module called
>main and make it your startup object on your DLL. The terminate you
>get by instantiating an object in your Sub Main()
>
>Public Sub Main()
>
>Static libEvent As CLibEvent
>
> Set libEvent = New CLibEvent
>
>End Sub
>
>When libEvent's Terminate method is called, the library is being
>unloaded.
>
>Obviously, when Sub Main is called, the library is being loaded.
>
>Ciao, Craig
>
devx.com
Copyright WebMediaBrands Inc. All Rights Reserved