mirror of
https://github.com/felixrieseberg/windows95.git
synced 2026-05-09 00:24:09 +00:00
Windows 95 can now mount a host folder as a network drive at \\HOST\HOST. Read-only, ~1500 lines, zero deps. Defaults to ~/Downloads, configurable in Settings. Protocol: NEGOTIATE (LANMAN2.1), SESSION_SETUP, TREE_CONNECT, TRANSACTION/RAP (NetShareEnum, NetServerGetInfo, NetWkstaGetInfo), TRANSACTION2/FIND_FIRST2, SEARCH (8.3 with ~N suffix mapping), OPEN_ANDX, NT_CREATE_ANDX, READ_ANDX, CLOSE, QUERY_INFORMATION, CHECK_DIRECTORY. NetBIOS Name Service on UDP 137 answers Node Status and Name Query so \\HOST resolves. v86 hook: monkeypatches adapter.on_tcp_connection (old API), shadows adapter.receive during a port-80 probe to steal a TCPConnection without side effects, re-aims it at port 139. Data via .on_data (Closure dead-code-eliminated .on/.emit). Also registers tcp-connection bus event for newer v86 builds. Security: read-only, path traversal blocked lexically and through symlinks (realpath the deepest existing ancestor, re-append tail, confirm under root). Share path validated in main-process IPC. BIOS updated to SeaBIOS 1.16.2 (compatible with old v86). v86 itself stays on the Feb 2025 prod build — newer builds hang at the splash screen on fresh boot (bisect tooling included in tools/). Also: tools/update-v86.js builds wasm+libv86+BIOS from a local v86 checkout and refuses to install JS/wasm pairs more than 14 days apart (copy.sh ships mismatched pairs). tools/parcel-build.js dynamic-import patch made tolerant of post-d4c5fa86 builds.
75 lines
1.6 KiB
TypeScript
75 lines
1.6 KiB
TypeScript
import * as fs from "fs";
|
|
import * as path from "path";
|
|
import { app } from "electron";
|
|
|
|
export interface Settings {
|
|
isFileServerEnabled: boolean;
|
|
isFileServerShowingHiddenFiles: boolean;
|
|
isFileServerShowingSystemHiddenFiles: boolean;
|
|
smbSharePath: string;
|
|
}
|
|
|
|
const DEFAULT_SETTINGS: Settings = {
|
|
isFileServerEnabled: true,
|
|
isFileServerShowingHiddenFiles: false,
|
|
isFileServerShowingSystemHiddenFiles: false,
|
|
smbSharePath: app.getPath("downloads"),
|
|
};
|
|
|
|
class SettingsManager {
|
|
private filePath: string;
|
|
private data: Settings;
|
|
|
|
constructor() {
|
|
this.filePath = path.join(app.getPath("userData"), "settings.json");
|
|
this.data = this.load();
|
|
}
|
|
|
|
private load(): Settings {
|
|
try {
|
|
if (fs.existsSync(this.filePath)) {
|
|
const fileContent = fs.readFileSync(this.filePath, "utf8");
|
|
const parsed = JSON.parse(fileContent);
|
|
|
|
return {
|
|
...DEFAULT_SETTINGS,
|
|
...parsed,
|
|
};
|
|
}
|
|
} catch (error) {
|
|
console.error("Error loading settings:", error);
|
|
}
|
|
|
|
return DEFAULT_SETTINGS;
|
|
}
|
|
|
|
private save(): void {
|
|
try {
|
|
fs.writeFileSync(this.filePath, JSON.stringify(this.data, null, 2));
|
|
} catch (error) {
|
|
console.error("Error saving settings:", error);
|
|
}
|
|
}
|
|
|
|
get(key: keyof Settings): any {
|
|
return this.data[key];
|
|
}
|
|
|
|
set<K extends keyof Settings>(key: K, value: Settings[K]): void {
|
|
this.data[key] = value;
|
|
this.save();
|
|
}
|
|
|
|
delete(key: keyof Settings): void {
|
|
delete this.data[key];
|
|
this.save();
|
|
}
|
|
|
|
clear(): void {
|
|
this.data = DEFAULT_SETTINGS;
|
|
this.save();
|
|
}
|
|
}
|
|
|
|
export const settings = new SettingsManager();
|