@echo off
setlocal EnableExtensions EnableDelayedExpansion
title Poytek WiFi Fix - Windows 7 - v1.3.0

rem ===========================================================================
rem  Poytek WiFi Fix for Windows 7 SP1 x64
rem  Version 1.3.0
rem
rem  Purpose
rem    Repairs WPA2-Enterprise / PEAP-MSCHAPv2 association with SSID "Poytek"
rem    on Windows 7 SP1 x64 clients.
rem
rem  What this tool changes (this computer only)
rem    - Installs the Poytek RADIUS Root CA into LocalMachine Root and CA.
rem    - Installs the active Poytek RADIUS server certificate into
rem      LocalMachine Root. This is required because the Poytek RADIUS server
rem      certificate carries a Subject name identical to its issuing CA, which
rem      Windows 7 chain building cannot resolve. Trust stays pinned to these
rem      two exact certificates only.
rem    - Enables TLS 1.2 for EAP and for the Schannel client.
rem    - Rebuilds only the "Poytek" wireless profile.
rem
rem  What this tool never changes
rem    - No RADIUS server, no FreeRADIUS configuration, no server certificate.
rem    - No access point, router, CAPsMAN, SSID or WPA2 security profile.
rem    - No other wireless profile on this computer.
rem    - No certificate that is unrelated to Poytek.
rem    - Server certificate validation is never disabled or weakened.
rem
rem  This tool never stores, transmits or logs a Poytek password.
rem ===========================================================================

set "FIX_VERSION=1.3.0"
set "WORK=%ProgramData%\Poytek\WiFiFix"
set "LOG=%WORK%\fix.log"
set "SSID_NAME=Poytek"
set "REBOOT_REQUIRED=1"
set "PROFILE_APPLIED=0"

rem Poytek RADIUS Root CA - self signed, CA:TRUE, valid 2026-07-05 to 2036-07-02
set "CA_SHA1=996426851C342052387AC541D6D7904E3C3FE621"
rem Active Poytek RADIUS server certificate - EKU serverAuth, valid 2026-07-29 to 2027-07-29
set "LEAF_SHA1=466DD2083C6960C17A38C572C09F646F8F07ECCF"
rem Minimum rastls.dll build that contains EAP TLS 1.2 support (KB2977292 or later servicing)
set "RASTLS_MIN=6.1.7601.18540"

rem ---------------------------------------------------------------------------
rem  Elevation
rem ---------------------------------------------------------------------------
net session >nul 2>&1
if errorlevel 1 (
  echo Requesting administrator permission...
  >"%temp%\poytek-elevate.vbs" echo Set UAC = CreateObject^("Shell.Application"^)
  >>"%temp%\poytek-elevate.vbs" echo UAC.ShellExecute "%~s0", "", "", "runas", 1
  cscript //nologo "%temp%\poytek-elevate.vbs"
  del /f /q "%temp%\poytek-elevate.vbs" >nul 2>&1
  exit /b 0
)

rem ---------------------------------------------------------------------------
rem  Supported platform guard - Windows 7 SP1 x64 only
rem ---------------------------------------------------------------------------
set "WIN_VER="
for /f "tokens=3" %%A in ('reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" /v CurrentVersion 2^>nul ^| findstr /I /C:"CurrentVersion"') do set "WIN_VER=%%A"

set "CSD_VER="
for /f "tokens=3" %%A in ('reg query "HKLM\SYSTEM\CurrentControlSet\Control\Windows" /v CSDVersion 2^>nul ^| findstr /I /C:"CSDVersion"') do set "CSD_VER=%%A"

set "IS_X64=0"
if /I "%PROCESSOR_ARCHITECTURE%"=="AMD64" set "IS_X64=1"
if defined PROCESSOR_ARCHITEW6432 if /I "%PROCESSOR_ARCHITEW6432%"=="AMD64" set "IS_X64=1"

if not "%WIN_VER%"=="6.1" (
  echo.
  echo This repair tool only supports Windows 7.
  echo Detected Windows version: %WIN_VER%
  echo No change was made.
  echo.
  pause
  exit /b 10
)

if /I not "%CSD_VER%"=="0x100" (
  echo.
  echo Windows 7 Service Pack 1 is required.
  echo Detected service pack value: %CSD_VER%
  echo No change was made.
  echo.
  pause
  exit /b 11
)

if not "%IS_X64%"=="1" (
  echo.
  echo This repair tool only supports the 64-bit ^(x64^) edition of Windows 7.
  echo Detected architecture: %PROCESSOR_ARCHITECTURE%
  echo No change was made.
  echo.
  pause
  exit /b 12
)

rem ---------------------------------------------------------------------------
rem  Working directory, timestamped backup directory, log
rem ---------------------------------------------------------------------------
if not exist "%WORK%" mkdir "%WORK%" >nul 2>&1

set "TS="
for /f "delims=" %%T in ('powershell.exe -NoProfile -ExecutionPolicy Bypass -Command "Get-Date -Format yyyyMMdd-HHmmss" 2^>nul') do if not defined TS set "TS=%%T"
if not defined TS set "TS=notimestamp"

set "BACKUP=%WORK%\backup-%TS%"
if not exist "%BACKUP%" mkdir "%BACKUP%" >nul 2>&1

