1159 lines
34 KiB
Batchfile
1159 lines
34 KiB
Batchfile
@echo off
|
|
REM ------------------------------------------------------------------
|
|
REM
|
|
REM removerc.cmd
|
|
REM Move resource from US binaries to MUI resource binaries
|
|
REM Read $nttree\\build_logs\\LgNeutral\\lgntobuildlist.txt which generated by lgndata.cmd
|
|
REM
|
|
REM Copyright (c) Microsoft Corporation. All rights reserved.
|
|
REM
|
|
REM ------------------------------------------------------------------
|
|
perl -x "%~f0" %*
|
|
goto :EOF
|
|
#!perl
|
|
use strict;
|
|
use File::Basename;
|
|
use IO::File;
|
|
|
|
use lib $ENV{RAZZLETOOLPATH} . "\\PostBuildScripts";
|
|
use lib $ENV{RAZZLETOOLPATH};
|
|
use PbuildEnv;
|
|
use ParseArgs;
|
|
use Logmsg;
|
|
use cksku;
|
|
|
|
|
|
BEGIN {
|
|
$ENV{SCRIPT_NAME} = 'removerc.cmd';
|
|
}
|
|
|
|
sub Usage { print<<USAGE; exit(1) }
|
|
removerc
|
|
Move resource from US binaries to MUI resource binaries.
|
|
If CMF is enabled, add MUI resource to CMF.
|
|
Read nttree\\build_logs\\LgNeutral\\lgntobuildlist.txt which generated by lgndata.cmd
|
|
|
|
USAGE
|
|
|
|
# Global variables
|
|
|
|
my(@FILE_LIST);
|
|
|
|
my ( $Neutral_LogDir, $LGNToBuildList);
|
|
my( $LogFilename, $TempDir, $Rsrc_Temp );
|
|
my( $CodeBinDir, $OrigBinDir, $RCBinDir, $CMFBinDir, $CodeBinPath, $OrigBinPath, $RCBinPath, $RenamedRCBinPath,$CMFBinPath, $CMFFilePath);
|
|
my( $nttree, $razpath, $TempDir);
|
|
my ($LGNStatus);
|
|
my ($STS_Freshs, $STS_OK, $STS_ToBuildList, $STS_BuildList, $STS_Copy, $STS_RemoveRC, $STS_Unknown);
|
|
my($lang, $fNeedGenerateCMF, %RenameTable);
|
|
my(%CDDataSKUs, %INFPathSKUs);
|
|
|
|
##################
|
|
#
|
|
# parse command line
|
|
#
|
|
##################
|
|
parseargs( '?' => \&Usage,
|
|
'l:' => \$lang
|
|
);
|
|
&Main();
|
|
|
|
|
|
#
|
|
# Check if Language Neutral is enabled or not
|
|
#
|
|
sub IsLGNActivated()
|
|
{
|
|
my ($MUI_MAGIC, $Result);
|
|
|
|
$Result = 0;
|
|
|
|
$MUI_MAGIC= $ENV{ "MUI_MAGIC" };
|
|
|
|
if ( defined($MUI_MAGIC))
|
|
{
|
|
$Result=1;
|
|
}
|
|
return $Result
|
|
|
|
}
|
|
#
|
|
# Check if we need generate CMF (Compact Resource File)
|
|
#
|
|
sub IsCMFActivated()
|
|
{
|
|
my ($MUI_MAGIC_CMF, $Result);
|
|
|
|
$Result = 0;
|
|
|
|
$MUI_MAGIC_CMF= $ENV{ "MUI_MAGIC_CMF" };
|
|
|
|
if ( defined($MUI_MAGIC_CMF))
|
|
{
|
|
$Result=1;
|
|
}
|
|
return $Result
|
|
}
|
|
sub Main {
|
|
# /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
|
|
# Begin Main code section
|
|
# /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
|
|
# Return when you want to exit on error
|
|
#
|
|
my ($Mylang );
|
|
if (! &IsLGNActivated())
|
|
{
|
|
return 0;
|
|
}
|
|
#
|
|
# $lang must be set. Default is usa
|
|
#
|
|
if ( ! defined($lang))
|
|
{
|
|
$lang = $ENV{LANG};
|
|
if (! defined($lang))
|
|
{
|
|
$lang="usa";
|
|
}
|
|
}
|
|
$Mylang="\L$lang";
|
|
if ( $Mylang ne "usa")
|
|
{
|
|
return 0;
|
|
}
|
|
#
|
|
# Should we generate CMF (Compact resource file ?)
|
|
#
|
|
$fNeedGenerateCMF=&IsCMFActivated();
|
|
|
|
$Logmsg::DEBUG = 0; # set to 1 to activate logging of dbgmsg's
|
|
$LogFilename = $ENV{ "LOGFILE" };
|
|
if ( ! defined( $LogFilename ) )
|
|
{
|
|
$TempDir = $ENV{ "TMP" };
|
|
$LogFilename = "$TempDir\\$0.log";
|
|
}
|
|
|
|
$CodeBinDir=$ENV{ "CodeBinDir" };
|
|
if ( ! defined( $CodeBinDir) )
|
|
{
|
|
$CodeBinDir="CodeBin";
|
|
}
|
|
$RCBinDir=$ENV{ "RcBinDir" };
|
|
if ( ! defined( $RCBinDir) )
|
|
{
|
|
$RCBinDir="RCBin";
|
|
}
|
|
$OrigBinDir=$ENV{ "OrigBinDir" };
|
|
if ( ! defined( $OrigBinDir) )
|
|
{
|
|
$OrigBinDir="OrigBin";
|
|
}
|
|
$CMFBinDir=$ENV{ "CMFBinDir" };
|
|
if ( ! defined( $CMFBinDir) )
|
|
{
|
|
$CMFBinDir="CMFBin";
|
|
}
|
|
timemsg( "Beginning ...");
|
|
|
|
|
|
# set up paths to important files
|
|
$nttree = $ENV{ "_NTPostBld" };
|
|
$razpath= $ENV{ "RazzleToolPath" };
|
|
$TempDir = $ENV{ "TMP" };
|
|
$Rsrc_Temp="$TempDir\\Rsrc_temp";
|
|
|
|
$Neutral_LogDir = $nttree."\\build_logs\\LgNeutral";
|
|
$LGNToBuildList = $Neutral_LogDir."\\lgntobuildlist.txt";
|
|
$LGNStatus = $Neutral_LogDir."\\lgnStatusLock.txt";
|
|
$OrigBinPath = "$Neutral_LogDir\\$OrigBinDir";
|
|
$CodeBinPath="$Neutral_LogDir\\$CodeBinDir";
|
|
$RCBinPath ="$Neutral_LogDir\\$RCBinDir";
|
|
$RenamedRCBinPath="$Neutral_LogDir\\RenamedRCBin";
|
|
$CMFBinPath ="$Neutral_LogDir\\$CMFBinDir";
|
|
$CMFFilePath= "$CMFBinPath\\CompMUI.CMF";
|
|
$STS_Freshs = "Fresh";
|
|
$STS_OK = "OK";
|
|
$STS_ToBuildList="ToBuildList";
|
|
$STS_RemoveRC="RemoveRC";
|
|
$STS_BuildList="BuildList";
|
|
$STS_Copy="CopyBin";
|
|
$STS_Unknown="Unknown";
|
|
|
|
# Create three BIN folder if they do not exist
|
|
|
|
# Home for LGN
|
|
if (! -d $Neutral_LogDir )
|
|
{
|
|
errmsg("Fatal: $Neutral_LogDir doesn't exist");
|
|
exit(1);
|
|
}
|
|
# Origional Binary
|
|
if (! -d $OrigBinPath)
|
|
{
|
|
if (system("md $OrigBinPath") != 0)
|
|
{
|
|
errmsg("Fatal: can't create $OrigBinPath");
|
|
exit(1);
|
|
}
|
|
}
|
|
# Binary with resource moved out
|
|
if (! -d $CodeBinPath)
|
|
{
|
|
if (system("md $CodeBinPath") != 0)
|
|
{
|
|
errmsg("Fatal: can't create CodeBinPath");
|
|
exit(1);
|
|
}
|
|
}
|
|
# Binary contains resource only
|
|
if (! -d $RCBinPath)
|
|
{
|
|
if (system("md $RCBinPath") != 0)
|
|
{
|
|
errmsg("Fatal: can't create $RCBinPath");
|
|
exit(1);
|
|
}
|
|
}
|
|
if ($fNeedGenerateCMF)
|
|
{
|
|
if (! -d $RenamedRCBinPath)
|
|
{
|
|
if (system("md $RenamedRCBinPath") != 0)
|
|
{
|
|
errmsg("Fatal: can't create $RenamedRCBinPath");
|
|
exit(1);
|
|
}
|
|
}
|
|
}
|
|
unless ( -d $CMFBinPath)
|
|
{
|
|
if (system("md $CMFBinPath") != 0)
|
|
{
|
|
errmsg("Fatal: can't create $CMFBinPath");
|
|
exit(1);
|
|
}
|
|
}
|
|
#
|
|
# ToBuildList should be created by lgndata.cmd.
|
|
# logndata.cmd will be called by pbuild with -g parameter to generate the said list
|
|
#
|
|
unless ( -e $LGNToBuildList)
|
|
{
|
|
logmsg(" No files to be processed because $LGNToBuildList doesn't exist");
|
|
exit(0);
|
|
}
|
|
|
|
#
|
|
# Put binaries be processed in array @FILE_LIST
|
|
#
|
|
if (!&MakeSourceFileList())
|
|
{
|
|
errmsg ("Could not get the filtered contents of the source directory.");
|
|
}
|
|
#
|
|
# If CMF is enabled, we have to create rename table because some mui files should be renamed before it added to CMF
|
|
#
|
|
if ($fNeedGenerateCMF)
|
|
{
|
|
BuildRename4CMF();
|
|
}
|
|
#
|
|
# Generate resource dlls from the files in the source file list
|
|
# call muirct.exe to process binaries listed in @FILE_LIST
|
|
#
|
|
if (!&GenLGNResDlls())
|
|
{
|
|
errmsg ("Error(s) occurs in moving resource out of binaries");
|
|
}
|
|
|
|
|
|
|
|
#
|
|
# Done
|
|
#
|
|
LogStatus($STS_RemoveRC);
|
|
timemsg( "Finished." );
|
|
|
|
# /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
|
|
# End Main code section
|
|
# /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
|
|
}
|
|
|
|
|
|
# /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
|
|
#
|
|
# MakeSourceFileListl - gets list of appropriate files to process from $LGNToBuildList
|
|
#
|
|
# /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
|
|
sub MakeSourceFileList
|
|
{
|
|
my (@Bufs, $Result, $Line);
|
|
|
|
$Result = 0;
|
|
|
|
unless ( open(INFILE, $LGNToBuildList))
|
|
{
|
|
errmsg("Fatal: Can't open $LGNToBuildList");
|
|
return $Result;
|
|
}
|
|
@Bufs=<INFILE>;
|
|
close(INFILE);
|
|
foreach $Line (@Bufs)
|
|
{
|
|
chomp($Line);
|
|
$Line =~ s/\s//g;
|
|
if (length($Line) == 0)
|
|
{
|
|
next;
|
|
}
|
|
push(@FILE_LIST, $Line);
|
|
}
|
|
$Result = 1;
|
|
return $Result;
|
|
}
|
|
|
|
# /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
|
|
#
|
|
# IsFusionResource --- Check if the binary contains fusion resource (#24)
|
|
#
|
|
# /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
|
|
sub IsFusionResource
|
|
{
|
|
my ($FileName) = @_;
|
|
|
|
my (@Rsrc_Record,@Qualified,$Num, $Result);
|
|
|
|
#logmsg("rsrc.exe $FileName >$Rsrc_Temp ");
|
|
|
|
$Result = 0;
|
|
|
|
#
|
|
# Call RSRC to check
|
|
#
|
|
system("rsrc.exe $FileName >$Rsrc_Temp 2>nul");
|
|
|
|
|
|
unless (open(RSRCFILE, $Rsrc_Temp))
|
|
{
|
|
errmsg("Can't open RSRC for $FileName");
|
|
return $Result;
|
|
}
|
|
@Rsrc_Record=<RSRCFILE>;
|
|
close (RSRCFILE);
|
|
#
|
|
# Scan the output of rsrc.exe.
|
|
#
|
|
@Qualified=grep /^\s{3}18/ , @Rsrc_Record;
|
|
$Num=scalar(@Qualified);
|
|
if ($Num > 0 )
|
|
{
|
|
$Result = 1;
|
|
}
|
|
return $Result;
|
|
}
|
|
|
|
# /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
|
|
#
|
|
# MakeSourceFileList_All - gets list of appropriate files to process from $nttree
|
|
# Not used in this moment.
|
|
#
|
|
# /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
|
|
|
|
sub MakeSourceFileListlAll
|
|
{
|
|
logmsg ("Get list of appropriate files to process.");
|
|
|
|
my(@files,$filename);
|
|
|
|
# Initial messages
|
|
logmsg ("--------------------------------------------------------");
|
|
logmsg ("Move resource out of US binaries to MUI resource binaries");
|
|
logmsg ("--------------------------------------------------------");
|
|
|
|
# Get contents of source directory
|
|
if(!opendir(LOCBINDIR, $nttree)) {
|
|
errmsg ("Can't open $nttree");
|
|
return 0;
|
|
}
|
|
# Skip files won't contain resource. We also skip drivers(*.drv *.sys) because MUI currently doesn't support it
|
|
|
|
@files = grep !/\.(gpd|icm|ppd|bmp|txt|cab|cat|hlp|chm|chq|cnt|mfl|drv|sys|gif|cur|fon|sf2|jpg|p4|nls|uce|wmz|ttf|mof)$/i, readdir LOCBINDIR;
|
|
close(LOCBINDIR);
|
|
|
|
#
|
|
# Filter out non-binaries, store in global @FILE_LIST
|
|
# (muirct.exe gives errors on text files, and produces annoying
|
|
#
|
|
@FILE_LIST = ();
|
|
foreach (@files)
|
|
{
|
|
chomp($_);
|
|
$_ =~ s/\s//g;
|
|
if (length($_) == 0)
|
|
{
|
|
next;
|
|
}
|
|
if(-B "$nttree\\$_")
|
|
{
|
|
push(@FILE_LIST, "$nttree\\$_");
|
|
}
|
|
}
|
|
|
|
logmsg ("Success: Get list of appropriate files to process.");
|
|
return 1;
|
|
}
|
|
|
|
# /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
|
|
#
|
|
# GenResDlls - loops over the file list, performs muirct.exe, and logs output
|
|
# Work around fusion issue ---- Resource type #24
|
|
#
|
|
# /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
|
|
sub GenLGNResDlls
|
|
{
|
|
logmsg ("Loop over the file list, perform muirct.exe , and log output");
|
|
my( $Line, $error, $resdlls_created, @resdlls, $total_resdlls);
|
|
my( $muirct_command, $source, $source_new, $mui_new);
|
|
my ($error,@trash, $Backup);
|
|
|
|
# Process each (binary) file in the source directory
|
|
$resdlls_created = 0;
|
|
|
|
foreach $Line (@FILE_LIST)
|
|
{
|
|
chomp($Line);
|
|
$Line =~ s/\s//g;
|
|
if (length($Line) == 0)
|
|
{
|
|
next;
|
|
}
|
|
$source = "$nttree\\$Line";
|
|
|
|
$source_new = "$CodeBinPath\\$Line";
|
|
$mui_new = "$RCBinPath\\$Line.mui";
|
|
|
|
logmsg("$muirct_command");
|
|
|
|
if (-e $source_new)
|
|
{
|
|
system("del $source_new");
|
|
}
|
|
if (-e $mui_new)
|
|
{
|
|
system("del $mui_new");
|
|
}
|
|
if (&IsFusionResource($source))
|
|
{
|
|
# Keep: Icon(3) version(16)
|
|
# stay: 24 TYPELIB REGINST
|
|
#$muirct_command = "muirct.exe -l 0x0409 -k 16 -y 3 12 13 14 15 -p 24 TYPELIB $source $source_new $mui_new";
|
|
$muirct_command = "muirct.exe -l 0x0409 -k 16 -c $source -o 4 5 6 9 10 11 16 REGINST HTML MOFDATA 23 240 1024 2110 $source $source_new $mui_new";
|
|
|
|
}
|
|
else
|
|
{
|
|
#$muirct_command = "muirct.exe -l 0x0409 -k 16 -y 3 12 13 14 15 -p TYPELIB $source $source_new $mui_new";
|
|
$muirct_command = "muirct.exe -l 0x0409 -k 16 -c $source -o 4 5 6 9 10 11 16 REGINST HTML MOFDATA 23 240 1024 2110 $source $source_new $mui_new";
|
|
}
|
|
@trash=`$muirct_command`;
|
|
if ( ! -e $mui_new)
|
|
{
|
|
if ( -e $source_new)
|
|
{
|
|
system("del $source_new");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( ! -e $source_new)
|
|
{
|
|
if ( -e $mui_new)
|
|
{
|
|
system("del $mui_new");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
$resdlls_created++;
|
|
$Backup="$OrigBinPath\\$Line";
|
|
#
|
|
# Backup origional binary to $OrigBinPath
|
|
#
|
|
system("copy/y $source $Backup");
|
|
#
|
|
# ADD this mui file to CMF file if CMF is enabled
|
|
#
|
|
if ($fNeedGenerateCMF)
|
|
{
|
|
AddtoCMF($resdlls_created,$Line);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
# Final messages
|
|
logmsg ("RESULTS: muirct: Process Succeeded");
|
|
logmsg ("Number of resource-only dlls created in:...........($resdlls_created)");
|
|
return 1;
|
|
}
|
|
|
|
# /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
|
|
#
|
|
# GenResDlls_ALL - loops over the file list, performs muirct.exe, and logs output
|
|
# /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
|
|
sub GenResDlls_All
|
|
{
|
|
logmsg ("Loop over the file list, perform muirct.exe , and log output");
|
|
my( $error, $resdlls_created, @resdlls, $total_resdlls);
|
|
my( $muirct_command, $source, $source_new, $mui_new);
|
|
my ($error,@trash);
|
|
|
|
# Process each (binary) file in the source directory
|
|
$resdlls_created = 0;
|
|
foreach $_ (@FILE_LIST)
|
|
{
|
|
|
|
$_ =~ s/\s//g;
|
|
if (length($_) == 0)
|
|
{
|
|
next;
|
|
}
|
|
|
|
$source = $_;
|
|
|
|
if ($_ =~ /\Q$nttree\E\\(.*)/)
|
|
{
|
|
$source_new = "$CodeBinPath\\$1";
|
|
$mui_new = "$RCBinPath\\$1.mui";
|
|
logmsg("$muirct_command");
|
|
|
|
$muirct_command = "muirct.exe -l 0x0409 -k 16 $source $source_new $mui_new";
|
|
|
|
@trash = `$muirct_command`;
|
|
$error = $?/256;
|
|
|
|
if(!$error)
|
|
{
|
|
$resdlls_created++;
|
|
}
|
|
}
|
|
}
|
|
|
|
# Get total number of resource-only dlls in destination directory
|
|
if(!opendir(TARGETDIR, $RCBinPath))
|
|
{
|
|
wrnmsg ("WARNING: Can't open $RCBinPath");
|
|
}
|
|
|
|
@resdlls = grep /\.mui$/, readdir TARGETDIR;
|
|
close(TARGETDIR);
|
|
$total_resdlls = scalar(@resdlls);
|
|
|
|
# Final messages
|
|
logmsg ("RESULTS: Process Succeeded");
|
|
logmsg ("Number of resource-only dlls created in:...........($resdlls_created)");
|
|
logmsg (" $RCBinPath");
|
|
logmsg ("Total number of resource-only dlls in:.............($total_resdlls)");
|
|
logmsg (" $RCBinPath");
|
|
return 1;
|
|
}
|
|
#
|
|
# Log the state of LGN processing so it can be restart anytime correctly
|
|
#
|
|
sub LogStatus
|
|
{
|
|
my ($TheStatus) = @_;
|
|
my ($Result);
|
|
|
|
$Result = 0;
|
|
|
|
unless (open(OUTFILE, ">$LGNStatus"))
|
|
{
|
|
errmsg("Fatal: can't create status file $LGNStatus");
|
|
return $Result;
|
|
}
|
|
print (OUTFILE "$TheStatus\n");
|
|
close(OUTFILE);
|
|
$Result = 1;
|
|
return $Result;
|
|
|
|
}
|
|
|
|
#
|
|
# Add one MUI resource file to CMF.
|
|
#
|
|
sub AddtoCMF
|
|
{
|
|
my ($Counter,$BinaryName) = @_;
|
|
|
|
my ($MUIPath, $muirct_command, $muirct_command0, @trash, $IsRenamed, @Renamed);
|
|
my ($Number, $Idx, $MUINewPath, $NewName,$CreateIt, $Result,$CodePath, $CodeNewPath);
|
|
|
|
$Result=0;
|
|
|
|
if ( defined($RenameTable{$BinaryName}))
|
|
{
|
|
$IsRenamed=1;
|
|
@Renamed=@{$RenameTable{$BinaryName}};
|
|
}
|
|
else
|
|
{
|
|
$IsRenamed=0;
|
|
}
|
|
logmsg("**** Counter : $Counter");
|
|
|
|
if ($Counter <= 1)
|
|
{
|
|
if ( -e $CMFFilePath)
|
|
{
|
|
system("del $CMFFilePath");
|
|
}
|
|
$muirct_command0 ="muirct.exe -m ";
|
|
$CreateIt=0;
|
|
}
|
|
else
|
|
{
|
|
$muirct_command0="muirct.exe -a ";
|
|
}
|
|
if (! $IsRenamed)
|
|
{
|
|
$MUIPath="$RCBinPath\\$BinaryName.mui";
|
|
$muirct_command=$muirct_command0."$MUIPath -f $CMFFilePath -e $CodeBinPath";
|
|
#@trash = `$muirct_command`;
|
|
`$muirct_command`;
|
|
logmsg("$muirct_command");
|
|
}
|
|
else
|
|
{
|
|
$Number=scalar(@Renamed);
|
|
for ($Idx=0; $Idx < $Number; $Idx++)
|
|
{
|
|
$NewName=$Renamed[$Idx];
|
|
$MUIPath="$RCBinPath\\$BinaryName.mui";
|
|
$MUINewPath="$RenamedRCBinPath\\$NewName.mui";
|
|
$CodePath="$CodeBinPath\\$BinaryName";
|
|
$CodeNewPath="$RenamedRCBinPath\\$NewName";
|
|
if (system("copy $MUIPath $MUINewPath") != 0)
|
|
{
|
|
errmsg("Can't copy renamed file: $MUINewPath");
|
|
return $Result;
|
|
}
|
|
if (system("copy $CodePath $CodeNewPath") != 0)
|
|
{
|
|
errmsg("Can't copy renamed file: $CodeNewPath");
|
|
return $Result;
|
|
}
|
|
$muirct_command=$muirct_command0."$MUINewPath -f $CMFFilePath -e $RenamedRCBinPath";
|
|
#@trash = `$muirct_command`;
|
|
`$muirct_command`;
|
|
logmsg("$muirct_command");
|
|
if (system("copy $CodeNewPath $CodePath") != 0)
|
|
{
|
|
errmsg("Can't copy back renamed file: $CodeNewPath");
|
|
return $Result;
|
|
}
|
|
if ( ($Counter <= 1) && ($CreateIt == 0))
|
|
{
|
|
$CreateIt=1;
|
|
$muirct_command0="muirct.exe -a ";
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
$Result=1;
|
|
|
|
return $Result;
|
|
}
|
|
#
|
|
# Build a rename table for those files will be renamed during setup
|
|
# for CMF, we have to check if a file will be renamed. If it's the case, we'll build the renamed one into CMF
|
|
#
|
|
sub BuildRename4CMF
|
|
{
|
|
my ($Sku, $Result);
|
|
|
|
my ($Path_Dosnet, $Path_Txtsetup, $Path_Layout, $Path_Dir);
|
|
my ($Path_Dosnet_sign, $Path_Txtsetup_sign, $Path_Layout_sign, $Path_Dir_sign);
|
|
|
|
$Result=0;
|
|
|
|
&BuildArray();
|
|
|
|
|
|
foreach $Sku ( keys(%CDDataSKUs))
|
|
{
|
|
# SKU populated ?
|
|
if ($CDDataSKUs{$Sku})
|
|
{
|
|
if ( !defined($INFPathSKUs{$Sku} ))
|
|
{
|
|
errmag("Fatal: $Sku has no corr. entry in INFPathSKUs");
|
|
return $Result;
|
|
}
|
|
#
|
|
# Read the INFs path for the SKU
|
|
#
|
|
($Path_Dosnet,$Path_Txtsetup,$Path_Layout,$Path_Dir, $Path_Dosnet_sign,$Path_Txtsetup_sign,$Path_Layout_sign,$Path_Dir_sign)=@{$INFPathSKUs{$Sku}};
|
|
#
|
|
# Rename information stored in the layout.inf
|
|
#
|
|
BuildRenameTableFromLayout($Path_Layout);
|
|
}
|
|
}
|
|
$Result=1;
|
|
|
|
return $Result;
|
|
}
|
|
|
|
#
|
|
# Build Up Rename Table
|
|
#
|
|
sub BuildRenameTableFromLayout
|
|
{
|
|
my ($FilePath) = @_;
|
|
|
|
my (@Items, @ItemsInSection, $Section, $Result, $nStart, $nEnd, $nStartTag1, $nStartTag2,$nStartDirs,$nEndDirs);
|
|
my ($nStart_Dir,$nEnd_Dir);
|
|
my ($ReplaceDirs, $Replace, $Line, $Entry);
|
|
my (@AddedItems, $FileName, $Path, $Idx, $Item_no);
|
|
my ($FileRenamed, $nUppbound);
|
|
my ($NoAlt, $BldArch, $AltSection,$nAltStart,$nAltEnd);
|
|
my ($LGNTagStart, $LGNTagEnd, $LGNDirs);
|
|
|
|
$Result = 0;
|
|
|
|
unless ( open(INFILE, $FilePath) )
|
|
{
|
|
errmsg ("Can't open $FilePath");
|
|
return $Result;
|
|
}
|
|
# Read into @Items
|
|
@Items=<INFILE>;
|
|
close(INFILE);
|
|
|
|
$LGNTagStart = "; Following are entries added for Language neutral resource files:\$\$\$ ";
|
|
$LGNTagEnd = "; End of entries for Language neutral resource files: \$\$\$";
|
|
$LGNDirs = "190 = mui\\fallback\\0409";
|
|
|
|
#
|
|
# First, we have to read [WinntDirectories] section to see if '190 = mui\fallback\0409' is there
|
|
#
|
|
$Section="WinntDirectories";
|
|
$nStartDirs=0;
|
|
$nEndDirs=0;
|
|
#
|
|
# Read [WinntDirectories] Section, position in nStart, nEnd
|
|
#
|
|
if (!ReadSection($Section,\@Items, \@ItemsInSection, \$nStart_Dir, \$nEnd_Dir, \$nStartDirs, \$nEndDirs,
|
|
$LGNDirs,"Nothing"))
|
|
{
|
|
errmsg("Fatal: Can't find $Section in $FilePath");
|
|
return $Result;
|
|
}
|
|
|
|
$Section="SourceDisksFiles";
|
|
$nStartTag1=0;
|
|
$nStartTag2=0;
|
|
#
|
|
# Read [SourceDisksFiles] Section, position in nStart, nEnd
|
|
#
|
|
if (!ReadSection($Section,\@Items, \@ItemsInSection, \$nStart, \$nEnd, \$nStartTag1, \$nStartTag2,
|
|
$LGNTagStart,$LGNTagEnd))
|
|
{
|
|
errmsg("Fatal: Can't find $Section in $FilePath");
|
|
return $Result;
|
|
}
|
|
#
|
|
# Read [SourceDisksFiles.<BldArch>] Section. This section contains platform specific files
|
|
#
|
|
my ($NoAlt, $BldArch, $AltSection);
|
|
$NoAlt=0;
|
|
$BldArch = $ENV{ "\_BuildArch" };
|
|
if ( $BldArch =~ /x86/i )
|
|
{
|
|
$AltSection= "$Section.x86";
|
|
}
|
|
elsif ( $BldArch =~ /amd64/i)
|
|
{
|
|
$AltSection= "$Section.amd64";
|
|
}
|
|
elsif ( $BldArch =~ /ia64/i )
|
|
{
|
|
$AltSection= "$Section.ia64";
|
|
}
|
|
else
|
|
{
|
|
$AltSection= "$Section.x86";
|
|
}
|
|
if (!ReadSection($AltSection,\@Items, \@ItemsInSection, \$nAltStart, \$nAltEnd, \$nStartTag1, \$nStartTag2,
|
|
$LGNTagStart,$LGNTagEnd))
|
|
{
|
|
errmsg(" Can't find $AltSection in $FilePath");
|
|
$NoAlt=1;
|
|
}
|
|
#
|
|
# Search Tag here
|
|
#
|
|
$nStartDirs=-1;
|
|
$nEndDirs=-1;
|
|
$nStartTag1=-1;
|
|
$nStartTag2=-1;
|
|
$ReplaceDirs="FALSE";
|
|
$Replace="FALSE";
|
|
$Idx=-1;
|
|
foreach (@Items)
|
|
{
|
|
chomp($_);
|
|
$Idx++;
|
|
# Find $LGNDirs, position in nStartDirs
|
|
if ( $_ eq $LGNDirs)
|
|
{
|
|
$nStartDirs = $Idx;
|
|
}
|
|
# Find$ LGN tag, position in nStartTag1, nStartTag2
|
|
if ( $_ eq $LGNTagStart)
|
|
{
|
|
$nStartTag1 = $Idx;
|
|
}
|
|
if ( $_ eq $LGNTagEnd)
|
|
{
|
|
$nStartTag2 = $Idx;
|
|
}
|
|
}
|
|
if ($nStartDirs != -1)
|
|
{
|
|
$ReplaceDirs = "TRUE";
|
|
}
|
|
if ( ($nStartTag1 != -1) && ($nStartTag2 != -1))
|
|
{
|
|
$Replace = "TRUE";
|
|
}
|
|
|
|
#
|
|
# Build up rename table here !
|
|
# Windows sepcify the renaming in txtsetup.txt and layout.inf
|
|
#
|
|
%RenameTable={};
|
|
if ($Replace eq "TRUE")
|
|
{
|
|
$nUppbound = $nStartTag1;
|
|
}
|
|
else
|
|
{
|
|
$nUppbound = $nEnd;
|
|
}
|
|
if (! &BuildRenameTable(\@Items,$nStart, $nUppbound,\%RenameTable))
|
|
{
|
|
errmsg("Can't build File Rename Table");
|
|
return $Result;
|
|
}
|
|
if ( ! $NoAlt )
|
|
{
|
|
if (! &BuildRenameTable(\@Items,$nAltStart, $nAltEnd,\%RenameTable))
|
|
{
|
|
errmsg("Can't build File Rename Table from $AltSection");
|
|
}
|
|
}
|
|
$Result=1;
|
|
|
|
return $Result;
|
|
|
|
}
|
|
#
|
|
# Search a Section of a INFs. INFs stored in @$pItemsList
|
|
#
|
|
|
|
sub ReadSection
|
|
{
|
|
|
|
my ($Section, $pItemsList, $pItemsInSection, $pnStart, $pnEnd, $pnStartTag1, $pnStartTag2, $Tag1,$Tag2) = @_;
|
|
my ($Index, $SectionStart, $SectionEnd, $Line, $Line_Org, $ReadFlag, $Result);
|
|
|
|
$ReadFlag = "FALSE";
|
|
$Index= -1;
|
|
$SectionStart = -1;
|
|
$SectionEnd = -1;
|
|
$Result = 0;
|
|
|
|
#
|
|
# Read The section
|
|
#
|
|
LINE: foreach $Line_Org (@$pItemsList)
|
|
{
|
|
$Line = $Line_Org;
|
|
chomp($Line);
|
|
$Index++;
|
|
if ( (length($Line) == 0) || (substr($Line,0,1) eq ";") || (substr($Line,0,1) eq "#") )
|
|
{
|
|
if ( $ReadFlag eq "TRUE" )
|
|
{
|
|
push (@$pItemsInSection, $Line_Org);
|
|
}
|
|
next;
|
|
}
|
|
if ( $Line =~ /^\[/ )
|
|
{
|
|
|
|
if ( $ReadFlag eq "TRUE")
|
|
{
|
|
$ReadFlag = "FALSE";
|
|
if ( $SectionStart != -1)
|
|
{
|
|
if ($SectionEnd == -1)
|
|
{
|
|
$SectionEnd = $Index-1;
|
|
}
|
|
}
|
|
last LINE;
|
|
}
|
|
|
|
}
|
|
if ( $Line =~ /^\[$Section\]/ ) # pattern in $Section !!!
|
|
{
|
|
$ReadFlag = "TRUE";
|
|
$SectionStart=$Index;
|
|
}
|
|
if ($ReadFlag eq "TRUE")
|
|
{
|
|
# Check if it's a LGN starting Tag
|
|
if ( $$pnStartTag1 != 0)
|
|
{
|
|
if ($Line eq $Tag1)
|
|
{
|
|
$$pnStartTag1 = $Index;
|
|
}
|
|
}
|
|
# Check if it's a LGN ending Tag
|
|
if ( $$pnStartTag2 != 0)
|
|
{
|
|
if ($Line eq $Tag2)
|
|
{
|
|
$$pnStartTag2 = $Index;
|
|
}
|
|
}
|
|
|
|
push(@$pItemsInSection, $Line_Org);
|
|
}
|
|
}
|
|
if ( $SectionStart != -1)
|
|
{
|
|
if ( $SectionEnd == -1)
|
|
{
|
|
$SectionEnd = $Index;
|
|
}
|
|
$Result = 1;
|
|
$$pnStart = $SectionStart;
|
|
$$pnEnd = $SectionEnd;
|
|
}
|
|
return $Result;
|
|
}
|
|
#
|
|
# Scan the entries of txtsetup.sif/layout.inf to find the files to be renamed
|
|
#
|
|
# If a file is renamed, then its associated mui file should be renamed also
|
|
#
|
|
sub BuildRenameTable
|
|
{
|
|
|
|
my ($pItems,$nStart, $nEnd,$pRenameTable)= @_;
|
|
my ($Line, $Trash, $Idx,$OldName,$NewName);
|
|
|
|
|
|
|
|
for ($Idx = $nStart; $Idx <= $nEnd; $Idx++)
|
|
{
|
|
|
|
$Line=$$pItems[$Idx];
|
|
chomp($Line);
|
|
|
|
if ( length($Line) == 0)
|
|
{
|
|
next;
|
|
}
|
|
if (substr($Line,0,1) eq ";")
|
|
{
|
|
next;
|
|
}
|
|
|
|
if ($Line =~ /=\s*[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,([^,]+)/ )
|
|
{
|
|
$NewName=$1;
|
|
($OldName,$Trash) = split ( /=+/, $Line);
|
|
$OldName =~ s/\s//g;
|
|
$NewName=~ s/\s//g;
|
|
if ( defined( $$pRenameTable{$OldName}))
|
|
{
|
|
push(@{ $$pRenameTable{$OldName}},$NewName);
|
|
}
|
|
else
|
|
{
|
|
$$pRenameTable{$OldName}=[($NewName)];
|
|
}
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
|
|
sub BuildArray
|
|
{
|
|
|
|
|
|
my ($BigDosnet, $PerDosnet, $BlaDosnet, $SbsDosnet, $SrvDosnet , $EntDosnet , $DtcDosnet);
|
|
my ($BigDosnet_sign, $PerDosnet_sign, $BlaDosnet_sign, $SbsDosnet_sign, $SrvDosnet_sign , $EntDosnet_sign , $DtcDosnet_sign);
|
|
|
|
my ($BigTxtsetup, $PerTxtsetup, $BlaTxtsetup, $SbsTxtsetup, $SrvTxtsetup, $EntTxtsetup, $DtcTxtsetup);
|
|
my ($BigTxtsetup_sign, $PerTxtsetup_sign, $BlaTxtsetup_sign, $SbsTxtsetup_sign, $SrvTxtsetup_sign, $EntTxtsetup_sign, $DtcTxtsetup_sign);
|
|
|
|
my ($BigLayout, $PerLayout, $BlaLayout, $SbsLayout, $SrvLayout , $EntLayout, $DtcLayout);
|
|
my ($BigLayout_sign, $PerLayout_sign, $BlaLayout_sign, $SbsLayout_sign, $SrvLayout_sign , $EntLayout_sign, $DtcLayout_sign);
|
|
|
|
my ($Path_Dosnet, $Path_Txtsetup, $Path_Layout, $Path_Dir);
|
|
my ($Path_Dosnet_sign, $Path_Txtsetup_sign, $Path_Layout_sign, $Path_Dir_sign);
|
|
|
|
#
|
|
# Get SKUs
|
|
#
|
|
%CDDataSKUs = map({uc$_ => cksku::CkSku($_, $lang, $ENV{_BuildArch})} qw(PRO PER SRV BLA SBS ADS DTC));
|
|
#
|
|
# Build Key INFs for SKUs
|
|
#
|
|
$BigDosnet = $nttree . "\\dosnet.inf";
|
|
$PerDosnet = $nttree . "\\perinf\\dosnet.inf";
|
|
$BlaDosnet = $nttree . "\\blainf\\dosnet.inf";
|
|
$SbsDosnet = $nttree . "\\sbsinf\\dosnet.inf";
|
|
$SrvDosnet = $nttree . "\\srvinf\\dosnet.inf";
|
|
$EntDosnet = $nttree . "\\entinf\\dosnet.inf";
|
|
$DtcDosnet = $nttree . "\\dtcinf\\dosnet.inf";
|
|
|
|
$BigTxtsetup = $nttree . "\\txtsetup.sif";
|
|
$PerTxtsetup = $nttree . "\\perinf\\txtsetup.sif";
|
|
$BlaTxtsetup = $nttree . "\\blainf\\txtsetup.sif";
|
|
$SbsTxtsetup = $nttree . "\\sbsinf\\txtsetup.sif";
|
|
$SrvTxtsetup = $nttree . "\\srvinf\\txtsetup.sif";
|
|
$EntTxtsetup = $nttree . "\\entinf\\txtsetup.sif";
|
|
$DtcTxtsetup = $nttree . "\\dtcinf\\txtsetup.sif";
|
|
|
|
|
|
$BigLayout = $nttree . "\\layout.inf";
|
|
$PerLayout = $nttree . "\\perinf\\layout.inf";
|
|
$BlaLayout = $nttree . "\\blainf\\layout.inf";
|
|
$SbsLayout = $nttree . "\\sbsinf\\layout.inf";
|
|
$SrvLayout = $nttree . "\\srvinf\\layout.inf";
|
|
$EntLayout = $nttree . "\\entinf\\layout.inf";
|
|
$DtcLayout = $nttree . "\\dtcinf\\layout.inf";
|
|
|
|
|
|
$BigDosnet_sign = $nttree . "\\realsign\\dosnet.inf";
|
|
$PerDosnet_sign = $nttree . "\\perinf\\realsign\\dosnet.inf";
|
|
$BlaDosnet_sign = $nttree . "\\blainf\\realsign\\dosnet.inf";
|
|
$SbsDosnet_sign = $nttree . "\\sbsinf\\realsign\\dosnet.inf";
|
|
$SrvDosnet_sign = $nttree . "\\srvinf\\realsign\\dosnet.inf";
|
|
$EntDosnet_sign = $nttree . "\\entinf\\realsign\\dosnet.inf";
|
|
$DtcDosnet_sign = $nttree . "\\dtcinf\\realsign\\dosnet.inf";
|
|
|
|
$BigTxtsetup_sign = $nttree . "\\realsign\\txtsetup.sif";
|
|
$PerTxtsetup_sign = $nttree . "\\perinf\\realsign\\txtsetup.sif";
|
|
$BlaTxtsetup_sign = $nttree . "\\blainf\\realsign\\txtsetup.sif";
|
|
$SbsTxtsetup_sign = $nttree . "\\sbsinf\\realsign\\txtsetup.sif";
|
|
$SrvTxtsetup_sign = $nttree . "\\srvinf\\realsign\\txtsetup.sif";
|
|
$EntTxtsetup_sign = $nttree . "\\entinf\\realsign\\txtsetup.sif";
|
|
$DtcTxtsetup_sign = $nttree . "\\dtcinf\\realsign\\txtsetup.sif";
|
|
|
|
|
|
$BigLayout_sign = $nttree . "\\realsign\\layout.inf";
|
|
$PerLayout_sign = $nttree . "\\perinf\\realsign\\layout.inf";
|
|
$BlaLayout_sign = $nttree . "\\blainf\\realsign\\layout.inf";
|
|
$SbsLayout_sign = $nttree . "\\sbsinf\\realsign\\layout.inf";
|
|
$SrvLayout_sign = $nttree . "\\srvinf\\realsign\\layout.inf";
|
|
$EntLayout_sign = $nttree . "\\entinf\\realsign\\layout.inf";
|
|
$DtcLayout_sign = $nttree . "\\dtcinf\\realsign\\layout.inf";
|
|
|
|
# PRO
|
|
$Path_Dosnet =$BigDosnet;
|
|
$Path_Txtsetup =$BigTxtsetup;
|
|
$Path_Layout =$BigLayout;
|
|
$Path_Dir ="ProInf";
|
|
$Path_Dosnet_sign =$BigDosnet_sign;
|
|
$Path_Txtsetup_sign =$BigTxtsetup_sign;
|
|
$Path_Layout_sign =$BigLayout_sign;
|
|
$Path_Dir_sign ="ProInf\\realsign";
|
|
$INFPathSKUs{"PRO"} = [ ($Path_Dosnet,$Path_Txtsetup,$Path_Layout,$Path_Dir, $Path_Dosnet_sign,$Path_Txtsetup_sign,$Path_Layout_sign,$Path_Dir_sign) ];
|
|
|
|
#PER
|
|
$Path_Dosnet =$PerDosnet;
|
|
$Path_Txtsetup =$PerTxtsetup;
|
|
$Path_Layout =$PerLayout;
|
|
$Path_Dir ="PerInf";
|
|
$Path_Dosnet_sign =$PerDosnet_sign;
|
|
$Path_Txtsetup_sign =$PerTxtsetup_sign;
|
|
$Path_Layout_sign =$PerLayout_sign;
|
|
$Path_Dir_sign ="PerInf\\realsign";
|
|
$INFPathSKUs{"PER"} = [ ($Path_Dosnet,$Path_Txtsetup,$Path_Layout,$Path_Dir, $Path_Dosnet_sign,$Path_Txtsetup_sign,$Path_Layout_sign,$Path_Dir_sign) ];
|
|
|
|
#SRV
|
|
$Path_Dosnet =$SrvDosnet;
|
|
$Path_Txtsetup =$SrvTxtsetup;
|
|
$Path_Layout =$SrvLayout;
|
|
$Path_Dir ="SrvInf";
|
|
$Path_Dosnet_sign =$SrvDosnet_sign;
|
|
$Path_Txtsetup_sign =$SrvTxtsetup_sign;
|
|
$Path_Layout_sign =$SrvLayout_sign;
|
|
$Path_Dir_sign ="SrvInf\\realsign";
|
|
$INFPathSKUs{"SRV"} = [ ($Path_Dosnet,$Path_Txtsetup,$Path_Layout,$Path_Dir, $Path_Dosnet_sign,$Path_Txtsetup_sign,$Path_Layout_sign,$Path_Dir_sign) ];
|
|
|
|
#BLA
|
|
$Path_Dosnet =$BlaDosnet;
|
|
$Path_Txtsetup =$BlaTxtsetup;
|
|
$Path_Layout =$BlaLayout;
|
|
$Path_Dir ="BlaInf";
|
|
$Path_Dosnet_sign =$BlaDosnet_sign;
|
|
$Path_Txtsetup_sign =$BlaTxtsetup_sign;
|
|
$Path_Layout_sign =$BlaLayout_sign;
|
|
$Path_Dir_sign ="BlaInf\\realsign";
|
|
$INFPathSKUs{"BLA"} = [ ($Path_Dosnet,$Path_Txtsetup,$Path_Layout,$Path_Dir, $Path_Dosnet_sign,$Path_Txtsetup_sign,$Path_Layout_sign,$Path_Dir_sign) ];
|
|
|
|
#SBS
|
|
$Path_Dosnet =$SbsDosnet;
|
|
$Path_Txtsetup =$SbsTxtsetup;
|
|
$Path_Layout =$SbsLayout;
|
|
$Path_Dir ="SbsInf";
|
|
$Path_Dosnet_sign =$SbsDosnet_sign ;
|
|
$Path_Txtsetup_sign =$SbsTxtsetup_sign ;
|
|
$Path_Layout_sign =$SbsLayout_sign ;
|
|
$Path_Dir_sign ="SbsInf\\realsign";
|
|
$INFPathSKUs{"SBS"} = [ ($Path_Dosnet,$Path_Txtsetup,$Path_Layout,$Path_Dir, $Path_Dosnet_sign,$Path_Txtsetup_sign,$Path_Layout_sign,$Path_Dir_sign) ];
|
|
|
|
#ADS (ENT)
|
|
$Path_Dosnet =$EntDosnet;
|
|
$Path_Txtsetup =$EntTxtsetup;
|
|
$Path_Layout =$EntLayout;
|
|
$Path_Dir ="EntInf";
|
|
$Path_Dosnet_sign =$EntDosnet_sign;
|
|
$Path_Txtsetup_sign =$EntTxtsetup_sign;
|
|
$Path_Layout_sign =$EntLayout_sign;
|
|
$Path_Dir_sign ="EntInf\\realsign";
|
|
$INFPathSKUs{"ADS"} = [ ($Path_Dosnet,$Path_Txtsetup,$Path_Layout,$Path_Dir, $Path_Dosnet_sign,$Path_Txtsetup_sign,$Path_Layout_sign,$Path_Dir_sign) ];
|
|
|
|
#DTC
|
|
$Path_Dosnet =$DtcDosnet;
|
|
$Path_Txtsetup =$DtcTxtsetup;
|
|
$Path_Layout =$DtcLayout;
|
|
$Path_Dir ="DtcInf";
|
|
$Path_Dosnet_sign =$DtcDosnet_sign;
|
|
$Path_Txtsetup_sign =$DtcTxtsetup_sign;
|
|
$Path_Layout_sign =$DtcLayout_sign;
|
|
$Path_Dir_sign ="DtcInf\\realsign";
|
|
$INFPathSKUs{"DTC"} = [ ($Path_Dosnet,$Path_Txtsetup,$Path_Layout,$Path_Dir, $Path_Dosnet_sign,$Path_Txtsetup_sign,$Path_Layout_sign,$Path_Dir_sign) ];
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|