The MR adds implementations (+ a few tests) for the following methods in `bluetoothapis.h`:
* `BluetoothSdpEnumAttributes` * `BluetoothSdpGetContainerElementData` * `BluetoothSdpGetElementData` * `BluetoothSdpGetAttributeValue`
-- v22: bluetoothapis: Implement BluetoothSdpGetAttributeValue. bluetoothapis/tests: Add tests for BluetoothSdpGetAttributeValue. bluetoothapis: Add stub for BluetoothSdpGetAttributeValue. bluetoothapis: Implement BluetoothSdpEnumAttributes. bluetoothapis/tests: Add tests for BluetoothSdpEnumAttributes. bluetoothapis: Add stub for BluetoothSdpEnumAttributes. bluetoothapis: Implement BluetoothSdpGetContainerElementData. bluetoothapis/tests: Add tests for BluetoothSdpGetContainerElementData. bluetoothapis: Add stub for BluetoothSdpGetContainerElementData. bluetoothapis: Implement BluetoothSdpGetElementData. bluetoothapis/tests: Add tests for BluetoothSdpGetElementData.
From: Vibhav Pant vibhavp@gmail.com
--- dlls/bluetoothapis/Makefile.in | 3 +- dlls/bluetoothapis/bluetoothapis.spec | 2 +- dlls/bluetoothapis/sdp.c | 40 +++++++++++++++++++++++++++ dlls/bthprops.cpl/bthprops.cpl.spec | 2 +- dlls/irprops.cpl/irprops.cpl.spec | 2 +- 5 files changed, 45 insertions(+), 4 deletions(-) create mode 100644 dlls/bluetoothapis/sdp.c
diff --git a/dlls/bluetoothapis/Makefile.in b/dlls/bluetoothapis/Makefile.in index 78518822519..1fd74074703 100644 --- a/dlls/bluetoothapis/Makefile.in +++ b/dlls/bluetoothapis/Makefile.in @@ -4,4 +4,5 @@ IMPORTLIB = bluetoothapis EXTRADLLFLAGS = -Wb,--prefer-native
SOURCES = \ - main.c + main.c \ + sdp.c diff --git a/dlls/bluetoothapis/bluetoothapis.spec b/dlls/bluetoothapis/bluetoothapis.spec index 625dffb8254..a35e1e22ecc 100644 --- a/dlls/bluetoothapis/bluetoothapis.spec +++ b/dlls/bluetoothapis/bluetoothapis.spec @@ -56,7 +56,7 @@ @ stub BluetoothSdpEnumAttributes @ stub BluetoothSdpGetAttributeValue @ stub BluetoothSdpGetContainerElementData -@ stub BluetoothSdpGetElementData +@ stdcall BluetoothSdpGetElementData(ptr long ptr) @ stub BluetoothSdpGetString @ stub BluetoothSendAuthenticationResponse @ stub BluetoothSendAuthenticationResponseEx diff --git a/dlls/bluetoothapis/sdp.c b/dlls/bluetoothapis/sdp.c new file mode 100644 index 00000000000..e3c6b27afc2 --- /dev/null +++ b/dlls/bluetoothapis/sdp.c @@ -0,0 +1,40 @@ +/* + * SDP APIs + * + * Copyright 2024 Vibhav Pant + * + * 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 <stdarg.h> +#include <windef.h> +#include <winbase.h> +#include <winternl.h> + +#include "wine/debug.h" +#include "bthsdpdef.h" +#include "bluetoothapis.h" + +WINE_DEFAULT_DEBUG_CHANNEL( bluetoothapis ); + +/********************************************************************* + * BluetoothSdpGetElementData + */ +DWORD WINAPI BluetoothSdpGetElementData( BYTE *stream, ULONG stream_size, SDP_ELEMENT_DATA *data ) +{ + FIXME( "(%p, %lu, %p) stub!\n", stream, stream_size, data ); + return ERROR_CALL_NOT_IMPLEMENTED; +} diff --git a/dlls/bthprops.cpl/bthprops.cpl.spec b/dlls/bthprops.cpl/bthprops.cpl.spec index 1698344581e..0bef83810db 100644 --- a/dlls/bthprops.cpl/bthprops.cpl.spec +++ b/dlls/bthprops.cpl/bthprops.cpl.spec @@ -47,7 +47,7 @@ @ stub BluetoothSdpEnumAttributes @ stub BluetoothSdpGetAttributeValue @ stub BluetoothSdpGetContainerElementData -@ stub BluetoothSdpGetElementData +@ stdcall -import BluetoothSdpGetElementData(ptr long ptr) @ stub BluetoothSdpGetString @ stub BluetoothSelectDevices @ stub BluetoothSelectDevicesFree diff --git a/dlls/irprops.cpl/irprops.cpl.spec b/dlls/irprops.cpl/irprops.cpl.spec index b2bdf3c3b2a..c9cd4df62d6 100644 --- a/dlls/irprops.cpl/irprops.cpl.spec +++ b/dlls/irprops.cpl/irprops.cpl.spec @@ -41,7 +41,7 @@ @ stub BluetoothSdpEnumAttributes @ stub BluetoothSdpGetAttributeValue @ stub BluetoothSdpGetContainerElementData -@ stub BluetoothSdpGetElementData +@ stdcall -import BluetoothSdpGetElementData(ptr long ptr) @ stub BluetoothSdpGetString @ stub BluetoothSelectDevices @ stub BluetoothSelectDevicesFree
From: Vibhav Pant vibhavp@gmail.com
--- configure.ac | 1 + dlls/bluetoothapis/tests/Makefile.in | 5 + dlls/bluetoothapis/tests/sdp.c | 284 +++++++++++++++++++++++++++ 3 files changed, 290 insertions(+) create mode 100644 dlls/bluetoothapis/tests/Makefile.in create mode 100644 dlls/bluetoothapis/tests/sdp.c
diff --git a/configure.ac b/configure.ac index d729fb56b89..c0a7d364f86 100644 --- a/configure.ac +++ b/configure.ac @@ -2415,6 +2415,7 @@ WINE_CONFIG_MAKEFILE(dlls/bcrypt) WINE_CONFIG_MAKEFILE(dlls/bcrypt/tests) WINE_CONFIG_MAKEFILE(dlls/bcryptprimitives) WINE_CONFIG_MAKEFILE(dlls/bluetoothapis) +WINE_CONFIG_MAKEFILE(dlls/bluetoothapis/tests) WINE_CONFIG_MAKEFILE(dlls/browseui) WINE_CONFIG_MAKEFILE(dlls/browseui/tests) WINE_CONFIG_MAKEFILE(dlls/bthprops.cpl) diff --git a/dlls/bluetoothapis/tests/Makefile.in b/dlls/bluetoothapis/tests/Makefile.in new file mode 100644 index 00000000000..c2e8bc0377a --- /dev/null +++ b/dlls/bluetoothapis/tests/Makefile.in @@ -0,0 +1,5 @@ +TESTDLL = bluetoothapis.dll +IMPORTS = bluetoothapis + +SOURCES = \ + sdp.c diff --git a/dlls/bluetoothapis/tests/sdp.c b/dlls/bluetoothapis/tests/sdp.c new file mode 100644 index 00000000000..6aead0d2883 --- /dev/null +++ b/dlls/bluetoothapis/tests/sdp.c @@ -0,0 +1,284 @@ +/* Tests for bluetoothapis.dll's SDP API + * + * Copyright 2024 Vibhav Pant + * + * 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 <stdarg.h> +#include <windef.h> +#include <winbase.h> + +#include "bthsdpdef.h" +#include "bluetoothapis.h" + +#include "wine/test.h" + +static const char *debugstr_SDP_ELEMENT_DATA( const SDP_ELEMENT_DATA *data ) +{ + return wine_dbg_sprintf( "{%#x %#x {%llu %llu}}", data->type, data->specificType, + data->data.uint128.LowPart, data->data.uint128.HighPart ); +} + +static void test_BluetoothSdpGetElementData( BYTE *stream, SIZE_T size, DWORD error, + const SDP_ELEMENT_DATA *sdp_data ) +{ + DWORD ret; + SDP_ELEMENT_DATA result = {0}; + + ret = BluetoothSdpGetElementData( stream, size, &result ); + ok( ret == error, "%ld != %ld.\n", error, ret ); + if (ret == error && error == ERROR_SUCCESS) + { + ok( result.type == sdp_data->type, "%#x != %#x.\n", sdp_data->type, result.type ); + ok( result.specificType == sdp_data->specificType, + "%#x != %#x.\n", sdp_data->specificType, + result.specificType ); + ok( !memcmp( &sdp_data->data, &result.data, sizeof( result.data ) ), + "%s != %s.\n", debugstr_SDP_ELEMENT_DATA( sdp_data ), + debugstr_SDP_ELEMENT_DATA( &result ) ); + } +} + +#define TEST_CASE_NAME( n ) ("%s %d"), __func__, (int)(n) + +static void test_BluetoothSdpGetElementData_invalid( void ) +{ + SDP_ELEMENT_DATA data; + BYTE stream[] = {0}; + DWORD ret; + + ret = BluetoothSdpGetElementData( NULL, 10, &data ); + todo_wine ok( ret == ERROR_INVALID_PARAMETER, "%d != %ld.\n", ERROR_INVALID_PARAMETER, ret ); + + ret = BluetoothSdpGetElementData( stream, 1, NULL ); + todo_wine ok( ret == ERROR_INVALID_PARAMETER, "%d != %ld.\n", ERROR_INVALID_PARAMETER, ret ); + + ret = BluetoothSdpGetElementData( stream, 0, &data ); + todo_wine ok( ret == ERROR_INVALID_PARAMETER, "%d != %ld.\n", ERROR_INVALID_PARAMETER, ret ); + + ret = BluetoothSdpGetElementData( NULL, 0, NULL ); + todo_wine ok( ret == ERROR_INVALID_PARAMETER, "%d != %ld.\n", ERROR_INVALID_PARAMETER, ret ); +} + +static void test_BluetoothSdpGetElementData_nil( void ) +{ + static struct + { + BYTE data_elem; + DWORD error; + SDP_ELEMENT_DATA data; + } test_cases[] = { + {0x0, ERROR_SUCCESS, {.type = SDP_TYPE_NIL, .specificType = SDP_ST_NONE }}, + {0x1, ERROR_INVALID_PARAMETER}, + {0x3, ERROR_INVALID_PARAMETER}, + {0x4, ERROR_INVALID_PARAMETER}, + }; + SIZE_T i; + + for (i = 0; i < ARRAY_SIZE( test_cases ); i++) + { + winetest_push_context(TEST_CASE_NAME( i )); + todo_wine test_BluetoothSdpGetElementData( &test_cases[i].data_elem, 1, test_cases[i].error, + &test_cases[i].data ); + winetest_pop_context(); + } +} + +#define SDP_SIZE_DESC_1_BYTE 0 +#define SDP_SIZE_DESC_2_BYTES 1 +#define SDP_SIZE_DESC_4_BYTES 2 +#define SDP_SIZE_DESC_8_BYTES 3 +#define SDP_SIZE_DESC_16_BYTES 4 +#define SDP_SIZE_DESC_NEXT_UINT8 5 +#define SDP_SIZE_DESC_NEXT_UINT16 6 +#define SDP_SIZE_DESC_NEXT_UINT32 7 + +#define SDP_DATA_ELEM_TYPE_DESC(t,s) ((t) << 3 | SDP_SIZE_DESC_##s) + +#define SDP_DEF_TYPE(n, t, s) const static BYTE SDP_TYPE_DESC_##n = SDP_DATA_ELEM_TYPE_DESC(SDP_TYPE_##t, s) +#define SDP_DEF_INTEGRAL( w, s ) \ + SDP_DEF_TYPE( INT##w, INT, s ); \ + SDP_DEF_TYPE( UINT##w, UINT, s); + +SDP_DEF_INTEGRAL( 8, 1_BYTE ); +SDP_DEF_INTEGRAL( 16, 2_BYTES ); +SDP_DEF_INTEGRAL( 32, 4_BYTES ); +SDP_DEF_INTEGRAL( 64, 8_BYTES ); +SDP_DEF_INTEGRAL( 128, 16_BYTES ); + +SDP_DEF_TYPE( STR8, STRING, NEXT_UINT8 ); +SDP_DEF_TYPE( STR16, STRING, NEXT_UINT16 ); +SDP_DEF_TYPE( STR32, STRING, NEXT_UINT32 ); + +static void test_BluetoothSdpGetElementData_ints( void ) +{ + static struct + { + BYTE data_elem[17]; + SIZE_T size; + DWORD error; + SDP_ELEMENT_DATA data; + } test_cases[] = { + { + {SDP_TYPE_DESC_INT8, 0xde}, + 2, + ERROR_SUCCESS, + {SDP_TYPE_INT, SDP_ST_INT8, {.int8 = 0xde}} + }, + { + {SDP_TYPE_DESC_UINT8, 0xde}, + 2, + ERROR_SUCCESS, + {SDP_TYPE_UINT, SDP_ST_UINT8, {.uint8 = 0xde}}, + }, + { + {SDP_TYPE_DESC_INT16, 0xde, 0xad}, + 3, + ERROR_SUCCESS, + {SDP_TYPE_INT, SDP_ST_INT16, {.int16 = 0xdead}}, + }, + { + {SDP_TYPE_DESC_UINT16, 0xde, 0xad }, + 3, + ERROR_SUCCESS, + {SDP_TYPE_UINT, SDP_ST_UINT16, {.uint16 = 0xdead}}, + }, + { + {SDP_TYPE_DESC_INT32, 0xde, 0xad, 0xbe, 0xef}, + 5, + ERROR_SUCCESS, + {SDP_TYPE_INT, SDP_ST_INT32, {.int32 = 0xdeadbeef}}, + }, + { + {SDP_TYPE_DESC_UINT32, 0xde, 0xad, 0xbe, 0xef}, + 5, + ERROR_SUCCESS, + {SDP_TYPE_UINT, SDP_ST_UINT32, {.uint32 = 0xdeadbeef}}, + }, + { + {SDP_TYPE_DESC_INT64, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef}, + 9, + ERROR_SUCCESS, + {SDP_TYPE_INT, SDP_ST_INT64, {.int64 = 0xdeadbeefdeadbeef}}, + }, + { + {SDP_TYPE_DESC_UINT64, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef}, + 9, + ERROR_SUCCESS, + {SDP_TYPE_UINT, SDP_ST_UINT64, {.uint64 = 0xdeadbeefdeadbeef}}, + }, + { + {SDP_TYPE_DESC_INT64, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef}, + 9, + ERROR_SUCCESS, + {SDP_TYPE_INT, SDP_ST_INT64, {.int64 = 0xdeadbeefdeadbeef}}, + }, + { + {SDP_TYPE_DESC_UINT64, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef}, + 9, + ERROR_SUCCESS, + {SDP_TYPE_UINT, SDP_ST_UINT64, {.uint64 = 0xdeadbeefdeadbeef}}, + }, + { + {SDP_TYPE_DESC_INT128, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef }, + 17, + ERROR_SUCCESS, + {SDP_TYPE_INT, SDP_ST_INT128, {.int128 = {0xdeadbeefdeadbeef, 0xdeadbeefdeadbeef}}}, + }, + { + {SDP_TYPE_DESC_UINT128, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef}, + 17, + ERROR_SUCCESS, + {SDP_TYPE_UINT, SDP_ST_UINT128, {.uint128 = {0xdeadbeefdeadbeef, 0xdeadbeefdeadbeef}}}, + } + }; + SIZE_T i; + + for (i = 0; i < ARRAY_SIZE( test_cases ); i++) + { + winetest_push_context( TEST_CASE_NAME( i ) ); + todo_wine test_BluetoothSdpGetElementData( test_cases[i].data_elem, test_cases[i].size, + test_cases[i].error, &test_cases[i].data ); + winetest_pop_context(); + } +} + +static void test_BluetoothSdpGetElementData_str( void ) +{ + static struct { + BYTE stream[11]; + SIZE_T size; + DWORD error; + SDP_ELEMENT_DATA data; + const char *string; + } test_cases[] = { + { + {SDP_TYPE_DESC_STR8, 0x06, 'f', 'o', 'o', 'b', 'a', 'r'}, + 8, + ERROR_SUCCESS, + {SDP_TYPE_STRING, SDP_ST_NONE, {.string = {&test_cases[0].stream[2], 6}}}, + "foobar", + }, + { + {SDP_TYPE_DESC_STR16, 0x00, 0x06, 'f', 'o', 'o', 'b', 'a', 'r'}, + 9, + ERROR_SUCCESS, + {SDP_TYPE_STRING, SDP_ST_NONE, {.string = {&test_cases[1].stream[3], 6}}}, + "foobar", + }, + { + {SDP_TYPE_DESC_STR32, 0x00, 0x00, 0x00, 0x06, 'f', 'o', 'o', 'b', 'a', 'r'}, + 11, + ERROR_SUCCESS, + {SDP_TYPE_STRING, SDP_ST_NONE, {.string = {&test_cases[2].stream[5], 6}}}, + "foobar", + } + }; + SIZE_T i; + + for (i = 0; i < ARRAY_SIZE( test_cases ); i++) + { + winetest_push_context( TEST_CASE_NAME( i ) ); + todo_wine test_BluetoothSdpGetElementData( test_cases[i].stream, test_cases[i].size, + test_cases[i].error, &test_cases[i].data ); + if (test_cases[i].error == ERROR_SUCCESS) + { + SDP_ELEMENT_DATA result = {0}; + if (!BluetoothSdpGetElementData( test_cases[i].stream, test_cases[i].size, &result )) + { + todo_wine ok( strlen( test_cases[i].string ) == result.data.string.length, + "%s != %s.\n", debugstr_a( test_cases[i].string ), + debugstr_an( (const char *)result.data.string.value, + result.data.string.length ) ); + todo_wine ok( !memcmp( result.data.string.value, test_cases[i].string, + result.data.string.length ), + "%s != %s.\n", debugstr_a( test_cases[i].string ), + debugstr_an( (const char *)result.data.string.value, + result.data.string.length ) ); + } + } + winetest_pop_context(); + } +} + +START_TEST( sdp ) +{ + test_BluetoothSdpGetElementData_nil(); + test_BluetoothSdpGetElementData_ints(); + test_BluetoothSdpGetElementData_invalid(); + test_BluetoothSdpGetElementData_str(); +}
From: Vibhav Pant vibhavp@gmail.com
--- dlls/bluetoothapis/sdp.c | 228 ++++++++++++++++++++++++++++++++- dlls/bluetoothapis/tests/sdp.c | 38 +++--- 2 files changed, 245 insertions(+), 21 deletions(-)
diff --git a/dlls/bluetoothapis/sdp.c b/dlls/bluetoothapis/sdp.c index e3c6b27afc2..0b87e9488da 100644 --- a/dlls/bluetoothapis/sdp.c +++ b/dlls/bluetoothapis/sdp.c @@ -30,11 +30,235 @@
WINE_DEFAULT_DEBUG_CHANNEL( bluetoothapis );
+#ifdef WORDS_BIGENDIAN +#define BTH_READ_UINT16( s ) (s) +#define BTH_READ_UINT32( s ) (s) +#define BTH_READ_UINT64( s ) (s) +#else +#define BTH_READ_UINT16( s ) RtlUshortByteSwap( *(USHORT *)(s) ) +#define BTH_READ_UINT32( s ) RtlUlongByteSwap( *(ULONG *)(s) ) +#define BTH_READ_UINT64( s ) RtlUlonglongByteSwap( *(ULONGLONG *)(s) ) +#endif + +#define SDP_SIZE_DESC_1_BYTE 0 +#define SDP_SIZE_DESC_2_BYTES 1 +#define SDP_SIZE_DESC_4_BYTES 2 +#define SDP_SIZE_DESC_8_BYTES 3 +#define SDP_SIZE_DESC_16_BYTES 4 +#define SDP_SIZE_DESC_NEXT_UINT8 5 +#define SDP_SIZE_DESC_NEXT_UINT16 6 +#define SDP_SIZE_DESC_NEXT_UINT32 7 + +static void bth_read_uint128( BYTE *s, SDP_ULARGE_INTEGER_16 *v ) +{ + v->HighPart = BTH_READ_UINT64( s ); + v->LowPart = BTH_READ_UINT64( s + 8 ); +} + +static BYTE data_elem_type( BYTE elem ) { return (elem & 0xf8) >> 3; } +static BYTE data_elem_size_desc( BYTE elem ) { return elem & 0x7; } + +#define SDP_ELEMENT_IS_UINT16( d ) ( (d)->type == SDP_TYPE_UINT && (d)->specificType == SDP_ST_UINT16 ) +#define SDP_ELEMENT_IS_ATTRID( d ) SDP_ELEMENT_IS_UINT16((d)) + +/* Read the data element's size/length as described by the size descriptor, starting from stream. Only + * valid for SDP_SIZE_DESC_NEXT_* types. */ +static BOOL sdp_elem_read_var_size( BYTE *stream, ULONG stream_size, SIZE_T *read, BYTE size_desc, + UINT32 *size ) +{ + switch (size_desc) + { + case SDP_SIZE_DESC_NEXT_UINT8: + if (stream_size < sizeof( UINT8 )) return FALSE; + *size = *stream; + *read += sizeof( UINT8 ); + return TRUE; + case SDP_SIZE_DESC_NEXT_UINT16: + if (stream_size < sizeof( UINT16 )) return FALSE; + *size = BTH_READ_UINT16( stream ); + *read += sizeof( UINT16 ); + return TRUE; + case SDP_SIZE_DESC_NEXT_UINT32: + if (stream_size < sizeof( UINT32 )) return FALSE; + *size = BTH_READ_UINT32( stream ); + *read += sizeof( UINT32 ); + return TRUE; + default: + return FALSE; + } +} + +const static SDP_SPECIFICTYPE SDP_BASIC_TYPES[4][5] = { + [SDP_TYPE_UINT] = + { + [SDP_SIZE_DESC_1_BYTE] = SDP_ST_UINT8, + [SDP_SIZE_DESC_2_BYTES] = SDP_ST_UINT16, + [SDP_SIZE_DESC_4_BYTES] = SDP_ST_UINT32, + [SDP_SIZE_DESC_8_BYTES] = SDP_ST_UINT64, + [SDP_SIZE_DESC_16_BYTES] = SDP_ST_UINT128, + }, + [SDP_TYPE_INT] = + { + [SDP_SIZE_DESC_1_BYTE] = SDP_ST_INT8, + [SDP_SIZE_DESC_2_BYTES] = SDP_ST_INT16, + [SDP_SIZE_DESC_4_BYTES] = SDP_ST_INT32, + [SDP_SIZE_DESC_8_BYTES] = SDP_ST_INT64, + [SDP_SIZE_DESC_16_BYTES] = SDP_ST_INT128, + }, + [SDP_TYPE_UUID] = + { + [SDP_SIZE_DESC_2_BYTES] = SDP_ST_UUID16, + [SDP_SIZE_DESC_4_BYTES] = SDP_ST_UUID32, + [SDP_SIZE_DESC_16_BYTES] = SDP_ST_UUID128, + }, +}; + +static BOOL sdp_read_specific_type( BYTE *stream, ULONG stream_size, SDP_SPECIFICTYPE st, + SDP_ELEMENT_DATA *data, SIZE_T *read ) +{ + switch (st) + { + case SDP_ST_UINT8: + case SDP_ST_INT8: + if (stream_size < sizeof( UINT8 )) return FALSE; + data->data.uint8 = *stream; + *read += sizeof( UINT8 ); + break; + case SDP_ST_UINT16: + case SDP_ST_INT16: + case SDP_ST_UUID16: + if (stream_size < sizeof( UINT16 )) return FALSE; + data->data.uint16 = BTH_READ_UINT16( stream ); + *read += sizeof( UINT16 ); + break; + case SDP_ST_UINT32: + case SDP_ST_INT32: + if (stream_size < sizeof( UINT32 )) return FALSE; + data->data.uint32 = BTH_READ_UINT32( stream ); + *read += sizeof( UINT32 ); + break; + case SDP_ST_UINT64: + case SDP_ST_INT64: + if (stream_size < sizeof( UINT64 )) return FALSE; + data->data.uint64 = BTH_READ_UINT64( stream ); + *read += sizeof( UINT64 ); + break; + case SDP_ST_UINT128: + case SDP_ST_INT128: + case SDP_ST_UUID128: + if (stream_size < sizeof( SDP_ULARGE_INTEGER_16 )) return FALSE; + bth_read_uint128( stream, &data->data.uint128 ); + *read += sizeof( SDP_ULARGE_INTEGER_16 ); + break; + default: + return FALSE; + } + + return TRUE; +} + +static DWORD sdp_read_element_data( BYTE *stream, ULONG stream_size, SDP_ELEMENT_DATA *data, + SIZE_T *read ) +{ + BYTE type, size_desc, elem; + SDP_SPECIFICTYPE st; + + if (stream_size < sizeof( BYTE )) return ERROR_INVALID_PARAMETER; + + elem = *stream; + type = data_elem_type( elem ); + size_desc = data_elem_size_desc( elem ); + + stream += sizeof( BYTE ); + *read += sizeof( BYTE ); + stream_size -= sizeof( BYTE ); + + memset( data, 0, sizeof( *data ) ); + switch (type) + { + case SDP_TYPE_NIL: + if (size_desc != 0) return ERROR_INVALID_PARAMETER; + + data->type = type; + data->specificType = SDP_ST_NONE; + break; + case SDP_TYPE_UINT: + case SDP_TYPE_INT: + case SDP_TYPE_UUID: + if (size_desc > SDP_SIZE_DESC_16_BYTES) return ERROR_INVALID_PARAMETER; + + st = SDP_BASIC_TYPES[type][size_desc]; + if (st == SDP_ST_NONE) return ERROR_INVALID_PARAMETER; + + if (!sdp_read_specific_type( stream, stream_size, st, data, read )) + return ERROR_INVALID_PARAMETER; + + data->type = type; + data->specificType = st; + break; + case SDP_TYPE_BOOLEAN: + if (size_desc != SDP_SIZE_DESC_1_BYTE) return ERROR_INVALID_PARAMETER; + if (stream_size < sizeof( BYTE )) return ERROR_INVALID_PARAMETER; + + data->type = type; + data->specificType = SDP_ST_NONE; + data->data.booleanVal = *stream; + *read += sizeof( BYTE ); + break; + case SDP_TYPE_STRING: + case SDP_TYPE_URL: + case SDP_TYPE_SEQUENCE: + case SDP_TYPE_ALTERNATIVE: + { + UINT32 elems_size; + SIZE_T size_read = 0; + + if (!(size_desc >= SDP_SIZE_DESC_NEXT_UINT8 && size_desc <= SDP_SIZE_DESC_NEXT_UINT32)) + return ERROR_INVALID_PARAMETER; + if (!sdp_elem_read_var_size( stream, stream_size, &size_read, size_desc, &elems_size )) + return ERROR_INVALID_PARAMETER; + + stream_size -= size_read; + if (type == SDP_TYPE_STRING || type == SDP_TYPE_URL) + stream += size_read; + + if (stream_size < elems_size) return ERROR_INVALID_PARAMETER; + + data->type = type; + data->specificType = SDP_ST_NONE; + if (type == SDP_TYPE_STRING || type == SDP_TYPE_URL) + { + data->data.string.value = stream; + data->data.string.length = elems_size; + } + else + { + /* For sequence and alternative containers, the stream should begin at the container + * header. */ + data->data.sequence.value = stream - sizeof( BYTE ); + data->data.sequence.length = elems_size + *read + size_read; + } + *read += size_read + elems_size; + break; + } + default: + return ERROR_INVALID_PARAMETER; + } + + return ERROR_SUCCESS; +} + /********************************************************************* * BluetoothSdpGetElementData */ DWORD WINAPI BluetoothSdpGetElementData( BYTE *stream, ULONG stream_size, SDP_ELEMENT_DATA *data ) { - FIXME( "(%p, %lu, %p) stub!\n", stream, stream_size, data ); - return ERROR_CALL_NOT_IMPLEMENTED; + SIZE_T read = 0; + + TRACE( "(%p, %lu, %p)\n", stream, stream_size, data ); + + if (stream == NULL || stream_size < sizeof( BYTE ) || data == NULL) + return ERROR_INVALID_PARAMETER; + + return sdp_read_element_data( stream, stream_size, data, &read ); } diff --git a/dlls/bluetoothapis/tests/sdp.c b/dlls/bluetoothapis/tests/sdp.c index 6aead0d2883..47c5bd46615 100644 --- a/dlls/bluetoothapis/tests/sdp.c +++ b/dlls/bluetoothapis/tests/sdp.c @@ -62,16 +62,16 @@ static void test_BluetoothSdpGetElementData_invalid( void ) DWORD ret;
ret = BluetoothSdpGetElementData( NULL, 10, &data ); - todo_wine ok( ret == ERROR_INVALID_PARAMETER, "%d != %ld.\n", ERROR_INVALID_PARAMETER, ret ); + ok( ret == ERROR_INVALID_PARAMETER, "%d != %ld.\n", ERROR_INVALID_PARAMETER, ret );
ret = BluetoothSdpGetElementData( stream, 1, NULL ); - todo_wine ok( ret == ERROR_INVALID_PARAMETER, "%d != %ld.\n", ERROR_INVALID_PARAMETER, ret ); + ok( ret == ERROR_INVALID_PARAMETER, "%d != %ld.\n", ERROR_INVALID_PARAMETER, ret );
ret = BluetoothSdpGetElementData( stream, 0, &data ); - todo_wine ok( ret == ERROR_INVALID_PARAMETER, "%d != %ld.\n", ERROR_INVALID_PARAMETER, ret ); + ok( ret == ERROR_INVALID_PARAMETER, "%d != %ld.\n", ERROR_INVALID_PARAMETER, ret );
ret = BluetoothSdpGetElementData( NULL, 0, NULL ); - todo_wine ok( ret == ERROR_INVALID_PARAMETER, "%d != %ld.\n", ERROR_INVALID_PARAMETER, ret ); + ok( ret == ERROR_INVALID_PARAMETER, "%d != %ld.\n", ERROR_INVALID_PARAMETER, ret ); }
static void test_BluetoothSdpGetElementData_nil( void ) @@ -92,8 +92,8 @@ static void test_BluetoothSdpGetElementData_nil( void ) for (i = 0; i < ARRAY_SIZE( test_cases ); i++) { winetest_push_context(TEST_CASE_NAME( i )); - todo_wine test_BluetoothSdpGetElementData( &test_cases[i].data_elem, 1, test_cases[i].error, - &test_cases[i].data ); + test_BluetoothSdpGetElementData( &test_cases[i].data_elem, 1, test_cases[i].error, + &test_cases[i].data ); winetest_pop_context(); } } @@ -211,8 +211,8 @@ static void test_BluetoothSdpGetElementData_ints( void ) for (i = 0; i < ARRAY_SIZE( test_cases ); i++) { winetest_push_context( TEST_CASE_NAME( i ) ); - todo_wine test_BluetoothSdpGetElementData( test_cases[i].data_elem, test_cases[i].size, - test_cases[i].error, &test_cases[i].data ); + test_BluetoothSdpGetElementData( test_cases[i].data_elem, test_cases[i].size, + test_cases[i].error, &test_cases[i].data ); winetest_pop_context(); } } @@ -253,22 +253,22 @@ static void test_BluetoothSdpGetElementData_str( void ) for (i = 0; i < ARRAY_SIZE( test_cases ); i++) { winetest_push_context( TEST_CASE_NAME( i ) ); - todo_wine test_BluetoothSdpGetElementData( test_cases[i].stream, test_cases[i].size, - test_cases[i].error, &test_cases[i].data ); + test_BluetoothSdpGetElementData( test_cases[i].stream, test_cases[i].size, + test_cases[i].error, &test_cases[i].data ); if (test_cases[i].error == ERROR_SUCCESS) { SDP_ELEMENT_DATA result = {0}; if (!BluetoothSdpGetElementData( test_cases[i].stream, test_cases[i].size, &result )) { - todo_wine ok( strlen( test_cases[i].string ) == result.data.string.length, - "%s != %s.\n", debugstr_a( test_cases[i].string ), - debugstr_an( (const char *)result.data.string.value, - result.data.string.length ) ); - todo_wine ok( !memcmp( result.data.string.value, test_cases[i].string, - result.data.string.length ), - "%s != %s.\n", debugstr_a( test_cases[i].string ), - debugstr_an( (const char *)result.data.string.value, - result.data.string.length ) ); + ok( strlen( test_cases[i].string ) == result.data.string.length, "%s != %s.\n", + debugstr_a( test_cases[i].string ), + debugstr_an( (const char *)result.data.string.value, + result.data.string.length ) ); + ok( !memcmp( result.data.string.value, test_cases[i].string, + result.data.string.length ), + "%s != %s.\n", debugstr_a( test_cases[i].string ), + debugstr_an( (const char *)result.data.string.value, + result.data.string.length ) ); } } winetest_pop_context();
From: Vibhav Pant vibhavp@gmail.com
--- dlls/bluetoothapis/bluetoothapis.spec | 2 +- dlls/bluetoothapis/sdp.c | 12 ++++++++++++ dlls/bthprops.cpl/bthprops.cpl.spec | 2 +- dlls/irprops.cpl/irprops.cpl.spec | 2 +- 4 files changed, 15 insertions(+), 3 deletions(-)
diff --git a/dlls/bluetoothapis/bluetoothapis.spec b/dlls/bluetoothapis/bluetoothapis.spec index a35e1e22ecc..51fdf55d8ed 100644 --- a/dlls/bluetoothapis/bluetoothapis.spec +++ b/dlls/bluetoothapis/bluetoothapis.spec @@ -55,7 +55,7 @@ @ stub BluetoothRemoveDevice @ stub BluetoothSdpEnumAttributes @ stub BluetoothSdpGetAttributeValue -@ stub BluetoothSdpGetContainerElementData +@ stdcall BluetoothSdpGetContainerElementData(ptr long ptr ptr) @ stdcall BluetoothSdpGetElementData(ptr long ptr) @ stub BluetoothSdpGetString @ stub BluetoothSendAuthenticationResponse diff --git a/dlls/bluetoothapis/sdp.c b/dlls/bluetoothapis/sdp.c index 0b87e9488da..30aff8d0fd4 100644 --- a/dlls/bluetoothapis/sdp.c +++ b/dlls/bluetoothapis/sdp.c @@ -262,3 +262,15 @@ DWORD WINAPI BluetoothSdpGetElementData( BYTE *stream, ULONG stream_size, SDP_EL
return sdp_read_element_data( stream, stream_size, data, &read ); } + +/********************************************************************* + * BluetoothSdpGetContainerElementData + */ +DWORD WINAPI BluetoothSdpGetContainerElementData( BYTE *stream, ULONG stream_size, + HBLUETOOTH_CONTAINER_ELEMENT *handle, + SDP_ELEMENT_DATA *data ) +{ + FIXME( "(%p, %lu, %p, %p) stub!\n", stream, stream_size, handle, data ); + return ERROR_CALL_NOT_IMPLEMENTED; +} + diff --git a/dlls/bthprops.cpl/bthprops.cpl.spec b/dlls/bthprops.cpl/bthprops.cpl.spec index 0bef83810db..cd17f0f108c 100644 --- a/dlls/bthprops.cpl/bthprops.cpl.spec +++ b/dlls/bthprops.cpl/bthprops.cpl.spec @@ -46,7 +46,7 @@ @ stub BluetoothRemoveDevice @ stub BluetoothSdpEnumAttributes @ stub BluetoothSdpGetAttributeValue -@ stub BluetoothSdpGetContainerElementData +@ stdcall -import BluetoothSdpGetContainerElementData(ptr long ptr ptr) @ stdcall -import BluetoothSdpGetElementData(ptr long ptr) @ stub BluetoothSdpGetString @ stub BluetoothSelectDevices diff --git a/dlls/irprops.cpl/irprops.cpl.spec b/dlls/irprops.cpl/irprops.cpl.spec index c9cd4df62d6..847b1552603 100644 --- a/dlls/irprops.cpl/irprops.cpl.spec +++ b/dlls/irprops.cpl/irprops.cpl.spec @@ -40,7 +40,7 @@ @ stub BluetoothRemoveDevice @ stub BluetoothSdpEnumAttributes @ stub BluetoothSdpGetAttributeValue -@ stub BluetoothSdpGetContainerElementData +@ stdcall -import BluetoothSdpGetContainerElementData(ptr long ptr ptr) @ stdcall -import BluetoothSdpGetElementData(ptr long ptr) @ stub BluetoothSdpGetString @ stub BluetoothSelectDevices
From: Vibhav Pant vibhavp@gmail.com
--- dlls/bluetoothapis/tests/sdp.c | 106 +++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+)
diff --git a/dlls/bluetoothapis/tests/sdp.c b/dlls/bluetoothapis/tests/sdp.c index 47c5bd46615..a91cc9f3dd3 100644 --- a/dlls/bluetoothapis/tests/sdp.c +++ b/dlls/bluetoothapis/tests/sdp.c @@ -124,6 +124,10 @@ SDP_DEF_TYPE( STR8, STRING, NEXT_UINT8 ); SDP_DEF_TYPE( STR16, STRING, NEXT_UINT16 ); SDP_DEF_TYPE( STR32, STRING, NEXT_UINT32 );
+SDP_DEF_TYPE( SEQ8, SEQUENCE, NEXT_UINT8 ); +SDP_DEF_TYPE( SEQ16, SEQUENCE, NEXT_UINT16 ); +SDP_DEF_TYPE( SEQ32, SEQUENCE, NEXT_UINT32 ); + static void test_BluetoothSdpGetElementData_ints( void ) { static struct @@ -275,10 +279,112 @@ static void test_BluetoothSdpGetElementData_str( void ) } }
+static void test_BluetoothSdpGetContainerElementData( void ) +{ + static struct { + BYTE stream[11]; + SIZE_T size; + DWORD error; + SDP_ELEMENT_DATA data; + SDP_ELEMENT_DATA sequence[6]; + SIZE_T container_size; + } test_cases[] = { + { + {SDP_TYPE_DESC_SEQ8, 0x06, SDP_TYPE_DESC_UINT8, 0xde, SDP_TYPE_DESC_UINT8, 0xad, SDP_TYPE_DESC_UINT8, 0xbe}, + 8, + ERROR_SUCCESS, + {SDP_TYPE_SEQUENCE, SDP_ST_NONE, {.sequence = {&test_cases[0].stream[0], 8}}}, + { + {SDP_TYPE_UINT, SDP_ST_UINT8, {.uint8 = 0xde}}, + {SDP_TYPE_UINT, SDP_ST_UINT8, {.uint8 = 0xad}}, + {SDP_TYPE_UINT, SDP_ST_UINT8, {.uint8 = 0xbe}} + }, + 3 + }, + { + {SDP_TYPE_DESC_SEQ16, 0x00, 0x06, SDP_TYPE_DESC_UINT8, 0xde, SDP_TYPE_DESC_UINT8, 0xad, SDP_TYPE_DESC_UINT8, 0xbe}, + 9, + ERROR_SUCCESS, + {SDP_TYPE_SEQUENCE, SDP_ST_NONE, {.sequence = {&test_cases[1].stream[0], 9}}}, + { + {SDP_TYPE_UINT, SDP_ST_UINT8, {.uint8 = 0xde}}, + {SDP_TYPE_UINT, SDP_ST_UINT8, {.uint8 = 0xad}}, + {SDP_TYPE_UINT, SDP_ST_UINT8, {.uint8 = 0xbe}} + }, + 3 + }, + { + {SDP_TYPE_DESC_SEQ32, 0x00, 0x00, 0x00, 0x06, SDP_TYPE_DESC_UINT8, 0xde, SDP_TYPE_DESC_UINT8, 0xad, SDP_TYPE_DESC_UINT8, 0xbe}, + 11, + ERROR_SUCCESS, + {SDP_TYPE_SEQUENCE, SDP_ST_NONE, {.sequence = {&test_cases[2].stream[0], 11}}}, + { + {SDP_TYPE_UINT, SDP_ST_UINT8, {.uint8 = 0xde}}, + {SDP_TYPE_UINT, SDP_ST_UINT8, {.uint8 = 0xad}}, + {SDP_TYPE_UINT, SDP_ST_UINT8, {.uint8 = 0xbe}} + }, + 3 + }, + { + {SDP_TYPE_DESC_SEQ8, SDP_TYPE_DESC_UINT8, 0xde, SDP_TYPE_DESC_UINT8, 0xad, SDP_TYPE_DESC_UINT8, 0xbe}, + 1, + ERROR_INVALID_PARAMETER, + }, + }; + SIZE_T i; + + for (i = 0; i < ARRAY_SIZE( test_cases ); i++) + { + SIZE_T n = 0; + HBLUETOOTH_CONTAINER_ELEMENT handle = NULL; + DWORD ret; + + winetest_push_context( TEST_CASE_NAME( i ) ); + test_BluetoothSdpGetElementData( test_cases[i].stream, test_cases[i].size, + test_cases[i].error, &test_cases[i].data ); + if (test_cases[i].error != ERROR_SUCCESS) + { + winetest_pop_context(); + continue; + } + + while (n < test_cases[i].container_size) + { + SDP_ELEMENT_DATA container_elem = {0}; + + winetest_push_context( "test_cases[%d].sequence[%d]", (int)i, (int)n ); + ret = BluetoothSdpGetContainerElementData( test_cases[i].data.data.sequence.value, + test_cases[i].data.data.sequence.length, + &handle, &container_elem ); + if (ret == ERROR_NO_MORE_ITEMS) + { + todo_wine ok( n == test_cases[i].container_size, "%d != %d.\n", + (int)test_cases[i].container_size, (int)n ); + winetest_pop_context(); + break; + } + todo_wine ok( ret == ERROR_SUCCESS, + "BluetoothSdpGetContainerElementData failed: %ld.\n", ret ); + if (ret == ERROR_SUCCESS) + { + todo_wine ok( !memcmp( &test_cases[i].sequence[n], &container_elem, + sizeof( container_elem ) ), + "%s != %s.\n", + debugstr_SDP_ELEMENT_DATA( &test_cases[i].sequence[n] ), + debugstr_SDP_ELEMENT_DATA( &container_elem ) ); + } + n++; + winetest_pop_context(); + } + winetest_pop_context(); + } +} + START_TEST( sdp ) { test_BluetoothSdpGetElementData_nil(); test_BluetoothSdpGetElementData_ints(); test_BluetoothSdpGetElementData_invalid(); test_BluetoothSdpGetElementData_str(); + test_BluetoothSdpGetContainerElementData(); }
From: Vibhav Pant vibhavp@gmail.com
--- dlls/bluetoothapis/sdp.c | 50 ++++++++++++++++++++++++++++++++-- dlls/bluetoothapis/tests/sdp.c | 16 +++++------ 2 files changed, 55 insertions(+), 11 deletions(-)
diff --git a/dlls/bluetoothapis/sdp.c b/dlls/bluetoothapis/sdp.c index 30aff8d0fd4..72b36e50cb5 100644 --- a/dlls/bluetoothapis/sdp.c +++ b/dlls/bluetoothapis/sdp.c @@ -270,7 +270,53 @@ DWORD WINAPI BluetoothSdpGetContainerElementData( BYTE *stream, ULONG stream_siz HBLUETOOTH_CONTAINER_ELEMENT *handle, SDP_ELEMENT_DATA *data ) { - FIXME( "(%p, %lu, %p, %p) stub!\n", stream, stream_size, handle, data ); - return ERROR_CALL_NOT_IMPLEMENTED; + BYTE *cursor; + DWORD result; + SIZE_T read = 0; + + TRACE( "(%p, %lu, %p, %p)\n", stream, stream_size, handle, data ); + + if (stream == NULL || stream_size < sizeof( BYTE ) || handle == NULL || data == NULL) + return ERROR_INVALID_PARAMETER; + + cursor = (BYTE *)(*handle); + + if (cursor == NULL) + { + BYTE header, type, size_desc; + UINT32 elems_size = 0; + SIZE_T read = 0; + + header = *stream; + type = data_elem_type( header ); + size_desc = data_elem_size_desc( header ); + + if (type != SDP_TYPE_SEQUENCE && type != SDP_TYPE_ALTERNATIVE) + return ERROR_INVALID_PARAMETER; + if (!(size_desc >= SDP_SIZE_DESC_NEXT_UINT8 && size_desc <= SDP_SIZE_DESC_NEXT_UINT32)) + return ERROR_INVALID_PARAMETER; + + stream++; + if (!sdp_elem_read_var_size( stream, stream_size, &read, size_desc, &elems_size )) + return ERROR_INVALID_PARAMETER; + + stream += read; + stream_size -= read; + } + else + { + if (cursor < stream) return ERROR_INVALID_PARAMETER; + if (cursor == (stream + stream_size)) return ERROR_NO_MORE_ITEMS; + + stream = cursor; + stream_size = stream_size - (cursor - stream); + } + result = sdp_read_element_data( stream, stream_size, data, &read ); + if (result != ERROR_SUCCESS) return result; + + stream += read; + TRACE( "handle=%p\n", stream ); + *handle = stream; + return ERROR_SUCCESS; }
diff --git a/dlls/bluetoothapis/tests/sdp.c b/dlls/bluetoothapis/tests/sdp.c index a91cc9f3dd3..ebdd70a4abc 100644 --- a/dlls/bluetoothapis/tests/sdp.c +++ b/dlls/bluetoothapis/tests/sdp.c @@ -358,20 +358,18 @@ static void test_BluetoothSdpGetContainerElementData( void ) &handle, &container_elem ); if (ret == ERROR_NO_MORE_ITEMS) { - todo_wine ok( n == test_cases[i].container_size, "%d != %d.\n", - (int)test_cases[i].container_size, (int)n ); + ok( n == test_cases[i].container_size, "%d != %d.\n", + (int)test_cases[i].container_size, (int)n ); winetest_pop_context(); break; } - todo_wine ok( ret == ERROR_SUCCESS, - "BluetoothSdpGetContainerElementData failed: %ld.\n", ret ); + ok( ret == ERROR_SUCCESS, "BluetoothSdpGetContainerElementData failed: %ld.\n", ret ); if (ret == ERROR_SUCCESS) { - todo_wine ok( !memcmp( &test_cases[i].sequence[n], &container_elem, - sizeof( container_elem ) ), - "%s != %s.\n", - debugstr_SDP_ELEMENT_DATA( &test_cases[i].sequence[n] ), - debugstr_SDP_ELEMENT_DATA( &container_elem ) ); + ok( !memcmp( &test_cases[i].sequence[n], &container_elem, + sizeof( container_elem ) ), + "%s != %s.\n", debugstr_SDP_ELEMENT_DATA( &test_cases[i].sequence[n] ), + debugstr_SDP_ELEMENT_DATA( &container_elem ) ); } n++; winetest_pop_context();
From: Vibhav Pant vibhavp@gmail.com
--- dlls/bluetoothapis/bluetoothapis.spec | 2 +- dlls/bluetoothapis/sdp.c | 10 ++++++++++ dlls/bthprops.cpl/bthprops.cpl.spec | 2 +- dlls/irprops.cpl/irprops.cpl.spec | 2 +- 4 files changed, 13 insertions(+), 3 deletions(-)
diff --git a/dlls/bluetoothapis/bluetoothapis.spec b/dlls/bluetoothapis/bluetoothapis.spec index 51fdf55d8ed..3531e2f901c 100644 --- a/dlls/bluetoothapis/bluetoothapis.spec +++ b/dlls/bluetoothapis/bluetoothapis.spec @@ -53,7 +53,7 @@ @ stub BluetoothRegisterForAuthentication @ stdcall BluetoothRegisterForAuthenticationEx(ptr ptr ptr ptr) @ stub BluetoothRemoveDevice -@ stub BluetoothSdpEnumAttributes +@ stdcall BluetoothSdpEnumAttributes(ptr long ptr ptr) @ stub BluetoothSdpGetAttributeValue @ stdcall BluetoothSdpGetContainerElementData(ptr long ptr ptr) @ stdcall BluetoothSdpGetElementData(ptr long ptr) diff --git a/dlls/bluetoothapis/sdp.c b/dlls/bluetoothapis/sdp.c index 72b36e50cb5..06b1b957848 100644 --- a/dlls/bluetoothapis/sdp.c +++ b/dlls/bluetoothapis/sdp.c @@ -320,3 +320,13 @@ DWORD WINAPI BluetoothSdpGetContainerElementData( BYTE *stream, ULONG stream_siz return ERROR_SUCCESS; }
+/********************************************************************* + * BluetoothSdpEnumAttributes + */ +BOOL WINAPI BluetoothSdpEnumAttributes( BYTE *stream, ULONG stream_size, + PFN_BLUETOOTH_ENUM_ATTRIBUTES_CALLBACK callback, void *param ) +{ + FIXME( "(%p, %ld, %p, %p) stub!\n", stream, stream_size, callback, param ); + SetLastError( ERROR_CALL_NOT_IMPLEMENTED ); + return FALSE; +} diff --git a/dlls/bthprops.cpl/bthprops.cpl.spec b/dlls/bthprops.cpl/bthprops.cpl.spec index cd17f0f108c..8e4d2e02a42 100644 --- a/dlls/bthprops.cpl/bthprops.cpl.spec +++ b/dlls/bthprops.cpl/bthprops.cpl.spec @@ -44,7 +44,7 @@ @ stub BluetoothRegisterForAuthentication @ stdcall -import BluetoothRegisterForAuthenticationEx(ptr ptr ptr ptr) @ stub BluetoothRemoveDevice -@ stub BluetoothSdpEnumAttributes +@ stdcall -import BluetoothSdpEnumAttributes(ptr long ptr ptr) @ stub BluetoothSdpGetAttributeValue @ stdcall -import BluetoothSdpGetContainerElementData(ptr long ptr ptr) @ stdcall -import BluetoothSdpGetElementData(ptr long ptr) diff --git a/dlls/irprops.cpl/irprops.cpl.spec b/dlls/irprops.cpl/irprops.cpl.spec index 847b1552603..a4cc145dc8f 100644 --- a/dlls/irprops.cpl/irprops.cpl.spec +++ b/dlls/irprops.cpl/irprops.cpl.spec @@ -38,7 +38,7 @@ @ stub BluetoothMapClassOfDeviceToString @ stub BluetoothRegisterForAuthentication @ stub BluetoothRemoveDevice -@ stub BluetoothSdpEnumAttributes +@ stdcall -import BluetoothSdpEnumAttributes(ptr long ptr ptr) @ stub BluetoothSdpGetAttributeValue @ stdcall -import BluetoothSdpGetContainerElementData(ptr long ptr ptr) @ stdcall -import BluetoothSdpGetElementData(ptr long ptr)
From: Vibhav Pant vibhavp@gmail.com
--- dlls/bluetoothapis/tests/sdp.c | 68 ++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+)
diff --git a/dlls/bluetoothapis/tests/sdp.c b/dlls/bluetoothapis/tests/sdp.c index ebdd70a4abc..0f7f4321c6f 100644 --- a/dlls/bluetoothapis/tests/sdp.c +++ b/dlls/bluetoothapis/tests/sdp.c @@ -378,6 +378,73 @@ static void test_BluetoothSdpGetContainerElementData( void ) } }
+struct attr_callback_data +{ + const ULONG *attrs_id; + const SDP_ELEMENT_DATA *attrs; + const SIZE_T attrs_n; + SIZE_T i; +}; + +static BYTE sdp_record_bytes[] = { + 0x35, 0x48, 0x09, 0x00, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x09, 0x00, 0x01, 0x35, 0x03, + 0x19, 0x12, 0x00, 0x09, 0x00, 0x05, 0x35, 0x03, 0x19, 0x10, 0x02, 0x09, 0x00, 0x09, 0x35, + 0x08, 0x35, 0x06, 0x19, 0x12, 0x00, 0x09, 0x01, 0x03, 0x09, 0x02, 0x00, 0x09, 0x01, 0x03, + 0x09, 0x02, 0x01, 0x09, 0x1d, 0x6b, 0x09, 0x02, 0x02, 0x09, 0x02, 0x46, 0x09, 0x02, 0x03, + 0x09, 0x05, 0x4d, 0x09, 0x02, 0x04, 0x28, 0x01, 0x09, 0x02, 0x05, 0x09, 0x00, 0x02 }; + +static BOOL WINAPI enum_attr_callback( ULONG attr_id, BYTE *stream, ULONG stream_size, void *param ) +{ + struct attr_callback_data *params = param; + winetest_push_context( TEST_CASE_NAME( params->i + 1) ); + if (params->i < params->attrs_n) + { + SDP_ELEMENT_DATA data = {0}; + DWORD result; + + todo_wine ok( attr_id == params->attrs_id[params->i], + "Expected attribute id %lu, got %lu.\n", params->attrs_id[params->i], + attr_id ); + result = BluetoothSdpGetElementData( stream, stream_size, &data ); + todo_wine ok( result == ERROR_SUCCESS, "BluetoothSdpGetElementData failed: %ld.\n", + result ); + todo_wine ok( !memcmp( ¶ms->attrs[params->i], &data, sizeof( data ) ), + "Expected %s, got %s.\n", + debugstr_SDP_ELEMENT_DATA( ¶ms->attrs[params->i] ), + debugstr_SDP_ELEMENT_DATA( &data ) ); + + params->i++; + } + winetest_pop_context(); + return TRUE; +} + +static void test_BluetoothSdpEnumAttributes( void ) +{ + static SDP_ELEMENT_DATA attributes[] = { + {SDP_TYPE_UINT, SDP_ST_UINT32, {.uint32 = 0x10000}}, + {SDP_TYPE_SEQUENCE, SDP_ST_NONE, {.sequence = {&sdp_record_bytes[13], 5}}}, + {SDP_TYPE_SEQUENCE, SDP_ST_NONE, {.sequence = {&sdp_record_bytes[21], 5}}}, + {SDP_TYPE_SEQUENCE, SDP_ST_NONE, {.sequence = {&sdp_record_bytes[29], 10}}}, + {SDP_TYPE_UINT, SDP_ST_UINT16, {.uint16 = 0x0103}}, + {SDP_TYPE_UINT, SDP_ST_UINT16, {.uint16 = 0x1d6b}}, + {SDP_TYPE_UINT, SDP_ST_UINT16, {.uint16 = 0x0246}}, + {SDP_TYPE_UINT, SDP_ST_UINT16, {.uint16 = 0x054d}}, + {SDP_TYPE_BOOLEAN, SDP_ST_NONE, {.booleanVal = 1}}, + {SDP_TYPE_UINT, SDP_ST_UINT16, {.uint16 = 0x02}}, + }; + const ULONG attrs_id[] = {0x0, 0x1, 0x5, 0x9, 0x200, 0x201, 0x202, 0x203, 0x204, 0x205}; + struct attr_callback_data data = {attrs_id, attributes, ARRAY_SIZE( attributes ), 0}; + + BOOL ret; + + SetLastError( 0xdeadbeef ); + ret = BluetoothSdpEnumAttributes( sdp_record_bytes, ARRAY_SIZE( sdp_record_bytes ), enum_attr_callback, + &data ); + todo_wine ok( ret, "BluetoothSdpEnumAttributes failed with %ld.\n", GetLastError() ); + todo_wine ok( data.i == data.attrs_n, "%d != %d\n", (int)data.i, (int)data.attrs_n ); +} + START_TEST( sdp ) { test_BluetoothSdpGetElementData_nil(); @@ -385,4 +452,5 @@ START_TEST( sdp ) test_BluetoothSdpGetElementData_invalid(); test_BluetoothSdpGetElementData_str(); test_BluetoothSdpGetContainerElementData(); + test_BluetoothSdpEnumAttributes(); }
From: Vibhav Pant vibhavp@gmail.com
--- dlls/bluetoothapis/sdp.c | 55 ++++++++++++++++++++++++++++++++-- dlls/bluetoothapis/tests/sdp.c | 19 +++++------- 2 files changed, 60 insertions(+), 14 deletions(-)
diff --git a/dlls/bluetoothapis/sdp.c b/dlls/bluetoothapis/sdp.c index 06b1b957848..d375645ef67 100644 --- a/dlls/bluetoothapis/sdp.c +++ b/dlls/bluetoothapis/sdp.c @@ -326,7 +326,56 @@ DWORD WINAPI BluetoothSdpGetContainerElementData( BYTE *stream, ULONG stream_siz BOOL WINAPI BluetoothSdpEnumAttributes( BYTE *stream, ULONG stream_size, PFN_BLUETOOTH_ENUM_ATTRIBUTES_CALLBACK callback, void *param ) { - FIXME( "(%p, %ld, %p, %p) stub!\n", stream, stream_size, callback, param ); - SetLastError( ERROR_CALL_NOT_IMPLEMENTED ); - return FALSE; + SDP_ELEMENT_DATA data = {0}; + DWORD result; + HBLUETOOTH_CONTAINER_ELEMENT cursor = NULL; + + TRACE( "(%p, %ld, %p, %p)\n", stream, stream_size, callback, param ); + + if (stream == NULL || callback == NULL) return ERROR_INVALID_PARAMETER; + + result = BluetoothSdpGetElementData( stream, stream_size, &data ); + if (result != ERROR_SUCCESS) + { + SetLastError( ERROR_INVALID_DATA ); + return FALSE; + } + + switch (data.type) + { + case SDP_TYPE_SEQUENCE: + case SDP_TYPE_ALTERNATIVE: + break; + default: + SetLastError( ERROR_INVALID_DATA ); + return FALSE; + } + + for (;;) + { + SDP_ELEMENT_DATA attrid = {0}; + SDP_ELEMENT_DATA attr = {0}; + BYTE *raw_attr_stream; + + result = BluetoothSdpGetContainerElementData( data.data.sequence.value, + data.data.sequence.length, &cursor, &attrid ); + if (result == ERROR_NO_MORE_ITEMS) return TRUE; + if (result || !SDP_ELEMENT_IS_ATTRID( &attrid )) + { + SetLastError( ERROR_INVALID_DATA ); + return FALSE; + } + + raw_attr_stream = cursor; + result = BluetoothSdpGetContainerElementData( data.data.sequence.value, + data.data.sequence.length, &cursor, &attr ); + if (result != ERROR_SUCCESS) + { + SetLastError( ERROR_INVALID_DATA ); + return FALSE; + } + if (!callback( attrid.data.uint16, raw_attr_stream, ((BYTE *)cursor - raw_attr_stream), + param )) + return TRUE; + } } diff --git a/dlls/bluetoothapis/tests/sdp.c b/dlls/bluetoothapis/tests/sdp.c index 0f7f4321c6f..ddd906b1089 100644 --- a/dlls/bluetoothapis/tests/sdp.c +++ b/dlls/bluetoothapis/tests/sdp.c @@ -402,16 +402,13 @@ static BOOL WINAPI enum_attr_callback( ULONG attr_id, BYTE *stream, ULONG stream SDP_ELEMENT_DATA data = {0}; DWORD result;
- todo_wine ok( attr_id == params->attrs_id[params->i], - "Expected attribute id %lu, got %lu.\n", params->attrs_id[params->i], - attr_id ); + ok( attr_id == params->attrs_id[params->i], "Expected attribute id %lu, got %lu.\n", + params->attrs_id[params->i], attr_id ); result = BluetoothSdpGetElementData( stream, stream_size, &data ); - todo_wine ok( result == ERROR_SUCCESS, "BluetoothSdpGetElementData failed: %ld.\n", - result ); - todo_wine ok( !memcmp( ¶ms->attrs[params->i], &data, sizeof( data ) ), - "Expected %s, got %s.\n", - debugstr_SDP_ELEMENT_DATA( ¶ms->attrs[params->i] ), - debugstr_SDP_ELEMENT_DATA( &data ) ); + ok( result == ERROR_SUCCESS, "BluetoothSdpGetElementData failed: %ld.\n", result ); + ok( !memcmp( ¶ms->attrs[params->i], &data, sizeof( data ) ), "Expected %s, got %s.\n", + debugstr_SDP_ELEMENT_DATA( ¶ms->attrs[params->i] ), + debugstr_SDP_ELEMENT_DATA( &data ) );
params->i++; } @@ -441,8 +438,8 @@ static void test_BluetoothSdpEnumAttributes( void ) SetLastError( 0xdeadbeef ); ret = BluetoothSdpEnumAttributes( sdp_record_bytes, ARRAY_SIZE( sdp_record_bytes ), enum_attr_callback, &data ); - todo_wine ok( ret, "BluetoothSdpEnumAttributes failed with %ld.\n", GetLastError() ); - todo_wine ok( data.i == data.attrs_n, "%d != %d\n", (int)data.i, (int)data.attrs_n ); + ok( ret, "BluetoothSdpEnumAttributes failed with %ld.\n", GetLastError() ); + ok( data.i == data.attrs_n, "%d != %d\n", (int)data.i, (int)data.attrs_n ); }
START_TEST( sdp )
From: Vibhav Pant vibhavp@gmail.com
--- dlls/bluetoothapis/bluetoothapis.spec | 2 +- dlls/bluetoothapis/sdp.c | 10 ++++++++++ dlls/bthprops.cpl/bthprops.cpl.spec | 2 +- dlls/irprops.cpl/irprops.cpl.spec | 2 +- 4 files changed, 13 insertions(+), 3 deletions(-)
diff --git a/dlls/bluetoothapis/bluetoothapis.spec b/dlls/bluetoothapis/bluetoothapis.spec index 3531e2f901c..939072d308c 100644 --- a/dlls/bluetoothapis/bluetoothapis.spec +++ b/dlls/bluetoothapis/bluetoothapis.spec @@ -54,7 +54,7 @@ @ stdcall BluetoothRegisterForAuthenticationEx(ptr ptr ptr ptr) @ stub BluetoothRemoveDevice @ stdcall BluetoothSdpEnumAttributes(ptr long ptr ptr) -@ stub BluetoothSdpGetAttributeValue +@ stdcall BluetoothSdpGetAttributeValue(ptr long long ptr) @ stdcall BluetoothSdpGetContainerElementData(ptr long ptr ptr) @ stdcall BluetoothSdpGetElementData(ptr long ptr) @ stub BluetoothSdpGetString diff --git a/dlls/bluetoothapis/sdp.c b/dlls/bluetoothapis/sdp.c index d375645ef67..7740a8a371e 100644 --- a/dlls/bluetoothapis/sdp.c +++ b/dlls/bluetoothapis/sdp.c @@ -379,3 +379,13 @@ BOOL WINAPI BluetoothSdpEnumAttributes( BYTE *stream, ULONG stream_size, return TRUE; } } + +/********************************************************************* + * BluetoothSdpGetAttributeValue + */ +DWORD WINAPI BluetoothSdpGetAttributeValue( BYTE *stream, ULONG stream_size, USHORT attr_id, + SDP_ELEMENT_DATA *data ) +{ + FIXME( "(%p %lu %u %p) stub!\n", stream, stream_size, attr_id, data ); + return ERROR_CALL_NOT_IMPLEMENTED; +} diff --git a/dlls/bthprops.cpl/bthprops.cpl.spec b/dlls/bthprops.cpl/bthprops.cpl.spec index 8e4d2e02a42..7fe1d82ac89 100644 --- a/dlls/bthprops.cpl/bthprops.cpl.spec +++ b/dlls/bthprops.cpl/bthprops.cpl.spec @@ -45,7 +45,7 @@ @ stdcall -import BluetoothRegisterForAuthenticationEx(ptr ptr ptr ptr) @ stub BluetoothRemoveDevice @ stdcall -import BluetoothSdpEnumAttributes(ptr long ptr ptr) -@ stub BluetoothSdpGetAttributeValue +@ stdcall -import BluetoothSdpGetAttributeValue(ptr long long ptr) @ stdcall -import BluetoothSdpGetContainerElementData(ptr long ptr ptr) @ stdcall -import BluetoothSdpGetElementData(ptr long ptr) @ stub BluetoothSdpGetString diff --git a/dlls/irprops.cpl/irprops.cpl.spec b/dlls/irprops.cpl/irprops.cpl.spec index a4cc145dc8f..0baeb9179e3 100644 --- a/dlls/irprops.cpl/irprops.cpl.spec +++ b/dlls/irprops.cpl/irprops.cpl.spec @@ -39,7 +39,7 @@ @ stub BluetoothRegisterForAuthentication @ stub BluetoothRemoveDevice @ stdcall -import BluetoothSdpEnumAttributes(ptr long ptr ptr) -@ stub BluetoothSdpGetAttributeValue +@ stdcall -import BluetoothSdpGetAttributeValue(ptr long long ptr) @ stdcall -import BluetoothSdpGetContainerElementData(ptr long ptr ptr) @ stdcall -import BluetoothSdpGetElementData(ptr long ptr) @ stub BluetoothSdpGetString
From: Vibhav Pant vibhavp@gmail.com
--- dlls/bluetoothapis/tests/sdp.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/dlls/bluetoothapis/tests/sdp.c b/dlls/bluetoothapis/tests/sdp.c index ddd906b1089..5681edbbcce 100644 --- a/dlls/bluetoothapis/tests/sdp.c +++ b/dlls/bluetoothapis/tests/sdp.c @@ -399,7 +399,7 @@ static BOOL WINAPI enum_attr_callback( ULONG attr_id, BYTE *stream, ULONG stream winetest_push_context( TEST_CASE_NAME( params->i + 1) ); if (params->i < params->attrs_n) { - SDP_ELEMENT_DATA data = {0}; + SDP_ELEMENT_DATA data = {0}, data2 = {0}; DWORD result;
ok( attr_id == params->attrs_id[params->i], "Expected attribute id %lu, got %lu.\n", @@ -410,6 +410,15 @@ static BOOL WINAPI enum_attr_callback( ULONG attr_id, BYTE *stream, ULONG stream debugstr_SDP_ELEMENT_DATA( ¶ms->attrs[params->i] ), debugstr_SDP_ELEMENT_DATA( &data ) );
+ result = BluetoothSdpGetAttributeValue( sdp_record_bytes, ARRAY_SIZE( sdp_record_bytes ), + params->attrs_id[params->i], &data2 ); + todo_wine ok( result == ERROR_SUCCESS, "BluetoothSdpGetAttributeValue failed: %ld.\n", + result ); + todo_wine ok( !memcmp( ¶ms->attrs[params->i], &data2, sizeof( data2 ) ), + "Expected %s, got %s.\n", + debugstr_SDP_ELEMENT_DATA( ¶ms->attrs[params->i] ), + debugstr_SDP_ELEMENT_DATA( &data2 ) ); + params->i++; } winetest_pop_context(); @@ -432,6 +441,8 @@ static void test_BluetoothSdpEnumAttributes( void ) }; const ULONG attrs_id[] = {0x0, 0x1, 0x5, 0x9, 0x200, 0x201, 0x202, 0x203, 0x204, 0x205}; struct attr_callback_data data = {attrs_id, attributes, ARRAY_SIZE( attributes ), 0}; + SDP_ELEMENT_DATA elem_data = {0}; + DWORD result;
BOOL ret;
@@ -440,6 +451,10 @@ static void test_BluetoothSdpEnumAttributes( void ) &data ); ok( ret, "BluetoothSdpEnumAttributes failed with %ld.\n", GetLastError() ); ok( data.i == data.attrs_n, "%d != %d\n", (int)data.i, (int)data.attrs_n ); + + result = BluetoothSdpGetAttributeValue( sdp_record_bytes, ARRAY_SIZE( sdp_record_bytes ), 0xff, + &elem_data ); + todo_wine ok( result == ERROR_FILE_NOT_FOUND, "%d != %ld.\n", ERROR_FILE_NOT_FOUND, result ); }
START_TEST( sdp )
From: Vibhav Pant vibhavp@gmail.com
--- dlls/bluetoothapis/sdp.c | 34 ++++++++++++++++++++++++++++++++-- dlls/bluetoothapis/tests/sdp.c | 12 +++++------- 2 files changed, 37 insertions(+), 9 deletions(-)
diff --git a/dlls/bluetoothapis/sdp.c b/dlls/bluetoothapis/sdp.c index 7740a8a371e..be74839ce09 100644 --- a/dlls/bluetoothapis/sdp.c +++ b/dlls/bluetoothapis/sdp.c @@ -380,12 +380,42 @@ BOOL WINAPI BluetoothSdpEnumAttributes( BYTE *stream, ULONG stream_size, } }
+struct get_attr_value_data +{ + USHORT attr_id; + BYTE *attr_stream; + ULONG stream_size; +}; + +static BOOL WINAPI get_attr_value_callback( ULONG attr_id, BYTE *stream, ULONG stream_size, + void *params ) +{ + struct get_attr_value_data *args = params; + if (attr_id == args->attr_id) + { + args->attr_stream = stream; + args->stream_size = stream_size; + return FALSE; + } + return TRUE; +} + /********************************************************************* * BluetoothSdpGetAttributeValue */ DWORD WINAPI BluetoothSdpGetAttributeValue( BYTE *stream, ULONG stream_size, USHORT attr_id, SDP_ELEMENT_DATA *data ) { - FIXME( "(%p %lu %u %p) stub!\n", stream, stream_size, attr_id, data ); - return ERROR_CALL_NOT_IMPLEMENTED; + struct get_attr_value_data args = {0}; + + TRACE( "(%p %lu %u %p)\n", stream, stream_size, attr_id, data ); + + if (stream == NULL || data == NULL) return ERROR_INVALID_PARAMETER; + + args.attr_id = attr_id; + if (!BluetoothSdpEnumAttributes( stream, stream_size, get_attr_value_callback, &args )) + return ERROR_INVALID_PARAMETER; + if (!args.attr_stream) return ERROR_FILE_NOT_FOUND; + + return BluetoothSdpGetElementData( args.attr_stream, args.stream_size, data ); } diff --git a/dlls/bluetoothapis/tests/sdp.c b/dlls/bluetoothapis/tests/sdp.c index 5681edbbcce..cfad2944d07 100644 --- a/dlls/bluetoothapis/tests/sdp.c +++ b/dlls/bluetoothapis/tests/sdp.c @@ -412,12 +412,10 @@ static BOOL WINAPI enum_attr_callback( ULONG attr_id, BYTE *stream, ULONG stream
result = BluetoothSdpGetAttributeValue( sdp_record_bytes, ARRAY_SIZE( sdp_record_bytes ), params->attrs_id[params->i], &data2 ); - todo_wine ok( result == ERROR_SUCCESS, "BluetoothSdpGetAttributeValue failed: %ld.\n", - result ); - todo_wine ok( !memcmp( ¶ms->attrs[params->i], &data2, sizeof( data2 ) ), - "Expected %s, got %s.\n", - debugstr_SDP_ELEMENT_DATA( ¶ms->attrs[params->i] ), - debugstr_SDP_ELEMENT_DATA( &data2 ) ); + ok( result == ERROR_SUCCESS, "BluetoothSdpGetAttributeValue failed: %ld.\n", result ); + ok( !memcmp( ¶ms->attrs[params->i], &data2, sizeof( data2 ) ), "Expected %s, got %s.\n", + debugstr_SDP_ELEMENT_DATA( ¶ms->attrs[params->i] ), + debugstr_SDP_ELEMENT_DATA( &data2 ) );
params->i++; } @@ -454,7 +452,7 @@ static void test_BluetoothSdpEnumAttributes( void )
result = BluetoothSdpGetAttributeValue( sdp_record_bytes, ARRAY_SIZE( sdp_record_bytes ), 0xff, &elem_data ); - todo_wine ok( result == ERROR_FILE_NOT_FOUND, "%d != %ld.\n", ERROR_FILE_NOT_FOUND, result ); + ok( result == ERROR_FILE_NOT_FOUND, "%d != %ld.\n", ERROR_FILE_NOT_FOUND, result ); }
START_TEST( sdp )