To read more about ADSs, google "Alternate Data Streams" and you will find information about it.
I created an API in batch to manipulate the ADSs easily. It was not very easy to write this extension because most commands in windows either don't support ADSs, or the ADSs use is limited. That's why the code can seem sometimes messy and unreadable, because I had to use different tricks that I could come up with to achieve different tasks.
All functions of the api are described inside the code. If anyone finds any bugs or suggests something for the code, write it under this topic.
ads.cmd:
Code: Select all
:ADS function args...
::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: ADS batch extension v1.0
:: By KKZiomek (c) 2017
::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: The first most complete API written using pure
:: batch for manipulation of Alternate Data Streams
:: and files that are containing them. Feel free to
:: use this code in any project, private or commercial,
:: but always keep this information box attached
:: with the code.
::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: To use any of the functions in this API, just
:: use "call :ADS function args...", where 'function'
:: is the name of API function, and 'args...' are
:: arguments specific to the function. The current
:: functions in this API are: clear, echo, write,
:: readToFile, appendToFile, readToVar, copy,
:: move, append, moveAppend, delete, rename.
:: DO NOT use "call :ADS_function rest..." but
:: "call :ADS function rest...". Notice that there is
:: a space instead of the '_' character. It is intended
:: even though function definitions have this character
:: in them. Specific arguments to a function can be
:: found with the label/function declaration.
:: The API doesn't support putting or reading binary
:: files to or from ADS's yet, but it will in future versions.
::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: YOU CAN DELETE THE REST OF THIS INFORMATION
:: BOX. IT IS JUST FOR REFERENCE FOR DEVELOPERS!
:: Function 'clear' clears a stream in a file.
:: Function 'echo' inputs a text to a stream.
:: Function 'write' inputs contents of a file into a stream.
:: The contents already in the stream are NOT overriden.
:: Function 'readToFile' outputs contents of a stream into
:: an outside file. Contents of the outside file are overriden.
:: Function 'appendToFile' appends contents of a stream into
:: an outside file. Contents of the outside file are NOT overriden.
:: Function 'readToVar' puts contents of a stream into
:: a variable of specified name. Newline characters are
:: ommited because there isn't a way to store a newline
:: character in batch in a variable, only to output it.
:: Function 'copy' copies contents from one stream to
:: another stream in the same file. The contents already
:: in the second stream are overriden.
:: Function 'move' moves contents from one stream to
:: another stream in the same file. The contents already
:: in the second stream are overriden.
:: Function 'append' appends contents of one stream to
:: another stream in the same file. The contents already
:: in the second stream are NOT overriden.
:: Function 'moveAppend' moves contents of one stream
:: to another stream by appending it. The contents already
:: in the second stream are NOT overriden.
:: Function 'delete' deletes a stream from a file completely.
:: Other streams in the same file are unaffected.
:: Function 'rename' renames a stream in a file to a new
:: name, but keeping the contents. Other streams in the
:: same file are unaffected.
::::::::::::::::::::::::::::::::::::::::::::::::::::::
set "$=goto:eof"
call:ADS_%*&%$%
:ADS_clear file streamname
if not exist %1 echo nul>%1
type nul>"%~1:%~2"&%$%
:ADS_echo file streamname content
if not exist %1 echo nul>%1
echo:%~3>>"%~1:%~2"&%$%
:ADS_write file streamname inputfile
if not exist %1 echo nul>%1
for /f usebackq %%# in ("%~3") do echo:%%#>>"%~1:%~2"
%$%
:ADS_readToFile file streamname outputfile
if not exist %3 echo nul>%3
more<"%~1:%~2">%3&%$%
:ADS_appendToFile file streamname outputfile
if not exist %3 echo nul>%3
more<"%~1:%~2">>%3&%$%
:ADS_readToVar file streamname variable_name
set %~3=
call:ADS_readToFile %1 %2 `
for /f usebackq %%# in ("`") do call set %~3=%%%~3%%%%#
del /q "`"&%$%
:ADS_copy file streamname1 streamname2
call:ADS_readToFile %1 %2 `
call:ADS_clear %1 %3
call:ADS_write %1 %3 `
del /q "`"&%$%
:ADS_move file streamname1 streamname2
call:ADS_copy %1 %2 %3
call:ADS_clear %1 %2
%$%
:ADS_append file streamname1 streamname2
call:ADS_readToFile %1 %2 `
call:ADS_write %1 %3 `
del /q "`"&%$%
:ADS_moveAppend file streamname1 streamname2
call:ADS_append %1 %2 %3
call:ADS_clear %1 %2
%$%
:ADS_delete file streamname
for /f "tokens=2 delims=: usebackq" %%# in (`dir /r ^| find "%~1:" ^| find ":$DATA" ^| find /v "%~2"`) do echo %%#>>`
if exist "`" (
md `strs`
waitfor /t 1 shortPause >nul 2>&1
for /f usebackq %%# in ("`") do call:ADS_readToFile %1 "%%#" "`strs`\%%#" )
for /f usebackq %%# in ("%~1") do echo:%%#>>"``"
del /q %1
waitfor /t 1 shortPause >nul 2>&1
for /f usebackq %%# in ("``") do echo:%%#>>"%~1"
del /q "``"
if exist "`" (
for /r `strs` %%# in (*) do call:ADS_write %1 "%%~nx#" "`strs`\%%~nx#"
del /q "`strs`\*"
rmdir "`strs`"
del /q "`" )
%$%
:ADS_rename file streamname newStreamname
call:ADS_readToFile %1 %2 ```
call:ADS_delete %1 %2
call:ADS_write %1 %3 ```
del /q "```"&%$%
KKZiomek