DanysysTeam / PS-SFTA

PowerShell Set File Type Association
253 stars 53 forks source link

IndexOf #13

Closed wrobin68 closed 1 year ago

wrobin68 commented 2 years ago

Hello,

I'm trying to change .txt association. I want to set notepad++ as default. BTW I tried with notepad and get same error. My error is the following one :

Exception calling "IndexOf" with "2" argument(s): "Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: startIndex" At \NetworkPath\SFTA.ps1:523 char:5

  • $position2 = $dataString.IndexOf("}", $position1)
  • 
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : ArgumentOutOfRangeException

Exception calling "Substring" with "2" argument(s): "StartIndex cannot be less than zero. Parameter name: startIndex" At \NetworkPath\SFTA.ps1:525 char:5

  • Write-Output $dataString.Substring($position1, $position2 - $posi ...
  • 
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : ArgumentOutOfRangeException

I use the following command : Register-FTA "C:\Program Files (x86)\Notepad++\notepad++.exe" .txt -Icon "C:\Program Files (x86)\Notepad++\notepad++.exe" or Register-FTA "C:\Windows\notepad.exe" .txt -Icon "C:\Windows\notepad.exe"

Can you help me with this ?

Regards

Robin

Danyfirex commented 2 years ago

Hello, If you have Notepad++ Installed You just need to use Set-FTA with Notepad++'s ProgId like this:

powershell -ExecutionPolicy Bypass -command "& { . .\SFTA.ps1; Set-FTA 'Applications\notepad++.exe' '.txt' }"

Regards

wrobin68 commented 2 years ago

Thx for your fast answer. But I get the same error I see that when I click now on a .txt file, the file ask me to chose the program I want to use to open the .txt file. But it doesnt open directly notepad++ and the icon didn't changed.

Regards

Robin

Danyfirex commented 2 years ago

is SFTA.ps1 in a Network Path?

wrobin68 commented 2 years ago

Not in a network path

Danyfirex commented 2 years ago

Windows Version? are you running from Batch file or from a PowerShell file? Are you running in a Remote machine? Where is SFTA.ps1 located at?

wrobin68 commented 2 years ago

Windows 2012r2 from powershell file Local machine c:\temp

Danyfirex commented 2 years ago

what I notice is that It's not getting User-Experience string from C:\Windows\SysWOW64\Shell32.dll

Could you check/test if this function works? https://github.com/DanysysTeam/PS-SFTA/blob/42ac9468a49ef37557024428ca94cca248323c19/SFTA.ps1#L512

or maybe you could send me C:\Windows\SysWOW64\Shell32.dll file to check if it has the User-Experience string.

wrobin68 commented 2 years ago

Okay, I will now go away but I will check that beginning of next week. Thanks for your help :)

wrobin68 commented 2 years ago

Hello,

You can find my shell32.dll files in the following link https://www.grosfichiers.com/gmf8EDiEj7U Regards

Robin

Danyfirex commented 2 years ago

Hello. It seems to be you Shell32.dll has not the User Experience string used in the Hash. Try this version with the string hardcoded.

