ReactOS 0.4.16-dev-2491-g3dc6630
sdp.c
Go to the documentation of this file.
1/*
2 * SDP APIs
3 *
4 * Copyright 2024 Vibhav Pant
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 *
20 */
21
22#include <stdarg.h>
23#include <windef.h>
24#include <winbase.h>
25#include <winternl.h>
26
27#include "wine/debug.h"
28#include "bthsdpdef.h"
29#include "bluetoothapis.h"
30
32
33#define BTH_READ_UINT16( s ) RtlUshortByteSwap( *(USHORT *)(s) )
34#define BTH_READ_UINT32( s ) RtlUlongByteSwap( *(ULONG *)(s) )
35#define BTH_READ_UINT64( s ) RtlUlonglongByteSwap( *(ULONGLONG *)(s) )
36
37#define SDP_SIZE_DESC_1_BYTE 0
38#define SDP_SIZE_DESC_2_BYTES 1
39#define SDP_SIZE_DESC_4_BYTES 2
40#define SDP_SIZE_DESC_8_BYTES 3
41#define SDP_SIZE_DESC_16_BYTES 4
42#define SDP_SIZE_DESC_NEXT_UINT8 5
43#define SDP_SIZE_DESC_NEXT_UINT16 6
44#define SDP_SIZE_DESC_NEXT_UINT32 7
45
47{
48 v->HighPart = BTH_READ_UINT64( s );
49 v->LowPart = BTH_READ_UINT64( s + 8 );
50}
51
52static BYTE data_elem_type( BYTE elem ) { return (elem & 0xf8) >> 3; }
53static BYTE data_elem_size_desc( BYTE elem ) { return elem & 0x7; }
54
55#define SDP_ELEMENT_IS_UINT16( d ) ( (d)->type == SDP_TYPE_UINT && (d)->specificType == SDP_ST_UINT16 )
56#define SDP_ELEMENT_IS_ATTRID( d ) SDP_ELEMENT_IS_UINT16((d))
57
58/* Read the data element's size/length as described by the size descriptor, starting from stream. Only
59 * valid for SDP_SIZE_DESC_NEXT_* types. */
61 UINT32 *size )
62{
63 switch (size_desc)
64 {
66 if (stream_size < sizeof( UINT8 )) return FALSE;
67 *size = *stream;
68 *read += sizeof( UINT8 );
69 return TRUE;
71 if (stream_size < sizeof( UINT16 )) return FALSE;
73 *read += sizeof( UINT16 );
74 return TRUE;
76 if (stream_size < sizeof( UINT32 )) return FALSE;
78 *read += sizeof( UINT32 );
79 return TRUE;
80 default:
81 return FALSE;
82 }
83}
84
85const static SDP_SPECIFICTYPE SDP_BASIC_TYPES[4][5] = {
87 {
93 },
94 [SDP_TYPE_INT] =
95 {
101 },
102 [SDP_TYPE_UUID] =
103 {
107 },
108};
109
112{
113 switch (st)
114 {
115 case SDP_ST_UINT8:
116 case SDP_ST_INT8:
117 if (stream_size < sizeof( UINT8 )) return FALSE;
118 data->data.uint8 = *stream;
119 *read += sizeof( UINT8 );
120 break;
121 case SDP_ST_UINT16:
122 case SDP_ST_INT16:
123 case SDP_ST_UUID16:
124 if (stream_size < sizeof( UINT16 )) return FALSE;
125 data->data.uint16 = BTH_READ_UINT16( stream );
126 *read += sizeof( UINT16 );
127 break;
128 case SDP_ST_UINT32:
129 case SDP_ST_INT32:
130 if (stream_size < sizeof( UINT32 )) return FALSE;
131 data->data.uint32 = BTH_READ_UINT32( stream );
132 *read += sizeof( UINT32 );
133 break;
134 case SDP_ST_UINT64:
135 case SDP_ST_INT64:
136 if (stream_size < sizeof( UINT64 )) return FALSE;
137 data->data.uint64 = BTH_READ_UINT64( stream );
138 *read += sizeof( UINT64 );
139 break;
140 case SDP_ST_UINT128:
141 case SDP_ST_INT128:
142 case SDP_ST_UUID128:
143 if (stream_size < sizeof( SDP_ULARGE_INTEGER_16 )) return FALSE;
144 bth_read_uint128( stream, &data->data.uint128 );
145 *read += sizeof( SDP_ULARGE_INTEGER_16 );
146 break;
147 default:
148 return FALSE;
149 }
150
151 return TRUE;
152}
153
155 SIZE_T *read )
156{
157 BYTE type, size_desc, elem;
159
160 if (stream_size < sizeof( BYTE )) return ERROR_INVALID_PARAMETER;
161
162 elem = *stream;
164 size_desc = data_elem_size_desc( elem );
165
166 stream += sizeof( BYTE );
167 *read += sizeof( BYTE );
168 stream_size -= sizeof( BYTE );
169
170 memset( data, 0, sizeof( *data ) );
171 switch (type)
172 {
173 case SDP_TYPE_NIL:
174 if (size_desc != 0) return ERROR_INVALID_PARAMETER;
175
176 data->type = type;
177 data->specificType = SDP_ST_NONE;
178 break;
179 case SDP_TYPE_UINT:
180 case SDP_TYPE_INT:
181 case SDP_TYPE_UUID:
182 if (size_desc > SDP_SIZE_DESC_16_BYTES) return ERROR_INVALID_PARAMETER;
183
184 st = SDP_BASIC_TYPES[type][size_desc];
185 if (st == SDP_ST_NONE) return ERROR_INVALID_PARAMETER;
186
189
190 data->type = type;
191 data->specificType = st;
192 break;
193 case SDP_TYPE_BOOLEAN:
194 if (size_desc != SDP_SIZE_DESC_1_BYTE) return ERROR_INVALID_PARAMETER;
195 if (stream_size < sizeof( BYTE )) return ERROR_INVALID_PARAMETER;
196
197 data->type = type;
198 data->specificType = SDP_ST_NONE;
199 data->data.booleanVal = *stream;
200 *read += sizeof( BYTE );
201 break;
202 case SDP_TYPE_STRING:
203 case SDP_TYPE_URL:
206 {
207 UINT32 elems_size;
208 SIZE_T size_read = 0;
209
210 if (!(size_desc >= SDP_SIZE_DESC_NEXT_UINT8 && size_desc <= SDP_SIZE_DESC_NEXT_UINT32))
212 if (!sdp_elem_read_var_size( stream, stream_size, &size_read, size_desc, &elems_size ))
214
215 stream_size -= size_read;
217 stream += size_read;
218
219 if (stream_size < elems_size) return ERROR_INVALID_PARAMETER;
220
221 data->type = type;
222 data->specificType = SDP_ST_NONE;
224 {
225 data->data.string.value = stream;
226 data->data.string.length = elems_size;
227 }
228 else
229 {
230 /* For sequence and alternative containers, the stream should begin at the container
231 * header. */
232 data->data.sequence.value = stream - sizeof( BYTE );
233 data->data.sequence.length = elems_size + *read + size_read;
234 }
235 *read += size_read + elems_size;
236 break;
237 }
238 default:
240 }
241
242 return ERROR_SUCCESS;
243}
244
245/*********************************************************************
246 * BluetoothSdpGetElementData
247 */
249{
250 SIZE_T read = 0;
251
252 TRACE( "(%p, %lu, %p)\n", stream, stream_size, data );
253
254 if (stream == NULL || stream_size < sizeof( BYTE ) || data == NULL)
256
258}
259
260/*********************************************************************
261 * BluetoothSdpGetContainerElementData
262 */
266{
267 BYTE *cursor;
269 SIZE_T read = 0;
270
271 TRACE( "(%p, %lu, %p, %p)\n", stream, stream_size, handle, data );
272
273 if (stream == NULL || stream_size < sizeof( BYTE ) || handle == NULL || data == NULL)
275
276 cursor = (BYTE *)(*handle);
277
278 if (cursor == NULL)
279 {
280 BYTE header, type, size_desc;
281 UINT32 elems_size = 0;
282 SIZE_T read = 0;
283
284 header = *stream;
286 size_desc = data_elem_size_desc( header );
287
290 if (!(size_desc >= SDP_SIZE_DESC_NEXT_UINT8 && size_desc <= SDP_SIZE_DESC_NEXT_UINT32))
292
293 stream++;
294 if (!sdp_elem_read_var_size( stream, stream_size, &read, size_desc, &elems_size ))
296
297 stream += read;
298 stream_size -= read;
299 }
300 else
301 {
303 if (cursor == (stream + stream_size)) return ERROR_NO_MORE_ITEMS;
304
305 stream = cursor;
307 }
309 if (result != ERROR_SUCCESS) return result;
310
311 stream += read;
312 TRACE( "handle=%p\n", stream );
313 *handle = stream;
314 return ERROR_SUCCESS;
315}
316
317/*********************************************************************
318 * BluetoothSdpEnumAttributes
319 */
322{
326
327 TRACE( "(%p, %ld, %p, %p)\n", stream, stream_size, callback, param );
328
329 if (stream == NULL || callback == NULL) return ERROR_INVALID_PARAMETER;
330
332 if (result != ERROR_SUCCESS)
333 {
335 return FALSE;
336 }
337
338 switch (data.type)
339 {
342 break;
343 default:
345 return FALSE;
346 }
347
348 for (;;)
349 {
350 SDP_ELEMENT_DATA attrid = {0};
352 BYTE *raw_attr_stream;
353
354 result = BluetoothSdpGetContainerElementData( data.data.sequence.value,
355 data.data.sequence.length, &cursor, &attrid );
356 if (result == ERROR_NO_MORE_ITEMS) return TRUE;
357 if (result || !SDP_ELEMENT_IS_ATTRID( &attrid ))
358 {
360 return FALSE;
361 }
362
363 raw_attr_stream = cursor;
364 result = BluetoothSdpGetContainerElementData( data.data.sequence.value,
365 data.data.sequence.length, &cursor, &attr );
366 if (result != ERROR_SUCCESS)
367 {
369 return FALSE;
370 }
371 if (!callback( attrid.data.uint16, raw_attr_stream, ((BYTE *)cursor - raw_attr_stream),
372 param ))
373 return TRUE;
374 }
375}
376
378{
382};
383
385 void *params )
386{
388 if (attr_id == args->attr_id)
389 {
390 args->attr_stream = stream;
391 args->stream_size = stream_size;
392 return FALSE;
393 }
394 return TRUE;
395}
396
397/*********************************************************************
398 * BluetoothSdpGetAttributeValue
399 */
402{
403 struct get_attr_value_data args = {0};
404
405 TRACE( "(%p %lu %u %p)\n", stream, stream_size, attr_id, data );
406
407 if (stream == NULL || data == NULL) return ERROR_INVALID_PARAMETER;
408
409 args.attr_id = attr_id;
412 if (!args.attr_stream) return ERROR_FILE_NOT_FOUND;
413
414 return BluetoothSdpGetElementData( args.attr_stream, args.stream_size, data );
415}
unsigned short UINT16
Definition: actypes.h:129
unsigned char UINT8
Definition: actypes.h:128
COMPILER_DEPENDENT_UINT64 UINT64
Definition: actypes.h:131
#define read
Definition: acwin.h:96
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
BOOL(CALLBACK * PFN_BLUETOOTH_ENUM_ATTRIBUTES_CALLBACK)(ULONG uAttribId, BYTE *pValueStream, ULONG cbStreamSize, void *pvParam)
SDP_SPECIFICTYPE
Definition: bthsdpdef.h:55
@ SDP_ST_NONE
Definition: bthsdpdef.h:56
@ SDP_ST_UUID32
Definition: bthsdpdef.h:68
@ SDP_ST_UINT64
Definition: bthsdpdef.h:60
@ SDP_ST_UINT32
Definition: bthsdpdef.h:59
@ SDP_ST_UUID128
Definition: bthsdpdef.h:69
@ SDP_ST_INT32
Definition: bthsdpdef.h:64
@ SDP_ST_INT8
Definition: bthsdpdef.h:62
@ SDP_ST_INT16
Definition: bthsdpdef.h:63
@ SDP_ST_UINT16
Definition: bthsdpdef.h:58
@ SDP_ST_UINT128
Definition: bthsdpdef.h:61
@ SDP_ST_UINT8
Definition: bthsdpdef.h:57
@ SDP_ST_INT128
Definition: bthsdpdef.h:66
@ SDP_ST_INT64
Definition: bthsdpdef.h:65
@ SDP_ST_UUID16
Definition: bthsdpdef.h:67
@ SDP_TYPE_BOOLEAN
Definition: bthsdpdef.h:48
@ SDP_TYPE_NIL
Definition: bthsdpdef.h:43
@ SDP_TYPE_INT
Definition: bthsdpdef.h:45
@ SDP_TYPE_SEQUENCE
Definition: bthsdpdef.h:49
@ SDP_TYPE_ALTERNATIVE
Definition: bthsdpdef.h:50
@ SDP_TYPE_UINT
Definition: bthsdpdef.h:44
@ SDP_TYPE_URL
Definition: bthsdpdef.h:51
@ SDP_TYPE_STRING
Definition: bthsdpdef.h:47
@ SDP_TYPE_UUID
Definition: bthsdpdef.h:46
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define SetLastError(x)
Definition: compat.h:752
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:105
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
const GLdouble * v
Definition: gl.h:2040
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLdouble s
Definition: gl.h:2039
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLsizeiptr size
Definition: glext.h:5919
GLenum const GLfloat * params
Definition: glext.h:5645
GLuint64EXT * result
Definition: glext.h:11304
GLfloat param
Definition: glext.h:5796
const char cursor[]
Definition: icontest.c:13
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
static IPrintDialogCallback callback
Definition: printdlg.c:326
static size_t elem
Definition: string.c:71
unsigned short USHORT
Definition: pedump.c:61
int const char int stream_size
Definition: zlib.h:814
#define memset(x, y, z)
Definition: compat.h:39
#define SDP_SIZE_DESC_2_BYTES
Definition: sdp.c:38
#define SDP_SIZE_DESC_NEXT_UINT16
Definition: sdp.c:43
static void bth_read_uint128(BYTE *s, SDP_ULARGE_INTEGER_16 *v)
Definition: sdp.c:46
#define SDP_SIZE_DESC_1_BYTE
Definition: sdp.c:37
#define SDP_SIZE_DESC_8_BYTES
Definition: sdp.c:40
DWORD WINAPI BluetoothSdpGetElementData(BYTE *stream, ULONG stream_size, SDP_ELEMENT_DATA *data)
Definition: sdp.c:248
static BYTE data_elem_size_desc(BYTE elem)
Definition: sdp.c:53
DWORD WINAPI BluetoothSdpGetAttributeValue(BYTE *stream, ULONG stream_size, USHORT attr_id, SDP_ELEMENT_DATA *data)
Definition: sdp.c:400
#define SDP_SIZE_DESC_4_BYTES
Definition: sdp.c:39
static BOOL WINAPI get_attr_value_callback(ULONG attr_id, BYTE *stream, ULONG stream_size, void *params)
Definition: sdp.c:384
static BOOL sdp_elem_read_var_size(BYTE *stream, ULONG stream_size, SIZE_T *read, BYTE size_desc, UINT32 *size)
Definition: sdp.c:60
DWORD WINAPI BluetoothSdpGetContainerElementData(BYTE *stream, ULONG stream_size, HBLUETOOTH_CONTAINER_ELEMENT *handle, SDP_ELEMENT_DATA *data)
Definition: sdp.c:263
#define BTH_READ_UINT16(s)
Definition: sdp.c:33
#define SDP_SIZE_DESC_NEXT_UINT8
Definition: sdp.c:42
#define BTH_READ_UINT64(s)
Definition: sdp.c:35
static const SDP_SPECIFICTYPE SDP_BASIC_TYPES[4][5]
Definition: sdp.c:85
BOOL WINAPI BluetoothSdpEnumAttributes(BYTE *stream, ULONG stream_size, PFN_BLUETOOTH_ENUM_ATTRIBUTES_CALLBACK callback, void *param)
Definition: sdp.c:320
#define SDP_ELEMENT_IS_ATTRID(d)
Definition: sdp.c:56
static BOOL sdp_read_specific_type(BYTE *stream, ULONG stream_size, SDP_SPECIFICTYPE st, SDP_ELEMENT_DATA *data, SIZE_T *read)
Definition: sdp.c:110
#define SDP_SIZE_DESC_16_BYTES
Definition: sdp.c:41
#define SDP_SIZE_DESC_NEXT_UINT32
Definition: sdp.c:44
static DWORD sdp_read_element_data(BYTE *stream, ULONG stream_size, SDP_ELEMENT_DATA *data, SIZE_T *read)
Definition: sdp.c:154
#define BTH_READ_UINT32(s)
Definition: sdp.c:34
static BYTE data_elem_type(BYTE elem)
Definition: sdp.c:52
#define TRACE(s)
Definition: solgame.cpp:4
union _SDP_ELEMENT_DATA::@2942 data
Definition: match.c:390
Definition: cookie.c:202
BYTE * attr_stream
Definition: sdp.c:380
USHORT attr_id
Definition: sdp.c:379
ULONG stream_size
Definition: sdp.c:381
Definition: parse.h:23
unsigned char * data
Definition: parse.h:26
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t UINT32
Definition: typedefs.h:59
uint32_t ULONG
Definition: typedefs.h:59
#define WINAPI
Definition: msvc.h:6
#define ERROR_INVALID_DATA
Definition: winerror.h:238
unsigned char BYTE
Definition: xxhash.c:193