diff --git a/dlls/webservices/Makefile.in b/dlls/webservices/Makefile.in index 4dc0f7924ae..fa79a68d9eb 100644 --- a/dlls/webservices/Makefile.in +++ b/dlls/webservices/Makefile.in @@ -5,6 +5,7 @@ IMPORTS = winhttp rpcrt4 user32 C_SRCS = \ channel.c \ error.c \ + heap.c \ msg.c \ proxy.c \ reader.c \ diff --git a/dlls/webservices/heap.c b/dlls/webservices/heap.c new file mode 100644 index 00000000000..9e8e0bda6d0 --- /dev/null +++ b/dlls/webservices/heap.c @@ -0,0 +1,356 @@ +/* + * Copyright 2015, 2016 Hans Leidekker for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include + +#include "windef.h" +#include "winbase.h" +#include "winnls.h" +#include "webservices.h" + +#include "wine/debug.h" +#include "wine/list.h" +#include "webservices_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(webservices); + +static const struct prop_desc heap_props[] = +{ + { sizeof(SIZE_T), FALSE }, /* WS_HEAP_PROPERTY_MAX_SIZE */ + { sizeof(SIZE_T), FALSE }, /* WS_HEAP_PROPERTY_TRIM_SIZE */ + { sizeof(SIZE_T), TRUE }, /* WS_HEAP_PROPERTY_REQUESTED_SIZE */ + { sizeof(SIZE_T), TRUE } /* WS_HEAP_PROPERTY_ACTUAL_SIZE */ +}; + +struct heap +{ + ULONG magic; + CRITICAL_SECTION cs; + HANDLE handle; + SIZE_T max_size; + SIZE_T allocated; + ULONG prop_count; + struct prop prop[sizeof(heap_props)/sizeof(heap_props[0])]; +}; + +#define HEAP_MAGIC (('H' << 24) | ('E' << 16) | ('A' << 8) | 'P') + +static BOOL ensure_heap( struct heap *heap ) +{ + SIZE_T size; + if (heap->handle) return TRUE; + prop_get( heap->prop, heap->prop_count, WS_HEAP_PROPERTY_MAX_SIZE, &size, sizeof(size) ); + if (!(heap->handle = HeapCreate( 0, 0, 0 ))) return FALSE; + heap->max_size = size; + heap->allocated = 0; + return TRUE; +} + +void *ws_alloc( WS_HEAP *handle, SIZE_T size ) +{ + struct heap *heap = (struct heap *)handle; + void *ret = NULL; + + EnterCriticalSection( &heap->cs ); + + if (heap->magic != HEAP_MAGIC) goto done; + if (!ensure_heap( heap ) || size > heap->max_size - heap->allocated) goto done; + if ((ret = HeapAlloc( heap->handle, 0, size ))) heap->allocated += size; + +done: + LeaveCriticalSection( &heap->cs ); + return ret; +} + +void *ws_alloc_zero( WS_HEAP *handle, SIZE_T size ) +{ + struct heap *heap = (struct heap *)handle; + void *ret = NULL; + + EnterCriticalSection( &heap->cs ); + + if (heap->magic != HEAP_MAGIC) goto done; + if (!ensure_heap( heap ) || size > heap->max_size - heap->allocated) goto done; + if ((ret = HeapAlloc( heap->handle, HEAP_ZERO_MEMORY, size ))) heap->allocated += size; + +done: + LeaveCriticalSection( &heap->cs ); + return ret; +} + +void *ws_realloc( WS_HEAP *handle, void *ptr, SIZE_T old_size, SIZE_T new_size ) +{ + struct heap *heap = (struct heap *)handle; + void *ret = NULL; + + EnterCriticalSection( &heap->cs ); + + if (heap->magic != HEAP_MAGIC || !ensure_heap( heap )) goto done; + if (new_size >= old_size) + { + SIZE_T size = new_size - old_size; + if (size > heap->max_size - heap->allocated) goto done; + if ((ret = HeapReAlloc( heap->handle, 0, ptr, new_size ))) heap->allocated += size; + } + else + { + SIZE_T size = old_size - new_size; + if ((ret = HeapReAlloc( heap->handle, 0, ptr, new_size ))) heap->allocated -= size; + } + +done: + LeaveCriticalSection( &heap->cs ); + return ret; +} + +void *ws_realloc_zero( WS_HEAP *handle, void *ptr, SIZE_T old_size, SIZE_T new_size ) +{ + struct heap *heap = (struct heap *)handle; + void *ret = NULL; + + EnterCriticalSection( &heap->cs ); + + if (heap->magic != HEAP_MAGIC || !ensure_heap( heap )) goto done; + if (new_size >= old_size) + { + SIZE_T size = new_size - old_size; + if (size > heap->max_size - heap->allocated) goto done; + if ((ret = HeapReAlloc( heap->handle, HEAP_ZERO_MEMORY, ptr, new_size ))) heap->allocated += size; + } + else + { + SIZE_T size = old_size - new_size; + if ((ret = HeapReAlloc( heap->handle, HEAP_ZERO_MEMORY, ptr, new_size ))) heap->allocated -= size; + } + +done: + LeaveCriticalSection( &heap->cs ); + return ret; +} + +void ws_free( WS_HEAP *handle, void *ptr, SIZE_T size ) +{ + struct heap *heap = (struct heap *)handle; + + EnterCriticalSection( &heap->cs ); + + if (heap->magic == HEAP_MAGIC) + { + HeapFree( heap->handle, 0, ptr ); + heap->allocated -= size; + } + + LeaveCriticalSection( &heap->cs ); +} + +/************************************************************************** + * WsAlloc [webservices.@] + */ +HRESULT WINAPI WsAlloc( WS_HEAP *handle, SIZE_T size, void **ptr, WS_ERROR *error ) +{ + void *mem; + + TRACE( "%p %u %p %p\n", handle, (ULONG)size, ptr, error ); + if (error) FIXME( "ignoring error parameter\n" ); + + if (!handle || !ptr) return E_INVALIDARG; + if (!(mem = ws_alloc( handle, size ))) return WS_E_QUOTA_EXCEEDED; + *ptr = mem; + return S_OK; +} + +static struct heap *alloc_heap(void) +{ + static const ULONG count = sizeof(heap_props)/sizeof(heap_props[0]); + struct heap *ret; + ULONG size = sizeof(*ret) + prop_size( heap_props, count ); + + if (!(ret = heap_alloc_zero( size ))) return NULL; + + ret->magic = HEAP_MAGIC; + InitializeCriticalSection( &ret->cs ); + ret->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": heap.cs"); + + prop_init( heap_props, count, ret->prop, &ret[1] ); + ret->prop_count = count; + return ret; +} + +/************************************************************************** + * WsCreateHeap [webservices.@] + */ +HRESULT WINAPI WsCreateHeap( SIZE_T max_size, SIZE_T trim_size, const WS_HEAP_PROPERTY *properties, + ULONG count, WS_HEAP **handle, WS_ERROR *error ) +{ + struct heap *heap; + + TRACE( "%u %u %p %u %p %p\n", (ULONG)max_size, (ULONG)trim_size, properties, count, handle, error ); + if (error) FIXME( "ignoring error parameter\n" ); + + if (!handle || count) return E_INVALIDARG; + if (!(heap = alloc_heap())) return E_OUTOFMEMORY; + + prop_set( heap->prop, heap->prop_count, WS_HEAP_PROPERTY_MAX_SIZE, &max_size, sizeof(max_size) ); + prop_set( heap->prop, heap->prop_count, WS_HEAP_PROPERTY_TRIM_SIZE, &trim_size, sizeof(trim_size) ); + + *handle = (WS_HEAP *)heap; + return S_OK; +} + +static void reset_heap( struct heap *heap ) +{ + HeapDestroy( heap->handle ); + heap->handle = NULL; + heap->max_size = heap->allocated = 0; +} + +/************************************************************************** + * WsFreeHeap [webservices.@] + */ +void WINAPI WsFreeHeap( WS_HEAP *handle ) +{ + struct heap *heap = (struct heap *)handle; + + TRACE( "%p\n", handle ); + + if (!heap) return; + + EnterCriticalSection( &heap->cs ); + + if (heap->magic != HEAP_MAGIC) + { + LeaveCriticalSection( &heap->cs ); + return; + } + + reset_heap( heap ); + heap->magic = 0; + + LeaveCriticalSection( &heap->cs ); + + heap->cs.DebugInfo->Spare[0] = 0; + DeleteCriticalSection( &heap->cs ); + heap_free( heap ); +} + +/************************************************************************** + * WsResetHeap [webservices.@] + */ +HRESULT WINAPI WsResetHeap( WS_HEAP *handle, WS_ERROR *error ) +{ + struct heap *heap = (struct heap *)handle; + + TRACE( "%p %p\n", handle, error ); + if (error) FIXME( "ignoring error parameter\n" ); + + if (!heap) return E_INVALIDARG; + + EnterCriticalSection( &heap->cs ); + + if (heap->magic != HEAP_MAGIC) + { + LeaveCriticalSection( &heap->cs ); + return E_INVALIDARG; + } + + reset_heap( heap ); + + LeaveCriticalSection( &heap->cs ); + return S_OK; +} + +/************************************************************************** + * WsGetHeapProperty [webservices.@] + */ +HRESULT WINAPI WsGetHeapProperty( WS_HEAP *handle, WS_HEAP_PROPERTY_ID id, void *buf, + ULONG size, WS_ERROR *error ) +{ + struct heap *heap = (struct heap *)handle; + HRESULT hr = S_OK; + + TRACE( "%p %u %p %u %p\n", handle, id, buf, size, error ); + if (error) FIXME( "ignoring error parameter\n" ); + + if (!heap) return E_INVALIDARG; + + EnterCriticalSection( &heap->cs ); + + if (heap->magic != HEAP_MAGIC) + { + LeaveCriticalSection( &heap->cs ); + return E_INVALIDARG; + } + + switch (id) + { + case WS_HEAP_PROPERTY_REQUESTED_SIZE: + case WS_HEAP_PROPERTY_ACTUAL_SIZE: + { + SIZE_T *heap_size = buf; + if (!buf || size != sizeof(heap_size)) hr = E_INVALIDARG; + else *heap_size = heap->allocated; + break; + } + default: + hr = prop_get( heap->prop, heap->prop_count, id, buf, size ); + } + + LeaveCriticalSection( &heap->cs ); + return hr; +} + +#define XML_BUFFER_INITIAL_ALLOCATED_SIZE 256 +struct xmlbuf *alloc_xmlbuf( WS_HEAP *heap ) +{ + struct xmlbuf *ret; + + if (!(ret = ws_alloc( heap, sizeof(*ret) ))) return NULL; + if (!(ret->ptr = ws_alloc( heap, XML_BUFFER_INITIAL_ALLOCATED_SIZE ))) + { + ws_free( heap, ret, sizeof(*ret) ); + return NULL; + } + ret->heap = heap; + ret->size_allocated = XML_BUFFER_INITIAL_ALLOCATED_SIZE; + ret->size = 0; + return ret; +} + +void free_xmlbuf( struct xmlbuf *xmlbuf ) +{ + if (!xmlbuf) return; + ws_free( xmlbuf->heap, xmlbuf->ptr, xmlbuf->size_allocated ); + ws_free( xmlbuf->heap, xmlbuf, sizeof(*xmlbuf) ); +} + +/************************************************************************** + * WsCreateXmlBuffer [webservices.@] + */ +HRESULT WINAPI WsCreateXmlBuffer( WS_HEAP *heap, const WS_XML_BUFFER_PROPERTY *properties, + ULONG count, WS_XML_BUFFER **handle, WS_ERROR *error ) +{ + struct xmlbuf *xmlbuf; + + if (!heap || !handle) return E_INVALIDARG; + if (count) FIXME( "properties not implemented\n" ); + + if (!(xmlbuf = alloc_xmlbuf( heap ))) return WS_E_QUOTA_EXCEEDED; + + *handle = (WS_XML_BUFFER *)xmlbuf; + return S_OK; +} diff --git a/dlls/webservices/reader.c b/dlls/webservices/reader.c index 07c645a1e27..6d15002d00c 100644 --- a/dlls/webservices/reader.c +++ b/dlls/webservices/reader.c @@ -70,291 +70,6 @@ HRESULT prop_get( const struct prop *prop, ULONG count, ULONG id, void *buf, ULO return S_OK; } -static const struct prop_desc heap_props[] = -{ - { sizeof(SIZE_T), FALSE }, /* WS_HEAP_PROPERTY_MAX_SIZE */ - { sizeof(SIZE_T), FALSE }, /* WS_HEAP_PROPERTY_TRIM_SIZE */ - { sizeof(SIZE_T), TRUE }, /* WS_HEAP_PROPERTY_REQUESTED_SIZE */ - { sizeof(SIZE_T), TRUE } /* WS_HEAP_PROPERTY_ACTUAL_SIZE */ -}; - -struct heap -{ - ULONG magic; - CRITICAL_SECTION cs; - HANDLE handle; - SIZE_T max_size; - SIZE_T allocated; - ULONG prop_count; - struct prop prop[sizeof(heap_props)/sizeof(heap_props[0])]; -}; - -#define HEAP_MAGIC (('H' << 24) | ('E' << 16) | ('A' << 8) | 'P') - -static BOOL ensure_heap( struct heap *heap ) -{ - SIZE_T size; - if (heap->handle) return TRUE; - prop_get( heap->prop, heap->prop_count, WS_HEAP_PROPERTY_MAX_SIZE, &size, sizeof(size) ); - if (!(heap->handle = HeapCreate( 0, 0, 0 ))) return FALSE; - heap->max_size = size; - heap->allocated = 0; - return TRUE; -} - -void *ws_alloc( WS_HEAP *handle, SIZE_T size ) -{ - struct heap *heap = (struct heap *)handle; - void *ret = NULL; - - EnterCriticalSection( &heap->cs ); - - if (heap->magic != HEAP_MAGIC) goto done; - if (!ensure_heap( heap ) || size > heap->max_size - heap->allocated) goto done; - if ((ret = HeapAlloc( heap->handle, 0, size ))) heap->allocated += size; - -done: - LeaveCriticalSection( &heap->cs ); - return ret; -} - -static void *ws_alloc_zero( WS_HEAP *handle, SIZE_T size ) -{ - struct heap *heap = (struct heap *)handle; - void *ret = NULL; - - EnterCriticalSection( &heap->cs ); - - if (heap->magic != HEAP_MAGIC) goto done; - if (!ensure_heap( heap ) || size > heap->max_size - heap->allocated) goto done; - if ((ret = HeapAlloc( heap->handle, HEAP_ZERO_MEMORY, size ))) heap->allocated += size; - -done: - LeaveCriticalSection( &heap->cs ); - return ret; -} - -void *ws_realloc( WS_HEAP *handle, void *ptr, SIZE_T old_size, SIZE_T new_size ) -{ - struct heap *heap = (struct heap *)handle; - void *ret = NULL; - - EnterCriticalSection( &heap->cs ); - - if (heap->magic != HEAP_MAGIC || !ensure_heap( heap )) goto done; - if (new_size >= old_size) - { - SIZE_T size = new_size - old_size; - if (size > heap->max_size - heap->allocated) goto done; - if ((ret = HeapReAlloc( heap->handle, 0, ptr, new_size ))) heap->allocated += size; - } - else - { - SIZE_T size = old_size - new_size; - if ((ret = HeapReAlloc( heap->handle, 0, ptr, new_size ))) heap->allocated -= size; - } - -done: - LeaveCriticalSection( &heap->cs ); - return ret; -} - -static void *ws_realloc_zero( WS_HEAP *handle, void *ptr, SIZE_T old_size, SIZE_T new_size ) -{ - struct heap *heap = (struct heap *)handle; - void *ret = NULL; - - EnterCriticalSection( &heap->cs ); - - if (heap->magic != HEAP_MAGIC || !ensure_heap( heap )) goto done; - if (new_size >= old_size) - { - SIZE_T size = new_size - old_size; - if (size > heap->max_size - heap->allocated) goto done; - if ((ret = HeapReAlloc( heap->handle, HEAP_ZERO_MEMORY, ptr, new_size ))) heap->allocated += size; - } - else - { - SIZE_T size = old_size - new_size; - if ((ret = HeapReAlloc( heap->handle, HEAP_ZERO_MEMORY, ptr, new_size ))) heap->allocated -= size; - } - -done: - LeaveCriticalSection( &heap->cs ); - return ret; -} - -void ws_free( WS_HEAP *handle, void *ptr, SIZE_T size ) -{ - struct heap *heap = (struct heap *)handle; - - EnterCriticalSection( &heap->cs ); - - if (heap->magic == HEAP_MAGIC) - { - HeapFree( heap->handle, 0, ptr ); - heap->allocated -= size; - } - - LeaveCriticalSection( &heap->cs ); -} - -/************************************************************************** - * WsAlloc [webservices.@] - */ -HRESULT WINAPI WsAlloc( WS_HEAP *handle, SIZE_T size, void **ptr, WS_ERROR *error ) -{ - void *mem; - - TRACE( "%p %u %p %p\n", handle, (ULONG)size, ptr, error ); - if (error) FIXME( "ignoring error parameter\n" ); - - if (!handle || !ptr) return E_INVALIDARG; - if (!(mem = ws_alloc( handle, size ))) return WS_E_QUOTA_EXCEEDED; - *ptr = mem; - return S_OK; -} - -static struct heap *alloc_heap(void) -{ - static const ULONG count = sizeof(heap_props)/sizeof(heap_props[0]); - struct heap *ret; - ULONG size = sizeof(*ret) + prop_size( heap_props, count ); - - if (!(ret = heap_alloc_zero( size ))) return NULL; - - ret->magic = HEAP_MAGIC; - InitializeCriticalSection( &ret->cs ); - ret->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": heap.cs"); - - prop_init( heap_props, count, ret->prop, &ret[1] ); - ret->prop_count = count; - return ret; -} - -/************************************************************************** - * WsCreateHeap [webservices.@] - */ -HRESULT WINAPI WsCreateHeap( SIZE_T max_size, SIZE_T trim_size, const WS_HEAP_PROPERTY *properties, - ULONG count, WS_HEAP **handle, WS_ERROR *error ) -{ - struct heap *heap; - - TRACE( "%u %u %p %u %p %p\n", (ULONG)max_size, (ULONG)trim_size, properties, count, handle, error ); - if (error) FIXME( "ignoring error parameter\n" ); - - if (!handle || count) return E_INVALIDARG; - if (!(heap = alloc_heap())) return E_OUTOFMEMORY; - - prop_set( heap->prop, heap->prop_count, WS_HEAP_PROPERTY_MAX_SIZE, &max_size, sizeof(max_size) ); - prop_set( heap->prop, heap->prop_count, WS_HEAP_PROPERTY_TRIM_SIZE, &trim_size, sizeof(trim_size) ); - - *handle = (WS_HEAP *)heap; - return S_OK; -} - -static void reset_heap( struct heap *heap ) -{ - HeapDestroy( heap->handle ); - heap->handle = NULL; - heap->max_size = heap->allocated = 0; -} - -/************************************************************************** - * WsFreeHeap [webservices.@] - */ -void WINAPI WsFreeHeap( WS_HEAP *handle ) -{ - struct heap *heap = (struct heap *)handle; - - TRACE( "%p\n", handle ); - - if (!heap) return; - - EnterCriticalSection( &heap->cs ); - - if (heap->magic != HEAP_MAGIC) - { - LeaveCriticalSection( &heap->cs ); - return; - } - - reset_heap( heap ); - heap->magic = 0; - - LeaveCriticalSection( &heap->cs ); - - heap->cs.DebugInfo->Spare[0] = 0; - DeleteCriticalSection( &heap->cs ); - heap_free( heap ); -} - -/************************************************************************** - * WsResetHeap [webservices.@] - */ -HRESULT WINAPI WsResetHeap( WS_HEAP *handle, WS_ERROR *error ) -{ - struct heap *heap = (struct heap *)handle; - - TRACE( "%p %p\n", handle, error ); - if (error) FIXME( "ignoring error parameter\n" ); - - if (!heap) return E_INVALIDARG; - - EnterCriticalSection( &heap->cs ); - - if (heap->magic != HEAP_MAGIC) - { - LeaveCriticalSection( &heap->cs ); - return E_INVALIDARG; - } - - reset_heap( heap ); - - LeaveCriticalSection( &heap->cs ); - return S_OK; -} - -/************************************************************************** - * WsGetHeapProperty [webservices.@] - */ -HRESULT WINAPI WsGetHeapProperty( WS_HEAP *handle, WS_HEAP_PROPERTY_ID id, void *buf, - ULONG size, WS_ERROR *error ) -{ - struct heap *heap = (struct heap *)handle; - HRESULT hr = S_OK; - - TRACE( "%p %u %p %u %p\n", handle, id, buf, size, error ); - if (error) FIXME( "ignoring error parameter\n" ); - - if (!heap) return E_INVALIDARG; - - EnterCriticalSection( &heap->cs ); - - if (heap->magic != HEAP_MAGIC) - { - LeaveCriticalSection( &heap->cs ); - return E_INVALIDARG; - } - - switch (id) - { - case WS_HEAP_PROPERTY_REQUESTED_SIZE: - case WS_HEAP_PROPERTY_ACTUAL_SIZE: - { - SIZE_T *heap_size = buf; - if (!buf || size != sizeof(heap_size)) hr = E_INVALIDARG; - else *heap_size = heap->allocated; - break; - } - default: - hr = prop_get( heap->prop, heap->prop_count, id, buf, size ); - } - - LeaveCriticalSection( &heap->cs ); - return hr; -} - struct node *alloc_node( WS_XML_NODE_TYPE type ) { struct node *ret; diff --git a/dlls/webservices/webservices_private.h b/dlls/webservices/webservices_private.h index a70f7d5d4f4..e93b03ebe18 100644 --- a/dlls/webservices/webservices_private.h +++ b/dlls/webservices/webservices_private.h @@ -27,8 +27,13 @@ struct xmlbuf }; void *ws_alloc( WS_HEAP *, SIZE_T ) DECLSPEC_HIDDEN; +void *ws_alloc_zero( WS_HEAP *, SIZE_T ) DECLSPEC_HIDDEN; void *ws_realloc( WS_HEAP *, void *, SIZE_T, SIZE_T ) DECLSPEC_HIDDEN; +void *ws_realloc_zero( WS_HEAP *, void *, SIZE_T, SIZE_T ) DECLSPEC_HIDDEN; void ws_free( WS_HEAP *, void *, SIZE_T ) DECLSPEC_HIDDEN; +struct xmlbuf *alloc_xmlbuf( WS_HEAP * ) DECLSPEC_HIDDEN; +void free_xmlbuf( struct xmlbuf * ) DECLSPEC_HIDDEN; + const char *debugstr_xmlstr( const WS_XML_STRING * ) DECLSPEC_HIDDEN; WS_XML_STRING *alloc_xml_string( const unsigned char *, ULONG ) DECLSPEC_HIDDEN; WS_XML_UTF8_TEXT *alloc_utf8_text( const unsigned char *, ULONG ) DECLSPEC_HIDDEN; diff --git a/dlls/webservices/writer.c b/dlls/webservices/writer.c index 4736c07e0b3..0ea9ac14baf 100644 --- a/dlls/webservices/writer.c +++ b/dlls/webservices/writer.c @@ -252,47 +252,6 @@ void WINAPI WsFreeWriter( WS_XML_WRITER *handle ) free_writer( writer ); } -#define XML_BUFFER_INITIAL_ALLOCATED_SIZE 256 -static struct xmlbuf *alloc_xmlbuf( WS_HEAP *heap ) -{ - struct xmlbuf *ret; - - if (!(ret = ws_alloc( heap, sizeof(*ret) ))) return NULL; - if (!(ret->ptr = ws_alloc( heap, XML_BUFFER_INITIAL_ALLOCATED_SIZE ))) - { - ws_free( heap, ret, sizeof(*ret) ); - return NULL; - } - ret->heap = heap; - ret->size_allocated = XML_BUFFER_INITIAL_ALLOCATED_SIZE; - ret->size = 0; - return ret; -} - -static void free_xmlbuf( struct xmlbuf *xmlbuf ) -{ - if (!xmlbuf) return; - ws_free( xmlbuf->heap, xmlbuf->ptr, xmlbuf->size_allocated ); - ws_free( xmlbuf->heap, xmlbuf, sizeof(*xmlbuf) ); -} - -/************************************************************************** - * WsCreateXmlBuffer [webservices.@] - */ -HRESULT WINAPI WsCreateXmlBuffer( WS_HEAP *heap, const WS_XML_BUFFER_PROPERTY *properties, - ULONG count, WS_XML_BUFFER **handle, WS_ERROR *error ) -{ - struct xmlbuf *xmlbuf; - - if (!heap || !handle) return E_INVALIDARG; - if (count) FIXME( "properties not implemented\n" ); - - if (!(xmlbuf = alloc_xmlbuf( heap ))) return WS_E_QUOTA_EXCEEDED; - - *handle = (WS_XML_BUFFER *)xmlbuf; - return S_OK; -} - /************************************************************************** * WsGetWriterProperty [webservices.@] */