Modified SFTA.ps1 ```powershell <# .SYNOPSIS Set File Type Association Windows 8/10/11 .DESCRIPTION Set File/Protocol Type Association Default Application Windows 8/10/11 .NOTES Version : 1.2.0 Author(s) : Danyfirex & Dany3j Credits : https://bbs.pediy.com/thread-213954.htm LMongrain - Hash Algorithm PureBasic Version License : MIT License Copyright : 2022 Danysys. .EXAMPLE Get-FTA Show All Application Program Id .EXAMPLE Get-FTA .pdf Show Default Application Program Id for an Extension .EXAMPLE Set-FTA AcroExch.Document.DC .pdf Set Acrobat Reader DC as Default .pdf reader .EXAMPLE Set-FTA Applications\SumatraPDF.exe .pdf Set Sumatra PDF as Default .pdf reader .EXAMPLE Set-PTA ChromeHTML http Set Google Chrome as Default for http Protocol .EXAMPLE Register-FTA "C:\SumatraPDF.exe" .pdf -Icon "shell32.dll,100" Register Application and Set as Default for .pdf reader .LINK https://github.com/DanysysTeam/PS-SFTA #> function Get-FTA { [CmdletBinding()] param ( [Parameter(Mandatory = $false)] [String] $Extension ) if ($Extension) { Write-Verbose "Get File Type Association for $Extension" $assocFile = (Get-ItemProperty "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\$Extension\UserChoice" -ErrorAction SilentlyContinue).ProgId Write-Output $assocFile } else { Write-Verbose "Get File Type Association List" $assocList = Get-ChildItem HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\* | ForEach-Object { $progId = (Get-ItemProperty "$($_.PSParentPath)\$($_.PSChildName)\UserChoice" -ErrorAction SilentlyContinue).ProgId if ($progId) { "$($_.PSChildName), $progId" } } Write-Output $assocList } } function Get-PTA { [CmdletBinding()] param ( [Parameter(Mandatory = $false)] [String] $Protocol ) if ($Protocol) { Write-Verbose "Get Protocol Type Association for $Protocol" $assocFile = (Get-ItemProperty "HKCU:\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\$Protocol\UserChoice" -ErrorAction SilentlyContinue).ProgId Write-Output $assocFile } else { Write-Verbose "Get Protocol Type Association List" $assocList = Get-ChildItem HKCU:\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\* | ForEach-Object { $progId = (Get-ItemProperty "$($_.PSParentPath)\$($_.PSChildName)\UserChoice" -ErrorAction SilentlyContinue).ProgId if ($progId) { "$($_.PSChildName), $progId" } } Write-Output $assocList } } function Register-FTA { [CmdletBinding()] param ( [Parameter( Position = 0, Mandatory = $true)] [ValidateScript( { Test-Path $_ })] [String] $ProgramPath, [Parameter( Position = 1, Mandatory = $true)] [Alias("Protocol")] [String] $Extension, [Parameter( Position = 2, Mandatory = $false)] [String] $ProgId, [Parameter( Position = 3, Mandatory = $false)] [String] $Icon ) Write-Verbose "Register Application + Set Association" Write-Verbose "Application Path: $ProgramPath" if ($Extension.Contains(".")) { Write-Verbose "Extension: $Extension" } else { Write-Verbose "Protocol: $Extension" } if (!$ProgId) { $ProgId = "SFTA." + [System.IO.Path]::GetFileNameWithoutExtension($ProgramPath).replace(" ", "") + $Extension } $progCommand = """$ProgramPath"" ""%1""" Write-Verbose "ApplicationId: $ProgId" Write-Verbose "ApplicationCommand: $progCommand" try { $keyPath = "HKEY_CURRENT_USER\SOFTWARE\Classes\$Extension\OpenWithProgids" [Microsoft.Win32.Registry]::SetValue( $keyPath, $ProgId, ([byte[]]@()), [Microsoft.Win32.RegistryValueKind]::None) $keyPath = "HKEY_CURRENT_USER\SOFTWARE\Classes\$ProgId\shell\open\command" [Microsoft.Win32.Registry]::SetValue($keyPath, "", $progCommand) Write-Verbose "Register ProgId and ProgId Command OK" } catch { throw "Register ProgId and ProgId Command FAILED" } Set-FTA -ProgId $ProgId -Extension $Extension -Icon $Icon } function Remove-FTA { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [Alias("ProgId")] [String] $ProgramPath, [Parameter(Mandatory = $true)] [String] $Extension ) function local:Remove-UserChoiceKey { param ( [Parameter( Position = 0, Mandatory = $True )] [String] $Key ) $code = @' using System; using System.Runtime.InteropServices; using Microsoft.Win32; namespace Registry { public class Utils { [DllImport("advapi32.dll", SetLastError = true)] private static extern int RegOpenKeyEx(UIntPtr hKey, string subKey, int ulOptions, int samDesired, out UIntPtr hkResult); [DllImport("advapi32.dll", SetLastError=true, CharSet = CharSet.Unicode)] private static extern uint RegDeleteKey(UIntPtr hKey, string subKey); public static void DeleteKey(string key) { UIntPtr hKey = UIntPtr.Zero; RegOpenKeyEx((UIntPtr)0x80000001u, key, 0, 0x20019, out hKey); RegDeleteKey((UIntPtr)0x80000001u, key); } } } '@ try { Add-Type -TypeDefinition $code } catch {} try { [Registry.Utils]::DeleteKey($Key) } catch {} } function local:Update-Registry { $code = @' [System.Runtime.InteropServices.DllImport("Shell32.dll")] private static extern int SHChangeNotify(int eventId, int flags, IntPtr item1, IntPtr item2); public static void Refresh() { SHChangeNotify(0x8000000, 0, IntPtr.Zero, IntPtr.Zero); } '@ try { Add-Type -MemberDefinition $code -Namespace SHChange -Name Notify } catch {} try { [SHChange.Notify]::Refresh() } catch {} } if (Test-Path -Path $ProgramPath) { $ProgId = "SFTA." + [System.IO.Path]::GetFileNameWithoutExtension($ProgramPath).replace(" ", "") + $Extension } else { $ProgId = $ProgramPath } try { $keyPath = "Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\$Extension\UserChoice" Write-Verbose "Remove User UserChoice Key If Exist: $keyPath" Remove-UserChoiceKey $keyPath $keyPath = "HKCU:\SOFTWARE\Classes\$ProgId" Write-Verbose "Remove Key If Exist: $keyPath" Remove-Item -Path $keyPath -Recurse -ErrorAction Stop | Out-Null } catch { Write-Verbose "Key No Exist: $keyPath" } try { $keyPath = "HKCU:\SOFTWARE\Classes\$Extension\OpenWithProgids" Write-Verbose "Remove Property If Exist: $keyPath Property $ProgId" Remove-ItemProperty -Path $keyPath -Name $ProgId -ErrorAction Stop | Out-Null } catch { Write-Verbose "Property No Exist: $keyPath Property: $ProgId" } Update-Registry Write-Output "Removed: $ProgId" } function Set-FTA { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [String] $ProgId, [Parameter(Mandatory = $true)] [Alias("Protocol")] [String] $Extension, [String] $Icon, [switch] $DomainSID ) if (Test-Path -Path $ProgId) { $ProgId = "SFTA." + [System.IO.Path]::GetFileNameWithoutExtension($ProgId).replace(" ", "") + $Extension } Write-Verbose "ProgId: $ProgId" Write-Verbose "Extension/Protocol: $Extension" #Write required Application Ids to ApplicationAssociationToasts #When more than one application associated with an Extension/Protocol is installed ApplicationAssociationToasts need to be updated function local:Write-RequiredApplicationAssociationToasts { param ( [Parameter( Position = 0, Mandatory = $True )] [String] $ProgId, [Parameter( Position = 1, Mandatory = $True )] [String] $Extension ) try { $keyPath = "HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\ApplicationAssociationToasts" [Microsoft.Win32.Registry]::SetValue($keyPath, $ProgId + "_" + $Extension, 0x0) Write-Verbose ("Write Reg ApplicationAssociationToasts OK: " + $ProgId + "_" + $Extension) } catch { Write-Verbose ("Write Reg ApplicationAssociationToasts FAILED: " + $ProgId + "_" + $Extension) } $allApplicationAssociationToasts = Get-ChildItem -Path HKLM:\SOFTWARE\Classes\$Extension\OpenWithList\* -ErrorAction SilentlyContinue | ForEach-Object { "Applications\$($_.PSChildName)" } $allApplicationAssociationToasts += @( ForEach ($item in (Get-ItemProperty -Path HKLM:\SOFTWARE\Classes\$Extension\OpenWithProgids -ErrorAction SilentlyContinue).PSObject.Properties ) { if ([string]::IsNullOrEmpty($item.Value) -and $item -ne "(default)") { $item.Name } }) $allApplicationAssociationToasts += Get-ChildItem -Path HKLM:SOFTWARE\Clients\StartMenuInternet\* , HKCU:SOFTWARE\Clients\StartMenuInternet\* -ErrorAction SilentlyContinue | ForEach-Object { (Get-ItemProperty ("$($_.PSPath)\Capabilities\" + (@("URLAssociations", "FileAssociations") | Select-Object -Index $Extension.Contains("."))) -ErrorAction SilentlyContinue).$Extension } $allApplicationAssociationToasts | ForEach-Object { if ($_) { if (Set-ItemProperty HKCU:\Software\Microsoft\Windows\CurrentVersion\ApplicationAssociationToasts $_"_"$Extension -Value 0 -Type DWord -ErrorAction SilentlyContinue -PassThru) { Write-Verbose ("Write Reg ApplicationAssociationToastsList OK: " + $_ + "_" + $Extension) } else { Write-Verbose ("Write Reg ApplicationAssociationToastsList FAILED: " + $_ + "_" + $Extension) } } } } function local:Update-RegistryChanges { $code = @' [System.Runtime.InteropServices.DllImport("Shell32.dll")] private static extern int SHChangeNotify(int eventId, int flags, IntPtr item1, IntPtr item2); public static void Refresh() { SHChangeNotify(0x8000000, 0, IntPtr.Zero, IntPtr.Zero); } '@ try { Add-Type -MemberDefinition $code -Namespace SHChange -Name Notify } catch {} try { [SHChange.Notify]::Refresh() } catch {} } function local:Set-Icon { param ( [Parameter( Position = 0, Mandatory = $True )] [String] $ProgId, [Parameter( Position = 1, Mandatory = $True )] [String] $Icon ) try { $keyPath = "HKEY_CURRENT_USER\SOFTWARE\Classes\$ProgId\DefaultIcon" [Microsoft.Win32.Registry]::SetValue($keyPath, "", $Icon) Write-Verbose "Write Reg Icon OK" Write-Verbose "Reg Icon: $keyPath" } catch { Write-Verbose "Write Reg Icon FAILED" } } function local:Write-ExtensionKeys { param ( [Parameter( Position = 0, Mandatory = $True )] [String] $ProgId, [Parameter( Position = 1, Mandatory = $True )] [String] $Extension, [Parameter( Position = 2, Mandatory = $True )] [String] $ProgHash ) function local:Remove-UserChoiceKey { param ( [Parameter( Position = 0, Mandatory = $True )] [String] $Key ) $code = @' using System; using System.Runtime.InteropServices; using Microsoft.Win32; namespace Registry { public class Utils { [DllImport("advapi32.dll", SetLastError = true)] private static extern int RegOpenKeyEx(UIntPtr hKey, string subKey, int ulOptions, int samDesired, out UIntPtr hkResult); [DllImport("advapi32.dll", SetLastError=true, CharSet = CharSet.Unicode)] private static extern uint RegDeleteKey(UIntPtr hKey, string subKey); public static void DeleteKey(string key) { UIntPtr hKey = UIntPtr.Zero; RegOpenKeyEx((UIntPtr)0x80000001u, key, 0, 0x20019, out hKey); RegDeleteKey((UIntPtr)0x80000001u, key); } } } '@ try { Add-Type -TypeDefinition $code } catch {} try { [Registry.Utils]::DeleteKey($Key) } catch {} } try { $keyPath = "Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\$Extension\UserChoice" Write-Verbose "Remove Extension UserChoice Key If Exist: $keyPath" Remove-UserChoiceKey $keyPath } catch { Write-Verbose "Extension UserChoice Key No Exist: $keyPath" } try { $keyPath = "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\$Extension\UserChoice" [Microsoft.Win32.Registry]::SetValue($keyPath, "Hash", $ProgHash) [Microsoft.Win32.Registry]::SetValue($keyPath, "ProgId", $ProgId) Write-Verbose "Write Reg Extension UserChoice OK" } catch { throw "Write Reg Extension UserChoice FAILED" } } function local:Write-ProtocolKeys { param ( [Parameter( Position = 0, Mandatory = $True )] [String] $ProgId, [Parameter( Position = 1, Mandatory = $True )] [String] $Protocol, [Parameter( Position = 2, Mandatory = $True )] [String] $ProgHash ) try { $keyPath = "HKCU:\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\$Protocol\UserChoice" Write-Verbose "Remove Protocol UserChoice Key If Exist: $keyPath" Remove-Item -Path $keyPath -Recurse -ErrorAction Stop | Out-Null } catch { Write-Verbose "Protocol UserChoice Key No Exist: $keyPath" } try { $keyPath = "HKEY_CURRENT_USER\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\$Protocol\UserChoice" [Microsoft.Win32.Registry]::SetValue( $keyPath, "Hash", $ProgHash) [Microsoft.Win32.Registry]::SetValue($keyPath, "ProgId", $ProgId) Write-Verbose "Write Reg Protocol UserChoice OK" } catch { throw "Write Reg Protocol UserChoice FAILED" } } function local:Get-UserExperience { [OutputType([string])] # $userExperienceSearch = "User Choice set via Windows User Experience" # $user32Path = [Environment]::GetFolderPath([Environment+SpecialFolder]::SystemX86) + "\Shell32.dll" # $fileStream = [System.IO.File]::Open($user32Path, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read, [System.IO.FileShare]::ReadWrite) # $binaryReader = New-Object System.IO.BinaryReader($fileStream) # [Byte[]] $bytesData = $binaryReader.ReadBytes(5mb) # $fileStream.Close() # $dataString = [Text.Encoding]::Unicode.GetString($bytesData) # $position1 = $dataString.IndexOf($userExperienceSearch) # $position2 = $dataString.IndexOf("}", $position1) # Write-Output $dataString.Substring($position1, $position2 - $position1 + 1) $hardcoded="User Choice set via Windows User Experience {D18B6DD5-6124-4341-9318-804003BAFA0B}" Write-Output $hardcoded } function local:Get-UserSid { [OutputType([string])] $userSid = ((New-Object System.Security.Principal.NTAccount([Environment]::UserName)).Translate([System.Security.Principal.SecurityIdentifier]).value).ToLower() Write-Output $userSid } #use in this special case #https://github.com/DanysysTeam/PS-SFTA/pull/7 function local:Get-UserSidDomain { if (-not ("System.DirectoryServices.AccountManagement" -as [type])) { Add-Type -AssemblyName System.DirectoryServices.AccountManagement } [OutputType([string])] $userSid = ([System.DirectoryServices.AccountManagement.UserPrincipal]::Current).SID.Value.ToLower() Write-Output $userSid } function local:Get-HexDateTime { [OutputType([string])] $now = [DateTime]::Now $dateTime = [DateTime]::New($now.Year, $now.Month, $now.Day, $now.Hour, $now.Minute, 0) $fileTime = $dateTime.ToFileTime() $hi = ($fileTime -shr 32) $low = ($fileTime -band 0xFFFFFFFFL) $dateTimeHex = ($hi.ToString("X8") + $low.ToString("X8")).ToLower() Write-Output $dateTimeHex } function Get-Hash { [CmdletBinding()] param ( [Parameter( Position = 0, Mandatory = $True )] [string] $BaseInfo ) function local:Get-ShiftRight { [CmdletBinding()] param ( [Parameter( Position = 0, Mandatory = $true)] [long] $iValue, [Parameter( Position = 1, Mandatory = $true)] [int] $iCount ) if ($iValue -band 0x80000000) { Write-Output (( $iValue -shr $iCount) -bxor 0xFFFF0000) } else { Write-Output ($iValue -shr $iCount) } } function local:Get-Long { [CmdletBinding()] param ( [Parameter( Position = 0, Mandatory = $true)] [byte[]] $Bytes, [Parameter( Position = 1)] [int] $Index = 0 ) Write-Output ([BitConverter]::ToInt32($Bytes, $Index)) } function local:Convert-Int32 { param ( [Parameter( Position = 0, Mandatory = $true)] $Value ) [byte[]] $bytes = [BitConverter]::GetBytes($Value) return [BitConverter]::ToInt32( $bytes, 0) } [Byte[]] $bytesBaseInfo = [System.Text.Encoding]::Unicode.GetBytes($baseInfo) $bytesBaseInfo += 0x00, 0x00 $MD5 = New-Object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider [Byte[]] $bytesMD5 = $MD5.ComputeHash($bytesBaseInfo) $lengthBase = ($baseInfo.Length * 2) + 2 $length = (($lengthBase -band 4) -le 1) + (Get-ShiftRight $lengthBase 2) - 1 $base64Hash = "" if ($length -gt 1) { $map = @{PDATA = 0; CACHE = 0; COUNTER = 0 ; INDEX = 0; MD51 = 0; MD52 = 0; OUTHASH1 = 0; OUTHASH2 = 0; R0 = 0; R1 = @(0, 0); R2 = @(0, 0); R3 = 0; R4 = @(0, 0); R5 = @(0, 0); R6 = @(0, 0); R7 = @(0, 0) } $map.CACHE = 0 $map.OUTHASH1 = 0 $map.PDATA = 0 $map.MD51 = (((Get-Long $bytesMD5) -bor 1) + 0x69FB0000L) $map.MD52 = ((Get-Long $bytesMD5 4) -bor 1) + 0x13DB0000L $map.INDEX = Get-ShiftRight ($length - 2) 1 $map.COUNTER = $map.INDEX + 1 while ($map.COUNTER) { $map.R0 = Convert-Int32 ((Get-Long $bytesBaseInfo $map.PDATA) + [long]$map.OUTHASH1) $map.R1[0] = Convert-Int32 (Get-Long $bytesBaseInfo ($map.PDATA + 4)) $map.PDATA = $map.PDATA + 8 $map.R2[0] = Convert-Int32 (($map.R0 * ([long]$map.MD51)) - (0x10FA9605L * ((Get-ShiftRight $map.R0 16)))) $map.R2[1] = Convert-Int32 ((0x79F8A395L * ([long]$map.R2[0])) + (0x689B6B9FL * (Get-ShiftRight $map.R2[0] 16))) $map.R3 = Convert-Int32 ((0xEA970001L * $map.R2[1]) - (0x3C101569L * (Get-ShiftRight $map.R2[1] 16) )) $map.R4[0] = Convert-Int32 ($map.R3 + $map.R1[0]) $map.R5[0] = Convert-Int32 ($map.CACHE + $map.R3) $map.R6[0] = Convert-Int32 (($map.R4[0] * [long]$map.MD52) - (0x3CE8EC25L * (Get-ShiftRight $map.R4[0] 16))) $map.R6[1] = Convert-Int32 ((0x59C3AF2DL * $map.R6[0]) - (0x2232E0F1L * (Get-ShiftRight $map.R6[0] 16))) $map.OUTHASH1 = Convert-Int32 ((0x1EC90001L * $map.R6[1]) + (0x35BD1EC9L * (Get-ShiftRight $map.R6[1] 16))) $map.OUTHASH2 = Convert-Int32 ([long]$map.R5[0] + [long]$map.OUTHASH1) $map.CACHE = ([long]$map.OUTHASH2) $map.COUNTER = $map.COUNTER - 1 } [Byte[]] $outHash = @(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00) [byte[]] $buffer = [BitConverter]::GetBytes($map.OUTHASH1) $buffer.CopyTo($outHash, 0) $buffer = [BitConverter]::GetBytes($map.OUTHASH2) $buffer.CopyTo($outHash, 4) $map = @{PDATA = 0; CACHE = 0; COUNTER = 0 ; INDEX = 0; MD51 = 0; MD52 = 0; OUTHASH1 = 0; OUTHASH2 = 0; R0 = 0; R1 = @(0, 0); R2 = @(0, 0); R3 = 0; R4 = @(0, 0); R5 = @(0, 0); R6 = @(0, 0); R7 = @(0, 0) } $map.CACHE = 0 $map.OUTHASH1 = 0 $map.PDATA = 0 $map.MD51 = ((Get-Long $bytesMD5) -bor 1) $map.MD52 = ((Get-Long $bytesMD5 4) -bor 1) $map.INDEX = Get-ShiftRight ($length - 2) 1 $map.COUNTER = $map.INDEX + 1 while ($map.COUNTER) { $map.R0 = Convert-Int32 ((Get-Long $bytesBaseInfo $map.PDATA) + ([long]$map.OUTHASH1)) $map.PDATA = $map.PDATA + 8 $map.R1[0] = Convert-Int32 ($map.R0 * [long]$map.MD51) $map.R1[1] = Convert-Int32 ((0xB1110000L * $map.R1[0]) - (0x30674EEFL * (Get-ShiftRight $map.R1[0] 16))) $map.R2[0] = Convert-Int32 ((0x5B9F0000L * $map.R1[1]) - (0x78F7A461L * (Get-ShiftRight $map.R1[1] 16))) $map.R2[1] = Convert-Int32 ((0x12CEB96DL * (Get-ShiftRight $map.R2[0] 16)) - (0x46930000L * $map.R2[0])) $map.R3 = Convert-Int32 ((0x1D830000L * $map.R2[1]) + (0x257E1D83L * (Get-ShiftRight $map.R2[1] 16))) $map.R4[0] = Convert-Int32 ([long]$map.MD52 * ([long]$map.R3 + (Get-Long $bytesBaseInfo ($map.PDATA - 4)))) $map.R4[1] = Convert-Int32 ((0x16F50000L * $map.R4[0]) - (0x5D8BE90BL * (Get-ShiftRight $map.R4[0] 16))) $map.R5[0] = Convert-Int32 ((0x96FF0000L * $map.R4[1]) - (0x2C7C6901L * (Get-ShiftRight $map.R4[1] 16))) $map.R5[1] = Convert-Int32 ((0x2B890000L * $map.R5[0]) + (0x7C932B89L * (Get-ShiftRight $map.R5[0] 16))) $map.OUTHASH1 = Convert-Int32 ((0x9F690000L * $map.R5[1]) - (0x405B6097L * (Get-ShiftRight ($map.R5[1]) 16))) $map.OUTHASH2 = Convert-Int32 ([long]$map.OUTHASH1 + $map.CACHE + $map.R3) $map.CACHE = ([long]$map.OUTHASH2) $map.COUNTER = $map.COUNTER - 1 } $buffer = [BitConverter]::GetBytes($map.OUTHASH1) $buffer.CopyTo($outHash, 8) $buffer = [BitConverter]::GetBytes($map.OUTHASH2) $buffer.CopyTo($outHash, 12) [Byte[]] $outHashBase = @(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00) $hashValue1 = ((Get-Long $outHash 8) -bxor (Get-Long $outHash)) $hashValue2 = ((Get-Long $outHash 12) -bxor (Get-Long $outHash 4)) $buffer = [BitConverter]::GetBytes($hashValue1) $buffer.CopyTo($outHashBase, 0) $buffer = [BitConverter]::GetBytes($hashValue2) $buffer.CopyTo($outHashBase, 4) $base64Hash = [Convert]::ToBase64String($outHashBase) } Write-Output $base64Hash } Write-Verbose "Getting Hash For $ProgId $Extension" If ($DomainSID.IsPresent) { Write-Verbose "Use Get-UserSidDomain" } Else { Write-Verbose "Use Get-UserSid" } $userSid = If ($DomainSID.IsPresent) { Get-UserSidDomain } Else { Get-UserSid } $userExperience = Get-UserExperience $userDateTime = Get-HexDateTime Write-Debug "UserDateTime: $userDateTime" Write-Debug "UserSid: $userSid" Write-Debug "UserExperience: $userExperience" $baseInfo = "$Extension$userSid$ProgId$userDateTime$userExperience".ToLower() Write-Verbose "baseInfo: $baseInfo" $progHash = Get-Hash $baseInfo Write-Verbose "Hash: $progHash" #Write AssociationToasts List Write-RequiredApplicationAssociationToasts $ProgId $Extension #Handle Extension Or Protocol if ($Extension.Contains(".")) { Write-Verbose "Write Registry Extension: $Extension" Write-ExtensionKeys $ProgId $Extension $progHash } else { Write-Verbose "Write Registry Protocol: $Extension" Write-ProtocolKeys $ProgId $Extension $progHash } if ($Icon) { Write-Verbose "Set Icon: $Icon" Set-Icon $ProgId $Icon } Update-RegistryChanges } function Set-PTA { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [String] $ProgId, [Parameter(Mandatory = $true)] [String] $Protocol, [String] $Icon ) Set-FTA -ProgId $ProgId -Protocol $Protocol -Icon $Icon } ```

It would be great If You can tell me the whole Windows Version so I can do more tests.

wrobin68 commented 2 years ago

It's all good now :)

Thanks for your support Fast and clear