discstation 0.1.17 → 0.1.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -5
- package/docs/PLATFORM_SUPPORT.md +24 -5
- package/install-windows.ps1 +139 -18
- package/package.json +2 -1
- package/scripts/setup.mjs +1 -1
- package/src/discstation.py +127 -41
- package/src/discstation_burn.py +102 -9
- package/src/discstation_host.py +91 -3
- package/src/static/app.js +2 -1
- package/src/static/index.html +2 -2
- package/src/win/_json.ps1 +29 -0
- package/src/win/audio-toc.ps1 +43 -0
- package/src/win/burn-audio.ps1 +72 -0
- package/src/win/burn-data.ps1 +71 -0
- package/src/win/burn-image.ps1 +64 -0
- package/src/win/disc-info.ps1 +76 -0
- package/src/win/eject.ps1 +30 -0
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Optical drive + media state for DiscStation. Emits one JSON line.
|
|
2
|
+
# Works on PowerShell 2.0 (Win7) and later. Optional arg: a drive letter ("D:")
|
|
3
|
+
# to force; otherwise the first optical drive is used.
|
|
4
|
+
param([string]$Drive = "")
|
|
5
|
+
|
|
6
|
+
$ErrorActionPreference = "Stop"
|
|
7
|
+
. (Join-Path $PSScriptRoot "_json.ps1")
|
|
8
|
+
|
|
9
|
+
$out = @{ drive = ""; media_loaded = $false; blank = $false; label = "";
|
|
10
|
+
fs = ""; media_type = ""; rewritable = $false; capacity_bytes = 0 }
|
|
11
|
+
|
|
12
|
+
try {
|
|
13
|
+
$cd = @(Get-WmiObject Win32_CDROMDrive)
|
|
14
|
+
if ($Drive) { $cd = @($cd | Where-Object { $_.Drive -eq $Drive }) }
|
|
15
|
+
if ($cd.Count -eq 0) { Write-Output (ConvertTo-JsonCompat $out); exit 0 }
|
|
16
|
+
$d = $cd[0]
|
|
17
|
+
$out.drive = $d.Drive
|
|
18
|
+
# NOTE: [bool]"False" is $true in PowerShell (any non-empty string casts
|
|
19
|
+
# truthy) -- compare explicitly instead of casting.
|
|
20
|
+
$out.media_loaded = ($d.MediaLoaded -eq $true) -or ("$($d.MediaLoaded)" -eq "True")
|
|
21
|
+
} catch { Write-Output (ConvertTo-JsonCompat $out); exit 0 }
|
|
22
|
+
|
|
23
|
+
if (-not $out.media_loaded) { Write-Output (ConvertTo-JsonCompat $out); exit 0 }
|
|
24
|
+
|
|
25
|
+
# Volume label + filesystem (WMI logical disk).
|
|
26
|
+
try {
|
|
27
|
+
$ld = Get-WmiObject Win32_LogicalDisk -Filter ("DeviceID='" + $out.drive + "'")
|
|
28
|
+
if ($ld) {
|
|
29
|
+
if ($ld.VolumeName) { $out.label = $ld.VolumeName }
|
|
30
|
+
if ($ld.FileSystem) {
|
|
31
|
+
$fs = $ld.FileSystem.ToLower()
|
|
32
|
+
if ($fs -match "udf") { $out.fs = "udf" }
|
|
33
|
+
elseif ($fs -match "cdfs|iso9660") { $out.fs = "iso9660" }
|
|
34
|
+
else { $out.fs = $fs }
|
|
35
|
+
}
|
|
36
|
+
if ($ld.Size) { $out.capacity_bytes = [int64]$ld.Size }
|
|
37
|
+
}
|
|
38
|
+
} catch {}
|
|
39
|
+
|
|
40
|
+
# IMAPI2: physical media type, blank flag, recordable capacity.
|
|
41
|
+
try {
|
|
42
|
+
$master = New-Object -ComObject "IMAPI2.MsftDiscMaster2"
|
|
43
|
+
for ($i = 0; $i -lt $master.Count; $i++) {
|
|
44
|
+
$rec = New-Object -ComObject "IMAPI2.MsftDiscRecorder2"
|
|
45
|
+
$rec.InitializeDiscRecorder($master.Item($i))
|
|
46
|
+
$match = $false
|
|
47
|
+
foreach ($p in $rec.VolumePathNames) { if ($p -and $p.TrimEnd('\') -ieq $out.drive) { $match = $true } }
|
|
48
|
+
if (-not $match) { continue }
|
|
49
|
+
$fmt = New-Object -ComObject "IMAPI2.MsftDiscFormat2Data"
|
|
50
|
+
if (-not $fmt.IsRecorderSupported($rec)) { break }
|
|
51
|
+
$fmt.Recorder = $rec
|
|
52
|
+
$fmt.ClientName = "DiscStation"
|
|
53
|
+
try { $out.blank = ($fmt.MediaHeuristicallyBlank -eq $true) } catch {}
|
|
54
|
+
try { if ($fmt.MediaPhysicallyBlank) { $out.blank = $true } } catch {}
|
|
55
|
+
try { $out.capacity_bytes = [int64]$fmt.TotalSectorsOnMedia * 2048 } catch {}
|
|
56
|
+
$t = 0; try { $t = [int]$fmt.CurrentPhysicalMediaType } catch {}
|
|
57
|
+
# IMAPI_MEDIA_PHYSICAL_TYPE
|
|
58
|
+
$map = @{ 1="cd-rom"; 2="cd-r"; 3="cd-rw"; 4="dvd-rom"; 5="dvd-r"; 6="dvd-ram";
|
|
59
|
+
7="dvd+r"; 8="dvd+rw"; 9="dvd+r dl"; 10="dvd-r dl"; 12="dvd+rw dl";
|
|
60
|
+
16="bd-rom"; 17="bd-r"; 18="bd-re" }
|
|
61
|
+
if ($map.ContainsKey($t)) { $out.media_type = $map[$t] }
|
|
62
|
+
if ($out.media_type -match "rw|ram|-re") { $out.rewritable = $true }
|
|
63
|
+
break
|
|
64
|
+
}
|
|
65
|
+
} catch {}
|
|
66
|
+
|
|
67
|
+
# An audio CD has readable media, no filesystem, and (usually) no IMAPI type.
|
|
68
|
+
if (-not $out.fs -and -not $out.blank -and ($out.media_type -eq "" -or $out.media_type -match "^cd")) {
|
|
69
|
+
try {
|
|
70
|
+
$ld2 = Get-WmiObject Win32_CDROMDrive -Filter ("Drive='" + $out.drive + "'")
|
|
71
|
+
# Win32_CDROMDrive has no track info; treat "media loaded, no FS, not blank" as audio.
|
|
72
|
+
$out.media_type = "audio_cd"
|
|
73
|
+
} catch {}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
Write-Output (ConvertTo-JsonCompat $out)
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Eject or close the optical tray via IMAPI2, with a Shell.Application fallback.
|
|
2
|
+
# Usage: eject.ps1 <drive letter e.g. D:> [close]
|
|
3
|
+
param([string]$Drive = "", [switch]$Close)
|
|
4
|
+
|
|
5
|
+
$ErrorActionPreference = "Stop"
|
|
6
|
+
$ok = $false
|
|
7
|
+
|
|
8
|
+
try {
|
|
9
|
+
$master = New-Object -ComObject "IMAPI2.MsftDiscMaster2"
|
|
10
|
+
for ($i = 0; $i -lt $master.Count; $i++) {
|
|
11
|
+
$rec = New-Object -ComObject "IMAPI2.MsftDiscRecorder2"
|
|
12
|
+
$rec.InitializeDiscRecorder($master.Item($i))
|
|
13
|
+
$match = -not $Drive
|
|
14
|
+
foreach ($p in $rec.VolumePathNames) { if ($p -and $Drive -and $p.TrimEnd('\') -ieq $Drive) { $match = $true } }
|
|
15
|
+
if (-not $match) { continue }
|
|
16
|
+
if ($Close) { $rec.CloseTray() } else { $rec.EjectMedia() }
|
|
17
|
+
$ok = $true
|
|
18
|
+
break
|
|
19
|
+
}
|
|
20
|
+
} catch {}
|
|
21
|
+
|
|
22
|
+
if (-not $ok -and -not $Close -and $Drive) {
|
|
23
|
+
try {
|
|
24
|
+
$sh = New-Object -ComObject "Shell.Application"
|
|
25
|
+
$sh.Namespace(17).ParseName($Drive).InvokeVerb("Eject")
|
|
26
|
+
$ok = $true
|
|
27
|
+
} catch {}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if ($ok) { exit 0 } else { Write-Error "eject failed"; exit 1 }
|