Sign in to follow this  
Followers 0
ViciousXUSMC

Block Unblock Comm Ports

1 post in this topic

I was working on a little project to assign Com Ports for a USB GPS Device, one of the things I needed to do was unblock the old Com Port and Block the new one.

When I say "Block" it reserves the port in the registry in a Key called ComDB under HKLM\SYSTEM\CurrentControlSet\Control\COM Name Arbiter

How it does so is kind of complex because its basically Hex values in the registry representing Binary values for the Com Ports.  I wanted a way to make changes to this Key without damaging the integrity of it (meaning preserve all settings that are current but make the needed changes) so I came up with these two functions.  I have not done clean up on the code so I would not call it a UDF and just a full blown example.

Here is the code:

#Include <Array.au3>

$vTest = _BlockComPort(25)
MsgBox(0, "" , $vTest & " " & @Error & " " & @Extended)

$vTest2 = _UnblockComPort(25)
MsgBox(0, "" , $vTest & " " & @Error & " " & @Extended)

;Function _BlockComPort($iPortNumber)
;Return 1 if Succsess or already blocked, Return 0 if @Error, @Error 1 = Registry Issue @Extended 1 = Can Not Read Registry @Extended 2 = Can Not Write Registry

Func _BlockComPort($iPortToChange)

$sComDB = RegRead("HKLM\SYSTEM\CurrentControlSet\Control\COM Name Arbiter", "ComDB")
If @Error Then
SetError(1, 1, 0)
Return
EndIf

$sComDB = StringTrimLeft($sComDB, 2)
$aComDB =  _StringChop($sComDB, 2) ;Array of ComDB
; _ArrayDisplay($aComDB) ;Debug Show Array
$sArraySection =Ceiling($iPortToChange / 8) ;Returns the Array Row This Com Port Falls Into
ConsoleWrite(@CRLF & "Array Section (Octect Count) " & $sArraySection) ;Debug Show Octect Count for Com Port
$iHexValueOctet = $aComDB[$sArraySection]
ConsoleWrite(@CRLF & "Current Com Port Octect Hex Value " &  $iHexValueOctet) ;Debug Show Hex Value of Octet
$iDecValueOctet = Dec($iHexValueOctet)
ConsoleWrite (@CRLF & "Current Com Port Octect Decimal Value " & $iDecValueOctet) ;Debug Show Decimal Value of Octet
$iBinaryValueOctet = _HexToBinaryString($iHexValueOctet)
ConsoleWrite(@CRLF & "Current Com Port Octect Binary Value " &  $iBinaryValueOctet) ;Debug Show Binary String of Octet

Local $aPortValue[257][4]
Local $iBitPlace = 9
;_ArrayDisplay($aPortValue) ;Debug Show Array
For $i = 1 to 256
    $iBitPlace = $iBitPlace-1
    $aPortValue[$i][0] = "COM" & $i
    $aPortValue[$i][1] = $iBitPlace
    If $iBitPlace = 1 Then $iBitPlace = 9
    Switch $aPortValue[$i][1]
        Case 1
            $aPortValue[$i][2] = 128
        Case 2
            $aPortValue[$i][2] = 64
        Case 3
            $aPortValue[$i][2] = 32
        Case 4
            $aPortValue[$i][2] = 16
        Case 5
            $aPortValue[$i][2] = 8
        Case 6
            $aPortValue[$i][2] = 4
        Case 7
            $aPortValue[$i][2] = 2
        Case 8
            $aPortValue[$i][2] = 1
    EndSwitch
$aPortValue[$i][3] = Ceiling($i/8)
Next
$aPortValue[0][0] = "COM Name"
$aPortValue[0][1] = "Reverse Bit Place"
$aPortValue[0][2] = "Decimal Value"
$aPortValue[0][3] = "Octect Count"
;_ArrayDisplay($aPortValue) ;Debug Show Binary Table

$iBinaryPosition = $aPortValue[$iPortToChange][1]
ConsoleWrite(@CRLF & "Binary Position To Check for 1 (Blocked) or 0 (Unblocked) " & $iBinaryPosition) ;Debug Show What Postion is being checked and value

;Test of Blocked
$vReturnTest = StringMid($iBinaryValueOctet, $iBinaryPosition, 1)
ConsoleWrite(@CRLF & "Current Binary Value of Com Port " &  $vReturnTest) ;Debug Shows Binary Value of This Com Port and If Blocked

If $vReturnTest = 1 Then Return 1 ;Port already blocked exit function
;Find Decimal Value of Port
$iDecToAdd = $aPortValue[$iPortToChange][2]

$iNewDecTotal = $iDecToAdd + $iDecValueOctet
ConsoleWrite(@CRLF & "New Decimal Value for Com Port Octet " &  $iNewDecTotal) ;Debug Show New Decimal Value

;Convert Decimal To Hex
$sNewHexTotal = Hex($iNewDecTotal, 2)
ConsoleWrite(@CRLF & "New Hex Value for Com Port Octet " & $sNewHexTotal) ;Debug Show New Hex Value

;Make Changes to ComDB
$aComDB[$sArraySection] = $sNewHexTotal
;_ArrayDisplay($aComDB) ;Debug Show New Array of ComDB
Local $sNewReg
For $i = 1 to $aComDB[0]
    $sNewReg &= $aComDB[$i]
Next

RegWrite("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\COM Name Arbiter", "ComDB", "REG_BINARY", Binary("0x" & $sNewReg))
If @Error Then
SetError(1, 2, 0)
Return
EndIf

Return 1 ;Return 1 if No Errors
EndFunc
;End BlockComPort