>"%LOG%" echo Poytek WiFi Fix %FIX_VERSION%
>>"%LOG%" echo Started: %date% %time%
>>"%LOG%" echo Windows version: %WIN_VER%  ServicePack: %CSD_VER%  Arch: %PROCESSOR_ARCHITECTURE%
>>"%LOG%" echo Computer: %COMPUTERNAME%
>>"%LOG%" echo Backup directory: %BACKUP%
>>"%LOG%" echo Expected Poytek Root CA SHA1: %CA_SHA1%
>>"%LOG%" echo Expected Poytek RADIUS server certificate SHA1: %LEAF_SHA1%
>>"%LOG%" echo No password or secret is ever written to this log.
>>"%LOG%" echo.

echo.
echo ============================================================
echo  Poytek WiFi repair for Windows 7 - version %FIX_VERSION%
echo ============================================================
echo.
echo Please wait. Do not close this window.
echo.

rem ---------------------------------------------------------------------------
rem  STAGE 1 - read only evidence collection and rollback material
rem ---------------------------------------------------------------------------
set "STAGE=1-evidence"
>>"%LOG%" echo === STAGE 1: collecting evidence and rollback material ===

echo Collecting system evidence...

netsh.exe wlan show drivers >"%BACKUP%\wlan-drivers.txt" 2>&1
netsh.exe wlan show interfaces >"%BACKUP%\wlan-interfaces.txt" 2>&1
netsh.exe wlan show profiles >"%BACKUP%\wlan-profiles.txt" 2>&1
wmic qfe get HotFixID^,InstalledOn /format:table >"%BACKUP%\installed-updates.txt" 2>&1
w32tm.exe /query /status >"%BACKUP%\time-state.txt" 2>&1
>>"%BACKUP%\time-state.txt" echo Local date/time at capture: %date% %time%

powershell.exe -NoProfile -ExecutionPolicy Bypass -Command "$out=@(); foreach($s in @('Cert:\LocalMachine\Root','Cert:\LocalMachine\CA','Cert:\LocalMachine\My','Cert:\LocalMachine\TrustedPeople','Cert:\CurrentUser\Root','Cert:\CurrentUser\CA','Cert:\CurrentUser\My')){ if(Test-Path $s){ Get-ChildItem $s | Where-Object { ($_.Subject + ' ' + $_.Issuer) -match '(?i)poytek' } | ForEach-Object { $out += ($s + ' | ' + ($_.Thumbprint -replace ' ','').ToUpper() + ' | ' + $_.Subject + ' | issuer=' + $_.Issuer + ' | NotBefore=' + $_.NotBefore.ToString('s') + ' | NotAfter=' + $_.NotAfter.ToString('s')) } } }; if($out.Count -eq 0){ $out = @('none') }; Set-Content -LiteralPath '%BACKUP%\poytek-certificates-before.txt' -Value $out" >>"%LOG%" 2>&1

>>"%LOG%" echo --- Poytek related certificates before change ---
type "%BACKUP%\poytek-certificates-before.txt" >>"%LOG%" 2>&1
>>"%LOG%" echo --- end ---

reg export "HKLM\SYSTEM\CurrentControlSet\Services\RasMan\PPP\EAP\13" "%BACKUP%\eap13-before.reg" /y >>"%LOG%" 2>&1
reg export "HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols" "%BACKUP%\schannel-protocols-before.reg" /y >>"%LOG%" 2>&1

>>"%LOG%" echo Exporting the existing "%SSID_NAME%" wireless profile for rollback.
netsh.exe wlan export profile name="%SSID_NAME%" folder="%BACKUP%" >>"%LOG%" 2>&1

set "PROFILE_BACKUP="
for %%F in ("%BACKUP%\*%SSID_NAME%*.xml") do if not defined PROFILE_BACKUP set "PROFILE_BACKUP=%%~fF"
if defined PROFILE_BACKUP (
  >>"%LOG%" echo Existing profile backed up to: !PROFILE_BACKUP!
  >>"%LOG%" echo Key material in the exported profile stays encrypted. It is never exported in clear text.
) else (
  >>"%LOG%" echo No existing "%SSID_NAME%" profile was present. Nothing to roll back to.
)

rem ---------------------------------------------------------------------------
rem  STAGE 2 - effective EAP TLS implementation check (rastls.dll, authoritative)
rem ---------------------------------------------------------------------------
set "STAGE=2-eap-binary-check"
>>"%LOG%" echo.
>>"%LOG%" echo === STAGE 2: verifying the effective EAP TLS implementation ===
>>"%LOG%" echo The installed-update list is recorded as supporting evidence only.
>>"%LOG%" echo The pass/fail decision is taken from the effective rastls.dll file version.

echo Verifying the Windows EAP components...

set "QFE_PRESENT=no"
wmic qfe get HotFixID 2>nul | findstr /I /C:"KB2977292" >nul 2>&1
if not errorlevel 1 set "QFE_PRESENT=yes"
>>"%LOG%" echo KB2977292 listed by WMIC/QFE: %QFE_PRESENT% ^(supporting evidence only^)

set "RASTLS_VER="
for /f "delims=" %%V in ('powershell.exe -NoProfile -ExecutionPolicy Bypass -Command "$p=Join-Path $env:windir 'System32\rastls.dll'; if(Test-Path $p){ (Get-Item $p).VersionInfo.FileVersion } else { 'missing' }" 2^>nul') do if not defined RASTLS_VER set "RASTLS_VER=%%V"
if not defined RASTLS_VER set "RASTLS_VER=unknown"
>>"%LOG%" echo Effective System32\rastls.dll file version: %RASTLS_VER%
>"%BACKUP%\rastls-version.txt" echo %RASTLS_VER%

set "RASTLS_WOW="
for /f "delims=" %%V in ('powershell.exe -NoProfile -ExecutionPolicy Bypass -Command "$p=Join-Path $env:windir 'SysWOW64\rastls.dll'; if(Test-Path $p){ (Get-Item $p).VersionInfo.FileVersion } else { 'missing' }" 2^>nul') do if not defined RASTLS_WOW set "RASTLS_WOW=%%V"
>>"%LOG%" echo Effective SysWOW64\rastls.dll file version: %RASTLS_WOW% ^(informational^)

powershell.exe -NoProfile -ExecutionPolicy Bypass -Command "$p=Join-Path $env:windir 'System32\rastls.dll'; if(-not (Test-Path $p)){ exit 1 }; $raw=(Get-Item $p).VersionInfo.FileVersion; if($raw -notmatch '([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)'){ exit 1 }; if([version]$matches[1] -lt [version]'%RASTLS_MIN%'){ exit 1 }; exit 0" >>"%LOG%" 2>&1
if errorlevel 1 goto :eap_update_required

>>"%LOG%" echo The effective EAP TLS implementation meets the required minimum %RASTLS_MIN%.

rem ---------------------------------------------------------------------------
rem  STAGE 3 - decode and verify the embedded Poytek certificates
rem ---------------------------------------------------------------------------
set "STAGE=3-certificate-decode"
>>"%LOG%" echo.
>>"%LOG%" echo === STAGE 3: decoding and verifying the embedded Poytek certificates ===

echo Preparing the Poytek certificates...

set "CA_B64=MIIDdzCCAl+gAwIBAgIUd4EKjia9UISZGsDfybHakEq9E7wwDQYJKoZIhvcNAQELBQAwSzELMAkGA1UEBhMCSVIxEDAOBgNVBAgMB0lzZmFoYW4xDzANBgNVBAoMBlBveXRlazEZMBcGA1UEAwwQcG95dGVrLXYyLXJhZGl1czAeFw0yNjA3MDUwNDI2MjBaFw0zNjA3MDIwNDI2MjBaMEsxCzAJBgNVBAYTAklSMRAwDgYDVQQIDAdJc2ZhaGFuMQ8wDQYDVQQKDAZQb3l0ZWsxGTAXBgNVBAMMEHBveXRlay12Mi1yYWRpdXMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6Yz4g97g5NRi7Pxe21V13uI8vjB5H4sOZI37iB/T4uM0RF8pZR6ruX2UwgZ6I4JwCH3aFYW+juuU3UEuYaaokOfKAzi0t8mDxEJjfVyzGagR9NaGmfVpnoG/q9G0ApXtR8O6E1LZIXzBqFvuMf/3tGCqG2lFFEBhYx4WgTfteS3CcGYVp83Cncn2KP67shcowafXmASIMqJ6CNI+BbLcKWZ5Ref+R9i7r8LBKjAprPTihifs5PtdiudSsTkdDp1os8vmfiigLVTm+9GdWEvNVuakp1LWpJo87x6Tb/PhZ2+pKtVmgVxx7yRxGMbdro+EsTPgGW6i9V+gxLD2Bhbq9AgMBAAGjUzBRMB0GA1UdDgQWBBTRZkxo756pZXiEScpdDqBhqRZZzDAfBgNVHSMEGDAWgBTRZkxo756pZXiEScpdDqBhqRZZzDAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBfs5CU+HOGCX2sdr4EQyamXXc1NMAIeb7DMsKq5A2Nltx2o0v+TUB0mRNHLgtGuQ3Xk+N08xNPO9lbdjx4Kn7I2MmLI9JVi5XjAEixlfGLD0NAyBd2qj4L8Y0+J3m5rlkttqFvwD++zqEtOVdp+wJyvTDZPKH9Yzvz5b12GiKibSVomIUnnSPlO4JpYFukchKemYvo7VCJxvq8wz4ZXL6LkOPW/pQvqCWqsw5ph48iyI2rHHAHgoDHP+Trts5kQ4pF/w7IYlI02BnF+5mrum6bdORjnqgV2Jdhst6T7ILtxfaoRJGZ0y+BedWPa+nqkbLPVy3f4LvGKJTpKNQZXpOB"
set "LEAF_B64=MIIESDCCAzCgAwIBAgIRAMkza7zLyBFS9vZPIZ5o8scwDQYJKoZIhvcNAQELBQAwSzELMAkGA1UEBhMCSVIxEDAOBgNVBAgMB0lzZmFoYW4xDzANBgNVBAoMBlBveXRlazEZMBcGA1UEAwwQcG95dGVrLXYyLXJhZGl1czAeFw0yNjA3MjkwODAwNDZaFw0yNzA3MjkwODAwNDZaMEsxCzAJBgNVBAYTAklSMRAwDgYDVQQIDAdJc2ZhaGFuMQ8wDQYDVQQKDAZQb3l0ZWsxGTAXBgNVBAMMEHBveXRlay12Mi1yYWRpdXMwggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQC9BSFNmMPGFZ1Tx3MDePcT5OTtt3cVRazXJ8HPhbr2bztfLwoZUl8j5TgYy4ISNUP3ORjLpNm175m/C3CFunDgV/PAKkTBQut+LEM9g7MJ/ypoUR+PH2XzyEt9zi/mNZLbt0NCSwW6Cl3ZxazglgFWCBXNwH8zqkLB6rNH/YXBqTQ9zPnluFNXMdI72Epm+sfqh/55tgUabV6JTSEBFDPpK5w/HlcqxcAkA9naZBTxpLmk/p9Hkotug3lOP7JVr7a/ETRmLxvhBk+SlcspT1sZHypIS1zChwYBJf8i5ZYU5HerkXzjObIig+NWtHFw6xjnRa3d/4YKwioKG4P6lGN896YrRyslilRmPgTsAccbbcj9t6yEhYLHPOXscl8vJrqJzukvjmZv5BjXCZi8H5bKFuL1UoWz0OHQGKuwbxt5+V432rlY7AtnwtKguuozsRfdarDCplJuR7lJBQJmUBvvz4Fj0WYE2yvp4U5i9DaIGlllFDIf63p9TB2paqjyxE0CAwEAAaOBpjCBozAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATAdBgNVHQ4EFgQURMWctqbjL+MYH/FcdKXB3h5E5+4wHwYDVR0jBBgwFoAU0WZMaO+eqWV4hEnKXQ6gYakWWcwwLgYDVR0RBCcwJYIQcG95dGVrLXYyLXJhZGl1c4IRcmFkaXVzLnBveXRlay5jb20wDQYJKoZIhvcNAQELBQADggEBABhKECdiKl9+dfixyeoErXopQ4Me5zdGwqOGLSSuxUEDmCE/wnaiQLUS5bbgukrj+gDkiBPkVadsottoA91pTwnsKGVEqqjCYiIjdKJmodDDxQrT8blxw3qphuxWEGTPAXFoswg+C25HIJO6nGWraLZxL92vvryCH3QLRXFEhx32txEJ5/MeewCoF+jsSpku8rMts/WrWfbck4QUvDmD3bvnVRBtlEt2+YtK5zR8KX7dBjnBzNcTicmtxeYVogN3ZUQzElRcu7by9qFJcqX679nJY4DA00L8VqOSjuJCyIcpJ8pw6bH1eiOlCGSzaCCuK24jUJ8c/zZLwzkCaTmNa9g="

