fix double drive_c issues

This commit is contained in:
olcxja 2026-10-03 08:43:19 +02:00
commit f2145d6678
7 changed files with 73 additions and 33 deletions

View file

@ -5,7 +5,7 @@ const path = require('path')
const { DIRS, resolvePortablePath } = require('./paths')
const { newGame, newGameId, addGame } = require('./library')
const { extractIconFromExe } = require('./icons')
const { listPrefixes, prefixDriveRoot } = require('./prefixes')
const { listPrefixes, prefixDriveRoots, isPrefixRoot } = require('./prefixes')
const { rewireSymlinks } = require('./symlinks')
const { copyTree, treeSize } = require('./fsutil')
@ -22,6 +22,9 @@ function moveFolder(src, dst, onProgress) {
}
async function importGame(srcDir, mode, onProgress) {
// a prefix (or its drive_c / pfx) is not an app folder: copy/move would take
// the prefix's C: drive with it and leave the prefix gutted
if (isPrefixRoot(srcDir)) return { ok: false, error: 'prefix-root' }
const name = path.basename(srcDir)
// Validate before touching the user's files: refuse an import without any
// .exe (and don't half-move a folder we'd then have to roll back).
@ -71,17 +74,23 @@ async function importGame(srcDir, mode, onProgress) {
// normally into C:\...
async function importGameFromPrefix(prefix, srcDir, onProgress) {
if (!listPrefixes().prefixes.some(p => p.name === prefix)) return { ok: false, error: 'prefix-not-found' }
// the folder must live inside the prefix's C: drive so the C:\ mapping
// holds - drive_c sits at the prefix top for plain wine, under pfx/ for
// Proton-managed prefixes
const driveRoot = prefixDriveRoot(prefix)
if (!driveRoot) return { ok: false, error: 'no-drive-c' }
const rel = path.relative(driveRoot, srcDir)
if (!rel || rel.startsWith('..') || path.isAbsolute(rel)) return { ok: false, error: 'outside-drive-c' }
const preExe = await findDefaultExe(srcDir)
// The folder must live inside one of the prefix's C: drives so the C:\
// mapping holds - drive_c sits at the prefix top for plain wine, under pfx/
// for Proton-managed prefixes, and a prefix used with BOTH kinds has both.
// Every existing drive_c counts; the stored path keeps its drive_c segment
// either way, so it resolves in the layout the app will run in.
const driveRoots = prefixDriveRoots(prefix)
if (!driveRoots.length) return { ok: false, error: 'no-drive-c' }
const src = path.resolve(String(srcDir))
const insideDrive = driveRoots.some(root => {
const rel = path.relative(root, src)
return rel && !rel.startsWith('..') && !path.isAbsolute(rel)
})
if (!insideDrive) return { ok: false, error: 'outside-drive-c' }
const preExe = await findDefaultExe(src)
if (!preExe) return { ok: false, error: 'no-exe-found' }
const id = newGameId()
const game = newGame({ id, name: path.basename(srcDir), exePath: preExe, workdir: srcDir, mode: 'prefix' })
const game = newGame({ id, name: path.basename(src), exePath: preExe, workdir: src, mode: 'prefix' })
game.importSource = 'prefix'
game.prefix = prefix
// exe picked automatically -> grab its icon right away; a missing icon is