Библиотека для работы с Bluetooth
01.01.2007
package BTClasses; {$R *.res} {$ALIGN 8} {$ASSERTIONS ON} {$BOOLEVAL OFF} {$DEBUGINFO ON} {$EXTENDEDSYNTAX ON} {$IMPORTEDDATA ON} {$IOCHECKS ON} {$LOCALSYMBOLS ON} {$LONGSTRINGS ON} {$OPENSTRINGS ON} {$OPTIMIZATION ON} {$OVERFLOWCHECKS OFF} {$RANGECHECKS OFF} {$REFERENCEINFO ON} {$SAFEDIVIDE OFF} {$STACKFRAMES OFF} {$TYPEDADDRESS OFF} {$VARSTRINGCHECKS ON} {$WRITEABLECONST OFF} {$MINENUMSIZE 1} {$IMAGEBASE $400000} {$IMPLICITBUILD OFF} requires rtl; contains BTRadio in 'BTRadio.pas', BluetoothAPI in 'BluetoothAPI.pas', BthSdpDef in 'BthSdpDef.pas', BTExceptions in 'BTExceptions.pas', BTStrings in 'BTStrings.pas', BTDevice in 'BTDevice.pas'; end.
unit BluetoothAPI; interface uses Windows, BthSdpDef; const BLUETOOTH_MAX_NAME_SIZE = 248; {$EXTERNALSYM BLUETOOTH_MAX_NAME_SIZE} BLUETOOTH_MAX_PASSKEY_SIZE = 16; {$EXTERNALSYM BLUETOOTH_MAX_PASSKEY_SIZE} BLUETOOTH_MAX_PASSKEY_BUFFER_SIZE = BLUETOOTH_MAX_PASSKEY_SIZE + 1; {$EXTERNALSYM BLUETOOTH_MAX_PASSKEY_BUFFER_SIZE} // *************************************************************************** // // Bluetooth Address // // *************************************************************************** type BTH_ADDR = Int64; {$EXTERNALSYM BTH_ADDR} _BLUETOOTH_ADDRESS = record case Integer of 0: (ullLong: BTH_ADDR); // easier to compare again BLUETOOTH_NULL_ADDRESS 1: (rgBytes: array [0..5] of Byte); // easier to format when broken out end; {$EXTERNALSYM _BLUETOOTH_ADDRESS} BLUETOOTH_ADDRESS = _BLUETOOTH_ADDRESS; {$EXTERNALSYM BLUETOOTH_ADDRESS} TBlueToothAddress = BLUETOOTH_ADDRESS; PBlueToothAddress = ^BLUETOOTH_ADDRESS; const BLUETOOTH_NULL_ADDRESS: TBlueToothAddress = (ullLong: 0;); {$EXTERNALSYM BLUETOOTH_NULL_ADDRESS} // *************************************************************************** // // Radio Enumeration // // Description: // This group of APIs enumerates the installed Bluetooth radios. // // Sample Usage: // HANDLE hRadio; // BLUETOOTH_FIND_RADIO_PARAMS btfrp = { sizeof(btfrp) }; // // HBLUETOOTH_RADIO_FIND hFind = BluetoothFindFirstRadio( &btfrp, &hRadio ); // if ( NULL != hFind ) // { // do // { // // // // TODO: Do something with the radio handle. // // // // CloseHandle( hRadio ); // // } while( BluetoothFindNextRadio( hFind, &hRadio ) ); // // BluetoothFindRadioClose( hFind ); // } // // *************************************************************************** type _BLUETOOTH_FIND_RADIO_PARAMS = record dwSize: DWORD; // IN sizeof this structure end; {$EXTERNALSYM _BLUETOOTH_FIND_RADIO_PARAMS} BLUETOOTH_FIND_RADIO_PARAMS = _BLUETOOTH_FIND_RADIO_PARAMS; {$EXTERNALSYM BLUETOOTH_FIND_RADIO_PARAMS} TBlueToothFindRadioParams = BLUETOOTH_FIND_RADIO_PARAMS; PBlueToothFindRadioParams = ^BLUETOOTH_FIND_RADIO_PARAMS; HBLUETOOTH_RADIO_FIND = THandle; {$EXTERNALSYM HBLUETOOTH_RADIO_FIND} // // Description: // Begins the enumeration of local Bluetooth radios. // // Parameters: // pbtfrp // A pointer to a BLUETOOTH_FIND_RADIO_PARAMS structure. The dwSize // member of this structure must match the sizeof the of the structure. // // phRadio // A pointer where the first radio HANDLE enumerated will be returned. // // Return Values: // NULL // Error opening radios or no devices found. Use GetLastError() for // more info. // // ERROR_INVALID_PARAMETER // pbtfrp parameter is NULL. // // ERROR_REVISION_MISMATCH // The pbtfrp structure is not the right length. // // ERROR_OUTOFMEMORY // Out of memory. // // other Win32 errors. // // any other // Success. The return handle is valid and phRadio points to a valid handle. // function BluetoothFindFirstRadio(const pbtfrp: PBlueToothFindRadioParams; var phRadio: THandle): HBLUETOOTH_RADIO_FIND; stdcall; {$EXTERNALSYM BluetoothFindFirstRadio} // // Description: // Finds the next installed Bluetooth radio. // // Parameters: // hFind // The handle returned by BluetoothFindFirstRadio(). // // phRadio // A pointer where the next radio HANDLE enumerated will be returned. // // Return Values: // TRUE // Next device succesfully found. pHandleOut points to valid handle. // // FALSE // No device found. pHandleOut points to an invalid handle. Call // GetLastError() for more details. // // ERROR_INVALID_HANDLE // The handle is NULL. // // ERROR_NO_MORE_ITEMS // No more radios found. // // ERROR_OUTOFMEMORY // Out of memory. // // other Win32 errors // function BluetoothFindNextRadio(hFind: HBLUETOOTH_RADIO_FIND; var phRadio: THandle): BOOL; stdcall; {$EXTERNALSYM BluetoothFindNextRadio} // // Description: // Closes the enumeration handle. // // Parameters // hFind // The handle returned by BluetoothFindFirstRadio(). // // Return Values: // TRUE // Handle succesfully closed. // // FALSE // Failure. Check GetLastError() for details. // // ERROR_INVALID_HANDLE // The handle is NULL. // function BluetoothFindRadioClose(hFind: HBLUETOOTH_RADIO_FIND): BOOL; stdcall; {$EXTERNALSYM BluetoothFindRadioClose} // *************************************************************************** // // Radio Information // // *************************************************************************** type _BLUETOOTH_RADIO_INFO = record dwSize: DWORD; // Size, in bytes, of this entire data structure address: BLUETOOTH_ADDRESS; // Address of the local radio szName: array [0..BLUETOOTH_MAX_NAME_SIZE - 1] of WideChar; // Name of the local radio ulClassofDevice: ULONG; // Class of device for the local radio lmpSubversion: Word; // lmpSubversion, manufacturer specifc. manufacturer: Word; // Manufacturer of the radio, BTH_MFG_Xxx value. For the most up to date // list, goto the Bluetooth specification website and get the Bluetooth // assigned numbers document. end; {$EXTERNALSYM _BLUETOOTH_RADIO_INFO} BLUETOOTH_RADIO_INFO = _BLUETOOTH_RADIO_INFO; {$EXTERNALSYM BLUETOOTH_RADIO_INFO} PBLUETOOTH_RADIO_INFO = ^BLUETOOTH_RADIO_INFO; {$EXTERNALSYM PBLUETOOTH_RADIO_INFO} TBlueToothRadioFind = BLUETOOTH_RADIO_INFO; PBlueToothRadioFind = PBLUETOOTH_RADIO_INFO; // // Description: // Retrieves the information about the radio represented by the handle. // // Parameters: // hRadio // Handle to a local radio retrieved through BluetoothFindFirstRadio() // et al or SetupDiEnumerateDeviceInterfaces() // // pRadioInfo // Radio information to be filled in. The dwSize member must match the // size of the structure. // // Return Values: // ERROR_SUCCESS // The information was retrieved successfully. // // ERROR_INVALID_PARAMETER // pRadioInfo or hRadio is NULL. // // ERROR_REVISION_MISMATCH // pRadioInfo->dwSize is invalid. // // other Win32 error codes. // function BluetoothGetRadioInfo(hRadio: THandle; var pRadioInfo: BLUETOOTH_RADIO_INFO): DWORD; stdcall; {$EXTERNALSYM BluetoothGetRadioInfo} // *************************************************************************** // // Device Information Stuctures // // *************************************************************************** type _BLUETOOTH_DEVICE_INFO = record dwSize: DWORD; // size, in bytes, of this structure - must be the sizeof(BLUETOOTH_DEVICE_INFO) Address: BLUETOOTH_ADDRESS; // Bluetooth address ulClassofDevice: ULONG; // Bluetooth "Class of Device" fConnected: BOOL; // Device connected/in use fRemembered: BOOL; // Device remembered fAuthenticated: BOOL; // Device authenticated/paired/bonded stLastSeen: SYSTEMTIME; // Last time the device was seen stLastUsed: SYSTEMTIME; // Last time the device was used for other than RNR, inquiry, or SDP szName: array [0..BLUETOOTH_MAX_NAME_SIZE - 1] of WideChar; // Name of the device end; {$EXTERNALSYM _BLUETOOTH_DEVICE_INFO} BLUETOOTH_DEVICE_INFO = _BLUETOOTH_DEVICE_INFO; {$EXTERNALSYM BLUETOOTH_DEVICE_INFO} PBLUETOOTH_DEVICE_INFO = BLUETOOTH_DEVICE_INFO; {$EXTERNALSYM PBLUETOOTH_DEVICE_INFO} TBlueToothDeviceInfo = BLUETOOTH_DEVICE_INFO; PBlueToothDeviceInfo = PBLUETOOTH_DEVICE_INFO; // *************************************************************************** // // Device Enumeration // // Description: // Enumerates the Bluetooth devices. The types of returned device depends // on the flags set in the BLUETOOTH_DEVICE_SEARCH_PARAMS (see structure // definition for details). // // Sample Usage: // HBLUETOOTH_DEVICE_FIND hFind; // BLUETOOTH_DEVICE_SEARCH_PARAMS btsp = { sizeof(btsp) }; // BLUETOOTH_DEVICE_INFO btdi = { sizeof(btdi) }; // // btsp.fReturnAuthenticated = TRUE; // btsp.fReturnRemembered = TRUE; // // hFind = BluetoothFindFirstDevice( &btsp, &btdi ); // if ( NULL != hFind ) // { // do // { // // // // TODO: Do something useful with the device info. // // // // } while( BluetoothFindNextDevice( hFind, &btdi ) ); // // BluetoothFindDeviceClose( hFind ); // } // // *************************************************************************** type _BLUETOOTH_DEVICE_SEARCH_PARAMS = record dwSize: DWORD; // IN sizeof this structure fReturnAuthenticated: BOOL; // IN return authenticated devices fReturnRemembered: BOOL; // IN return remembered devices fReturnUnknown: BOOL; // IN return unknown devices fReturnConnected: BOOL; // IN return connected devices fIssueInquiry: BOOL; // IN issue a new inquiry cTimeoutMultiplier: UCHAR; // IN timeout for the inquiry hRadio: THandle; // IN handle to radio to enumerate - NULL == all radios will be searched end; {$EXTERNALSYM _BLUETOOTH_DEVICE_SEARCH_PARAMS} BLUETOOTH_DEVICE_SEARCH_PARAMS = _BLUETOOTH_DEVICE_SEARCH_PARAMS; {$EXTERNALSYM BLUETOOTH_DEVICE_SEARCH_PARAMS} TBlueToothDeviceSearchParams = BLUETOOTH_DEVICE_SEARCH_PARAMS; HBLUETOOTH_DEVICE_FIND = THandle; {$EXTERNALSYM HBLUETOOTH_DEVICE_FIND} // // Description: // Begins the enumeration of Bluetooth devices. // // Parameters: // pbtsp // A pointer to a BLUETOOTH_DEVICE_SEARCH_PARAMS structure. This // structure contains the flags and inputs used to conduct the search. // See BLUETOOTH_DEVICE_SEARCH_PARAMS for details. // // pbtdi // A pointer to a BLUETOOTH_DEVICE_INFO structure to return information // about the first Bluetooth device found. Note that the dwSize member // of the structure must be the sizeof(BLUETOOTH_DEVICE_INFO) before // calling because the APIs hast to know the size of the buffer being // past in. The dwSize member must also match the exact // sizeof(BLUETOOTH_DEVICE_INFO) or the call will fail. // // Return Values: // NULL // Error opening radios or not devices found. Use GetLastError for more info. // // ERROR_INVALID_PARAMETER // pbtsp parameter or pbtdi parameter is NULL. // // ERROR_REVISION_MISMATCH // The pbtfrp structure is not the right length. // // other Win32 errors // // any other value // Success. The return handle is valid and pbtdi points to valid data. // function BluetoothFindFirstDevice(const pbtsp: BLUETOOTH_DEVICE_SEARCH_PARAMS; var pbtdi: BLUETOOTH_DEVICE_INFO): HBLUETOOTH_DEVICE_FIND; stdcall; {$EXTERNALSYM BluetoothFindFirstDevice} // // Description: // Finds the next Bluetooth device in the enumeration. // // Parameters: // hFind // The handle returned from BluetoothFindFirstDevice(). // // pbtdi // A pointer to a BLUETOOTH_DEVICE_INFO structure to return information // about the first Bluetooth device found. Note that the dwSize member // of the structure must be the sizeof(BLUETOOTH_DEVICE_INFO) before // calling because the APIs hast to know the size of the buffer being // past in. The dwSize member must also match the exact // sizeof(BLUETOOTH_DEVICE_INFO) or the call will fail. // // Return Values: // TRUE // Next device succesfully found. pHandleOut points to valid handle. // // FALSE // No device found. pHandleOut points to an invalid handle. Call // GetLastError() for more details. // // ERROR_INVALID_HANDLE // The handle is NULL. // // ERROR_NO_MORE_ITEMS // No more radios found. // // ERROR_OUTOFMEMORY // Out of memory. // // other Win32 errors // function BluetoothFindNextDevice(hFind: HBLUETOOTH_DEVICE_FIND; var pbtdi: BLUETOOTH_DEVICE_INFO): BOOL; stdcall; {$EXTERNALSYM BluetoothFindNextDevice} // // Description: // Closes the enumeration handle. // // Parameters: // hFind // The handle returned from BluetoothFindFirstDevice(). // // Return Values: // TRUE // Handle succesfully closed. // // FALSE // Failure. Check GetLastError() for details. // // ERROR_INVALID_HANDLE // The handle is NULL. // function BluetoothFindDeviceClose(hFind: HBLUETOOTH_DEVICE_FIND): BOOL; stdcall; {$EXTERNALSYM BluetoothFindDeviceClose} // // Description: // Retrieves information about a remote device. // // Fill in the dwSize and the Address members of the pbtdi structure // being passed in. On success, the rest of the members will be filled // out with the information that the system knows. // // Parameters: // hRadio // Handle to a local radio retrieved through BluetoothFindFirstRadio() // et al or SetupDiEnumerateDeviceInterfaces() // // pbtdi // A pointer to a BLUETOOTH_DEVICE_INFO structure to return information // about the first Bluetooth device found. The dwSize member of the // structure must be the sizeof the structure in bytes. The Address // member must be filled out with the Bluetooth address of the remote // device. // // Return Values: // ERROR_SUCCESS // Success. Information returned. // // ERROR_REVISION_MISMATCH // The size of the BLUETOOTH_DEVICE_INFO isn't compatible. Check // the dwSize member of the BLUETOOTH_DEVICE_INFO structure you // passed in. // // ERROR_NOT_FOUND // The radio is not known by the system or the Address field of // the BLUETOOTH_DEVICE_INFO structure is all zeros. // // ERROR_INVALID_PARAMETER // pbtdi is NULL. // // other error codes // function BluetoothGetDeviceInfo(hRadio: THandle; var pbtdi: BLUETOOTH_DEVICE_INFO): DWORD; stdcall; {$EXTERNALSYM BluetoothGetDeviceInfo} // // Description: // Updates the computer local cache about the device. // // Parameters: // pbtdi // A pointer to the BLUETOOTH_DEVICE_INFO structure to be updated. // The following members must be valid: // dwSize // Must match the size of the structure. // Address // Must be a previously found radio address. // szName // New name to be stored. // // Return Values: // ERROR_SUCCESS // The device information was updated successfully. // // ERROR_INVALID_PARAMETER // pbtdi is NULL. // // ERROR_REVISION_MISMATCH // pbtdi->dwSize is invalid. // // other Win32 error codes. // function BluetoothUpdateDeviceRecord(var pbtdi: BLUETOOTH_DEVICE_INFO): DWORD; stdcall; {$EXTERNALSYM BluetoothUpdateDeviceRecord} // // Description: // Delete the authentication (aka "bond") between the computer and the // device. Also purges any cached information about the device. // // Return Values: // ERROR_SUCCESS // The device was removed successfully. // // ERROR_NOT_FOUND // The device was not found. If no Bluetooth radio is installed, // the devices could not be enumerated or removed. // function BluetoothRemoveDevice(var pAddress: BLUETOOTH_ADDRESS): DWORD; stdcall; {$EXTERNALSYM BluetoothRemoveDevice} // *************************************************************************** // // Device Picker Dialog // // Description: // Invokes a common dialog for selecting Bluetooth devices. The list // of devices displayed to the user is determined by the flags and // settings the caller specifies in the BLUETOOTH_SELECT_DEVICE_PARAMS // (see structure definition for more details). // // If BluetoothSelectDevices() returns TRUE, the caller must call // BluetoothSelectDevicesFree() or memory will be leaked within the // process. // // Sample Usage: // // BLUETOOTH_SELECT_DEVICE_PARAMS btsdp = { sizeof(btsdp) }; // // btsdp.hwndParent = hDlg; // btsdp.fShowUnknown = TRUE; // btsdp.fAddNewDeviceWizard = TRUE; // // BOOL b = BluetoothSelectDevices( &btsdp ); // if ( b ) // { // BLUETOOTH_DEVICE_INFO * pbtdi = btsdp.pDevices; // for ( ULONG cDevice = 0; cDevice < btsdp.cNumDevices; cDevice ++ ) // { // if ( pbtdi->fAuthenticated || pbtdi->fRemembered ) // { // // // // TODO: Do something usefull with the device info // // // } // // pbtdi = (BLUETOOTH_DEVICE_INFO *) ((LPBYTE)pbtdi + pbtdi->dwSize); // } // // BluetoothSelectDevicesFree( &btsdp ); // } // // *************************************************************************** type _BLUETOOTH_COD_PAIRS = record ulCODMask: ULONG; // ClassOfDevice mask to compare pcszDescription: LPWSTR; // Descriptive string of mask end; {$EXTERNALSYM _BLUETOOTH_COD_PAIRS} BLUETOOTH_COD_PAIRS = _BLUETOOTH_COD_PAIRS; {$EXTERNALSYM BLUETOOTH_COD_PAIRS} TBlueToothCodPairs = BLUETOOTH_COD_PAIRS; PBlueToothCodPairs = ^BLUETOOTH_COD_PAIRS; PFN_DEVICE_CALLBACK = function(pvParam: Pointer; pDevice: PBLUETOOTH_DEVICE_INFO): BOOL; stdcall; {$EXTERNALSYM PFN_DEVICE_CALLBACK} _BLUETOOTH_SELECT_DEVICE_PARAMS = record dwSize: DWORD; // IN sizeof this structure cNumOfClasses: ULONG; // IN Number in prgClassOfDevice - if ZERO search for all devices prgClassOfDevices: PBlueToothCodPairs; // IN Array of CODs to find. pszInfo: LPWSTR; // IN If not NULL, sets the "information" text hwndParent: HWND; // IN parent window - NULL == no parent fForceAuthentication: BOOL; // IN If TRUE, authenication will be forced before returning fShowAuthenticated: BOOL; // IN If TRUE, authenticated devices will be shown in the picker fShowRemembered: BOOL; // IN If TRUE, remembered devices will be shown in the picker fShowUnknown: BOOL; // IN If TRUE, unknown devices that are not authenticated or "remember" will be shown. fAddNewDeviceWizard: BOOL; // IN If TRUE, invokes the add new device wizard. fSkipServicesPage: BOOL; // IN If TRUE, skips the "Services" page in the wizard. pfnDeviceCallback: PFN_DEVICE_CALLBACK; // IN If non-NULL, a callback that will be called for each device. If the // the callback returns TRUE, the item will be added. If the callback is // is FALSE, the item will not be shown. pvParam: Pointer; // IN Parameter to be passed to pfnDeviceCallback as the pvParam. cNumDevices: DWORD; // IN number calles wants - ZERO == no limit. // OUT the number of devices returned. pDevices: PBLUETOOTH_DEVICE_INFO; // OUT pointer to an array for BLUETOOTH_DEVICE_INFOs. // call BluetoothSelectDevicesFree() to free end; {$EXTERNALSYM _BLUETOOTH_SELECT_DEVICE_PARAMS} BLUETOOTH_SELECT_DEVICE_PARAMS = _BLUETOOTH_SELECT_DEVICE_PARAMS; {$EXTERNALSYM BLUETOOTH_SELECT_DEVICE_PARAMS} TBlueToothSelectDeviceParams = BLUETOOTH_SELECT_DEVICE_PARAMS; PBlueToothSelectDeviceParams = ^BLUETOOTH_SELECT_DEVICE_PARAMS; // // Description: // (See header above) // // Return Values: // TRUE // User selected a device. pbtsdp->pDevices points to valid data. // Caller should check the fAuthenticated && fRemembered flags to // determine which devices we successfuly authenticated or valid // selections by the user. // // Use BluetoothSelectDevicesFree() to free the nessecary data // such as pDevices only if this function returns TRUE. // // FALSE // No valid data returned. Call GetLastError() for possible details // of the failure. If GLE() is: // // ERROR_CANCELLED // The user cancelled the request. // // ERROR_INVALID_PARAMETER // The pbtsdp is NULL. // // ERROR_REVISION_MISMATCH // The structure passed in as pbtsdp is of an unknown size. // // other WIN32 errors // function BluetoothSelectDevices(pbtsdp: PBlueToothSelectDeviceParams): BOOL; stdcall; {$EXTERNALSYM BluetoothSelectDevices} // // Description: // This function should only be called if BluetoothSelectDevices() returns // TRUE. This function will free any memory and resource returned by the // BluetoothSelectDevices() in the BLUETOOTH_SELECT_DEVICE_PARAMS // structure. // // Return Values: // TRUE // Success. // // FALSE // Nothing to free. // function BluetoothSelectDevicesFree(pbtsdp: PBlueToothSelectDeviceParams): BOOL; stdcall; {$EXTERNALSYM BluetoothSelectDevicesFree} // *************************************************************************** // // Device Property Sheet // // *************************************************************************** // // Description: // Invokes the CPLs device info property sheet. // // Parameters: // hwndParent // HWND to parent the property sheet. // // pbtdi // A pointer to a BLUETOOTH_DEVICE_INFO structure of the device // to be displayed. // // Return Values: // TRUE // The property page was successfully displayed. // // FALSE // Failure. The property page was not displayed. Check GetLastError // for more details. // function BluetoothDisplayDeviceProperties(hwndParent: HWND; pbtdi: PBLUETOOTH_DEVICE_INFO): BOOL; stdcall; {$EXTERNALSYM BluetoothDisplayDeviceProperties} // *************************************************************************** // // Radio Authentication // // *************************************************************************** // // Description: // Sends an authentication request to a remote device. // // There are two modes of operation. "Wizard mode" and "Blind mode." // // "Wizard mode" is invoked when the pszPasskey is NULL. This will cause // the "Bluetooth Connection Wizard" to be invoked. The user will be // prompted to enter a passkey during the wizard after which the // authentication request will be sent. The user will see the success // or failure of the authentication attempt. The user will also be // given the oppurtunity to try to fix a failed authentication. // // "Blind mode" is invoked when the pszPasskey is non-NULL. This will // cause the computer to send a authentication request to the remote // device. No UI is ever displayed. The Bluetooth status code will be // mapped to a Win32 Error code. // // Parameters: // // hwndParent // The window to parent the authentication wizard. If NULL, the // wizard will be parented off the desktop. // // hRadio // A valid local radio handle or NULL. If NULL, then all radios will // be tired. If any of the radios succeed, then the call will // succeed. // // pbtdi // BLUETOOTH_DEVICE_INFO record of the device to be authenticated. // // pszPasskey // PIN to be used to authenticate the device. If NULL, then UI is // displayed and the user steps through the authentication process. // If not NULL, no UI is shown. The passkey is NOT NULL terminated. // // ulPasskeyLength // Length of szPassKey in bytes. The length must be less than or // equal to BLUETOOTH_MAX_PASSKEY_SIZE * sizeof(WCHAR). // // Return Values: // // ERROR_SUCCESS // Success. // // ERROR_CANCELLED // User aborted the operation. // // ERROR_INVALID_PARAMETER // The device structure in pbtdi is invalid. // // ERROR_NO_MORE_ITEMS // The device in pbtdi is already been marked as authenticated. // // other WIN32 error // Failure. Return value is the error code. // // For "Blind mode," here is the current mapping of Bluetooth status // code to Win32 error codes: // // { BTH_ERROR_SUCCESS, ERROR_SUCCESS }, // { BTH_ERROR_NO_CONNECTION, ERROR_DEVICE_NOT_CONNECTED }, // { BTH_ERROR_PAGE_TIMEOUT, WAIT_TIMEOUT }, // { BTH_ERROR_HARDWARE_FAILURE, ERROR_GEN_FAILURE }, // { BTH_ERROR_AUTHENTICATION_FAILURE, ERROR_NOT_AUTHENTICATED }, // { BTH_ERROR_MEMORY_FULL, ERROR_NOT_ENOUGH_MEMORY }, // { BTH_ERROR_CONNECTION_TIMEOUT, WAIT_TIMEOUT }, // { BTH_ERROR_LMP_RESPONSE_TIMEOUT, WAIT_TIMEOUT }, // { BTH_ERROR_MAX_NUMBER_OF_CONNECTIONS, ERROR_REQ_NOT_ACCEP }, // { BTH_ERROR_PAIRING_NOT_ALLOWED, ERROR_ACCESS_DENIED }, // { BTH_ERROR_UNSPECIFIED_ERROR, ERROR_NOT_READY }, // { BTH_ERROR_LOCAL_HOST_TERMINATED_CONNECTION, ERROR_VC_DISCONNECTED }, // function BluetoothAuthenticateDevice( hwndParent: HWND; hRadio: THandle; pbtbi: PBLUETOOTH_DEVICE_INFO; pszPasskey: PWideChar; ulPasskeyLength: ULONG): DWORD; stdcall; {$EXTERNALSYM BluetoothAuthenticateDevice} // // Description: // Allows the caller to prompt for multiple devices to be authenticated // within a single instance of the "Bluetooth Connection Wizard." // // Parameters: // // hwndParent // The window to parent the authentication wizard. If NULL, the // wizard will be parented off the desktop. // // hRadio // A valid local radio handle or NULL. If NULL, then all radios will // be tired. If any of the radios succeed, then the call will // succeed. // // cDevices // Number of devices in the rgbtdi array. // // rgbtdi // An array BLUETOOTH_DEVICE_INFO records of the devices to be // authenticated. // // Return Values: // // ERROR_SUCCESS // Success. Check the fAuthenticate flag on each of the devices. // // ERROR_CANCELLED // User aborted the operation. Check the fAuthenticate flags on // each device to determine if any of the devices were authenticated // before the user cancelled the operation. // // ERROR_INVALID_PARAMETER // One of the items in the array of devices is invalid. // // ERROR_NO_MORE_ITEMS // All the devices in the array of devices are already been marked as // being authenticated. // // other WIN32 error // Failure. Return value is the error code. // function BluetoothAuthenticateMultipleDevices( hwndParent: HWND; hRadio: THandle; cDevices: DWORD; pbtdi: PBLUETOOTH_DEVICE_INFO): DWORD; stdcall; {$EXTERNALSYM BluetoothAuthenticateMultipleDevices} // *************************************************************************** // // Bluetooth Services // // *************************************************************************** const BLUETOOTH_SERVICE_DISABLE = $00; {$EXTERNALSYM BLUETOOTH_SERVICE_DISABLE} BLUETOOTH_SERVICE_ENABLE = $01; {$EXTERNALSYM BLUETOOTH_SERVICE_ENABLE} BLUETOOTH_SERVICE_MASK = BLUETOOTH_SERVICE_ENABLE or BLUETOOTH_SERVICE_DISABLE; {$EXTERNALSYM BLUETOOTH_SERVICE_MASK} // // Description: // Enables/disables the services for a particular device. // // The system maintains a mapping of service guids to supported drivers for // Bluetooth-enabled devices. Enabling a service installs the corresponding // device driver. Disabling a service removes the corresponding device driver. // // If a non-supported service is enabled, a driver will not be installed. // // Parameters // hRadio // Handle of the local Bluetooth radio device. // // pbtdi // Pointer to a BLUETOOTH_DEVICE_INFO record. // // pGuidService // The service GUID on the remote device. // // dwServiceFlags // Flags to adjust the service. // BLUETOOTH_SERVICE_DISABLE - disable the service // BLUETOOTH_SERVICE_ENABLE - enables the service // // Return Values: // ERROR_SUCCESS // The call was successful. // // ERROR_INVALID_PARAMETER // dwServiceFlags are invalid. // // ERROR_SERVICE_DOES_NOT_EXIST // The GUID in pGuidService is not supported. // // other WIN32 error // The call failed. // function BluetoothSetServiceState( hRadio: THandle; pbtdi: PBLUETOOTH_DEVICE_INFO; const pGuidService: TGUID; dwServiceFlags: DWORD): DWORD; stdcall; {$EXTERNALSYM BluetoothSetServiceState} // // Description: // Enumerates the services guids enabled on a particular device. If hRadio // is NULL, all device will be searched for the device and all the services // enabled will be returned. // // Parameters: // hRadio // Handle of the local Bluetooth radio device. If NULL, it will search // all the radios for the address in the pbtdi. // // pbtdi // Pointer to a BLUETOOTH_DEVICE_INFO record. // // pcService // On input, the number of records pointed to by pGuidServices. // On output, the number of valid records return in pGuidServices. // // pGuidServices // Pointer to memory that is at least *pcService in length. // // Return Values: // ERROR_SUCCESS // The call succeeded. pGuidServices is valid. // // ERROR_MORE_DATA // The call succeeded. pGuidService contains an incomplete list of // enabled service GUIDs. // // other WIN32 errors // The call failed. // function BluetoothEnumerateInstalledServices( hRadio: THandle; pbtdi: PBLUETOOTH_DEVICE_INFO; var pcServices: DWORD; pGuidServices: PGUID): DWORD; stdcall; {$EXTERNALSYM BluetoothEnumerateInstalledServices} // // Description: // Change the discovery state of the local radio(s). // If hRadio is NULL, all the radios will be set. // // Use BluetoothIsDiscoverable() to determine the radios current state. // // The system ensures that a discoverable system is connectable, thus // the radio must allow incoming connections (see // BluetoothEnableIncomingConnections) prior to making a radio // discoverable. Failure to do so will result in this call failing // (returns FALSE). // // Parameters: // hRadio // If not NULL, changes the state of a specific radio. // If NULL, the API will interate through all the radios. // // fEnabled // If FALSE, discovery will be disabled. // // Return Values // TRUE // State was successfully changed. If the caller specified NULL for // hRadio, at least of the radios accepted the state change. // // FALSE // State was not changed. If the caller specified NULL for hRadio, all // of the radios did not accept the state change. // function BluetoothEnableDiscovery(hRadio: THandle; fEnabled: BOOL): BOOL; stdcall; {$EXTERNALSYM BluetoothEnableDiscovery} // // Description: // Determines if the Bluetooth radios are discoverable. If there are // multiple radios, the first one to say it is discoverable will cause // this function to return TRUE. // // Parameters: // hRadio // Handle of the radio to check. If NULL, it will check all local // radios. // // Return Values: // TRUE // A least one radio is discoverable. // // FALSE // No radios are discoverable. // function BluetoothIsDiscoverable(hRadio: THandle): BOOL; stdcall; {$EXTERNALSYM BluetoothIsDiscoverable} // // Description: // Enables/disables the state of a radio to accept incoming connections. // If hRadio is NULL, all the radios will be set. // // Use BluetoothIsConnectable() to determine the radios current state. // // The system enforces that a radio that is not connectable is not // discoverable too. The radio must be made non-discoverable (see // BluetoothEnableDiscovery) prior to making a radio non-connectionable. // Failure to do so will result in this call failing (returns FALSE). // // Parameters: // hRadio // If not NULL, changes the state of a specific radio. // If NULL, the API will interate through all the radios. // // fEnabled // If FALSE, incoming connection will be disabled. // // Return Values // TRUE // State was successfully changed. If the caller specified NULL for // hRadio, at least of the radios accepted the state change. // // FALSE // State was not changed. If the caller specified NULL for hRadio, all // of the radios did not accept the state change. // function BluetoothEnableIncomingConnections(hRadio: THandle; fEnabled: BOOL): BOOL; stdcall; {$EXTERNALSYM BluetoothEnableIncomingConnections} // // Description: // Determines if the Bluetooth radios are connectable. If there are // multiple radios, the first one to say it is connectable will cause // this function to return TRUE. // // Parameters: // hRadio // Handle of the radio to check. If NULL, it will check all local // radios. // // Return Values: // TRUE // A least one radio is allowing incoming connections. // // FALSE // No radios are allowing incoming connections. // function BluetoothIsConnectable(hRadio: THandle): BOOL; stdcall; {$EXTERNALSYM BluetoothIsConnectable} // *************************************************************************** // // Authentication Registration // // *************************************************************************** type HBLUETOOTH_AUTHENTICATION_REGISTRATION = THandle; {$EXTERNALSYM HBLUETOOTH_AUTHENTICATION_REGISTRATION} PFN_AUTHENTICATION_CALLBACK = function(pvParam: Pointer; pDevice: PBLUETOOTH_DEVICE_INFO): BOOL; stdcall; {$EXTERNALSYM PFN_AUTHENTICATION_CALLBACK} // // Description: // Registers a callback function to be called when a particular device // requests authentication. The request is sent to the last application // that requested authentication for a particular device. // // Parameters: // pbtdi // A pointer to a BLUETOOTH_DEVICE_INFO structure. The Bluetooth // address will be used for comparision. // // phRegHandle // A pointer to where the registration HANDLE value will be // stored. Call BluetoothUnregisterAuthentication() to close // the handle. // // pfnCallback // The function that will be called when the authentication event // occurs. This function should match PFN_AUTHENTICATION_CALLBACK's // prototype. // // pvParam // Optional parameter to be past through to the callback function. // This can be anything the application was to define. // // Return Values: // ERROR_SUCCESS // Success. A valid registration handle was returned. // // ERROR_OUTOFMEMORY // Out of memory. // // other Win32 error. // Failure. The registration handle is invalid. // function BluetoothRegisterForAuthentication( pbtdi: PBLUETOOTH_DEVICE_INFO; var phRegHandle: HBLUETOOTH_AUTHENTICATION_REGISTRATION; pfnCallback: PFN_AUTHENTICATION_CALLBACK; pvParam: Pointer): DWORD; stdcall; {$EXTERNALSYM BluetoothRegisterForAuthentication} // // Description: // Unregisters an authentication callback and closes the handle. See // BluetoothRegisterForAuthentication() for more information about // authentication registration. // // Parameters: // hRegHandle // Handle returned by BluetoothRegisterForAuthentication(). // // Return Value: // TRUE // The handle was successfully closed. // // FALSE // The handle was not successfully closed. Check GetLastError for // more details. // // ERROR_INVALID_HANDLE // The handle is NULL. // // other Win32 errors. // function BluetoothUnregisterAuthentication(hRegHandle: HBLUETOOTH_AUTHENTICATION_REGISTRATION): BOOL; stdcall; {$EXTERNALSYM BluetoothUnregisterAuthentication} // // Description: // This function should be called after receiving an authentication request // to send the passkey response. // // Parameters: // // hRadio // Optional handle to the local radio. If NULL, the function will try // each radio until one succeeds. // // pbtdi // A pointer to a BLUETOOTH_DEVICE_INFO structure describing the device // being authenticated. This can be the same structure passed to the // callback function. // // pszPasskey // A pointer to UNICODE zero-terminated string of the passkey response // that should be sent back to the authenticating device. // // Return Values: // ERROR_SUCESS // The device accepted the passkey response. The device is authenticated. // // ERROR_CANCELED // The device denied the passkey reponse. This also will returned if there // is a communications problem with the local radio. // // E_FAIL // The device returned a failure code during authentication. // // other Win32 error codes // function BluetoothSendAuthenticationResponse( hRadio: THandle; pbtdi: PBLUETOOTH_DEVICE_INFO; pszPasskey: LPWSTR): DWORD; stdcall; {$EXTERNALSYM BluetoothSendAuthenticationResponse} // *************************************************************************** // // SDP Parsing Functions // // *************************************************************************** type TSpdElementDataString = record // raw string buffer, may not be encoded as ANSI, use // BluetoothSdpGetString to convert the value if it is described // by the base language attribute ID list value: PBYTE; // raw length of the string, may not be NULL terminuated length: ULONG; end; TSpdElementDataUrl = record value: PBYTE; length: ULONG; end; // type == SDP_TYPE_SEQUENCE TSpdElementDataSequence = record // raw sequence, starts at sequence element header value: PBYTE; // raw sequence length length: ULONG; end; // type == SDP_TYPE_ALTERNATIVE TSpdElementDataAlternative = record // raw alternative, starts at alternative element header value: PBYTE; // raw alternative length length: ULONG; end; _SDP_ELEMENT_DATA = record // // Enumeration of SDP element types. Generic element types will have a // specificType value other then SDP_ST_NONE. The generic types are: // o SDP_TYPE_UINT // o SDP_TYPE_INT // o SDP_TYPE_UUID // type_: SDP_TYPE; // // Specific types for the generic SDP element types. // specificType: SDP_SPECIFICTYPE; // // Union of all possible data types. type and specificType will indicate // which field is valid. For types which do not have a valid specificType, // specific type will be SDP_ST_NONE. // case Integer of // type == SDP_TYPE_INT 0: (int128: SDP_LARGE_INTEGER_16); // specificType == SDP_ST_INT128 1: (int64: LONGLONG); // specificType == SDP_ST_INT64 2: (int32: Integer); // specificType == SDP_ST_INT32 3: (int16: SHORT); // specificType == SDP_ST_INT16 4: (int8: CHAR); // specificType == SDP_ST_INT8 // type == SDP_TYPE_UINT 5: (uint128: SDP_ULARGE_INTEGER_16); // specificType == SDP_ST_UINT128 6: (uint64: Int64); // specificType == SDP_ST_UINT64 7: (uint32: ULONG); // specificType == SDP_ST_UINT32 8: (uint16: Word); // specificType == SDP_ST_UINT16 9: (uint8: UCHAR); // specificType == SDP_ST_UINT8 // type == SDP_TYPE_BOOLEAN 10: (booleanVal: UCHAR); // type == SDP_TYPE_UUID 11: (uuid128: TGUID); // specificType == SDP_ST_UUID128 12: (uuid32: ULONG); // specificType == SDP_ST_UUID32 13: (uuid16: Word); // specificType == SDP_ST_UUID32 // type == SDP_TYPE_STRING 14: (string_: TSpdElementDataString); // type == SDP_TYPE_URL 15: (url: TSpdElementDataUrl); // type == SDP_TYPE_SEQUENCE 16: (sequence: TSpdElementDataSequence); // type == SDP_TYPE_ALTERNATIVE 17: (alternative: TSpdElementDataAlternative); end; {$EXTERNALSYM _SDP_ELEMENT_DATA} SDP_ELEMENT_DATA = _SDP_ELEMENT_DATA; {$EXTERNALSYM SDP_ELEMENT_DATA} PSDP_ELEMENT_DATA = ^SDP_ELEMENT_DATA; {$EXTERNALSYM PSDP_ELEMENT_DATA} TSdpElementData = SDP_ELEMENT_DATA; PSdpElementData = PSDP_ELEMENT_DATA; // // Description: // Retrieves and parses the element found at pSdpStream // // Parameters: // IN pSdpStream // pointer to valid SDP stream // // IN cbSdpStreamLength // length of pSdpStream in bytes // // OUT pData // pointer to be filled in with the data of the SDP element at the // beginning of pSdpStream // // Return Values: // ERROR_INVALID_PARAMETER // one of required parameters is NULL or the pSdpStream is invalid // // ERROR_SUCCESS // the sdp element was parsed correctly // function BluetoothSdpGetElementData( pSdpStream: PBYTE; cbSdpStreamLength: ULONG; pData: PSDP_ELEMENT_DATA): DWORD; stdcall; {$EXTERNALSYM BluetoothSdpGetElementData} type HBLUETOOTH_CONTAINER_ELEMENT = THandle; {$EXTERNALSYM HBLUETOOTH_CONTAINER_ELEMENT} // // Description: // Iterates over a container stream, returning each elemetn contained with // in the container element at the beginning of pContainerStream // // Parameters: // IN pContainerStream // pointer to valid SDP stream whose first element is either a sequence // or alternative // // IN cbContainerlength // length in bytes of pContainerStream // // IN OUT pElement // Value used to keep track of location within the stream. The first // time this function is called for a particular container, *pElement // should equal NULL. Upon subsequent calls, the value should be // unmodified. // // OUT pData // pointer to be filled in with the data of the SDP element at the // current element of pContainerStream // // Return Values: // ERROR_SUCCESS // The call succeeded, pData contains the data // // ERROR_NO_MORE_ITEMS // There are no more items in the list, the caller should cease calling // BluetoothSdpGetContainerElementData for this container. // // ERROR_INVALID_PARAMETER // A required pointer is NULL or the container is not a valid SDP // stream // // Usage example: // // HBLUETOOTH_CONTAINER_ELEMENT element; // SDP_ELEMENT_DATA data; // ULONG result; // // element = NULL; // // while (TRUE) { // result = BluetoothSdpGetContainerElementData( // pContainer, ulContainerLength, &element, &data); // // if (result == ERROR_NO_MORE_ITEMS) { // // We are done // break; // } // else if (result != ERROR_SUCCESS) { // // error // } // // // do something with data ... // } // // function BluetoothSdpGetContainerElementData( pContainerStream: PBYTE; cbContainerLength: ULONG; var pElement: HBLUETOOTH_CONTAINER_ELEMENT; pData: PSDP_ELEMENT_DATA): DWORD; stdcall; {$EXTERNALSYM BluetoothSdpGetContainerElementData} // // Description: // Retrieves the attribute value for the given attribute ID. pRecordStream // must be an SDP stream that is formatted as an SDP record, a SEQUENCE // containing UINT16 + element pairs. // // Parameters: // IN pRecordStream // pointer to a valid SDP stream which is formatted as a singl SDP // record // // IN cbRecordlnegh // length of pRecordStream in bytes // // IN usAttributeId // the attribute ID to search for. see bthdef.h for SDP_ATTRIB_Xxx // values. // // OUT pAttributeData // pointer that will contain the attribute ID's value // // Return Values: // ERRROR_SUCCESS // Call succeeded, pAttributeData contains the attribute value // // ERROR_INVALID_PARAMETER // One of the required pointers was NULL, pRecordStream was not a valid // SDP stream, or pRecordStream was not a properly formatted SDP record // // ERROR_FILE_NOT_FOUND // usAttributeId was not found in the record // // Usage: // // ULONG result; // SDP_DATA_ELEMENT data; // // result = BluetoothSdpGetAttributeValue( // pRecordStream, cbRecordLength, SDP_ATTRIB_RECORD_HANDLE, &data); // if (result == ERROR_SUCCESS) { // printf("record handle is 0x%x\n", data.data.uint32); // } // function BluetoothSdpGetAttributeValue( pRecordStream: PBYTE; cbRecordLength: ULONG; usAttributeId: Word; pAttributeData: PSDP_ELEMENT_DATA): DWORD; stdcall; {$EXTERNALSYM BluetoothSdpGetAttributeValue} // // These three fields correspond one to one with the triplets defined in the // SDP specification for the language base attribute ID list. // type _SDP_STRING_TYPE_DATA = record // // How the string is encoded according to ISO 639:1988 (E/F): "Code // for the representation of names of languages". // encoding: Word; // // MIBE number from IANA database // mibeNum: Word; // // The base attribute where the string is to be found in the record // attributeId: Word; end; {$EXTERNALSYM _SDP_STRING_TYPE_DATA} SDP_STRING_TYPE_DATA = _SDP_STRING_TYPE_DATA; {$EXTERNALSYM SDP_STRING_TYPE_DATA} PSDP_STRING_TYPE_DATA = ^SDP_STRING_TYPE_DATA; {$EXTERNALSYM PSDP_STRING_TYPE_DATA} TSdpStringTypeData = SDP_STRING_TYPE_DATA; PSdpStringTypeData = PSDP_STRING_TYPE_DATA; // // Description: // Converts a raw string embedded in the SDP record into a UNICODE string // // Parameters: // IN pRecordStream // a valid SDP stream which is formatted as an SDP record // // IN cbRecordLength // length of pRecordStream in bytes // // IN pStringData // if NULL, then the calling thread's locale will be used to search // for a matching string in the SDP record. If not NUL, the mibeNum // and attributeId will be used to find the string to convert. // // IN usStringOffset // the SDP string type offset to convert. usStringOffset is added to // the base attribute id of the string. SDP specification defined // offsets are: STRING_NAME_OFFSET, STRING_DESCRIPTION_OFFSET, and // STRING_PROVIDER_NAME_OFFSET (found in bthdef.h). // // OUT pszString // if NULL, pcchStringLength will be filled in with the required number // of characters (not bytes) to retrieve the converted string. // // IN OUT pcchStringLength // Upon input, if pszString is not NULL, will contain the length of // pszString in characters. Upon output, it will contain either the // number of required characters including NULL if an error is returned // or the number of characters written to pszString (including NULL). // // Return Values: // ERROR_SUCCES // Call was successful and pszString contains the converted string // // ERROR_MORE_DATA // pszString was NULL or too small to contain the converted string, // pccxhStringLength contains the required length in characters // // ERROR_INVALID_DATA // Could not perform the conversion // // ERROR_NO_SYSTEM_RESOURCES // Could not allocate memory internally to perform the conversion // // ERROR_INVALID_PARAMETER // One of the rquired pointers was NULL, pRecordStream was not a valid // SDP stream, pRecordStream was not a properly formatted record, or // the desired attribute + offset was not a string. // // Other HRESULTs returned by COM // function BluetoothSdpGetString( pRecordStream: PBYTE; cbRecordLength: ULONG; pStringData: PSDP_STRING_TYPE_DATA; usStringOffset: Word; pszString: PWideChar; pcchStringLength: PULONG): DWORD; stdcall; {$EXTERNALSYM BluetoothSdpGetString} // *************************************************************************** // // Raw Attribute Enumeration // // *************************************************************************** type PFN_BLUETOOTH_ENUM_ATTRIBUTES_CALLBACK = function( uAttribId: ULONG; pValueStream: PBYTE; cbStreamSize: ULONG; pvParam: Pointer): BOOL; stdcall; {$EXTERNALSYM PFN_BLUETOOTH_ENUM_ATTRIBUTES_CALLBACK} // // Description: // Enumerates through the SDP record stream calling the Callback function // for each attribute in the record. If the Callback function returns // FALSE, the enumeration is stopped. // // Return Values: // TRUE // Success! Something was enumerated. // // FALSE // Failure. GetLastError() could be one of the following: // // ERROR_INVALID_PARAMETER // pSDPStream or pfnCallback is NULL. // // ERROR_INVALID_DATA // The SDP stream is corrupt. // // other Win32 errors. // function BluetoothSdpEnumAttributes( pSDPStream: PBYTE; cbStreamSize: ULONG; pfnCallback: PFN_BLUETOOTH_ENUM_ATTRIBUTES_CALLBACK; pvParam: Pointer): BOOL; stdcall; {$EXTERNALSYM BluetoothSdpEnumAttributes} // (rom) MACRO function BluetoothEnumAttributes( pSDPStream: PBYTE; cbStreamSize: ULONG; pfnCallback: PFN_BLUETOOTH_ENUM_ATTRIBUTES_CALLBACK; pvParam: Pointer): BOOL; {$EXTERNALSYM BluetoothEnumAttributes} implementation const btapi = 'irprops.cpl'; // (rom) MACRO implementation function BluetoothEnumAttributes(pSDPStream: PBYTE; cbStreamSize: ULONG; pfnCallback: PFN_BLUETOOTH_ENUM_ATTRIBUTES_CALLBACK; pvParam: Pointer): BOOL; begin Result := BluetoothSdpEnumAttributes(pSDPStream, cbStreamSize, pfnCallback, pvParam); end; function BluetoothFindFirstRadio; external btapi name 'BluetoothFindFirstRadio'; function BluetoothFindNextRadio; external btapi name 'BluetoothFindNextRadio'; function BluetoothFindRadioClose; external btapi name 'BluetoothFindRadioClose'; function BluetoothGetRadioInfo; external btapi name 'BluetoothGetRadioInfo'; function BluetoothFindFirstDevice; external btapi name 'BluetoothFindFirstDevice'; function BluetoothFindNextDevice; external btapi name 'BluetoothFindNextDevice'; function BluetoothFindDeviceClose; external btapi name 'BluetoothFindDeviceClose'; function BluetoothGetDeviceInfo; external btapi name 'BluetoothGetDeviceInfo'; function BluetoothUpdateDeviceRecord; external btapi name 'BluetoothUpdateDeviceRecord'; function BluetoothRemoveDevice; external btapi name 'BluetoothRemoveDevice'; function BluetoothSelectDevices; external btapi name 'BluetoothSelectDevices'; function BluetoothSelectDevicesFree; external btapi name 'BluetoothSelectDevicesFree'; function BluetoothDisplayDeviceProperties; external btapi name 'BluetoothDisplayDeviceProperties'; function BluetoothAuthenticateDevice; external btapi name 'BluetoothAuthenticateDevice'; function BluetoothAuthenticateMultipleDevices; external btapi name 'BluetoothAuthenticateMultipleDevices'; function BluetoothSetServiceState; external btapi name 'BluetoothSetServiceState'; function BluetoothEnumerateInstalledServices; external btapi name 'BluetoothEnumerateInstalledServices'; function BluetoothEnableDiscovery; external btapi name 'BluetoothEnableDiscovery'; function BluetoothIsDiscoverable; external btapi name 'BluetoothIsDiscoverable'; function BluetoothEnableIncomingConnections; external btapi name 'BluetoothEnableIncomingConnections'; function BluetoothIsConnectable; external btapi name 'BluetoothIsConnectable'; function BluetoothRegisterForAuthentication; external btapi name 'BluetoothRegisterForAuthentication'; function BluetoothUnregisterAuthentication; external btapi name 'BluetoothUnregisterAuthentication'; function BluetoothSendAuthenticationResponse; external btapi name 'BluetoothSendAuthenticationResponse'; function BluetoothSdpGetElementData; external btapi name 'BluetoothSdpGetElementData'; function BluetoothSdpGetContainerElementData; external btapi name 'BluetoothSdpGetContainerElementData'; function BluetoothSdpGetAttributeValue; external btapi name 'BluetoothSdpGetAttributeValue'; function BluetoothSdpGetString; external btapi name 'BluetoothSdpGetString'; function BluetoothSdpEnumAttributes; external btapi name 'BluetoothSdpEnumAttributes'; end.
{ Copyright (C) 2006 Mike B. Petrichenko pmb_stv@mail.ru mobileservicesoft@yandex.ru ICQ: 190812766 Phone: +7 (928) 324-58-24 +7 (928) 819-46-40 All Rights Reserved. Only for non commercial purpose. } unit BTDevice; interface uses BTRadio, BluetoothAPI, Windows; type TBTDeviceSearchFlag = (sfReturnAuthenticated, sfReturnRemembered, sfReturnUnknown, sfReturnConnected); TBTDeviceSearchFlags = set of TBTDeviceSearchFlag; TBTDeviceSelectFlag = (dsForceAuthentication, dsShowAuthenticated, dsShowRemembered, dsShowUnknown, dsAddNewDeviceWizard, dsSkipServicesPage); TBTDeviceSelectFlags = set of TBTDeviceSelectFlag; TBTAuthenticateEvent = procedure (Sender: TObject; var Pwd: string); TBTDevice = class private FAddress: BTH_ADDR; FAuReg: HBLUETOOTH_AUTHENTICATION_REGISTRATION; FBTRadio: TBTRadio; FOnAuthenticate: TBTAuthenticateEvent; function GetAuthenticated: boolean; function GetClassOfDevice: cardinal; function GetConnected: boolean; function GetDeviceInfo: BLUETOOTH_DEVICE_INFO; function GetLastSeen: TDateTime; function GetLastUsed: TDateTime; function GetName: string; function GetRemembered: boolean; procedure SetOnAuthenticate(const Value: TBTAuthenticateEvent); procedure DoAuthenticate; protected property DeviceInfo: BLUETOOTH_DEVICE_INFO read GetDeviceInfo; public constructor Create(const Addr: BTH_ADDR; const ABTRadio: TBTRadio); destructor Destroy; override; procedure Authenticate(const Pwd: string); procedure DisplayProperties; procedure Remove; procedure Select(const FLags: TBTDeviceSelectFlags); procedure Update(const NewName: string); property Address: BTH_ADDR read FAddress; property Authenticated: boolean read GetAuthenticated; property BTRadio: TBTRadio read FBTRadio; property ClassofDevice: cardinal read GetClassOfDevice; property Connected: boolean read GetConnected; property LastSeen: TDateTime read GetLastSeen; property LastUsed: TDateTime read GetLastUsed; property Name: string read GetName; property Remembered: boolean read GetRemembered; property OnAuthenticate: TBTAuthenticateEvent read FOnAuthenticate write SetOnAuthenticate; end; function BTGetDeviceByAddr(const Addr: BTH_ADDR; const ABTRadio: TBTRadio): TBTDevice; procedure BTEnumDevices(const BTRadio: TBTRadio; const SearchFlags: TBTDeviceSearchFlags; var Devices: TBTAddrArray); implementation uses BTExceptions, BTStrings, SysUtils; function BTAuCallBack(pvParam: Pointer; pDevice: PBLUETOOTH_DEVICE_INFO): BOOL; stdcall; begin TBTDevice(pvParam).DoAuthenticate; Result := true; end; function BTGetDeviceByAddr(const Addr: BTH_ADDR; const ABTRadio: TBTRadio): TBTDevice; begin if (not Assigned(ABTRadio)) then raise BTException.Create(STR_ERROR_INVALID_PARAMETER); Result := TBTDevice.Create(Addr, ABTRadio); end; procedure BTEnumDevices(const BTRadio: TBTRadio; const SearchFlags: TBTDeviceSearchFlags; var Devices: TBTAddrArray); var hFind: HBLUETOOTH_DEVICE_FIND; SearchParams: BLUETOOTH_DEVICE_SEARCH_PARAMS; SearchParamsSize: dword; DeviceInfo: BLUETOOTH_DEVICE_INFO; DeviceInfoSize: dword; Ndx: word; begin if (not Assigned(BTRadio)) then raise BTException.Create(STR_ERROR_INVALID_PARAMETER); Ndx := 0; SearchParamsSize := SizeOf(BLUETOOTH_DEVICE_SEARCH_PARAMS); FillChar(SearchParams, SearchParamsSize, 0); with SearchParams do begin dwSize := SearchParamsSize; hRadio := BTRadio.Handle; fReturnAuthenticated := (sfReturnAuthenticated in SearchFlags); fReturnRemembered := (sfReturnRemembered in SearchFlags); fReturnUnknown := (sfReturnUnknown in SearchFlags); fReturnConnected := (sfReturnConnected in SearchFlags); end; DeviceInfoSize := SizeOf(BLUETOOTH_DEVICE_INFO); FillChar(DeviceInfo, DeviceInfoSize, 0); DeviceInfo.dwSize := DeviceInfoSize; hFind := BluetoothFindFirstDevice(SearchParams, DeviceInfo); if (hFind <> 0) then begin repeat Inc(Ndx); SetLength(Devices, Ndx); Devices[Ndx - 1] := DeviceInfo.Address.ullLong; FillChar(DeviceInfo, DeviceInfoSize, 0); DeviceInfo.dwSize := DeviceInfoSize; until (not BluetoothFindNextDevice(hFind, DeviceInfo)); BluetoothFindDeviceClose(hFind); end; end; function TBTDevice.GetAuthenticated: boolean; begin Result := boolean(GetDeviceInfo.fAuthenticated); end; function TBTDevice.GetClassOfDevice: cardinal; begin Result := GetDeviceInfo.ulClassofDevice; end; function TBTDevice.GetConnected: boolean; begin Result := boolean(GetDeviceInfo.fConnected); end; function TBTDevice.GetDeviceInfo: BLUETOOTH_DEVICE_INFO; var DeviceInfoSize: dword; Res: dword; begin DeviceInfoSize := SizeOf(BLUETOOTH_DEVICE_INFO); FillChar(Result, DeviceInfoSize, 0); with Result do begin dwSize := DeviceInfoSize; Address.ullLong := FAddress; end; Res := BluetoothGetDeviceInfo(FBTRadio.Handle, Result); if (Res <> ERROR_SUCCESS) then case Res of ERROR_REVISION_MISMATCH: raise BTException.Create(STR_ERROR_REVISION_MISMATCH_DEV); ERROR_INVALID_PARAMETER: raise BTException.Create(STR_ERROR_INVALID_PARAMETER_DEV); else RaiseLastOSError; end; end; function TBTDevice.GetLastSeen: TDateTime; begin Result := SystemTimeToDateTime(GetDeviceInfo.stLastSeen); end; function TBTDevice.GetLastUsed: TDateTime; begin Result := SystemTimeToDateTime(GetDeviceInfo.stLastUsed); end; function TBTDevice.GetName: string; begin Result := string(widestring(GetDeviceInfo.szName)); end; function TBTDevice.GetRemembered: boolean; begin Result := boolean(GetDeviceInfo.fRemembered); end; procedure TBTDevice.SetOnAuthenticate(const Value: TBTAuthenticateEvent); procedure Unreg; begin if (FAuReg <> 0) then if (not BluetoothUnregisterAuthentication(FAuReg)) then RaiseLastOsError; FAuReg := 0; FOnAuthenticate := nil; end; begin if Assigned(Value) then begin Unreg; if (BluetoothRegisterForAuthentication(GetDeviceInfo, FAuReg, BTAuCallBack, Self) <> ERROR_SUCCESS) then begin FAuReg := 0; RaiseLastOSError; end; FOnAuthenticate := Value; end else Unreg; end; procedure TBTDevice.DoAuthenticate; var Pwd: string; begin if Assigned(FOnAuthenticate) then begin FOnAuthenticate(Self, Pwd); BluetoothSendAuthenticationResponse(FBTRadio.Handle, GetDeviceInfo, pwidechar(widestring(Pwd))); end; end; constructor TBTDevice.Create(const Addr: BTH_ADDR; const ABTRadio: TBTRadio); begin if (not Assigned(FBTRadio)) then raise BTException.Create(STR_ERROR_INVALID_PARAMETER); FAddress := Addr; FAuReg := 0; FBTRadio := ABTRadio; FOnAuthenticate := nil; end; destructor TBTDevice.Destroy; begin if Assigned(FOnAuthenticate) then OnAuthenticate := nil; inherited; end; procedure TBTDevice.Authenticate(const Pwd: string); var Res: dword; PPwd: pwidechar; PPwdLength: dword; begin if (Pwd = '') then begin PPwd := nil; PPwdLength := 0; end else begin PPwd := pwidechar(widestring(Pwd)); PPwdLength := Length(WideString(Pwd)); end; Res := BluetoothAuthenticateDevice(0, FBTRadio.Handle, GetDeviceInfo, PPwd, PPwdLength); if (Res <> ERROR_SUCCESS) then RaiseLastOsError; end; procedure TBTDevice.DisplayProperties; begin if (not BluetoothDisplayDeviceProperties(0, GetDeviceInfo)) then RaiseLastOsError; end; procedure TBTDevice.Remove; var Addr: BLUETOOTH_ADDRESS; begin Addr.ullLong := FAddress; if (BluetoothRemoveDevice(Addr) <> ERROR_SUCCESS) then RaiseLastOsError; end; procedure TBTDevice.Select(const FLags: TBTDeviceSelectFlags); var SelectParams: BLUETOOTH_SELECT_DEVICE_PARAMS; SelectParamsSize: dword; Res: dword; begin SelectParamsSize := SizeOf(BLUETOOTH_SELECT_DEVICE_PARAMS); FillChar(SelectParams, SelectParamsSize, 0); with SelectParams do begin dwSize := SelectParamsSize; fForceAuthentication := (dsForceAuthentication in Flags); fShowAuthenticated := (dsShowAuthenticated in Flags); fShowRemembered := (dsShowRemembered in Flags); fShowUnknown := (dsShowUnknown in Flags); fAddNewDeviceWizard := (dsAddNewDeviceWizard in Flags); fSkipServicesPage := (dsSkipServicesPage in Flags); end; if BluetoothSelectDevices(@SelectParams) then begin FAddress := BLUETOOTH_DEVICE_INFO(SelectParams.pDevices).Address.ullLong; BluetoothSelectDevicesFree(@SelectParams); end else begin Res := GetLastError; if (Res <> ERROR_CANCELLED) then case Res of ERROR_INVALID_PARAMETER: raise BTException.Create(STR_ERROR_INVALID_PARAMETER_SEL); ERROR_REVISION_MISMATCH: raise BTException.Create(STR_ERROR_REVISION_MISMATCH_SEL); else RaiseLastOSError; end; end; end; procedure TBTDevice.Update(const NewName: string); var DeviceInfo: BLUETOOTH_DEVICE_INFO; DeviceInfoSize: dword; Res: dword; begin DeviceInfoSize := SizeOf(BLUETOOTH_DEVICE_INFO); FillChar(DeviceInfo, DeviceInfoSize, 0); with DeviceInfo do begin dwSize := DeviceInfoSize; Address.ullLong := FAddress; lstrcpyw(szName, pwidechar(widestring(NewName))); end; Res := BluetoothUpdateDeviceRecord(DeviceInfo); if (Res <> ERROR_SUCCESS) then case Res of ERROR_INVALID_PARAMETER: raise BTException.Create(STR_ERROR_INVALID_PARAMETER_DEV); ERROR_REVISION_MISMATCH: raise BTException.Create(STR_ERROR_REVISION_MISMATCH_DEV); else RaiseLastOsError; end; end; end.
{ Copyright (C) 2006 Mike B. Petrichenko pmb_stv@mail.ru mobileservicesoft@yandex.ru ICQ: 190812766 Phone: +7 (928) 324-58-24 +7 (928) 819-46-40 All Rights Reserved. Only for non commercial purpose. } unit BTExceptions; interface uses SysUtils; type BTException = class(Exception); implementation end.
unit BthSdpDef; interface uses Windows; type SDP_LARGE_INTEGER_16 = record LowPart: Int64; HighPart: Int64; end; {$EXTERNALSYM SDP_LARGE_INTEGER_16} PSDP_LARGE_INTEGER_16 = ^SDP_LARGE_INTEGER_16; {$EXTERNALSYM PSDP_LARGE_INTEGER_16} LPSDP_LARGE_INTEGER_16 = PSDP_LARGE_INTEGER_16; {$EXTERNALSYM LPSDP_LARGE_INTEGER_16} TSdpLargeInteger = SDP_LARGE_INTEGER_16; PSdpLargeInteger = PSDP_LARGE_INTEGER_16; SDP_ULARGE_INTEGER_16 = record LowPart: Int64; HighPart: Int64; end; {$EXTERNALSYM SDP_ULARGE_INTEGER_16} PSDP_ULARGE_INTEGER_16 = ^SDP_ULARGE_INTEGER_16; {$EXTERNALSYM PSDP_ULARGE_INTEGER_16} LPSDP_ULARGE_INTEGER_16 = PSDP_ULARGE_INTEGER_16; {$EXTERNALSYM LPSDP_ULARGE_INTEGER_16} TSdpULargeInteger16 = SDP_ULARGE_INTEGER_16; PSdpULargeInteger16 = PSDP_ULARGE_INTEGER_16; NodeContainerType = (NodeContainerTypeSequence, NodeContainerTypeAlternative); TNodeContainerType = NodeContainerType; SDP_ERROR = Word; {$EXTERNALSYM SDP_ERROR} PSDP_ERROR = ^SDP_ERROR; {$EXTERNALSYM PSDP_ERROR} TSdpError = SDP_ERROR; PSdpError = PSDP_ERROR; type SDP_TYPE = DWORD; {$EXTERNALSYM SDP_TYPE} TSdpType = SDP_TYPE; const SDP_TYPE_NIL = $00; {$EXTERNALSYM SDP_TYPE_NIL} SDP_TYPE_UINT = $01; {$EXTERNALSYM SDP_TYPE_UINT} SDP_TYPE_INT = $02; {$EXTERNALSYM SDP_TYPE_INT} SDP_TYPE_UUID = $03; {$EXTERNALSYM SDP_TYPE_UUID} SDP_TYPE_STRING = $04; {$EXTERNALSYM SDP_TYPE_STRING} SDP_TYPE_BOOLEAN = $05; {$EXTERNALSYM SDP_TYPE_BOOLEAN} SDP_TYPE_SEQUENCE = $06; {$EXTERNALSYM SDP_TYPE_SEQUENCE} SDP_TYPE_ALTERNATIVE = $07; {$EXTERNALSYM SDP_TYPE_ALTERNATIVE} SDP_TYPE_URL = $08; {$EXTERNALSYM SDP_TYPE_URL} // 9 - 31 are reserved SDP_TYPE_CONTAINER = $20; {$EXTERNALSYM SDP_TYPE_CONTAINER} // allow for a little easier type checking / sizing for integers and UUIDs // ((SDP_ST_XXX & 0xF0) >> 4) == SDP_TYPE_XXX // size of the data (in bytes) is encoded as ((SDP_ST_XXX & 0xF0) >> 8) type SDP_SPECIFICTYPE = DWORD; {$EXTERNALSYM SDP_SPECIFICTYPE} TSdpSpecificType = SDP_SPECIFICTYPE; const SDP_ST_NONE = $0000; {$EXTERNALSYM SDP_ST_NONE} SDP_ST_UINT8 = $0010; {$EXTERNALSYM SDP_ST_UINT8} SDP_ST_UINT16 = $0110; {$EXTERNALSYM SDP_ST_UINT16} SDP_ST_UINT32 = $0210; {$EXTERNALSYM SDP_ST_UINT32} SDP_ST_UINT64 = $0310; {$EXTERNALSYM SDP_ST_UINT64} SDP_ST_UINT128 = $0410; {$EXTERNALSYM SDP_ST_UINT128} SDP_ST_INT8 = $0020; {$EXTERNALSYM SDP_ST_INT8} SDP_ST_INT16 = $0120; {$EXTERNALSYM SDP_ST_INT16} SDP_ST_INT32 = $0220; {$EXTERNALSYM SDP_ST_INT32} SDP_ST_INT64 = $0320; {$EXTERNALSYM SDP_ST_INT64} SDP_ST_INT128 = $0420; {$EXTERNALSYM SDP_ST_INT128} SDP_ST_UUID16 = $0130; {$EXTERNALSYM SDP_ST_UUID16} SDP_ST_UUID32 = $0220; {$EXTERNALSYM SDP_ST_UUID32} SDP_ST_UUID128 = $0430; {$EXTERNALSYM SDP_ST_UUID128} type _SdpAttributeRange = record minAttribute: Word; maxAttribute: Word; end; {$EXTERNALSYM _SdpAttributeRange} SdpAttributeRange = _SdpAttributeRange; {$EXTERNALSYM SdpAttributeRange} TSdpAttributeRange = SdpAttributeRange; SdpQueryUuidUnion = record case Integer of 0: (uuid128: TGUID); 1: (uuid32: ULONG); 2: (uuid16: Word); end; TSdpQueryUuidUnion = SdpQueryUuidUnion; _SdpQueryUuid = record u: SdpQueryUuidUnion; uuidType: Word; end; {$EXTERNALSYM _SdpQueryUuid} SdpQueryUuid = _SdpQueryUuid; {$EXTERNALSYM SdpQueryUuid} TSdpQueryUuid = SdpQueryUuid; implementation end.
{ Copyright (C) 2006 Mike B. Petrichenko pmb_stv@mail.ru mobileservicesoft@yandex.ru ICQ: 190812766 Phone: +7 (928) 324-58-24 +7 (928) 819-46-40 All Rights Reserved. Only for non commercial purpose. } unit BTRadio; interface uses Windows, BluetoothAPI; type TBTAddrArray = array of BTH_ADDR; TBTRadio = class private FAddress: BTH_ADDR; FClassOfDevice: cardinal; FHandle: THandle; FManufacturer: word; FName: string; FSubversion: word; function GetConnectable: boolean; function GetDiscoverable: boolean; procedure SetConnectable(const Value: boolean); procedure SetDiscoverable(const Value: boolean); public constructor Create(const AHandle: THandle); destructor Destroy; override; property Address: BTH_ADDR read FAddress; property ClassOfDevice: cardinal read FClassOfDevice; property Connectable: boolean read GetConnectable write SetConnectable; property Discoverable: boolean read GetDiscoverable write SetDiscoverable; property Handle: THandle read FHandle; property Manufacturer: word read FManufacturer; property Name: string read FName; property Subversion: word read FSubversion; end; function BTGetRadioByAddr(const Addr: BTH_ADDR): TBTRadio; procedure BTEnumRadios(var Radios: TBTAddrArray); implementation uses SysUtils, BTStrings, BTExceptions; function BTGetRadioByAddr(const Addr: BTH_ADDR): TBTRadio; var hFind: HBLUETOOTH_RADIO_FIND; SearchParams: BLUETOOTH_FIND_RADIO_PARAMS; hRadio: THandle; RadioInfo: BLUETOOTH_RADIO_INFO; RadioInfoSize: dword; begin Result := nil; SearchParams.dwSize := SizeOf(BLUETOOTH_FIND_RADIO_PARAMS); hFind := BluetoothFindFirstRadio(@SearchParams, hRadio); if (hFind <> 0) then begin repeat RadioInfoSize := SizeOf(BLUETOOTH_RADIO_INFO); FillChar(RadioInfo, RadioInfoSize, 0); RadioInfo.dwSize := RadioInfoSize; if (BluetoothGetRadioInfo(hRadio, RadioInfo) = ERROR_SUCCESS) then if (RadioInfo.address.ullLong = Addr) then begin Result := TBTRadio.Create(hRadio); Break; end; CloseHandle(hRadio); until (not BluetoothFindNextRadio(hFind, hRadio)); BluetoothFindRadioClose(hFind); end; end; procedure BTEnumRadios(var Radios: TBTAddrArray); var hFind: HBLUETOOTH_RADIO_FIND; SearchParams: BLUETOOTH_FIND_RADIO_PARAMS; hRadio: THandle; Ndx: word; RadioInfo: BLUETOOTH_RADIO_INFO; RadioInfoSize: dword; begin Radios := nil; Ndx := 0; SearchParams.dwSize := SizeOf(BLUETOOTH_FIND_RADIO_PARAMS); hFind := BluetoothFindFirstRadio(@SearchParams, hRadio); if (hFind <> 0) then begin repeat RadioInfoSize := SizeOf(BLUETOOTH_RADIO_INFO); FillChar(RadioInfo, RadioInfoSize, 0); RadioInfo.dwSize := RadioInfoSize; if (BluetoothGetRadioInfo(hRadio, RadioInfo) = ERROR_SUCCESS) then begin Inc(Ndx); SetLength(Radios, Ndx); CopyMemory(@Radios[Ndx - 1], @RadioInfo, RadioInfoSize); end; CloseHandle(hRadio); until (not BluetoothFindNextRadio(hFind, hRadio)); BluetoothFindRadioClose(hFind); end; end; function TBTRadio.GetConnectable: boolean; begin Result := BluetoothIsConnectable(FHandle); end; function TBTRadio.GetDiscoverable: boolean; begin Result := BluetoothIsDiscoverable(FHandle); end; procedure TBTRadio.SetConnectable(const Value: boolean); begin if (not BluetoothEnableIncomingConnections(FHandle, Value)) then raise BTException.Create(STR_ERROR_ENABLE_CONNECTION); end; procedure TBTRadio.SetDiscoverable(const Value: boolean); begin if (not BluetoothEnableDiscovery(FHandle, Value)) then raise BTException.Create(STR_ERROR_ENABLE_DISCOVERY); end; constructor TBTRadio.Create(const AHandle: THandle); var RadioInfo: BLUETOOTH_RADIO_INFO; RadioInfoSize: dword; Res: dword; begin FHandle := AHandle; RadioInfoSize := SizeOf(BLUETOOTH_RADIO_INFO); FillChar(RadioInfo, RadioInfoSize, 0); RadioInfo.dwSize := RadioInfoSize; Res := BluetoothGetRadioInfo(FHandle, RadioInfo); if (Res = ERROR_SUCCESS) then begin FAddress := RadioInfo.address.ullLong; FClassOfDevice := RadioInfo.ulClassofDevice; FManufacturer := RadioInfo.manufacturer; FName := string(widestring(RadioInfo.szName)); FSubversion := RadioInfo.lmpSubversion; end else case Res of ERROR_INVALID_PARAMETER: raise BTException.Create(STR_ERROR_INVALID_PARAMETER); ERROR_REVISION_MISMATCH: raise BTException.Create(STR_ERROR_REVISION_MISMATCH); else RaiseLastOSError; end; end; destructor TBTRadio.Destroy; begin CloseHandle(FHandle); inherited; end; end.
{ Copyright (C) 2006 Mike B. Petrichenko pmb_stv@mail.ru mobileservicesoft@yandex.ru ICQ: 190812766 Phone: +7 (928) 324-58-24 +7 (928) 819-46-40 All Rights Reserved. Only for non commercial purpose. } unit BTStrings; interface resourcestring STR_ERROR_INVALID_PARAMETER = 'The hRadio or pRadioInfo parameter is NULL.'; STR_ERROR_REVISION_MISMATCH = 'The dwSize member of the BLUETOOTH_RADIO_INFO structure pointed to by pRadioInfo is not valid.'; STR_ERROR_ENABLE_CONNECTION = 'Unable change incoming connection state.'; STR_ERROR_ENABLE_DISCOVERY = 'Unable change discovery state'; STR_ERROR_REVISION_MISMATCH_DEV = 'The size of the BLUETOOTH_DEVICE_INFO is not compatible. Check the dwSize member of the BLUETOOTH_DEVICE_INFO structure.'; STR_ERROR_NOT_FOUND = 'The radio is not known by the system, or the Address member of the BLUETOOTH_DEVICE_INFO structure is all zeros.'; STR_ERROR_INVALID_PARAMETER_DEV = 'The pbtdi parameter is NULL.'; STR_ERROR_INVALID_PARAMETER_SEL = 'The pbtsdp is NULL.'; STR_ERROR_REVISION_MISMATCH_SEL = 'The structure passed in as pbtsdp is of an unknown size.'; implementation end.