Skip to content

Commit

Permalink
Finished base application
Browse files Browse the repository at this point in the history
  • Loading branch information
aziascreations committed Jun 23, 2021
1 parent 569def6 commit 19e2b68
Show file tree
Hide file tree
Showing 4 changed files with 183 additions and 17 deletions.
14 changes: 9 additions & 5 deletions Includes/SerialHelper_Win32.pbi
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@

DeclareModule SerialHelper
Prototype.i _RegGetValueW(hKey.l, lpSubKey.s, lpValue.s, dwFlags.l, *pdwType, *pvData, *pcbData)

Global RegGetValueW._RegGetValueW = #Null

; Returns a positive integer representing the amount of COM port available.
; Returns -1 is any error occured.
Declare.i GetComPortDeviceNameMap(Map ComPortDeviceNames.s())
Expand All @@ -13,8 +17,7 @@ Module SerialHelper

EnableExplicit

Prototype.i _RegGetValueW(hKey.l, lpSubKey.s, lpValue.s, dwFlags.l, *pdwType, *pvData, *pcbData)
Global RegGetValueW._RegGetValueW = #Null

Global LibrariIdAdvapi32 = OpenLibrary(#PB_Any, "Advapi32.dll")

If IsLibrary(LibrariIdAdvapi32)
Expand Down Expand Up @@ -86,8 +89,9 @@ Module SerialHelper
Debug "> No more items !"
Break
Else ; Implies #ERROR_SUCCESS or #ERROR_MORE_DATA
Debug "> "+PeekS(*KeyStringBuffer, #Name_Buffer_Size) + " #> "+PeekS(*ValueStringBuffer, #Data_Buffer_Size)
ComPortDeviceNames(PeekS(*KeyStringBuffer, #Name_Buffer_Size)) = PeekS(*ValueStringBuffer, #Data_Buffer_Size)
Debug "> "+PeekS(*ValueStringBuffer, #Data_Buffer_Size)+" #> "+PeekS(*KeyStringBuffer, #Name_Buffer_Size)
;ComPortDeviceNames(PeekS(*KeyStringBuffer, #Name_Buffer_Size)) = PeekS(*ValueStringBuffer, #Data_Buffer_Size)
ComPortDeviceNames(PeekS(*ValueStringBuffer, #Data_Buffer_Size)) = PeekS(*KeyStringBuffer, #Name_Buffer_Size)
EndIf
Next

Expand All @@ -110,7 +114,7 @@ Module SerialHelper
If GetComPortDeviceNameMap(ComPortDeviceNames()) <> -1
ForEach ComPortDeviceNames()
AddElement(ComPortList())
ComPortList() = ComPortDeviceNames()
ComPortList() = MapKey(ComPortDeviceNames())
Next
EndIf

Expand Down
24 changes: 24 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
This is free and unencumbered software released into the public domain.

Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.

In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

For more information, please refer to <http://unlicense.org/>
105 changes: 93 additions & 12 deletions ListComPort.pb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
;{
; * Arguments.pbi
; Version: 0.0.4
; Version: 1.0.0
; Author: Herwin Bozet
;
; A basic arguments parser.
Expand All @@ -15,6 +15,10 @@

EnableExplicit

CompilerIf #PB_Compiler_ExecutableFormat <> #PB_Compiler_Console
CompilerError("this program need to be compiled as a console application !")
CompilerEndIf


;- Constants

Expand All @@ -27,11 +31,19 @@ EnableExplicit

If Not OpenConsole("lscom")
; TODO: Play Windows error bell sound
MessageRequester("Fatal error !", "Failed to open the console !",
#PB_MessageRequester_Ok | #PB_MessageRequester_Error)
End 1
EndIf

CompilerIf #PB_Compiler_OS = #PB_OS_Windows
XIncludeFile "./Includes/SerialHelper_Win32.pbi"

If Not SerialHelper::RegGetValueW
ConsoleError("Cannot continue without being able to use RegGetValueW() !")
SerialHelper::Finish()
End 2
EndIf
CompilerElse
CompilerError "Non-windows platforms are not supported !"
CompilerEndIf
Expand All @@ -49,10 +61,10 @@ Define SortingOrder.b = #Sort_Order_None
If Arguments::Init()
Define HasRegisteredArgumentsCorrectly.b = #True

Define *HelpOption.Arguments::Option = Arguments::CreateOption('h', "help", "Display the help text")
If Not Arguments::RegisterOption(*HelpOption)
ConsoleError("Failed to register *HelpOption !")
Arguments::FreeOption(*HelpOption)
Define *NameAllOption.Arguments::Option = Arguments::CreateOption('a', "show-all", "Display the complete port's name (Equal to -dfn)")
If Not Arguments::RegisterOption(*NameAllOption)
ConsoleError("Failed to register *NameAllOption !")
Arguments::FreeOption(*NameAllOption)
HasRegisteredArgumentsCorrectly = #False
EndIf

Expand All @@ -70,6 +82,13 @@ If Arguments::Init()
HasRegisteredArgumentsCorrectly = #False
EndIf

Define *HelpOption.Arguments::Option = Arguments::CreateOption('h', "help", "Display the help text")
If Not Arguments::RegisterOption(*HelpOption)
ConsoleError("Failed to register *HelpOption !")
Arguments::FreeOption(*HelpOption)
HasRegisteredArgumentsCorrectly = #False
EndIf

Define *NameRawOption.Arguments::Option = Arguments::CreateOption('n', "show-name-raw", "Displays the port's raw name (See info section)")
If Not Arguments::RegisterOption(*NameRawOption)
ConsoleError("Failed to register *NameRawOption !")
Expand All @@ -94,9 +113,10 @@ If Arguments::Init()
If HasRegisteredArgumentsCorrectly
If Not Arguments::ParseArguments(0, CountProgramParameters())
If *HelpOption\WasUsed
PrintN("lscom.exe [-d|--show-device] [-f|--show-friendly] [-h|--help] [-n|--show-name-raw] [-s|--sort] [-S|--sort-reverse]")
PrintN("lscom.exe [-a|--show-all] [-d|--show-device] [-f|--show-friendly] [-h|--help] [-n|--show-name-raw] [-s|--sort] [-S|--sort-reverse]")
PrintN("")
PrintN("Arguments:")
PrintN("-a, --show-all Display the complete port's name (Equal to '-dfn')")
PrintN("-d, --show-device Displays the port's device name")
PrintN("-f, --show-friendly Displays the port's friendly name")
PrintN("-h, --help Display the help text")
Expand Down Expand Up @@ -135,6 +155,7 @@ If Arguments::Init()
PrintN(" * '-n' and '-d' and '-f'")
PrintN(" > $RawName - $FriendlyName [$DeviceName]")
PrintN(" > COM1 - Communications Port [\Device\Serial1]")
SerialHelper::Finish()
End 0
EndIf

Expand All @@ -152,6 +173,12 @@ If Arguments::Init()
ShouldPrintRawNames = #True
EndIf

If *NameAllOption\WasUsed
ShouldPrintDeviceNames = #True
ShouldPrintFriendlyNames = #True
ShouldPrintRawNames = #True
EndIf

If *SortAscOption\WasUsed
SortingOrder = #Sort_Order_Ascending
EndIf
Expand All @@ -175,15 +202,69 @@ EndIf

;-> Listing ports

Global NewMap ComPortDeviceName.s()
If SerialHelper::GetComPortDeviceNameMap(ComPortDeviceName()) <> -1
ForEach ComPortDeviceName()
PrintN(ComPortDeviceName())
Global IsDoingFine.b = #True
Global NewMap ComPortDeviceNames.s()
Global NewList ComPortRawNames.s()
Global NewMap ComPortFriendlyNames.s() ; May not be used depending on the options used.

If SerialHelper::GetComPortDeviceNameMap(ComPortDeviceNames()) <> -1
ForEach ComPortDeviceNames()
AddElement(ComPortRawNames())
ComPortRawNames() = MapKey(ComPortDeviceNames())
Next

If ShouldPrintFriendlyNames
If SerialHelper::GetComPortFriendlyNameList(ComPortRawNames(), ComPortFriendlyNames(), #True) = -1
ConsoleError("Failed to list the friendly names !")
IsDoingFine = #False
EndIf
EndIf
Else
ConsoleError("Failed to list the COM ports !")
IsDoingFine = #False
EndIf

If IsDoingFine
If SortingOrder = #Sort_Order_Ascending
SortList(ComPortRawNames(), #PB_Sort_Ascending | #PB_Sort_NoCase)
EndIf

If SortingOrder = #Sort_Order_Descending
SortList(ComPortRawNames(), #PB_Sort_Descending | #PB_Sort_NoCase)
EndIf

ForEach ComPortRawNames()
If ShouldPrintRawNames
Print(ComPortRawNames())

If ShouldPrintFriendlyNames
Print(" - "+ComPortFriendlyNames(ComPortRawNames()))
EndIf

If ShouldPrintDeviceNames
PrintN(" ["+ComPortDeviceNames(ComPortRawNames())+"]")
Else
Print(#CRLF$)
EndIf
Else
If ShouldPrintFriendlyNames
Print(ComPortFriendlyNames(ComPortRawNames()))
If ShouldPrintDeviceNames
PrintN(" ["+ComPortDeviceNames(ComPortRawNames())+"]")
Else
Print(#CRLF$)
EndIf
Else
PrintN(ComPortDeviceNames(ComPortRawNames()))
EndIf
EndIf
Next
EndIf

Debug Str(SerialHelper::GetComPortDeviceNameMap(ComPortDeviceName())) + " port(s) found !"
; Cleaning...
FreeMap(ComPortDeviceNames())
FreeList(ComPortRawNames())
FreeMap(ComPortFriendlyNames())

FreeMap(ComPortDeviceName())
SerialHelper::Finish()
End 0
57 changes: 57 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# PB-ListComPort

A simple cli tool that can list COM ports with their full name easily and cleanly.

This tool is intended to replace the tedious task of having to use the `mode` command, and the *Device Manager* to find
a newly plugged-in device that provides a COM port.

Only works on x64 releases of Windows 10, it might work on older versions, but I won't explicitly support
them as they have reached their EOL.

## Usage
```
lscom.exe [-a|--show-all] [-d|--show-device] [-f|--show-friendly] [-h|--help] [-n|--show-name-raw] [-s|--sort] [-S|--sort-reverse]
Arguments:
-a, --show-all Display the complete port's name (Equal to '-dfn')
-d, --show-device Displays the port's device name
-f, --show-friendly Displays the port's friendly name
-h, --help Display the help text
-n, --show-name-raw Displays the port's raw name (See info section)
-s, --sort Sorts the port based on their raw names in an ascending order
-S, --sort-reverse Sorts the port based on their raw names in a descending order
```

## Remarks
* If '-d' or '-f' is used, the raw name will not be shown unless '-n' is used.
* By default, the order the ports are shown in SHOULD be the [plug-in time] order from Windows' registry.
* Searching for the friendly names can be a time consuming task !
* Raw name simply refers to a port name (e.g.: COM1, COM2, ...)
* Device name refers to a port device path (e.g.: \Device\Serial1, ...)
* Friendly name refers to a port name as seen in the device manager (e.g.: Communications Port, USB-SERIAL CH340, )

## Output formatting
* No argument:
> $RawName<br>
> COM1
* '-d' or '-f'
> $DeviceName
> > \Device\Serial1
>
> $FriendlyName
> > Communications Port
* '-d' and '-f'
> $FriendlyName [$DeviceName]
> > Communications Port [\Device\Serial1]
* '-n' and '-d'
> $RawName [$DeviceName]
> > COM1 [\Device\Serial1]
* '-n' and '-f'
> $RawName - $FriendlyName
> > COM1 - Communications Port
* '-n' and '-d' and '-f'
> $RawName - $FriendlyName [$DeviceName]
> > COM1 - Communications Port [\Device\Serial1]
## License
[Unlicense](LICENSE)

0 comments on commit 19e2b68

Please sign in to comment.