Apparently there's always an alternative way to do something.
What ultimately worked for me was:
SELECT convert(float, (sum(f.size) - sum(fileproperty(f.name,'SpaceUsed')))) / sum(f.size)
FROM sys.sysfiles f JOIN sys.database_files db_f ON f.fileid = db_f.file_id
WHERE db_f.type = 0
It works through ODBC and gives the same results as my original solution when executed in Management Studio.