update all the functiosn now used in the msvc pack
This commit is contained in:
parent
df3c29f0d9
commit
8ad86744fc
@ -44,6 +44,10 @@ PRG=$(readlink -f $0)
|
||||
BASEDIR=`dirname "$PRG"`
|
||||
BASEDIR=`cd "$BASEDIR" && pwd`/..
|
||||
|
||||
OLDPATH=$PATH
|
||||
export PATH=$BASEDIR/libexec:$PATH
|
||||
echo $PATH
|
||||
|
||||
# Parameters
|
||||
PRODUCT_DIR=$1
|
||||
TARGET=$2
|
||||
@ -64,6 +68,8 @@ fi
|
||||
# call main
|
||||
builder_controller
|
||||
|
||||
export PATH=$OLDPATH
|
||||
|
||||
# exit
|
||||
exit 0
|
||||
|
||||
|
160
doc/beautify_bash.py
Normal file
160
doc/beautify_bash.py
Normal file
@ -0,0 +1,160 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
#**************************************************************************
|
||||
# Copyright (C) 2011, Paul Lutus *
|
||||
# *
|
||||
# This program is free software; you can redistribute it and/or modify *
|
||||
# it under the terms of the GNU General Public License as published by *
|
||||
# the Free Software Foundation; either version 2 of the License, or *
|
||||
# (at your option) any later version. *
|
||||
# *
|
||||
# This program is distributed in the hope that it will be useful, *
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
# GNU General Public License for more details. *
|
||||
# *
|
||||
# You should have received a copy of the GNU General Public License *
|
||||
# along with this program; if not, write to the *
|
||||
# Free Software Foundation, Inc., *
|
||||
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
#**************************************************************************
|
||||
|
||||
import re, sys
|
||||
|
||||
PVERSION = '1.0'
|
||||
|
||||
class BeautifyBash:
|
||||
|
||||
def __init__(self):
|
||||
self.tab_str = ' '
|
||||
self.tab_size = 2
|
||||
|
||||
def read_file(self,fp):
|
||||
with open(fp) as f:
|
||||
return f.read()
|
||||
|
||||
def write_file(self,fp,data):
|
||||
with open(fp,'w') as f:
|
||||
f.write(data)
|
||||
|
||||
def beautify_string(self,data,path = ''):
|
||||
tab = 0
|
||||
case_stack = []
|
||||
in_here_doc = False
|
||||
defer_ext_quote = False
|
||||
in_ext_quote = False
|
||||
ext_quote_string = ''
|
||||
here_string = ''
|
||||
output = []
|
||||
line = 1
|
||||
for record in re.split('\n',data):
|
||||
record = record.rstrip()
|
||||
stripped_record = record.strip()
|
||||
|
||||
# collapse multiple quotes between ' ... '
|
||||
test_record = re.sub(r'\'.*?\'','',stripped_record)
|
||||
# collapse multiple quotes between " ... "
|
||||
test_record = re.sub(r'".*?"','',test_record)
|
||||
# collapse multiple quotes between ` ... `
|
||||
test_record = re.sub(r'`.*?`','',test_record)
|
||||
# collapse multiple quotes between \` ... ' (weird case)
|
||||
test_record = re.sub(r'\\`.*?\'','',test_record)
|
||||
# strip out any escaped single characters
|
||||
test_record = re.sub(r'\\.','',test_record)
|
||||
# remove '#' comments
|
||||
test_record = re.sub(r'(\A|\s)(#.*)','',test_record,1)
|
||||
if(not in_here_doc):
|
||||
if(re.search('<<-?',test_record)):
|
||||
here_string = re.sub('.*<<-?\s*[\'|"]?([_|\w]+)[\'|"]?.*','\\1',stripped_record,1)
|
||||
in_here_doc = (len(here_string) > 0)
|
||||
if(in_here_doc): # pass on with no changes
|
||||
output.append(record)
|
||||
# now test for here-doc termination string
|
||||
if(re.search(here_string,test_record) and not re.search('<<',test_record)):
|
||||
in_here_doc = False
|
||||
else: # not in here doc
|
||||
if(in_ext_quote):
|
||||
if(re.search(ext_quote_string,test_record)):
|
||||
# provide line after quotes
|
||||
test_record = re.sub('.*%s(.*)' % ext_quote_string,'\\1',test_record,1)
|
||||
in_ext_quote = False
|
||||
else: # not in ext quote
|
||||
if(re.search(r'(\A|\s)(\'|")',test_record)):
|
||||
# apply only after this line has been processed
|
||||
defer_ext_quote = True
|
||||
ext_quote_string = re.sub('.*([\'"]).*','\\1',test_record,1)
|
||||
# provide line before quote
|
||||
test_record = re.sub('(.*)%s.*' % ext_quote_string,'\\1',test_record,1)
|
||||
if(in_ext_quote):
|
||||
# pass on unchanged
|
||||
output.append(record)
|
||||
else: # not in ext quote
|
||||
inc = len(re.findall('(\s|\A|;)(case|then|do)(;|\Z|\s)',test_record))
|
||||
inc += len(re.findall('(\{|\(|\[)',test_record))
|
||||
outc = len(re.findall('(\s|\A|;)(esac|fi|done|elif)(;|\)|\||\Z|\s)',test_record))
|
||||
outc += len(re.findall('(\}|\)|\])',test_record))
|
||||
if(re.search(r'\besac\b',test_record)):
|
||||
if(len(case_stack) == 0):
|
||||
sys.stderr.write(
|
||||
'File %s: error: "esac" before "case" in line %d.\n' % (path,line)
|
||||
)
|
||||
else:
|
||||
outc += case_stack.pop()
|
||||
# sepcial handling for bad syntax within case ... esac
|
||||
if(len(case_stack) > 0):
|
||||
if(re.search('\A[^(]*\)',test_record)):
|
||||
# avoid overcount
|
||||
outc -= 2
|
||||
case_stack[-1] += 1
|
||||
if(re.search(';;',test_record)):
|
||||
outc += 1
|
||||
case_stack[-1] -= 1
|
||||
# an ad-hoc solution for the "else" keyword
|
||||
else_case = (0,-1)[re.search('^(else)',test_record) != None]
|
||||
net = inc - outc
|
||||
tab += min(net,0)
|
||||
extab = tab + else_case
|
||||
extab = max(0,extab)
|
||||
output.append((self.tab_str * self.tab_size * extab) + stripped_record)
|
||||
tab += max(net,0)
|
||||
if(defer_ext_quote):
|
||||
in_ext_quote = True
|
||||
defer_ext_quote = False
|
||||
if(re.search(r'\bcase\b',test_record)):
|
||||
case_stack.append(0)
|
||||
line += 1
|
||||
error = (tab != 0)
|
||||
if(error):
|
||||
sys.stderr.write('File %s: error: indent/outdent mismatch: %d.\n' % (path,tab))
|
||||
return '\n'.join(output), error
|
||||
|
||||
def beautify_file(self,path):
|
||||
error = False
|
||||
if(path == '-'):
|
||||
data = sys.stdin.read()
|
||||
result,error = self.beautify_string(data,'(stdin)')
|
||||
sys.stdout.write(result)
|
||||
else: # named file
|
||||
data = self.read_file(path)
|
||||
result,error = self.beautify_string(data,path)
|
||||
if(data != result):
|
||||
# make a backup copy
|
||||
self.write_file(path + '~',data)
|
||||
self.write_file(path,result)
|
||||
return error
|
||||
|
||||
def main(self):
|
||||
error = False
|
||||
sys.argv.pop(0)
|
||||
if(len(sys.argv) < 1):
|
||||
sys.stderr.write('usage: shell script filenames or \"-\" for stdin.\n')
|
||||
else:
|
||||
for path in sys.argv:
|
||||
error |= self.beautify_file(path)
|
||||
sys.exit((0,1)[error])
|
||||
|
||||
# if not called as a module
|
||||
if(__name__ == '__main__'):
|
||||
BeautifyBash().main()
|
||||
|
@ -11,18 +11,20 @@
|
||||
builder_config() {
|
||||
|
||||
# Define commands
|
||||
CMD_7z="`which 7z.exe`" ; builder_check_error "Command '7z' not installed"
|
||||
CMD_unzip="`which unzip.exe`" ; builder_check_error "Command 'unzip' not installed"
|
||||
CMD_unrar="`which UnRAR.exe`" ; builder_check_error "Command 'UnRAR' not installed"
|
||||
CMD_zip="`which zip.exe`" ; builder_check_error "Command 'zip' not installed"
|
||||
CMD_lha="`which lha.exe`" ; builder_check_error "Command 'lha' not installed"
|
||||
CMD_tar="`which tar.exe`" ; builder_check_error "Command 'tar' not installed"
|
||||
CMD_cabextract="`which cabextract.exe`" ; builder_check_error "Command 'cabextract' not installed"
|
||||
CMD_unix2dos="`which unix2dos.exe`" ; builder_check_error "Command 'unix2dos' not installed"
|
||||
CMD_sha1sum="`which sha1sum.exe`" ; builder_check_error "Command 'sha1sum' not installed"
|
||||
CMD_inifile="`which inifile.exe`" ; builder_check_error "Command 'inifile' not installed (http://www.horstmuc.de/wbat32d.htm#inifile)"
|
||||
CMD_showver="`which ShowVer.exe`" ; builder_check_error "Command 'ShowVer' not installed (http://www.codeproject.com/Articles/2457/ShowVer-exe-command-line-VERSIONINFO-display-progr)"
|
||||
CMD_tidy="`which tidy.exe`" ; builder_check_error "Command 'tidy' not installed"
|
||||
CMD_7z="`which 7z`" ; builder_check_error "Command '7z' not installed"
|
||||
CMD_unzip="`which unzip.exe`" ; builder_check_error "Command 'unzip' not installed"
|
||||
CMD_unrar="`which UnRAR.exe`" ; builder_check_error "Command 'UnRAR' not installed"
|
||||
CMD_zip="`which zip.exe`" ; builder_check_error "Command 'zip' not installed"
|
||||
CMD_tar="`which tar.exe`" ; builder_check_error "Command 'tar' not installed"
|
||||
CMD_cabextract="`which cabextract.exe`" ; builder_check_error "Command 'cabextract' not installed"
|
||||
CMD_unix2dos="`which unix2dos.exe`" ; builder_check_error "Command 'unix2dos' not installed"
|
||||
CMD_sha1sum="`which sha1sum.exe`" ; builder_check_error "Command 'sha1sum' not installed"
|
||||
CMD_inifile="`which inifile.exe`" ; builder_check_error "Command 'inifile' not installed (http://www.horstmuc.de/wbat32d.htm#inifile)"
|
||||
CMD_showver="`which ShowVer.exe`" ; builder_check_error "Command 'ShowVer' not installed (http://www.codeproject.com/Articles/2457/ShowVer-exe-command-line-VERSIONINFO-display-progr)"
|
||||
CMD_tidy="`which tidy.exe`" ; builder_check_error "Command 'tidy' not installed"
|
||||
CMD_msiexec="`which msiexec.exe`" ; builder_check_error "Command 'msiexec' not installed"
|
||||
CMD_innounp="`which innounp.exe`" ; builder_check_error "Command 'innounp' not installed"
|
||||
CMD_xmlstarlet="`which xmlstarlet.exe`" ; builder_check_error "Command 'xmlstarlat' not installed"
|
||||
|
||||
# Check temp dir
|
||||
test -d ${TMP_DIR}
|
||||
@ -188,14 +190,14 @@ builder_create() {
|
||||
|
||||
# Copy files and convert text files to dos format
|
||||
# cp -Rv ${PRODUCT_DIR}/AIO $INST_DIR
|
||||
# cp -Rv ${PRODUCT_DIR}/CLIENT_DATA $INST_DIR
|
||||
# cp -Rv ${PRODUCT_DIR}/Temp $INST_DIR
|
||||
# if [ -d "${PRODUCT_DIR}/SERVER_DATA" ] ; then
|
||||
# cp -Rv ${PRODUCT_DIR}/SERVER_DATA $INST_DIR
|
||||
# fi
|
||||
|
||||
# copy binaries
|
||||
for (( i = 0 ; i < ${#DL_SOURCE[@]} ; i++ )) ; do
|
||||
DL_EXTRACT_PATH[$i]=${INST_DIR}/CLIENT_DATA/${DL_ARCH[$i]}/${DL_EXTRACT_TO[$i]}
|
||||
DL_EXTRACT_PATH[$i]=${INST_DIR}/Temp/${DL_ARCH[$i]}/${DL_EXTRACT_TO[$i]}
|
||||
local format=${DL_EXTRACT_FORMAT[$i]}
|
||||
if [ -z "$format" ] ; then format="cp"; fi
|
||||
local option=${DL_EXTRACT_OPTION[$i]}
|
||||
@ -240,9 +242,10 @@ builder_package() {
|
||||
local release_new=${CREATOR_TAG}${RELEASE}
|
||||
local aio_file=${PN}_${VERSION}-${release_new}.7z
|
||||
|
||||
rm -rf $INST_DIR/Temp
|
||||
pushd ${OUTPUT_DIR}
|
||||
rm -f ${aio_file} ${AIO_REPOS_FILE_PATTERN}.7z
|
||||
7z a ${AIO_REPOS_FILE_PATTERN}.7z -v $INST_DIR/*
|
||||
$CMD_7z a ${AIO_REPOS_FILE_PATTERN}.7z $INST_DIR/*
|
||||
builder_check_error "Building AIO-package"
|
||||
popd
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
|
||||
#############################################
|
||||
# void retrieve_file (src, dst)
|
||||
#
|
||||
@ -67,8 +68,6 @@ function process_file() {
|
||||
$CMD_unzip $option -o $src -d $dst
|
||||
elif [ "$format" = "unrar" ]; then
|
||||
$CMD_unrar x -y $option $src $dst
|
||||
elif [ "$format" = "lha" ]; then
|
||||
$CMD_lha x $option -w=$dst $src
|
||||
elif [ "$format" = "targz" ]; then
|
||||
$CMD_tar xzvf $option $src -C $dst
|
||||
elif [ "$format" = "tarbz2" ]; then
|
||||
@ -201,16 +200,28 @@ write_ini_file() {
|
||||
# Var:
|
||||
#
|
||||
###################
|
||||
get_file_version() {
|
||||
local getver_file=$1
|
||||
local getver_var=$2
|
||||
|
||||
if [ -f "$getver_file" ] ; then
|
||||
$CMD_showver $getver_file | grep FileVersion: | rev | cut -d: -f1 | rev | tr -d ' ' > $getver_ver
|
||||
echo "file $getver_file has version $getver_ver"
|
||||
else
|
||||
echo "$getver_file not found"
|
||||
fi
|
||||
vercomp() {
|
||||
[ ! $(echo -e "$1\n$2" | sort --version-sort | head -1) = "$1" ]
|
||||
}
|
||||
|
||||
###################
|
||||
# Get Verison of File
|
||||
#
|
||||
# Copy file only if it is newer
|
||||
#
|
||||
# Parameter
|
||||
# File: to process
|
||||
# Var:
|
||||
#
|
||||
###################
|
||||
|
||||
|
||||
get_file_ver() {
|
||||
local getver_file=$2
|
||||
local __resultvar=$1
|
||||
local myresult=`$CMD_showver $(cygpath -pw "$getver_file") | grep FileVersion: | rev | cut -d: -f1 | rev | tr -d ' '`
|
||||
echo "$getver_file -> $myresult"
|
||||
eval $__resultvar="'$myresult'"
|
||||
}
|
||||
|
||||
###################
|
||||
@ -226,10 +237,29 @@ get_file_version() {
|
||||
copyver() {
|
||||
local source_file=$1
|
||||
local target_file=$2
|
||||
local source_ver
|
||||
local target_ver
|
||||
local source_ver=""
|
||||
local target_ver=""
|
||||
|
||||
get_file_version $source_file $source_ver
|
||||
echo "Source File: $source_file Target Version: $target_file"
|
||||
if [ -f "$source_file" ] && [ -f "$target_file" ] ; then
|
||||
get_file_ver source_ver $source_file
|
||||
get_file_ver target_ver $target_file
|
||||
if [ vercomp $source_ver $target_ver ] ; then
|
||||
echo "Source Verssion: $source_ver > Target Version: $target_ver"
|
||||
echo "Copying File"
|
||||
cp $source_file $target_file
|
||||
else
|
||||
echo "Source Verssion: $source_ver =< Target Version: $target_ver"
|
||||
echo "Not Copying File"
|
||||
fi
|
||||
elif [ -f "$source_file" ] && [ ! -f "$target_file" ] ; then
|
||||
source_ver=$(get_file_version $source_file)
|
||||
echo "Source Verssion: $source_ver"
|
||||
echo "Copying File"
|
||||
cp $source_file $target_file
|
||||
else
|
||||
echo "Nothing to copy"
|
||||
fi
|
||||
}
|
||||
|
||||
###################
|
||||
@ -249,3 +279,68 @@ tidy_xml() {
|
||||
cat $source_file | $CMD_tidy -utf8 -xml -w 255 -i -c -q -asxml | sed -e 's!>!>!g' -e 's!<!<!g' > $target_file
|
||||
}
|
||||
|
||||
#############################################
|
||||
# void extract_file (format, src, dst)
|
||||
#
|
||||
# Description: Extract a file
|
||||
#
|
||||
# Parameter
|
||||
# format: compression format
|
||||
# src: source file to be used
|
||||
# dst: path to extract the file
|
||||
#
|
||||
#############################################
|
||||
function extract_file() {
|
||||
|
||||
local format=$1
|
||||
local src=$2
|
||||
local dst=$3
|
||||
local option=$4
|
||||
local src_dir=`dirname "$src"`
|
||||
local src_file=`basename "$src"`
|
||||
local dst_dir=`dirname "$dst"`
|
||||
local dst_file=`basename "$dst"`
|
||||
|
||||
log_debug "Compression format: $format"
|
||||
|
||||
mkdir -p $dst
|
||||
if [ "$format" = "msi-a" ]; then
|
||||
mkdir /cygdrive/c/msi-adm
|
||||
pushd $src_dir
|
||||
echo $src_file
|
||||
$CMD_msiexec /a "$src_file" $option TARGETDIR="c:\msi-adm"
|
||||
popd
|
||||
cp -r /cygdrive/c/msi-adm/* $dst
|
||||
rm -rf /cygdrive/c/msi-adm
|
||||
elif [ "$format" = "msp-a" ]; then
|
||||
pushd $dst_dir
|
||||
cp $src $dst_dir
|
||||
$CMD_msiexec /p "$src_file" /a "$dst_file" SHORTFILENAMES=TRUE /qb
|
||||
popd
|
||||
elif [ "$format" = "7zip" ]; then
|
||||
$CMD_7z x -y $option -o$dst $src
|
||||
elif [ "$format" = "unzip" ]; then
|
||||
$CMD_unzip $option -o $src -d $dst
|
||||
elif [ "$format" = "unrar" ]; then
|
||||
$CMD_unrar x -y $option $(cygpath -pw "$src") $(cygpath -pw "$dst")
|
||||
elif [ "$format" = "cab" ]; then
|
||||
$CMD_cabextract $option -d $dst $src
|
||||
elif [ "$format" = "cab-sfx" ]; then
|
||||
$CMD_cabextract $option -d $dst $src
|
||||
$CMD_xmlstarlet sel -N X="http://schemas.microsoft.com/wix/2008/Burn" -t -m "//X:Payload" -v "concat(@SourcePath,'-',@FilePath)" -n $dst/0 | tr '\\' '/' > $dst/rename.list
|
||||
for i in `cat $dst/rename.list`
|
||||
do
|
||||
pushd $dst
|
||||
local src_var=$(echo $i | cut -f1 -d-)
|
||||
local dst_var=$(echo $i | cut -f2 -d-)
|
||||
mkdir -p $(dirname $dst_var)
|
||||
mv -v $src_var $dst_var
|
||||
popd
|
||||
done
|
||||
elif [ "$format" = "inno" ]; then
|
||||
$CMD_innounp $option -d $dst $src
|
||||
else
|
||||
fatal_error "Unknown compression format: $format"
|
||||
fi
|
||||
}
|
||||
|
||||
|
BIN
libexec/MsiX.exe
Executable file
BIN
libexec/MsiX.exe
Executable file
Binary file not shown.
534
libexec/MsiX/MsiX.cpp
Normal file
534
libexec/MsiX/MsiX.cpp
Normal file
@ -0,0 +1,534 @@
|
||||
|
||||
#include "msix.h"
|
||||
#pragma comment(lib, "msi.lib")
|
||||
|
||||
// Entry point.
|
||||
int _tmain(int argc, _TCHAR* argv[])
|
||||
{
|
||||
DWORD dwError = NOERROR;
|
||||
HRESULT hr = NOERROR;
|
||||
ARGS args = { 0 };
|
||||
IStorage* pRootStorage = NULL;
|
||||
IEnumSTATSTG* pEnum = NULL;
|
||||
LPCTSTR pszPersist = (LPTSTR)MSIDBOPEN_READONLY;
|
||||
STATSTG stg = { 0 };
|
||||
PMSIHANDLE hDatabase = NULL;
|
||||
PMSIHANDLE hView = NULL;
|
||||
PMSIHANDLE hRecord = NULL;
|
||||
|
||||
dwError = ParseArguments(argc, argv, &args);
|
||||
if (ERROR_SUCCESS != dwError)
|
||||
{
|
||||
return dwError;
|
||||
}
|
||||
|
||||
// Open the root storage file and extract storages first. Storages cannot
|
||||
// be extracted using MSI APIs so we must use the compound file implementation
|
||||
// for IStorage.
|
||||
hr = StgOpenStorage(
|
||||
CT2W(args.Path),
|
||||
NULL,
|
||||
STGM_READ | STGM_SHARE_EXCLUSIVE,
|
||||
NULL,
|
||||
0,
|
||||
&pRootStorage);
|
||||
if (SUCCEEDED(hr) && pRootStorage)
|
||||
{
|
||||
// Determine if the file path specifies an MSP file.
|
||||
// This will be used later to open the database with MSI APIs.
|
||||
if (IsPatch(pRootStorage))
|
||||
{
|
||||
pszPersist = MSIDBOPEN_READONLY + MSIDBOPEN_PATCHFILE;
|
||||
}
|
||||
|
||||
hr = pRootStorage->EnumElements(0, NULL, 0, &pEnum);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
while (S_OK == (hr = pEnum->Next(1, &stg, NULL)))
|
||||
{
|
||||
if (STGTY_STORAGE == stg.type)
|
||||
{
|
||||
hr = SaveStorage(pRootStorage, args.Directory, stg.pwcsName,
|
||||
args.IncludeExtension ? TEXT(".mst") : NULL);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
SAFE_RELEASE(pEnum);
|
||||
}
|
||||
}
|
||||
SAFE_RELEASE(pRootStorage);
|
||||
|
||||
// Now open the database using MSI APIs. Patches cannot be opened simultaneously
|
||||
// since exclusive access is required and no MSI APIs are exported that accept
|
||||
// an IStorage pointer.
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
dwError = MsiOpenDatabase(args.Path, pszPersist, &hDatabase);
|
||||
if (ERROR_SUCCESS == dwError)
|
||||
{
|
||||
dwError = MsiDatabaseOpenView(hDatabase,
|
||||
TEXT("SELECT `Name`, `Data` FROM `_Streams`"), &hView);
|
||||
if (ERROR_SUCCESS == dwError)
|
||||
{
|
||||
dwError = MsiViewExecute(hView, NULL);
|
||||
if (ERROR_SUCCESS == dwError)
|
||||
{
|
||||
while (ERROR_SUCCESS == (dwError = MsiViewFetch(hView, &hRecord)))
|
||||
{
|
||||
dwError = SaveStream(hRecord, args.Directory, args.IncludeExtension);
|
||||
if (ERROR_SUCCESS != dwError)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If there are no more records indicate success.
|
||||
if (ERROR_NO_MORE_ITEMS == dwError)
|
||||
{
|
||||
dwError = ERROR_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If a Win32 error has occurred return only the win32 error portion.
|
||||
if (FACILITY_WIN32 == HRESULT_FACILITY(hr))
|
||||
{
|
||||
dwError = HRESULT_CODE(hr);
|
||||
}
|
||||
else if (FAILED(hr))
|
||||
{
|
||||
// Just set it to the HRESULT. Many common HRESULTs
|
||||
// will yield an error string from FormatMessage.
|
||||
dwError = hr;
|
||||
}
|
||||
|
||||
// Print the error to the console.
|
||||
if (ERROR_SUCCESS != dwError)
|
||||
{
|
||||
win32_error(dwError);
|
||||
}
|
||||
|
||||
return dwError;
|
||||
}
|
||||
|
||||
// Parse the file path, and optionally output directory and extension guessing switch.
|
||||
DWORD ParseArguments(int argc, [Pre(Null=No)] _TCHAR* argv[], [Pre(Null=No)] LPARGS args)
|
||||
{
|
||||
_ASSERTE(argv);
|
||||
_ASSERTE(args);
|
||||
|
||||
int iParamIndex = 1;
|
||||
|
||||
// Validate arguments.
|
||||
if (2 > argc)
|
||||
{
|
||||
error(TEXT("Error: you must specify a Windows Installer file from which to extract files.\n"));
|
||||
usage(argv[0], stderr);
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (0 == _tcsicmp(TEXT("/?"), argv[iParamIndex]) || 0 == _tcsicmp(TEXT("-?"), argv[iParamIndex]))
|
||||
{
|
||||
// Display the usage text.
|
||||
usage(argv[0], stdout);
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
else if (TEXT('/') == argv[iParamIndex][0] || TEXT('-') == argv[iParamIndex][0])
|
||||
{
|
||||
// Filename should not begin with a command-switch character.
|
||||
error(TEXT("Error: invalid file name.\n"));
|
||||
usage(argv[0], stderr);
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Set the path argument.
|
||||
args->Path = const_cast<LPTSTR>(argv[iParamIndex]);
|
||||
}
|
||||
|
||||
// Get the output directory if requested.
|
||||
while (++iParamIndex < argc)
|
||||
{
|
||||
// The directory in which files are extracted.
|
||||
if (0 == _tcsicmp(TEXT("/out"), argv[iParamIndex]) || 0 == _tcsicmp(TEXT("-out"), argv[iParamIndex]))
|
||||
{
|
||||
if (++iParamIndex < argc && TEXT('/') != argv[iParamIndex][0] && TEXT('-') != argv[iParamIndex][0])
|
||||
{
|
||||
args->Directory = const_cast<LPTSTR>(argv[iParamIndex]);
|
||||
}
|
||||
else
|
||||
{
|
||||
error(TEXT("Error: you must specify an output directory with /out.\n"));
|
||||
usage(argv[0], stderr);
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
// Whether or not to include or guess at extensions for output file names.
|
||||
else if (0 == _tcsicmp(TEXT("/ext"), argv[iParamIndex]) || 0 == _tcsicmp(TEXT("-ext"), argv[iParamIndex]))
|
||||
{
|
||||
args->IncludeExtension = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
error(TEXT("Error: unknown option: %s.\n"), argv[iParamIndex]);
|
||||
usage (argv[0], stderr);
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
// Prints usage to the given output file stream.
|
||||
void usage(LPCTSTR pszPath, FILE* out)
|
||||
{
|
||||
_ASSERTE(pszPath);
|
||||
_ASSERTE(out);
|
||||
|
||||
LPTSTR pszName = NULL;
|
||||
pszName = (LPTSTR)_tcsrchr(pszPath, TEXT('\\'));
|
||||
if (pszName)
|
||||
{
|
||||
// Advance past the backslash.
|
||||
pszName++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Set the executable name.
|
||||
pszName = const_cast<LPTSTR>(pszPath);
|
||||
}
|
||||
|
||||
_ftprintf(out, TEXT("Usage: %s <file> [/out <output>] [/ext]\n\n"), pszName);
|
||||
_ftprintf(out, TEXT("\tfile - Path to an MSI, MSM, MSP, or PCP file.\n"));
|
||||
_ftprintf(out, TEXT("\tout - Extract streams and storages to the <output> directory.\n"));
|
||||
_ftprintf(out, TEXT("\text - Append appropriate extensions to output files.\n"));
|
||||
_ftprintf(out, TEXT("\nExtracts transforms and cabinets from a Windows Installer file.\n"));
|
||||
}
|
||||
|
||||
// Colors errors on the console red and prints the formatted error.
|
||||
// You can use positional format specifiers with CRT8.
|
||||
void error(LPCTSTR pszFormat, ...)
|
||||
{
|
||||
_ASSERTE(pszFormat);
|
||||
|
||||
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||
HANDLE hStdErr = INVALID_HANDLE_VALUE;
|
||||
va_list args;
|
||||
|
||||
// Set console colors to error values.
|
||||
hStdErr = GetStdHandle(STD_ERROR_HANDLE);
|
||||
if (INVALID_HANDLE_VALUE != hStdErr)
|
||||
{
|
||||
if (GetConsoleScreenBufferInfo(hStdErr, &csbi))
|
||||
{
|
||||
// Set new console colors.
|
||||
SetConsoleTextAttribute(hStdErr, COLOR_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
// Print error.
|
||||
va_start(args, pszFormat);
|
||||
_vftprintf_p(stderr, pszFormat, args);
|
||||
va_end(args);
|
||||
|
||||
// Reset the console colors to original values.
|
||||
if (INVALID_HANDLE_VALUE != hStdErr)
|
||||
{
|
||||
SetConsoleTextAttribute(hStdErr, csbi.wAttributes);
|
||||
}
|
||||
}
|
||||
|
||||
// Wrapper around FormatMessage for getting error text.
|
||||
// Calls error() to print the error to the console.
|
||||
void win32_error(DWORD dwError)
|
||||
{
|
||||
LPTSTR pszError;
|
||||
|
||||
// Format the error. Error ends with new line.
|
||||
if (FormatMessage(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
|
||||
NULL,
|
||||
dwError,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
(LPTSTR) &pszError,
|
||||
0,
|
||||
NULL))
|
||||
{
|
||||
error(TEXT("Error 0x%1$08x (%1$d): %2$s"), dwError, pszError);
|
||||
LocalFree(pszError);
|
||||
}
|
||||
}
|
||||
|
||||
// Creates a patch from components, using the current working
|
||||
// directory if pszDir is NULL.
|
||||
// pszExt should be either NULL or start with a ".".
|
||||
LPTSTR MakePath(LPTSTR pszDest, size_t cchDest, LPCTSTR pszDir, LPCTSTR pszName, LPCTSTR pszExt)
|
||||
{
|
||||
size_t len = 0;
|
||||
|
||||
_ASSERTE(pszDest);
|
||||
_ASSERTE(cchDest);
|
||||
_ASSERTE(pszName);
|
||||
|
||||
// Make sure pszDest is NULL-terminated.
|
||||
pszDest[0] = TEXT('\0');
|
||||
|
||||
if (pszDir)
|
||||
{
|
||||
// Get the length of pszDir.
|
||||
len = _tcslen(pszDir);
|
||||
|
||||
if (len && 0 != _tcsncpy_s(pszDest, cchDest, pszDir, len))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (len && TEXT('\\') != pszDest[len - 1])
|
||||
{
|
||||
// Make sure the path ends with a "\".
|
||||
if (0 != _tcsncat_s(pszDest, cchDest, TEXT("\\"), _TRUNCATE))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Append the file name.
|
||||
if (0 != _tcsncat_s(pszDest, cchDest, pszName, _TRUNCATE))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Append the extension.
|
||||
if (pszExt)
|
||||
{
|
||||
if (0 != _tcsncat_s(pszDest, cchDest, pszExt, _TRUNCATE))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return pszDest;
|
||||
}
|
||||
|
||||
// Wrapper around allocating and filling a buffer using MsiRecordGetString().
|
||||
UINT GetString(MSIHANDLE hRecord, UINT iField, LPTSTR* ppszProperty, DWORD* pcchProperty)
|
||||
{
|
||||
_ASSERTE(hRecord);
|
||||
_ASSERTE(iField > 0);
|
||||
_ASSERTE(ppszProperty);
|
||||
_ASSERTE(pcchProperty);
|
||||
|
||||
UINT iErr = NOERROR;
|
||||
DWORD cchProperty = 0;
|
||||
|
||||
iErr = MsiRecordGetString(hRecord, iField, TEXT(""), &cchProperty);
|
||||
if (ERROR_MORE_DATA == iErr)
|
||||
{
|
||||
*ppszProperty = new TCHAR[++cchProperty];
|
||||
*pcchProperty = cchProperty;
|
||||
|
||||
iErr = MsiRecordGetString(hRecord, iField, *ppszProperty, &cchProperty);
|
||||
if (ERROR_SUCCESS != iErr)
|
||||
{
|
||||
delete [] *ppszProperty;
|
||||
*ppszProperty = NULL;
|
||||
*pcchProperty = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return iErr;
|
||||
}
|
||||
|
||||
// Determines if the given IStorage* is for a patch
|
||||
// using the STATSTG for the IStorage object.
|
||||
BOOL IsPatch(IStorage* pStorage)
|
||||
{
|
||||
_ASSERTE(pStorage);
|
||||
|
||||
HRESULT hr = NOERROR;
|
||||
STATSTG stg = { 0 };
|
||||
|
||||
hr = pStorage->Stat(&stg, STATFLAG_NONAME);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
return !memcmp(&stg.clsid, &CLSID_MsiPatch, sizeof(CLSID));
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Creates a new storage file and saves the named sub-storage of pRootStorage
|
||||
// to the new storage file.
|
||||
HRESULT SaveStorage(IStorage* pRootStorage, LPCTSTR pszDir, PCWSTR pszName, LPCTSTR pszExt)
|
||||
{
|
||||
HRESULT hr = NOERROR;
|
||||
TCHAR szPath[MAX_PATH] = { TEXT('\0') };
|
||||
IStorage* pStg = NULL;
|
||||
IStorage* pFileStg = NULL;
|
||||
|
||||
_ASSERTE(pRootStorage);
|
||||
_ASSERTE(pszName);
|
||||
|
||||
hr = pRootStorage->OpenStorage(
|
||||
pszName,
|
||||
NULL,
|
||||
STGM_READ | STGM_SHARE_EXCLUSIVE,
|
||||
NULL,
|
||||
0,
|
||||
&pStg);
|
||||
if (SUCCEEDED(hr) && pStg)
|
||||
{
|
||||
if (!MakePath(szPath, MAX_PATH, pszDir, CW2T(pszName), pszExt))
|
||||
{
|
||||
hr = E_INVALIDARG;
|
||||
}
|
||||
else
|
||||
{
|
||||
_tprintf(TEXT("%s\n"), szPath);
|
||||
|
||||
// Create the storage file.
|
||||
hr = StgCreateDocfile(
|
||||
CT2W(szPath),
|
||||
STGM_WRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE,
|
||||
0,
|
||||
&pFileStg);
|
||||
if (SUCCEEDED(hr) && pFileStg)
|
||||
{
|
||||
hr = pStg->CopyTo(0, NULL, NULL, pFileStg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SAFE_RELEASE(pFileStg);
|
||||
SAFE_RELEASE(pStg);
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
error(TEXT("Error: failed to save storage '%s'.\n"), CW2T(pszName));
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
// Saves the stream from the given record to a file with or without
|
||||
// an extension based on whether or not fIncludeExt is set to TRUE.
|
||||
UINT SaveStream(MSIHANDLE hRecord, [Pre(Null=Maybe)] LPCTSTR pszDir, BOOL fIncludeExt)
|
||||
{
|
||||
UINT uiError = NOERROR;
|
||||
TCHAR szPath[MAX_PATH];
|
||||
LPTSTR pszName = NULL;
|
||||
DWORD cchName = 0;
|
||||
CHAR szBuffer[256];
|
||||
DWORD cbBuffer = sizeof(szBuffer);
|
||||
std::ofstream file;
|
||||
|
||||
try
|
||||
{
|
||||
// Get the name of the stream but skip if \005SummaryInformation stream.
|
||||
if (ERROR_SUCCESS == GetString(hRecord, 1, &pszName, &cchName) &&
|
||||
0 != _tcsncmp(pszName, TEXT("\005"), 1))
|
||||
{
|
||||
// Create the local file with the simple CFile write-only class.
|
||||
do
|
||||
{
|
||||
uiError = MsiRecordReadStream(hRecord, 2, szBuffer, &cbBuffer);
|
||||
if (ERROR_SUCCESS == uiError)
|
||||
{
|
||||
if (!file.is_open())
|
||||
{
|
||||
// Create the file path if the file is not created and assume the extension
|
||||
// if requested by fIncludeExt.
|
||||
if (!MakePathForData(szPath, MAX_PATH, pszDir, pszName, szBuffer, cbBuffer, fIncludeExt))
|
||||
{
|
||||
throw std::exception("Could not create the output path name");
|
||||
}
|
||||
|
||||
// Create the local file in which data is written.
|
||||
_tprintf(TEXT("%s\n"), szPath);
|
||||
file.open(CT2A(szPath), std::ios_base::binary);
|
||||
}
|
||||
|
||||
file.write(szBuffer, cbBuffer );
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::exception("Could not read from stream.");
|
||||
}
|
||||
} while (cbBuffer);
|
||||
}
|
||||
}
|
||||
catch (std::exception& ex)
|
||||
{
|
||||
error(TEXT("Error: %s\n"), CA2T(ex.what()));
|
||||
uiError = ERROR_CANNOT_MAKE;
|
||||
}
|
||||
|
||||
file.close();
|
||||
if (pszName)
|
||||
{
|
||||
delete [] pszName;
|
||||
pszName = NULL;
|
||||
}
|
||||
|
||||
return uiError;
|
||||
}
|
||||
|
||||
// Creates a patch for the given file using MakePath, but uses what of the
|
||||
// buffer it can to guess the file type and infer a common file extension.
|
||||
LPTSTR MakePathForData(LPTSTR pszDest, size_t cchDest, LPCTSTR pszDir, LPCTSTR pszName,
|
||||
LPCVOID pBuffer, size_t cbBuffer, BOOL fIncludeExt)
|
||||
{
|
||||
LPTSTR pszExt = NULL;
|
||||
if (fIncludeExt)
|
||||
{
|
||||
// Cabinet (*.cab) files.
|
||||
if (0 == memcmp(pBuffer, "MSCF", 4))
|
||||
{
|
||||
pszExt = TEXT(".cab");
|
||||
}
|
||||
|
||||
// Executable files. Assumed to be .dll (more common).
|
||||
else if (0 == memcmp(pBuffer, "MZ", 2))
|
||||
{
|
||||
pszExt = TEXT(".dll");
|
||||
}
|
||||
|
||||
// Icon (*.ico) files. Only assumed because they're common.
|
||||
else if (0 == memcmp(pBuffer, "\0\0\1\0", 4))
|
||||
{
|
||||
pszExt = TEXT(".ico");
|
||||
}
|
||||
|
||||
// Bitmap (*.bmp) files.
|
||||
else if (0 == memcmp(pBuffer, "BM", 2))
|
||||
{
|
||||
pszExt = TEXT(".bmp");
|
||||
}
|
||||
|
||||
// GIF (*.gif) files.
|
||||
else if (0 == memcmp(pBuffer, "GIF", 3))
|
||||
{
|
||||
pszExt = TEXT(".gif");
|
||||
}
|
||||
|
||||
// PING (*.png) files.
|
||||
else if (0 == memcmp(pBuffer, "\x89PNG", 4))
|
||||
{
|
||||
pszExt = TEXT(".png");
|
||||
}
|
||||
|
||||
// TIFF (*.tif) files.
|
||||
else if (0 == memcmp(pBuffer, "II", 2))
|
||||
{
|
||||
pszExt = TEXT(".tif");
|
||||
}
|
||||
}
|
||||
|
||||
return MakePath(pszDest, cchDest, pszDir, pszName, pszExt);
|
||||
}
|
266
libexec/MsiX/MsiX.h
Normal file
266
libexec/MsiX/MsiX.h
Normal file
@ -0,0 +1,266 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
|
||||
#include <tchar.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <crtdbg.h>
|
||||
#include <windows.h>
|
||||
#include <objbase.h>
|
||||
#include <msiquery.h>
|
||||
#include <exception>
|
||||
#include <fstream>
|
||||
|
||||
#include <codeanalysis/sourceannotations.h>
|
||||
using namespace vc_attributes;
|
||||
|
||||
#define SAFE_RELEASE(ptr) if (ptr) { (ptr)->Release(); ptr = NULL; }
|
||||
#define COLOR_ERROR FOREGROUND_RED | FOREGROUND_INTENSITY
|
||||
|
||||
void usage([Pre(Null=No)] LPCTSTR pszPath, [Pre(Null=No)] FILE* out);
|
||||
void error([Pre(Null=No)] LPCTSTR pszFormat, ...);
|
||||
void win32_error(DWORD dwError);
|
||||
|
||||
typedef struct _ARGS
|
||||
{
|
||||
LPTSTR Path;
|
||||
LPTSTR Directory;
|
||||
BOOL IncludeExtension;
|
||||
} ARGS, *LPARGS;
|
||||
|
||||
DWORD ParseArguments(int argc, [Pre(Null=No)] _TCHAR* argv[], [Pre(Null=No)] LPARGS args);
|
||||
LPTSTR MakePath([Pre(Null=No)] LPTSTR pszDest, size_t cchDest, [Pre(Null=Maybe)] LPCTSTR pszDir,
|
||||
[Pre(Null=No)] LPCTSTR pszName, [Pre(Null=Maybe)] LPCTSTR pszExt);
|
||||
UINT GetString(MSIHANDLE hRecord, UINT iField,
|
||||
[Pre(Null=No)] LPTSTR* ppszProperty, [Pre(Null=No)] DWORD* pcchProperty);
|
||||
HRESULT SaveStorage([Pre(Null=No)] IStorage* pRootStorage, [Pre(Null=Maybe)] LPCTSTR pszDir,
|
||||
[Pre(Null=No)] PCWSTR pszName, [Pre(Null=Maybe)] LPCTSTR pszExt);
|
||||
UINT SaveStream(MSIHANDLE hRecord, [Pre(Null=Maybe)] LPCTSTR pszDir, BOOL fIncludeExt);
|
||||
LPTSTR MakePathForData([Pre(Null=No)] LPTSTR pszDest, size_t cchDest,
|
||||
[Pre(Null=Maybe)] LPCTSTR pszDir, [Pre(Null=No)] LPCTSTR pszName,
|
||||
[Pre(Null=No)] LPCVOID pBuffer, size_t cbBuffer, BOOL fIncludeExt);
|
||||
|
||||
BOOL IsPatch([Pre(Null=No)] IStorage* pStorage);
|
||||
EXTERN_C const CLSID CLSID_MsiPatch = {0xC1086, 0x0, 0x0, {0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x46}};
|
||||
|
||||
// Simple string conversion classes.
|
||||
class CW2W
|
||||
{
|
||||
public:
|
||||
|
||||
CW2W(LPCWSTR psz) throw(...) :
|
||||
m_psz(psz)
|
||||
{
|
||||
_ASSERTE(psz);
|
||||
}
|
||||
|
||||
CW2W(LPCWSTR psz, UINT nCodePage) throw(...) :
|
||||
m_psz(psz)
|
||||
{
|
||||
_ASSERTE(psz);
|
||||
(void)nCodePage;
|
||||
}
|
||||
|
||||
~CW2W() throw()
|
||||
{
|
||||
}
|
||||
|
||||
operator LPWSTR() const throw()
|
||||
{
|
||||
return const_cast<LPWSTR>(m_psz);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
LPCWSTR m_psz;
|
||||
|
||||
// Hide the copy constructor and assignment operator.
|
||||
CW2W( const CW2W& ) throw();
|
||||
CW2W& operator=( const CW2W& ) throw();
|
||||
};
|
||||
|
||||
class CW2A
|
||||
{
|
||||
public:
|
||||
|
||||
CW2A(LPCWSTR psz) throw(...) :
|
||||
m_psz(NULL)
|
||||
{
|
||||
_ASSERTE(psz);
|
||||
Init(psz, CP_ACP);
|
||||
}
|
||||
|
||||
CW2A(LPCWSTR psz, UINT nCodePage) throw(...) :
|
||||
m_psz(NULL)
|
||||
{
|
||||
_ASSERTE(psz);
|
||||
Init(psz, nCodePage);
|
||||
}
|
||||
|
||||
~CW2A() throw()
|
||||
{
|
||||
if (m_psz)
|
||||
{
|
||||
delete [] m_psz;
|
||||
m_psz = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
operator LPSTR() const throw()
|
||||
{
|
||||
return m_psz;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
LPSTR m_psz;
|
||||
|
||||
void Init(LPCWSTR psz, UINT nCodePage) throw(...)
|
||||
{
|
||||
int iErr = NOERROR;
|
||||
int cch = 0;
|
||||
|
||||
cch = WideCharToMultiByte(nCodePage, 0, psz, -1, NULL, 0, NULL, NULL);
|
||||
if (cch)
|
||||
{
|
||||
// cch includes the NULL terminator character.
|
||||
m_psz = new CHAR[cch]; // Throws if no memory.
|
||||
if (!WideCharToMultiByte(nCodePage, 0, psz, -1, m_psz, cch, NULL, NULL))
|
||||
{
|
||||
iErr = (int)GetLastError();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
iErr = (int)GetLastError();
|
||||
}
|
||||
|
||||
if (ERROR_SUCCESS != iErr)
|
||||
{
|
||||
throw iErr;
|
||||
}
|
||||
}
|
||||
|
||||
// Hide the copy constructor and assignment operator.
|
||||
CW2A( const CW2A& ) throw();
|
||||
CW2A& operator=( const CW2A& ) throw();
|
||||
};
|
||||
|
||||
class CA2W
|
||||
{
|
||||
public:
|
||||
|
||||
CA2W(LPCSTR psz) throw(...) :
|
||||
m_psz(NULL)
|
||||
{
|
||||
_ASSERTE(psz);
|
||||
Init(psz, CP_ACP);
|
||||
}
|
||||
|
||||
CA2W(LPCSTR psz, UINT nCodePage) throw(...) :
|
||||
m_psz(NULL)
|
||||
{
|
||||
_ASSERTE(psz);
|
||||
Init(psz, nCodePage);
|
||||
}
|
||||
|
||||
~CA2W() throw()
|
||||
{
|
||||
if (m_psz)
|
||||
{
|
||||
delete [] m_psz;
|
||||
m_psz = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
operator LPWSTR() const throw()
|
||||
{
|
||||
return m_psz;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
LPWSTR m_psz;
|
||||
|
||||
void Init(LPCSTR psz, UINT nCodePage) throw(...)
|
||||
{
|
||||
int iErr = NOERROR;
|
||||
int cch = 0;
|
||||
|
||||
cch = MultiByteToWideChar(nCodePage, MB_PRECOMPOSED, psz, -1, NULL, 0);
|
||||
if (cch)
|
||||
{
|
||||
// cch includes the NULL terminator character.
|
||||
m_psz = new WCHAR[cch]; // Throws if no memory.
|
||||
if (!MultiByteToWideChar(nCodePage, MB_PRECOMPOSED, psz, -1, m_psz, cch))
|
||||
{
|
||||
iErr = (int)GetLastError();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
iErr = (int)GetLastError();
|
||||
}
|
||||
|
||||
if (ERROR_SUCCESS != iErr)
|
||||
{
|
||||
throw iErr;
|
||||
}
|
||||
}
|
||||
|
||||
// Hide the copy constructor and assignment operator.
|
||||
CA2W( const CA2W& ) throw();
|
||||
CA2W& operator=( const CA2W& ) throw();
|
||||
};
|
||||
|
||||
class CA2A
|
||||
{
|
||||
public:
|
||||
|
||||
CA2A(LPCSTR psz) throw(...) :
|
||||
m_psz(psz)
|
||||
{
|
||||
_ASSERTE(psz);
|
||||
}
|
||||
|
||||
CA2A(LPCSTR psz, UINT nCodePage) throw(...) :
|
||||
m_psz(psz)
|
||||
{
|
||||
_ASSERTE(psz);
|
||||
(void)nCodePage;
|
||||
}
|
||||
|
||||
~CA2A() throw()
|
||||
{
|
||||
}
|
||||
|
||||
operator LPSTR() const throw()
|
||||
{
|
||||
return const_cast<LPSTR>(m_psz);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
LPCSTR m_psz;
|
||||
|
||||
// Hide the copy constructor and assignment operator.
|
||||
CA2A( const CA2A& ) throw();
|
||||
CA2A& operator=( const CA2A& ) throw();
|
||||
};
|
||||
|
||||
// Declare macros for proper conversion
|
||||
// based on whether UNICODE being defined.
|
||||
#ifdef UNICODE
|
||||
#define CT2W CW2W
|
||||
#define CT2A CW2A
|
||||
#define CW2T CW2W
|
||||
#define CA2T CA2W
|
||||
#else
|
||||
#define CT2W CA2W
|
||||
#define CT2A CA2A
|
||||
#define CW2T CW2A
|
||||
#define CA2T CA2A
|
||||
#endif // UNICODE
|
BIN
libexec/MsiX/MsiX.pdb
Normal file
BIN
libexec/MsiX/MsiX.pdb
Normal file
Binary file not shown.
103
libexec/MsiX/MsiX.rc
Normal file
103
libexec/MsiX/MsiX.rc
Normal file
@ -0,0 +1,103 @@
|
||||
// Microsoft Visual C++ generated resource script.
|
||||
//
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "afxres.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (U.S.) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#include ""afxres.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,0,0,0
|
||||
PRODUCTVERSION 1,0,0,0
|
||||
FILEFLAGSMASK 0x17L
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x4L
|
||||
FILETYPE 0x1L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "Comments", "Extracts transforms and streams from Windows Installer files."
|
||||
VALUE "CompanyName", "Microsoft Corporation"
|
||||
VALUE "FileDescription", "MSI Extractor"
|
||||
VALUE "FileVersion", "1, 0, 0, 0"
|
||||
VALUE "InternalName", "MsiX"
|
||||
VALUE "LegalCopyright", "Copyright (C) Microsoft Corporation"
|
||||
VALUE "OriginalFilename", "MsiX.exe"
|
||||
VALUE "ProductName", "MSI Extractor"
|
||||
VALUE "ProductVersion", "1, 0, 0, 0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
|
||||
#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
211
libexec/MsiX/MsiX.vcproj
Normal file
211
libexec/MsiX/MsiX.vcproj
Normal file
@ -0,0 +1,211 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="MsiX"
|
||||
ProjectGUID="{CC64C520-EFC5-4947-B7FC-B50C54D9D734}"
|
||||
RootNamespace="MsiX"
|
||||
Keyword="Win32Proj"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
EmbedManifest="false"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="1"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||
RuntimeLibrary="0"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
EmbedManifest="false"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\MsiX.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\MsiX.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\resource.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\MsiX.rc"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
14
libexec/MsiX/resource.h
Normal file
14
libexec/MsiX/resource.h
Normal file
@ -0,0 +1,14 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by MsiX.rc
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 101
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1001
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
0
libexec/ShowVer.exe
Normal file → Executable file
0
libexec/ShowVer.exe
Normal file → Executable file
0
libexec/UnRAR.exe
Normal file → Executable file
0
libexec/UnRAR.exe
Normal file → Executable file
BIN
libexec/infozip/funzip.exe
Normal file
BIN
libexec/infozip/funzip.exe
Normal file
Binary file not shown.
BIN
libexec/infozip/unzip.exe
Normal file
BIN
libexec/infozip/unzip.exe
Normal file
Binary file not shown.
BIN
libexec/infozip/unzipsfx.exe
Normal file
BIN
libexec/infozip/unzipsfx.exe
Normal file
Binary file not shown.
BIN
libexec/infozip/zip.exe
Normal file
BIN
libexec/infozip/zip.exe
Normal file
Binary file not shown.
BIN
libexec/infozip/zipcloak.exe
Normal file
BIN
libexec/infozip/zipcloak.exe
Normal file
Binary file not shown.
BIN
libexec/infozip/zipnote.exe
Normal file
BIN
libexec/infozip/zipnote.exe
Normal file
Binary file not shown.
BIN
libexec/infozip/zipsplit.exe
Normal file
BIN
libexec/infozip/zipsplit.exe
Normal file
Binary file not shown.
0
libexec/inifile.exe
Normal file → Executable file
0
libexec/inifile.exe
Normal file → Executable file
0
libexec/innounp.exe
Normal file → Executable file
0
libexec/innounp.exe
Normal file → Executable file
Loading…
Reference in New Issue
Block a user