del /f /q "%WORK%\poytek-ca.b64" "%WORK%\poytek-ca.cer" "%WORK%\poytek-radius.b64" "%WORK%\poytek-radius.cer" >nul 2>&1

>"%WORK%\poytek-ca.b64" echo %CA_B64%
certutil.exe -f -decode "%WORK%\poytek-ca.b64" "%WORK%\poytek-ca.cer" >>"%LOG%" 2>&1
if errorlevel 1 goto :cert_decode_error
if not exist "%WORK%\poytek-ca.cer" goto :cert_decode_error

>"%WORK%\poytek-radius.b64" echo %LEAF_B64%
certutil.exe -f -decode "%WORK%\poytek-radius.b64" "%WORK%\poytek-radius.cer" >>"%LOG%" 2>&1
if errorlevel 1 goto :cert_decode_error
if not exist "%WORK%\poytek-radius.cer" goto :cert_decode_error

>>"%LOG%" echo Verifying the decoded Root CA thumbprint...
powershell.exe -NoProfile -ExecutionPolicy Bypass -Command "$c=New-Object System.Security.Cryptography.X509Certificates.X509Certificate2('%WORK%\poytek-ca.cer'); if(($c.Thumbprint -replace ' ','').ToUpper() -ne '%CA_SHA1%'){ exit 1 } else { exit 0 }" >>"%LOG%" 2>&1
if errorlevel 1 goto :cert_thumbprint_mismatch

>>"%LOG%" echo Verifying the decoded RADIUS server certificate thumbprint...
powershell.exe -NoProfile -ExecutionPolicy Bypass -Command "$c=New-Object System.Security.Cryptography.X509Certificates.X509Certificate2('%WORK%\poytek-radius.cer'); if(($c.Thumbprint -replace ' ','').ToUpper() -ne '%LEAF_SHA1%'){ exit 1 } else { exit 0 }" >>"%LOG%" 2>&1
if errorlevel 1 goto :cert_thumbprint_mismatch

>>"%LOG%" echo Both embedded certificate thumbprints verified.

rem ---------------------------------------------------------------------------
rem  STAGE 4 - remove only stale or conflicting Poytek certificates
rem ---------------------------------------------------------------------------
set "STAGE=4-certificate-cleanup"
>>"%LOG%" echo.
>>"%LOG%" echo === STAGE 4: removing stale or conflicting Poytek certificates ===
>>"%LOG%" echo Only certificates naming Poytek are considered. Unrelated certificates are never touched.

echo Removing stale Poytek certificates...

