Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=55759
-- v3: wintypes: Implement IBufferByteAccess::Buffer(). wintypes/tests: Add IBufferByteAccess::Buffer() tests. wintypes: Add IBufferByteAccess stub. wintypes: Implement IBuffer::get_Length(). wintypes: Implement IBuffer::put_Length(). wintypes: Implement IBuffer::get_Capacity(). wintypes: Implement IBufferFactory::Create(). wintypes/tests: Add IBufferFactory::Create() tests.
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- dlls/wintypes/tests/wintypes.c | 88 +++++++++++++++++++++++++++++++++- 1 file changed, 87 insertions(+), 1 deletion(-)
diff --git a/dlls/wintypes/tests/wintypes.c b/dlls/wintypes/tests/wintypes.c index 90bd32513f8..29ef93de17c 100644 --- a/dlls/wintypes/tests/wintypes.c +++ b/dlls/wintypes/tests/wintypes.c @@ -139,6 +139,7 @@ static void test_IBufferStatics(void) static const WCHAR *class_name = L"Windows.Storage.Streams.Buffer"; IBufferFactory *buffer_factory = NULL; IActivationFactory *factory = NULL; + UINT32 capacity, length; IBuffer *buffer = NULL; HSTRING str; HRESULT hr; @@ -175,8 +176,93 @@ static void test_IBufferStatics(void) hr = IBufferFactory_Create(buffer_factory, 0, &buffer); todo_wine ok(hr == S_OK, "IBufferFactory_Create failed, hr %#lx.\n", hr); - if (hr == S_OK) IBuffer_Release(buffer); + if (hr != S_OK) goto done;
+ check_interface(buffer, &IID_IAgileObject, TRUE); + + if (0) /* Crash on Windows */ + { + hr = IBuffer_get_Capacity(buffer, NULL); + ok(hr == E_INVALIDARG, "IBuffer_get_Capacity failed, hr %#lx.\n", hr); + } + + capacity = 0xdeadbeef; + hr = IBuffer_get_Capacity(buffer, &capacity); + todo_wine + ok(hr == S_OK, "IBuffer_get_Capacity failed, hr %#lx.\n", hr); + todo_wine + ok(capacity == 0, "IBuffer_get_Capacity returned capacity %u.\n", capacity); + + if (0) /* Crash on Windows */ + { + hr = IBuffer_get_Length(buffer, NULL); + ok(hr == E_INVALIDARG, "IBuffer_get_Length failed, hr %#lx.\n", hr); + } + + length = 0xdeadbeef; + hr = IBuffer_get_Length(buffer, &length); + todo_wine + ok(hr == S_OK, "IBuffer_get_Length failed, hr %#lx.\n", hr); + todo_wine + ok(length == 0, "IBuffer_get_Length returned length %u.\n", length); + + hr = IBuffer_put_Length(buffer, 1); + todo_wine + ok(hr == E_INVALIDARG, "IBuffer_put_Length failed, hr %#lx.\n", hr); + + IBuffer_Release(buffer); + + buffer = (void *)0xdeadbeef; + hr = IBufferFactory_Create(buffer_factory, 0xdeadbeef, &buffer); + todo_wine + ok(hr == S_OK || hr == E_OUTOFMEMORY, "IBufferFactory_Create failed, hr %#lx.\n", hr); + if (hr == E_OUTOFMEMORY) /* 32-bit memory limitation, Large Address Aware is ignored */ + { + todo_wine + ok(buffer == NULL, "IBufferFactory_Create returned buffer %p.\n", buffer); + goto done; + } + + capacity = 0; + hr = IBuffer_get_Capacity(buffer, &capacity); + todo_wine + ok(hr == S_OK, "IBuffer_get_Capacity failed, hr %#lx.\n", hr); + todo_wine + ok(capacity == 0xdeadbeef, "IBuffer_get_Capacity returned capacity %u.\n", capacity); + + length = 0xdeadbeef; + hr = IBuffer_get_Length(buffer, &length); + todo_wine + ok(hr == S_OK, "IBuffer_get_Length failed, hr %#lx.\n", hr); + todo_wine + ok(length == 0, "IBuffer_get_Length returned length %u.\n", length); + + hr = IBuffer_put_Length(buffer, 1); + todo_wine + ok(hr == S_OK, "IBuffer_put_Length failed, hr %#lx.\n", hr); + length = 0xdeadbeef; + hr = IBuffer_get_Length(buffer, &length); + todo_wine + ok(hr == S_OK, "IBuffer_get_Length failed, hr %#lx.\n", hr); + todo_wine + ok(length == 1, "IBuffer_get_Length returned length %u.\n", length); + + hr = IBuffer_put_Length(buffer, 0xdeadbeef + 1); + todo_wine + ok(hr == E_INVALIDARG, "IBuffer_put_Length failed, hr %#lx.\n", hr); + + hr = IBuffer_put_Length(buffer, 0xdeadbeef); + todo_wine + ok(hr == S_OK, "IBuffer_put_Length failed, hr %#lx.\n", hr); + length = 0; + hr = IBuffer_get_Length(buffer, &length); + todo_wine + ok(hr == S_OK, "IBuffer_get_Length failed, hr %#lx.\n", hr); + todo_wine + ok(length == 0xdeadbeef, "IBuffer_get_Length returned length %u.\n", length); + + IBuffer_Release(buffer); +done: IBufferFactory_Release(buffer_factory); IActivationFactory_Release(factory); RoUninitialize();
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- dlls/wintypes/buffer.c | 126 ++++++++++++++++++++++++++++++++- dlls/wintypes/tests/wintypes.c | 4 -- 2 files changed, 124 insertions(+), 6 deletions(-)
diff --git a/dlls/wintypes/buffer.c b/dlls/wintypes/buffer.c index a5dc7d2d1f7..d3268a03e33 100644 --- a/dlls/wintypes/buffer.c +++ b/dlls/wintypes/buffer.c @@ -114,12 +114,134 @@ static const struct IActivationFactoryVtbl factory_vtbl = factory_ActivateInstance, };
+struct buffer +{ + IBuffer IBuffer_iface; + LONG ref; + + UINT32 capacity; + UINT32 length; + BYTE data[]; +}; + +C_ASSERT( offsetof( struct buffer, data ) <= sizeof( struct buffer ) ); + +static inline struct buffer *impl_from_IBuffer( IBuffer *iface ) +{ + return CONTAINING_RECORD( iface, struct buffer, IBuffer_iface ); +} + +static HRESULT WINAPI buffer_QueryInterface( IBuffer *iface, REFIID iid, void **out ) +{ + struct buffer *impl = impl_from_IBuffer( iface ); + + TRACE( "iface %p, iid %s, out %p.\n", iface, debugstr_guid( iid ), out ); + + if (IsEqualGUID( iid, &IID_IUnknown ) || + IsEqualGUID( iid, &IID_IInspectable ) || + IsEqualGUID( iid, &IID_IAgileObject ) || + IsEqualGUID( iid, &IID_IBuffer )) + { + *out = &impl->IBuffer_iface; + IInspectable_AddRef( *out ); + return S_OK; + } + + FIXME( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid ) ); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI buffer_AddRef( IBuffer *iface ) +{ + struct buffer *impl = impl_from_IBuffer( iface ); + ULONG ref = InterlockedIncrement( &impl->ref ); + TRACE( "iface %p increasing refcount to %lu.\n", iface, ref ); + return ref; +} + +static ULONG WINAPI buffer_Release( IBuffer *iface ) +{ + struct buffer *impl = impl_from_IBuffer( iface ); + ULONG ref = InterlockedDecrement( &impl->ref ); + + TRACE( "iface %p decreasing refcount to %lu.\n", iface, ref ); + + if (!ref) free( impl ); + return ref; +} + +static HRESULT WINAPI buffer_GetIids( IBuffer *iface, ULONG *iid_count, IID **iids ) +{ + FIXME( "iface %p, iid_count %p, iids %p stub!\n", iface, iid_count, iids ); + return E_NOTIMPL; +} + +static HRESULT WINAPI buffer_GetRuntimeClassName( IBuffer *iface, HSTRING *class_name ) +{ + FIXME( "iface %p, class_name %p stub!\n", iface, class_name ); + return E_NOTIMPL; +} + +static HRESULT WINAPI buffer_GetTrustLevel( IBuffer *iface, TrustLevel *trust_level ) +{ + FIXME( "iface %p, trust_level %p stub!\n", iface, trust_level ); + return E_NOTIMPL; +} + +static HRESULT WINAPI buffer_get_Capacity( IBuffer *iface, UINT32 *value ) +{ + FIXME( "iface %p, value %p stub!\n", iface, value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI buffer_get_Length( IBuffer *iface, UINT32 *value ) +{ + FIXME( "iface %p, value %p stub!\n", iface, value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI buffer_put_Length( IBuffer *iface, UINT32 value ) +{ + FIXME( "iface %p, value %u stub!\n", iface, value ); + return E_NOTIMPL; +} + +static const struct IBufferVtbl buffer_vtbl = +{ + buffer_QueryInterface, + buffer_AddRef, + buffer_Release, + /* IInspectable methods */ + buffer_GetIids, + buffer_GetRuntimeClassName, + buffer_GetTrustLevel, + /* IBuffer methods */ + buffer_get_Capacity, + buffer_get_Length, + buffer_put_Length, +}; + DEFINE_IINSPECTABLE( buffer_factory_statics, IBufferFactory, struct buffer_factory_statics, IActivationFactory_iface )
static HRESULT WINAPI buffer_factory_statics_Create( IBufferFactory *iface, UINT32 capacity, IBuffer **value ) { - FIXME( "iface %p, capacity %u, value %p stub!\n", iface, capacity, value ); - return E_NOTIMPL; + struct buffer *impl; + + TRACE( "iface %p, capacity %u, value %p\n", iface, capacity, value ); + + *value = NULL; + + if (!(impl = malloc( offsetof( struct buffer, data[capacity] ) ))) return E_OUTOFMEMORY; + + impl->IBuffer_iface.lpVtbl = &buffer_vtbl; + impl->ref = 1; + impl->capacity = capacity; + impl->length = 0; + + *value = &impl->IBuffer_iface; + TRACE( "created IBuffer %p.\n", *value ); + return S_OK; }
static const struct IBufferFactoryVtbl buffer_factory_statics_vtbl = diff --git a/dlls/wintypes/tests/wintypes.c b/dlls/wintypes/tests/wintypes.c index 29ef93de17c..71e1d5878ff 100644 --- a/dlls/wintypes/tests/wintypes.c +++ b/dlls/wintypes/tests/wintypes.c @@ -174,9 +174,7 @@ static void test_IBufferStatics(void) }
hr = IBufferFactory_Create(buffer_factory, 0, &buffer); - todo_wine ok(hr == S_OK, "IBufferFactory_Create failed, hr %#lx.\n", hr); - if (hr != S_OK) goto done;
check_interface(buffer, &IID_IAgileObject, TRUE);
@@ -214,11 +212,9 @@ static void test_IBufferStatics(void)
buffer = (void *)0xdeadbeef; hr = IBufferFactory_Create(buffer_factory, 0xdeadbeef, &buffer); - todo_wine ok(hr == S_OK || hr == E_OUTOFMEMORY, "IBufferFactory_Create failed, hr %#lx.\n", hr); if (hr == E_OUTOFMEMORY) /* 32-bit memory limitation, Large Address Aware is ignored */ { - todo_wine ok(buffer == NULL, "IBufferFactory_Create returned buffer %p.\n", buffer); goto done; }
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- dlls/wintypes/buffer.c | 8 ++++++-- dlls/wintypes/tests/wintypes.c | 4 ---- 2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/dlls/wintypes/buffer.c b/dlls/wintypes/buffer.c index d3268a03e33..e279f7c493d 100644 --- a/dlls/wintypes/buffer.c +++ b/dlls/wintypes/buffer.c @@ -191,8 +191,12 @@ static HRESULT WINAPI buffer_GetTrustLevel( IBuffer *iface, TrustLevel *trust_le
static HRESULT WINAPI buffer_get_Capacity( IBuffer *iface, UINT32 *value ) { - FIXME( "iface %p, value %p stub!\n", iface, value ); - return E_NOTIMPL; + struct buffer *impl = impl_from_IBuffer( iface ); + + TRACE( "iface %p, value %p\n", iface, value ); + + *value = impl->capacity; + return S_OK; }
static HRESULT WINAPI buffer_get_Length( IBuffer *iface, UINT32 *value ) diff --git a/dlls/wintypes/tests/wintypes.c b/dlls/wintypes/tests/wintypes.c index 71e1d5878ff..c8d1c76d8c2 100644 --- a/dlls/wintypes/tests/wintypes.c +++ b/dlls/wintypes/tests/wintypes.c @@ -186,9 +186,7 @@ static void test_IBufferStatics(void)
capacity = 0xdeadbeef; hr = IBuffer_get_Capacity(buffer, &capacity); - todo_wine ok(hr == S_OK, "IBuffer_get_Capacity failed, hr %#lx.\n", hr); - todo_wine ok(capacity == 0, "IBuffer_get_Capacity returned capacity %u.\n", capacity);
if (0) /* Crash on Windows */ @@ -221,9 +219,7 @@ static void test_IBufferStatics(void)
capacity = 0; hr = IBuffer_get_Capacity(buffer, &capacity); - todo_wine ok(hr == S_OK, "IBuffer_get_Capacity failed, hr %#lx.\n", hr); - todo_wine ok(capacity == 0xdeadbeef, "IBuffer_get_Capacity returned capacity %u.\n", capacity);
length = 0xdeadbeef;
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- dlls/wintypes/buffer.c | 10 ++++++++-- dlls/wintypes/tests/wintypes.c | 4 ---- 2 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/dlls/wintypes/buffer.c b/dlls/wintypes/buffer.c index e279f7c493d..1c96ee4cc1e 100644 --- a/dlls/wintypes/buffer.c +++ b/dlls/wintypes/buffer.c @@ -207,8 +207,14 @@ static HRESULT WINAPI buffer_get_Length( IBuffer *iface, UINT32 *value )
static HRESULT WINAPI buffer_put_Length( IBuffer *iface, UINT32 value ) { - FIXME( "iface %p, value %u stub!\n", iface, value ); - return E_NOTIMPL; + struct buffer *impl = impl_from_IBuffer( iface ); + + TRACE( "iface %p, value %u\n", iface, value ); + + if (value > impl->capacity) return E_INVALIDARG; + + impl->length = value; + return S_OK; }
static const struct IBufferVtbl buffer_vtbl = diff --git a/dlls/wintypes/tests/wintypes.c b/dlls/wintypes/tests/wintypes.c index c8d1c76d8c2..87a975620f9 100644 --- a/dlls/wintypes/tests/wintypes.c +++ b/dlls/wintypes/tests/wintypes.c @@ -203,7 +203,6 @@ static void test_IBufferStatics(void) ok(length == 0, "IBuffer_get_Length returned length %u.\n", length);
hr = IBuffer_put_Length(buffer, 1); - todo_wine ok(hr == E_INVALIDARG, "IBuffer_put_Length failed, hr %#lx.\n", hr);
IBuffer_Release(buffer); @@ -230,7 +229,6 @@ static void test_IBufferStatics(void) ok(length == 0, "IBuffer_get_Length returned length %u.\n", length);
hr = IBuffer_put_Length(buffer, 1); - todo_wine ok(hr == S_OK, "IBuffer_put_Length failed, hr %#lx.\n", hr); length = 0xdeadbeef; hr = IBuffer_get_Length(buffer, &length); @@ -240,11 +238,9 @@ static void test_IBufferStatics(void) ok(length == 1, "IBuffer_get_Length returned length %u.\n", length);
hr = IBuffer_put_Length(buffer, 0xdeadbeef + 1); - todo_wine ok(hr == E_INVALIDARG, "IBuffer_put_Length failed, hr %#lx.\n", hr);
hr = IBuffer_put_Length(buffer, 0xdeadbeef); - todo_wine ok(hr == S_OK, "IBuffer_put_Length failed, hr %#lx.\n", hr); length = 0; hr = IBuffer_get_Length(buffer, &length);
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- dlls/wintypes/buffer.c | 8 ++++++-- dlls/wintypes/tests/wintypes.c | 8 -------- 2 files changed, 6 insertions(+), 10 deletions(-)
diff --git a/dlls/wintypes/buffer.c b/dlls/wintypes/buffer.c index 1c96ee4cc1e..6129e096035 100644 --- a/dlls/wintypes/buffer.c +++ b/dlls/wintypes/buffer.c @@ -201,8 +201,12 @@ static HRESULT WINAPI buffer_get_Capacity( IBuffer *iface, UINT32 *value )
static HRESULT WINAPI buffer_get_Length( IBuffer *iface, UINT32 *value ) { - FIXME( "iface %p, value %p stub!\n", iface, value ); - return E_NOTIMPL; + struct buffer *impl = impl_from_IBuffer( iface ); + + TRACE( "iface %p, value %p\n", iface, value ); + + *value = impl->length; + return S_OK; }
static HRESULT WINAPI buffer_put_Length( IBuffer *iface, UINT32 value ) diff --git a/dlls/wintypes/tests/wintypes.c b/dlls/wintypes/tests/wintypes.c index 87a975620f9..91d69f410e2 100644 --- a/dlls/wintypes/tests/wintypes.c +++ b/dlls/wintypes/tests/wintypes.c @@ -197,9 +197,7 @@ static void test_IBufferStatics(void)
length = 0xdeadbeef; hr = IBuffer_get_Length(buffer, &length); - todo_wine ok(hr == S_OK, "IBuffer_get_Length failed, hr %#lx.\n", hr); - todo_wine ok(length == 0, "IBuffer_get_Length returned length %u.\n", length);
hr = IBuffer_put_Length(buffer, 1); @@ -223,18 +221,14 @@ static void test_IBufferStatics(void)
length = 0xdeadbeef; hr = IBuffer_get_Length(buffer, &length); - todo_wine ok(hr == S_OK, "IBuffer_get_Length failed, hr %#lx.\n", hr); - todo_wine ok(length == 0, "IBuffer_get_Length returned length %u.\n", length);
hr = IBuffer_put_Length(buffer, 1); ok(hr == S_OK, "IBuffer_put_Length failed, hr %#lx.\n", hr); length = 0xdeadbeef; hr = IBuffer_get_Length(buffer, &length); - todo_wine ok(hr == S_OK, "IBuffer_get_Length failed, hr %#lx.\n", hr); - todo_wine ok(length == 1, "IBuffer_get_Length returned length %u.\n", length);
hr = IBuffer_put_Length(buffer, 0xdeadbeef + 1); @@ -244,9 +238,7 @@ static void test_IBufferStatics(void) ok(hr == S_OK, "IBuffer_put_Length failed, hr %#lx.\n", hr); length = 0; hr = IBuffer_get_Length(buffer, &length); - todo_wine ok(hr == S_OK, "IBuffer_get_Length failed, hr %#lx.\n", hr); - todo_wine ok(length == 0xdeadbeef, "IBuffer_get_Length returned length %u.\n", length);
IBuffer_Release(buffer);
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- dlls/wintypes/buffer.c | 49 ++++++++++++++++++++++++++++++++++ dlls/wintypes/tests/wintypes.c | 12 +++++++++ 2 files changed, 61 insertions(+)
diff --git a/dlls/wintypes/buffer.c b/dlls/wintypes/buffer.c index 6129e096035..4e3fdebb151 100644 --- a/dlls/wintypes/buffer.c +++ b/dlls/wintypes/buffer.c @@ -18,6 +18,8 @@ */
#include "private.h" +#include "initguid.h" +#include "robuffer.h"
WINE_DEFAULT_DEBUG_CHANNEL(wintypes);
@@ -117,6 +119,7 @@ static const struct IActivationFactoryVtbl factory_vtbl = struct buffer { IBuffer IBuffer_iface; + IBufferByteAccess IBufferByteAccess_iface; LONG ref;
UINT32 capacity; @@ -147,6 +150,13 @@ static HRESULT WINAPI buffer_QueryInterface( IBuffer *iface, REFIID iid, void ** return S_OK; }
+ if (IsEqualGUID( iid, &IID_IBufferByteAccess )) + { + *out = &impl->IBufferByteAccess_iface; + IInspectable_AddRef( *out ); + return S_OK; + } + FIXME( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid ) ); *out = NULL; return E_NOINTERFACE; @@ -236,6 +246,44 @@ static const struct IBufferVtbl buffer_vtbl = buffer_put_Length, };
+static inline struct buffer *impl_from_IBufferByteAccess( IBufferByteAccess *iface ) +{ + return CONTAINING_RECORD( iface, struct buffer, IBufferByteAccess_iface ); +} + +static HRESULT WINAPI buffer_byte_access_QueryInterface( IBufferByteAccess *iface, REFIID iid, void **out ) +{ + struct buffer *impl = impl_from_IBufferByteAccess( iface ); + return IBuffer_QueryInterface( &impl->IBuffer_iface, iid, out ); +} + +static ULONG WINAPI buffer_byte_access_AddRef( IBufferByteAccess *iface ) +{ + struct buffer *impl = impl_from_IBufferByteAccess( iface ); + return IBuffer_AddRef( &impl->IBuffer_iface ); +} + +static ULONG WINAPI buffer_byte_access_Release( IBufferByteAccess *iface ) +{ + struct buffer *impl = impl_from_IBufferByteAccess( iface ); + return IBuffer_Release( &impl->IBuffer_iface ); +} + +static HRESULT WINAPI buffer_byte_access_Buffer( IBufferByteAccess *iface, byte **value ) +{ + FIXME( "iface %p, value %p stub!\n", iface, value ); + return E_NOTIMPL; +} + +static const struct IBufferByteAccessVtbl buffer_byte_access_vtbl = +{ + buffer_byte_access_QueryInterface, + buffer_byte_access_AddRef, + buffer_byte_access_Release, + /* IBufferByteAccess methods */ + buffer_byte_access_Buffer, +}; + DEFINE_IINSPECTABLE( buffer_factory_statics, IBufferFactory, struct buffer_factory_statics, IActivationFactory_iface )
static HRESULT WINAPI buffer_factory_statics_Create( IBufferFactory *iface, UINT32 capacity, IBuffer **value ) @@ -249,6 +297,7 @@ static HRESULT WINAPI buffer_factory_statics_Create( IBufferFactory *iface, UINT if (!(impl = malloc( offsetof( struct buffer, data[capacity] ) ))) return E_OUTOFMEMORY;
impl->IBuffer_iface.lpVtbl = &buffer_vtbl; + impl->IBufferByteAccess_iface.lpVtbl = &buffer_byte_access_vtbl; impl->ref = 1; impl->capacity = capacity; impl->length = 0; diff --git a/dlls/wintypes/tests/wintypes.c b/dlls/wintypes/tests/wintypes.c index 91d69f410e2..a77d86cd465 100644 --- a/dlls/wintypes/tests/wintypes.c +++ b/dlls/wintypes/tests/wintypes.c @@ -35,6 +35,8 @@ #define WIDL_using_Windows_Storage_Streams #include "windows.storage.streams.h"
+#include "robuffer.h" + #include "wine/test.h"
static BOOL is_wow64; @@ -137,6 +139,7 @@ static void test_interfaces(void) static void test_IBufferStatics(void) { static const WCHAR *class_name = L"Windows.Storage.Streams.Buffer"; + IBufferByteAccess *buffer_byte_access = NULL; IBufferFactory *buffer_factory = NULL; IActivationFactory *factory = NULL; UINT32 capacity, length; @@ -163,6 +166,7 @@ static void test_IBufferStatics(void) check_interface(factory, &IID_IUnknown, TRUE); check_interface(factory, &IID_IInspectable, TRUE); check_interface(factory, &IID_IAgileObject, TRUE); + check_interface(factory, &IID_IBufferByteAccess, FALSE);
hr = IActivationFactory_QueryInterface(factory, &IID_IBufferFactory, (void **)&buffer_factory); ok(hr == S_OK, "QueryInterface IID_IBufferFactory failed, hr %#lx.\n", hr); @@ -203,6 +207,14 @@ static void test_IBufferStatics(void) hr = IBuffer_put_Length(buffer, 1); ok(hr == E_INVALIDARG, "IBuffer_put_Length failed, hr %#lx.\n", hr);
+ hr = IBuffer_QueryInterface(buffer, &IID_IBufferByteAccess, (void **)&buffer_byte_access); + ok(hr == S_OK, "QueryInterface IID_IBufferByteAccess failed, hr %#lx.\n", hr); + + check_interface(buffer_byte_access, &IID_IInspectable, TRUE); + check_interface(buffer_byte_access, &IID_IAgileObject, TRUE); + check_interface(buffer_byte_access, &IID_IBuffer, TRUE); + + IBufferByteAccess_Release(buffer_byte_access); IBuffer_Release(buffer);
buffer = (void *)0xdeadbeef;
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- dlls/wintypes/tests/wintypes.c | 41 ++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+)
diff --git a/dlls/wintypes/tests/wintypes.c b/dlls/wintypes/tests/wintypes.c index a77d86cd465..325833a0588 100644 --- a/dlls/wintypes/tests/wintypes.c +++ b/dlls/wintypes/tests/wintypes.c @@ -146,6 +146,7 @@ static void test_IBufferStatics(void) IBuffer *buffer = NULL; HSTRING str; HRESULT hr; + BYTE *data;
hr = RoInitialize(RO_INIT_MULTITHREADED); ok(hr == S_OK, "RoInitialize failed, hr %#lx.\n", hr); @@ -214,6 +215,19 @@ static void test_IBufferStatics(void) check_interface(buffer_byte_access, &IID_IAgileObject, TRUE); check_interface(buffer_byte_access, &IID_IBuffer, TRUE);
+ if (0) /* Crash on Windows */ + { + hr = IBufferByteAccess_Buffer(buffer_byte_access, NULL); + ok(hr == E_INVALIDARG, "IBufferByteAccess_Buffer failed, hr %#lx.\n", hr); + } + + data = NULL; + hr = IBufferByteAccess_Buffer(buffer_byte_access, &data); + todo_wine + ok(hr == S_OK, "IBufferByteAccess_Buffer failed, hr %#lx.\n", hr); + todo_wine + ok(data != NULL, "IBufferByteAccess_Buffer returned NULL data.\n"); + IBufferByteAccess_Release(buffer_byte_access); IBuffer_Release(buffer);
@@ -253,6 +267,33 @@ static void test_IBufferStatics(void) ok(hr == S_OK, "IBuffer_get_Length failed, hr %#lx.\n", hr); ok(length == 0xdeadbeef, "IBuffer_get_Length returned length %u.\n", length);
+ hr = IBuffer_QueryInterface(buffer, &IID_IBufferByteAccess, (void **)&buffer_byte_access); + ok(hr == S_OK, "QueryInterface IID_IBufferByteAccess failed, hr %#lx.\n", hr); + + hr = IBufferByteAccess_Buffer(buffer_byte_access, &data); + todo_wine + ok(hr == S_OK, "IBufferByteAccess_Buffer failed, hr %#lx.\n", hr); + if (hr != S_OK) goto done2; + + /* Windows does not zero out data when changing Length */ + + hr = IBuffer_put_Length(buffer, 0); + ok(hr == S_OK, "IBuffer_put_Length failed, hr %#lx.\n", hr); + data[0] = 1; + data[10] = 10; + length = 0xdeadbeef; + hr = IBuffer_get_Length(buffer, &length); + ok(hr == S_OK, "IBuffer_get_Length failed, hr %#lx.\n", hr); + ok(length == 0, "IBuffer_get_Length returned length %u.\n", length); + hr = IBuffer_put_Length(buffer, 1); + ok(hr == S_OK, "IBuffer_put_Length failed, hr %#lx.\n", hr); + todo_wine + ok(data[0] == 1, "Buffer returned %#x.\n", data[0]); + todo_wine + ok(data[10] == 10, "Buffer returned %#x.\n", data[10]); + + IBufferByteAccess_Release(buffer_byte_access); +done2: IBuffer_Release(buffer); done: IBufferFactory_Release(buffer_factory);
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=55759 --- dlls/wintypes/buffer.c | 8 ++++++-- dlls/wintypes/tests/wintypes.c | 7 ------- 2 files changed, 6 insertions(+), 9 deletions(-)
diff --git a/dlls/wintypes/buffer.c b/dlls/wintypes/buffer.c index 4e3fdebb151..620cb39709e 100644 --- a/dlls/wintypes/buffer.c +++ b/dlls/wintypes/buffer.c @@ -271,8 +271,12 @@ static ULONG WINAPI buffer_byte_access_Release( IBufferByteAccess *iface )
static HRESULT WINAPI buffer_byte_access_Buffer( IBufferByteAccess *iface, byte **value ) { - FIXME( "iface %p, value %p stub!\n", iface, value ); - return E_NOTIMPL; + struct buffer *impl = impl_from_IBufferByteAccess( iface ); + + TRACE( "iface %p, value %p\n", iface, value ); + + *value = impl->data; + return S_OK; }
static const struct IBufferByteAccessVtbl buffer_byte_access_vtbl = diff --git a/dlls/wintypes/tests/wintypes.c b/dlls/wintypes/tests/wintypes.c index 325833a0588..216e6c0d4cc 100644 --- a/dlls/wintypes/tests/wintypes.c +++ b/dlls/wintypes/tests/wintypes.c @@ -223,9 +223,7 @@ static void test_IBufferStatics(void)
data = NULL; hr = IBufferByteAccess_Buffer(buffer_byte_access, &data); - todo_wine ok(hr == S_OK, "IBufferByteAccess_Buffer failed, hr %#lx.\n", hr); - todo_wine ok(data != NULL, "IBufferByteAccess_Buffer returned NULL data.\n");
IBufferByteAccess_Release(buffer_byte_access); @@ -271,9 +269,7 @@ static void test_IBufferStatics(void) ok(hr == S_OK, "QueryInterface IID_IBufferByteAccess failed, hr %#lx.\n", hr);
hr = IBufferByteAccess_Buffer(buffer_byte_access, &data); - todo_wine ok(hr == S_OK, "IBufferByteAccess_Buffer failed, hr %#lx.\n", hr); - if (hr != S_OK) goto done2;
/* Windows does not zero out data when changing Length */
@@ -287,13 +283,10 @@ static void test_IBufferStatics(void) ok(length == 0, "IBuffer_get_Length returned length %u.\n", length); hr = IBuffer_put_Length(buffer, 1); ok(hr == S_OK, "IBuffer_put_Length failed, hr %#lx.\n", hr); - todo_wine ok(data[0] == 1, "Buffer returned %#x.\n", data[0]); - todo_wine ok(data[10] == 10, "Buffer returned %#x.\n", data[10]);
IBufferByteAccess_Release(buffer_byte_access); -done2: IBuffer_Release(buffer); done: IBufferFactory_Release(buffer_factory);
On Wed Mar 19 07:21:54 2025 +0000, Mohamad Al-Jaf wrote:
I'm not sure what you mean by corner case, the test fails on i386 because 0xdeadbeef is too big of an allocation. In any case, letting malloc handle it makes the check unnecessary.
I meant, is it useful to check memory allocation limits here. I think a test with a smaller, non zero, size to check how capacity and length work would be more reasonable, and less subject to random failures depending on the available RAM.