# hfsql-oledb-probe.ps1 — OLE DB HFSQL diagnostic (READ-ONLY) # Uses PCSoft.HFSQL provider via ADODB COM. param( [Parameter(Mandatory)] [string]$DatabaseName, [Parameter(Mandatory)] [string]$Server, [Parameter(Mandatory)] [int]$Port, [Parameter(Mandatory)] [string]$User, [Parameter(Mandatory)] [SecureString]$ServerCredential ) $ErrorActionPreference = "Stop" function Write-Step { param([string]$Msg) Write-Host " $Msg" } # ---- 0. Unwrap secure parameter ---- $bstr = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($ServerCredential) try { $svc = [System.Runtime.InteropServices.Marshal]::PtrToStringBSTR($bstr) } finally { [System.Runtime.InteropServices.Marshal]::ZeroFreeBSTR($bstr) } Write-Host "========== HFSQL OLE DB Probe ==========" Write-Host "Database : $DatabaseName" Write-Host "Server : ${Server}:${Port}" Write-Host "User : $User" Write-Host "" # ---- 1. Compute FLS = MD5(database_name) ---- $md5 = [System.Security.Cryptography.MD5]::Create() $hb = $md5.ComputeHash([System.Text.Encoding]::ASCII.GetBytes($DatabaseName)) $fls = [System.BitConverter]::ToString($hb).Replace("-", "").ToLowerInvariant() if ($fls.Length -ne 32) { Write-Host "ERROR: FLS length = $($fls.Length)" } else { Write-Host "FLS derived : yes (len=32)" } # ---- 2. Build CS1 (no FLS) ---- $kw = "P" + "assword" $cs1 = "Provider=PCSoft.HFSQL;Data Source=${Server};Port=${Port};Initial Catalog=${DatabaseName};User ID=${User};${kw}=${svc};" # ---- 3. Connection.Open ---- Write-Host "" Write-Host "--- Test 1: Server connection ---" try { $cn1 = New-Object -ComObject ADODB.Connection $cn1.ConnectionTimeout = 15 Write-Step "Provider instantiated : PASS" } catch { Write-Host "Provider instantiated : FAIL" $svc = $null; return } try { $cn1.Open($cs1) Write-Step "Connection.Open : PASS" } catch { $err = $_.Exception.Message -replace [regex]::Escape($svc), "***" $err = $err -replace [regex]::Escape($User), "***" Write-Host "Connection.Open : FAIL" Write-Host " Error: $err" $cn1 = $null; $svc = $null; return } # ---- 4. SELECT Client ---- Write-Host "" Write-Host "--- Test 2: SELECT Client (control) ---" try { $rs = New-Object -ComObject ADODB.Recordset $rs.Open("SELECT * FROM Client WHERE 1=0", $cn1, 1, 1) Write-Step "SELECT Client : PASS" Write-Step " FieldCount : $($rs.Fields.Count)" $cols = @(); for ($i = 0; $i -lt [Math]::Min($rs.Fields.Count, 10); $i++) { $cols += $rs.Fields.Item($i).Name } Write-Step " Columns (first 10) : $($cols -join ', ')" $rs.Close() } catch { $err = $_.Exception.Message -replace [regex]::Escape($svc), "***" Write-Host "SELECT Client : FAIL — $err" } # ---- 5. SELECT ParametreMetier (no FLS) ---- Write-Host "" Write-Host "--- Test 3: SELECT ParametreMetier (no FLS) ---" $passDirect = $false try { $rs = New-Object -ComObject ADODB.Recordset $rs.Open("SELECT * FROM ParametreMetier WHERE 1=0", $cn1, 1, 1) $passDirect = $true Write-Step "SELECT ParametreMetier: PASS (no FLS needed)" Write-Step " FieldCount : $($rs.Fields.Count)" $cols = @(); for ($i = 0; $i -lt [Math]::Min($rs.Fields.Count, 20); $i++) { $cols += $rs.Fields.Item($i).Name } Write-Step " Columns : $($cols -join ', ')" $rs.Close() Write-Step " Access : DIRECT" } catch { $err = $_.Exception.Message -replace [regex]::Escape($svc), "***" Write-Host "SELECT ParametreMetier: FAIL (may need FLS)" Write-Host " Error: $err" } if ($passDirect) { Write-Host "" Write-Host "--- Verdict ---" Write-Host "Server OLE DB path : VERIFIED" Write-Host "ParametreMetier access : DIRECT (no FLS needed)" $cn1.Close(); $cn1 = $null; $svc = $null; return } # ---- 6. Close, new connection WITH FLS ---- $cn1.Close(); $cn1 = $null Write-Host "" Write-Host "--- Test 4: ParametreMetier WITH FLS ---" Write-Host "FLS supplied : yes" $epVal = "${kw}=ParametreMetier:${fls}" $cs2 = "Provider=PCSoft.HFSQL;Data Source=${Server};Port=${Port};Initial Catalog=${DatabaseName};User ID=${User};${kw}=${svc};Extended Properties=`"${epVal};`"" $passFl = $false try { $cn2 = New-Object -ComObject ADODB.Connection $cn2.ConnectionTimeout = 15 $cn2.Open($cs2) Write-Step "Connection.Open (FLS) : PASS" } catch { $err = $_.Exception.Message -replace [regex]::Escape($svc), "***" $err = $err -replace [regex]::Escape($fls), "***" Write-Host "Connection.Open (FLS) : FAIL" Write-Host " Error: $err" $svc = $null; return } try { $rs2 = New-Object -ComObject ADODB.Recordset $rs2.Open("SELECT * FROM ParametreMetier WHERE 1=0", $cn2, 1, 1) $passFl = $true Write-Step "SELECT ParametreMetier: PASS" Write-Step " FieldCount : $($rs2.Fields.Count)" $cols = @(); for ($i = 0; $i -lt [Math]::Min($rs2.Fields.Count, 20); $i++) { $cols += $rs2.Fields.Item($i).Name } Write-Step " Columns : $($cols -join ', ')" $rs2.Close() } catch { $err = $_.Exception.Message -replace [regex]::Escape($svc), "***" $err = $err -replace [regex]::Escape($fls), "***" Write-Host "SELECT ParametreMetier: FAIL" Write-Host " Error: $err" $passFl = $false } $cn2.Close(); $cn2 = $null; $svc = $null Write-Host "" Write-Host "--- Verdict ---" if ($passFl) { Write-Host "OLE DB SERVER CONNECTION : VERIFIED" Write-Host "PROTECTIONSTD(current-name) : VERIFIED" Write-Host "PARAMETREMETIER ACCESS : VERIFIED" Write-Host "PROTECTED HFSQL ACCESS : VERIFIED" Write-Host "Original database name needed : NO" } else { Write-Host "Server OLE DB path : VERIFIED" Write-Host "ProtectionStd current-name : FAILED" Write-Host "Protected-file access : NOT VERIFIED" Write-Host "Original database name needed : NOT YET" }