Func _UnblockComPort($iPortToChange)

$sComDB = RegRead("HKLM\SYSTEM\CurrentControlSet\Control\COM Name Arbiter", "ComDB")
If @Error Then
SetError(1, 1, 0)
Return
EndIf

$sComDB = StringTrimLeft($sComDB, 2)
$aComDB =  _StringChop($sComDB, 2) ;Array of ComDB
; _ArrayDisplay($aComDB) ;Debug Show Array
$sArraySection =Ceiling($iPortToChange / 8) ;Returns the Array Row This Com Port Falls Into
ConsoleWrite(@CRLF & "Array Section (Octect Count) " & $sArraySection) ;Debug Show Octect Count for Com Port
$iHexValueOctet = $aComDB[$sArraySection]
ConsoleWrite(@CRLF & "Current Com Port Octect Hex Value " &  $iHexValueOctet) ;Debug Show Hex Value of Octet
$iDecValueOctet = Dec($iHexValueOctet)
ConsoleWrite (@CRLF & "Current Com Port Octect Decimal Value " & $iDecValueOctet) ;Debug Show Decimal Value of Octet
$iBinaryValueOctet = _HexToBinaryString($iHexValueOctet)
ConsoleWrite(@CRLF & "Current Com Port Octect Binary Value " &  $iBinaryValueOctet) ;Debug Show Binary String of Octet

Local $aPortValue[257][4]
Local $iBitPlace = 9
;_ArrayDisplay($aPortValue)
For $i = 1 to 256
    $iBitPlace = $iBitPlace-1
    $aPortValue[$i][0] = "COM" & $i
    $aPortValue[$i][1] = $iBitPlace
    If $iBitPlace = 1 Then $iBitPlace = 9
    Switch $aPortValue[$i][1]
        Case 1
            $aPortValue[$i][2] = 128
        Case 2
            $aPortValue[$i][2] = 64
        Case 3
            $aPortValue[$i][2] = 32
        Case 4
            $aPortValue[$i][2] = 16
        Case 5
            $aPortValue[$i][2] = 8
        Case 6
            $aPortValue[$i][2] = 4
        Case 7
            $aPortValue[$i][2] = 2
        Case 8
            $aPortValue[$i][2] = 1
    EndSwitch
$aPortValue[$i][3] = Ceiling($i/8)
Next
$aPortValue[0][0] = "COM Name"
$aPortValue[0][1] = "Reverse Bit Place"
$aPortValue[0][2] = "Decimal Value"
$aPortValue[0][3] = "Octect Count"
;_ArrayDisplay($aPortValue) ;Debug Show Binary Table

$iBinaryPosition = $aPortValue[$iPortToChange][1]
ConsoleWrite(@CRLF & "Binary Position To Check for 1 (Blocked) or 0 (Unblocked) " & $iBinaryPosition) ;Debug Show What Postion is being checked and value

;Test of Blocked
$vReturnTest = StringMid($iBinaryValueOctet, $iBinaryPosition, 1)
ConsoleWrite(@CRLF & "Current Binary Value of Com Port " &  $vReturnTest) ;Debug Shows Binary Value of This Com Port and If Blocked

If $vReturnTest = 0 Then Return 1 ;Port already unblocked exit function
;Find Decimal Value of Port
$iDecToAdd = $aPortValue[$iPortToChange][2]

$iNewDecTotal =  $iDecValueOctet - $iDecToAdd
ConsoleWrite(@CRLF & "New Decimal Value for Com Port Octet " &  $iNewDecTotal) ;Debug Show New Decimal Value

;Convert Decimal To Hex
$sNewHexTotal = Hex($iNewDecTotal, 2)
ConsoleWrite(@CRLF & "New Hex Value for Com Port Octet " & $sNewHexTotal) ;Debug Show New Hex Value

;Make Changes to ComDB
$aComDB[$sArraySection] = $sNewHexTotal
;_ArrayDisplay($aComDB) ;Debug Show New Array of ComDB
Local $sNewReg
For $i = 1 to $aComDB[0]
    $sNewReg &= $aComDB[$i]
Next

RegWrite("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\COM Name Arbiter", "ComDB", "REG_BINARY", Binary("0x" & $sNewReg))
If @Error Then
SetError(1, 2, 0)
Return
EndIf
Return 1 ;Return 1 if No Errors
EndFunc
;End BlockComPort

;Func StringChop
Func _StringChop($string, $size)
$count = Ceiling(StringLen($string)/$size)
Dim $array[$count+1], $start = 1
For $i = 1 To $count
    $array[$i] = StringMid($string, $start, $size)
    $start += $size
Next
$array[0] = $count
Return $array
EndFunc
; --> End StringChop

; Hex To Binary
Func _HexToBinaryString($HexValue)
Local $Allowed = '0123456789ABCDEF'
Local $Test,$n
Local $Result = ''
if $hexValue = '' then
SetError(-2)
Return
EndIf

$hexvalue = StringSplit($hexvalue,'')
for $n = 1 to $hexValue[0]
if not StringInStr($Allowed,$hexvalue[$n]) Then
SetError(-1)
return 0
EndIf
Next

Local $bits = "0000|0001|0010|0011|0100|0101|0110|0111|1000|1001|1010|1011|1100|1101|1110|1111"
$bits = stringsplit($bits,'|')
for $n = 1 to $hexvalue[0]
$Result &= $bits[Dec($hexvalue[$n])+1]
Next

Return $Result

EndFunc
;--> End Hex To Binary

 

Share this post


Link to post
Share on other sites



Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0