/// <exclude/> /// <summary> /// Remove a SDP record as added by <see cref="SetService"/>. /// </summary> /// <param name="handle">The handle. /// </param> /// <param name="sdpRecord">The raw record, presumably not actually used by the stack. /// </param> public static void RemoveService(IntPtr handle, byte[] sdpRecord) { BTHNS_SETBLOB blob = new BTHNS_SETBLOB(sdpRecord); blob.Handle = handle; WSAQUERYSET qs = new WSAQUERYSET(); qs.dwSize = WqsOffset.StructLength_60; qs.dwNameSpace = WqsOffset.NsBth_16; System.Diagnostics.Debug.Assert(Marshal.SizeOf(qs) == qs.dwSize, "WSAQUERYSET SizeOf == dwSize"); GCHandle hBlob = GCHandle.Alloc(blob.ToByteArray(), GCHandleType.Pinned); BLOB b = new BLOB(blob.Length, GCHandleHelper.AddrOfPinnedObject(hBlob)); GCHandle hb = GCHandle.Alloc(b, GCHandleType.Pinned); qs.lpBlob = hb.AddrOfPinnedObject(); try { int hresult = NativeMethods.WSASetService(ref qs, WSAESETSERVICEOP.RNRSERVICE_DELETE, 0); SocketBluetoothClient.ThrowSocketExceptionForHR(hresult); } finally { hb.Free(); hBlob.Free(); //release blob and associated GCHandles blob.Dispose(); } }
/// <exclude/> /// <summary> /// Add a SDP record. /// </summary> /// - /// <param name="sdpRecord">An array of <see cref="T:System.Byte"/> /// containing the complete SDP record. /// </param> /// <param name="cod">A <see cref="T:InTheHand.Net.Bluetooth.ServiceClass"/> /// containing any bits to set in the devices Class of Device value. /// </param> /// - /// <returns>A handle representing the record, pass to /// <see cref="RemoveService"/> to remote the record. /// </returns> public static IntPtr SetService(byte[] sdpRecord, ServiceClass cod) { BTHNS_SETBLOB blob = new BTHNS_SETBLOB(sdpRecord); //added for XP - adds class of device bits #if WinXP blob.CodService = (uint)cod; #endif WSAQUERYSET qs = new WSAQUERYSET(); qs.dwSize = WqsOffset.StructLength_60; qs.dwNameSpace = WqsOffset.NsBth_16; System.Diagnostics.Debug.Assert(Marshal.SizeOf(qs) == qs.dwSize, "WSAQUERYSET SizeOf == dwSize"); GCHandle hBlob = GCHandle.Alloc(blob.ToByteArray(), GCHandleType.Pinned); BLOB b = new BLOB(blob.Length, GCHandleHelper.AddrOfPinnedObject(hBlob)); GCHandle hb = GCHandle.Alloc(b, GCHandleType.Pinned); qs.lpBlob = hb.AddrOfPinnedObject(); try { int hresult = NativeMethods.WSASetService(ref qs, WSAESETSERVICEOP.RNRSERVICE_REGISTER, 0); SocketBluetoothClient.ThrowSocketExceptionForHR(hresult); } finally { hb.Free(); hBlob.Free(); } IntPtr handle = blob.Handle; blob.Dispose(); return(handle); }
/* ULONG __RPC_FAR *pSdpVersion; * ULONG __RPC_FAR *pRecordHandle; * ULONG Reserved[ 4 ]; * ULONG fSecurity; * ULONG fOptions; * ULONG ulRecordLength; * UCHAR pRecord[ 1 ]; * * public IntPtr pRecordHandle; * private uint fSecurity; * private uint fOptions; * public uint ulRecordLength; * public byte pRecord;*/ // // * Win32 //typedef struct _BTH_SET_SERVICE { // PULONG pSdpVersion; // HANDLE *pRecordHandle; // ULONG fCodService; // COD_SERVICE_* bits // ULONG Reserved[5]; // Reserved by system. Must be zero. // ULONG ulRecordLength; // length of pRecord which follows // UCHAR pRecord[1]; // SDP record as defined by bluetooth spec //} // * WinCE //struct _BTHNS_SETBLOB //{ // ULONG __RPC_FAR *pSdpVersion; // ULONG __RPC_FAR *pRecordHandle; // ULONG Reserved[ 4 ]; // ULONG fSecurity; // ULONG fOptions; // ULONG ulRecordLength; // UCHAR pRecord[ 1 ]; //} public BTHNS_SETBLOB(byte[] record) { BTHNS_SETBLOB.AssertCheckLayout(); //create data buffer m_data = new byte[StructLength_36 + record.Length]; pVersionHandle = GCHandle.Alloc(BTH_SDP_VERSION, GCHandleType.Pinned); pRecordHandle = GCHandle.Alloc((IntPtr)0, GCHandleType.Pinned); IntPtr vaddr = pVersionHandle.AddrOfPinnedObject(); IntPtr haddr = pRecordHandle.AddrOfPinnedObject(); Marshal32.WriteIntPtr(m_data, Offset_pSdpVersion_0, vaddr); Marshal32.WriteIntPtr(m_data, Offset_pRecordHandle_4, haddr); BitConverter.GetBytes(record.Length).CopyTo(m_data, Offset_ulRecordLength_32); //copy sdp record Buffer.BlockCopy(record, 0, m_data, StructLength_36, record.Length); }