powershell.exe -NoProfile -ExecutionPolicy Bypass -Command "$keep=@('%CA_SHA1%','%LEAF_SHA1%'); $now=Get-Date; $required=@('Cert:\LocalMachine\Root','Cert:\LocalMachine\CA'); $stores=@('Cert:\LocalMachine\Root','Cert:\LocalMachine\CA','Cert:\LocalMachine\TrustedPeople','Cert:\CurrentUser\Root','Cert:\CurrentUser\CA'); $hard=0; foreach($s in $stores){ if(-not (Test-Path $s)){ continue }; foreach($c in @(Get-ChildItem $s)){ $tp=($c.Thumbprint -replace ' ','').ToUpper(); if($keep -contains $tp){ continue }; if((($c.Subject + ' ' + $c.Issuer) -notmatch '(?i)poytek')){ continue }; $stale=($c.NotAfter -lt $now -or $c.NotBefore -gt $now); $conflict=($c.Subject -match '(?i)CN=poytek-v2-radius'); if(-not ($stale -or $conflict)){ continue }; try { Remove-Item -LiteralPath $c.PSPath -Force -ErrorAction Stop; Add-Content -LiteralPath '%LOG%' -Value ('Removed  ' + $s + ' , ' + $tp + ' , ' + $c.Subject + ' , NotAfter=' + $c.NotAfter.ToString('s')) } catch { Add-Content -LiteralPath '%LOG%' -Value ('SKIPPED  ' + $s + ' , ' + $tp + ' , not removable in this store view'); if($required -contains $s){ $hard=1 } } } }; exit $hard" >>"%LOG%" 2>&1
if errorlevel 1 goto :cert_cleanup_error

>>"%LOG%" echo Stale certificate cleanup finished.

rem ---------------------------------------------------------------------------
rem  STAGE 5 - install the Poytek trust anchors
rem ---------------------------------------------------------------------------
set "STAGE=5-certificate-install"
>>"%LOG%" echo.
>>"%LOG%" echo === STAGE 5: installing the Poytek trust anchors ===

echo Installing the Poytek certificates...

>>"%LOG%" echo Installing the Poytek Root CA into LocalMachine Root.
certutil.exe -addstore -f Root "%WORK%\poytek-ca.cer" >>"%LOG%" 2>&1
if errorlevel 1 goto :cert_store_error

>>"%LOG%" echo Installing the Poytek Root CA into LocalMachine CA as chain building material.
certutil.exe -addstore -f CA "%WORK%\poytek-ca.cer" >>"%LOG%" 2>&1
if errorlevel 1 goto :cert_store_error

>>"%LOG%" echo Installing the active Poytek RADIUS server certificate into LocalMachine Root.
>>"%LOG%" echo Reason: the Poytek RADIUS server certificate carries a Subject name identical
>>"%LOG%" echo to its issuing CA. Windows 7 terminates chain building at that certificate.
>>"%LOG%" echo Trusting it explicitly is the only client side way to satisfy PEAP server
>>"%LOG%" echo validation without weakening validation. It is CA:FALSE and EKU serverAuth,
>>"%LOG%" echo so it can never be used to issue any other certificate.
certutil.exe -addstore -f Root "%WORK%\poytek-radius.cer" >>"%LOG%" 2>&1
if errorlevel 1 goto :cert_store_error

>>"%LOG%" echo Confirming both certificates are present in the Root store.
certutil.exe -store Root %CA_SHA1% >>"%LOG%" 2>&1
if errorlevel 1 goto :cert_store_error
certutil.exe -store Root %LEAF_SHA1% >>"%LOG%" 2>&1
if errorlevel 1 goto :cert_store_error

>>"%LOG%" echo Both Poytek trust anchors are installed.

rem ---------------------------------------------------------------------------
rem  STAGE 6 - enable TLS 1.2 for EAP and for the Schannel client
rem ---------------------------------------------------------------------------
set "STAGE=6-registry"
>>"%LOG%" echo.
>>"%LOG%" echo === STAGE 6: enabling TLS 1.2 for EAP and Schannel client ===

echo Enabling TLS 1.2 for the Windows EAP client...

reg add "HKLM\SYSTEM\CurrentControlSet\Services\RasMan\PPP\EAP\13" /v TlsVersion /t REG_DWORD /d 3072 /f >>"%LOG%" 2>&1
if errorlevel 1 goto :registry_error
reg add "HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client" /v Enabled /t REG_DWORD /d 1 /f >>"%LOG%" 2>&1
if errorlevel 1 goto :registry_error
reg add "HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client" /v DisabledByDefault /t REG_DWORD /d 0 /f >>"%LOG%" 2>&1
if errorlevel 1 goto :registry_error

>>"%LOG%" echo TLS 1.2 registry values applied.

>>"%LOG%" echo Resynchronising the Windows clock if the time service is available.
sc.exe query w32time >>"%LOG%" 2>&1
net start w32time >>"%LOG%" 2>&1
w32tm.exe /resync /nowait >>"%LOG%" 2>&1

rem ---------------------------------------------------------------------------
rem  STAGE 7 - rebuild only the Poytek wireless profile
rem ---------------------------------------------------------------------------
set "STAGE=7-wlan-profile"
>>"%LOG%" echo.
>>"%LOG%" echo === STAGE 7: rebuilding the "%SSID_NAME%" wireless profile ===
>>"%LOG%" echo No other wireless profile on this computer is read, changed or deleted.

echo Rebuilding the Poytek wireless profile...

