/// <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); }
public byte[][] GetServiceRecordsUnparsedWindowsRaw(Guid service) { WqsOffset.AssertCheckLayout(); BlobOffsets.AssertCheckLayout(); //temporary workaround - sockets must be initialised Socket s = new Socket(AddressFamily32.Bluetooth, SocketType.Stream, BluetoothProtocolType.RFComm); //store variable length collection of records System.Collections.ArrayList records = new System.Collections.ArrayList(); byte[] sdp = null; WSAQUERYSET wqs = new WSAQUERYSET(); wqs.dwSize = WqsOffset.StructLength_60; wqs.dwNameSpace = WqsOffset.NsBth_16; #if NETCF CSADDR_INFO sainfo = new CSADDR_INFO(null, this.DeviceAddress , SocketType.Unknown, ProtocolType.Unknown); wqs.dwNumberOfCsAddrs = 1; IntPtr pSaInfo = Marshal32.AllocHGlobal(24); IntPtr pBrb = Marshal32.AllocHGlobal(256); IntPtr pService = Marshal32.AllocHGlobal(240); Marshal.StructureToPtr(sainfo, pSaInfo, false); wqs.lpcsaBuffer = pSaInfo; Marshal.WriteInt32(pBrb, 0, (int)SdpQueryType.SearchAttributeRequest); //write the service guid Marshal.Copy(service.ToByteArray(), 0, new IntPtr(pBrb.ToInt32() + 8), 16); Marshal.WriteInt16(pBrb, 24, (short)SdpSpecificType.Uuid128); Marshal.WriteInt16(pBrb, 26, 0); //write an empty guid to the next position Marshal.Copy(Guid.Empty.ToByteArray(), 0, new IntPtr(pBrb.ToInt32() + 28), 16); Marshal.WriteInt16(pBrb, 44, 0x0); Marshal.WriteInt16(pBrb, 46, 0); //number of attribute ranges Marshal.WriteInt32(pBrb, 248, 1); //min attribute Marshal.WriteInt16(pBrb, 252, 0); //max attribute Marshal.StructureToPtr((ushort)0xffff, (IntPtr)(pBrb.ToInt32() + 254), false); //Marshal.WriteInt16(pBrb, 254, 0x800); BLOB b = new BLOB(256, pBrb); IntPtr pb = Marshal32.AllocHGlobal(8); Marshal.StructureToPtr(b, pb, false); wqs.lpBlob = pb; #endif #if WinXP GCHandle hservice = GCHandle.Alloc(service.ToByteArray(), GCHandleType.Pinned); wqs.lpServiceClassId = hservice.AddrOfPinnedObject(); wqs.lpszContext = "(" + this.DeviceAddress.ToString("C") + ")"; // sb.ToString(); // hContext.AddrOfPinnedObject(); #endif IntPtr handle = IntPtr.Zero; int lookupresult; //start looking for Bluetooth services #if NETCF LookupFlags flagsForBegin; // Move above the #if is changed to use for desktop build too. flagsForBegin = 0; bool isQueryingLocalhost = false; try { BluetoothRadio theOne = BluetoothRadio.PrimaryRadio; // Only ever one on CE... if (theOne != null) { BluetoothAddress localAddr = theOne.LocalAddress; if (localAddr != null) { if (localAddr == this.DeviceAddress) { isQueryingLocalhost = true; } } } } catch (Exception ex) { System.Diagnostics.Debug.Fail("Exception in hack on CE to check if localhost: " + ex); } if (isQueryingLocalhost) { flagsForBegin |= LookupFlags.ResService; } #endif #if NETCF try { lookupresult = NativeMethods.WSALookupServiceBegin(ref wqs, flagsForBegin, out handle); #else lookupresult = NativeMethods.WSALookupServiceBegin(ref wqs, LookupFlags.FlushCache | LookupFlags.ReturnName | LookupFlags.ReturnBlob, out handle); #endif SocketBluetoothClient.ThrowSocketExceptionForHR(lookupresult); #if WinXP hservice.Free(); #endif while (lookupresult == 0) { byte[] sdpBuffer = new byte[6000]; BitConverter.GetBytes(WqsOffset.StructLength_60).CopyTo(sdpBuffer, WqsOffset.dwSize_0); BitConverter.GetBytes(WqsOffset.NsBth_16).CopyTo(sdpBuffer, WqsOffset.dwNameSpace_20); int size = sdpBuffer.Length; #if NETCF lookupresult = NativeMethods.WSALookupServiceNext(handle, (LookupFlags)0, ref size, sdpBuffer); #else lookupresult = NativeMethods.WSALookupServiceNext(handle, LookupFlags.FlushCache | LookupFlags.ReturnBlob, ref size, sdpBuffer); #endif if (lookupresult == -1) { const int WSA_E_NO_MORE = 10110; SocketBluetoothClient.ThrowSocketExceptionForHrExceptFor(lookupresult, WSA_E_NO_MORE); } else { IntPtr pBlob = InTheHand.Runtime.InteropServices.Marshal32.ReadIntPtr(sdpBuffer, WqsOffset.lpBlob_56); if (pBlob != IntPtr.Zero) { IntPtr pSdpBlob = InTheHand.Runtime.InteropServices.Marshal32.ReadIntPtr(pBlob, BlobOffsets.Offset_pBlobData_4); int cSdpBlob = Marshal.ReadInt32(pBlob); if (cSdpBlob > 2) { sdp = new byte[cSdpBlob]; Marshal.Copy(pSdpBlob, sdp, 0, cSdpBlob); records.Add(sdp); } } } } #if NETCF } finally { sainfo.Dispose(); Marshal32.FreeHGlobal(pSaInfo); Marshal32.FreeHGlobal(pb); Marshal32.FreeHGlobal(pBrb); } #endif //stop looking lookupresult = NativeMethods.WSALookupServiceEnd(handle); SocketBluetoothClient.ThrowSocketExceptionForHR(lookupresult); return (byte[][])records.ToArray(typeof(byte[])); }