[License] ////////////////////////////////////////////////////////////////////////////////////////////////////////// // // This script is part of the PhoenixPE project and distributed under the MIT License. // // Additional 3rd party tools, encoded files, and programs used by the project are the property // of their respective authors and may be subject to their own license agreement. // // Copyright (c) 2014-2022 Jonathan Holmgren (Homes32) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // ////////////////////////////////////////////////////////////////////////////////////////////////////////// [Main] Title=PhoenixPE API Author=Homes32 Description=PhoenixPE scripting support library. Version=1.4.0.0 Date=2021-04-03 Level=0 Selected=None [Variables] // Defines the configuration (pre-shell) processor used for things like creating shortcuts and auto-run entries. // In the future this can be used to add support for replacement pre-shell processors. // PECMD - Use PECMD (Default) %_PhoenixAPI_ConfigMode%=PECMD [Macros] // Registry RegLoadHives=Run,%API%,_PhoenixAPI_RegLoadHives RegUnloadHives=Run,%API%,_PhoenixAPI_RegUnloadHives RegCopyDriver=Run,%API%,_PhoenixAPI_RegCopyDriver // Shortcuts/Autorun RunFromRam=Run,%API%,_PhoenixAPI_RunFromRam AddAutoRun=Run,%API%,_PhoenixAPI_AddAutoRun AddShortcut=Run,%API%,_PhoenixAPI_AddShortcut PinShortcut=Run,%API%,_PhoenixAPI_PinShortcut // File/Dir Handling DirDeleteEx=Run,%API%,_PhoenixAPI_DirDeleteEx FileCopyEx=Run,%API%,_PhoenixAPI_FileCopyEx FileDeleteEx=Run,%API%,_PhoenixAPI_FileDeleteEx SetFileACL=Run,%API%,_PhoenixAPI_SetFileACL SetRegACL=Run,%API%,_PhoenixAPI_SetRegACL RequireDriver=Run,%API%,_PhoenixAPI_RequireDriver RequireFile=Run,%API%,_PhoenixAPI_RequireFile RequireFileEx=Run,%API%,_PhoenixAPI_RequireFileEx Associate=Run,%API%,_PhoenixAPI_Associate ConvertImage=Run,%API%,_PhoenixAPI_ConvertImage // Experimental - May be changed or removed without notice 7z=Run,%API%,_PhoenixAPI_7z //7zExtract=Run,%API%,_PhoenixAPI_7z InnoUnpack=Run,%API%,_PhoenixAPI_InnoUnpack Innounp=Run,%API%,_PhoenixAPI_Innounp // XML XMLAdd=Run,%API%,_PhoenixAPI_XMLAdd XMLDelete=Run,%API%,_PhoenixAPI_XMLDelete //XMLRead=NOT IMPLIMENTED XMLRename=Run,%API%,_PhoenixAPI_XMLRename XMLUpdate=Run,%API%,_PhoenixAPI_XMLUpdate // Bitmask Handling ApplyBitMask=Run,%API%,_PhoenixAPI_ApplyBitMask BitClear=Run,%API%,_PhoenixAPI_BitClear BitSet=Run,%API%,_PhoenixAPI_BitSet BitToggle=Run,%API%,_PhoenixAPI_BitToggle [#_PhoenixAPI_RegLoadHives#] // =============================================================================================================================== // Name...........: RegLoadHives // Description....: Mount Source and Build registry hives. // Syntax.........: RegLoadHives // Parameters.....: // Return values..: // Author.........: Homes32 // Remarks........: // Related........: // =============================================================================================================================== [_PhoenixAPI_RegLoadHives] RegHiveLoad,Tmp_Default,%RegDefault% RegHiveLoad,Tmp_Drivers,%RegDrivers% RegHiveLoad,Tmp_Software,%RegSoftware% RegHiveLoad,Tmp_System,%RegSystem% RegHiveLoad,Tmp_Install_Default,%RegInstallDefault% RegHiveLoad,Tmp_Install_Drivers,%RegInstallDrivers% RegHiveLoad,Tmp_Install_Software,%RegInstallSoftware% RegHiveLoad,Tmp_Install_System,%RegInstallSystem% [#_PhoenixAPI_RegUnloadHives#] // =============================================================================================================================== // Name...........: RegUnloadHives // Description....: UnMount Source and Build registry hives. // Syntax.........: RegUnLoadHives[,FORCE][,HKEY=][,Target=] // Parameters.....: Force - Force hive unload using HiveUnload.exe // HKEY= - Unload hives from this root key. (HKLM, HKU) // Target= - Unload hives from this directory. // Return values..: ExitCode provided by the HiveUnload.exe application // 0 - All registry hives unloaded successfully. // 1 - Not all registry hives could be unloaded. // 2 - No loaded registry hives were found. // You must handle ExitCode. The script will not Exit/Halt. // Author.........: Homes32 // Remarks........: HiveUnload.exe is open-source software developed by BlueLife // Related........: // =============================================================================================================================== [_PhoenixAPI_RegUnloadHives] System,SetLocal GetParam,1,%Arg1% GetParam,2,%Arg2% GetParam,3,%Arg3% Set,%ForceUnmount%,False Set,%HKEY%,"HKLM" Set,%UnloadTarget%,"ALL" Run,%API%,__PhoenixAPI_RegUnloadHives_Process_Arg,%Arg1% Run,%API%,__PhoenixAPI_RegUnloadHives_Process_Arg,%Arg2% Run,%API%,__PhoenixAPI_RegUnloadHives_Process_Arg,%Arg3% If,%ForceUnmount%,Equal,True,Begin If,ExistFile,"%Tools%\x86\HiveUnload.exe",ShellExecute,Hide,"%Tools%\x86\HiveUnload.exe","/%HKEY% /Target:%UnloadTarget%" If,%ExitCode%,Equal,0,Echo,"HiveUnload: All registry hives unloaded successfully." If,%ExitCode%,Equal,1,Echo,"HiveUnload: Warning: Not all registry hives could be unloaded! Please verify that regedit is not running and try again.",Warn If,%ExitCode%,Equal,2,Echo,"HiveUnload: No loaded registry hives were found." End Else,Begin RegHiveUnload,Tmp_Default RegHiveUnload,Tmp_Drivers RegHiveUnload,Tmp_Software RegHiveUnload,Tmp_System RegHiveUnload,Tmp_Install_Default RegHiveUnload,Tmp_Install_Drivers RegHiveUnload,Tmp_Install_Software RegHiveUnload,Tmp_Install_System End System,EndLocal [#__PhoenixAPI_RegUnloadHives_Process_Arg#] // =============================================================================================================================== // Name...........: __PhoenixAPI_RegUnloadHives_Process_Arg // Description....: Process RegUnloadHives optional arguments // Syntax.........: __PhoenixAPI_RegUnloadHives_Process_Arg, // Parameters.....: #1 Arg - The argument to process // Return values..: // Author.........: Homes32 // Remarks........: Internal Function // Do not call System,SetLocal here. We need this function to run in the same scope as PhoenixAPI_InnoUnpack // Related........: _PhoenixAPI_RegUnloadHives // =============================================================================================================================== [__PhoenixAPI_RegUnloadHives_Process_Arg] If,#1,Equal,"Force",Set,%ForceUnmount%,True Else,Begin StrFormat,Split,#1,"=",1,%ArgKey% If,Not,%ArgKey%,Equal,"",Begin If,%ArgKey%,Equal,"HKEY",StrFormat,Split,#1,"=",2,%HKEY% Else,If,%ArgKey%,Equal,"TARGET",StrFormat,Split,#1,"=",2,%UnloadTarget% Else,Halt,"SYNTAX ERROR: Invalid Argument [#1]" End End [#_PhoenixAPI_RegCopyDriver#] // =============================================================================================================================== // Name...........: RegCopyDriver // Description....: Copy the driver entries from the INSTALL.WIM driver database to the target registry driver database. // Both the DRIVERS hive and SYSTEM\Drivers store are processed. // Syntax.........: RegCopyDriver, // Parameters.....: InfFile - The name of the driver's .inf file // Return values..: // Author.........: Homes32 // Remarks........: This function uses a modified version of ChrisR's RegAddDriver.cmd as PEBakery does not have a good way // to enum/query registry keys yet... // Registry hives Tmp_Install_Drivers, Tmp_Install_System, Tmp_Drivers, Tmp_System must be loaded before calling. // Related........: Depends on %Tools%\RegCopyDriver.cmd // =============================================================================================================================== [_PhoenixAPI_RegCopyDriver] System,SetLocal Set,%Debug%,True If,#1,Equal,"",Halt,"Syntax Error: You must specify the name of the driver's .inf to register." GetParam,1,%InfFile% Echo,"Processing [%InfFile%] registration..." If,%Debug%,Equal,True,TXTReplace,"%Tools%\RegCopyDriver.cmd",":::","" ShellExecute,Hide,"cmd.exe","/D /C RegCopyDriver.cmd #$q%InfFile%#$q",%Tools% System,EndLocal [#_PhoenixAPI_RequireDriver#] // =============================================================================================================================== // Name...........: RequireDriver // Description....: Copy the driver support files and driver entries from the INSTALL.WIM driver database to the target registry driver database. // Both the DRIVERS hive and SYSTEM\Drivers store are processed. // // You must still copy additional/supporting driver files yourself if they have a different name then the .inf file itself. // Ex. RequireDriver,netrndis.inf - you still need to copy \Windows\System32\drivers\usb8023.sys yourself. // // Syntax.........: RequireDriver, // Parameters.....: InfFile - The name of the driver's .inf file // NOREG - (Optional) Don't copy registry (driver database) // Return values..: // Author.........: Homes32 // Remarks........: This function uses a modified version of ChrisR's RegAddDriver.cmd as PEBakery does not have a good way // to enum/query registry keys yet... // Registry hives Tmp_Install_Drivers, Tmp_Install_System, Tmp_Drivers, Tmp_System must be loaded before calling. // Related........: Depends on %Tools%\RegCopyDriver.cmd // =============================================================================================================================== [_PhoenixAPI_RequireDriver] System,SetLocal If,#1,Equal,"",Halt,"Syntax Error: You must specify the name of the driver's .inf to include/register." GetParam,1,%InfFile% GetParam,2,%Arg2% If,%Arg2%,Equal,NOREG,Set,%NOREG%,True Else,Set,%NOREG%,False StrFormat,RTRIM,%InfFile%,3,%InfFileNoExt% Set,%RequireDriver-Listfile%,%ProjectTemp%\RequireDriver-ListFile.txt FileDeleteEx,%RequireDriver-Listfile% Echo,"Extracting [%InfFile%] Driver Support Files..." TxtAddline,%RequireDriver-Listfile%,"\Windows\INF\%InfFileNoExt%*",Append TxtAddline,%RequireDriver-Listfile%,"\Windows\System32\%InfFileNoExt%*",Append TxtAddline,%RequireDriver-Listfile%,"\Windows\System32\Drivers\%InfFileNoExt%*",Append TxtAddline,%RequireDriver-Listfile%,"\Windows\System32\Driverstore\??-??\%InfFile%_loc",Append TxtAddline,%RequireDriver-Listfile%,"\Windows\System32\DriverStore\FileRepository\%InfFile%*",Append WimExtractBulk,%SourceInstallWim%,%SourceInstallWimImage%,%RequireDriver-Listfile%,%TargetDir%,NOACL,NOATTRIB,NOERR If,%NOREG%,Equal,False,Begin Echo,"Registering [%InfFile%] Driver..." RegCopyDriver,%InfFile% End System,EndLocal [#_PhoenixAPI_7z#] // =============================================================================================================================== // Name...........: 7z // Description....: Execute 7zip with the provided arguments. // Syntax.........: 7z,[,] // Parameters.....: #1 Args - The arguments to pass to the 7z executable. // #2 WorkDir - The full path to the working directory. Default is the exe path. // Return values..: ExitCode provided by the 7zip application // Author.........: Homes32 // Remarks........: *** Experimental - May be changed or removed without notice *** // Related........: // =============================================================================================================================== [_PhoenixAPI_7z] System,SetLocal If,#1,Equal,"",Halt,"7zip Error: You must specify the program arguments." GetParam,1,%Args% Getparam,2,%WorkDir% ShellExecute,Hide,"%Tools%\%HostArch%\7z.exe",%Args%,%WorkDir% Set,#r,%ExitCode% System,EndLocal [#_PhoenixAPI_Innounp#] // =============================================================================================================================== // Name...........: Innounp // Description....: Execute Innounp (Inno Setup Unpacker) with the provided arguments. // Syntax.........: Innounp,[,] // Parameters.....: #1 Args - The arguments to pass to the Innounp executable. // #2 WorkDir - The full path to the working directory. Default is the exe path. // // Return values..: ExitCode provided by the Innounp application // Author.........: Homes32 // Remarks........: This command is a wrapper for Innounp.exe and passes any arguments directly to the executable. You are // responsible for checking the return code and handling any errors. Unless you need advanced features such // extracting using a @filelist or filemask it is recommended to use the Innounp macro instead. // Innounp Website: http://innounp.sourceforge.net/ // Related........: Innounp.exe // =============================================================================================================================== [_PhoenixAPI_Innounp] System,SetLocal If,#1,Equal,"",Halt,"InnoExtractEx Syntax Error: You must specify the program arguments." GetParam,1,%Args% Getparam,2,%WorkDir% ShellExecute,Hide,"%Tools%\x86\Innounp.exe","%Args%",%WorkDir% Set,#r,%ExitCode% System,EndLocal [#_PhoenixAPI_InnoUnpack#] // =============================================================================================================================== // Name...........: InnoUnpack // Description....: Extract files from an Innounp (Inno Setup Unpacker) installer. // Syntax.........: InnoUnpack,,[,] // Parameters.....: #1 SetupFile - The inno-setup file to unpack. // #2 DestDir - The full path to the directory where the files will be unpacked. // #3-#5 - Additional Arguments: // PASSWORD= - Password required to decrypt the setup file. (-p) // CDIR= - Notifies innounp that you are only interested in paths from the current directory and below. (-c) // LIST= - Instructs innounp to use a list file to determine the files to extract (@listfile) // Return values..: // Author.........: Homes32 // Remarks........: *** Experimental - May be changed or removed without notice *** // Related........: Innounp.exe // =============================================================================================================================== [_PhoenixAPI_InnoUnpack] System,SetLocal If,#1,Equal,"",Halt,"InnoExtract Syntax Error: You must specify the setup file." If,#2,Equal,"",Halt,"InnoExtract Syntax Error: You must specify the destination directory." GetParam,1,%SetupFile% Getparam,2,%DestDir% Getparam,3,%Arg3% Getparam,4,%Arg4% Getparam,5,%Arg5% Set,%Password%,"" Set,%CurrentDir%,"" Set,%ListFile%,"" Run,%API%,__PhoenixAPI_InnoUnpack_Process_Arg,%Arg3% Run,%API%,__PhoenixAPI_InnoUnpack_Process_Arg,%Arg4% Run,%API%,__PhoenixAPI_InnoUnpack_Process_Arg,%Arg5% ShellExecute,Hide,"%Tools%\x86\Innounp.exe","-x -b -y -a -d#$q%DestDir%#$q %Password%%CurrentDir%#$q%SetupFile%#$q%ListFile%" If,Not,%ExitCode%,Equal,0,Begin, FileVersion,"%Tools%\x86\Innounp.exe",%InnounpVer% Halt,"Error: Failed to unpack setup file#$x#$x[%SetupFile%]#$x#$xThe command returned: [%ExitCode%].#$xYou are using Innounp.exe version [%InnounpVer%]." End System,EndLocal [#__PhoenixAPI_InnoUnpack_Process_Arg#] // =============================================================================================================================== // Name...........: __PhoenixAPI_InnoUnpack_Process_Arg // Description....: Process InnoUnpack optional arguments // Syntax.........: __PhoenixAPI_InnoUnpack_Process_Arg, // Parameters.....: #1 Arg - The argument to process // Return values..: // Author.........: Homes32 // Remarks........: Internal Function // Do not call System,SetLocal here. We need this function to run in the same scope as PhoenixAPI_InnoUnpack // Related........: _PhoenixAPI_InnoUnpack // =============================================================================================================================== [__PhoenixAPI_InnoUnpack_Process_Arg] StrFormat,Split,#1,"=",1,%ArgKey% If,Not,%ArgKey%,Equal,"",Begin If,%ArgKey%,Equal,"PASSWORD",Begin StrFormat,Split,#1,"=",2,%Password% Set,%Password%," -p#$q%Password%#$q " End Else,If,%ArgKey%,Equal,"CDIR",Begin StrFormat,Split,#1,"=",2,%CurrentDir% Set,%CurrentDir%," -c#$q%CurrentDir%#$q " End Else,If,%ArgKey%,Equal,"LIST",Begin StrFormat,Split,#1,"=",2,%ListFile% Set,%ListFile%," #$q@%ListFile%#$q" End Else,Halt,"SYNTAX ERROR: Invalid Argument [#1]" End [#_PhoenixAPI_ConvertImage#] // =============================================================================================================================== // Name...........: ConvertImage // Description....: Convert an image to the specified format. // Syntax.........: ConvertImage,,[,] // Parameters.....: #1 - The full path to the image file. // #2 - The full path to the converted image file. // #3 - (Optional) Resize the image. // Return values..: // Author.........: Homes32 // Remarks........: Depends on ImageConvert.exe in %Tools%. // ImageConvert.exe // Related........: // =============================================================================================================================== [_PhoenixAPI_ConvertImage] // Convert images to the specified format... StrFormat,EXT,#2,%NewImageExt% Echo,"Converting [#1] to a [%NewImageExt%] image..." If,Not,#3,Equal,"",Set,%ResizeParam%," --resize:#3" ShellExecute,Hide,"%Tools%\%HostArch%\ImageConvert.exe","#$q#1#$q #$q#2#$q --silent%ResizeParam%" If,Not,%ExitCode%,Equal,0,Halt,"ERROR: Image conversion failed. [%ExitCode%]" [#_PhoenixAPI_Associate#] // =============================================================================================================================== // Name...........: Associate // Description....: Associate a file extension with a program. // Syntax.........: Associate,,[,] // Parameters.....: #1 FileExtension - The file extension to associate. // #2 ProgramExe - The full path to the executable to which the file extension will be associated with. // // Example: Associate,.ini,"C:\Windows\System32\notepad.exe" // // Return values..: // Author.........: Homes32 // Remarks........: // Related........: // =============================================================================================================================== [_PhoenixAPI_Associate] System,SetLocal If,#1,Equal,"",Halt,"Associate Syntax Error: You must specify the file extension to associate." If,#2,Equal,"",Halt,"Associate Syntax Error: You must specify the program to associate with the file extension." GetParam,1,%FileExt% Getparam,2,%Program% Set,%ExeExtList%,".exe|.cmd|.bat|.com|.js|.vbs|.wsf" // Are hives already loaded? - We don't want to unload them if they were loaded by a script If,ExistRegSubKey,HKLM,"Tmp_Software",Set,%RegHivesLoaded%,True Else,Set,%RegHivesLoaded%,False // Remove . from the file extension if present. StrFormat,CTRIM,%FileExt%,".",%FileExt% StrFormat,FILENAME,%Program%,%ProgramFileName% StrFormat,EXT,%ProgramFileName%,%ProgramExt% List,Pos,%ExeExtList%,%ProgramExt%,%IsExecutable% If,%IsExecutable%,Equal,0,Halt,"Associate Error: [%Program%] is not an executable file (%ExeExtList%)." Else,Begin Echo,"Associating file extension [.%FileExt%] with [%Program%]..." If,%RegHivesLoaded%,Equal,False,RegHiveLoad,Tmp_Software,%RegSoftware% RegWrite,HKLM,0x1,"Tmp_Software\Classes\.%FileExt%","","%FileExt%file" RegWrite,HKLM,0x1,"Tmp_Software\Classes\%FileExt%file","","%FileExt% File" RegWrite,HKLM,0x2,"Tmp_Software\Classes\%FileExt%file\DefaultIcon","","#$q%Program%#$q" RegWrite,HKLM,0x2,"Tmp_Software\Classes\%FileExt%file\shell\open\command","","#$q%Program%#$q #$q#$p1#$q" If,%RegHivesLoaded%,Equal,False,RegHiveUnLoad,Tmp_Software Echo,"" End System,EndLocal [#_PhoenixAPI_SetFileACL#] // =============================================================================================================================== // Name...........: SetFileACL // Description....: Give full control for "Everyone" on a file or directory using Helge Klein's SetAcl.exe // Syntax.........: SetFileACL, // Parameters.....: #1 Path - The file or directory to modify. // Return values..: // Author.........: Homes32 // Remarks........: Depends on SetAcl.exe in %Tools% // Related........: // =============================================================================================================================== [_PhoenixAPI_SetFileACL] System,SetLocal If,#1,Equal,"",Halt,"SetFileACL Syntax Error: You must specify the file or directory to modify." Echo,"Granting full access to [#1] ...#$X#$XThis can take awhile, please be patient." ShellExecute,Hide,%Tools%\%HostArch%\SetAcl.exe," -ot #$qfile#$q -on #$q#1#$q -actn ace -actn setprot -op #$qdacl:p_nc#$q -ace #$qn:S-1-1-0;p:full;s:y#$q" If,Not,%ExitCode%,Equal,0,Halt,"Error: Could not grant full permission on#$x#$x#1#$x#$xThe command returned: [%ExitCode%]" System,EndLocal [#_PhoenixAPI_SetRegACL#] // =============================================================================================================================== // Name...........: SetRegACL // Description....: Take ownership and grant full control for "Everyone" on a registry key using Helge Klein's SetAcl.exe // Syntax.........: SetRegACL, // Parameters.....: #1 Path - Registry key to modify. The hive must already be mounted. // Return values..: // Author.........: Homes32 // Remarks........: Depends on SetAcl.exe in %Tools% // Related........: // =============================================================================================================================== [_PhoenixAPI_SetRegACL] System,SetLocal If,#1,Equal,"",Halt,"SetRegACL Syntax Error: You must specify the Registry Key to modify." Echo,"Taking ownership of [#1] ...#$X#$XThis can take awhile, please be patient." ShellExecute,Hide,%Tools%\%HostArch%\SetAcl.exe,"-on #$q#1#$q -ot reg -rec yes -actn setowner -ownr #$qn:S-1-1-0;s:y#$q -silent" If,Not,%ExitCode%,Equal,0,Halt,"SetRegACL Error: Could not take ownership of#$x#$x#1#$x#$xThe command returned: [%ExitCode%]" Echo,"Granting full access to [#1] ...#$X#$XThis can take awhile, please be patient." ShellExecute,Hide,%Tools%\%HostArch%\SetAcl.exe,"-on #$q#1#$q -ot reg -rec yes -actn ace -ace #$qn:S-1-1-0;p:full;s:y#$q -silent" If,Not,%ExitCode%,Equal,0,Halt,"Error: Could not grant full permission on#$x#$x#1#$x#$xThe command returned: [%ExitCode%]" System,EndLocal [#_PhoenixAPI_FileCopyEx#] // =============================================================================================================================== // Name...........: FileCopyEx // Description....: Copy a single file and it's .mui's (if they exist) from a specified directory. // Syntax.........: FileCopyEx,, // Parameters.....: #1 SourcePath - Full path to the source file to copy. Wildcards are NOT supported. // #2 DestPath - Full path to the destination. // Return values..: // Author.........: Homes32 // Remarks........: Wildcards are not supported. If you need wildcards use FileCopy instead. // Related........: // =============================================================================================================================== [_PhoenixAPI_FileCopyEx] System,SetLocal If,#1,Equal,"",Halt,"FileCopyEx Syntax Error: Source file was not specified." If,#2,Equal,"",Halt,"FileCopyEx Syntax Error: Destination was not specified." GetParam,1,%SrcFile% GetParam,2,%DestPath% StrFormat,Pos,%SrcFile%,*,%WildCard% If,Not,%WildCard%,Equal,0,Halt,"FileCopyEx Syntax Error: Wildcards are not supported." StrFormat,Pos,%SrcFile%,?,%WildCard% If,Not,%WildCard%,Equal,0,Halt,"FileCopyEx Syntax Error: Wildcards are not supported." List,Count,%SourceFallbackLang%,%LangCount% FileCopy,%SrcFile%,%DestPath% StrFormat,FileName,%SrcFile%,%Filename% StrFormat,Split,%DestPath%,"\",1,%DriveLtr% If,ExistFile,"%DriveLtr%\Windows\SystemResources\%Filename%.mun",FileCopy,"%DriveLtr%\Windows\SystemResources\%Filename%.mun",APPEND Loop,%API%,__PhoenixAPI_FileCopyEx_mui_Loop,1,%LangCount%,%SrcFile%,%SourceFallbackLang%,%DestPath% System,EndLocal [#__PhoenixAPI_FileCopyEx_mui_Loop#] // =============================================================================================================================== // Name...........: FileCopyEx_mui_Loop // Description....: Loop to copy a file's .mui // Syntax.........: FileCopyEx_mui_Loop,,, // Parameters.....: #1 FilePath - Path to the parent file // #2 Language - Language to copy // #3 DestPath - Destination path // Return values..: // Author.........: Homes32 // Remarks........: Internal Function // Related........: FileCopyEx // =============================================================================================================================== [__PhoenixAPI_FileCopyEx_mui_Loop] System,SetLocal List,Get,#2,#c,%Language% StrFormat,FileName,#1,%FileName% StrFormat,Ext,#1,%FileExt% StrFormat,DirPath,#1,%SrcDirPath% StrFormat,DirPath,#3,%DestDirPath% If,%FileExt%,Equal,.msc,FileCopy,"%SrcDirPath%%Language%\%FileName%","#3\%Language%\%FileName%" Else,If,ExistFile,"%SrcDirPath%%Language%\%FileName%.mui",FileCopy,"%SrcDirPath%%Language%\%FileName%.mui","%DestDirPath%%Language%\%FileName%.mui" System,EndLocal [#_PhoenixAPI_RequireFile#] // =============================================================================================================================== // Name...........: RequireFile // Description....: Extract a single file and it's .mui's (if they exist) from Install.wim // Syntax.........: RequireFileEx,[,NOMUI] // Parameters.....: #1 FilePath - Path to the file to extract relative to the root of Install.wim // #2 NOMUI - Don't extract .mui files. // Return values..: // Author.........: Homes32 // Remarks........: This command is an alias to RequireFileEx,ExtractFile // Related........: _PhoenixAPI_RequireFileEx // =============================================================================================================================== [_PhoenixAPI_RequireFile] Run,%API%,_PhoenixAPI_RequireFileEx,ExtractFile,#1,#2 [#_PhoenixAPI_RequireFileEx#] // =============================================================================================================================== // Name...........: RequireFileEx // Description....: Extract files and their .mui's (if they exist) from Install.wim // Syntax.........: RequireFileEx,,[,NOMUI] // Parameters.....: #1 Action: // AppendList - Append the file to a list (bulk extraction). You must call RequireFileEx,ExtractList // in order to perform the actual extraction of the list. // ExtractFile - Single file extraction // ExtractList - Extract the list created with Append // #2 Path to the file to extract relative to the root of Install.wim // #3 NOMUI - (Optional) Don't extract .mui files. // If you know the file to be extracted isn't localized you can save a some time by not checking // for .mui files that don't exist. // Return values..: // Author.........: Homes32 // Remarks........: RequireFileEx uses WimExtractBulk in NOERR mode so it does not verify that files exist before trying to extract. // Check the build log for WimExtract warnings. // Right now we are lazy and just add the .mun files to the list files regardless of whether or not it exists, // and let WimExtractBulk log a warning if it doesn't. In order to reduce log clutter with false positive warnings // we should check if the files exist first using WimExistFile, but it slows things down too much with large lists. // Related........: // =============================================================================================================================== [_PhoenixAPI_RequireFileEx] If,#1,Equal,"",Halt,"RequireFileEx Syntax Error: Action was not specified." System,SetLocal GetParam,1,%Action% GetParam,2,%GLOB% GetParam,3,%Arg3% If,%Arg3%,Equal,NOMUI,Set,%ExtractMui%,False Else,Set,%ExtractMui%,True Set,%BulkFileList%,%ProjectTemp%\RequireFileEx-BulkFileList.txt Set,%SingleFileList%,%ProjectTemp%\RequireFileEx-SingleFileList.txt List,Count,%SourceFallbackLang%,%LangCount% // For .mun file check StrFormat,FileName,%GLOB%,%FileName% If,%Action%,Equal,"AppendList",Begin If,%GLOB%,Equal,"",Halt,"RequireFileEx Syntax Error: File was not specified." If,Not,ExistFile,%BulkFileList%,FileCreateBlank,%BulkFileList% TXTAddLine,%BulkFileList%,%GLOB%,APPEND TXTAddLine,%BulkFileList%,\Windows\SystemResources\%FileName%.mun,APPEND If,%ExtractMui%,Equal,True,Loop,%API%,__PhoenixAPI_RequireFileEx_mui_Loop,1,%LangCount%,%GLOB%,%SourceFallbackLang%,%BulkFileList% End Else,If,%Action%,Equal,"ExtractFile",Begin Echo,"Extracting required file(s) [%GLOB%]..." If,%GLOB%,Equal,"",Halt,"RequireFileEx Syntax Error: File was not specified." If,Not,ExistFile,%SingleFileList%,FileCreateBlank,%SingleFileList% TXTAddLine,%SingleFileList%,%GLOB%,APPEND TXTAddLine,%SingleFileList%,\Windows\SystemResources\%FileName%.mun,APPEND If,%ExtractMui%,Equal,True,Loop,%API%,__PhoenixAPI_RequireFileEx_mui_Loop,1,%LangCount%,%GLOB%,%SourceFallbackLang%,%SingleFileList% WimExtractBulk,%SourceInstallWim%,%SourceInstallWimImage%,%SingleFileList%,%TargetDir%,NOACL,NOATTRIB,NOERR,NOWARN FileDeleteEx,%SingleFileList% End Else,If,%Action%,Equal,"ExtractList",Begin If,Not,ExistFile,%BulkFileList%,Halt,"RequireFileEx Error: You must create a list using [RequireFileEx,AppendList] before you can extract it!" Echo,"Extracting required files...#$x#$xThis can take awhile, please be patient." WimExtractBulk,%SourceInstallWim%,%SourceInstallWimImage%,%BulkFileList%,%TargetDir%,NOACL,NOATTRIB,NOERR,NOWARN FileDeleteEx,%BulkFileList% End Else,Halt,"RequireFileEx Syntax Error: Invalid Action [#1]." System,EndLocal [#__PhoenixAPI_RequireFileEx_mui_Loop#] // =============================================================================================================================== // Name...........: RequireFileEx_mui_Loop // Description....: Loop to extract a file's .mui from Install.wim // Syntax.........: RequireFileEx_mui_Loop,,, // Parameters.....: #1 FilePath - Path to the file relative to the root of Install.wim // #2 Language - Language to extract // #3 ListFile - ListFile to write the MUI path // Return values..: // Author.........: Homes32 // Remarks........: Internal Function // Right now we are lazy and just add the .mui files to the list files regardless of whether or not it exists, // and let WimExtractBulk log a warning if it doesn't. In order to reduce log clutter with false positive warnings // we should check if the files exist first using WimExistFile, but it slows things down too much with large lists. // Related........: RequireFileEx // =============================================================================================================================== [__PhoenixAPI_RequireFileEx_mui_Loop] System,SetLocal List,Get,#2,#c,%Language% StrFormat,FileName,#1,%FileName% StrFormat,Ext,#1,%FileExt% StrFormat,DirPath,#1,%DirPath% StrFormat,Len,%FileExt%,%FileExtLen% StrFormat,RTrim,%FileName%,%FileExtLen%,%FileNameNoExt% If,%FileExt%,Equal,.mof,TXTAddLine,#3,"%DirPath%%Language%\%FileNameNoExt%.mfl",APPEND Else,If,%FileExt%,Equal,.msc,TXTAddLine,#3,"%DirPath%%Language%\%FileName%",APPEND Else,TXTAddLine,#3,"%DirPath%%Language%\%FileName%.mui",APPEND System,EndLocal [#_PhoenixAPI_AddAutoRun#] // =============================================================================================================================== // Name...........: AddAutoRun // Description....: Run a program when the PE Environment starts // Syntax.........: AddAutoRun,,,,<ProgramExe>,[Parameters] // Parameters.....: #1 RunGroup // PreShell - Run before the shell (ie. Explorer) is loaded. // PostShell - Run after the shell is loaded. // RunOnce - Run during startup via HKLM\Software\Microsoft\Windows\CurrentVersion\RunOnce // AfterNetwork - Run after network connectivity has been established by PENetwork. // #2 Mode // NoWait - Do not wait for the program to terminate. // Wait - Wait for the program to terminate before moving on. // HideNoWait - Run the program hidden and do not wait for it to terminate. // HideWait - Run the program hidden and wait for it to terminate. // #3 Title - Title that may be shown in a progress window while the program is running. // #4 ProgramExe - The full path to the program to be executed. // #5 Parameters - (Optional) Parameters that will be passed to the program. // Return values..: // Author.........: Homes32 // Remarks........: PECMD: EXEC {[-hide] [-wait]} <ProgramExe> [Parameters] // Related........: // =============================================================================================================================== [_PhoenixAPI_AddAutoRun] System,SetLocal If,#1,Equal,"",Halt,"AddAutoRun Syntax Error: Run position was not specified." If,#2,Equal,"",Halt,"AddAutoRun Syntax Error: Run mode was not specified." // #3 Title is required but may be empty. If,#4,Equal,"",Halt,"AddAutoRun Syntax Error: Program Executable was not specified." GetParam,1,%RunGroup% GetParam,2,%Mode% GetParam,3,%Title% GetParam,4,%ProgramExe% GetParam,5,%Parameters% If,%_PhoenixAPI_ConfigMode%,Equal,PECMD,Begin If,%Mode%,Equal,NoWait,Set,%ExecMode%,"" Else,If,%Mode%,Equal,Wait,Set,%ExecMode%,"-wait " Else,If,%Mode%,Equal,HideNoWait,Set,%ExecMode%,"-hide " Else,If,%Mode%,Equal,HideWait,Set,%ExecMode%,"-hide -wait " Else,Halt,"AddAutoRun Syntax Error: [%Mode%] is not a valid run mode." If,%RunGroup%,Equal,"Preshell",TXTReplace,"%TargetSystem32%\pecmd.ini","_END Preshell","TEXT %Title%##0xFFFFFF L59 T39 $20#$xEXEC %ExecMode%%ProgramExe% %Parameters%#$x#$x_END Preshell" Else,If,%RunGroup%,Equal,"Postshell",TXTReplace,"%TargetSystem32%\pecmd.ini","_END PostShell","TEXT %Title%##0xFFFFFF L59 T39 $20#$xEXEC %ExecMode%%ProgramExe% %Parameters%#$x#$x_END PostShell" Else,If,%RunGroup%,Equal,"RunOnce",Run,%API%,__PhoenixAPI_AddAutoRun_RunOnce Else,If,%RunGroup%,Equal,"AfterNetwork",Run,%API%,__PhoenixAPI_AddAutoRun_AfterNetwork Else,Halt,"AddAutoRun Syntax Error: [%RunGroup%] is not a supported Run method." End Else,Begin // Shortcuts.exe - Not fully implemented yet... If,%RunGroup%,Equal,"Preshell",IniWriteTextLine,%TargetSystem32%\PhoenixPE.cfg,PreConfig,"%Mode%|%Title%|%ProgramExe% %Parameters%" Else,If,%RunGroup%,Equal,"Postshell",IniWriteTextLine,%TargetSystem32%\PhoenixPE.cfg,PostConfig,"%Mode%|%Title%|%ProgramExe% %Parameters%" //Else,If,%RunGroup%,Equal,"?",IniWriteTextLine,%TargetSystem32%\PhoenixPE.cfg,Autorun,"%Mode%|%Title%|%ProgramExe% %Parameters%" Else,Halt,"AddAutoRun Syntax Error: [%RunGroup%] is not a supported Run method." End System,EndLocal [#__PhoenixAPI_AddAutoRun_RunOnce#] // =============================================================================================================================== // Name...........: PhoenixAPI_AddAutoRun_RunOnce // Description....: Run a program during startup via HKCU\Software\Microsoft\Windows\CurrentVersion\RunOnce // RunOnce entries are always processed synchronously by Windows. NoWait and HideNoWait modes are not supported. // Syntax.........: PhoenixAPI_AddAutoRun_RunOnce // Parameters.....: // Return values..: // Author.........: Homes32 // Remarks........: Internal Function // Requires hiderun.exe to exist in %SystemRoot% for run hidden. // Do not call System,SetLocal here. We need this function to run in the same scope as PhoenixAPI_AddAutoRun // Related........: PhoenixAPI_AddAutoRun // =============================================================================================================================== [__PhoenixAPI_AddAutoRun_RunOnce] // Are hives already loaded? - We don't want to unload them if they were loaded by a script If,ExistRegSubKey,HKLM,"Tmp_Default",Set,%RegHivesLoaded%,True Else,Set,%RegHivesLoaded%,False If,%RegHivesLoaded%,Equal,False,RegHiveLoad,Tmp_Default,%RegDefault% Set,%ExecMode%,"" If,%Mode%,Equal,NoWait,Halt,"AddAutoRun Error: RunOnce does not support [%Mode%]." Else,If,%Mode%,Equal,Wait,Set,%ExecMode%,"" Else,If,%Mode%,Equal,HideWait,Set,%ExecMode%,"hiderun.exe " Else,If,%Mode%,Equal,HideNoWait,Halt,"AddAutoRun Error: RunOnce does not support [%Mode%]." Else,Halt,"AddAutoRun Syntax Error: [%Mode%] is not a valid run mode." RegWrite,HKLM,0x2,"Tmp_Default\Software\Microsoft\Windows\CurrentVersion\Run","%Title%","#$q%ExecMode%%ProgramExe%#$q #$q%Parameters%#$q" If,%RegHivesLoaded%,Equal,False,RegHiveUnload,Tmp_Default [#__PhoenixAPI_AddAutoRun_AfterNetwork#] // =============================================================================================================================== // Name...........: PhoenixAPI_AddAutoRun_AfterNetwork // Description....: Run a program after PENetwork has established connectivity. // Syntax.........: PhoenixAPI_AddAutoRun_AfterNetwork // Parameters.....: // Return values..: // Author.........: Homes32 // Remarks........: Internal Function // Requires hiderun.exe to exist in %SystemRoot% for run hidden. // Requires PENetwork to be configured to execute System32\RunAfterNetwork.cmd // Do not call System,SetLocal here. We need this function to run in the same scope as PhoenixAPI_AddAutoRun // Related........: PhoenixAPI_AddAutoRun // =============================================================================================================================== [__PhoenixAPI_AddAutoRun_AfterNetwork] Set,%ExecMode%,"" If,%Mode%,Equal,NoWait,Set,%ExecMode%,"" Else,If,%Mode%,Equal,Wait,Set,%ExecMode%,"/WAIT " Else,If,%Mode%,Equal,HideWait,Set,%ExecMode%,"/WAIT hiderun.exe " Else,If,%Mode%,Equal,HideNoWait,Set,%ExecMode%,"hiderun.exe " Else,Halt,"AddAutoRun Syntax Error: [%Mode%] is not a valid run mode." TxtAddLine,"%TargetSystem32%\RunAfterNetwork.cmd","START #$q%Title%#$q %ExecMode%#$q%ProgramExe%#$q %Parameters%",Append [#_PhoenixAPI_AddShortcut#] // =============================================================================================================================== // Name...........: AddShortcut // Description....: Create Shortcuts for programs in PE. // Syntax.........: AddShortcut,<Type>,<StartMenuFolder>,<Title>,<PathProgramExe>,[Parameters],[WorkDir],[IconPath],[IconIndex],[State],[Hotkey],[Tooltip] // Parameters.....: #1 Type // Desktop - The shortcut will be created on the desktop. // StartMenu - The shortcut will be created in the start menu. // #2 StartMenuFolder - The name of the start menu folder where the shortcut will be created. // #3 Title - The name of the shortcut. // #4 ProgramExe - The full path to the program to be executed. // #5 Parameters - Parameters that will be passed to the program. // #6 WorkDir - The work directory for the program. // #7 IconPath - The full path to file containing the icon. // #8 IconIndex - For files containing multiple icons this is Index of the icon to use. // #9 WindowState - One of the following: // Normal - Start the program normally. // Minimized - Start the program minimized to the taskbar. // Maximized - Start the program maximized. // #10 Hotkey - Keyboard sequence used to active the shortcut. // #11 Tooltip - Tooltip Text // Return values..: // Author.........: Homes32 // Remarks........: PECMD: LINK {[!] {[_]|[^]}} <ShortcutPath>, <TargetPath>, [Parameters], [IconPath[#IconIndex]], [Tooltip], [WorkDir], [HotKey] // WindowState: ! - Hide, _ - Minimize, ^ - Maximize // // Shortcuts.exe: <ShortcutPath> | <Title> | <TargetPath> | [IconPath,IconIndex] | [Parameters] // // TODO: Shortcuts.exe needs to support all AddShortcut parameters. This requires rewriting a portion of shortcuts.exe // Related........: // =============================================================================================================================== [_PhoenixAPI_AddShortcut] System,SetLocal If,#1,Equal,"",Halt,"AddShortcut Syntax Error: The shortcut type was not specified." If,#3,Equal,"",Halt,"AddShortcut Syntax Error: The shortcut title was not specified." If,#4,Equal,"",Halt,"AddShortcut Syntax Error: The shortcut's ProgramExe was not specified." GetParam,1,%Type% GetParam,2,%Folder% GetParam,3,%Title% GetParam,4,%ProgramExe% GetParam,5,%Parameters% GetParam,6,%WorkDir% GetParam,7,%IconPath% GetParam,8,%IconIndex% GetParam,9,%WindowState% GetParam,10,%Hotkey% GetParam,11,%Tooltip% If,%_PhoenixAPI_ConfigMode%,Equal,PECMD,Begin If,%Folder%,Equal,".",Set,%Folder%,"" Else,Set,%Folder%,"\%Folder%" // Type If,%Type%,Equal,"Desktop",Set,%Cmd%,"LINK #$pDesktop#$p\%Title%#$c%ProgramExe%#$c%Parameters%" Else,If,%Type%,Equal,"StartMenu",Set,%Cmd%,"LINK #$pPrograms#$p%Folder%\%Title%#$c%ProgramExe%#$c%Parameters%" Else,Halt,"AddShortcut Syntax Error: Shortcut type [%Type%] is not supported." // Window State If,%WindowState%,Equal,"Minimized",Set,%Cmd%,"_%Cmd%" Else,If,%WindowState%,Equal,"Maximized",Set,%Cmd%,"^%Cmd%" Else,Set,%WindowState%,"" // Icon If,Not,%IconPath%,Equal,"",Begin Set,%Cmd%,"%Cmd%#$c%IconPath%" If,Not,%IconIndex%,Equal,"",Set,%Cmd%,"%Cmd%##%IconIndex%" End Else,Set,%Cmd%,"%Cmd%#$c" // Tooltip If,Not,%Tooltip%,Equal,"",Set,%Cmd%,"%Cmd%#$c%Tooltip%" Else,Set,%Cmd%,"%Cmd%#$c" // WorkDir If,Not,%WorkDir%,Equal,"",Set,%Cmd%,"%Cmd%#$c%WorkDir%" // Hotkey If,Not,%Hotkey%,Equal,"",Set,%Cmd%,"%Cmd%#$c%HotKey%" // Final LINK command TXTReplace,"%TargetSystem32%\pecmd.ini","_END Shortcuts","%Cmd%#$x#$x_END Shortcuts" End Else,Begin // Shortcuts.exe // Window State If,Not,%WindowState%,Equal,"",Echo,"Warning: Shortcuts.exe does not support the <WindowState> argument for AddShortcut.",Warn // Icon If,Not,%IconIndex%,Equal,"",Set,%Icon%,"%IconPath%#$c%IconIndex%" Else,Set,%Icon%,%IconPath% // Tooltip If,Not,%Tooltip%,Equal,"",Echo,"Warning: Shortcuts.exe does not support the <Tooltip> argument for AddShortcut.",Warn // WorkDir If,Not,%WorkDir%,Equal,"",Echo,"Warning: Shortcuts.exe does not support the <WorkDir> argument for AddShortcut.",Warn // Hotkey If,%Hotkey%,Not,Equal,"",Echo,"Warning: Shortcuts.exe does not support the <Hotkey> argument for AddShortcut.",Warn // Final Cfg Entry If,%Type%,Equal,"Desktop",IniWriteTextLine,%TargetSystem32%\PhoenixPE.cfg,Shortcut,"%Folder%|%Title%|%ProgramExe%|%Icon%|%Parameters%" If,%Type%,Equal,"StartMenu",IniWriteTextLine,%TargetSystem32%\PhoenixPE.cfg,Shortcut,"%Folder%|%Title%|%ProgramExe%|%Icon%|%Parameters%" Else,Halt,"AddShortcut Syntax Error: Shortcut type [%Type%] is not supported." End System,EndLocal [_PhoenixAPI_PinShortcut] // =============================================================================================================================== // Name...........: PinShortcut // Description....: Pin a shortcut to the taskbar or start menu. // Syntax.........: PinShortcut,<Location>,<Position>,<ProgramExe> // Parameters.....: #1 Location // StartMenu - Pin to the start menu. // Taskbar - Pin to the taskbar. // #2 Position // Auto - (Default) Automatically determine the pin position. // 1-99 - Pin the shortcut to a specific position [0-99]. // #3 ProgramExe - The full path to the program to be executed. // Return values..: // Author.........: Homes32 // Remarks........: This macro relies on PinUtil.exe to perform the actual pinning at boot. // Normally Pins cannot target an executable located on removable media. To get around this restriction // we trick Windows by creating a symlink on the ramdrive (B:\) to the Y:\Programs folder. // PECMD takes care of the symlink creation on boot, so here we only need to point Pintool to B:\ instead of Y:\ // Related........: Depends on %ProjectDir%\Components\330-ImDisk.script for Ramdisk drive letter // =============================================================================================================================== [_PhoenixAPI_PinShortcut] System,SetLocal If,#1,Equal,"",Halt,"PinShortcut Syntax Error: Pin location was not specified." If,#2,Equal,"",Halt,"PinShortcut Syntax Error: Pin position was not specified." If,#3,Equal,"",Halt,"PinShortcut Syntax Error: Program Executable was not specified." GetParam,1,%PinLocation% GetParam,2,%PinPos% GetParam,3,%ProgramExe% If,Not,%PinLocation%,Equal,"StartMenu",If,Not,%PinLocation%,Equal,"Taskbar",Halt,"PinShortcut Syntax Error: [%PinLocation%] is not a valid pin location." If,%PinPos%,Equal,"Auto",Begin // Find an unused pin position Loop,%Api%,__PhoenixAPI_PinShortcut_FindOpenPos_Loop,0,99,"%TargetSystem32%\pecmd.ini","PinUtil",%PinLocation% Set,%PinPos%,#r End Else,If,%PinPos%,Smaller,0,Halt,"PinShortcut Syntax Error: [%PinPos%] is not a value from [0-99]." Else,If,%PinPos%,Bigger,99,Halt,"PinShortcut Syntax Error: [%PinPos%] is not a value from [0-99]." If,%PinPos%,Equal,-1,Begin Echo,"PinShortcut Warning: Could not find an open [%PinLocation%] position for [%ProgramExe%].",Warn // Return without doing anything. End Else,Begin // Check if user specified position will be overwritten IniReadSection,"%TargetSystem32%\pecmd.ini","PinUtil",%IniSection% List,Pos,%IniSection%,%PinLocation%%PinPos%,%Index% If,Not,%Index%,Equal,0,Begin IniRead,"%TargetSystem32%\pecmd.ini","PinUtil",%PinLocation%%PinPos%,%ExistingExe% Echo,"PinShortcut Warning: Existing pin for [%ExistingExe%] in [%PinLocation%] position [%PinPos%] will be overwritten by [%ProgramExe%].",Warn End // Work around pin restrictions on removable media ReadInterface,Value,"%ProjectDir%\Components\330-ImDisk.script",Interface,cmb_DriveLetter,%RamDisk% StrFormat,Replace,%ProgramExe%,"Y:\","%RamDisk%\",%ProgramExe% IniWrite,"%TargetSystem32%\pecmd.ini","PinUtil",%PinLocation%%PinPos%,%ProgramExe% End System,EndLocal [#__PhoenixAPI_PinShortcut_FindOpenPos_Loop#] // =============================================================================================================================== // Name...........: PinShortcut_FindOpenPos_Loop // Description....: Loop to // Syntax.........: PinShortcut_FindOpenPos_Loop,<FilePath>,<Section>,<PinLocation> // Parameters.....: #1 FilePath - Path to the config file // #2 Section - Section in the config file // #3 PinLocation - Location of Pin [StartMenu | Taskbar] // Return values..: #r - Success: Returns an int specifying the first open position found // Failure: Returns -1 indicating no open positions were found // Author.........: Homes32 // Remarks........: Internal Function // Related........: PinShortcut // =============================================================================================================================== [__PhoenixAPI_PinShortcut_FindOpenPos_Loop] System,SetLocal IniRead,#1,#2,#3#c,%CurrentPos% If,%CurrentPos%,Equal,"",Begin Set,#r,#c Loop,Break End Else,Set,#r,-1 System,EndLocal [#_PhoenixAPI_RunFromRam#] // =============================================================================================================================== // Name...........: RunFromRam // Description....: Choose to redirect the programs folder to Boot.wim // // This macro works by overwriting the GLOBAL %TargetPrograms% and %PEPrograms% with // local variables that redirect to boot.wim instead of the boot media. // Syntax.........: RunFromRam // Parameters.....: // Return values..: // Author.........: Homes32 // Remarks........: Do not use System,SetLocal here. For this macro to work it must run in the scope of the calling script. // Related........: // =============================================================================================================================== [_PhoenixAPI_RunFromRam] Set,%TargetPrograms%,"%TargetDir%\Program Files" Set,%PEPrograms%,"X:\Program Files" [#_PhoenixAPI_DirDeleteEx#] // =============================================================================================================================== // Name...........: DirDeleteEx // Description....: Delete a directory if it exists. If the DirDelete commands fails, for example if a file or folder is open in another // application or Explorer then give the user a meaningful error message and a chance to correct the problem. // if that doesn't work halt the build. // Syntax.........: DirDeleteEx,<Directory> // Parameters.....: #1 Directory - The full path to the directory to delete. // Return values..: // Author.........: Homes32 // Remarks........: // Related........: // =============================================================================================================================== [_PhoenixAPI_DirDeleteEx] If,#1,Equal,"",Halt,"Syntax Error: Directory was not specified." System,ErrorOff If,ExistDir,#1,DirDelete,#1 // If Dir still exists wait a few more seconds to give async tasks time to complete before we bother the user... If,ExistDir,#1,Wait,5 If,ExistDir,#1,Begin If,Question,"Error: The specified folder could not be deleted.#$x#$x#1#$x#$xPlease make sure there are no files open in other applications (eg. Text Editor/vmWare/VirtualBox), registry hives are unloaded, and you do not have the directory open in Explorer.#$x#$xRetry?",Begin // User clicked 'Yes' System,ErrorOff If,ExistDir,#1,Begin DirDelete,#1 // Wait a few seconds to give async tasks time to complete... Wait,5 End If,ExistDir,#1,Begin Message,"Error: The specified folder could not be deleted.#$x#$x#1#$x#$xPlease make sure there are no files open in other applications (eg. Text Editor/vmWare/VirtualBox), registry hives are unloaded, and you do not have the directory open in Explorer then try building again.",Error Halt,"Error: The specified folder could not be deleted." End End Else,Begin // User clicked 'No' Halt,"Error: The specified folder could not be deleted." End End [#_PhoenixAPI_FileDeleteEx#] // =============================================================================================================================== // Name...........: FileDeleteEx // Description....: Delete a file if it exists. If the FileDelete commands fails, for example if a file is open in another // application, then give the user a meaningful error message and a chance to correct the problem. // if that doesn't work halt the build. // Syntax.........: DirDeleteEx,<File> // Parameters.....: #1 File - The full path to the file to delete. // Return values..: // Author.........: Homes32 // Remarks........: // Related........: // =============================================================================================================================== [_PhoenixAPI_FileDeleteEx] If,#1,Equal,"",Halt,"Syntax Error: File was not specified." System,ErrorOff If,ExistFile,#1,FileDelete,#1 If,ExistFile,#1,Begin If,Question,"Error: The specified file could not be deleted.#$x#$x#1#$x#$xPlease make sure the file is not running or in use by another application (eg. Text Editor/vmWare/VirtualBox).#$x#$xRetry?",Begin // User clicked 'Yes' Wait,3 System,ErrorOff If,ExistFile,#1,FileDelete,#1 If,ExistFile,#1,Begin Message,"Error: The specified file could not be deleted.#$x#$x#1#$x#$xPlease make sure the file is not running or in use by another application (eg. Text Editor/vmWare/VirtualBox) then try building again.",Error Halt,"Error: The specified file could not be deleted." End End Else,Begin // User clicked 'No' Halt,"Error: The specified file could not be deleted." End End [#_PhoenixAPI_ApplyBitMask#] // =============================================================================================================================== // Name...........: ApplyBitMask // Description....: Apply a bitmask to a hex value in a binary string. // Syntax.........: ApplyBitMask,<BitArray>,<BitGroup>,<BitMask>[,BitSize] // Parameters.....: #1 BitArray - A comma separated string of bits in hex format. // #2 BitGroup - The specific group of bits to manipulate. This is determined by the 1-based index of the bit group // supplied by <BitArray>. Example: In order to apply a mask to the value 'DB' in // <BitArray> 01,DB,1A,4C we would specify a <BitGroup> of 2. // #3 BitMask - The hexadecimal bitmask to apply to the specified <BitGroup>. Ex. 0x000020 // #4 BitSize - (Optional) Specify the bitsize (8,16,32,64) used. Default is 32. // Return values..: #r - Returns <BitArray> with the specified bitmask applied. // Author.........: Homes32 // Remarks........: // Related........: // =============================================================================================================================== [_PhoenixAPI_ApplyBitMask] System,SetLocal GetParam,1,%BitArray% GetParam,2,%BitGroup% GetParam,3,%BitMask% GetParam,4,%BitSize% If,%BitArray%,Equal,"",Halt,"ApplyBitMask Syntax Error: You must specify a bit array." If,%BitGroup%,Equal,"",Halt,"ApplyBitMask Syntax Error: You must specify the bit group in order to apply a mask." If,%BitMask%,Equal,"",Halt,"ApplyBitMask Syntax Error: You must specify the bitmask to apply." If,%BitSize%,Equal,"",Begin Echo,"ApplyBitMask Warning: BitSize was not specified. Assuming it's a 32bit integer.",WARN Set,%BitSize%,32 End List,Get,%BitArray%,%BitGroup%,%Bits%,Delim=#$c Math,BitOr,%Bits%,0x%Bits%,%BitMask% // Back to Hex for our return value Math,Hex,%Hex%,%Bits%,%BitSize% StrFormat,LTRIM,%Hex%,2,%Hex% List,Set,%BitArray%,%BitGroup%,%Hex%,Delim=#$c Set,#r,%BitArray% System,EndLocal [#_PhoenixAPI_BitClear#] // =============================================================================================================================== // Name...........: BitClear // Description....: Clear a specific bit in a binary string. // Syntax.........: BitClear,<BitArray>,<BitGroup>,<BitPosition>[,BitSize] // Parameters.....: #1 BitArray - A comma separated string of bits in hex format. // #2 BitGroup - The specific group of bits to manipulate. This is determined by the 1-based index of the bit group // supplied by <BitArray>. Example: In order to clear a bit in the value 'DB' in // <BitArray> 01,DB,1A,4C we would specify a <BitGroup> of 2. // #3 BitPosition - The binary position to modify. (0-based Right to Left) // #4 BitSize - (Optional) Specify the bitsize (8,16,32,64) used. Default is 32. // Return values..: #r - Returns <BitArray> with the specified bit cleared. // Author.........: Homes32 // Remarks........: BitGroup &= ~(1 << BitPosition); // Take OR of <BitGroup> and 1 shifted <BitPosition> positions negated // Related........: // =============================================================================================================================== [_PhoenixAPI_BitClear] System,SetLocal GetParam,1,%BitArray% GetParam,2,%BitGroup% GetParam,3,%BitPosition% GetParam,4,%BitSize% If,%BitArray%,Equal,"",Halt,"BitClear Syntax Error: You must specify a bit array." If,%BitGroup%,Equal,"",Halt,"BitClear Syntax Error: You must specify the bit group in order clear a bit." If,%BitPosition%,Equal,"",Halt,"BitClear Syntax Error: You must specify the position of the bit to clear." If,%BitSize%,Equal,"",Begin Echo,"BitClear Warning: BitSize was not specified. Assuming it's a 32bit integer.",WARN Set,%BitSize%,32 End List,Get,%BitArray%,%BitGroup%,%Bits%,Delim=#$c Math,BitShift,%BitMask%,1,LEFT,%BitPosition%,%BitSize% Math,BitNot,%BitMask%,%BitMask%,%BitSize% Math,BitAnd,%Bits%,0x%Bits%,%BitMask% // Back to Hex for our return value Math,Hex,%Hex%,%Bits%,%BitSize% StrFormat,LTRIM,%Hex%,2,%Hex% List,Set,%BitArray%,%BitGroup%,%Hex%,Delim=#$c Set,#r,%BitArray% System,EndLocal [#_PhoenixAPI_BitSet#] // =============================================================================================================================== // Name...........: BitSet // Description....: Set a specific bit in a binary string. // Syntax.........: BitSet,<BitArray>,<BitGroup>,<BitPosition>[,BitSize] // Parameters.....: #1 BitArray - A comma separated string of bits in hex format. // #2 BitGroup - The specific group of bits to manipulate. This is determined by the 1-based index of the bit group // supplied by <BitArray>. Example: In order to set a bit in the value 'DB' in // <BitArray> 01,DB,1A,4C we would specify a <BitGroup> of 2. // #3 BitPosition - The binary position to modify. (0-based Right to Left) // #4 BitSize - (Optional) Specify the bitsize (8,16,32,64) used. Default is 32. // Return values..: #r - Returns <BitArray> with the specified bit set. // Author.........: Homes32 // Remarks........: BitGroup |= (1 << BitPosition); // Take OR of <BitGroup> and 1 shifted <BitPosition> positions // Related........: // =============================================================================================================================== [_PhoenixAPI_BitSet] System,SetLocal GetParam,1,%BitArray% GetParam,2,%BitGroup% GetParam,3,%BitPosition% GetParam,4,%BitSize% If,%BitArray%,Equal,"",Halt,"BitSet Syntax Error: You must specify a bit array." If,%BitGroup%,Equal,"",Halt,"BitSet Syntax Error: You must specify the bit group in order to set a bit." If,%BitPosition%,Equal,"",Halt,"BitSet Syntax Error: You must specify the position of the bit to set." If,%BitSize%,Equal,"",Begin Echo,"BitSet Warning: BitSize was not specified. Assuming it's a 32bit integer.",WARN Set,%BitSize%,32 End List,Get,%BitArray%,%BitGroup%,%Bits%,Delim=#$c Math,BitShift,%BitMask%,1,LEFT,%BitPosition%,%BitSize% Math,BitOr,%Bits%,0x%Bits%,%BitMask% // Back to Hex for our return value Math,Hex,%Hex%,%Bits%,%BitSize% StrFormat,LTRIM,%Hex%,2,%Hex% List,Set,%BitArray%,%BitGroup%,%Hex%,Delim=#$c Set,#r,%BitArray% System,EndLocal [#_PhoenixAPI_BitToggle#] // =============================================================================================================================== // Name...........: BitToggle // Description....: Set/Clear a specific bit in a binary string. // Syntax.........: BitToggle,<BitArray>,<BitGroup>,<BitPosition>[,BitSize] // Parameters.....: #1 BitArray - A comma separated string of bits in hex format. // #2 BitGroup - The specific group of bits to manipulate. This is determined by the 1-based index of the bit group // supplied by <BitArray>. Example: In order to toggle a bit in the value 'DB' in // <BitArray> 01,DB,1A,4C we would specify a <BitGroup> of 2. // #3 BitPosition - The binary position to modify. (0-based Right to Left) // #4 BitSize - (Optional) Specify the bitsize (8,16,32,64) used. Default is 32. // Return values..: #r - Returns <BitArray> with the specified bit flipped. // Author.........: Homes32 // Remarks........: BitGroup ^= (1 << BitPosition); // Take XOR of <BitGroup> and 1 shifted <BitPosition> positions // Related........: // =============================================================================================================================== [_PhoenixAPI_BitToggle] System,SetLocal GetParam,1,%BitArray% GetParam,2,%BitGroup% GetParam,3,%BitPosition% GetParam,4,%BitSize% If,%BitArray%,Equal,"",Halt,"BitToggle Syntax Error: You must specify a bit array." If,%BitGroup%,Equal,"",Halt,"BitToggle Syntax Error: You must specify the bit group in order to toggle a bit." If,%BitPosition%,Equal,"",Halt,"BitToggle Syntax Error: You must specify the position of the bit to toggle." If,%BitSize%,Equal,"",Begin Echo,"BitToggle Warning: BitSize was not specified. Assuming it's a 32bit integer.",WARN Set,%BitSize%,32 End List,Get,%BitArray%,%BitGroup%,%Bits%,Delim=#$c Math,BitShift,%BitMask%,1,LEFT,%BitPosition%,%BitSize% Math,BitXOr,%Bits%,0x%Bits%,%BitMask% // Back to Hex for our return value Math,Hex,%Hex%,%Bits%,%BitSize% StrFormat,LTRIM,%Hex%,2,%Hex% List,Set,%BitArray%,%BitGroup%,%Hex%,Delim=#$c Set,#r,%BitArray% System,EndLocal [#_PhoenixAPI_XMLAdd#] // =============================================================================================================================== // Name...........: XMLAdd // Description....: Experimental wrapper for XmlStarlet - Add a new element/text/attribute to an XML file. // Syntax.........: XMLAdd,<Operation>,<XMLFile>,<XPath>,<Type>,<Name>[,<Value>] // Parameters.....: #1 Operation - Can be one of: // Insert - Insert a node at the the beginning of the XPath. // Append - Append a node to the end of the XPath. // Subnode - Add a new subnode to each XPath in the document. // #2 XMLFile - Full path to the .xml filed to edit. // #3 XPath - XPath (XML Path Language) query used to insert the Attribute/Element. // #4 Type - XPath type [elem|text|attr] // #5 Name - Value Name // #6 Value - (Optional) Value // Return values..: #r - Returns // Author.........: Homes32 // Remarks........: // http://xmlstar.sourceforge.net/doc/UG/xmlstarlet-ug.pdf // Related........: // =============================================================================================================================== [_PhoenixAPI_XMLAdd] System,SetLocal GetParam,1,%Operation% GetParam,2,%XMLFile% GetParam,3,%XPath% GetParam,4,%Type% GetParam,5,%Name% GetParam,6,%Value% If,%Operation%,Equal,"",Halt,"XMLAdd Syntax Error: You must specify an operation [insert|append|subnode]." If,Not,ExistFile,%XMLFile%,Halt,"XMLAdd Syntax Error: The file [%XMLFile%] does not exist." If,%XPath%,Equal,"",Halt,"XMLAdd Syntax Error: You must specify an XPath." If,%Type%,Equal,"",Halt,"XMLAdd Syntax Error: You must specify a type [elem|text|attr]." If,%Name%,Equal,"",Halt,"XMLAdd Syntax Error: You must specify a name." //ShellExecute,Hide,"%Tools%\x86\xml.exe","select --text --template --value-of #$q%XPath%/@%Name%#$q #$q%XMLFile%#$q" //If,Not,#r,Equal,0,Halt,"XMLAdd ERROR: Failed to query [%XPath%/@%Name%] from [%XMLFile%]." If,%Operation%,Equal,"Insert",Begin ShellExecute,Hide,"%Tools%\x86\xml.exe","edit --inplace --insert #$q%XPath%#$q --type #$q%Type%#$q --name #$q%Name%#$q --value #$q%Value%#$q #$q%XMLFile%#$q" If,Not,#r,Equal,0,Halt,"XMLAdd ERROR: Failed to insert value [%XPath%/%Name%: %Value%] to [%XMLFile%]." End Else,If,%Operation%,Equal,"Append",Begin ShellExecute,Hide,"%Tools%\x86\xml.exe","edit --inplace --append #$q%XPath%#$q --type #$q%Type%#$q --name #$q%Name%#$q --value #$q%Value%#$q #$q%XMLFile%#$q" If,Not,#r,Equal,0,Halt,"XMLAdd ERROR: Failed to append value [%XPath%/%Name%: %Value%] to [%XMLFile%]." End Else,If,%Operation%,Equal,"Subnode",Begin ShellExecute,Hide,"%Tools%\x86\xml.exe","edit --inplace --subnode #$q%XPath%#$q --type #$q%Type%#$q --name #$q%Name%#$q --value #$q%Value%#$q #$q%XMLFile%#$q" If,Not,#r,Equal,0,Halt,"XMLAdd ERROR: Failed to add subnode value [%XPath%/%Name%: %Value%] to [%XMLFile%]." End Else,Halt,"XMLAdd Syntax Error: You must specify an valid operation [insert|append|subnode]." System,EndLocal [#_PhoenixAPI_XMLDelete#] // =============================================================================================================================== // Name...........: XMLDelete // Description....: Experimental wrapper for XmlStarlet - Delete an XML path/value. // Syntax.........: XMLDelete,<XMLFile>,<XPath> // Parameters.....: #1 XMLFile - Full path to the .xml filed to edit. // #2 XPath - XPath (XML Path Language) query used to locate the Attribute/Element to delete. // Return values..: #r - Returns // Author.........: Homes32 // Remarks........: http://xmlstar.sourceforge.net/doc/UG/xmlstarlet-ug.pdf // Related........: // =============================================================================================================================== [_PhoenixAPI_XMLDelete] System,SetLocal GetParam,1,%XMLFile% GetParam,2,%XPath% If,Not,ExistFile,%XMLFile%,Halt,"XMLDelete Syntax Error: The file [%XMLFile%] does not exist." If,%XPath%,Equal,"",Halt,"XMLDelete Syntax Error: You must specify an XPath." //ShellExecute,Hide,"%Tools%\x86\xml.exe","select --text --template --value-of #$q%XPath%#$q #$q%XMLFile%#$q" //If,Not,#r,Equal,0,Halt,"XMLDelete ERROR: Failed to query [%XPath%] from [%XMLFile%]." ShellExecute,Hide,"%Tools%\x86\xml.exe","edit --inplace --delete #$q%XPath%#$q #$q%XMLFile%#$q" If,Not,#r,Equal,0,Halt,"XMLDelete ERROR: Failed to delete [%XPath%] from [%XMLFile%]." System,EndLocal [#_PhoenixAPI_XMLRename#] // =============================================================================================================================== // Name...........: XMLRename // Description....: Experimental wrapper for XmlStarlet - Rename a value in an XML file. // Syntax.........: XMLRename,<XMLFile>,<XPath>,<Value> // Parameters.....: #1 XMLFile - Full path to the .xml filed to edit. // #2 XPath - XPath (XML Path Language) query used to locate the Attribute/Element to rename. // #3 Value - New Value // Return values..: #r - Returns // Author.........: Homes32 // Remarks........: The XPath must exist in order for the value to be Renamed. // http://xmlstar.sourceforge.net/doc/UG/xmlstarlet-ug.pdf // Related........: // =============================================================================================================================== [_PhoenixAPI_XMLRename] System,SetLocal GetParam,1,%XMLFile% GetParam,2,%XPath% GetParam,3,%Value% If,Not,ExistFile,%XMLFile%,Halt,"XMLRename Syntax Error: The file [%XMLFile%] does not exist." If,%XPath%,Equal,"",Halt,"XMLRename Syntax Error: You must specify an XPath." If,%Value%,Equal,"",Halt,"XMLRename Syntax Error: You must specify a value." //ShellExecute,Hide,"%Tools%\x86\xml.exe","select --text --template --value-of #$q%XPath%#$q #$q%XMLFile%#$q" //If,Not,#r,Equal,0,Halt,"XMLRename ERROR: Failed to query [%XPath%] from [%XMLFile%]." ShellExecute,Hide,"%Tools%\x86\xml.exe","edit --inplace --rename #$q%XPath%#$q --value #$q%Value%#$q #$q%XMLFile%#$q" If,Not,#r,Equal,0,Halt,"XMLRename ERROR: Failed to write value [%XPath%: %Value%] to [%XMLFile%]." System,EndLocal [#_PhoenixAPI_XMLUpdate#] // =============================================================================================================================== // Name...........: XMLUpdate // Description....: Update the value of an existing Attribute/Element // Syntax.........: XMLUpdate,<XMLFile>,<XPath>,<Value>,[NOERR] // Parameters.....: #1 XMLFile - Full path to the .xml filed to edit. // #2 XPath - XPath (XML Path Language) query used to locate the Attribute/Element to update. // #3 Value - New Value // #4 NOERR - Don't Halt on errors. (Use if you intend to handle errors yourself). // Return values..: #r - Returns: 0 - Success // 1 - Failure // 2 - Invalid Arguments // 3 - Invalid XML File // 4 - Library Exception // 5 - Internal Error // -99999999 - XPath does not exist // Author.........: Homes32 // Remarks........: The XPath must exist in order for the value to be updated. // http://xmlstar.sourceforge.net/doc/UG/xmlstarlet-ug.pdf // Related........: // =============================================================================================================================== [_PhoenixAPI_XMLUpdate] System,SetLocal GetParam,1,%XMLFile% GetParam,2,%XPath% GetParam,3,%Value% GetParam,4,%NOERR% If,Not,ExistFile,%XMLFile%,Halt,"XMLUpdate Syntax Error: The file [%XMLFile%] does not exist." If,%XPath%,Equal,"",Halt,"XMLUpdate Syntax Error: You must specify an XPath." If,%Value%,Equal,"",Halt,"XMLUpdate Syntax Error: You must specify a value." ShellExecute,Hide,"%Tools%\x86\xml.exe","select --text --template --value-of #$q%XPath%#$q #$q%XMLFile%#$q" If,Not,#r,Equal,0,Begin If,Not,%NOERR%,Equal,"NOERR",Halt,"XMLUpdate ERROR: Failed to query [%XPath%] from [%XMLFile%]. The XPath must exist in order for the value to be updated." Set,#r,-99999999 // Return End Else,Begin ShellExecute,Hide,"%Tools%\x86\xml.exe","edit --inplace --update #$q%XPath%#$q --value #$q%Value%#$q #$q%XMLFile%#$q" If,Not,#r,Equal,0,Halt,"XMLUpdate ERROR: Failed to write value [%XPath%: %Value%] to [%XMLFile%]." End System,EndLocal