diff --git a/installer/myodbc-installer.cc b/installer/myodbc-installer.cc index 0995be16..bb45d9a7 100644 --- a/installer/myodbc-installer.cc +++ b/installer/myodbc-installer.cc @@ -400,6 +400,21 @@ int add_driver(Driver *driver, const SQLWCHAR *attrs) return 1; } + /* + Some Windows Driver Manager versions can return TRUE from + SQLInstallDriverExW() to a non-elevated caller even though the system + registration was not persisted. Do not report success until the driver is + observable through the same installer profile APIs used by list/lookup. + */ + if (driver->lookup() != 0) + { + fprintf(stderr, + "[ERROR] Driver Manager reported success, but the driver " + "registration could not be verified\n"); + print_installer_error(); + return 1; + } + printf("Success: Usage count is %lu\n", (long unsigned)usage_count); return 0; diff --git a/test/windows/Test-NonAdminDriverRegistration.ps1 b/test/windows/Test-NonAdminDriverRegistration.ps1 new file mode 100644 index 00000000..6b353541 --- /dev/null +++ b/test/windows/Test-NonAdminDriverRegistration.ps1 @@ -0,0 +1,47 @@ +param( + [Parameter(Mandatory = $true)] + [string]$PackageRoot +) + +$ErrorActionPreference = 'Stop' +$identity = [Security.Principal.WindowsIdentity]::GetCurrent() +$principal = [Security.Principal.WindowsPrincipal]$identity +if ($principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) { + throw 'This regression test must run from a non-elevated process.' +} + +$package = (Resolve-Path -LiteralPath $PackageRoot).Path +$installer = Join-Path $package 'bin\myodbc-installer.exe' +$lib = Join-Path $package 'lib' +$name = "MatrixOne ODBC non-admin probe $([Guid]::NewGuid())" +$keys = @( + "HKLM:\SOFTWARE\ODBC\ODBCINST.INI\$name", + "HKLM:\SOFTWARE\WOW6432Node\ODBC\ODBCINST.INI\$name", + "HKCU:\SOFTWARE\ODBC\ODBCINST.INI\$name" +) + +foreach ($key in $keys) { + if (Test-Path -LiteralPath $key) { + throw "Refusing to overwrite pre-existing driver registration: $key" + } +} + +$output = & $installer -d -a -n $name -t "DRIVER=$(Join-Path $lib 'myodbc9w.dll');SETUP=$(Join-Path $lib 'myodbc9S.dll')" 2>&1 +$exitCode = $LASTEXITCODE +$created = @($keys | Where-Object { Test-Path -LiteralPath $_ }) + +try { + if ($created.Count -ne 0) { + throw "Non-admin registration unexpectedly created: $($created -join ', ')" + } + if ($exitCode -eq 0) { + throw "Installer reported success without registering the driver. Output: $($output -join ' | ')" + } + Write-Output "PASS non-admin registration failed truthfully (exit $exitCode)" + Write-Output ($output -join [Environment]::NewLine) +} +finally { + foreach ($key in $created) { + Remove-Item -LiteralPath $key -Recurse -Force -ErrorAction SilentlyContinue + } +}