# Vorbis ACM x64 — Windows XP x64 compatibility patch

Makes the 64-bit Ogg Vorbis ACM codec load on Windows XP Professional x64
Edition, so that 64-bit applications (FL Studio 11 x64 in particular) can
decode Vorbis-compressed WAV samples.

---

## The problem

On Windows XP x64 with FL Studio 11.1.1 installed:

- **FL Studio 32-bit** opens the demo projects and all samples load and play.
- **FL Studio 64-bit** reports the samples as missing, and dragging one in
  by hand produces an empty audio clip. Plain PCM WAVs work fine.
- The same FL Studio 11 x64 build on **Windows 7 x64** works correctly.

The FL Studio demo projects ship their samples as Vorbis-compressed WAV
files — a RIFF/WAV container whose audio data is Ogg Vorbis rather than PCM.
Decoding those requires the Vorbis ACM codec (`vorbis.acm`), which FL Studio
installs. A 32-bit process uses the 32-bit codec in `SysWOW64`; a 64-bit
process needs the 64-bit codec in `system32`. Both were present and
correctly registered under `Drivers32`.

### What was actually wrong

The 64-bit `vorbis.acm` shipped with FL Studio 11 **cannot be loaded on
Windows XP x64 at all.** It was compiled against a Windows Vista era SDK and
imports three kernel32 functions that do not exist in the XP x64 /
Server 2003 kernel:

| Function | Introduced in |
|---|---|
| `LCMapStringEx` | Vista |
| `InitOnceExecuteOnce` | Vista |
| `GetTickCount64` | Vista |

Its PE header also declares a required subsystem version of **6.00**
(Vista), against **5.00** for the working 32-bit file.

When Windows loads a DLL it maps the image first and resolves imports
afterwards. The mapping succeeds, the import resolution then fails, and the
image is silently unmapped. This is why Process Monitor shows
`Load Image ... SUCCESS` for `vorbis.acm` inside the 64-bit FL Studio
process and yet nothing works: the load is aborted a moment later, invisibly.

Because the DLL never finishes loading, the Audio Compression Manager never
registers it as a driver. Enumerating ACM drivers in a 64-bit process on the
affected machine returns only the six codecs Windows itself ships — no Ogg
Vorbis. The same enumeration in a 32-bit process on the same machine returns
fourteen drivers, Ogg Vorbis included.

**FL Studio is not at fault.** No FL Studio setting, reinstall, or registry
change can affect this. The missing `AudioCompressionManager\DriverCache`
registry key that this failure produces is a symptom, not a cause — do not
try to create or transplant it.

All three missing functions are Microsoft C runtime scaffolding pulled in by
the compiler. None of them are used by Vorbis decoding itself. The codec
code is fine; only its runtime dependencies are too new.

---

## What the patch does

Two pieces.

### 1. `KERNXP32.dll` — an import shim

A small DLL that stands in for `kernel32` as far as the codec is concerned.

- **66 functions are forwarded.** These are PE export forwarders, resolved
  by the Windows loader directly to the real `kernel32`. They cost nothing
  at runtime and change no behaviour.
- **3 functions are implemented**, using only APIs that XP x64 provides:
  - `GetTickCount64` — wraps the 32-bit `GetTickCount` and counts rollovers
    so the returned value keeps increasing.
  - `InitOnceExecuteOnce` — one-time initialisation built on
    `InterlockedCompareExchange64`, with a spin-wait for competing threads.
  - `LCMapStringEx` — translates the Vista-style locale *name* to an LCID
    and defers to `LCMapStringW`, which XP has.

The shim itself imports only four functions (`GetTickCount`,
`LCMapStringW`, `Sleep`, `DisableThreadLibraryCalls`), all present on XP,
and is stamped subsystem 5.02.

### 2. `patch_vorbis.exe` — the codec patcher

Reads the original `vorbis.acm` and writes a patched copy:

1. Rewrites the import descriptor's DLL name from `KERNEL32.dll` to
   `KERNXP32.dll`. Both strings are exactly 12 characters, so this is a
   byte-for-byte overwrite — no relative virtual addresses shift and no
   other structure in the file is disturbed.
2. Lowers the declared subsystem and OS version from 6.00 to 5.02.
3. Clears the bound-import directory, so the loader cannot use a stale
   binding that still points at the real `kernel32`.

The original file is opened read-only and never modified.

The decoder itself is untouched. Vorbis decoding is performed by the
original, unmodified code — the patch only changes where three runtime
support functions come from.

---

## Usage

### Requirements

- Windows XP Professional x64 Edition
- An account with Administrator rights
- FL Studio 11 (or whatever else needs the 64-bit Vorbis codec)

### Step 1 — make sure the codec is actually installed

