??# kb_pointer_refresh_v1.0.ps1 - Recompute & rewrite pointer (UTF-8 no BOM, CRLF, PS 5.1-safe) Param( [Parameter(Mandatory=$true)][string]$RegistryRoot, [switch]$Write ) try{ [Console]::OutputEncoding = New-Object System.Text.UTF8Encoding($false) }catch{} function Read-Text([string]$p){ if(-not (Test-Path -LiteralPath $p)){ return '' } try{ return Get-Content -LiteralPath $p -Raw -Encoding UTF8 }catch{ return (Get-Content -LiteralPath $p -Raw) } } function To-CRLF([string]$t){ return ($t -replace "(`r?`n)","`r`n") } function Count-EntriesFromJson([string]$json){ if([string]::IsNullOrWhiteSpace($json)){ return -1 } if($json.Length -gt 0 -and ([int]$json[0] -eq 0xFEFF)){ $json=$json.Substring(1) } try{ $o = $json | ConvertFrom-Json; if($o -and $o.PSObject.Properties.Name -contains 'entries'){ return @($o.entries).Count } }catch{} try{ $m=[regex]::Match($json,'(?ms)\"entries\"\s*:\s*\[(.*?)\]'); if($m.Success){ return ([regex]::Matches($m.Groups[1].Value,'(?i)\"id\"\s*:')).Count } }catch{} return -1 } $bp = Join-Path $RegistryRoot 'bootpack\bootpack.txt' if(-not (Test-Path -LiteralPath $bp)){ Write-Host "[ERROR] bootpack.txt introuvable -> $bp"; exit 3 } $pp = Join-Path $RegistryRoot 'bootpack\bootpack_paste.txt' if(-not (Test-Path -LiteralPath $pp)){ Write-Host "[ERROR] paste introuvable -> $pp"; exit 3 } $rawPaste = Read-Text $pp try{ $sha = (Get-FileHash -Algorithm SHA256 -LiteralPath $pp).Hash.ToUpperInvariant() }catch{ $sha=' } try{ $size = (Get-Item -LiteralPath $pp).Length }catch{ $size=-1 } $ents = Count-EntriesFromJson $rawPaste $block = "[BUG_KB_JSON_POINTER]`r`n" $block += ("Path : {0}`r`n" -f $pp) $block += ("SHA256 : {0}`r`n" -f $sha) $block += ("Entries : {0}`r`n" -f $ents) $block += ("SizeBytes : {0}`r`n" -f $size) $linePtr = ("KB Pointer : {0} (SHA={1}, Entries={2}, Size={3})" -f $pp,$sha,$ents,$size) $rawBP = Read-Text $bp $patBlock = '(?ms)^\[BUG_KB_JSON_POINTER\][\s\S]*?(?=^\[|\z)' if([regex]::IsMatch($rawBP,$patBlock)){ $rawBP = [regex]::Replace($rawBP,$patBlock,$block) }else{ $sep = if($rawBP -match '\S'){ "`r`n`r`n" } else { '' } $rawBP = $block + $sep + $rawBP } $patLine = '(?mi)^\s*KB\W*Pointer\s*:\s*.*$' if([regex]::IsMatch($rawBP,$patLine)){ $rawBP = [regex]::Replace($rawBP,$patLine,$linePtr,1) }else{ $rawBP = $block + $linePtr + "`r`n`r`n" + [regex]::Replace($rawBP,$patBlock,'') } Write-Host ("[POINTER] Path={0}" -f $pp) Write-Host ("Values : SHA={0} Entries={1} Size={2}" -f $sha,$ents,$size) if($Write){ $enc = New-Object System.Text.UTF8Encoding($false) $out = To-CRLF $rawBP $bak = $bp + '.' + (Get-Date -Format 'yyyyMMdd_HHmmss') + '.bak' try{ Copy-Item -LiteralPath $bp -Destination $bak -Force }catch{} [IO.File]::WriteAllText($bp,$out,$enc) Write-Host ("STATUS=WRITE-OK -> {0}" -f $bp) exit 0 }else{ Write-Host 'PREVIEW (no write).'; exit 0 }