mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-02 12:23:31 +00:00
[OLE32_WINETEST]
* Sync to Wine 1.5.4. See issue #7070 for more details. svn path=/trunk/; revision=56598
This commit is contained in:
@@ -19,6 +19,7 @@
|
||||
*/
|
||||
|
||||
#define COBJMACROS
|
||||
#define CONST_VTABLE
|
||||
#define NONAMELESSUNION
|
||||
|
||||
#include <stdarg.h>
|
||||
@@ -49,7 +50,7 @@ static inline char *dump_fmtetc(FORMATETC *fmt)
|
||||
}
|
||||
|
||||
typedef struct DataObjectImpl {
|
||||
const IDataObjectVtbl *lpVtbl;
|
||||
IDataObject IDataObject_iface;
|
||||
LONG ref;
|
||||
|
||||
FORMATETC *fmtetc;
|
||||
@@ -61,7 +62,7 @@ typedef struct DataObjectImpl {
|
||||
} DataObjectImpl;
|
||||
|
||||
typedef struct EnumFormatImpl {
|
||||
const IEnumFORMATETCVtbl *lpVtbl;
|
||||
IEnumFORMATETC IEnumFORMATETC_iface;
|
||||
LONG ref;
|
||||
|
||||
FORMATETC *fmtetc;
|
||||
@@ -79,9 +80,19 @@ static UINT cf_stream, cf_storage, cf_global, cf_another, cf_onemore;
|
||||
|
||||
static HRESULT EnumFormatImpl_Create(FORMATETC *fmtetc, UINT size, LPENUMFORMATETC *lplpformatetc);
|
||||
|
||||
static inline DataObjectImpl *impl_from_IDataObject(IDataObject *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, DataObjectImpl, IDataObject_iface);
|
||||
}
|
||||
|
||||
static inline EnumFormatImpl *impl_from_IEnumFORMATETC(IEnumFORMATETC *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, EnumFormatImpl, IEnumFORMATETC_iface);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI EnumFormatImpl_QueryInterface(IEnumFORMATETC *iface, REFIID riid, LPVOID *ppvObj)
|
||||
{
|
||||
EnumFormatImpl *This = (EnumFormatImpl*)iface;
|
||||
EnumFormatImpl *This = impl_from_IEnumFORMATETC(iface);
|
||||
|
||||
if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IEnumFORMATETC)) {
|
||||
IEnumFORMATETC_AddRef(iface);
|
||||
@@ -94,14 +105,14 @@ static HRESULT WINAPI EnumFormatImpl_QueryInterface(IEnumFORMATETC *iface, REFII
|
||||
|
||||
static ULONG WINAPI EnumFormatImpl_AddRef(IEnumFORMATETC *iface)
|
||||
{
|
||||
EnumFormatImpl *This = (EnumFormatImpl*)iface;
|
||||
EnumFormatImpl *This = impl_from_IEnumFORMATETC(iface);
|
||||
LONG ref = InterlockedIncrement(&This->ref);
|
||||
return ref;
|
||||
}
|
||||
|
||||
static ULONG WINAPI EnumFormatImpl_Release(IEnumFORMATETC *iface)
|
||||
{
|
||||
EnumFormatImpl *This = (EnumFormatImpl*)iface;
|
||||
EnumFormatImpl *This = impl_from_IEnumFORMATETC(iface);
|
||||
ULONG ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
if(!ref) {
|
||||
@@ -115,7 +126,7 @@ static ULONG WINAPI EnumFormatImpl_Release(IEnumFORMATETC *iface)
|
||||
static HRESULT WINAPI EnumFormatImpl_Next(IEnumFORMATETC *iface, ULONG celt,
|
||||
FORMATETC *rgelt, ULONG *pceltFetched)
|
||||
{
|
||||
EnumFormatImpl *This = (EnumFormatImpl*)iface;
|
||||
EnumFormatImpl *This = impl_from_IEnumFORMATETC(iface);
|
||||
ULONG count, i;
|
||||
|
||||
trace("next: count %d cur %d\n", celt, This->cur);
|
||||
@@ -147,7 +158,7 @@ static HRESULT WINAPI EnumFormatImpl_Skip(IEnumFORMATETC *iface, ULONG celt)
|
||||
|
||||
static HRESULT WINAPI EnumFormatImpl_Reset(IEnumFORMATETC *iface)
|
||||
{
|
||||
EnumFormatImpl *This = (EnumFormatImpl*)iface;
|
||||
EnumFormatImpl *This = impl_from_IEnumFORMATETC(iface);
|
||||
|
||||
This->cur = 0;
|
||||
return S_OK;
|
||||
@@ -174,7 +185,7 @@ static HRESULT EnumFormatImpl_Create(FORMATETC *fmtetc, UINT fmtetc_cnt, IEnumFO
|
||||
EnumFormatImpl *ret;
|
||||
|
||||
ret = HeapAlloc(GetProcessHeap(), 0, sizeof(EnumFormatImpl));
|
||||
ret->lpVtbl = &VT_EnumFormatImpl;
|
||||
ret->IEnumFORMATETC_iface.lpVtbl = &VT_EnumFormatImpl;
|
||||
ret->ref = 1;
|
||||
ret->cur = 0;
|
||||
ret->fmtetc_cnt = fmtetc_cnt;
|
||||
@@ -186,7 +197,7 @@ static HRESULT EnumFormatImpl_Create(FORMATETC *fmtetc, UINT fmtetc_cnt, IEnumFO
|
||||
|
||||
static HRESULT WINAPI DataObjectImpl_QueryInterface(IDataObject *iface, REFIID riid, LPVOID *ppvObj)
|
||||
{
|
||||
DataObjectImpl *This = (DataObjectImpl*)iface;
|
||||
DataObjectImpl *This = impl_from_IDataObject(iface);
|
||||
|
||||
if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IDataObject)) {
|
||||
IDataObject_AddRef(iface);
|
||||
@@ -199,14 +210,14 @@ static HRESULT WINAPI DataObjectImpl_QueryInterface(IDataObject *iface, REFIID r
|
||||
|
||||
static ULONG WINAPI DataObjectImpl_AddRef(IDataObject* iface)
|
||||
{
|
||||
DataObjectImpl *This = (DataObjectImpl*)iface;
|
||||
DataObjectImpl *This = impl_from_IDataObject(iface);
|
||||
ULONG ref = InterlockedIncrement(&This->ref);
|
||||
return ref;
|
||||
}
|
||||
|
||||
static ULONG WINAPI DataObjectImpl_Release(IDataObject* iface)
|
||||
{
|
||||
DataObjectImpl *This = (DataObjectImpl*)iface;
|
||||
DataObjectImpl *This = impl_from_IDataObject(iface);
|
||||
ULONG ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
if(!ref)
|
||||
@@ -226,7 +237,7 @@ static ULONG WINAPI DataObjectImpl_Release(IDataObject* iface)
|
||||
|
||||
static HRESULT WINAPI DataObjectImpl_GetData(IDataObject* iface, FORMATETC *pformatetc, STGMEDIUM *pmedium)
|
||||
{
|
||||
DataObjectImpl *This = (DataObjectImpl*)iface;
|
||||
DataObjectImpl *This = impl_from_IDataObject(iface);
|
||||
UINT i;
|
||||
BOOL foundFormat = FALSE;
|
||||
|
||||
@@ -282,7 +293,7 @@ static HRESULT WINAPI DataObjectImpl_GetDataHere(IDataObject* iface, FORMATETC *
|
||||
|
||||
static HRESULT WINAPI DataObjectImpl_QueryGetData(IDataObject* iface, FORMATETC *pformatetc)
|
||||
{
|
||||
DataObjectImpl *This = (DataObjectImpl*)iface;
|
||||
DataObjectImpl *This = impl_from_IDataObject(iface);
|
||||
UINT i;
|
||||
BOOL foundFormat = FALSE;
|
||||
|
||||
@@ -320,7 +331,7 @@ static HRESULT WINAPI DataObjectImpl_SetData(IDataObject* iface, FORMATETC *pfor
|
||||
static HRESULT WINAPI DataObjectImpl_EnumFormatEtc(IDataObject* iface, DWORD dwDirection,
|
||||
IEnumFORMATETC **ppenumFormatEtc)
|
||||
{
|
||||
DataObjectImpl *This = (DataObjectImpl*)iface;
|
||||
DataObjectImpl *This = impl_from_IDataObject(iface);
|
||||
|
||||
DataObjectImpl_EnumFormatEtc_calls++;
|
||||
|
||||
@@ -371,7 +382,7 @@ static HRESULT DataObjectImpl_CreateText(LPCSTR text, LPDATAOBJECT *lplpdataobj)
|
||||
DataObjectImpl *obj;
|
||||
|
||||
obj = HeapAlloc(GetProcessHeap(), 0, sizeof(DataObjectImpl));
|
||||
obj->lpVtbl = &VT_DataObjectImpl;
|
||||
obj->IDataObject_iface.lpVtbl = &VT_DataObjectImpl;
|
||||
obj->ref = 1;
|
||||
obj->text = GlobalAlloc(GMEM_MOVEABLE, strlen(text) + 1);
|
||||
strcpy(GlobalLock(obj->text), text);
|
||||
@@ -387,9 +398,9 @@ static HRESULT DataObjectImpl_CreateText(LPCSTR text, LPDATAOBJECT *lplpdataobj)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
const char *cmpl_stm_data = "complex stream";
|
||||
const char *cmpl_text_data = "complex text";
|
||||
const WCHAR device_name[] = {'m','y','d','e','v',0};
|
||||
static const char *cmpl_stm_data = "complex stream";
|
||||
static const char *cmpl_text_data = "complex text";
|
||||
static const WCHAR device_name[] = {'m','y','d','e','v',0};
|
||||
|
||||
static HRESULT DataObjectImpl_CreateComplex(LPDATAOBJECT *lplpdataobj)
|
||||
{
|
||||
@@ -398,7 +409,7 @@ static HRESULT DataObjectImpl_CreateComplex(LPDATAOBJECT *lplpdataobj)
|
||||
DEVMODEW dm;
|
||||
|
||||
obj = HeapAlloc(GetProcessHeap(), 0, sizeof(DataObjectImpl));
|
||||
obj->lpVtbl = &VT_DataObjectImpl;
|
||||
obj->IDataObject_iface.lpVtbl = &VT_DataObjectImpl;
|
||||
obj->ref = 1;
|
||||
obj->text = GlobalAlloc(GMEM_MOVEABLE, strlen(cmpl_text_data) + 1);
|
||||
strcpy(GlobalLock(obj->text), cmpl_text_data);
|
||||
@@ -417,18 +428,21 @@ static HRESULT DataObjectImpl_CreateComplex(LPDATAOBJECT *lplpdataobj)
|
||||
InitFormatEtc(obj->fmtetc[1], cf_stream, TYMED_ISTREAM);
|
||||
InitFormatEtc(obj->fmtetc[2], cf_storage, TYMED_ISTORAGE);
|
||||
InitFormatEtc(obj->fmtetc[3], cf_another, TYMED_ISTORAGE|TYMED_ISTREAM|TYMED_HGLOBAL);
|
||||
memset(&dm, 0, sizeof(dm));
|
||||
dm.dmSize = sizeof(dm);
|
||||
dm.dmDriverExtra = 0;
|
||||
lstrcpyW(dm.dmDeviceName, device_name);
|
||||
obj->fmtetc[3].ptd = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(DVTARGETDEVICE, tdData) + sizeof(device_name) + dm.dmSize + dm.dmDriverExtra);
|
||||
obj->fmtetc[3].ptd->tdSize = FIELD_OFFSET(DVTARGETDEVICE, tdData) + sizeof(device_name) + dm.dmSize + dm.dmDriverExtra;
|
||||
obj->fmtetc[3].ptd->tdDriverNameOffset = FIELD_OFFSET(DVTARGETDEVICE, tdData);
|
||||
obj->fmtetc[3].ptd->tdDeviceNameOffset = 0;
|
||||
obj->fmtetc[3].ptd->tdPortNameOffset = 0;
|
||||
obj->fmtetc[3].ptd->tdExtDevmodeOffset = obj->fmtetc[3].ptd->tdDriverNameOffset + sizeof(device_name);
|
||||
lstrcpyW((WCHAR*)obj->fmtetc[3].ptd->tdData, device_name);
|
||||
memcpy(obj->fmtetc[3].ptd->tdData + sizeof(device_name), &dm, dm.dmSize + dm.dmDriverExtra);
|
||||
if (0) /* Causes crashes on both Wine and Windows */
|
||||
{
|
||||
memset(&dm, 0, sizeof(dm));
|
||||
dm.dmSize = sizeof(dm);
|
||||
dm.dmDriverExtra = 0;
|
||||
lstrcpyW(dm.dmDeviceName, device_name);
|
||||
obj->fmtetc[3].ptd = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(DVTARGETDEVICE, tdData) + sizeof(device_name) + dm.dmSize + dm.dmDriverExtra);
|
||||
obj->fmtetc[3].ptd->tdSize = FIELD_OFFSET(DVTARGETDEVICE, tdData) + sizeof(device_name) + dm.dmSize + dm.dmDriverExtra;
|
||||
obj->fmtetc[3].ptd->tdDriverNameOffset = FIELD_OFFSET(DVTARGETDEVICE, tdData);
|
||||
obj->fmtetc[3].ptd->tdDeviceNameOffset = 0;
|
||||
obj->fmtetc[3].ptd->tdPortNameOffset = 0;
|
||||
obj->fmtetc[3].ptd->tdExtDevmodeOffset = obj->fmtetc[3].ptd->tdDriverNameOffset + sizeof(device_name);
|
||||
lstrcpyW((WCHAR*)obj->fmtetc[3].ptd->tdData, device_name);
|
||||
memcpy(obj->fmtetc[3].ptd->tdData + sizeof(device_name), &dm, dm.dmSize + dm.dmDriverExtra);
|
||||
}
|
||||
|
||||
InitFormatEtc(obj->fmtetc[4], cf_global, TYMED_HGLOBAL);
|
||||
InitFormatEtc(obj->fmtetc[5], cf_another, TYMED_HGLOBAL);
|
||||
@@ -812,15 +826,15 @@ static void test_set_clipboard(void)
|
||||
cf_onemore = RegisterClipboardFormatA("one more format");
|
||||
|
||||
hr = DataObjectImpl_CreateText("data1", &data1);
|
||||
ok(SUCCEEDED(hr), "Failed to create data1 object: 0x%08x\n", hr);
|
||||
ok(hr == S_OK, "Failed to create data1 object: 0x%08x\n", hr);
|
||||
if(FAILED(hr))
|
||||
return;
|
||||
hr = DataObjectImpl_CreateText("data2", &data2);
|
||||
ok(SUCCEEDED(hr), "Failed to create data2 object: 0x%08x\n", hr);
|
||||
ok(hr == S_OK, "Failed to create data2 object: 0x%08x\n", hr);
|
||||
if(FAILED(hr))
|
||||
return;
|
||||
hr = DataObjectImpl_CreateComplex(&data_cmpl);
|
||||
ok(SUCCEEDED(hr), "Failed to create complex data object: 0x%08x\n", hr);
|
||||
ok(hr == S_OK, "Failed to create complex data object: 0x%08x\n", hr);
|
||||
if(FAILED(hr))
|
||||
return;
|
||||
|
||||
@@ -1180,32 +1194,33 @@ static void test_flushed_getdata(void)
|
||||
/* complex format with target device */
|
||||
|
||||
InitFormatEtc(fmt, cf_another, 0xffff);
|
||||
hr = IDataObject_GetData(get, &fmt, &med);
|
||||
ok(hr == DV_E_FORMATETC ||
|
||||
broken(hr == S_OK), /* win9x, winme & nt4 */
|
||||
"got %08x\n", hr);
|
||||
if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
|
||||
|
||||
InitFormatEtc(fmt, cf_another, 0xffff);
|
||||
memset(&dm, 0, sizeof(dm));
|
||||
dm.dmSize = sizeof(dm);
|
||||
dm.dmDriverExtra = 0;
|
||||
lstrcpyW(dm.dmDeviceName, device_name);
|
||||
fmt.ptd = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(DVTARGETDEVICE, tdData) + sizeof(device_name) + dm.dmSize + dm.dmDriverExtra);
|
||||
fmt.ptd->tdSize = FIELD_OFFSET(DVTARGETDEVICE, tdData) + sizeof(device_name) + dm.dmSize + dm.dmDriverExtra;
|
||||
fmt.ptd->tdDriverNameOffset = FIELD_OFFSET(DVTARGETDEVICE, tdData);
|
||||
fmt.ptd->tdDeviceNameOffset = 0;
|
||||
fmt.ptd->tdPortNameOffset = 0;
|
||||
fmt.ptd->tdExtDevmodeOffset = fmt.ptd->tdDriverNameOffset + sizeof(device_name);
|
||||
lstrcpyW((WCHAR*)fmt.ptd->tdData, device_name);
|
||||
memcpy(fmt.ptd->tdData + sizeof(device_name), &dm, dm.dmSize + dm.dmDriverExtra);
|
||||
|
||||
hr = IDataObject_GetData(get, &fmt, &med);
|
||||
ok(hr == S_OK, "got %08x\n", hr);
|
||||
ok(med.tymed == TYMED_ISTORAGE, "got %x\n", med.tymed);
|
||||
if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, fmt.ptd);
|
||||
if (0) /* Causes crashes on both Wine and Windows */
|
||||
{
|
||||
InitFormatEtc(fmt, cf_another, 0xffff);
|
||||
memset(&dm, 0, sizeof(dm));
|
||||
dm.dmSize = sizeof(dm);
|
||||
dm.dmDriverExtra = 0;
|
||||
lstrcpyW(dm.dmDeviceName, device_name);
|
||||
fmt.ptd = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(DVTARGETDEVICE, tdData) + sizeof(device_name) + dm.dmSize + dm.dmDriverExtra);
|
||||
fmt.ptd->tdSize = FIELD_OFFSET(DVTARGETDEVICE, tdData) + sizeof(device_name) + dm.dmSize + dm.dmDriverExtra;
|
||||
fmt.ptd->tdDriverNameOffset = FIELD_OFFSET(DVTARGETDEVICE, tdData);
|
||||
fmt.ptd->tdDeviceNameOffset = 0;
|
||||
fmt.ptd->tdPortNameOffset = 0;
|
||||
fmt.ptd->tdExtDevmodeOffset = fmt.ptd->tdDriverNameOffset + sizeof(device_name);
|
||||
lstrcpyW((WCHAR*)fmt.ptd->tdData, device_name);
|
||||
memcpy(fmt.ptd->tdData + sizeof(device_name), &dm, dm.dmSize + dm.dmDriverExtra);
|
||||
|
||||
hr = IDataObject_GetData(get, &fmt, &med);
|
||||
ok(hr == S_OK, "got %08x\n", hr);
|
||||
ok(med.tymed == TYMED_ISTORAGE, "got %x\n", med.tymed);
|
||||
if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, fmt.ptd);
|
||||
}
|
||||
|
||||
|
||||
IDataObject_Release(get);
|
||||
|
||||
@@ -38,11 +38,11 @@
|
||||
extern const IID GUID_NULL;
|
||||
|
||||
/* functions that are not present on all versions of Windows */
|
||||
HRESULT (WINAPI * pCoInitializeEx)(LPVOID lpReserved, DWORD dwCoInit);
|
||||
HRESULT (WINAPI * pCoGetObjectContext)(REFIID riid, LPVOID *ppv);
|
||||
HRESULT (WINAPI * pCoSwitchCallContext)(IUnknown *pObject, IUnknown **ppOldObject);
|
||||
HRESULT (WINAPI * pCoGetTreatAsClass)(REFCLSID clsidOld, LPCLSID pClsidNew);
|
||||
HRESULT (WINAPI * pCoGetContextToken)(ULONG_PTR *token);
|
||||
static HRESULT (WINAPI * pCoInitializeEx)(LPVOID lpReserved, DWORD dwCoInit);
|
||||
static HRESULT (WINAPI * pCoGetObjectContext)(REFIID riid, LPVOID *ppv);
|
||||
static HRESULT (WINAPI * pCoSwitchCallContext)(IUnknown *pObject, IUnknown **ppOldObject);
|
||||
static HRESULT (WINAPI * pCoGetTreatAsClass)(REFCLSID clsidOld, LPCLSID pClsidNew);
|
||||
static HRESULT (WINAPI * pCoGetContextToken)(ULONG_PTR *token);
|
||||
|
||||
#define ok_ole_success(hr, func) ok(hr == S_OK, func " failed with error 0x%08x\n", hr)
|
||||
#define ok_more_than_one_lock() ok(cLocks > 0, "Number of locks should be > 0, but actually is %d\n", cLocks)
|
||||
@@ -117,7 +117,7 @@ static ULONG WINAPI Test_IClassFactory_Release(LPCLASSFACTORY iface)
|
||||
|
||||
static HRESULT WINAPI Test_IClassFactory_CreateInstance(
|
||||
LPCLASSFACTORY iface,
|
||||
LPUNKNOWN pUnkOuter,
|
||||
IUnknown *pUnkOuter,
|
||||
REFIID riid,
|
||||
LPVOID *ppvObj)
|
||||
{
|
||||
@@ -192,6 +192,9 @@ static void test_CLSIDFromProgID(void)
|
||||
static void test_CLSIDFromString(void)
|
||||
{
|
||||
CLSID clsid;
|
||||
WCHAR wszCLSID_Broken[50];
|
||||
UINT i;
|
||||
|
||||
HRESULT hr = CLSIDFromString(wszCLSID_StdFont, &clsid);
|
||||
ok_ole_success(hr, "CLSIDFromString");
|
||||
ok(IsEqualCLSID(&clsid, &CLSID_StdFont), "clsid wasn't equal to CLSID_StdFont\n");
|
||||
@@ -199,6 +202,60 @@ static void test_CLSIDFromString(void)
|
||||
hr = CLSIDFromString(NULL, &clsid);
|
||||
ok_ole_success(hr, "CLSIDFromString");
|
||||
ok(IsEqualCLSID(&clsid, &CLSID_NULL), "clsid wasn't equal to CLSID_NULL\n");
|
||||
|
||||
lstrcpyW(wszCLSID_Broken, wszCLSID_StdFont);
|
||||
for(i = lstrlenW(wszCLSID_StdFont); i < 49; i++)
|
||||
wszCLSID_Broken[i] = 'A';
|
||||
wszCLSID_Broken[i] = '\0';
|
||||
|
||||
memset(&clsid, 0, sizeof(CLSID));
|
||||
hr = CLSIDFromString(wszCLSID_Broken, &clsid);
|
||||
ok(hr == CO_E_CLASSSTRING, "Got %08x\n", hr);
|
||||
ok(IsEqualCLSID(&clsid, &CLSID_StdFont), "clsid wasn't equal to CLSID_StdFont\n");
|
||||
|
||||
wszCLSID_Broken[lstrlenW(wszCLSID_StdFont)-1] = 'A';
|
||||
memset(&clsid, 0, sizeof(CLSID));
|
||||
hr = CLSIDFromString(wszCLSID_Broken, &clsid);
|
||||
ok(hr == CO_E_CLASSSTRING, "Got %08x\n", hr);
|
||||
ok(IsEqualCLSID(&clsid, &CLSID_StdFont), "clsid wasn't equal to CLSID_StdFont\n");
|
||||
|
||||
wszCLSID_Broken[lstrlenW(wszCLSID_StdFont)] = '\0';
|
||||
memset(&clsid, 0, sizeof(CLSID));
|
||||
hr = CLSIDFromString(wszCLSID_Broken, &clsid);
|
||||
ok(hr == CO_E_CLASSSTRING, "Got %08x\n", hr);
|
||||
ok(IsEqualCLSID(&clsid, &CLSID_StdFont), "clsid wasn't equal to CLSID_StdFont\n");
|
||||
|
||||
wszCLSID_Broken[lstrlenW(wszCLSID_StdFont)-1] = '\0';
|
||||
memset(&clsid, 0, sizeof(CLSID));
|
||||
hr = CLSIDFromString(wszCLSID_Broken, &clsid);
|
||||
ok(hr == CO_E_CLASSSTRING, "Got %08x\n", hr);
|
||||
ok(IsEqualCLSID(&clsid, &CLSID_StdFont), "clsid wasn't equal to CLSID_StdFont\n");
|
||||
|
||||
memset(&clsid, 0xcc, sizeof(CLSID));
|
||||
hr = CLSIDFromString(wszCLSID_Broken+1, &clsid);
|
||||
ok(hr == CO_E_CLASSSTRING, "Got %08x\n", hr);
|
||||
ok(IsEqualCLSID(&clsid, &CLSID_NULL), "clsid wasn't equal to CLSID_NULL\n");
|
||||
|
||||
wszCLSID_Broken[9] = '*';
|
||||
memset(&clsid, 0xcc, sizeof(CLSID));
|
||||
hr = CLSIDFromString(wszCLSID_Broken, &clsid);
|
||||
ok(hr == CO_E_CLASSSTRING, "Got %08x\n", hr);
|
||||
ok(clsid.Data1 == CLSID_StdFont.Data1, "Got %08x\n", clsid.Data1);
|
||||
ok(clsid.Data2 == 0xcccc, "Got %04x\n", clsid.Data2);
|
||||
|
||||
wszCLSID_Broken[3] = '*';
|
||||
memset(&clsid, 0xcc, sizeof(CLSID));
|
||||
hr = CLSIDFromString(wszCLSID_Broken, &clsid);
|
||||
ok(hr == CO_E_CLASSSTRING, "Got %08x\n", hr);
|
||||
ok(clsid.Data1 == 0xb, "Got %08x\n", clsid.Data1);
|
||||
ok(clsid.Data2 == 0xcccc, "Got %04x\n", clsid.Data2);
|
||||
|
||||
wszCLSID_Broken[3] = '\0';
|
||||
memset(&clsid, 0xcc, sizeof(CLSID));
|
||||
hr = CLSIDFromString(wszCLSID_Broken, &clsid);
|
||||
ok(hr == CO_E_CLASSSTRING, "Got %08x\n", hr);
|
||||
ok(clsid.Data1 == 0xb, "Got %08x\n", clsid.Data1);
|
||||
ok(clsid.Data2 == 0xcccc, "Got %04x\n", clsid.Data2);
|
||||
}
|
||||
|
||||
static void test_StringFromGUID2(void)
|
||||
@@ -515,7 +572,7 @@ static void test_CoRegisterMessageFilter(void)
|
||||
}
|
||||
|
||||
static HRESULT WINAPI Test_IUnknown_QueryInterface(
|
||||
LPUNKNOWN iface,
|
||||
IUnknown *iface,
|
||||
REFIID riid,
|
||||
LPVOID *ppvObj)
|
||||
{
|
||||
@@ -533,12 +590,12 @@ static HRESULT WINAPI Test_IUnknown_QueryInterface(
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI Test_IUnknown_AddRef(LPUNKNOWN iface)
|
||||
static ULONG WINAPI Test_IUnknown_AddRef(IUnknown *iface)
|
||||
{
|
||||
return 2; /* non-heap-based object */
|
||||
}
|
||||
|
||||
static ULONG WINAPI Test_IUnknown_Release(LPUNKNOWN iface)
|
||||
static ULONG WINAPI Test_IUnknown_Release(IUnknown *iface)
|
||||
{
|
||||
return 1; /* non-heap-based object */
|
||||
}
|
||||
@@ -872,7 +929,7 @@ static void test_CoRegisterClassObject(void)
|
||||
|
||||
/* crashes with at least win9x DCOM! */
|
||||
if (0)
|
||||
hr = CoRevokeClassObject(cookie);
|
||||
CoRevokeClassObject(cookie);
|
||||
|
||||
CoUninitialize();
|
||||
}
|
||||
@@ -1216,10 +1273,15 @@ static void test_CoGetObjectContext(void)
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
const IUnknownVtbl *lpVtbl;
|
||||
IUnknown IUnknown_iface;
|
||||
LONG refs;
|
||||
} Test_CallContext;
|
||||
|
||||
static inline Test_CallContext *impl_from_IUnknown(IUnknown *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, Test_CallContext, IUnknown_iface);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI Test_CallContext_QueryInterface(
|
||||
IUnknown *iface,
|
||||
REFIID riid,
|
||||
@@ -1240,13 +1302,13 @@ static HRESULT WINAPI Test_CallContext_QueryInterface(
|
||||
|
||||
static ULONG WINAPI Test_CallContext_AddRef(IUnknown *iface)
|
||||
{
|
||||
Test_CallContext *This = (Test_CallContext*)iface;
|
||||
Test_CallContext *This = impl_from_IUnknown(iface);
|
||||
return InterlockedIncrement(&This->refs);
|
||||
}
|
||||
|
||||
static ULONG WINAPI Test_CallContext_Release(IUnknown *iface)
|
||||
{
|
||||
Test_CallContext *This = (Test_CallContext*)iface;
|
||||
Test_CallContext *This = impl_from_IUnknown(iface);
|
||||
ULONG refs = InterlockedDecrement(&This->refs);
|
||||
if (!refs)
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
@@ -1265,7 +1327,7 @@ static void test_CoGetCallContext(void)
|
||||
HRESULT hr;
|
||||
ULONG refs;
|
||||
IUnknown *pUnk;
|
||||
IUnknown *test_object;
|
||||
Test_CallContext *test_object;
|
||||
|
||||
if (!pCoSwitchCallContext)
|
||||
{
|
||||
@@ -1276,41 +1338,43 @@ static void test_CoGetCallContext(void)
|
||||
CoInitialize(NULL);
|
||||
|
||||
test_object = HeapAlloc(GetProcessHeap(), 0, sizeof(Test_CallContext));
|
||||
((Test_CallContext*)test_object)->lpVtbl = &TestCallContext_Vtbl;
|
||||
((Test_CallContext*)test_object)->refs = 1;
|
||||
test_object->IUnknown_iface.lpVtbl = &TestCallContext_Vtbl;
|
||||
test_object->refs = 1;
|
||||
|
||||
hr = CoGetCallContext(&IID_IUnknown, (void**)&pUnk);
|
||||
ok(hr == RPC_E_CALL_COMPLETE, "Expected RPC_E_CALL_COMPLETE, got 0x%08x\n", hr);
|
||||
|
||||
pUnk = (IUnknown*)0xdeadbeef;
|
||||
hr = pCoSwitchCallContext(test_object, &pUnk);
|
||||
hr = pCoSwitchCallContext(&test_object->IUnknown_iface, &pUnk);
|
||||
ok_ole_success(hr, "CoSwitchCallContext");
|
||||
ok(pUnk == NULL, "expected NULL, got %p\n", pUnk);
|
||||
refs = IUnknown_AddRef(test_object);
|
||||
refs = IUnknown_AddRef(&test_object->IUnknown_iface);
|
||||
ok(refs == 2, "Expected refcount 2, got %d\n", refs);
|
||||
IUnknown_Release(test_object);
|
||||
IUnknown_Release(&test_object->IUnknown_iface);
|
||||
|
||||
pUnk = (IUnknown*)0xdeadbeef;
|
||||
hr = CoGetCallContext(&IID_IUnknown, (void**)&pUnk);
|
||||
ok_ole_success(hr, "CoGetCallContext");
|
||||
ok(pUnk == test_object, "expected %p, got %p\n", test_object, pUnk);
|
||||
refs = IUnknown_AddRef(test_object);
|
||||
ok(pUnk == &test_object->IUnknown_iface, "expected %p, got %p\n",
|
||||
&test_object->IUnknown_iface, pUnk);
|
||||
refs = IUnknown_AddRef(&test_object->IUnknown_iface);
|
||||
ok(refs == 3, "Expected refcount 3, got %d\n", refs);
|
||||
IUnknown_Release(test_object);
|
||||
IUnknown_Release(&test_object->IUnknown_iface);
|
||||
IUnknown_Release(pUnk);
|
||||
|
||||
pUnk = (IUnknown*)0xdeadbeef;
|
||||
hr = pCoSwitchCallContext(NULL, &pUnk);
|
||||
ok_ole_success(hr, "CoSwitchCallContext");
|
||||
ok(pUnk == test_object, "expected %p, got %p\n", test_object, pUnk);
|
||||
refs = IUnknown_AddRef(test_object);
|
||||
ok(pUnk == &test_object->IUnknown_iface, "expected %p, got %p\n",
|
||||
&test_object->IUnknown_iface, pUnk);
|
||||
refs = IUnknown_AddRef(&test_object->IUnknown_iface);
|
||||
ok(refs == 2, "Expected refcount 2, got %d\n", refs);
|
||||
IUnknown_Release(test_object);
|
||||
IUnknown_Release(&test_object->IUnknown_iface);
|
||||
|
||||
hr = CoGetCallContext(&IID_IUnknown, (void**)&pUnk);
|
||||
ok(hr == RPC_E_CALL_COMPLETE, "Expected RPC_E_CALL_COMPLETE, got 0x%08x\n", hr);
|
||||
|
||||
IUnknown_Release(test_object);
|
||||
IUnknown_Release(&test_object->IUnknown_iface);
|
||||
|
||||
CoUninitialize();
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ static int droptarget_refs;
|
||||
static HRESULT WINAPI DropTarget_QueryInterface(IDropTarget* iface, REFIID riid,
|
||||
void** ppvObject)
|
||||
{
|
||||
trace("DropTarget_QueryInterface\n");
|
||||
ok(0, "DropTarget_QueryInterface() shouldn't be called\n");
|
||||
if (IsEqualIID(riid, &IID_IUnknown) ||
|
||||
IsEqualIID(riid, &IID_IDropTarget))
|
||||
{
|
||||
|
||||
@@ -175,7 +175,7 @@ static void test_streamonhglobal(IStream *pStream)
|
||||
ull.u.HighPart = 0xCAFECAFE;
|
||||
ull.u.LowPart = 0xCAFECAFE;
|
||||
ll.u.HighPart = 0;
|
||||
ll.u.LowPart = -sizeof(data);
|
||||
ll.u.LowPart = -(DWORD)sizeof(data);
|
||||
hr = IStream_Seek(pStream, ll, STREAM_SEEK_CUR, &ull);
|
||||
ok_ole_success(hr, "IStream_Seek");
|
||||
ok(ull.u.LowPart == 0, "LowPart set to %d\n", ull.u.LowPart);
|
||||
@@ -190,7 +190,7 @@ static void test_streamonhglobal(IStream *pStream)
|
||||
ull.u.HighPart = 0xCAFECAFE;
|
||||
ull.u.LowPart = 0xCAFECAFE;
|
||||
ll.u.HighPart = 0;
|
||||
ll.u.LowPart = -sizeof(data)-1;
|
||||
ll.u.LowPart = -(DWORD)sizeof(data)-1;
|
||||
hr = IStream_Seek(pStream, ll, STREAM_SEEK_CUR, &ull);
|
||||
ok(hr == STG_E_SEEKERROR, "IStream_Seek should have returned STG_E_SEEKERROR instead of 0x%08x\n", hr);
|
||||
ok(ull.u.LowPart == sizeof(data), "LowPart set to %d\n", ull.u.LowPart);
|
||||
@@ -421,6 +421,8 @@ static void test_copyto(void)
|
||||
static const LARGE_INTEGER llZero;
|
||||
char buffer[15];
|
||||
|
||||
ok_ole_success(hr, "CreateStreamOnHGlobal");
|
||||
|
||||
expected_method_list = methods_copyto;
|
||||
|
||||
hr = IStream_Write(pStream, szHello, sizeof(szHello), &written);
|
||||
|
||||
@@ -36,9 +36,10 @@
|
||||
#include "wine/test.h"
|
||||
|
||||
DEFINE_GUID(CLSID_StdGlobalInterfaceTable,0x00000323,0x0000,0x0000,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
|
||||
DEFINE_GUID(CLSID_ManualResetEvent, 0x0000032c,0x0000,0x0000,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
|
||||
|
||||
/* functions that are not present on all versions of Windows */
|
||||
HRESULT (WINAPI * pCoInitializeEx)(LPVOID lpReserved, DWORD dwCoInit);
|
||||
static HRESULT (WINAPI * pCoInitializeEx)(LPVOID lpReserved, DWORD dwCoInit);
|
||||
|
||||
/* helper macros to make tests a bit leaner */
|
||||
#define ok_more_than_one_lock() ok(cLocks > 0, "Number of locks should be > 0, but actually is %d\n", cLocks)
|
||||
@@ -1437,14 +1438,8 @@ static DWORD CALLBACK bad_thread_proc(LPVOID p)
|
||||
/* Win9x returns E_NOINTERFACE, whilst NT returns RPC_E_WRONG_THREAD */
|
||||
trace("call to proxy's QueryInterface from wrong apartment returned 0x%08x\n", hr);
|
||||
|
||||
/* this statement causes Win9x DCOM to crash during CoUninitialize of
|
||||
* other apartment, so don't test this on Win9x (signified by NT-only
|
||||
* export of CoRegisterSurrogateEx) */
|
||||
if (GetProcAddress(GetModuleHandle("ole32"), "CoRegisterSurrogateEx"))
|
||||
/* now be really bad and release the proxy from the wrong apartment */
|
||||
IUnknown_Release(cf);
|
||||
else
|
||||
skip("skipping test for releasing proxy from wrong apartment that will succeed, but cause a crash during CoUninitialize\n");
|
||||
/* now be really bad and release the proxy from the wrong apartment */
|
||||
IUnknown_Release(cf);
|
||||
|
||||
CoUninitialize();
|
||||
|
||||
@@ -1703,10 +1698,15 @@ static void test_proxy_interfaces(void)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const IUnknownVtbl *lpVtbl;
|
||||
IUnknown IUnknown_iface;
|
||||
ULONG refs;
|
||||
} HeapUnknown;
|
||||
|
||||
static inline HeapUnknown *impl_from_IUnknown(IUnknown *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, HeapUnknown, IUnknown_iface);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI HeapUnknown_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
|
||||
{
|
||||
if (IsEqualIID(riid, &IID_IUnknown))
|
||||
@@ -1721,13 +1721,13 @@ static HRESULT WINAPI HeapUnknown_QueryInterface(IUnknown *iface, REFIID riid, v
|
||||
|
||||
static ULONG WINAPI HeapUnknown_AddRef(IUnknown *iface)
|
||||
{
|
||||
HeapUnknown *This = (HeapUnknown *)iface;
|
||||
HeapUnknown *This = impl_from_IUnknown(iface);
|
||||
return InterlockedIncrement((LONG*)&This->refs);
|
||||
}
|
||||
|
||||
static ULONG WINAPI HeapUnknown_Release(IUnknown *iface)
|
||||
{
|
||||
HeapUnknown *This = (HeapUnknown *)iface;
|
||||
HeapUnknown *This = impl_from_IUnknown(iface);
|
||||
ULONG refs = InterlockedDecrement((LONG*)&This->refs);
|
||||
if (!refs) HeapFree(GetProcessHeap(), 0, This);
|
||||
return refs;
|
||||
@@ -1750,7 +1750,7 @@ static void test_proxybuffer(REFIID riid)
|
||||
CLSID clsid;
|
||||
HeapUnknown *pUnkOuter = HeapAlloc(GetProcessHeap(), 0, sizeof(*pUnkOuter));
|
||||
|
||||
pUnkOuter->lpVtbl = &HeapUnknown_Vtbl;
|
||||
pUnkOuter->IUnknown_iface.lpVtbl = &HeapUnknown_Vtbl;
|
||||
pUnkOuter->refs = 1;
|
||||
|
||||
hr = CoGetPSClsid(riid, &clsid);
|
||||
@@ -1759,21 +1759,17 @@ static void test_proxybuffer(REFIID riid)
|
||||
hr = CoGetClassObject(&clsid, CLSCTX_INPROC_SERVER, NULL, &IID_IPSFactoryBuffer, (LPVOID*)&psfb);
|
||||
ok_ole_success(hr, CoGetClassObject);
|
||||
|
||||
hr = IPSFactoryBuffer_CreateProxy(psfb, (IUnknown*)pUnkOuter, riid, &proxy, &lpvtbl);
|
||||
hr = IPSFactoryBuffer_CreateProxy(psfb, &pUnkOuter->IUnknown_iface, riid, &proxy, &lpvtbl);
|
||||
ok_ole_success(hr, IPSFactoryBuffer_CreateProxy);
|
||||
ok(lpvtbl != NULL, "IPSFactoryBuffer_CreateProxy succeeded, but returned a NULL vtable!\n");
|
||||
|
||||
/* release our reference to the outer unknown object - the PS factory
|
||||
* buffer will have AddRef's it in the CreateProxy call */
|
||||
refs = IUnknown_Release((IUnknown *)pUnkOuter);
|
||||
refs = IUnknown_Release(&pUnkOuter->IUnknown_iface);
|
||||
ok(refs == 1, "Ref count of outer unknown should have been 1 instead of %d\n", refs);
|
||||
|
||||
refs = IPSFactoryBuffer_Release(psfb);
|
||||
if (0)
|
||||
{
|
||||
/* not reliable on native. maybe it leaks references! */
|
||||
ok(refs == 0, "Ref-count leak of %d on IPSFactoryBuffer\n", refs);
|
||||
}
|
||||
/* Not checking return, unreliable on native. Maybe it leaks references? */
|
||||
IPSFactoryBuffer_Release(psfb);
|
||||
|
||||
refs = IUnknown_Release((IUnknown *)lpvtbl);
|
||||
ok(refs == 0, "Ref-count leak of %d on IRpcProxyBuffer\n", refs);
|
||||
@@ -1801,12 +1797,8 @@ static void test_stubbuffer(REFIID riid)
|
||||
hr = IPSFactoryBuffer_CreateStub(psfb, riid, (IUnknown*)&Test_ClassFactory, &stub);
|
||||
ok_ole_success(hr, IPSFactoryBuffer_CreateStub);
|
||||
|
||||
refs = IPSFactoryBuffer_Release(psfb);
|
||||
if (0)
|
||||
{
|
||||
/* not reliable on native. maybe it leaks references */
|
||||
ok(refs == 0, "Ref-count leak of %d on IPSFactoryBuffer\n", refs);
|
||||
}
|
||||
/* Not checking return, unreliable on native. Maybe it leaks references? */
|
||||
IPSFactoryBuffer_Release(psfb);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
|
||||
@@ -1845,7 +1837,7 @@ static const IClassFactoryVtbl TestREClassFactory_Vtbl =
|
||||
Test_IClassFactory_LockServer
|
||||
};
|
||||
|
||||
IClassFactory TestRE_ClassFactory = { &TestREClassFactory_Vtbl };
|
||||
static IClassFactory TestRE_ClassFactory = { &TestREClassFactory_Vtbl };
|
||||
|
||||
static LRESULT CALLBACK window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
|
||||
{
|
||||
@@ -1878,6 +1870,7 @@ static LRESULT CALLBACK window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM l
|
||||
/* note the use of the magic IID_IWineTest value to tell remote thread
|
||||
* to try to send a message back to us */
|
||||
hr = IClassFactory_CreateInstance(proxy, NULL, &IID_IWineTest, (void **)&object);
|
||||
ok(hr == S_FALSE, "expected S_FALSE, got %d\n", hr);
|
||||
|
||||
IClassFactory_Release(proxy);
|
||||
|
||||
@@ -1917,6 +1910,7 @@ static LRESULT CALLBACK window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM l
|
||||
* WM_QUIT message doesn't stop the call from succeeding */
|
||||
PostMessage(hwnd, WM_QUIT, 0, 0);
|
||||
hr = IClassFactory_CreateInstance(proxy, NULL, &IID_IUnknown, (void **)&object);
|
||||
ok(hr == S_FALSE, "IClassFactory_CreateInstance returned 0x%08x, expected S_FALSE\n", hr);
|
||||
|
||||
IClassFactory_Release(proxy);
|
||||
|
||||
@@ -2011,7 +2005,7 @@ static IClassFactoryVtbl TestMsgClassFactory_Vtbl =
|
||||
Test_IClassFactory_LockServer
|
||||
};
|
||||
|
||||
IClassFactory TestMsg_ClassFactory = { &TestMsgClassFactory_Vtbl };
|
||||
static IClassFactory TestMsg_ClassFactory = { &TestMsgClassFactory_Vtbl };
|
||||
|
||||
static void test_call_from_message(void)
|
||||
{
|
||||
@@ -2274,7 +2268,7 @@ static void test_freethreadedmarshaler(void)
|
||||
IMarshal_Release(pFTMarshal);
|
||||
}
|
||||
|
||||
static void reg_unreg_wine_test_class(BOOL Register)
|
||||
static HRESULT reg_unreg_wine_test_class(BOOL Register)
|
||||
{
|
||||
HRESULT hr;
|
||||
char buffer[256];
|
||||
@@ -2292,9 +2286,16 @@ static void reg_unreg_wine_test_class(BOOL Register)
|
||||
if (Register)
|
||||
{
|
||||
error = RegCreateKeyEx(HKEY_CLASSES_ROOT, buffer, 0, NULL, 0, KEY_SET_VALUE, NULL, &hkey, &dwDisposition);
|
||||
if (error == ERROR_ACCESS_DENIED)
|
||||
{
|
||||
skip("Not authorized to modify the Classes key\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
ok(error == ERROR_SUCCESS, "RegCreateKeyEx failed with error %d\n", error);
|
||||
if (error != ERROR_SUCCESS) hr = E_FAIL;
|
||||
error = RegSetValueEx(hkey, NULL, 0, REG_SZ, (const unsigned char *)"\"ole32.dll\"", strlen("\"ole32.dll\"") + 1);
|
||||
ok(error == ERROR_SUCCESS, "RegSetValueEx failed with error %d\n", error);
|
||||
if (error != ERROR_SUCCESS) hr = E_FAIL;
|
||||
RegCloseKey(hkey);
|
||||
}
|
||||
else
|
||||
@@ -2303,6 +2304,7 @@ static void reg_unreg_wine_test_class(BOOL Register)
|
||||
*strrchr(buffer, '\\') = '\0';
|
||||
RegDeleteKey(HKEY_CLASSES_ROOT, buffer);
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
static void test_inproc_handler(void)
|
||||
@@ -2311,7 +2313,8 @@ static void test_inproc_handler(void)
|
||||
IUnknown *pObject;
|
||||
IUnknown *pObject2;
|
||||
|
||||
reg_unreg_wine_test_class(TRUE);
|
||||
if (FAILED(reg_unreg_wine_test_class(TRUE)))
|
||||
return;
|
||||
|
||||
hr = CoCreateInstance(&CLSID_WineTest, NULL, CLSCTX_INPROC_HANDLER, &IID_IUnknown, (void **)&pObject);
|
||||
ok_ole_success(hr, "CoCreateInstance");
|
||||
@@ -2392,7 +2395,8 @@ static void test_handler_marshaling(void)
|
||||
HANDLE thread;
|
||||
static const LARGE_INTEGER ullZero;
|
||||
|
||||
reg_unreg_wine_test_class(TRUE);
|
||||
if (FAILED(reg_unreg_wine_test_class(TRUE)))
|
||||
return;
|
||||
cLocks = 0;
|
||||
|
||||
hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
|
||||
@@ -2645,6 +2649,7 @@ static HANDLE create_target_process(const char *arg)
|
||||
{
|
||||
char **argv;
|
||||
char cmdline[MAX_PATH];
|
||||
BOOL ret;
|
||||
PROCESS_INFORMATION pi;
|
||||
STARTUPINFO si = { 0 };
|
||||
si.cb = sizeof(si);
|
||||
@@ -2653,8 +2658,8 @@ static HANDLE create_target_process(const char *arg)
|
||||
pi.hProcess = NULL;
|
||||
winetest_get_mainargs( &argv );
|
||||
sprintf(cmdline, "%s %s %s", argv[0], argv[1], arg);
|
||||
ok(CreateProcess(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL,
|
||||
&si, &pi) != 0, "CreateProcess failed with error: %u\n", GetLastError());
|
||||
ret = CreateProcess(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
|
||||
ok(ret, "CreateProcess failed with error: %u\n", GetLastError());
|
||||
if (pi.hThread) CloseHandle(pi.hThread);
|
||||
return pi.hProcess;
|
||||
}
|
||||
@@ -2843,6 +2848,68 @@ static void test_globalinterfacetable(void)
|
||||
IGlobalInterfaceTable_Release(git);
|
||||
}
|
||||
|
||||
static void test_manualresetevent(void)
|
||||
{
|
||||
ISynchronize *psync1, *psync2;
|
||||
IUnknown *punk;
|
||||
LONG ref;
|
||||
HRESULT hr;
|
||||
|
||||
hr = CoCreateInstance(&CLSID_ManualResetEvent, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void**)&punk);
|
||||
ok(hr == S_OK, "Got 0x%08x\n", hr);
|
||||
ok(!!punk, "Got NULL.\n");
|
||||
IUnknown_Release(punk);
|
||||
|
||||
hr = CoCreateInstance(&CLSID_ManualResetEvent, NULL, CLSCTX_INPROC_SERVER, &IID_ISynchronize, (void**)&psync1);
|
||||
ok(hr == S_OK, "Got 0x%08x\n", hr);
|
||||
ok(!!psync1, "Got NULL.\n");
|
||||
|
||||
hr = ISynchronize_Wait(psync1, 0, 5);
|
||||
ok(hr == RPC_S_CALLPENDING, "Got 0x%08x\n", hr);
|
||||
|
||||
hr = ISynchronize_Reset(psync1);
|
||||
ok(hr == S_OK, "Got 0x%08x\n", hr);
|
||||
hr = ISynchronize_Signal(psync1);
|
||||
ok(hr == S_OK, "Got 0x%08x\n", hr);
|
||||
hr = ISynchronize_Wait(psync1, 0, 5);
|
||||
ok(hr == S_OK, "Got 0x%08x\n", hr);
|
||||
hr = ISynchronize_Wait(psync1, 0, 5);
|
||||
ok(hr == S_OK, "Got 0x%08x\n", hr);
|
||||
hr = ISynchronize_Reset(psync1);
|
||||
ok(hr == S_OK, "Got 0x%08x\n", hr);
|
||||
hr = ISynchronize_Wait(psync1, 0, 5);
|
||||
ok(hr == RPC_S_CALLPENDING, "Got 0x%08x\n", hr);
|
||||
|
||||
hr = CoCreateInstance(&CLSID_ManualResetEvent, NULL, CLSCTX_INPROC_SERVER, &IID_ISynchronize, (void**)&psync2);
|
||||
ok(hr == S_OK, "Got 0x%08x\n", hr);
|
||||
ok(!!psync2, "Got NULL.\n");
|
||||
ok(psync1 != psync2, "psync1 == psync2.\n");
|
||||
hr = ISynchronize_Wait(psync2, 0, 5);
|
||||
ok(hr == RPC_S_CALLPENDING, "Got 0x%08x\n", hr);
|
||||
|
||||
hr = ISynchronize_Reset(psync1);
|
||||
ok(hr == S_OK, "Got 0x%08x\n", hr);
|
||||
hr = ISynchronize_Reset(psync2);
|
||||
ok(hr == S_OK, "Got 0x%08x\n", hr);
|
||||
hr = ISynchronize_Signal(psync1);
|
||||
ok(hr == S_OK, "Got 0x%08x\n", hr);
|
||||
hr = ISynchronize_Wait(psync2, 0, 5);
|
||||
ok(hr == RPC_S_CALLPENDING, "Got 0x%08x\n", hr);
|
||||
|
||||
ref = ISynchronize_AddRef(psync1);
|
||||
ok(ref == 2, "Got ref: %d\n", ref);
|
||||
ref = ISynchronize_AddRef(psync1);
|
||||
ok(ref == 3, "Got ref: %d\n", ref);
|
||||
ref = ISynchronize_Release(psync1);
|
||||
ok(ref == 2, "Got nonzero ref: %d\n", ref);
|
||||
ref = ISynchronize_Release(psync2);
|
||||
ok(!ref, "Got nonzero ref: %d\n", ref);
|
||||
ref = ISynchronize_Release(psync1);
|
||||
ok(ref == 1, "Got nonzero ref: %d\n", ref);
|
||||
ref = ISynchronize_Release(psync1);
|
||||
ok(!ref, "Got nonzero ref: %d\n", ref);
|
||||
}
|
||||
|
||||
static const char *debugstr_iid(REFIID riid)
|
||||
{
|
||||
static char name[256];
|
||||
@@ -3060,7 +3127,12 @@ START_TEST(marshal)
|
||||
int argc;
|
||||
char **argv;
|
||||
|
||||
if (!(pCoInitializeEx = (void*)GetProcAddress(hOle32, "CoInitializeEx"))) goto no_test;
|
||||
if (!GetProcAddress(hOle32, "CoRegisterSurrogateEx")) {
|
||||
win_skip("skipping test on win9x\n");
|
||||
return;
|
||||
}
|
||||
|
||||
pCoInitializeEx = (void*)GetProcAddress(hOle32, "CoInitializeEx");
|
||||
|
||||
argc = winetest_get_mainargs( &argv );
|
||||
if (argc > 2 && (!strcmp(argv[2], "-Embedding")))
|
||||
@@ -3122,14 +3194,10 @@ START_TEST(marshal)
|
||||
test_local_server();
|
||||
|
||||
test_globalinterfacetable();
|
||||
test_manualresetevent();
|
||||
|
||||
/* must be last test as channel hooks can't be unregistered */
|
||||
test_channel_hook();
|
||||
|
||||
CoUninitialize();
|
||||
return;
|
||||
|
||||
no_test:
|
||||
trace("You need DCOM95 installed to run this test\n");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "objbase.h"
|
||||
#include "ocidl.h"
|
||||
#include "initguid.h"
|
||||
#include "comcat.h"
|
||||
#include "olectl.h"
|
||||
@@ -156,10 +157,15 @@ static IClassFactory Test_ClassFactory = { &TestClassFactory_Vtbl };
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const IUnknownVtbl *lpVtbl;
|
||||
IUnknown IUnknown_iface;
|
||||
ULONG refs;
|
||||
} HeapUnknown;
|
||||
|
||||
static inline HeapUnknown *impl_from_IUnknown(IUnknown *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, HeapUnknown, IUnknown_iface);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI HeapUnknown_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
|
||||
{
|
||||
if (IsEqualIID(riid, &IID_IUnknown))
|
||||
@@ -174,13 +180,13 @@ static HRESULT WINAPI HeapUnknown_QueryInterface(IUnknown *iface, REFIID riid, v
|
||||
|
||||
static ULONG WINAPI HeapUnknown_AddRef(IUnknown *iface)
|
||||
{
|
||||
HeapUnknown *This = (HeapUnknown *)iface;
|
||||
HeapUnknown *This = impl_from_IUnknown(iface);
|
||||
return InterlockedIncrement((LONG*)&This->refs);
|
||||
}
|
||||
|
||||
static ULONG WINAPI HeapUnknown_Release(IUnknown *iface)
|
||||
{
|
||||
HeapUnknown *This = (HeapUnknown *)iface;
|
||||
HeapUnknown *This = impl_from_IUnknown(iface);
|
||||
ULONG refs = InterlockedDecrement((LONG*)&This->refs);
|
||||
if (!refs) HeapFree(GetProcessHeap(), 0, This);
|
||||
return refs;
|
||||
@@ -1007,7 +1013,6 @@ static void test_MkParseDisplayName(void)
|
||||
hr = IEnumMoniker_QueryInterface(spEM1, &IID_IUnknown, (void*) &lpEM1);
|
||||
/* Register a couple of Monikers and check is ok */
|
||||
ok(hr==0, "IEnumMoniker_QueryInterface hr %08x %p\n", hr, lpEM1);
|
||||
hr = MK_E_NOOBJECT;
|
||||
|
||||
matchCnt = count_moniker_matches(pbc, spEM1);
|
||||
trace("Number of matches is %i\n", matchCnt);
|
||||
@@ -1271,6 +1276,7 @@ static void test_moniker(
|
||||
IROTData_Release(rotdata);
|
||||
|
||||
hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
|
||||
ok_ole_success(hr, CreateStreamOnHGlobal);
|
||||
|
||||
/* Saving */
|
||||
|
||||
@@ -1451,6 +1457,7 @@ static void test_file_moniker(WCHAR* path)
|
||||
ok_ole_success(hr, CreateFileMoniker);
|
||||
|
||||
hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
|
||||
ok_ole_success(hr, CreateStreamOnHGlobal);
|
||||
|
||||
/* Marshal */
|
||||
hr = CoMarshalInterface(stream, &IID_IMoniker, (IUnknown *)moniker1, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
|
||||
@@ -1774,9 +1781,9 @@ static void test_pointer_moniker(void)
|
||||
/* Hashing */
|
||||
hr = IMoniker_Hash(moniker, &hash);
|
||||
ok_ole_success(hr, IMoniker_Hash);
|
||||
ok(hash == (DWORD)&Test_ClassFactory,
|
||||
ok(hash == PtrToUlong(&Test_ClassFactory),
|
||||
"Hash value should have been 0x%08x, instead of 0x%08x\n",
|
||||
(DWORD)&Test_ClassFactory, hash);
|
||||
PtrToUlong(&Test_ClassFactory), hash);
|
||||
|
||||
/* IsSystemMoniker test */
|
||||
hr = IMoniker_IsSystemMoniker(moniker, &moniker_type);
|
||||
@@ -1880,9 +1887,9 @@ static void test_bind_context(void)
|
||||
ok(hr == E_INVALIDARG, "IBindCtx_RegisterObjectParam should have returned E_INVALIDARG instead of 0x%08x\n", hr);
|
||||
|
||||
unknown = HeapAlloc(GetProcessHeap(), 0, sizeof(*unknown));
|
||||
unknown->lpVtbl = &HeapUnknown_Vtbl;
|
||||
unknown->IUnknown_iface.lpVtbl = &HeapUnknown_Vtbl;
|
||||
unknown->refs = 1;
|
||||
hr = IBindCtx_RegisterObjectParam(pBindCtx, (WCHAR *)wszParamName, (IUnknown *)&unknown->lpVtbl);
|
||||
hr = IBindCtx_RegisterObjectParam(pBindCtx, (WCHAR *)wszParamName, &unknown->IUnknown_iface);
|
||||
ok_ole_success(hr, "IBindCtx_RegisterObjectParam");
|
||||
|
||||
hr = IBindCtx_GetObjectParam(pBindCtx, (WCHAR *)wszParamName, ¶m_obj);
|
||||
@@ -1907,23 +1914,23 @@ static void test_bind_context(void)
|
||||
ok(hr == E_INVALIDARG, "IBindCtx_RevokeObjectBound(NULL) should have return E_INVALIDARG instead of 0x%08x\n", hr);
|
||||
|
||||
unknown2 = HeapAlloc(GetProcessHeap(), 0, sizeof(*unknown));
|
||||
unknown2->lpVtbl = &HeapUnknown_Vtbl;
|
||||
unknown2->IUnknown_iface.lpVtbl = &HeapUnknown_Vtbl;
|
||||
unknown2->refs = 1;
|
||||
hr = IBindCtx_RegisterObjectBound(pBindCtx, (IUnknown *)&unknown2->lpVtbl);
|
||||
hr = IBindCtx_RegisterObjectBound(pBindCtx, &unknown2->IUnknown_iface);
|
||||
ok_ole_success(hr, "IBindCtx_RegisterObjectBound");
|
||||
|
||||
hr = IBindCtx_RevokeObjectBound(pBindCtx, (IUnknown *)&unknown2->lpVtbl);
|
||||
hr = IBindCtx_RevokeObjectBound(pBindCtx, &unknown2->IUnknown_iface);
|
||||
ok_ole_success(hr, "IBindCtx_RevokeObjectBound");
|
||||
|
||||
hr = IBindCtx_RevokeObjectBound(pBindCtx, (IUnknown *)&unknown2->lpVtbl);
|
||||
hr = IBindCtx_RevokeObjectBound(pBindCtx, &unknown2->IUnknown_iface);
|
||||
ok(hr == MK_E_NOTBOUND, "IBindCtx_RevokeObjectBound with not bound object should have returned MK_E_NOTBOUND instead of 0x%08x\n", hr);
|
||||
|
||||
IBindCtx_Release(pBindCtx);
|
||||
|
||||
refs = IUnknown_Release((IUnknown *)&unknown->lpVtbl);
|
||||
refs = IUnknown_Release(&unknown->IUnknown_iface);
|
||||
ok(!refs, "object param should have been destroyed, instead of having %d refs\n", refs);
|
||||
|
||||
refs = IUnknown_Release((IUnknown *)&unknown2->lpVtbl);
|
||||
refs = IUnknown_Release(&unknown2->IUnknown_iface);
|
||||
ok(!refs, "bound object should have been destroyed, instead of having %d refs\n", refs);
|
||||
}
|
||||
|
||||
@@ -1998,6 +2005,11 @@ static void test_save_load_filemoniker(void)
|
||||
|
||||
START_TEST(moniker)
|
||||
{
|
||||
if (!GetProcAddress(GetModuleHandleA("ole32.dll"), "CoRegisterSurrogateEx")) {
|
||||
win_skip("skipping test on win9x\n");
|
||||
return;
|
||||
}
|
||||
|
||||
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
|
||||
|
||||
test_ROT();
|
||||
|
||||
+283
-21
@@ -20,9 +20,10 @@
|
||||
|
||||
#define COBJMACROS
|
||||
#define CONST_VTABLE
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
|
||||
#include <stdarg.h>
|
||||
#define NOCRYPT
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "objbase.h"
|
||||
@@ -44,7 +45,16 @@ static const CLSID CLSID_WineTest =
|
||||
{0xbc, 0x13, 0x51, 0x6e, 0x92, 0x39, 0xac, 0xe0}
|
||||
};
|
||||
|
||||
static const IID IID_WineTest =
|
||||
{ /* 9474ba1a-258b-490b-bc13-516e9239ace1 */
|
||||
0x9474ba1a,
|
||||
0x258b,
|
||||
0x490b,
|
||||
{0xbc, 0x13, 0x51, 0x6e, 0x92, 0x39, 0xac, 0xe1}
|
||||
};
|
||||
|
||||
#define TEST_OPTIONAL 0x1
|
||||
#define TEST_TODO 0x2
|
||||
|
||||
struct expected_method
|
||||
{
|
||||
@@ -53,21 +63,38 @@ struct expected_method
|
||||
};
|
||||
|
||||
static const struct expected_method *expected_method_list;
|
||||
static FORMATETC *g_expected_fetc = NULL;
|
||||
|
||||
BOOL g_showRunnable = TRUE;
|
||||
BOOL g_isRunning = TRUE;
|
||||
static BOOL g_showRunnable = TRUE;
|
||||
static BOOL g_isRunning = TRUE;
|
||||
static BOOL g_failGetMiscStatus;
|
||||
static HRESULT g_QIFailsWith;
|
||||
|
||||
static UINT cf_test_1, cf_test_2, cf_test_3;
|
||||
|
||||
#define CHECK_EXPECTED_METHOD(method_name) \
|
||||
do { \
|
||||
trace("%s\n", method_name); \
|
||||
ok(expected_method_list->method != NULL, "Extra method %s called\n", method_name); \
|
||||
if (!strcmp(expected_method_list->method, "WINE_EXTRA")) \
|
||||
{ \
|
||||
todo_wine ok(0, "Too many method calls.\n"); \
|
||||
break; \
|
||||
} \
|
||||
if (expected_method_list->method) \
|
||||
{ \
|
||||
while (expected_method_list->flags & TEST_OPTIONAL && \
|
||||
strcmp(expected_method_list->method, method_name) != 0) \
|
||||
expected_method_list++; \
|
||||
ok(!strcmp(expected_method_list->method, method_name), "Expected %s to be called instead of %s\n", \
|
||||
expected_method_list->method, method_name); \
|
||||
if (expected_method_list->flags & TEST_TODO) \
|
||||
todo_wine \
|
||||
ok(!strcmp(expected_method_list->method, method_name), \
|
||||
"Expected %s to be called instead of %s\n", \
|
||||
expected_method_list->method, method_name); \
|
||||
else \
|
||||
ok(!strcmp(expected_method_list->method, method_name), \
|
||||
"Expected %s to be called instead of %s\n", \
|
||||
expected_method_list->method, method_name); \
|
||||
expected_method_list++; \
|
||||
} \
|
||||
} while(0)
|
||||
@@ -93,6 +120,8 @@ static HRESULT WINAPI OleObject_QueryInterface(IOleObject *iface, REFIID riid, v
|
||||
*ppv = cache;
|
||||
else if (IsEqualIID(riid, &IID_IRunnableObject) && g_showRunnable)
|
||||
*ppv = runnable;
|
||||
else if (IsEqualIID(riid, &IID_WineTest))
|
||||
return g_QIFailsWith;
|
||||
|
||||
if(*ppv) {
|
||||
IUnknown_AddRef((IUnknown*)*ppv);
|
||||
@@ -327,8 +356,16 @@ static HRESULT WINAPI OleObject_GetMiscStatus
|
||||
)
|
||||
{
|
||||
CHECK_EXPECTED_METHOD("OleObject_GetMiscStatus");
|
||||
*pdwStatus = DVASPECT_CONTENT;
|
||||
return S_OK;
|
||||
if(!g_failGetMiscStatus)
|
||||
{
|
||||
*pdwStatus = OLEMISC_RECOMPOSEONRESIZE;
|
||||
return S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pdwStatus = 0x1234;
|
||||
return E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT WINAPI OleObject_SetColorScheme
|
||||
@@ -496,6 +533,22 @@ static HRESULT WINAPI OleObjectCache_Cache
|
||||
)
|
||||
{
|
||||
CHECK_EXPECTED_METHOD("OleObjectCache_Cache");
|
||||
if (g_expected_fetc) {
|
||||
ok(pformatetc != NULL, "pformatetc should not be NULL\n");
|
||||
if (pformatetc) {
|
||||
ok(pformatetc->cfFormat == g_expected_fetc->cfFormat,
|
||||
"cfFormat: %x\n", pformatetc->cfFormat);
|
||||
ok((pformatetc->ptd != NULL) == (g_expected_fetc->ptd != NULL),
|
||||
"ptd: %p\n", pformatetc->ptd);
|
||||
ok(pformatetc->dwAspect == g_expected_fetc->dwAspect,
|
||||
"dwAspect: %x\n", pformatetc->dwAspect);
|
||||
ok(pformatetc->lindex == g_expected_fetc->lindex,
|
||||
"lindex: %x\n", pformatetc->lindex);
|
||||
ok(pformatetc->tymed == g_expected_fetc->tymed,
|
||||
"tymed: %x\n", pformatetc->tymed);
|
||||
}
|
||||
} else
|
||||
ok(pformatetc == NULL, "pformatetc should be NULL\n");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -796,6 +849,12 @@ static void test_OleCreate(IStorage *pStorage)
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
g_expected_fetc = &formatetc;
|
||||
formatetc.cfFormat = 0;
|
||||
formatetc.ptd = NULL;
|
||||
formatetc.dwAspect = DVASPECT_CONTENT;
|
||||
formatetc.lindex = -1;
|
||||
formatetc.tymed = TYMED_NULL;
|
||||
runnable = &OleObjectRunnable;
|
||||
cache = &OleObjectCache;
|
||||
expected_method_list = methods_olerender_none;
|
||||
@@ -836,6 +895,8 @@ static void test_OleCreate(IStorage *pStorage)
|
||||
IOleObject_Release(pObject);
|
||||
CHECK_NO_EXTRA_METHODS();
|
||||
|
||||
formatetc.cfFormat = 0;
|
||||
formatetc.tymed = TYMED_NULL;
|
||||
runnable = NULL;
|
||||
expected_method_list = methods_olerender_draw_no_runnable;
|
||||
trace("OleCreate with OLERENDER_DRAW (no IRunnableObject):\n");
|
||||
@@ -853,6 +914,7 @@ static void test_OleCreate(IStorage *pStorage)
|
||||
IOleObject_Release(pObject);
|
||||
CHECK_NO_EXTRA_METHODS();
|
||||
trace("end\n");
|
||||
g_expected_fetc = NULL;
|
||||
}
|
||||
|
||||
static void test_OleLoad(IStorage *pStorage)
|
||||
@@ -874,10 +936,32 @@ static void test_OleLoad(IStorage *pStorage)
|
||||
{ "OleObject_SetClientSite", 0 },
|
||||
{ "OleObject_Release", 0 },
|
||||
{ "OleObject_QueryInterface", 0 },
|
||||
{ "OleObject_GetMiscStatus", 0 },
|
||||
{ "OleObject_Release", 0 },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
/* Test once with IOleObject_GetMiscStatus failing */
|
||||
expected_method_list = methods_oleload;
|
||||
g_failGetMiscStatus = TRUE;
|
||||
trace("OleLoad:\n");
|
||||
hr = OleLoad(pStorage, &IID_IOleObject, (IOleClientSite *)0xdeadbeef, (void **)&pObject);
|
||||
ok(hr == S_OK ||
|
||||
broken(hr == E_INVALIDARG), /* win98 and win2k */
|
||||
"OleLoad failed with error 0x%08x\n", hr);
|
||||
if(pObject)
|
||||
{
|
||||
DWORD dwStatus = 0xdeadbeef;
|
||||
hr = IOleObject_GetMiscStatus(pObject, DVASPECT_CONTENT, &dwStatus);
|
||||
ok(hr == E_FAIL, "Got 0x%08x\n", hr);
|
||||
ok(dwStatus == 0x1234, "Got 0x%08x\n", dwStatus);
|
||||
|
||||
IOleObject_Release(pObject);
|
||||
CHECK_NO_EXTRA_METHODS();
|
||||
}
|
||||
|
||||
/* Test again, let IOleObject_GetMiscStatus succeed. */
|
||||
g_failGetMiscStatus = FALSE;
|
||||
expected_method_list = methods_oleload;
|
||||
trace("OleLoad:\n");
|
||||
hr = OleLoad(pStorage, &IID_IOleObject, (IOleClientSite *)0xdeadbeef, (void **)&pObject);
|
||||
@@ -886,6 +970,11 @@ static void test_OleLoad(IStorage *pStorage)
|
||||
"OleLoad failed with error 0x%08x\n", hr);
|
||||
if (pObject)
|
||||
{
|
||||
DWORD dwStatus = 0xdeadbeef;
|
||||
hr = IOleObject_GetMiscStatus(pObject, DVASPECT_CONTENT, &dwStatus);
|
||||
ok(hr == S_OK, "Got 0x%08x\n", hr);
|
||||
ok(dwStatus == 1, "Got 0x%08x\n", dwStatus);
|
||||
|
||||
IOleObject_Release(pObject);
|
||||
CHECK_NO_EXTRA_METHODS();
|
||||
}
|
||||
@@ -897,6 +986,12 @@ static BOOL STDMETHODCALLTYPE draw_continue(ULONG_PTR param)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL STDMETHODCALLTYPE draw_continue_false(ULONG_PTR param)
|
||||
{
|
||||
CHECK_EXPECTED_METHOD("draw_continue_false");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI AdviseSink_QueryInterface(IAdviseSink *iface, REFIID riid, void **ppv)
|
||||
{
|
||||
if (IsEqualIID(riid, &IID_IAdviseSink) || IsEqualIID(riid, &IID_IUnknown))
|
||||
@@ -972,6 +1067,8 @@ static HRESULT WINAPI DataObject_QueryInterface(
|
||||
REFIID riid,
|
||||
void** ppvObject)
|
||||
{
|
||||
CHECK_EXPECTED_METHOD("DataObject_QueryInterface");
|
||||
|
||||
if (IsEqualIID(riid, &IID_IDataObject) || IsEqualIID(riid, &IID_IUnknown))
|
||||
{
|
||||
*ppvObject = iface;
|
||||
@@ -984,12 +1081,14 @@ static HRESULT WINAPI DataObject_QueryInterface(
|
||||
static ULONG WINAPI DataObject_AddRef(
|
||||
IDataObject* iface)
|
||||
{
|
||||
CHECK_EXPECTED_METHOD("DataObject_AddRef");
|
||||
return 2;
|
||||
}
|
||||
|
||||
static ULONG WINAPI DataObject_Release(
|
||||
IDataObject* iface)
|
||||
{
|
||||
CHECK_EXPECTED_METHOD("DataObject_Release");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1054,8 +1153,20 @@ static HRESULT WINAPI DataObject_DAdvise(
|
||||
IAdviseSink* pAdvSink,
|
||||
DWORD* pdwConnection)
|
||||
{
|
||||
STGMEDIUM stgmedium;
|
||||
|
||||
CHECK_EXPECTED_METHOD("DataObject_DAdvise");
|
||||
*pdwConnection = 1;
|
||||
|
||||
if(advf & ADVF_PRIMEFIRST)
|
||||
{
|
||||
ok(pformatetc->cfFormat == cf_test_2, "got %04x\n", pformatetc->cfFormat);
|
||||
stgmedium.tymed = TYMED_HGLOBAL;
|
||||
U(stgmedium).hGlobal = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, 4);
|
||||
stgmedium.pUnkForRelease = NULL;
|
||||
IAdviseSink_OnDataChange(pAdvSink, pformatetc, &stgmedium);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -1101,6 +1212,7 @@ static void test_data_cache(void)
|
||||
IPersistStorage *pPS;
|
||||
IViewObject *pViewObject;
|
||||
IOleCacheControl *pOleCacheControl;
|
||||
IDataObject *pCacheDataObject;
|
||||
FORMATETC fmtetc;
|
||||
STGMEDIUM stgmedium;
|
||||
DWORD dwConnection;
|
||||
@@ -1116,7 +1228,8 @@ static void test_data_cache(void)
|
||||
{
|
||||
{ "AdviseSink_OnViewChange", 0 },
|
||||
{ "AdviseSink_OnViewChange", 0 },
|
||||
{ "draw_continue", 0 },
|
||||
{ "draw_continue", 1 },
|
||||
{ "draw_continue_false", 1 },
|
||||
{ "DataObject_DAdvise", 0 },
|
||||
{ "DataObject_DAdvise", 0 },
|
||||
{ "DataObject_DUnadvise", 0 },
|
||||
@@ -1126,14 +1239,27 @@ static void test_data_cache(void)
|
||||
static const struct expected_method methods_cacheload[] =
|
||||
{
|
||||
{ "AdviseSink_OnViewChange", 0 },
|
||||
{ "draw_continue", 0 },
|
||||
{ "draw_continue", 0 },
|
||||
{ "draw_continue", 0 },
|
||||
{ "draw_continue", 1 },
|
||||
{ "draw_continue", 1 },
|
||||
{ "draw_continue", 1 },
|
||||
{ "DataObject_GetData", 0 },
|
||||
{ "DataObject_GetData", 0 },
|
||||
{ "DataObject_GetData", 0 },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
static const struct expected_method methods_cachethenrun[] =
|
||||
{
|
||||
{ "DataObject_DAdvise", 0 },
|
||||
{ "DataObject_DAdvise", 0 },
|
||||
{ "DataObject_DAdvise", 0 },
|
||||
{ "DataObject_QueryGetData", 1 }, /* called by win9x and nt4 */
|
||||
{ "DataObject_DAdvise", 0 },
|
||||
{ "DataObject_DUnadvise", 0 },
|
||||
{ "DataObject_DUnadvise", 0 },
|
||||
{ "DataObject_DUnadvise", 0 },
|
||||
{ "DataObject_DUnadvise", 0 },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
GetSystemDirectory(szSystemDir, sizeof(szSystemDir)/sizeof(szSystemDir[0]));
|
||||
|
||||
@@ -1248,6 +1374,7 @@ static void test_data_cache(void)
|
||||
fmtetc.dwAspect = DVASPECT_ICON;
|
||||
hr = IOleCache_SetData(pOleCache, &fmtetc, &stgmedium, FALSE);
|
||||
ok_ole_success(hr, "IOleCache_SetData");
|
||||
ReleaseStgMedium(&stgmedium);
|
||||
|
||||
hr = IViewObject_Freeze(pViewObject, DVASPECT_ICON, -1, NULL, &dwFreeze);
|
||||
todo_wine {
|
||||
@@ -1268,12 +1395,20 @@ static void test_data_cache(void)
|
||||
hr = IViewObject_Draw(pViewObject, DVASPECT_CONTENT, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
|
||||
ok(hr == OLE_E_BLANK, "IViewObject_Draw with uncached aspect should have returned OLE_E_BLANK instead of 0x%08x\n", hr);
|
||||
|
||||
/* a NULL draw_continue fn ptr */
|
||||
hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, NULL, 0xdeadbeef);
|
||||
ok_ole_success(hr, "IViewObject_Draw");
|
||||
|
||||
/* draw_continue that returns FALSE to abort drawing */
|
||||
hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue_false, 0xdeadbeef);
|
||||
ok(hr == E_ABORT ||
|
||||
broken(hr == S_OK), /* win9x may skip the callbacks */
|
||||
"IViewObject_Draw with draw_continue_false returns 0x%08x\n", hr);
|
||||
|
||||
DeleteDC(hdcMem);
|
||||
|
||||
hr = IOleCacheControl_OnRun(pOleCacheControl, &DataObject);
|
||||
todo_wine {
|
||||
ok_ole_success(hr, "IOleCacheControl_OnRun");
|
||||
}
|
||||
|
||||
hr = IPersistStorage_Save(pPS, pStorage, TRUE);
|
||||
ok_ole_success(hr, "IPersistStorage_Save");
|
||||
@@ -1289,9 +1424,7 @@ static void test_data_cache(void)
|
||||
IOleCache_Release(pOleCache);
|
||||
IOleCacheControl_Release(pOleCacheControl);
|
||||
|
||||
todo_wine {
|
||||
CHECK_NO_EXTRA_METHODS();
|
||||
}
|
||||
|
||||
/* Test with loaded data */
|
||||
trace("Testing loaded data with CreateDataCache:\n");
|
||||
@@ -1365,8 +1498,70 @@ static void test_data_cache(void)
|
||||
CHECK_NO_EXTRA_METHODS();
|
||||
}
|
||||
|
||||
IStorage_Release(pStorage);
|
||||
hr = CreateDataCache(NULL, &CLSID_NULL, &IID_IOleCache2, (LPVOID *)&pOleCache);
|
||||
ok_ole_success(hr, "CreateDataCache");
|
||||
|
||||
expected_method_list = methods_cachethenrun;
|
||||
|
||||
hr = IOleCache_QueryInterface(pOleCache, &IID_IDataObject, (LPVOID *)&pCacheDataObject);
|
||||
ok_ole_success(hr, "IOleCache_QueryInterface(IID_IDataObject)");
|
||||
hr = IOleCache_QueryInterface(pOleCache, &IID_IOleCacheControl, (LPVOID *)&pOleCacheControl);
|
||||
ok_ole_success(hr, "IOleCache_QueryInterface(IID_IOleCacheControl)");
|
||||
|
||||
fmtetc.cfFormat = CF_METAFILEPICT;
|
||||
fmtetc.dwAspect = DVASPECT_CONTENT;
|
||||
fmtetc.tymed = TYMED_MFPICT;
|
||||
|
||||
hr = IOleCache_Cache(pOleCache, &fmtetc, 0, &dwConnection);
|
||||
ok_ole_success(hr, "IOleCache_Cache");
|
||||
|
||||
hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium);
|
||||
ok(hr == OLE_E_BLANK, "got %08x\n", hr);
|
||||
|
||||
fmtetc.cfFormat = cf_test_1;
|
||||
fmtetc.dwAspect = DVASPECT_CONTENT;
|
||||
fmtetc.tymed = TYMED_HGLOBAL;
|
||||
|
||||
hr = IOleCache_Cache(pOleCache, &fmtetc, 0, &dwConnection);
|
||||
ok(hr == CACHE_S_FORMATETC_NOTSUPPORTED, "got %08x\n", hr);
|
||||
|
||||
hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium);
|
||||
ok(hr == OLE_E_BLANK, "got %08x\n", hr);
|
||||
|
||||
fmtetc.cfFormat = cf_test_2;
|
||||
hr = IOleCache_Cache(pOleCache, &fmtetc, ADVF_PRIMEFIRST, &dwConnection);
|
||||
ok(hr == CACHE_S_FORMATETC_NOTSUPPORTED, "got %08x\n", hr);
|
||||
|
||||
hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium);
|
||||
ok(hr == OLE_E_BLANK, "got %08x\n", hr);
|
||||
|
||||
hr = IOleCacheControl_OnRun(pOleCacheControl, &DataObject);
|
||||
ok_ole_success(hr, "IOleCacheControl_OnRun");
|
||||
|
||||
fmtetc.cfFormat = cf_test_3;
|
||||
hr = IOleCache_Cache(pOleCache, &fmtetc, 0, &dwConnection);
|
||||
ok(hr == CACHE_S_FORMATETC_NOTSUPPORTED, "got %08x\n", hr);
|
||||
|
||||
fmtetc.cfFormat = cf_test_1;
|
||||
hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium);
|
||||
ok(hr == OLE_E_BLANK, "got %08x\n", hr);
|
||||
|
||||
fmtetc.cfFormat = cf_test_2;
|
||||
hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium);
|
||||
ok(hr == S_OK, "got %08x\n", hr);
|
||||
ReleaseStgMedium(&stgmedium);
|
||||
|
||||
fmtetc.cfFormat = cf_test_3;
|
||||
hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium);
|
||||
ok(hr == OLE_E_BLANK, "got %08x\n", hr);
|
||||
|
||||
IOleCacheControl_Release(pOleCacheControl);
|
||||
IDataObject_Release(pCacheDataObject);
|
||||
IOleCache_Release(pOleCache);
|
||||
|
||||
CHECK_NO_EXTRA_METHODS();
|
||||
|
||||
IStorage_Release(pStorage);
|
||||
}
|
||||
|
||||
static void test_default_handler(void)
|
||||
@@ -1386,10 +1581,25 @@ static void test_default_handler(void)
|
||||
FORMATETC fmtetc;
|
||||
IOleInPlaceObject *pInPlaceObj;
|
||||
IEnumOLEVERB *pEnumVerbs;
|
||||
DWORD dwRegister;
|
||||
static const WCHAR wszUnknown[] = {'U','n','k','n','o','w','n',0};
|
||||
static const WCHAR wszHostName[] = {'W','i','n','e',' ','T','e','s','t',' ','P','r','o','g','r','a','m',0};
|
||||
static const WCHAR wszDelim[] = {'!',0};
|
||||
|
||||
static const struct expected_method methods_embeddinghelper[] =
|
||||
{
|
||||
{ "OleObject_QueryInterface", 0 },
|
||||
{ "OleObject_AddRef", 0 },
|
||||
{ "OleObject_QueryInterface", 0 },
|
||||
{ "OleObject_QueryInterface", TEST_TODO },
|
||||
{ "OleObject_QueryInterface", 0 },
|
||||
{ "OleObject_QueryInterface", 0 },
|
||||
{ "OleObject_QueryInterface", TEST_OPTIONAL }, /* Win95/98/NT4 */
|
||||
{ "OleObject_Release", TEST_TODO },
|
||||
{ "WINE_EXTRA", TEST_OPTIONAL },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
hr = CoCreateInstance(&CLSID_WineTest, NULL, CLSCTX_INPROC_HANDLER, &IID_IOleObject, (void **)&pObject);
|
||||
ok(hr == REGDB_E_CLASSNOTREG, "CoCreateInstance should have failed with REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
|
||||
|
||||
@@ -1449,6 +1659,7 @@ static void test_default_handler(void)
|
||||
|
||||
sizel.cx = sizel.cy = 0;
|
||||
hr = IOleObject_SetExtent(pObject, DVASPECT_CONTENT, &sizel);
|
||||
ok(hr == OLE_E_NOTRUNNING, "IOleObject_SetExtent should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr);
|
||||
|
||||
hr = IOleObject_SetHostNames(pObject, wszHostName, NULL);
|
||||
ok_ole_success(hr, "IOleObject_SetHostNames");
|
||||
@@ -1517,6 +1728,45 @@ static void test_default_handler(void)
|
||||
|
||||
IRunnableObject_Release(pRunnableObject);
|
||||
IOleObject_Release(pObject);
|
||||
|
||||
/* Test failure propagation from delegate ::QueryInterface */
|
||||
hr = CoRegisterClassObject(&CLSID_WineTest, (IUnknown*)&OleObjectCF,
|
||||
CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &dwRegister);
|
||||
ok_ole_success(hr, "CoRegisterClassObject");
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
expected_method_list = methods_embeddinghelper;
|
||||
hr = OleCreateEmbeddingHelper(&CLSID_WineTest, NULL, EMBDHLP_INPROC_SERVER,
|
||||
&OleObjectCF, &IID_IOleObject, (void**)&pObject);
|
||||
ok_ole_success(hr, "OleCreateEmbeddingHelper");
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
IUnknown *punk;
|
||||
|
||||
g_QIFailsWith = E_FAIL;
|
||||
hr = IOleObject_QueryInterface(pObject, &IID_WineTest, (void**)&punk);
|
||||
ok(hr == E_FAIL, "Got 0x%08x\n", hr);
|
||||
|
||||
g_QIFailsWith = E_NOINTERFACE;
|
||||
hr = IOleObject_QueryInterface(pObject, &IID_WineTest, (void**)&punk);
|
||||
ok(hr == E_NOINTERFACE, "Got 0x%08x\n", hr);
|
||||
|
||||
g_QIFailsWith = CO_E_OBJNOTCONNECTED;
|
||||
hr = IOleObject_QueryInterface(pObject, &IID_WineTest, (void**)&punk);
|
||||
ok(hr == CO_E_OBJNOTCONNECTED, "Got 0x%08x\n", hr);
|
||||
|
||||
g_QIFailsWith = 0x87654321;
|
||||
hr = IOleObject_QueryInterface(pObject, &IID_WineTest, (void**)&punk);
|
||||
ok(hr == 0x87654321, "Got 0x%08x\n", hr);
|
||||
|
||||
IOleObject_Release(pObject);
|
||||
}
|
||||
|
||||
CHECK_NO_EXTRA_METHODS();
|
||||
|
||||
hr = CoRevokeClassObject(dwRegister);
|
||||
ok_ole_success(hr, "CoRevokeClassObject");
|
||||
}
|
||||
}
|
||||
|
||||
static void test_runnable(void)
|
||||
@@ -1536,20 +1786,28 @@ static void test_runnable(void)
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
BOOL ret;
|
||||
IOleObject *object = &OleObject;
|
||||
|
||||
/* null argument */
|
||||
ret = OleIsRunning(NULL);
|
||||
ok(ret == FALSE, "got %d\n", ret);
|
||||
|
||||
expected_method_list = methods_query_runnable;
|
||||
ok(OleIsRunning(object), "Object should be running\n");
|
||||
ret = OleIsRunning(object);
|
||||
ok(ret == TRUE, "Object should be running\n");
|
||||
CHECK_NO_EXTRA_METHODS();
|
||||
|
||||
g_isRunning = FALSE;
|
||||
expected_method_list = methods_query_runnable;
|
||||
ok(OleIsRunning(object) == FALSE, "Object should not be running\n");
|
||||
ret = OleIsRunning(object);
|
||||
ok(ret == FALSE, "Object should not be running\n");
|
||||
CHECK_NO_EXTRA_METHODS();
|
||||
|
||||
g_showRunnable = FALSE; /* QueryInterface(IID_IRunnableObject, ...) will fail */
|
||||
expected_method_list = methods_no_runnable;
|
||||
ok(OleIsRunning(object), "Object without IRunnableObject should be running\n");
|
||||
ret = OleIsRunning(object);
|
||||
ok(ret == TRUE, "Object without IRunnableObject should be running\n");
|
||||
CHECK_NO_EXTRA_METHODS();
|
||||
|
||||
g_isRunning = TRUE;
|
||||
@@ -1585,13 +1843,13 @@ static const IUnknownVtbl UnknownVtbl =
|
||||
Unknown_Release
|
||||
};
|
||||
|
||||
static IUnknown Unknown = { &UnknownVtbl };
|
||||
static IUnknown unknown = { &UnknownVtbl };
|
||||
|
||||
static void test_OleLockRunning(void)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
hr = OleLockRunning((LPUNKNOWN)&Unknown, TRUE, FALSE);
|
||||
hr = OleLockRunning((LPUNKNOWN)&unknown, TRUE, FALSE);
|
||||
ok(hr == S_OK, "OleLockRunning failed 0x%08x\n", hr);
|
||||
}
|
||||
|
||||
@@ -1602,6 +1860,10 @@ START_TEST(ole2)
|
||||
STATSTG statstg;
|
||||
HRESULT hr;
|
||||
|
||||
cf_test_1 = RegisterClipboardFormatA("cf_winetest_1");
|
||||
cf_test_2 = RegisterClipboardFormatA("cf_winetest_2");
|
||||
cf_test_3 = RegisterClipboardFormatA("cf_winetest_3");
|
||||
|
||||
CoInitialize(NULL);
|
||||
|
||||
hr = CoRegisterClassObject(&CLSID_Equation3, (IUnknown *)&OleObjectCF, CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &dwRegister);
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#define PROP_V1A 2
|
||||
#define PROP_TODO 0x80
|
||||
|
||||
struct valid_mapping
|
||||
static const struct valid_mapping
|
||||
{
|
||||
BYTE simple;
|
||||
BYTE with_array;
|
||||
|
||||
@@ -186,7 +186,7 @@ static void testProps(void)
|
||||
spec.ulKind = PRSPEC_PROPID;
|
||||
U(spec).propid = PIDSI_THUMBNAIL;
|
||||
hr = IPropertyStorage_ReadMultiple(propertyStorage, 1, &spec, &var);
|
||||
ok(SUCCEEDED(hr), "ReadMultiple failed: 0x%08x\n", hr);
|
||||
ok(hr == S_OK, "ReadMultiple failed: 0x%08x\n", hr);
|
||||
ok(var.vt == VT_CF, "variant type wrong\n");
|
||||
ok(U(var).pclipdata->ulClipFmt == CF_ENHMETAFILE,
|
||||
"clipboard type wrong\n");
|
||||
@@ -315,13 +315,18 @@ static void testProps(void)
|
||||
|
||||
spec.ulKind = PRSPEC_PROPID;
|
||||
U(spec).propid = PID_FIRST_USABLE;
|
||||
var.vt = VT_I4;
|
||||
U(var).lVal = 1;
|
||||
hr = IPropertyStorage_WriteMultiple(propertyStorage, 1, &spec, &var, 0);
|
||||
ok(hr == S_OK, "WriteMultiple failed: 0x%08x\n", hr);
|
||||
|
||||
hr = IPropertyStorage_Commit(propertyStorage, STGC_DEFAULT);
|
||||
ok(hr == S_OK, "Commit failed: 0x%08x\n", hr);
|
||||
|
||||
IPropertyStorage_Release(propertyStorage);
|
||||
IPropertySetStorage_Release(propSetStorage);
|
||||
IStorage_Release(storage);
|
||||
propertyStorage = NULL;
|
||||
|
||||
/* now open it again */
|
||||
hr = StgOpenStorage(filename, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE,
|
||||
@@ -338,7 +343,11 @@ static void testProps(void)
|
||||
spec.ulKind = PRSPEC_PROPID;
|
||||
U(spec).propid = PID_FIRST_USABLE;
|
||||
hr = IPropertyStorage_ReadMultiple(propertyStorage, 1, &spec, &var);
|
||||
ok(hr == S_FALSE, "ReadMultiple failed: 0x%08x\n", hr);
|
||||
ok(hr == S_OK, "ReadMultiple failed: 0x%08x\n", hr);
|
||||
|
||||
ok(var.vt == VT_I4 && U(var).lVal == 1,
|
||||
"Didn't get expected type or value for property (got type %d, value %d)\n",
|
||||
var.vt, U(var).lVal);
|
||||
|
||||
IPropertyStorage_Release(propertyStorage);
|
||||
IPropertySetStorage_Release(propSetStorage);
|
||||
|
||||
@@ -66,6 +66,9 @@ static void test_hglobal_storage_stat(void)
|
||||
r = CreateILockBytesOnHGlobal( NULL, TRUE, &ilb );
|
||||
ok( r == S_OK, "CreateILockBytesOnHGlobal failed\n");
|
||||
|
||||
r = StgIsStorageILockBytes( ilb );
|
||||
ok( r == S_FALSE, "StgIsStorageILockBytes should have failed\n");
|
||||
|
||||
mode = STGM_CREATE|STGM_SHARE_EXCLUSIVE|STGM_READWRITE;/*0x1012*/
|
||||
r = StgCreateDocfileOnILockBytes( ilb, mode, 0, &stg );
|
||||
ok( r == S_OK, "StgCreateDocfileOnILockBytes failed\n");
|
||||
@@ -73,6 +76,9 @@ static void test_hglobal_storage_stat(void)
|
||||
r = WriteClassStg( stg, &test_stg_cls );
|
||||
ok( r == S_OK, "WriteClassStg failed\n");
|
||||
|
||||
r = StgIsStorageILockBytes( ilb );
|
||||
ok( r == S_OK, "StgIsStorageILockBytes failed\n");
|
||||
|
||||
memset( &stat, 0, sizeof stat );
|
||||
r = IStorage_Stat( stg, &stat, 0 );
|
||||
|
||||
@@ -241,6 +247,59 @@ static void test_create_storage_modes(void)
|
||||
ok(DeleteFileA(filenameA), "failed to delete file\n");
|
||||
}
|
||||
|
||||
static void test_stgcreatestorageex(void)
|
||||
{
|
||||
HRESULT (WINAPI *pStgCreateStorageEx)(const WCHAR* pwcsName, DWORD grfMode, DWORD stgfmt, DWORD grfAttrs, STGOPTIONS* pStgOptions, void* reserved, REFIID riid, void** ppObjectOpen);
|
||||
HMODULE hOle32 = GetModuleHandle("ole32");
|
||||
IStorage *stg = NULL;
|
||||
STGOPTIONS stgoptions = {1, 0, 4096};
|
||||
HRESULT r;
|
||||
|
||||
pStgCreateStorageEx = (void *) GetProcAddress(hOle32, "StgCreateStorageEx");
|
||||
if (!pStgCreateStorageEx)
|
||||
{
|
||||
win_skip("skipping test on NT4\n");
|
||||
return;
|
||||
}
|
||||
|
||||
DeleteFileA(filenameA);
|
||||
|
||||
/* Verify that StgCreateStorageEx can accept an options param */
|
||||
r = pStgCreateStorageEx( filename,
|
||||
STGM_SHARE_EXCLUSIVE | STGM_READWRITE,
|
||||
STGFMT_DOCFILE,
|
||||
0,
|
||||
&stgoptions,
|
||||
NULL,
|
||||
&IID_IStorage,
|
||||
(void **) &stg);
|
||||
ok(r==S_OK || r==STG_E_UNIMPLEMENTEDFUNCTION, "StgCreateStorageEx with options failed\n");
|
||||
if (r==STG_E_UNIMPLEMENTEDFUNCTION)
|
||||
{
|
||||
/* We're on win98 which means all bets are off. Let's get out of here. */
|
||||
win_skip("skipping test on win9x\n");
|
||||
return;
|
||||
}
|
||||
|
||||
r = IStorage_Release(stg);
|
||||
ok(r == 0, "storage not released\n");
|
||||
ok(DeleteFileA(filenameA), "failed to delete file\n");
|
||||
|
||||
/* Verify that StgCreateStorageEx can accept a NULL pStgOptions */
|
||||
r = pStgCreateStorageEx( filename,
|
||||
STGM_SHARE_EXCLUSIVE | STGM_READWRITE,
|
||||
STGFMT_STORAGE,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
&IID_IStorage,
|
||||
(void **) &stg);
|
||||
ok(r==S_OK, "StgCreateStorageEx with NULL options failed\n");
|
||||
r = IStorage_Release(stg);
|
||||
ok(r == 0, "storage not released\n");
|
||||
ok(DeleteFileA(filenameA), "failed to delete file\n");
|
||||
}
|
||||
|
||||
static void test_storage_stream(void)
|
||||
{
|
||||
static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
|
||||
@@ -822,7 +881,7 @@ static void test_storage_refcount(void)
|
||||
STATSTG statstg;
|
||||
|
||||
r = IStorage_Stat( stg, &statstg, STATFLAG_NONAME );
|
||||
ok(r == S_OK, "Stat should have succeded instead of returning 0x%08x\n", r);
|
||||
ok(r == S_OK, "Stat should have succeeded instead of returning 0x%08x\n", r);
|
||||
ok(statstg.type == STGTY_STORAGE, "Statstg type should have been STGTY_STORAGE instead of %d\n", statstg.type);
|
||||
ok(U(statstg.cbSize).LowPart == 0, "Statstg cbSize.LowPart should have been 0 instead of %d\n", U(statstg.cbSize).LowPart);
|
||||
ok(U(statstg.cbSize).HighPart == 0, "Statstg cbSize.HighPart should have been 0 instead of %d\n", U(statstg.cbSize).HighPart);
|
||||
@@ -837,7 +896,7 @@ static void test_storage_refcount(void)
|
||||
ok(r == S_OK, "CreateStorage should have succeeded instead of returning 0x%08x\n", r);
|
||||
|
||||
r = IStorage_Stat( stg2, &statstg, STATFLAG_DEFAULT );
|
||||
ok(r == S_OK, "Stat should have succeded instead of returning 0x%08x\n", r);
|
||||
ok(r == S_OK, "Stat should have succeeded instead of returning 0x%08x\n", r);
|
||||
ok(!memcmp(statstg.pwcsName, stgname, sizeof(stgname)),
|
||||
"Statstg pwcsName should have been the name the storage was created with\n");
|
||||
ok(statstg.type == STGTY_STORAGE, "Statstg type should have been STGTY_STORAGE instead of %d\n", statstg.type);
|
||||
@@ -955,6 +1014,7 @@ static void test_streamenum(void)
|
||||
CoTaskMemFree(stat.pwcsName);
|
||||
|
||||
r = IEnumSTATSTG_Release(ee);
|
||||
ok(r==S_OK, "EnumSTATSTG_Release failed with error 0x%08x\n", r);
|
||||
|
||||
/* second enum... destroy the stream before reading */
|
||||
r = IStorage_EnumElements(stg, 0, NULL, 0, &ee);
|
||||
@@ -985,6 +1045,7 @@ static void test_streamenum(void)
|
||||
ok(r==S_OK, "IStorage->CreateStream failed\n");
|
||||
|
||||
r = IStream_Release(stm);
|
||||
ok(r==S_OK, "Stream_Release failed with error 0x%08x\n", r);
|
||||
|
||||
count = 0xf00;
|
||||
r = IEnumSTATSTG_Next(ee, 1, &stat, &count);
|
||||
@@ -1001,6 +1062,7 @@ static void test_streamenum(void)
|
||||
ok(r==S_OK, "IStorage->CreateStream failed\n");
|
||||
|
||||
r = IStream_Release(stm);
|
||||
ok(r==S_OK, "Stream_Release failed with error 0x%08x\n", r);
|
||||
|
||||
count = 0xf00;
|
||||
r = IEnumSTATSTG_Next(ee, 1, &stat, &count);
|
||||
@@ -1018,6 +1080,7 @@ static void test_streamenum(void)
|
||||
ok(r==S_OK, "IStorage->CreateStream failed\n");
|
||||
|
||||
r = IStream_Release(stm);
|
||||
ok(r==S_OK, "Stream_Release failed with error 0x%08x\n", r);
|
||||
|
||||
r = IEnumSTATSTG_Reset(ee);
|
||||
ok(r==S_OK, "IEnumSTATSTG->Reset failed\n");
|
||||
@@ -1363,6 +1426,7 @@ static void test_revert(void)
|
||||
ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
|
||||
|
||||
r = IStorage_Revert(stg);
|
||||
ok(r==S_OK, "Storage_Revert failed with error 0x%08x\n", r);
|
||||
|
||||
/* all open objects become invalid */
|
||||
r = IStream_Write(stm, "this shouldn't work\n", 20, NULL);
|
||||
@@ -1497,7 +1561,7 @@ static void test_parent_free(void)
|
||||
if (r == S_OK)
|
||||
{
|
||||
r = IStream_Write(stm, "this should fail\n", 17, NULL);
|
||||
ok(r==STG_E_REVERTED, "IStream->Write sould fail, hr=%x\n", r);
|
||||
ok(r==STG_E_REVERTED, "IStream->Write should fail, hr=%x\n", r);
|
||||
|
||||
IStream_Release(stm);
|
||||
|
||||
@@ -2679,6 +2743,7 @@ static void test_toplevel_stat(void)
|
||||
ok(r==S_OK, "StgCreateDocfile failed\n");
|
||||
|
||||
r = IStorage_Stat( stg, &stat, STATFLAG_DEFAULT );
|
||||
ok(r==S_OK, "Storage_Stat failed with error 0x%08x\n", r);
|
||||
ok(!strcmp_ww(stat.pwcsName, filename), "expected %s, got %s\n",
|
||||
wine_dbgstr_w(filename), wine_dbgstr_w(stat.pwcsName));
|
||||
CoTaskMemFree(stat.pwcsName);
|
||||
@@ -2689,6 +2754,7 @@ static void test_toplevel_stat(void)
|
||||
ok(r==S_OK, "StgOpenStorage failed with error 0x%08x\n", r);
|
||||
|
||||
r = IStorage_Stat( stg, &stat, STATFLAG_DEFAULT );
|
||||
ok(r==S_OK, "Storage_Stat failed with error 0x%08x\n", r);
|
||||
ok(!strcmp_ww(stat.pwcsName, filename), "expected %s, got %s\n",
|
||||
wine_dbgstr_w(filename), wine_dbgstr_w(stat.pwcsName));
|
||||
CoTaskMemFree(stat.pwcsName);
|
||||
@@ -2712,6 +2778,7 @@ static void test_toplevel_stat(void)
|
||||
ok(r==S_OK, "StgCreateDocfile failed\n");
|
||||
|
||||
r = IStorage_Stat( stg, &stat, STATFLAG_DEFAULT );
|
||||
ok(r==S_OK, "Storage_Stat failed with error 0x%08x\n", r);
|
||||
ok(!strcmp_ww(stat.pwcsName, filename), "expected %s, got %s\n",
|
||||
wine_dbgstr_w(filename), wine_dbgstr_w(stat.pwcsName));
|
||||
CoTaskMemFree(stat.pwcsName);
|
||||
@@ -2722,6 +2789,7 @@ static void test_toplevel_stat(void)
|
||||
ok(r==S_OK, "StgOpenStorage failed with error 0x%08x\n", r);
|
||||
|
||||
r = IStorage_Stat( stg, &stat, STATFLAG_DEFAULT );
|
||||
ok(r==S_OK, "Storage_Stat failed with error 0x%08x\n", r);
|
||||
ok(!strcmp_ww(stat.pwcsName, filename), "expected %s, got %s\n",
|
||||
wine_dbgstr_w(filename), wine_dbgstr_w(stat.pwcsName));
|
||||
CoTaskMemFree(stat.pwcsName);
|
||||
@@ -2819,7 +2887,7 @@ static void test_copyto_locking(void)
|
||||
|
||||
/* Try to copy the storage while the substorage is open */
|
||||
r = IStorage_CopyTo(stg2, 0, NULL, NULL, stg3);
|
||||
todo_wine ok(r==S_OK, "IStorage->CopyTo failed, hr=%08x\n", r);
|
||||
ok(r==S_OK, "IStorage->CopyTo failed, hr=%08x\n", r);
|
||||
|
||||
IStorage_Release(stg4);
|
||||
IStorage_Release(stg3);
|
||||
@@ -2881,6 +2949,52 @@ static void test_copyto_recursive(void)
|
||||
ok( r == TRUE, "deleted file\n");
|
||||
}
|
||||
|
||||
static void test_hglobal_storage_creation(void)
|
||||
{
|
||||
ILockBytes *ilb = NULL;
|
||||
IStorage *stg = NULL;
|
||||
HRESULT r;
|
||||
STATSTG stat;
|
||||
char junk[512];
|
||||
ULARGE_INTEGER offset;
|
||||
|
||||
r = CreateILockBytesOnHGlobal(NULL, TRUE, &ilb);
|
||||
ok(r == S_OK, "CreateILockBytesOnHGlobal failed, hr=%x\n", r);
|
||||
|
||||
offset.QuadPart = 0;
|
||||
memset(junk, 0xaa, 512);
|
||||
r = ILockBytes_WriteAt(ilb, offset, junk, 512, NULL);
|
||||
ok(r == S_OK, "ILockBytes_WriteAt failed, hr=%x\n", r);
|
||||
|
||||
offset.QuadPart = 2000;
|
||||
r = ILockBytes_WriteAt(ilb, offset, junk, 512, NULL);
|
||||
ok(r == S_OK, "ILockBytes_WriteAt failed, hr=%x\n", r);
|
||||
|
||||
r = StgCreateDocfileOnILockBytes(ilb, STGM_CREATE|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stg);
|
||||
ok(r == S_OK, "StgCreateDocfileOnILockBytes failed, hr=%x\n", r);
|
||||
|
||||
IStorage_Release(stg);
|
||||
|
||||
r = StgOpenStorageOnILockBytes(ilb, NULL, STGM_READ|STGM_SHARE_EXCLUSIVE,
|
||||
NULL, 0, &stg);
|
||||
ok(r == S_OK, "StgOpenStorageOnILockBytes failed, hr=%x\n", r);
|
||||
|
||||
if (SUCCEEDED(r))
|
||||
{
|
||||
r = IStorage_Stat(stg, &stat, STATFLAG_NONAME);
|
||||
ok(r == S_OK, "StgOpenStorageOnILockBytes failed, hr=%x\n", r);
|
||||
ok(IsEqualCLSID(&stat.clsid, &GUID_NULL), "unexpected CLSID value\n");
|
||||
|
||||
IStorage_Release(stg);
|
||||
}
|
||||
|
||||
r = ILockBytes_Stat(ilb, &stat, STATFLAG_NONAME);
|
||||
ok(r == S_OK, "ILockBytes_Stat failed, hr=%x\n", r);
|
||||
ok(stat.cbSize.u.LowPart < 2512, "expected truncated size, got %d\n", stat.cbSize.u.LowPart);
|
||||
|
||||
ILockBytes_Release(ilb);
|
||||
}
|
||||
|
||||
START_TEST(storage32)
|
||||
{
|
||||
CHAR temp[MAX_PATH];
|
||||
@@ -2896,6 +3010,7 @@ START_TEST(storage32)
|
||||
|
||||
test_hglobal_storage_stat();
|
||||
test_create_storage_modes();
|
||||
test_stgcreatestorageex();
|
||||
test_storage_stream();
|
||||
test_open_storage();
|
||||
test_storage_suminfo();
|
||||
@@ -2922,4 +3037,5 @@ START_TEST(storage32)
|
||||
test_substorage_enum();
|
||||
test_copyto_locking();
|
||||
test_copyto_recursive();
|
||||
test_hglobal_storage_creation();
|
||||
}
|
||||
|
||||
@@ -182,6 +182,7 @@ static void test_marshal_HGLOBAL(void)
|
||||
wirehglobal += sizeof(ULONG);
|
||||
ok(*(ULONG *)wirehglobal == 0, "buffer+4 should be HGLOBAL\n");
|
||||
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL);
|
||||
hglobal2 = NULL;
|
||||
HGLOBAL_UserUnmarshal(&umcb.Flags, buffer, &hglobal2);
|
||||
ok(hglobal2 == hglobal, "Didn't unmarshal properly\n");
|
||||
HeapFree(GetProcessHeap(), 0, buffer);
|
||||
@@ -227,6 +228,7 @@ static void test_marshal_HGLOBAL(void)
|
||||
ok(wirehglobal[i] == i, "buffer+0x%x should be %d\n", 0x10 + i, i);
|
||||
|
||||
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL);
|
||||
hglobal2 = NULL;
|
||||
HGLOBAL_UserUnmarshal(&umcb.Flags, buffer, &hglobal2);
|
||||
ok(hglobal2 != NULL, "Didn't unmarshal properly\n");
|
||||
HeapFree(GetProcessHeap(), 0, buffer);
|
||||
@@ -578,7 +580,6 @@ static void marshal_WdtpInterfacePointer(DWORD umcb_ctx, DWORD ctx)
|
||||
ok(size == 0, "size should be 0 bytes, not %d\n", size);
|
||||
buffer = HeapAlloc(GetProcessHeap(), 0, size);
|
||||
buffer_end = WdtpInterfacePointer_UserMarshal(&umcb.Flags, ctx, buffer, unk, &IID_IUnknown);
|
||||
wireip = buffer;
|
||||
HeapFree(GetProcessHeap(), 0, buffer);
|
||||
|
||||
/* Now for a non-NULL pointer. The marshalled data are two size DWORDS and then
|
||||
|
||||
Reference in New Issue
Block a user