Before patching, confirm the 64-bit codec is present and registered. Run:

```
C:\Program Files (x86)\Image-Line\FL Studio 11\System\Installers\VorbisACM_x64\install.bat
```

Then **reboot**. The patch modifies the installed codec, so the codec has to
be there first. If it was already installed this does no harm.

### Step 2 — apply the patch

Unzip the archive to a folder of your choice. Everything needed is included;
keep the files together, as the scripts call each other by name from their
own directory.

Extract somewhere you can leave it — the backup of your original codec is
written into this folder, and you want to keep that. A permanent location
such as `C:\vorbisfix\` is better than a temporary one. Do **not** run the
scripts from inside the zip viewer; extract first.

**Close FL Studio**, both 32-bit and 64-bit. If a running process has
`vorbis.acm` open, the file cannot be replaced.

Then right-click `install_patch.bat` → **Run as administrator**.

It will:

1. Generate `vorbis_xp.acm` from your installed codec
2. Save a backup as `vorbis.acm.original` in the same folder
3. Copy `KERNXP32.dll` into `C:\WINDOWS\system32\`
4. Copy the patched codec over `C:\WINDOWS\system32\vorbis.acm`
5. Re-run the diagnostics

The script pauses before starting and again at the end, so nothing happens
without a keypress and you can read the results.

### Step 3 — verify

Success looks like this:

- `acmtest3_64.exe` reports **`0 MISSING`** and
  `subsystem version required: 5.02`
- `acmtest64.exe` lists **`[driver] Ogg Vorbis | Ogg Vorbis Audio CODEC`**,
  and the driver count rises from 6 to 7

The driver list is also saved to `verify.txt` in the patch folder, so if the
window is closed before the output can be read, open that file instead and
look for `Ogg Vorbis`.

You can re-run either check at any time; both are read-only:

```
acmtest3_64.exe "C:\WINDOWS\system32\vorbis.acm"
acmtest64.exe
```

The real test is FL Studio 64-bit: open a demo project and confirm the
samples load **and play correctly**. A waveform appearing is not by itself
proof — listen to a clip end to end. Correct sound means correct decoding.

### Reverting

Run `uninstall_patch.bat` as administrator from the same folder. It restores
`vorbis.acm.original` and removes `KERNXP32.dll`.

**Keep `vorbis.acm.original`.** It is the only copy of the file you started
with.

---

## Notes and limitations

- **Re-running `install_patch.bat` will fail**, because the already-patched
  file no longer contains a `KERNEL32.dll` import descriptor to rewrite. The
  error message unhelpfully blames Administrator rights. This is harmless —
  the patch is already applied and nothing needs redoing.

- **Reinstalling or updating FL Studio** may restore the original codec, in
  which case the patch needs applying again.

- **Import-table analysis only sees static imports.** If the codec resolved
  additional Vista-only functions at runtime via `GetProcAddress`, that would
  not have shown up in the diagnosis and would surface as a later failure.
  In practice it decodes correctly, so this appears not to be the case.

- **`LCMapStringEx` locale handling is approximate.** The shim maps `"C"` to
  the invariant locale and everything else to the user default. The C runtime
  uses this call for case folding and sort keys, where this is a safe
  approximation on a single-locale machine.

- **`GetTickCount64` rollover counting starts when the DLL loads.** On a
  machine with more than ~49.7 days of uptime the initial value will be low.
  Nothing in audio decoding depends on this.

- **PE checksum is zeroed** in the patched file. Checksums are only enforced
  for kernel-mode drivers, not user-mode DLLs.

---

## Files

| File | Purpose |
|---|---|
| `install_patch.bat` | Applies the patch (run as Administrator) |
| `uninstall_patch.bat` | Restores the original codec |
| `patch_vorbis.exe` | Rewrites the codec's import table |
| `KERNXP32.dll` | Compatibility shim installed into `system32` |
| `kernxp32.c` | Source for the shim |
| `patch_vorbis.c` | Source for the patcher |
| `acmtest64.exe` | Lists ACM drivers visible to a 64-bit process |
| `acmtest32.exe` | Same, 32-bit — useful as a control |
| `acmtest3_64.exe` | Checks a DLL's imports against the running OS |

Two files are created in the patch folder when `install_patch.bat` runs:

| File | Purpose |
|---|---|
| `vorbis.acm.original` | Backup of the codec as it was before patching — **keep this** |
| `vorbis_xp.acm` | The patched codec, before it is copied into `system32` |
| `verify.txt` | Saved output of the post-install driver enumeration |

Both `.c` sources are included so the patch can be inspected and rebuilt.
They were compiled with mingw-w64 targeting `_WIN32_WINNT=0x0502` and
linked with subsystem version 5.02, which is what makes the resulting
binaries runnable on XP x64.
