Hi.
I've tryed to run game Project Entropia and I got segmentation fault because of a bug in OLE. I've hacked code and I found two bugs:
1. ITypeInfo has back pointer to ITypeLib, but it's possible (and happened) that ITypeLib is destroyed and later ITypeInfo calls its function. I've solve this problem by call ITypeLib_AddRef while creating ITypeInfo (and ITypeLib_Release while destroying ITypeInfo).
2. ITypeInfo_Invoke doesn't support optional parameters. I've added support for cParamsOpt>0. MSDN says that optional parameter is when VARTYPE equals VT_EMPTY, but in my case it was a VT_BYREF | VT_VARIANT type but the pointer was NULL. When I treated it as VT_EMPTY, it was OK.
I enclose my patch. My knownlage about OLE is sparse so I'm not able to test this.
Thanks, Jacek
"jack" jack@itma.pwr.wroc.pl wrote:
@@ -3265,6 +3266,7 @@ return NULL; } *ppTypeInfoImpl = (ITypeInfoImpl*)ITypeInfo_Constructor();
pTypeLibImpl->ref++;
Are you sure you need this piece of the patch? It causes the following test program to fail:
#define COBJMACROS
#include <stdarg.h> #include <stdio.h> #include <assert.h>
#include "windef.h" #include "winbase.h" #include "oleauto.h"
static void load_type_lib(LPCWSTR type_lib) { ITypeLib *iface; TLIBATTR *pTLibAttr; HRESULT hResult; ULONG ref_count; // DWORD dwWritten;
printf("Loading: "%ws"\n", type_lib);
hResult = LoadTypeLib(type_lib, &iface); printf("LoadTypeLib() = %08lx\n", hResult); assert(hResult == S_OK);
hResult = ITypeLib2_GetLibAttr(iface, &pTLibAttr); printf("GetLibAttr() = %08lx\n", hResult); assert(hResult == S_OK);
// fflush(stdout); // WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), pTLibAttr, sizeof(*pTLibAttr), &dwWritten, NULL); // printf("\n\n");
ITypeLib2_ReleaseTLibAttr(iface, pTLibAttr);
ref_count = ITypeLib2_Release(iface); printf("ITypeLib2_Release() = %lu\n", ref_count); assert(ref_count == 0); }
int main(void) { // load_type_lib(L"olepro32.dll"); // load_type_lib(L"msvbvm60.dll"); load_type_lib(L"stdole32.tlb"); return 0; }
Dmitry Timoshkov wrote:
"jack" jack@itma.pwr.wroc.pl wrote:
@@ -3265,6 +3266,7 @@ return NULL; } *ppTypeInfoImpl = (ITypeInfoImpl*)ITypeInfo_Constructor();
pTypeLibImpl->ref++;
Are you sure you need this piece of the patch? It causes the following test program to fail:
No, I don't. In my case I need only this:
/* this is where we are coming from */ + ITypeLib2_AddRef((ITypeLib*)pLibInfo); ptiRet->pTypeLib = pLibInfo; ptiRet->index=count;
but I call ITypeLib_Release in ITypeInfo_Release so I thought I should increment ref here too.
Thanks, Jacek
"Jacek Caban" jack@itma.pwr.wroc.pl wrote:
No, I don't. In my case I need only this:
/* this is where we are coming from */
- ITypeLib2_AddRef((ITypeLib*)pLibInfo); ptiRet->pTypeLib = pLibInfo; ptiRet->index=count;
but I call ITypeLib_Release in ITypeInfo_Release so I thought I should increment ref here too.
Then use my test program and possibly add some other test for typelib reference counting until you get it right. Then submit a tested patch to wine-patches.
Dmitry Timoshkov wrote:
"Jacek Caban" jack@itma.pwr.wroc.pl wrote:
No, I don't. In my case I need only this:
/* this is where we are coming from */
- ITypeLib2_AddRef((ITypeLib*)pLibInfo); ptiRet->pTypeLib = pLibInfo; ptiRet->index=count;
but I call ITypeLib_Release in ITypeInfo_Release so I thought I should increment ref here too.
Then use my test program and possibly add some other test for typelib reference counting until you get it right. Then submit a tested patch to wine-patches.
Thanks for help. I found my bug and I'll send patch soon.
Jacek