safing-portbase/utils/osdetail/binmeta_windows.go
2020-11-17 10:04:32 +01:00

96 lines
2.9 KiB
Go

package osdetail
import (
"bufio"
"bytes"
"fmt"
"strings"
)
const powershellGetFileDescription = `Get-ItemProperty %q | Format-List`
// GetBinaryNameFromSystem queries the operating system for a human readable
// name for the given binary path.
func GetBinaryNameFromSystem(path string) (string, error) {
// Get FileProperties via Powershell call.
output, err := runPowershellCmd(fmt.Sprintf(powershellGetFileDescription, path))
if err != nil {
return "", fmt.Errorf("failed to get file properties of %s: %s", path, err)
}
// Create scanner for the output.
scanner := bufio.NewScanner(bytes.NewBufferString(output))
scanner.Split(bufio.ScanLines)
// Search for the FileDescription line.
for scanner.Scan() {
// Split line up into fields.
fields := strings.Fields(scanner.Text())
// Discard lines with less than two fields.
if len(fields) < 2 {
continue
}
// Skip all lines that we aren't looking for.
if fields[0] != "FileDescription:" {
continue
}
// Clean and return.
return cleanFileDescription(fields[1:]), nil
}
// Generate a default name as default.
return "", ErrNotFound
}
const powershellGetIcon = `Add-Type -AssemblyName System.Drawing
$Icon = [System.Drawing.Icon]::ExtractAssociatedIcon(%q)
$MemoryStream = New-Object System.IO.MemoryStream
$Icon.save($MemoryStream)
$Bytes = $MemoryStream.ToArray()
$MemoryStream.Flush()
$MemoryStream.Dispose()
[convert]::ToBase64String($Bytes)`
// TODO: This returns a small and crappy icon.
// Saving a better icon to file works:
/*
Add-Type -AssemblyName System.Drawing
$ImgList = New-Object System.Windows.Forms.ImageList
$ImgList.ImageSize = New-Object System.Drawing.Size(256,256)
$ImgList.ColorDepth = 32
$Icon = [System.Drawing.Icon]::ExtractAssociatedIcon("C:\Program Files (x86)\Mozilla Firefox\firefox.exe")
$ImgList.Images.Add($Icon);
$BigIcon = $ImgList.Images.Item(0)
$BigIcon.Save("test.png")
*/
// But not saving to a memory stream:
/*
Add-Type -AssemblyName System.Drawing
$ImgList = New-Object System.Windows.Forms.ImageList
$ImgList.ImageSize = New-Object System.Drawing.Size(256,256)
$ImgList.ColorDepth = 32
$Icon = [System.Drawing.Icon]::ExtractAssociatedIcon("C:\Program Files (x86)\Mozilla Firefox\firefox.exe")
$ImgList.Images.Add($Icon);
$MemoryStream = New-Object System.IO.MemoryStream
$BigIcon = $ImgList.Images.Item(0)
$BigIcon.Save($MemoryStream)
$Bytes = $MemoryStream.ToArray()
$MemoryStream.Flush()
$MemoryStream.Dispose()
[convert]::ToBase64String($Bytes)
*/
// GetBinaryIconFromSystem queries the operating system for the associated icon
// for a given binary path and returns it as a data-URL.
func GetBinaryIconFromSystem(path string) (string, error) {
// Get Associated File Icon via Powershell call.
output, err := runPowershellCmd(fmt.Sprintf(powershellGetIcon, path))
if err != nil {
return "", fmt.Errorf("failed to get file properties of %s: %s", path, err)
}
return "data:image/png;base64," + output, nil
}