Hello, Once again cross-posting because I would like to see if this is something we can work together on. What is left to do for us to be able to build and have a working implementation of stdole.tlb or any other type libs? I ask because it seems Wines DCOM implementaton is almost good enough for most apps except for this file and ReactOS is quickly getting to the point that it can run most of the same stuff Wine can without DCOM9x installed.
Thanks Steven
_______________________________ Do you Yahoo!? Win 1 of 4,000 free domain names from Yahoo! Enter now. http://promotions.yahoo.com/goldrush
It basically involves implementing the ICreateTypeLib interfaces in our OLE dlls. Nyef did some great work on this but for stdole32.tlb we need the other version, I think.
Once this is done maybe we can pull the stdole32.tlb generation program used in Crossover upstream. Right now it's pretty useless for Wine as it has to be run on Windows to work.
On Fri, 27 Aug 2004 23:26:07 -0700, Steven Edwards wrote:
Hello, Once again cross-posting because I would like to see if this is something we can work together on. What is left to do for us to be able to build and have a working implementation of stdole.tlb or any other type libs? I ask because it seems Wines DCOM implementaton is almost good enough for most apps except for this file and ReactOS is quickly getting to the point that it can run most of the same stuff Wine can without DCOM9x installed.
Thanks Steven
_______________________________ Do you Yahoo!? Win 1 of 4,000 free domain names from Yahoo! Enter now. http://promotions.yahoo.com/goldrush
Mike Hearn wrote:
It basically involves implementing the ICreateTypeLib interfaces in our OLE dlls. Nyef did some great work on this but for stdole32.tlb we need the other version, I think.
Can you elaborate more please? Looking at dlls/oleaut32/typelib2.c I see that the ICreateTypeLib2 interface is implemented.
Regards, Filip
On Sat, Aug 28, 2004 at 11:06:46PM +0200, Filip Navara wrote:
Mike Hearn wrote:
It basically involves implementing the ICreateTypeLib interfaces in our OLE dlls. Nyef did some great work on this but for stdole32.tlb we need the other version, I think.
Can you elaborate more please? Looking at dlls/oleaut32/typelib2.c I see that the ICreateTypeLib2 interface is implemented.
The ICreateTypeLib2 interface is used to create the new-style MSFT typelibs. The older ICreateTypeLib interface is used for the old-style typelibs. While the newer interface also implements the older one, when you ask for the old interface with CreateTypeLib() you get a completely different implementation.
I don't see why it necessarily follows that stdole32 wouldn't work as an MSFT typelib, but the implementation of ICreateTypeInfo2 is badly incomplete in places, and I would trust it to completely mess up any semi-complex type library you attempt to create with it. Specifically, any type library that involves functions or variables.
Regards, Filip
--Alastair Bridgewater
Nyef wrote:
The ICreateTypeLib2 interface is used to create the new-style MSFT typelibs. The older ICreateTypeLib interface is used for the old-style typelibs. While the newer interface also implements the older one, when you ask for the old interface with CreateTypeLib() you get a completely different implementation.
Ok, I studied the code more and now I understand the the difference (SLTG vs. MSFT libraries). Thanks for explaining.
I don't see why it necessarily follows that stdole32 wouldn't work as an MSFT typelib, but the implementation of ICreateTypeInfo2 is badly incomplete in places, and I would trust it to completely mess up any semi-complex type library you attempt to create with it. Specifically, any type library that involves functions or variables.
You're pretty much right. I tried to create *very* simple HelloWorld-type type library with it and and it reported me bunch of "stub!" messages and crashed. I also found a bug in implementation of ITypeLib2_fnGetTypeInfoOfGuid (in fact both implementations, the one in typelib.c and the second in typelib2.c). It should reference the typelib it's called on. This ensures that later call ITypeInfo_GetContainingTypeLib will not return bogus pointer if the original caller already released the TypeLib. See the attached test. If any COM hacker around can fix it, it would be nice.
Regards, Filip
#include <windows.h> #include <oaidl.h> #include <stdio.h>
#define ok(x,y) if (!(x)) printf(y); else printf("ok\n")
int main() { LPTYPELIB ptlibStdOle; LPTYPEINFO ptinfoIUnknown; HRESULT result;
result = LoadTypeLib(OLESTR("stdole32.tlb"), &ptlibStdOle); ok(result == S_OK, "can't load stdole32.tlb");
/* continue only if stdole32.tlb is present. */ if (result == S_OK) { ok(ptlibStdOle->AddRef() == 2, "invalid reference count\n"); /* GetTypeInfoOfGuid adds refernece to typelib */ result = ptlibStdOle->GetTypeInfoOfGuid(IID_IUnknown, &ptinfoIUnknown); ok(result == S_OK, "can't get type info about IUnknown"); ok(ptlibStdOle->Release() == 2, "invalid reference count\n"); ok(ptinfoIUnknown->Release() == 0, "invalid reference count\n"); ok(ptlibStdOle->Release() == 0, "invalid reference count\n"); } }
On Sun, Aug 29, 2004 at 04:42:04AM +0200, Filip Navara wrote:
You're pretty much right. I tried to create *very* simple HelloWorld-type type library with it and and it reported me bunch of "stub!" messages and crashed. I also found a bug in implementation of ITypeLib2_fnGetTypeInfoOfGuid (in fact both implementations, the one in typelib.c and the second in typelib2.c). It should reference the typelib it's called on. This ensures that later call ITypeInfo_GetContainingTypeLib will not return bogus pointer if the original caller already released the TypeLib. See the attached test. If any COM hacker around can fix it, it would be nice.
You're right to be suspicious, and there may actually be a bug with the reference counting in typelib2.c, but fnGetTypeInfoOfGuid should -not- directly AddRef() the containing typelib. Such an AddRef() rightfully belongs in with the implemetations of QueryInterface(), AddRef(), and Release() on ICreateTypeInfo2. It is supposed to be set up that the TypeInfo objects never deallocate themselves when they hit 0 references, but they do hold a reference to their containing typelib. The TypeLib objects never hold a reference to any of their typeinfos (so as not to cause a reference cycle), but they are set up to deallocate the typeinfo structures when the typelib hits 0 references.
I'll give the typelib2.c code a look-over tomorrow with an eye towards verifying that reference counting is correct.
Regards, Filip
--Alastair Bridgewater
<>You're right to be suspicious, and there may actually be a bug with the reference counting in typelib2.c, but fnGetTypeInfoOfGuid should -not- directly AddRef() the containing typelib. Such an AddRef() rightfully belongs in with the implemetations of QueryInterface(), AddRef(), and Release() on ICreateTypeInfo2. It is supposed to be set up that the TypeInfo objects never deallocate themselves when they hit 0 references, but they do hold a reference to their containing typelib. The TypeLib objects never hold a reference to any of their typeinfos (so as not to cause a reference cycle), but they are set up to deallocate the typeinfo structures when the typelib hits 0 references.
Application can use fnGetTypeInfoOfGuid function to get ITypeInfo, next release ITypeLib and still use ITypeInfo, so GetTypeInfoOfGuid must directly AddRef the contaning typelib. See this patch: http://www.winehq.org/hypermail/wine-patches/2004/08/0167.html and test "typelib". I think similar thing should be done in typelib2.c.
Jacek
You're pretty much right. I tried to create *very* simple HelloWorld-type type library with it and and it reported me bunch of "stub!" messages and crashed. I also found a bug in implementation of ITypeLib2_fnGetTypeInfoOfGuid (in fact both implementations, the one in typelib.c and the second in typelib2.c). It should reference the typelib it's called on. This ensures that later call ITypeInfo_GetContainingTypeLib will not return bogus pointer if the original caller already released the TypeLib. See the attached test. If any COM hacker around can fix it, it would be nice.
It's not a bug. It's a difference between Wine's and native Windows implementation. When you run the attached test with the builtin version, you'll get: ref = 2 ref = 3 ITypeLib has a reference to the linked list of ITypeInfo. Functions GetTypeInfo and GetTypeInfoOfGuid search this list, call ITypeInfo::AddRef and returns the reference to ITypeInfo. ITypeInfo is destroyed when ITypeLib is destroyed (it means that each other ITypeInfos are destroyed too). Running this test with native Windows dll, results are: ref = 1 ref = 2 While Wine creates ITypeInfo interfaces when creating ITypeLib, native Windows probably create ITypeInfo "on call" when GetTypeInfoOfGuid is called for the first time. ITypeInfo can be deleted in this way while ITypeLib exists, while, in Wine, ITypeInfo has to be deleted together with ITypeLib.
I don't thik it Wine's bug. Applications don't depend on this stuff and Wine's ref handling is correct.
Jacek
On Mon, 30 Aug 2004 08:56:38 +0000, Jacek Caban wrote:
It's not a bug. It's a difference between Wine's and native Windows implementation.
By definition an application that works fine on Windows should work fine on Wine. If they don't, it's a bug.
When you run the attached test with the builtin version, you'll get: ref = 2 ref = 3 ITypeLib has a reference to the linked list of ITypeInfo. Functions GetTypeInfo and GetTypeInfoOfGuid search this list, call ITypeInfo::AddRef and returns the reference to ITypeInfo. ITypeInfo is destroyed when ITypeLib is destroyed (it means that each other ITypeInfos are destroyed too). Running this test with native Windows dll, results are: ref = 1 ref = 2
Sounds like a bug to me. Refcounting differences can cause crashes and memory leaks.
I don't thik it Wine's bug. Applications don't depend on this stuff and Wine's ref handling is correct.
I'd be very surprised if there were no apps that depended on it, actually. Given the number of crashes we've seen caused by refcount problems in this part of the code, I'd say there definitely are.
Mike Hearn wrote:
Sounds like a bug to me. Refcounting differences can cause crashes and memory leaks.
I'm sure there are no memory leaks.
I don't thik it Wine's bug. Applications don't depend on this stuff and Wine's ref handling is correct.
I'd be very surprised if there were no apps that depended on it, actually. Given the number of crashes we've seen caused by refcount problems in this part of the code, I'd say there definitely are.
Application that depend on this will look like:
pITypeInfo = ITypeLib_GetTypeLib(.....)
(some stuff) //here application doesn't release ITypeLib
if(ITypeInfo_Release(pTypeInfo) == 0) { /* something funny */ }
Applications shouldn't do that. If we want to be full compatibile, ITypeInfo has to be created while application asks about ITypeInfo for the first time. It's not a big problem to do so but I don't think it's really important. Another solution would be to destroy ITypeinfo when ref == -1 and make initial value 0. It will keep the present handling of ITypeInfo in ITypeLib and, for application, it will look like Windows ref handling, but I don't know if it is acceptable. I also think that the way Wine does it is better - it just works faster and needes less memory.
Jacek
On Sat, Aug 28, 2004 at 05:59:39PM -0400, Nyef wrote:
The ICreateTypeLib2 interface is used to create the new-style MSFT typelibs. The older ICreateTypeLib interface is used for the old-style typelibs. While the newer interface also implements the older one, when you ask for the old interface with CreateTypeLib() you get a completely different implementation.
I don't see why it necessarily follows that stdole32 wouldn't work as an MSFT typelib, but the implementation of ICreateTypeInfo2 is badly incomplete in places, and I would trust it to completely mess up any semi-complex type library you attempt to create with it. Specifically, any type library that involves functions or variables.
You're right, an MSFT stdole32 might work fine - I guess we should at least try it. So for fun I've attached the program we used to generate CrossOver's stdole32.tlb (Actually you need to take the generated file and wrap it up in a resource only dll, but that's a detail). Since it was designed to be compiled with MSVC, it uses the L"" construct for olestrings - you can hack around this by compiling with -fshort-wchar for now.
Huw.
Huw D M Davies wrote:
You're right, an MSFT stdole32 might work fine - I guess we should at least try it. So for fun I've attached the program we used to generate CrossOver's stdole32.tlb (Actually you need to take the generated file and wrap it up in a resource only dll, but that's a detail). Since it was designed to be compiled with MSVC, it uses the L"" construct for olestrings - you can hack around this by compiling with -fshort-wchar for now.
I tried to change CreateTypeLib to CreateTypeLib2 and running it with Wine DLLs. It produced bunch of FIXMEs, but generated the type library in the end. The result is attached. Compared to the type library generated using the same executable with Windows DLL only two bytes differ. Is there some type library dump program that can be used to find out what are the differences or am I left alone and should I try to find out the actual differences other way?
- Filip
fixme:typelib2:ctl2_encode_typedesc Array vartype, hacking badly. fixme:typelib2:ctl2_encode_typedesc PTR vartype, may not work correctly. fixme:typelib2:ctl2_encode_typedesc Unrecognized type 12. fixme:typelib2:ctl2_encode_typedesc PTR vartype, may not work correctly. fixme:typelib2:ctl2_encode_typedesc PTR vartype, may not work correctly. fixme:typelib2:ctl2_encode_typedesc PTR vartype, may not work correctly. fixme:typelib2:ICreateTypeInfo2_fnAddFuncDesc (00257CD8,0,0022FE90), stub! fixme:typelib2:ICreateTypeInfo2_fnAddFuncDesc {1610612736,00000000,0022FD80,1,1,4,2,0,0,0,{25},1} fixme:typelib2:ctl2_encode_typedesc PTR vartype, may not work correctly. fixme:typelib2:ctl2_encode_typedesc PTR vartype, may not work correctly. fixme:typelib2:ctl2_encode_typedesc PTR vartype, may not work correctly. fixme:typelib2:ICreateTypeInfo2_fnSetFuncAndParamNames (00257CD8,0,L"QueryInterface",3), stub! fixme:typelib2:ICreateTypeInfo2_fnAddFuncDesc (00257CD8,1,0022FE90), stub! fixme:typelib2:ICreateTypeInfo2_fnAddFuncDesc {1610612737,00000000,00000000,1,1,4,0,0,0,0,{19},1} fixme:typelib2:ICreateTypeInfo2_fnSetFuncAndParamNames (00257CD8,1,L"AddRef",1), stub! fixme:typelib2:ICreateTypeInfo2_fnAddFuncDesc (00257CD8,2,0022FE90), stub! fixme:typelib2:ICreateTypeInfo2_fnAddFuncDesc {1610612738,00000000,00000000,1,1,4,0,0,0,0,{19},1} fixme:typelib2:ICreateTypeInfo2_fnSetFuncAndParamNames (00257CD8,2,L"Release",1), stub! fixme:typelib2:ICreateTypeInfo2_fnAddFuncDesc (00259F08,0,0022FE90), stub! fixme:typelib2:ICreateTypeInfo2_fnAddFuncDesc {1610678272,00000000,0022FD80,1,1,4,1,0,0,0,{25},1} fixme:typelib2:ctl2_encode_typedesc PTR vartype, may not work correctly. fixme:typelib2:ICreateTypeInfo2_fnSetFuncAndParamNames (00259F08,0,L"GetTypeInfoCount",2), stub! fixme:typelib2:ICreateTypeInfo2_fnAddFuncDesc (00259F08,1,0022FE90), stub! fixme:typelib2:ICreateTypeInfo2_fnAddFuncDesc {1610678273,00000000,0022FD80,1,1,4,3,0,0,0,{25},1} fixme:typelib2:ctl2_encode_typedesc PTR vartype, may not work correctly. fixme:typelib2:ctl2_encode_typedesc PTR vartype, may not work correctly. fixme:typelib2:ICreateTypeInfo2_fnSetFuncAndParamNames (00259F08,1,L"GetTypeInfo",4), stub! fixme:typelib2:ICreateTypeInfo2_fnAddFuncDesc (00259F08,2,0022FE90), stub! fixme:typelib2:ICreateTypeInfo2_fnAddFuncDesc {1610678274,00000000,0022FD80,1,1,4,5,0,0,0,{25},1} fixme:typelib2:ctl2_encode_typedesc PTR vartype, may not work correctly. fixme:typelib2:ctl2_encode_typedesc PTR vartype, may not work correctly. fixme:typelib2:ctl2_encode_typedesc PTR vartype, may not work correctly. fixme:typelib2:ctl2_encode_typedesc PTR vartype, may not work correctly. fixme:typelib2:ICreateTypeInfo2_fnSetFuncAndParamNames (00259F08,2,L"GetIDsOfNames",6), stub! fixme:typelib2:ICreateTypeInfo2_fnAddFuncDesc (00259F08,3,0022FE90), stub! fixme:typelib2:ICreateTypeInfo2_fnAddFuncDesc {1610678275,00000000,0022FD80,1,1,4,8,0,0,0,{25},1} fixme:typelib2:ctl2_encode_typedesc PTR vartype, may not work correctly. fixme:typelib2:ctl2_encode_typedesc PTR vartype, may not work correctly. fixme:typelib2:ctl2_encode_typedesc PTR vartype, may not work correctly. fixme:typelib2:ctl2_encode_typedesc Unrecognized type 12. fixme:typelib2:ctl2_encode_typedesc PTR vartype, may not work correctly. fixme:typelib2:ctl2_encode_typedesc PTR vartype, may not work correctly. fixme:typelib2:ICreateTypeInfo2_fnSetFuncAndParamNames (00259F08,3,L"Invoke",9), stub! fixme:typelib2:ICreateTypeInfo2_fnAddFuncDesc (0025C138,0,0022FE90), stub! fixme:typelib2:ICreateTypeInfo2_fnAddFuncDesc {1610678272,00000000,0022FD80,1,1,4,3,0,0,0,{25},0} fixme:typelib2:ctl2_encode_typedesc PTR vartype, may not work correctly. fixme:typelib2:ctl2_encode_typedesc Unrecognized type 12. fixme:typelib2:ctl2_encode_typedesc PTR vartype, may not work correctly. fixme:typelib2:ICreateTypeInfo2_fnSetFuncAndParamNames (0025C138,0,L"Next",4), stub! fixme:typelib2:ICreateTypeInfo2_fnAddFuncDesc (0025C138,1,0022FE90), stub! fixme:typelib2:ICreateTypeInfo2_fnAddFuncDesc {1610678273,00000000,0022FD80,1,1,4,1,0,0,0,{25},0} fixme:typelib2:ICreateTypeInfo2_fnSetFuncAndParamNames (0025C138,1,L"Skip",2), stub! fixme:typelib2:ICreateTypeInfo2_fnAddFuncDesc (0025C138,2,0022FE90), stub! fixme:typelib2:ICreateTypeInfo2_fnAddFuncDesc {1610678274,00000000,00000000,1,1,4,0,0,0,0,{25},0} fixme:typelib2:ICreateTypeInfo2_fnSetFuncAndParamNames (0025C138,2,L"Reset",1), stub! fixme:typelib2:ICreateTypeInfo2_fnAddFuncDesc (0025C138,3,0022FE90), stub! fixme:typelib2:ICreateTypeInfo2_fnAddFuncDesc {1610678275,00000000,0022FD80,1,1,4,1,0,0,0,{25},0} fixme:typelib2:ctl2_encode_typedesc PTR vartype, may not work correctly. fixme:typelib2:ctl2_encode_typedesc PTR vartype, may not work correctly. fixme:typelib2:ICreateTypeInfo2_fnSetFuncAndParamNames (0025C138,3,L"Clone",2), stub!
Hi,
--- Filip Navara xnavara@volny.cz wrote:
Wine DLLs. It produced bunch of FIXMEs, but generated the type library in the end. The result is attached. Compared to the type library generated using the same executable with Windows DLL only two bytes differ. Is there some type library dump program that can be used to find out what are the differences or am I left alone and should I try to find out the actual differences other way?
After a quick google search. I dont know if this will give you all the information you need but it does have a sample program that can do simple dumping of typelibs.
http://www.microsoft.com/msj/0399/comtype/comtype.aspx
Thanks Steven
__________________________________ Do you Yahoo!? Yahoo! Mail - 50x more storage than other providers! http://promotions.yahoo.com/new_mail
Le dim 29/08/2004 à 14:31, Filip Navara a écrit :
Huw D M Davies wrote:
You're right, an MSFT stdole32 might work fine - I guess we should at least try it. So for fun I've attached the program we used to generate CrossOver's stdole32.tlb (Actually you need to take the generated file and wrap it up in a resource only dll, but that's a detail). Since it was designed to be compiled with MSVC, it uses the L"" construct for olestrings - you can hack around this by compiling with -fshort-wchar for now.
I tried to change CreateTypeLib to CreateTypeLib2 and running it with Wine DLLs. It produced bunch of FIXMEs, but generated the type library in the end. The result is attached. Compared to the type library generated using the same executable with Windows DLL only two bytes differ. Is there some type library dump program that can be used to find out what are the differences or am I left alone and should I try to find out the actual differences other way?
Was the resulting stdole32.tlb file (generated on Wine) a suitable replacement for Microsoft's? IE, does InstallShield works better with this file than without any stdole32.tlb file?
Vincent
Hi Vincent,
--- Vincent B�ron vberon@mecano.gme.usherb.ca wrote:
Was the resulting stdole32.tlb file (generated on Wine) a suitable replacement for Microsoft's? IE, does InstallShield works better with this file than without any stdole32.tlb file?
I think it will work. One thing we have discussed in ReactOS was using the tools as part of our stage2 setup. If there is not a easy way to implement these tools in WIDL like Alexandre wanted maybe making them tools that are run via wineprefixcreate on first run is a acceptable solution?
Thanks Steven
__________________________________ Do you Yahoo!? Read only the mail you want - Yahoo! Mail SpamGuard. http://promotions.yahoo.com/new_mail