set "PROFILE_B64=PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVMtQVNDSUkiPz4NCjxXTEFOUHJvZmlsZSB4bWxucz0iaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL25ldHdvcmtpbmcvV0xBTi9wcm9maWxlL3YxIj4NCiAgPG5hbWU+UG95dGVrPC9uYW1lPg0KICA8U1NJRENvbmZpZz4NCiAgICA8U1NJRD48bmFtZT5Qb3l0ZWs8L25hbWU+PC9TU0lEPg0KICA8L1NTSURDb25maWc+DQogIDxjb25uZWN0aW9uVHlwZT5FU1M8L2Nvbm5lY3Rpb25UeXBlPg0KICA8Y29ubmVjdGlvbk1vZGU+YXV0bzwvY29ubmVjdGlvbk1vZGU+DQogIDxhdXRvU3dpdGNoPmZhbHNlPC9hdXRvU3dpdGNoPg0KICA8TVNNPg0KICAgIDxzZWN1cml0eT4NCiAgICAgIDxhdXRoRW5jcnlwdGlvbj4NCiAgICAgICAgPGF1dGhlbnRpY2F0aW9uPldQQTI8L2F1dGhlbnRpY2F0aW9uPg0KICAgICAgICA8ZW5jcnlwdGlvbj5BRVM8L2VuY3J5cHRpb24+DQogICAgICAgIDx1c2VPbmVYPnRydWU8L3VzZU9uZVg+DQogICAgICA8L2F1dGhFbmNyeXB0aW9uPg0KICAgICAgPE9uZVggeG1sbnM9Imh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9uZXR3b3JraW5nL09uZVgvdjEiPg0KICAgICAgICA8Y2FjaGVVc2VyRGF0YT50cnVlPC9jYWNoZVVzZXJEYXRhPg0KICAgICAgICA8YXV0aE1vZGU+dXNlcjwvYXV0aE1vZGU+DQogICAgICAgIDxFQVBDb25maWc+DQogICAgICAgICAgPEVhcEhvc3RDb25maWcgeG1sbnM9Imh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wcm92aXNpb25pbmcvRWFwSG9zdENvbmZpZyINCiAgICAgICAgICAgICB4bWxuczplYXBDb21tb249Imh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wcm92aXNpb25pbmcvRWFwQ29tbW9uIg0KICAgICAgICAgICAgIHhtbG5zOmJhc2VFYXA9Imh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wcm92aXNpb25pbmcvQmFzZUVhcE1ldGhvZENvbmZpZyI+DQogICAgICAgICAgICA8RWFwTWV0aG9kPg0KICAgICAgICAgICAgICA8ZWFwQ29tbW9uOlR5cGU+MjU8L2VhcENvbW1vbjpUeXBlPg0KICAgICAgICAgICAgICA8ZWFwQ29tbW9uOkF1dGhvcklkPjA8L2VhcENvbW1vbjpBdXRob3JJZD4NCiAgICAgICAgICAgIDwvRWFwTWV0aG9kPg0KICAgICAgICAgICAgPENvbmZpZyB4bWxuczpiYXNlRWFwPSJodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcHJvdmlzaW9uaW5nL0Jhc2VFYXBDb25uZWN0aW9uUHJvcGVydGllc1YxIg0KICAgICAgICAgICAgICAgICAgICB4bWxuczptc1BlYXA9Imh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wcm92aXNpb25pbmcvTXNQZWFwQ29ubmVjdGlvblByb3BlcnRpZXNWMSINCiAgICAgICAgICAgICAgICAgICAgeG1sbnM6bXNDaGFwVjI9Imh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wcm92aXNpb25pbmcvTXNDaGFwVjJDb25uZWN0aW9uUHJvcGVydGllc1YxIj4NCiAgICAgICAgICAgICAgPGJhc2VFYXA6RWFwPg0KICAgICAgICAgICAgICAgIDxiYXNlRWFwOlR5cGU+MjU8L2Jhc2VFYXA6VHlwZT4NCiAgICAgICAgICAgICAgICA8bXNQZWFwOkVhcFR5cGU+DQogICAgICAgICAgICAgICAgICA8bXNQZWFwOlNlcnZlclZhbGlkYXRpb24+DQogICAgICAgICAgICAgICAgICAgIDxtc1BlYXA6RGlzYWJsZVVzZXJQcm9tcHRGb3JTZXJ2ZXJWYWxpZGF0aW9uPnRydWU8L21zUGVhcDpEaXNhYmxlVXNlclByb21wdEZvclNlcnZlclZhbGlkYXRpb24+DQogICAgICAgICAgICAgICAgICAgIDxtc1BlYXA6VHJ1c3RlZFJvb3RDQT45OTY0MjY4NTFDMzQyMDUyMzg3QUM1NDFENkQ3OTA0RTNDM0ZFNjIxPC9tc1BlYXA6VHJ1c3RlZFJvb3RDQT4NCiAgICAgICAgICAgICAgICAgICAgPG1zUGVhcDpUcnVzdGVkUm9vdENBPjQ2NkREMjA4M0M2OTYwQzE3QTM4QzU3MkMwOUY2NDZGOEYwN0VDQ0Y8L21zUGVhcDpUcnVzdGVkUm9vdENBPg0KICAgICAgICAgICAgICAgICAgPC9tc1BlYXA6U2VydmVyVmFsaWRhdGlvbj4NCiAgICAgICAgICAgICAgICAgIDxtc1BlYXA6RmFzdFJlY29ubmVjdD5mYWxzZTwvbXNQZWFwOkZhc3RSZWNvbm5lY3Q+DQogICAgICAgICAgICAgICAgICA8bXNQZWFwOklubmVyRWFwT3B0aW9uYWw+ZmFsc2U8L21zUGVhcDpJbm5lckVhcE9wdGlvbmFsPg0KICAgICAgICAgICAgICAgICAgPGJhc2VFYXA6RWFwPg0KICAgICAgICAgICAgICAgICAgICA8YmFzZUVhcDpUeXBlPjI2PC9iYXNlRWFwOlR5cGU+DQogICAgICAgICAgICAgICAgICAgIDxtc0NoYXBWMjpFYXBUeXBlPg0KICAgICAgICAgICAgICAgICAgICAgIDxtc0NoYXBWMjpVc2VXaW5Mb2dvbkNyZWRlbnRpYWxzPmZhbHNlPC9tc0NoYXBWMjpVc2VXaW5Mb2dvbkNyZWRlbnRpYWxzPg0KICAgICAgICAgICAgICAgICAgICA8L21zQ2hhcFYyOkVhcFR5cGU+DQogICAgICAgICAgICAgICAgICA8L2Jhc2VFYXA6RWFwPg0KICAgICAgICAgICAgICAgICAgPG1zUGVhcDpFbmFibGVRdWFyYW50aW5lQ2hlY2tzPmZhbHNlPC9tc1BlYXA6RW5hYmxlUXVhcmFudGluZUNoZWNrcz4NCiAgICAgICAgICAgICAgICAgIDxtc1BlYXA6UmVxdWlyZUNyeXB0b0JpbmRpbmc+ZmFsc2U8L21zUGVhcDpSZXF1aXJlQ3J5cHRvQmluZGluZz4NCiAgICAgICAgICAgICAgICAgIDxtc1BlYXA6UGVhcEV4dGVuc2lvbnMgLz4NCiAgICAgICAgICAgICAgICA8L21zUGVhcDpFYXBUeXBlPg0KICAgICAgICAgICAgICA8L2Jhc2VFYXA6RWFwPg0KICAgICAgICAgICAgPC9Db25maWc+DQogICAgICAgICAgPC9FYXBIb3N0Q29uZmlnPg0KICAgICAgICA8L0VBUENvbmZpZz4NCiAgICAgIDwvT25lWD4NCiAgICA8L3NlY3VyaXR5Pg0KICA8L01TTT4NCjwvV0xBTlByb2ZpbGU+DQo="

