Alexandre said:
Part of it should be done with DllRegisterServer, the rest can be handled by the .inf script. And I think it's OK to add the necessary DllRegisterServer entry points even if the native dll doesn't have them.
I'm glad you feel that way. I created bug 1117, "Make all Wine OLE DLLs self-registerable", and have been working on an implementation. For some reason I can't accept the bug; though I've tried several times, it stays at UNCONFIRMED.
What to do about DLLs like ole32.dll that have a native DllRegisterServer but no corresponding DllUnregisterServer? I'm inclined to include it for completeness, though it's unlikely that anyone would ever want to unregister such a basic system DLL.
I posted my idea for representing the registration data, accidentally from "jhohm@happyhappy.dyndns.org" rather than my usual "jhohm@acm.org" (see http://www.winehq.com/hypermail/wine-devel/2002/11/1409.html), but I haven't gotten any responses, not even "looks fine" or "you are a moron". I guess I'll just start submitting patches, then.
"John K. Hohm" jhohm@acm.org writes:
I posted my idea for representing the registration data, accidentally from "jhohm@happyhappy.dyndns.org" rather than my usual "jhohm@acm.org" (see http://www.winehq.com/hypermail/wine-devel/2002/11/1409.html), but I haven't gotten any responses, not even "looks fine" or "you are a moron". I guess I'll just start submitting patches, then.
Sorry, I must have missed that one. I don't really like the ASCII description of the registry keys; I think it would be better to do it at a more symbolic level. For instance you shouldn't hardcode the ASCII form of the CLSID, you should have some kind of "register CLSID" function that takes a CLSID and uses StringFromCLSID or whatever to create the corresponding registry key.
On Wed, Dec 04, 2002 at 05:14:23PM -0800, Alexandre Julliard wrote:
"John K. Hohm" jhohm@acm.org writes:
I posted my idea for representing the registration data, accidentally from "jhohm@happyhappy.dyndns.org" rather than my usual "jhohm@acm.org" (see http://www.winehq.com/hypermail/wine-devel/2002/11/1409.html), but I haven't gotten any responses, not even "looks fine" or "you are a moron". I guess I'll just start submitting patches, then.
Sorry, I must have missed that one. I don't really like the ASCII description of the registry keys; I think it would be better to do it at a more symbolic level. For instance you shouldn't hardcode the ASCII form of the CLSID, you should have some kind of "register CLSID" function that takes a CLSID and uses StringFromCLSID or whatever to create the corresponding registry key.
The types of things that a COM server DLL is likely to register are fairly limited; essentially just classes and interfaces. I have come up with a different interface, that accepts a list of structures more closely matching the requirements of registering and unregistering a COM server.
This is the interface in regsvr.h for use by Dll[Un]RegisterServer:
struct regsvr_interface { IID const *iid; /* NULL for end of list */ LPCSTR name; /* can be NULL to omit */ IID const *base_iid; /* can be NULL to omit */ int num_methods; /* can be <0 to omit */ CLSID const *ps_clsid; /* can be NULL to omit */ CLSID const *ps_clsid32; /* can be NULL to omit */ };
HRESULT register_interfaces(struct regsvr_interface const *list); HRESULT unregister_interfaces(struct regsvr_interface const *list);
struct regsvr_coclass { CLSID const *clsid; /* NULL for end of list */ LPCSTR name; /* can be NULL to omit */ LPCSTR ips; /* can be NULL to omit */ LPCSTR ips32; /* can be NULL to omit */ LPCSTR ips32_tmodel; /* can be NULL to omit */ };
HRESULT register_coclasses(struct regsvr_coclass const *list); HRESULT unregister_coclasses(struct regsvr_coclass const *list);
Here is an example of its use in comcat_main.c; this is admittedly much less than would appear on ole32_main.c, but everything required there should be included in the structures:
static struct regsvr_coclass coclass_list[] = { { &CLSID_StdComponentCategoriesMgr, "StdComponentCategoriesMgr", NULL, "comcat.dll", "Both" }, { NULL } /* list terminator */ };
HRESULT WINAPI COMCAT_DllRegisterServer() { TRACE("\n"); return register_coclasses(coclass_list); }
HRESULT WINAPI COMCAT_DllUnregisterServer() { TRACE("\n"); return unregister_coclasses(coclass_list); }
Alexandre, feel free to disapprove of this interface also; most of my experience writing interfaces to library pieces has either been big, complex Automation stuff to support VB database apps, or object-oriented C++.
I would also like suggestions on whether an interface like this should be exported via a static library like libwine_unicode.a (can that work when I call advapi32 exports?), via a new wine-specific dll in src/dlls, or simply by copying the implementation around to all the COM server dlls (my least favorite option).
http://www.winehq.com/hypermail/wine-devel/2002/11/1409.html), but I haven't gotten any responses, not even "looks fine" or "you are a moron". I guess I'll just start submitting patches, then.
As long as they will self-register on Windows/ReactOS then it "looks fine" to me. =) If not I still cant write it so I wont say "you are a moron".
Thanks Steven
__________________________________________________ Do you Yahoo!? Yahoo! Mail Plus - Powerful. Affordable. Sign up now. http://mailplus.yahoo.com
"John K. Hohm" jhohm@acm.org writes:
Alexandre, feel free to disapprove of this interface also; most of my experience writing interfaces to library pieces has either been big, complex Automation stuff to support VB database apps, or object-oriented C++.
That's much better than the previous one. I'm not convinced you really need to build a static list, you might as well have a function to register a single interface and call it a number of times.
I would also like suggestions on whether an interface like this should be exported via a static library like libwine_unicode.a (can that work when I call advapi32 exports?), via a new wine-specific dll in src/dlls, or simply by copying the implementation around to all the COM server dlls (my least favorite option).
I'm afraid copying it is the best choice; I don't think we want a new dll for just a couple of routines. It's not very elegant to duplicate it, but it shouldn't be a lot of code anyway.
Quoting Alexandre Julliard julliard@winehq.com:
That's much better than the previous one. I'm not convinced you really need to build a static list, you might as well have a function to register a single interface and call it a number of times.
The main reason I used a static list was to make it impossible to forget to unregister one of the interfaces you registered; that is why the unregister functions take the entire structures (but only need the first members).
OTOH, if we might someday want to avoid unregistering one or more interfaces or classes we registered, having separate functions would make that easier.
I think I still prefer the structures, but are you convinced enough?
I'm afraid copying it is the best choice; I don't think we want a new dll for just a couple of routines. It's not very elegant to duplicate it, but it shouldn't be a lot of code anyway.
What would it take to make a static library work for this? Unlike a dll, that would not have any overhead, would it? I'm a real sucker for elegance, you know. :-)
I used to think any library, even a static one, had to have a certain amount of bloat, until I came across the dietlibc (http://www.fefe.de/dietlibc/).
"John K. Hohm" jhohm@acm.org writes:
The main reason I used a static list was to make it impossible to forget to unregister one of the interfaces you registered; that is why the unregister functions take the entire structures (but only need the first members).
OTOH, if we might someday want to avoid unregistering one or more interfaces or classes we registered, having separate functions would make that easier.
I think I still prefer the structures, but are you convinced enough?
Not really, but I don't feel strongly about it, so do it the way you like.
What would it take to make a static library work for this? Unlike a dll, that would not have any overhead, would it? I'm a real sucker for elegance, you know. :-)
It's possible, but it adds quite a bit of complexity to the build process, and creates annoying dll dependencies. I'd prefer that we start with the duplication for now, and see how ugly it gets.
What would it take to make a static library work for this? Unlike a dll, that would not have any overhead, would it? I'm a real sucker for
elegance,
you know. :-)
It's possible, but it adds quite a bit of complexity to the build process, and creates annoying dll dependencies. I'd prefer that we start with the duplication for now, and see how ugly it gets.
Okay, we'll start with the duplication. :-|
When I prepare a patch including the shared regsvr.h and regsvr.c, should I include them everywhere they're needed (repeating them in the patch multiple times), or just add a note like "Hey Alexandre, do a cp regsvr.[hc] ...", or maybe should I always submit the changes as separate patches for each dll?
On Thu, 9 Jan 2003, John K. Hohm wrote: [...]
Okay, we'll start with the duplication. :-|
When I prepare a patch including the shared regsvr.h and regsvr.c, should I include them everywhere they're needed (repeating them in the patch multiple times), or just add a note like "Hey Alexandre, do a cp regsvr.[hc] ...", or maybe should I always submit the changes as separate patches for each dll?
Could it be done byt putting the required functions in a single header ala 'include/wine/test.h'? This way it would be duplicated... but not really.
"John K. Hohm" jhohm@acm.org writes:
When I prepare a patch including the shared regsvr.h and regsvr.c, should I include them everywhere they're needed (repeating them in the patch multiple times), or just add a note like "Hey Alexandre, do a cp regsvr.[hc] ...", or maybe should I always submit the changes as separate patches for each dll?
Please do it in one dll only for now and submit that; once it's tested and integrated we can start copying it around. Also I'd suggest putting the Dll(Un)RegisterServer functions in the same .c file so that you don't need a .h at all, this way there will be less duplication.
Quoting Alexandre Julliard julliard@winehq.com:
Please do it in one dll only for now and submit that; once it's tested and integrated we can start copying it around. Also I'd suggest
Okay. Should I perhaps start with something better-used than comcat (perhaps ole32) so that testing will be likely to fail quickly if it's broken?
putting the Dll(Un)RegisterServer functions in the same .c file so that you don't need a .h at all, this way there will be less duplication.
Are you suggesting that the static data defining which classes and interfaces to register be located in the same file as the implementation of the (un)registration functions? That would make copying the implementation around even more work, since I couldn't just copy regsvr.[hc] and keep the differing data in the respective dll-specific sources.
I suppose you could also mean that *only* the static data be stored in a dll- specific file, with predefined variable names to be found by the regsvr.c, but that still requires a regsvr.h to get the struct definitions.
"John K. Hohm" jhohm@acm.org writes:
Are you suggesting that the static data defining which classes and interfaces to register be located in the same file as the implementation of the (un)registration functions? That would make copying the implementation around even more work, since I couldn't just copy regsvr.[hc] and keep the differing data in the respective dll-specific sources.
Not really, you shouldn't be copying it around all the time anyway. Once the functions are working properly they shouldn't need to change. The idea is that you put everything into regsvr.c, both the common functions and the dll-specific stuff; then when you want to do a new dll you copy a regsvr.c and modify the dll-specific parts. This also allows simplifying the code for dlls that don't need the complete support.