Discussion can be found here: My first serial communications app
In that thread I offered Jeffery Smith code that would get just about anything you ever wanted to know about Serial Ports via the SetupApi.dll but that example also involved many other concepts so was too large for some to grasp.
Then I thought about one core question of what ports are available? So I stripped down the code to a simple textbox and functions to report the following.
1st off let me thank Kev Peel for his port of the SetupApi.inc without which I would not be able to make any of this possible.
Tested on XP, but should work for Win95/NT4 SP3 and later versions.
To save space posting, the SetupApi.inc can be downloaded from PB Downloads at http://www.powerbasic.com/files/pub/pbwin/misc/
or direct link at SetupApi.zip
SetupApiSerialInfo.h
ListDevices.h
SetupApiSerialInfo.inc
ListDevices.inc
AvailableSerialPorts.bas
Hope its of use
In that thread I offered Jeffery Smith code that would get just about anything you ever wanted to know about Serial Ports via the SetupApi.dll but that example also involved many other concepts so was too large for some to grasp.
Then I thought about one core question of what ports are available? So I stripped down the code to a simple textbox and functions to report the following.
- Ports that exist
- If the port is available for use, or already taken
- If the port exists, but not currently connected to Windows (like a USB to RS232 adapter)
1st off let me thank Kev Peel for his port of the SetupApi.inc without which I would not be able to make any of this possible.
Tested on XP, but should work for Win95/NT4 SP3 and later versions.
To save space posting, the SetupApi.inc can be downloaded from PB Downloads at http://www.powerbasic.com/files/pub/pbwin/misc/
or direct link at SetupApi.zip
SetupApiSerialInfo.h
Code:
DECLARE FUNCTION GetDeviceList ALIAS "GetDeviceList"() AS DWORD DECLARE FUNCTION GetDeviceListSize ALIAS "GetDeviceListSize"() AS DWORD DECLARE FUNCTION GetDeviceClass ALIAS "GetDeviceClass"() AS STRING DECLARE FUNCTION GetDeviceFriendlyName ALIAS "GetDeviceFriendlyName"() AS STRING DECLARE FUNCTION GetDeviceDesc ALIAS "GetDeviceDesc"() AS STRING DECLARE FUNCTION GetDeviceHardwareId ALIAS "GetDeviceHardwareId"() AS STRING DECLARE FUNCTION GetDeviceCompatibleId ALIAS "GetDeviceCompatibleId"() AS STRING DECLARE FUNCTION GetDeviceUnused0 ALIAS "GeDevicetUnused0"() AS STRING DECLARE FUNCTION GetDeviceService ALIAS "GetDeviceService"() AS STRING DECLARE FUNCTION GetDeviceUnused1 ALIAS "GetDeviceUnused1"() AS STRING DECLARE FUNCTION GetDeviceUnused2 ALIAS "GetDeviceUnused2"() AS STRING DECLARE FUNCTION GetDeviceClassGuid ALIAS "GetDeviceClassGuid"() AS STRING DECLARE FUNCTION GetDeviceDriver ALIAS "GetDeviceDriver"() AS STRING DECLARE FUNCTION GetDeviceConfigFlags ALIAS "GetDeviceConfigFlags"() AS STRING DECLARE FUNCTION GetDeviceMfg ALIAS "GetDeviceMfg"() AS STRING DECLARE FUNCTION GetDeviceLocation ALIAS "GetDeviceLocation"() AS STRING DECLARE FUNCTION GetDeviceObjectName ALIAS "GetDeviceObjectName"() AS STRING DECLARE FUNCTION GetDeviceCapabilities ALIAS "GetDeviceCapabilities"() AS STRING DECLARE FUNCTION GetDeviceUiNumber ALIAS "GetDeviceUiNumber"() AS STRING DECLARE FUNCTION GetDeviceUpperFilters ALIAS "GetDeviceUpperFilters"() AS STRING DECLARE FUNCTION GetDeviceLowerFilters ALIAS "GetDeviceLowerFilters"() AS STRING DECLARE FUNCTION GetDeviceBusTypeGuid ALIAS "GetDeviceBusTypeGuid"() AS STRING DECLARE FUNCTION GetDeviceLegacyBusType ALIAS "GetDeviceLegacyBusType"() AS STRING DECLARE FUNCTION GetDeviceBusNumber ALIAS "GetDeviceBusNumber"() AS STRING DECLARE FUNCTION GetDeviceEnumeratorName ALIAS "GetDeviceEnumeratorName"() AS STRING DECLARE FUNCTION GetDeviceSecurityBinary ALIAS "GetDeviceSecurityBinary"() AS STRING DECLARE FUNCTION GetDeviceSecuritySelfDirectedSearch ALIAS "GetDeviceSecuritySelfDirectedSearch"() AS STRING DECLARE FUNCTION GetDeviceType ALIAS "GetDeviceType"() AS STRING DECLARE FUNCTION GetDeviceExclusive ALIAS "GetDeviceExclusive"() AS STRING DECLARE FUNCTION GetDeviceCharacteristics ALIAS "GetDeviceCharacteristics"() AS STRING DECLARE FUNCTION GetDeviceAddress ALIAS "GetDeviceAddress"() AS STRING DECLARE FUNCTION GetDeviceUiNumberDescFormat ALIAS "GetDeviceUiNumberDescFormat"() AS STRING DECLARE FUNCTION GetDeviceMaximumProperty ALIAS "GetDeviceMaximumProperty"() AS STRING DECLARE FUNCTION GetDeviceRemovalPolicy ALIAS "GetDeviceRemovalPolicy"() AS STRING DECLARE FUNCTION GetDeviceRemovalPolicyDefault ALIAS "GetDeviceRemovalPolicyDefault"() AS STRING DECLARE FUNCTION GetDeviceRemovalPolicyOverride ALIAS "GetDeviceRemovalPolicyOverride"() AS STRING DECLARE FUNCTION GetDeviceInstallState ALIAS "GetDeviceInstallState"() AS STRING DECLARE FUNCTION GetDeviceLocationPaths ALIAS "GetDeviceLocationPaths"() AS STRING DECLARE FUNCTION GetDevicePowerData ALIAS "GetDevicePowerData"() AS STRING DECLARE FUNCTION DestroyDeviceList ALIAS "DestroyDeviceList"() AS DWORD DECLARE FUNCTION ListUsbDrivers ALIAS "ListUsbDrivers"() AS LONG DECLARE FUNCTION ListSerialDrivers ALIAS "ListSerialDrivers"() AS LONG TYPE DeviceDriver ClassName AS ASCIIZ * %MAX_PATH FriendlyName AS ASCIIZ * %MAX_PATH DeviceDesc AS ASCIIZ * %MAX_PATH HardwareId AS ASCIIZ * %MAX_PATH CompatibleId AS ASCIIZ * %MAX_PATH Unused0 AS ASCIIZ * %MAX_PATH Service AS ASCIIZ * %MAX_PATH Unused1 AS ASCIIZ * %MAX_PATH Unused2 AS ASCIIZ * %MAX_PATH ClassGuid AS ASCIIZ * %MAX_PATH Driver AS ASCIIZ * %MAX_PATH ConfigFlags AS ASCIIZ * %MAX_PATH Mfg AS ASCIIZ * %MAX_PATH Location AS ASCIIZ * %MAX_PATH ObjectName AS ASCIIZ * %MAX_PATH Capabilities AS ASCIIZ * %MAX_PATH UiNumber AS ASCIIZ * %MAX_PATH UpperFilters AS ASCIIZ * %MAX_PATH LowerFilters AS ASCIIZ * %MAX_PATH BusTypeGuid AS ASCIIZ * %MAX_PATH LegacyBusType AS ASCIIZ * %MAX_PATH BusNumber AS ASCIIZ * %MAX_PATH EnumeratorName AS ASCIIZ * %MAX_PATH SecurityBinary AS ASCIIZ * %MAX_PATH SecuritySelfDirectedSearch AS ASCIIZ * %MAX_PATH DeviceType AS ASCIIZ * %MAX_PATH Exclusive AS ASCIIZ * %MAX_PATH Characteristics AS ASCIIZ * %MAX_PATH Address AS ASCIIZ * %MAX_PATH UiNumberDescFormat AS ASCIIZ * %MAX_PATH MaximumProperty AS ASCIIZ * %MAX_PATH RemovalPolicy AS ASCIIZ * %MAX_PATH RemovalPolicyDefault AS ASCIIZ * %MAX_PATH RemovalPolicyOverride AS ASCIIZ * %MAX_PATH InstallState AS ASCIIZ * %MAX_PATH LocationPaths AS ASCIIZ * %MAX_PATH PowerData AS ASCIIZ * %MAX_PATH END TYPE GLOBAL hDeviceInfo AS DWORD GLOBAL spdi AS SP_DEVINFO_DATA GLOBAL dwDevicetype AS DWORD GLOBAL InfoUsbDriver() AS DeviceDriver GLOBAL InfoSerialDriver() AS DeviceDriver
Code:
DECLARE FUNCTION ListDevicesSerial ALIAS "ListDevicesSerial"() AS LONG DECLARE FUNCTION StatusDevicesSerial ALIAS "StatusDevicesSerial"(PortName AS ASCIIZ) AS STRING TYPE DeviceInfo Name AS ASCIIZ * %MAX_PATH Port AS LONG Status AS ASCIIZ * %MAX_PATH END TYPE GLOBAL DeviceSerial() AS DeviceInfo
Code:
'**************************************************************************************** '*** Wrapper for Serial Port Information that can be gathered via SetupApi.dll '*** Cliff Nichols 11-29-07 '**************************************************************************************** '________________________________________________________________________________________ ' ' Device Viewer ' ------------- ' ' Win 95 must have IE4 installed and NT4 must have SP3 or later installed. '________________________________________________________________________________________ '' Note that SPDRP codes are zero based while CM_DRP codes are one based! ' '%SPDRP_DEVICEDESC = (&H00000000) ' DeviceDesc (R/W) '%SPDRP_HARDWAREID = (&H00000001) ' HardwareID (R/W) '%SPDRP_COMPATIBLEIDS = (&H00000002) ' CompatibleIDs (R/W) '%SPDRP_UNUSED0 = (&H00000003) ' unused '%SPDRP_SERVICE = (&H00000004) ' Service (R/W) '%SPDRP_UNUSED1 = (&H00000005) ' unused '%SPDRP_UNUSED2 = (&H00000006) ' unused '%SPDRP_CLASS = (&H00000007) ' Class (R--tied to ClassGUID) '%SPDRP_CLASSGUID = (&H00000008) ' ClassGUID (R/W) '%SPDRP_DRIVER = (&H00000009) ' Driver (R/W) '%SPDRP_CONFIGFLAGS = (&H0000000A) ' ConfigFlags (R/W) '%SPDRP_MFG = (&H0000000B) ' Mfg (R/W) '%SPDRP_FRIENDLYNAME = (&H0000000C) ' FriendlyName (R/W) '%SPDRP_LOCATION_INFORMATION = (&H0000000D) ' LocationInformation (R/W) '%SPDRP_PHYSICAL_DEVICE_OBJECT_NAME =(&H0000000E) ' PhysicalDeviceObjectName (R) '%SPDRP_CAPABILITIES = (&H0000000F) ' Capabilities (R) '%SPDRP_UI_NUMBER = (&H00000010) ' UiNumber (R) '%SPDRP_UPPERFILTERS = (&H00000011) ' UpperFilters (R/W) '%SPDRP_LOWERFILTERS = (&H00000012) ' LowerFilters (R/W) '%SPDRP_BUSTYPEGUID = (&H00000013) ' BusTypeGUID (R) '%SPDRP_LEGACYBUSTYPE = (&H00000014) ' LegacyBusType (R) '%SPDRP_BUSNUMBER = (&H00000015) ' BusNumber (R) '%SPDRP_ENUMERATOR_NAME = (&H00000016) ' Enumerator Name (R) '%SPDRP_SECURITY = (&H00000017) ' Security (R/W, binary form) '%SPDRP_SECURITY_SDS = (&H00000018) ' Security (W, SDS form) '%SPDRP_DEVTYPE = (&H00000019) ' Device Type (R/W) '%SPDRP_EXCLUSIVE = (&H0000001A) ' Device is exclusive-access (R/W) '%SPDRP_CHARACTERISTICS = (&H0000001B) ' Device Characteristics (R/W) '%SPDRP_ADDRESS = (&H0000001C) ' Device Address (R) '%SPDRP_UI_NUMBER_DESC_FORMAT = (&H0000001D) ' UiNumberDescFormat (R/W) '%SPDRP_DEVICE_POWER_DATA = (&H0000001E) ' Device Power Data (R) '%SPDRP_REMOVAL_POLICY = (&H0000001F) ' Removal Policy (R) '%SPDRP_REMOVAL_POLICY_HW_DEFAULT = (&H00000020) ' Hardware Removal Policy (R) '%SPDRP_REMOVAL_POLICY_OVERRIDE = (&H00000021) ' Removal Policy Override (RW) '%SPDRP_INSTALL_STATE = (&H00000022) ' Device Install State (R) '%SPDRP_LOCATION_PATHS = (&H00000023) ' Device Location Paths (R) ' '%SPDRP_MAXIMUM_PROPERTY = (&H00000024) ' Upper bound on ordinals FUNCTION GetDeviceList ALIAS "GetDeviceList"() EXPORT AS DWORD FUNCTION = SetupDiGetClassDevs(BYVAL %NULL, BYVAL %NULL, BYVAL %NULL, %DIGCF_ALLCLASSES) ' Get a handle to the device list... '*** Test to see if next line is for use with only present devices? ' hDeviceInfo = SetupDiGetClassDevs(BYVAL %NULL, BYVAL %NULL, byval %NULL, %DIGCF_PRESENT) END FUNCTION FUNCTION GetDeviceListSize ALIAS "GetDeviceListSize"() EXPORT AS DWORD FUNCTION = SIZEOF(spdi) END FUNCTION FUNCTION GetDeviceClass ALIAS "GetDeviceClass"() EXPORT AS STRING DIM zText AS ASCIIZ * %MAX_PATH SetupDiGetDeviceRegistryProperty(hDeviceInfo, spdi, %SPDRP_CLASS, BYVAL %NULL, zText, SIZEOF(zText), BYVAL %NULL) FUNCTION = zText END FUNCTION FUNCTION GetDeviceFriendlyName ALIAS "GetDeviceFriendlyName"() EXPORT AS STRING DIM zText AS ASCIIZ * %MAX_PATH SetupDiGetDeviceRegistryProperty(hDeviceInfo, spdi, %SPDRP_FRIENDLYNAME, BYVAL %NULL, zText, SIZEOF(zText), BYVAL %NULL) ' Try and get friendly name... FUNCTION = zText END FUNCTION FUNCTION GetDeviceDesc ALIAS "GetDeviceDesc"() EXPORT AS STRING DIM zText AS ASCIIZ * %MAX_PATH SetupDiGetDeviceRegistryProperty(hDeviceInfo, spdi, %SPDRP_DEVICEDESC, BYVAL %NULL, zText, SIZEOF(zText), BYVAL %NULL) ' Just get description... FUNCTION = zText END FUNCTION FUNCTION GetDeviceHardwareId ALIAS "GetDeviceHardwareId"() EXPORT AS STRING DIM zText AS ASCIIZ * %MAX_PATH SetupDiGetDeviceRegistryProperty(hDeviceInfo, spdi, %SPDRP_HARDWAREID, BYVAL %NULL, zText, SIZEOF(zText), BYVAL %NULL) ' Just get description... FUNCTION = zText END FUNCTION FUNCTION GetDeviceCompatibleId ALIAS "GetDeviceCompatibleId"() EXPORT AS STRING DIM zText AS ASCIIZ * %MAX_PATH SetupDiGetDeviceRegistryProperty(hDeviceInfo, spdi, %SPDRP_COMPATIBLEIDS, BYVAL %NULL, zText, SIZEOF(zText), BYVAL %NULL) ' Just get description... FUNCTION = zText END FUNCTION FUNCTION GetDeviceUnused0 ALIAS "GeDevicetUnused0"() EXPORT AS STRING DIM zText AS ASCIIZ * %MAX_PATH SetupDiGetDeviceRegistryProperty(hDeviceInfo, spdi, %SPDRP_UNUSED0, BYVAL %NULL, zText, SIZEOF(zText), BYVAL %NULL) ' Just get description... FUNCTION = zText END FUNCTION FUNCTION GetDeviceService ALIAS "GetDeviceService"() EXPORT AS STRING DIM zText AS ASCIIZ * %MAX_PATH SetupDiGetDeviceRegistryProperty(hDeviceInfo, spdi, %SPDRP_SERVICE, BYVAL %NULL, zText, SIZEOF(zText), BYVAL %NULL) ' Just get description... FUNCTION = zText END FUNCTION FUNCTION GetDeviceUnused1 ALIAS "GetDeviceUnused1"() EXPORT AS STRING DIM zText AS ASCIIZ * %MAX_PATH SetupDiGetDeviceRegistryProperty(hDeviceInfo, spdi, %SPDRP_UNUSED1, BYVAL %NULL, zText, SIZEOF(zText), BYVAL %NULL) ' Just get description... FUNCTION = zText END FUNCTION FUNCTION GetDeviceUnused2 ALIAS "GetDeviceUnused2"() EXPORT AS STRING DIM zText AS ASCIIZ * %MAX_PATH SetupDiGetDeviceRegistryProperty(hDeviceInfo, spdi, %SPDRP_UNUSED2, BYVAL %NULL, zText, SIZEOF(zText), BYVAL %NULL) ' Just get description... FUNCTION = zText END FUNCTION FUNCTION GetDeviceClassGuid ALIAS "GetDeviceClassGuid"() EXPORT AS STRING DIM zText AS ASCIIZ * %MAX_PATH SetupDiGetDeviceRegistryProperty(hDeviceInfo, spdi, %SPDRP_CLASSGUID, BYVAL %NULL, zText, SIZEOF(zText), BYVAL %NULL) ' Just get description... FUNCTION = zText END FUNCTION FUNCTION GetDeviceDriver ALIAS "GetDeviceDriver"() EXPORT AS STRING DIM zText AS ASCIIZ * %MAX_PATH SetupDiGetDeviceRegistryProperty(hDeviceInfo, spdi, %SPDRP_DRIVER, BYVAL %NULL, zText, SIZEOF(zText), BYVAL %NULL) ' Just get description... FUNCTION = zText END FUNCTION FUNCTION GetDeviceConfigFlags ALIAS "GetDeviceConfigFlags"() EXPORT AS STRING DIM zText AS ASCIIZ * %MAX_PATH SetupDiGetDeviceRegistryProperty(hDeviceInfo, spdi, %SPDRP_CONFIGFLAGS, BYVAL %NULL, zText, SIZEOF(zText), BYVAL %NULL) ' Just get description... FUNCTION = zText END FUNCTION FUNCTION GetDeviceMfg ALIAS "GetDeviceMfg"() EXPORT AS STRING DIM zText AS ASCIIZ * %MAX_PATH SetupDiGetDeviceRegistryProperty(hDeviceInfo, spdi, %SPDRP_MFG, BYVAL %NULL, zText, SIZEOF(zText), BYVAL %NULL) ' Just get description... FUNCTION = zText END FUNCTION FUNCTION GetDeviceLocation ALIAS "GetDeviceLocation"() EXPORT AS STRING DIM zText AS ASCIIZ * %MAX_PATH SetupDiGetDeviceRegistryProperty(hDeviceInfo, spdi, %SPDRP_LOCATION_INFORMATION, BYVAL %NULL, zText, SIZEOF(zText), BYVAL %NULL) ' Just get description... FUNCTION = zText END FUNCTION FUNCTION GetDeviceObjectName ALIAS "GetDeviceObjectName"() EXPORT AS STRING DIM zText AS ASCIIZ * %MAX_PATH SetupDiGetDeviceRegistryProperty(hDeviceInfo, spdi, %SPDRP_PHYSICAL_DEVICE_OBJECT_NAME, BYVAL %NULL, zText, SIZEOF(zText), BYVAL %NULL) ' Just get description... FUNCTION = zText END FUNCTION FUNCTION GetDeviceCapabilities ALIAS "GetDeviceCapabilities"() EXPORT AS STRING DIM zText AS ASCIIZ * %MAX_PATH SetupDiGetDeviceRegistryProperty(hDeviceInfo, spdi, %SPDRP_CAPABILITIES, BYVAL %NULL, zText, SIZEOF(zText), BYVAL %NULL) ' Just get description... FUNCTION = zText END FUNCTION FUNCTION GetDeviceUiNumber ALIAS "GetDeviceUiNumber"() EXPORT AS STRING DIM zText AS ASCIIZ * %MAX_PATH SetupDiGetDeviceRegistryProperty(hDeviceInfo, spdi, %SPDRP_UI_NUMBER, BYVAL %NULL, zText, SIZEOF(zText), BYVAL %NULL) ' Just get description... FUNCTION = zText END FUNCTION FUNCTION GetDeviceUpperFilters ALIAS "GetDeviceUpperFilters"() EXPORT AS STRING DIM zText AS ASCIIZ * %MAX_PATH SetupDiGetDeviceRegistryProperty(hDeviceInfo, spdi, %SPDRP_UPPERFILTERS, BYVAL %NULL, zText, SIZEOF(zText), BYVAL %NULL) ' Just get description... FUNCTION = zText END FUNCTION FUNCTION GetDeviceLowerFilters ALIAS "GetDeviceLowerFilters"() EXPORT AS STRING DIM zText AS ASCIIZ * %MAX_PATH SetupDiGetDeviceRegistryProperty(hDeviceInfo, spdi, %SPDRP_LOWERFILTERS, BYVAL %NULL, zText, SIZEOF(zText), BYVAL %NULL) ' Just get description... FUNCTION = zText END FUNCTION FUNCTION GetDeviceBusTypeGuid ALIAS "GetDeviceBusTypeGuid"() EXPORT AS STRING DIM zText AS ASCIIZ * %MAX_PATH SetupDiGetDeviceRegistryProperty(hDeviceInfo, spdi, %SPDRP_BUSTYPEGUID, BYVAL %NULL, zText, SIZEOF(zText), BYVAL %NULL) ' Just get description... FUNCTION = zText END FUNCTION FUNCTION GetDeviceLegacyBusType ALIAS "GetDeviceLegacyBusType"() EXPORT AS STRING DIM zText AS ASCIIZ * %MAX_PATH SetupDiGetDeviceRegistryProperty(hDeviceInfo, spdi, %SPDRP_LEGACYBUSTYPE, BYVAL %NULL, zText, SIZEOF(zText), BYVAL %NULL) ' Just get description... FUNCTION = zText END FUNCTION FUNCTION GetDeviceBusNumber ALIAS "GetDeviceBusNumber"() EXPORT AS STRING DIM zText AS ASCIIZ * %MAX_PATH SetupDiGetDeviceRegistryProperty(hDeviceInfo, spdi, %SPDRP_BUSNUMBER, BYVAL %NULL, zText, SIZEOF(zText), BYVAL %NULL) ' Just get description... FUNCTION = zText END FUNCTION FUNCTION GetDeviceEnumeratorName ALIAS "GetDeviceEnumeratorName"() EXPORT AS STRING DIM zText AS ASCIIZ * %MAX_PATH SetupDiGetDeviceRegistryProperty(hDeviceInfo, spdi, %SPDRP_ENUMERATOR_NAME, BYVAL %NULL, zText, SIZEOF(zText), BYVAL %NULL) ' Just get description... FUNCTION = zText END FUNCTION FUNCTION GetDeviceSecurityBinary ALIAS "GetDeviceSecurityBinary"() EXPORT AS STRING DIM zText AS ASCIIZ * %MAX_PATH SetupDiGetDeviceRegistryProperty(hDeviceInfo, spdi, %SPDRP_SECURITY, BYVAL %NULL, zText, SIZEOF(zText), BYVAL %NULL) ' Just get description... FUNCTION = zText END FUNCTION FUNCTION GetDeviceSecuritySelfDirectedSearch ALIAS "GetDeviceSecuritySelfDirectedSearch"() EXPORT AS STRING DIM zText AS ASCIIZ * %MAX_PATH SetupDiGetDeviceRegistryProperty(hDeviceInfo, spdi, %SPDRP_SECURITY_SDS, BYVAL %NULL, zText, SIZEOF(zText), BYVAL %NULL) ' Just get description... FUNCTION = zText END FUNCTION FUNCTION GetDeviceType ALIAS "GetDeviceType"() EXPORT AS STRING DIM zText AS ASCIIZ * %MAX_PATH SetupDiGetDeviceRegistryProperty(hDeviceInfo, spdi, %SPDRP_DEVTYPE, BYVAL %NULL, zText, SIZEOF(zText), BYVAL %NULL) ' Just get description... FUNCTION = zText END FUNCTION FUNCTION GetDeviceExclusive ALIAS "GetDeviceExclusive"() EXPORT AS STRING DIM zText AS ASCIIZ * %MAX_PATH SetupDiGetDeviceRegistryProperty(hDeviceInfo, spdi, %SPDRP_EXCLUSIVE, BYVAL %NULL, zText, SIZEOF(zText), BYVAL %NULL) ' Just get description... FUNCTION = zText END FUNCTION FUNCTION GetDeviceCharacteristics ALIAS "GetDeviceCharacteristics"() EXPORT AS STRING DIM zText AS ASCIIZ * %MAX_PATH SetupDiGetDeviceRegistryProperty(hDeviceInfo, spdi, %SPDRP_CHARACTERISTICS, BYVAL %NULL, zText, SIZEOF(zText), BYVAL %NULL) ' Just get description... FUNCTION = zText END FUNCTION FUNCTION GetDeviceAddress ALIAS "GetDeviceAddress"() EXPORT AS STRING DIM zText AS ASCIIZ * %MAX_PATH SetupDiGetDeviceRegistryProperty(hDeviceInfo, spdi, %SPDRP_ADDRESS, BYVAL %NULL, zText, SIZEOF(zText), BYVAL %NULL) ' Just get description... FUNCTION = zText END FUNCTION FUNCTION GetDeviceUiNumberDescFormat ALIAS "GetDeviceUiNumberDescFormat"() EXPORT AS STRING DIM zText AS ASCIIZ * %MAX_PATH SetupDiGetDeviceRegistryProperty(hDeviceInfo, spdi, %SPDRP_UI_NUMBER_DESC_FORMAT, BYVAL %NULL, zText, SIZEOF(zText), BYVAL %NULL) ' Just get description... FUNCTION = zText END FUNCTION FUNCTION GetDeviceMaximumProperty ALIAS "GetDeviceMaximumProperty"() EXPORT AS STRING DIM zText AS ASCIIZ * %MAX_PATH SetupDiGetDeviceRegistryProperty(hDeviceInfo, spdi, %SPDRP_MAXIMUM_PROPERTY, BYVAL %NULL, zText, SIZEOF(zText), BYVAL %NULL) ' Just get description... FUNCTION = zText END FUNCTION FUNCTION GetDeviceRemovalPolicy ALIAS "GetDeviceRemovalPolicy"() EXPORT AS STRING DIM zText AS ASCIIZ * %MAX_PATH SetupDiGetDeviceRegistryProperty(hDeviceInfo, spdi, %SPDRP_REMOVAL_POLICY, BYVAL %NULL, zText, SIZEOF(zText), BYVAL %NULL) ' Just get description... FUNCTION = zText END FUNCTION FUNCTION GetDeviceRemovalPolicyDefault ALIAS "GetDeviceRemovalPolicyDefault"() EXPORT AS STRING DIM zText AS ASCIIZ * %MAX_PATH SetupDiGetDeviceRegistryProperty(hDeviceInfo, spdi, %SPDRP_REMOVAL_POLICY_HW_DEFAULT, BYVAL %NULL, zText, SIZEOF(zText), BYVAL %NULL) ' Just get description... FUNCTION = zText END FUNCTION FUNCTION GetDeviceRemovalPolicyOverride ALIAS "GetDeviceRemovalPolicyOverride"() EXPORT AS STRING DIM zText AS ASCIIZ * %MAX_PATH SetupDiGetDeviceRegistryProperty(hDeviceInfo, spdi, %SPDRP_REMOVAL_POLICY_OVERRIDE, BYVAL %NULL, zText, SIZEOF(zText), BYVAL %NULL) ' Just get description... FUNCTION = zText END FUNCTION FUNCTION GetDeviceInstallState ALIAS "GetDeviceInstallState"() EXPORT AS STRING DIM zText AS ASCIIZ * %MAX_PATH SetupDiGetDeviceRegistryProperty(hDeviceInfo, spdi, %SPDRP_INSTALL_STATE, BYVAL %NULL, zText, SIZEOF(zText), BYVAL %NULL) ' Just get description... FUNCTION = zText END FUNCTION FUNCTION GetDeviceLocationPaths ALIAS "GetDeviceLocationPaths"() EXPORT AS STRING DIM zText AS ASCIIZ * %MAX_PATH SetupDiGetDeviceRegistryProperty(hDeviceInfo, spdi, %SPDRP_LOCATION_PATHS, BYVAL %NULL, zText, SIZEOF(zText), BYVAL %NULL) ' Just get description... FUNCTION = zText END FUNCTION FUNCTION GetDevicePowerData ALIAS "GetDevicePowerData"() EXPORT AS STRING DIM zText AS ASCIIZ * %MAX_PATH SetupDiGetDeviceRegistryProperty(hDeviceInfo, spdi, %SPDRP_DEVICE_POWER_DATA, BYVAL %NULL, zText, SIZEOF(zText), BYVAL %NULL) ' Just get description... FUNCTION = zText END FUNCTION FUNCTION DestroyDeviceList ALIAS "DestroyDeviceList"() EXPORT AS DWORD FUNCTION = SetupDiDestroyDeviceInfoList(hDeviceInfo) ' Tidy up... END FUNCTION FUNCTION ListSerialDrivers ALIAS "ListSerialDrivers"() EXPORT AS LONG ' LOCAL i AS LONG, zText AS ASCIIZ * 1024 '<--- NEVER use a hardcoded value you will forget later LOCAL i AS LONG, zText AS ASCIIZ * %MAX_PATH 'Default arrays REDIM InfoSerialDriver(LBOUND(InfoSerialDriver)) ' Enumerate devices using SETUPAPI.DLL... hDeviceInfo = GetDeviceList spdi.cbSize = GetDeviceListSize DO UNTIL SetupDiEnumDeviceInfo(hDeviceInfo, i, spdi) = 0 SELECT CASE UCASE$(GetDeviceClass) CASE "PORTS" SELECT CASE INSTR(UCASE$(GetDeviceFriendlyName), "LPT") CASE 0 'Not a parallel port InfoSerialDriver(UBOUND(InfoSerialDriver)).ClassName = GetDeviceClass InfoSerialDriver(UBOUND(InfoSerialDriver)).FriendlyName = GetDeviceFriendlyName InfoSerialDriver(UBOUND(InfoSerialDriver)).DeviceDesc = GetDeviceDesc InfoSerialDriver(UBOUND(InfoSerialDriver)).HardwareId = GetDeviceHardwareId InfoSerialDriver(UBOUND(InfoSerialDriver)).CompatibleId = GetDeviceCompatibleId InfoSerialDriver(UBOUND(InfoSerialDriver)).Service = GetDeviceService InfoSerialDriver(UBOUND(InfoSerialDriver)).ClassGuid = GetDeviceClassGuid InfoSerialDriver(UBOUND(InfoSerialDriver)).Driver = GetDeviceDriver InfoSerialDriver(UBOUND(InfoSerialDriver)).ConfigFlags = GetDeviceConfigFlags InfoSerialDriver(UBOUND(InfoSerialDriver)).Mfg = GetDeviceMfg InfoSerialDriver(UBOUND(InfoSerialDriver)).Location = GetDeviceLocation InfoSerialDriver(UBOUND(InfoSerialDriver)).ObjectName = GetDeviceObjectName InfoSerialDriver(UBOUND(InfoSerialDriver)).Capabilities = GetDeviceCapabilities InfoSerialDriver(UBOUND(InfoSerialDriver)).UiNumber = GetDeviceUiNumber InfoSerialDriver(UBOUND(InfoSerialDriver)).UpperFilters = GetDeviceUpperFilters InfoSerialDriver(UBOUND(InfoSerialDriver)).LowerFilters = GetDeviceLowerFilters InfoSerialDriver(UBOUND(InfoSerialDriver)).BusTypeGuid = GetDeviceBusTypeGuid InfoSerialDriver(UBOUND(InfoSerialDriver)).LegacyBusType = GetDeviceCompatibleId InfoSerialDriver(UBOUND(InfoSerialDriver)).BusNumber = GetDeviceCompatibleId InfoSerialDriver(UBOUND(InfoSerialDriver)).EnumeratorName = GetDeviceCompatibleId InfoSerialDriver(UBOUND(InfoSerialDriver)).SecurityBinary = GetDeviceCompatibleId InfoSerialDriver(UBOUND(InfoSerialDriver)).SecuritySelfDirectedSearch = GetDeviceSecuritySelfDirectedSearch InfoSerialDriver(UBOUND(InfoSerialDriver)).DeviceType = GetDeviceType InfoSerialDriver(UBOUND(InfoSerialDriver)).Exclusive = GetDeviceExclusive InfoSerialDriver(UBOUND(InfoSerialDriver)).Characteristics = GetDeviceCharacteristics InfoSerialDriver(UBOUND(InfoSerialDriver)).Address = GetDeviceAddress InfoSerialDriver(UBOUND(InfoSerialDriver)).UiNumberDescFormat = GetDeviceUiNumberDescFormat InfoSerialDriver(UBOUND(InfoSerialDriver)).MaximumProperty = GetDeviceMaximumProperty InfoSerialDriver(UBOUND(InfoSerialDriver)).RemovalPolicy = GetDeviceRemovalPolicy InfoSerialDriver(UBOUND(InfoSerialDriver)).RemovalPolicyDefault = GetDeviceRemovalPolicyDefault InfoSerialDriver(UBOUND(InfoSerialDriver)).RemovalPolicyOverride = GetDeviceRemovalPolicyOverride InfoSerialDriver(UBOUND(InfoSerialDriver)).InstallState = GetDeviceInstallState InfoSerialDriver(UBOUND(InfoSerialDriver)).LocationPaths = GetDeviceLocationPaths InfoSerialDriver(UBOUND(InfoSerialDriver)).PowerData = GetDevicePowerData ' InfoSerialDriver(UBOUND(InfoSerialDriver)).Unused0 = GetDeviceUnused0 ' InfoSerialDriver(UBOUND(InfoSerialDriver)).Unused1 = GetDeviceUnused1 ' InfoSerialDriver(UBOUND(InfoSerialDriver)).Unused2 = GetDeviceUnused2 REDIM PRESERVE InfoSerialDriver(UBOUND(InfoSerialDriver) + 1) CASE ELSE 'Parallel port END SELECT CASE ELSE END SELECT INCR i LOOP DestroyDeviceList REDIM PRESERVE InfoSerialDriver(UBOUND(InfoSerialDriver) - 1) FUNCTION = %True END FUNCTION
Code:
FUNCTION ListDevicesSerial ALIAS "ListDevicesSerial"() EXPORT AS LONG REDIM DeviceSerial(LBOUND(DeviceSerial)) 'Clear the array DIM i AS LONG DIM j AS LONG DIM zText AS ASCIIZ * %MAX_PATH DIM StartParse AS LONG DIM LenParse AS LONG hDeviceInfo = GetDeviceList 'Get the list of serial devices spdi.cbSize = GetDeviceListSize 'Get the size of the list DO UNTIL SetupDiEnumDeviceInfo(hDeviceInfo, i, spdi) = 0 SELECT CASE UCASE$(GetDeviceClass) CASE "PORTS" 'If class is not a port, then skip it for this example zText = GetDeviceFriendlyName SELECT CASE INSTR(UCASE$(zText), "LPT") 'If a port, but not a serial port, skip it for this example CASE 0 'Not a parallel port StartParse = INSTR(zText, "(") + 1 'It is a serial port so start parsing data LenParse = INSTR(zText, ")") - StartParse DeviceSerial(UBOUND(DeviceSerial)).NAME = MID$(zText, StartParse, LenParse) FOR j = 1 TO LEN(DeviceSerial(UBOUND(DeviceSerial)).NAME) SELECT CASE ASC(MID$(DeviceSerial(UBOUND(DeviceSerial)).NAME, j, 1)) CASE 48 TO 57 'Acii 0 to 9 DeviceSerial(UBOUND(DeviceSerial)).PORT = VAL(MID$(DeviceSerial(UBOUND(DeviceSerial)).NAME, j, LEN(DeviceSerial(UBOUND(DeviceSerial)).NAME))) EXIT FOR END SELECT NEXT j REDIM PRESERVE DeviceSerial(UBOUND(DeviceSerial) + 1) END SELECT END SELECT INCR i LOOP REDIM PRESERVE DeviceSerial(UBOUND(DeviceSerial) - 1) 'Remove empty array element FUNCTION = %True END FUNCTION FUNCTION StatusDevicesSerial ALIAS "StatusDevicesSerial"(PortName AS ASCIIZ) EXPORT AS STRING LOCAL HwndPort AS LONG LOCAL i AS LONG DIM lResult AS LONG DIM ErrorBuff AS ASCIIZ * %MAX_PATH HwndPort = FREEFILE REPLACE "\\.\" WITH "" IN PortName '<--- Just in case PortName was passed correctly PortName = "\\.\" + PortName '<--- Now put it back in case it was passed incorrectly, but still want above Com9 COMM OPEN PortName AS HwndPort 'Open the port SELECT CASE ERR CASE 69 'Comm Error - now find out why? HwndPort = CreateFile(PortName, %GENERIC_READ OR %GENERIC_WRITE, 0, BYVAL 0, %OPEN_EXISTING, 0, %NULL) 'Open Port via Windows API lResult = GetLastError() 'Check for the error FormatMessage %FORMAT_MESSAGE_FROM_SYSTEM, BYVAL %NULL, lResult, %NULL, ErrorBuff, SIZEOF(ErrorBuff), BYVAL %NULL 'Format the message CloseHandle HwndPort 'Close the handle to the port REPLACE $CR WITH "" IN ErrorBuff 'Reformat Error REPLACE $LF WITH "" IN ErrorBuff 'Reformat Error FOR i = LBOUND(DeviceSerial) TO UBOUND(DeviceSerial) 'Find the port to update status SELECT CASE DeviceSerial(i).NAME CASE PortName SELECT CASE lResult CASE 5 'Access Denied DeviceSerial(i).STATUS = "Error: " + STR$(lResult) + $TAB + ErrorBuff + " ---> " + "Port In Use by another program or driver" CASE 2 'System can not find Port DeviceSerial(i).STATUS = "Error: " + STR$(lResult) + $TAB + ErrorBuff + " ---> " + "Port Exists but is not connected to Windows" END SELECT FUNCTION = DeviceSerial(i).STATUS 'Report back the port status EXIT FUNCTION CASE ELSE 'Keep looking END SELECT NEXT i CASE ELSE SELECT CASE FILEATTR(HwndPort, 0) 'Check if the port is truly Open CASE 0 FOR i = LBOUND(DeviceSerial) TO UBOUND(DeviceSerial) 'Not open, so find correct port to update status SELECT CASE DeviceSerial(i).NAME CASE PortName DeviceSerial(i).STATUS = "Port In Use" FUNCTION = DeviceSerial(i).STATUS EXIT FUNCTION CASE ELSE 'Keep looking END SELECT NEXT i CASE ELSE FOR i = LBOUND(DeviceSerial) TO UBOUND(DeviceSerial) 'Open, so find correct port to update status SELECT CASE DeviceSerial(i).NAME CASE PortName DeviceSerial(i).STATUS = "Port Available" FUNCTION = DeviceSerial(i).STATUS EXIT FUNCTION CASE ELSE 'Keep looking END SELECT NEXT i END SELECT END SELECT IF FILEATTR(HwndPort, 0) THEN COMM CLOSE HwndPort 'Close the port (Handle#) if still open END FUNCTION
Code:
#COMPILE EXE #DIM ALL #INCLUDE "WIN32API.INC" 'Define Windows OS variables and functions #INCLUDE "SetupApi.INC" 'Windows Setup Api '<--- Many thanx to Kev Peel for this #INCLUDE "SetupApiSerialInfo.h" 'Header for SetupApi '<--- VB port from Cliff Nichols #INCLUDE "ListDevices.h" 'Header List Devices #INCLUDE "SetupApiSerialInfo.INC" 'Wrapper for SetupApi #INCLUDE "ListDevices.INC" 'List Devices DECLARE FUNCTION WINMAIN ( _ BYVAL hInstance AS LONG, _ ' handle of current instance BYVAL hPrevInstance AS LONG, _ ' handle of previous instance(not used in Win32) BYVAL pszCmdLine AS ASCIIZ PTR, _ ' address of command line BYVAL nCmdShow AS LONG _ ' show state of window ) AS LONG DECLARE CALLBACK FUNCTION ShowDIALOG1Proc() GLOBAL hInst AS LONG GLOBAL hDlg AS DWORD %IDD_DIALOG1 = 101 %IDC_TEXTBOX1 = 1001 CALLBACK FUNCTION ShowDIALOG1Proc() LOCAL i AS LONG LOCAL PortInfo AS STRING LOCAL TempText AS STRING SELECT CASE AS LONG CBMSG CASE %WM_INITDIALOG PortInfo = "" ListDevicesSerial 'Get the global array of ports that exist FOR i = LBOUND(DeviceSerial) TO UBOUND(DeviceSerial) 'Get the status of each port PortInfo = PortInfo + DeviceSerial(i).NAME + $TAB + StatusDevicesSerial(DeviceSerial(i).NAME) + $CRLF NEXT i CONTROL SET TEXT hDlg, %IDC_TEXTBOX1, PortInfo CONTROL GET TEXT hDlg, %IDC_TEXTBOX1 TO TempText CONTROL SEND hDlg, %IDC_TEXTBOX1, %EM_SETSEL, 1, 1 CASE %WM_NCACTIVATE STATIC hWndSaveFocus AS DWORD IF ISFALSE CBWPARAM THEN hWndSaveFocus = GetFocus() ' Save control focus ELSEIF hWndSaveFocus THEN SetFocus(hWndSaveFocus) 'Restore control focus hWndSaveFocus = 0 END IF CASE %WM_COMMAND '*** Process control notifications SELECT CASE AS LONG CBCTL CASE %IDC_TEXTBOX1 CASE ELSE END SELECT CASE %WM_DESTROY PostQuitMessage 0 'Stop the message pump END SELECT END FUNCTION '------------------------------------------------------------------------------ FUNCTION WINMAIN ( _ BYVAL hInstance AS LONG, _ ' handle of current instance BYVAL hPrevInstance AS LONG, _ ' handle of previous instance(not used in Win32) BYVAL pszCmdLine AS ASCIIZ PTR, _ ' address of command line BYVAL nCmdShow AS LONG _ ' show state of window ) AS LONG LOCAL tmsg AS TagMsg hInst = hInstance 'Global for use when creating Windows DIALOG NEW %HWND_DESKTOP, "Dialog1", 70, 70, 201, 121, %WS_POPUP OR %WS_BORDER _ OR %WS_DLGFRAME OR %WS_CAPTION OR %WS_SYSMENU OR %WS_CLIPSIBLINGS OR _ %WS_VISIBLE OR %DS_MODALFRAME OR %DS_3DLOOK OR %DS_NOFAILCREATE OR _ %DS_SETFONT, %WS_EX_CONTROLPARENT OR %WS_EX_LEFT OR _ %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR, TO hDlg CONTROL ADD TEXTBOX, hDlg, %IDC_TEXTBOX1, "TextBox1", 0, 0, 200, 120, _ %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %WS_HSCROLL OR _ %WS_VSCROLL OR %ES_LEFT OR %ES_MULTILINE OR %ES_AUTOHSCROLL OR _ %ES_AUTOVSCROLL, %WS_EX_CLIENTEDGE OR %WS_EX_LEFT OR _ %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR DIALOG SHOW MODELESS hDlg, CALL ShowDIALOG1Proc '*** Acquire and dispatch messages until a WM_QUIT message is received. WHILE ISTRUE GetMessage(tmsg, BYVAL %NULL, 0, 0) TranslateMessage tmsg DispatchMessage tmsg WEND END FUNCTION

Comment