del /f /q "%WORK%\Poytek-WiFi.xml.b64" "%WORK%\Poytek-WiFi.xml" >nul 2>&1
>"%WORK%\Poytek-WiFi.xml.b64" echo %PROFILE_B64%
certutil.exe -f -decode "%WORK%\Poytek-WiFi.xml.b64" "%WORK%\Poytek-WiFi.xml" >>"%LOG%" 2>&1
if errorlevel 1 goto :profile_decode_error
if not exist "%WORK%\Poytek-WiFi.xml" goto :profile_decode_error

>>"%LOG%" echo Validating the decoded wireless profile before it is applied.
powershell.exe -NoProfile -ExecutionPolicy Bypass -Command "$ErrorActionPreference='Stop'; $x=New-Object System.Xml.XmlDocument; $x.Load('%WORK%\Poytek-WiFi.xml'); $t=$x.InnerXml; if($t -notmatch 'TrustedRootCA'){ exit 1 }; if($t -notmatch '%CA_SHA1%'){ exit 1 }; if($t -notmatch '%LEAF_SHA1%'){ exit 1 }; exit 0" >>"%LOG%" 2>&1
if errorlevel 1 goto :profile_decode_error

netsh.exe wlan delete profile name="%SSID_NAME%" >>"%LOG%" 2>&1
netsh.exe wlan add profile filename="%WORK%\Poytek-WiFi.xml" user=all >>"%LOG%" 2>&1
if errorlevel 1 goto :profile_apply_error

netsh.exe wlan show profile name="%SSID_NAME%" >"%WORK%\profile-verify.txt" 2>&1
if errorlevel 1 goto :profile_apply_error
type "%WORK%\profile-verify.txt" >>"%LOG%" 2>&1

findstr /I /C:"WPA2-Enterprise" "%WORK%\profile-verify.txt" >nul 2>&1
if errorlevel 1 goto :profile_apply_error

set "PROFILE_APPLIED=1"
>>"%LOG%" echo The "%SSID_NAME%" profile was applied and verified.

rem ---------------------------------------------------------------------------
rem  Success
rem ---------------------------------------------------------------------------
set "STAGE=done"
>>"%LOG%" echo.
>>"%LOG%" echo === RESULT: SUCCESS ===
>>"%LOG%" echo Completed: %date% %time%
>>"%LOG%" echo REBOOT_REQUIRED=%REBOOT_REQUIRED%

