Skip to content

Instantly share code, notes, and snippets.

@kou1okada
Last active January 11, 2022 11:51
Show Gist options
  • Save kou1okada/24519177a9fc8e8591cc34f9d38b27ad to your computer and use it in GitHub Desktop.
Save kou1okada/24519177a9fc8e8591cc34f9d38b27ad to your computer and use it in GitHub Desktop.
shortcutfile_utils.rb: Utilities for the Windows Shortcut File

shortcutfile_utils.rb - Utilities for the Windows Shortcut File

Usage

Usage: shortcutfile_utils.rb <ShortcutFile>
    Utility of console properties.

Options:
        --show-facename
        --facename <FaceName>
        --overwrite
        --dump

Referenses

#!/bin/sh
exec ruby -x "$0" "$@"
#!ruby
# coding: utf-8
#
# shortcutfile_utils.rb
# Copyright (c) 2020 Koichi OKADA. All rights reserved.
# This script is distributed under the MIT license.
#
require 'optparse'
class ShortcutFile
attr_reader :console_properties
def initialize filename
@filename = filename
open(@filename, "rb"){|f| @data = f.read}
raise "Error: File is not ShotcutFile: '%s'" % filename unless valid?
@console_properties = ConsoleProperties.new @data
end
def valid?
size = [0x0000004c].pack("V")
guid = [0x00021401, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46].pack("VvvC8")
@data.index(size + guid) == 0
end
def dump
puts @data
end
def overwrite
open(@filename, "wb"){|f| f.write @data}
end
class ConsoleProperties
@@sig = [0x000000cc, 0xa0000002].pack("VV")
@@pFaceName = 44
@@lFaceName = 64
def initialize data
@data = data
@p0 = @data.index(@@sig)
raise "Error: Console Propertis block is not found." if @p0.nil?
end
def FaceName
@data[@p0 + @@pFaceName, @@lFaceName].force_encoding("UTF-16LE")
end
def FaceName=(facename)
bin = facename.encode("UTF-16LE").force_encoding("BINARY")
raise "Error: FaceName is too long: '%s':%d" % [bin, bin.length] if @@lFaceName < bin.length
p = @p0 + @@pFaceName
@@lFaceName.times{|i| @data[p + i] = "\0"}
bin.each_char{|c| @data[p] = c; p+=1}
end
end
end
$config = {}
opts = OptionParser.new
opts.banner = <<~EOD
Usage: #{File.basename $0} <ShortcutFile>
Utility of console properties.
Options:
EOD
opts.on("--show-facename"){|v| $config[:show_facename] = true}
opts.on("--facename <FaceName>"){|v| $config[:facename] = v}
opts.on("--overwrite"){|v| $config[:overwrite] = true}
opts.on("--dump"){|v| $config[:dump] = true}
opts.parse! ARGV
if ARGV.count <= 0
puts opts.help
exit
end
sf = ShortcutFile.new ARGV[0]
sf.console_properties.FaceName = $config[:facename] if $config[:facename]
puts sf.console_properties.FaceName if $config[:show_facename]
sf.dump if $config[:dump]
sf.overwrite if $config[:overwrite]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment