예제 #1
0
        /// <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);
        }
예제 #2
0
        /// <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();
            }
        }
예제 #3
0
 internal static extern int WSALookupServiceBegin(ref WSAQUERYSET pQuerySet, LookupFlags dwFlags, out IntPtr lphLookup);
예제 #4
0
        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[]));
        }
예제 #5
0
 internal static extern int WSASetService(ref WSAQUERYSET lpqsRegInfo, WSAESETSERVICEOP essoperation, int dwControlFlags);