From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- dlls/wintypes/buffer.c | 150 ++++++++++++++++++++++++++++++++- dlls/wintypes/tests/wintypes.c | 4 - 2 files changed, 148 insertions(+), 6 deletions(-)
diff --git a/dlls/wintypes/buffer.c b/dlls/wintypes/buffer.c index a5dc7d2d1f7..a80397bfd5d 100644 --- a/dlls/wintypes/buffer.c +++ b/dlls/wintypes/buffer.c @@ -17,6 +17,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
+#include <stdint.h> + #include "private.h"
WINE_DEFAULT_DEBUG_CHANNEL(wintypes); @@ -114,12 +116,156 @@ static const struct IActivationFactoryVtbl factory_vtbl = factory_ActivateInstance, };
+struct buffer +{ + IBuffer IBuffer_iface; + LONG ref; + + UINT32 capacity; + UINT32 length; + BYTE *data; +}; + +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->data ); + 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 UINT32 get_max_capacity(void) +{ + SYSTEM_INFO sys_info; + UINT_PTR max_addr; + BOOL is_wow64; + + IsWow64Process( GetCurrentProcess(), &is_wow64 ); + if (is_wow64) return 0x7FFEFFFF; + + GetNativeSystemInfo( &sys_info ); + max_addr = (UINT_PTR)sys_info.lpMaximumApplicationAddress; + + return (max_addr > UINT32_MAX) ? UINT32_MAX : max_addr; +} + 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 (capacity > get_max_capacity() || !(impl = calloc( 1, sizeof( *impl ) ))) return E_OUTOFMEMORY; + + impl->IBuffer_iface.lpVtbl = &buffer_vtbl; + impl->ref = 1; + impl->capacity = capacity; + impl->length = 0; + if (!(impl->data = malloc( capacity ))) + { + free( impl ); + return E_OUTOFMEMORY; + } + + *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 727c36511f3..f759744e754 100644 --- a/dlls/wintypes/tests/wintypes.c +++ b/dlls/wintypes/tests/wintypes.c @@ -188,9 +188,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);
@@ -230,11 +228,9 @@ static void test_IBufferStatics(void) max_capacity = get_max_capacity(); buffer = (void *)0xdeadbeef; hr = IBufferFactory_Create(buffer_factory, capacity, &buffer); - todo_wine ok(hr == S_OK || (hr == E_OUTOFMEMORY && capacity > max_capacity), "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; }