echo.
echo ============================================================
echo  The Poytek WiFi repair completed successfully.
echo ============================================================
echo.
echo Windows must restart once so that the new certificate trust
echo and the new EAP settings take effect.
echo.
echo After the restart:
echo   1. Select the "Poytek" wireless network.
echo   2. Enter your Poytek username using English digits.
echo   3. Enter your Poytek password.
echo.
echo Log file:
echo   %LOG%
echo Backup folder used for rollback:
echo   %BACKUP%
echo.
echo No Poytek server, access point or other user was changed by this tool.
echo.
choice /C YN /N /M "Restart Windows now? [Y/N]: "
if errorlevel 2 (
  echo.
  echo Please restart Windows manually before connecting to Poytek.
  echo.
  pause
  exit /b 0
)
>>"%LOG%" echo User accepted the restart prompt.
shutdown.exe /r /t 15 /c "Poytek WiFi repair completed - restart required"
exit /b 0

rem ===========================================================================
rem  Failure handlers
rem ===========================================================================

:eap_update_required
>>"%LOG%" echo.
>>"%LOG%" echo === RESULT: STOPPED AT STAGE %STAGE% ===
>>"%LOG%" echo The effective EAP TLS implementation is older than the required minimum.
>>"%LOG%" echo Detected System32\rastls.dll version: %RASTLS_VER%
>>"%LOG%" echo Required minimum version: %RASTLS_MIN%
>>"%LOG%" echo KB2977292 listed by WMIC/QFE: %QFE_PRESENT%
>>"%LOG%" echo No change was made to this computer.
echo.
echo ============================================================
echo  The repair was NOT applied.
echo ============================================================
echo.
echo This computer is missing the Microsoft EAP update that adds
echo TLS 1.2 support to the Windows 7 802.1X client.
echo.
echo   Detected rastls.dll version : %RASTLS_VER%
echo   Required minimum version    : %RASTLS_MIN%
echo   Listed by Windows Update    : %QFE_PRESENT%
echo.
echo This tool deliberately does not download or install Windows
echo update packages, so no change was made to this computer.
echo.
echo Please install update KB2977292 for Windows 7 SP1 x64 from
echo the official Microsoft Update Catalog:
echo.
echo   https://www.catalog.update.microsoft.com/Search.aspx?q=KB2977292
echo.
echo Restart Windows after installing it, then run this tool again.
echo.
echo Log file:
echo   %LOG%
echo.
pause
exit /b 40

:cert_decode_error
set "FAIL_CODE=20"
set "FAIL_TEXT=The embedded Poytek certificate could not be decoded."
goto :fail

:cert_thumbprint_mismatch
set "FAIL_CODE=21"
set "FAIL_TEXT=An embedded Poytek certificate did not match its expected fingerprint."
goto :fail

:cert_cleanup_error
set "FAIL_CODE=23"
set "FAIL_TEXT=A stale Poytek certificate could not be removed."
goto :fail

:cert_store_error
set "FAIL_CODE=22"
set "FAIL_TEXT=A Poytek certificate could not be installed into the Windows certificate store."
goto :fail

:registry_error
set "FAIL_CODE=30"
set "FAIL_TEXT=TLS 1.2 could not be enabled for the Windows EAP client."
goto :fail

:profile_decode_error
set "FAIL_CODE=50"
set "FAIL_TEXT=The Poytek wireless profile could not be prepared."
goto :fail

:profile_apply_error
set "FAIL_CODE=51"
set "FAIL_TEXT=The Poytek wireless profile could not be applied."
goto :fail

:fail
>>"%LOG%" echo.
>>"%LOG%" echo === RESULT: FAILED ===
>>"%LOG%" echo Failed stage: %STAGE%
>>"%LOG%" echo Failure code: %FAIL_CODE%
>>"%LOG%" echo Failure: %FAIL_TEXT%

del /f /q "%WORK%\poytek-ca.b64" "%WORK%\poytek-radius.b64" "%WORK%\Poytek-WiFi.xml.b64" >nul 2>&1

if "%PROFILE_APPLIED%"=="0" (
  if defined PROFILE_BACKUP (
    >>"%LOG%" echo Restoring the previous "%SSID_NAME%" wireless profile from !PROFILE_BACKUP!
    netsh.exe wlan delete profile name="%SSID_NAME%" >>"%LOG%" 2>&1
    netsh.exe wlan add profile filename="!PROFILE_BACKUP!" user=all >>"%LOG%" 2>&1
    if errorlevel 1 (
      >>"%LOG%" echo WARNING: the previous wireless profile could not be restored automatically.
    ) else (
      >>"%LOG%" echo The previous wireless profile was restored.
    )
  ) else (
    >>"%LOG%" echo No previous "%SSID_NAME%" profile existed, so none was restored.
    netsh.exe wlan delete profile name="%SSID_NAME%" >>"%LOG%" 2>&1
  )
)

if exist "%BACKUP%\eap13-before.reg" (
  >>"%LOG%" echo Restoring the previous EAP registry values.
  reg import "%BACKUP%\eap13-before.reg" >>"%LOG%" 2>&1
)

del /f /q "%WORK%\Poytek-WiFi.xml" >nul 2>&1

echo.
echo ============================================================
echo  The Poytek WiFi repair did NOT complete.
echo ============================================================
echo.
echo %FAIL_TEXT%
echo Failed stage: %STAGE%
echo.
echo Your previous settings were restored where possible.
echo Other wireless networks and other certificates were not changed.
echo.
echo Please send this log file to Poytek support:
echo   %LOG%
echo.
pause
exit /b %FAIL_CODE%
