balubeto wrote:Your fix works but now I found that the script always 'eats' a letter:
There is only one line of code in the program that is doing a substring with the SET command. Should be pretty obvious.
Moderator: DosItHelp
balubeto wrote:Your fix works but now I found that the script always 'eats' a letter:
penpen wrote:Code: Select all
if not defined invalid if not "!label:~33!" == "" set "invalid=More than 32 characters are not allowed for the volume label."
Code: Select all
C:\Users\Squashman\Desktop>so.bat "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567"
label: "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567"
Press any key to continue . . .
C:\Users\Squashman\Desktop>so.bat "ABCDEFGHIJKLMNOPQRSTUVWXYZ12345678"
Please enter a valid volume label (UDF 1.02 volume identifier):
Squashman wrote:penpen wrote:Code: Select all
if not defined invalid if not "!label:~33!" == "" set "invalid=More than 32 characters are not allowed for the volume label."
The set command is an offset. This means you are removing the first 33 characters and testing everything after that. This needs to be changed to 32.Code: Select all
C:\Users\Squashman\Desktop>so.bat "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567"
label: "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567"
Press any key to continue . . .
C:\Users\Squashman\Desktop>so.bat "ABCDEFGHIJKLMNOPQRSTUVWXYZ12345678"
Please enter a valid volume label (UDF 1.02 volume identifier):
balubeto wrote:Even this change does not work. Why?
Thanks
Bye
Squashman wrote:balubeto wrote:Even this change does not work. Why?
Thanks
Bye
What does not work? You are replying to a comment I was making to Penpen so I have no idea what does not work.
Code: Select all
@echo off
setlocal enableExtensions disableDelayedExpansion
call :setValidLabel "iso_Volume_Label" "%~1"
echo label: "%iso_Volume_Label%"
endlocal
goto :eof
:setValidLabel
:: %~1 variable to set
:: %~2 default value; MUST be in format "label:name"
setlocal disableDelayedExpansion
set "iso_Volume_Label=%~2"
set "first=1"
:validateLabel
set "invalid="
setlocal enableDelayedExpansion
if defined first (
if "!label!" == " " ( set "invalid=Null labels not allowed: Empty labels must be set using "label:"."
) else if "!label!" == " label:" set "label= "
)
if not defined invalid if not "!iso_Volume_Label:~32!" == "" set "invalid=More than 31 characters are not allowed for the volume label."
if not defined invalid for /F "tokens=1-2 delims=_0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" %%a in ("!iso_Volume_Label!") do (
setlocal disableDelayedExpansion
if not "%%~a" == " " (
endlocal
set "invalid=The only allowed characters are '_', '0', ... '9', 'A', ..., 'Z'."
) else if not "%%~b" == "" (
endlocal
set "invalid=The only allowed characters are '_', '0', ... '9', 'A', ..., 'Z'."
) else endlocal
)
endlocal & set "invalid=%invalid%" & ( if not defined invalid set "iso_Volume_Label=%iso_Volume_Label:~1%" )
if defined invalid (
if not defined first echo(%invalid%
set "first="
set "iso_Volume_Label="
set /p "iso_Volume_Label=Please enter a valid volume label (UDF 1.02 volume identifier): "
goto :validateLabel
)
endlocal & set "%~1=%iso_Volume_Label%"
goto :eof
Code: Select all
D:\Users\Public\Documents\balubeto\Test_script>Volume_label.bat "ABCDE"
label: "BCDE"
D:\Users\Public\Documents\balubeto\Test_script>Volume_label.bat
Please enter a valid volume label (UDF 1.02 volume identifier): MNOP
label: "NOP"
D:\Users\Public\Documents\balubeto\Test_script>
Code: Select all
@echo off
setlocal enabledelayedexpansion
set repeat=4
set "message=Please enter a valid volume label (UDF 1.02 volume identifier): "
set "message=Enter a UDF 1.02 volume label/identifier (using A to Z and 0 to 9 and _) : "
set "toolong=More than 31 characters are not allowed for the volume label."
set "invalid=The only allowed characters are '_', '0', ... '9', 'A', ..., 'Z'."
set "invalid=The only characters allowed are A to Z and 0 to 9 and _"
set "iso_Volume_Label="
for /L %%c in (1,1,%repeat%) do if not defined iso_Volume_Label (
set /p "iso_Volume_Label=%message%"
if defined iso_Volume_Label if not "!iso_Volume_Label:~32!" == "" echo %toolong% & set "iso_Volume_Label="
if defined iso_Volume_Label (
for /f "delims=_1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ" %%a in ("!iso_Volume_Label!|") do (
rem echo "%%a" "!iso_Volume_Label!"
if not "%%a"=="|" echo %invalid% & set "iso_Volume_Label="
))
if not defined iso_Volume_Label pause
)
if not defined iso_Volume_Label echo This is your sobriety test and you failed %repeat% times. & pause & goto :EOF
echo "%iso_Volume_Label%"& pause & goto :EOF
balubeto wrote:
If I run this script:
I always get:Code: Select all
D:\Users\Public\Documents\balubeto\Test_script>Volume_label.bat "ABCDE"
label: "BCDE"
D:\Users\Public\Documents\balubeto\Test_script>Volume_label.bat
Please enter a valid volume label (UDF 1.02 volume identifier): MNOP
label: "NOP"
D:\Users\Public\Documents\balubeto\Test_script>
Why?
Thanks
Bye
1.: You have removed too many lines (or better one line), this one:balubeto wrote:Where did I go wrong?
Code: Select all
set "label= !label!"
Code: Select all
@echo off
setlocal enableExtensions disableDelayedExpansion
call :setValidLabel "iso_Volume_Label" "%~1"
echo label: "%iso_Volume_Label%"
endlocal
goto :eof
:setValidLabel
:: %~1 variable to set
:: %~2 default value; MUST be in format "label:name"
setlocal disableDelayedExpansion
set "iso_Volume_Label=%~2"
set "first=1"
:validateLabel
set "invalid="
setlocal enableDelayedExpansion
set "iso_Volume_Label= !iso_Volume_Label!"
if defined first (
if "!iso_Volume_Label!" == " " ( set "invalid=Null labels not allowed: Empty labels must be set using "label:"."
) else if "!iso_Volume_Label!" == " label:" set "iso_Volume_Label= "
)
if not defined invalid if not "!iso_Volume_Label:~33!" == "" set "invalid=More than 32 characters are not allowed for the volume label."
if not defined invalid for /F "tokens=1-2 delims=_0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" %%a in ("!iso_Volume_Label!") do (
setlocal disableDelayedExpansion
if not "%%~a" == " " (
endlocal
set "invalid=The only allowed characters are '_', '0', ... '9', 'A', ..., 'Z'."
) else if not "%%~b" == "" (
endlocal
set "invalid=The only allowed characters are '_', '0', ... '9', 'A', ..., 'Z'."
) else endlocal
)
endlocal & set "invalid=%invalid%" & ( if not defined invalid set "iso_Volume_Label=%iso_Volume_Label:~1%" )
if defined invalid (
if not defined first echo(%invalid%
set "first="
set "iso_Volume_Label="
set /p "iso_Volume_Label=Please enter a valid volume label (UDF 1.02 volume identifier): "
goto :validateLabel
)
endlocal & set "%~1=%iso_Volume_Label%"
goto :eof
It may seem so, but balubeto has removed the important line for that part (see above under 1.: set "label= !label!").Squashman wrote:penpen wrote:Code: Select all
if not defined invalid if not "!label:~33!" == "" set "invalid=More than 32 characters are not allowed for the volume label."
The set command is an offset. This means you are removing the first 33 characters and testing everything after that. This needs to be changed to 32.
penpen wrote:1.: You have removed too many lines (or better one line), this one:penpen wrote:Where did I go wrong?Code: Select all
set "label= !label!"
2. You have renamed the "label" variable to "iso_Volume_Label".
So the fix is easy:Code: Select all
@echo off
setlocal enableExtensions disableDelayedExpansion
call :setValidLabel "iso_Volume_Label" "%~1"
echo label: "%iso_Volume_Label%"
endlocal
goto :eof
:setValidLabel
:: %~1 variable to set
:: %~2 default value; MUST be in format "label:name"
setlocal disableDelayedExpansion
set "iso_Volume_Label=%~2"
set "first=1"
:validateLabel
set "invalid="
setlocal enableDelayedExpansion
set "iso_Volume_Label= !iso_Volume_Label!"
if defined first (
if "!iso_Volume_Label!" == " " ( set "invalid=Null labels not allowed: Empty labels must be set using "label:"."
) else if "!iso_Volume_Label!" == " label:" set "iso_Volume_Label= "
)
if not defined invalid if not "!iso_Volume_Label:~33!" == "" set "invalid=More than 32 characters are not allowed for the volume label."
if not defined invalid for /F "tokens=1-2 delims=_0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" %%a in ("!iso_Volume_Label!") do (
setlocal disableDelayedExpansion
if not "%%~a" == " " (
endlocal
set "invalid=The only allowed characters are '_', '0', ... '9', 'A', ..., 'Z'."
) else if not "%%~b" == "" (
endlocal
set "invalid=The only allowed characters are '_', '0', ... '9', 'A', ..., 'Z'."
) else endlocal
)
endlocal & set "invalid=%invalid%" & ( if not defined invalid set "iso_Volume_Label=%iso_Volume_Label:~1%" )
if defined invalid (
if not defined first echo(%invalid%
set "first="
set "iso_Volume_Label="
set /p "iso_Volume_Label=Please enter a valid volume label (UDF 1.02 volume identifier): "
goto :validateLabel
)
endlocal & set "%~1=%iso_Volume_Label%"
goto :eofIt may seem so, but balubeto has removed the important line for that part (see above under 1.: set "label= !label!").Squashman wrote:penpen wrote:Code: Select all
if not defined invalid if not "!label:~33!" == "" set "invalid=More than 32 characters are not allowed for the volume label."
The set command is an offset. This means you are removing the first 33 characters and testing everything after that. This needs to be changed to 32.
(I added this line to be sure substring also will work on an empty environment variable and won't produce a "~33" string part.)
@foxidrive
Nice shortening of the "for/F" part, and the outer for/L loop with an additional error message is a nice ide, too^^.
penpen
Code: Select all
@echo off
setlocal enableExtensions disableDelayedExpansion
call :setValidLabel "iso_Volume_Label" "%~1"
echo label: "%iso_Volume_Label%"
endlocal
goto :eof
:setValidLabel
:: %~1 variable to set
:: %~2 default value; MUST be in format "label:name"
setlocal disableDelayedExpansion
set "iso_Volume_Label=%~2"
set "first=1"
:validateLabel
set "invalid="
setlocal enableDelayedExpansion
set "iso_Volume_Label= !iso_Volume_Label!"
if defined first (
if "!iso_Volume_Label!" == " " ( set "invalid=Null labels not allowed: Empty labels must be set using "label:"."
) else if "!iso_Volume_Label!" == " label:" set "iso_Volume_Label= "
)
if not defined invalid if not "!iso_Volume_Label:~33!" == "" set "invalid=More than 32 characters are not allowed for the volume label."
if not defined invalid for /F "tokens=1-2 delims=_0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" %%a in ("!iso_Volume_Label!") do (
setlocal disableDelayedExpansion
if not "%%~a" == " " (
endlocal
set "invalid=The only allowed characters are '_', '0', ... '9', 'a', ..., 'z', 'A', ..., 'Z'."
) else if not "%%~b" == "" (
endlocal
set "invalid=The only allowed characters are '_', '0', ... '9', 'a', ..., 'z', 'A', ..., 'Z'."
) else endlocal
)
endlocal & set "invalid=%invalid%" & ( if not defined invalid set "iso_Volume_Label=%iso_Volume_Label:~1%" )
if defined invalid (
if not defined first echo(%invalid%
set "first="
set "iso_Volume_Label="
set /p "iso_Volume_Label=Please enter a valid volume label (UDF 1.02 volume identifier): "
goto :validateLabel
)
endlocal & set "%~1=%iso_Volume_Label%"
goto :eof
Code: Select all
if defined first (
if "!iso_Volume_Label!" == " " ( set "invalid=Null labels not allowed: Empty labels must be set using "label:"."
) else if "!iso_Volume_Label!" == " label:" set "iso_Volume_Label= "
)
Code: Select all
if "!iso_Volume_Label!" == " " set "invalid=Empty labels not allowed."
Code: Select all
@echo off
setlocal enableExtensions disableDelayedExpansion
call :setValidPath "iso_Path" "%~1" "Enter the directory in which put the iso image file created:" "absolutePath" "mayExist" "directory" "--"
call :IsoFile "%iso_Path%" "%~2"
echo iso_Path : "%iso_Path%"
echo iso_File : "%iso_File%"
endlocal
goto :eof
:setValidPath
:: %~1 variable to set
:: %~2 default value
:: %~3 text if default value is invalid
:: %~4 Text equals: (forced to relativePath if %~6 equals file)
:: absolutePath if path must be absolute
:: relativePath if path must be relative
:: anyPath if path may be relative or absolute (any other value)
:: %~5 Text equals: (forced to mayExist if %~8 does not exist)
:: mustExist if file/directory must exist,
:: doesntExist if file/directory is not allowed to exist.
:: mayExist if file/directory may or may not exist (any other value).
:: %~6 Text equals:
:: file if object to test is a file
:: directory if object to test is a directory (any other value).
:: %~7 Text equals: (only checked if file/directory exists)
:: r check read access for specified file/directory
:: w check write access for specified file/directory
:: rw check read and write access for specified file/directory
:: - check no access for specified file/directory (any other value)
:: directory if object to test is a directory (any other value).
:: Note: testing write access on a directory creates a file "test.tmp"
:: %~8 Only if /I %~6 == "file": environment variable with an path to store the file to
:: (forced to empty word, if %~6 equals directory).
::
setlocal
set "firstTime=1"
set "input=%~2"
set "text=%~3"
if "%~4" == "absolutePath" ( set "pathType=%~4"
) else if "%~4" == "relativePath" ( set "pathType=%~4"
) else set "existType=anyPath"
if "%~5" == "mustExist" ( set "existType=%~5"
) else if "%~5" == "doesntExist" ( set "existType=%~5"
) else set "existType=mayExist"
setlocal enableDelayedExpansion
set "parent= "
if "%~6" == "file" (
set "parent= !%~8!"
if not "!parent:~-1!" == ":" (
set "parent=!parent!\"
if "!parent:~-2!" == "\\" set "parent=!parent:~0,-1!"
)
)
endlocal & set "parent=%parent:~1%"
if "%~6" == "file" (
set "fileType=file"
set "pathType=relativePath"
if defined parent (
if not exist "%parent%" set "existType=mayExist"
) else set "existType=mayExist"
) else set "fileType=directory"
if "%~7" == "r" ( set "checkAccess=r-"
) else if "%~7" == "w" ( set "checkAccess=-w"
) else if "%~7" == "rw" ( set "checkAccess=rw"
) else ( set "checkAccess=--"
)
:validatePath
:: validating
set "invalid="
call :isValidPathName "input" || goto :invalidatedPath
if /I "%pathType%" == "absolutePath" ( call :isAbsolutePathName "input" || ( set "invalid=Path must be absolute" & goto :invalidatedPath )
) else if /I "%pathType%" == "relativePath" ( call :isAbsolutePathName "input" && ( set "invalid=Path must be relative" & goto :invalidatedPath ) || >&2 >nul (echo @maybe: replace "<volume label>:" in !input!)
)
setlocal enableExtensions enableDelayedExpansion
set "input=!parent!!input!"
if /I "%existType%" == "mustExist" ( if not exist "!input!" ( endlocal & set "invalid=Path must exist." & goto :invalidatedPath )
) else if /I "%existType%" == "doesntExist" ( if exist "!input!" ( endlocal & set "invalid=Path must be non existent." & goto :invalidatedPath )
)
if exist "!input!" for %%b in ("!input!") do (
set "attribs=%%~ab"
if /I "%fileType%" == "file" (
if not "!attribs:d=!" == "!attribs!" (
endlocal & set "invalid=Path must denote a file (not a directory)." & goto :invalidatedPath
) else (
if "%checkAccess:~0,1%" == "r" (
2>nul <"!input!" set /p "check=" || (
for %%a in ("!input!") do if "%%~za" == "0" (
>&2 echo(Warning: Could not verify read access: Reason filesize of "!input!" is 0.
) else (
endlocal & set "invalid=No read access (wanted)." & goto :invalidatedPath
)
)
) else if "%checkAccess:~1,1%" == "w" 2>nul (
>"!input!" <nul set /p "check=" || ( endlocal & set "invalid=No write access (wanted)." & goto :invalidatedPath )
)
)
) else (
if "!attribs:d=!" == "!attribs!" (
endlocal & set "invalid=Path must denote a directory (not a file)." & goto :invalidatedPath
) else (
if "%checkAccess:~0,1%" == "r" 2>nul (
>nul dir "!input!" || ( endlocal & set "invalid=No read access (wanted)." & goto :invalidatedPath )
)
if "%checkAccess:~1,1%" == "w" 2>nul (
>nul pushd "!input!"
>"test.tmp" echo test || ( >nul popd & endlocal & set "invalid=No write access (wanted)." & goto :invalidatedPath )
>nul del "test.tmp" || ( >nul popd & endlocal & set "invalid=No write access (wanted)." & goto :invalidatedPath )
>nul popd
)
)
)
)
endlocal
endlocal & set "%~1=%input%"
goto :eof
:invalidatedPath
if defined invalid echo(Invalid: %invalid%
set /P ^"input=%text:""="% "
goto :validatePath
goto :eof
:: Check if the pathname follows mainly the naming convention:
:: https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx
:: Exceptions:
:: - Only a drive descriptor (for example "C:") is allowed for volume names.
:: - Not tested if characters 0x00-0x31, or any other forbidden character (of the target filesystem) are present. (disallowed)
:: - Not tested on alternative data streams
:isValidPathName
:: %~1 environment variable containing the path to test.
setlocal enableExtensions enableDelayedExpansion
set "pathName=!%~1!"
set "invalid="
if not defined invalid if "!pathName!" == "" if defined firstTime (exit /b 1 & goto :test) else set "invalid=The pathname cannot be empty." & set "pathName= "
if not defined invalid for /f tokens^=1^*^ delims^=^/^<^>^|^*^?^" %%a in ("#!pathName!#") do if not "%%~b" == "" set "invalid=Invalid character found."
if not defined invalid set ^"pathname=!pathname:"=!"
if not defined invalid (
set "pathName= !pathName:/=\!"
>nul echo @maybe:set "pathName= !pathName:\..\=\!"
>nul echo @maybe:set "pathName= !pathName:\.\=\!"
>nul echo @maybe:if "%pathName:~-3%" == "\.." set "pathName= !pathName:~0,-3!"
>nul echo @maybe:if "%pathName:~-2%" == "\." set "pathName= !pathName:~0,-2!"
)
if not defined invalid if not "!pathName:\\=__!" == "!pathname!" set "invalid=Empty string is no valid path component."
if not defined invalid if "!pathName:~1,1!" == ":" (
for /f "tokens=1* delims=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" %%a in ("#!pathName:~0,1!#") do if not "%%~a" == "#" set "invalid=Invalid drive name."
set "pathName=!pathName:~2!"
)
if not defined invalid 2>nul (
echo(\!pathname!\|>nul findstr /I /R /C:"[\\]AUX[\\]" /C:"[\\]CON[\\]" /C:"[\\]NUL[\\]" /C:"[\\]PRN[\\]" /C:"[\\]COM[0-9][\\]" /C:"[\\]LPT[0-9][\\]" && (
set "invalid=The following names are not allowed for file/directory names: CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, and LPT9."
)
)
if not defined invalid 2>nul (
echo(\!pathname!\|>nul findstr /R /C:"[\ ][\\]" /C:"[\.][\\]" && (
set "invalid=It is not allowed to end file/directory names with a space (' ') or a period ('.') character."
)
)
if not defined invalid (
endlocal
exit /b 0
) else (
endlocal & set "invalid=%invalid%"
exit /b 1
)
goto :eof
:: Using mainly the definition of the Windows Shell API, see:
:: https://msdn.microsoft.com/en-us/library/windows/desktop/bb773660(v=vs.85).aspx
:: Exception:
:: - Only accepts a drive descriptor (for example "C:") is allowed for volume names.
::
:: does not check validity (must be valid)
:isAbsolutePathName
:: %~1 environment variable containing the path to test.
setlocal enableExtensions enableDelayedExpansion
if not "!%~1:~1,2!" == ":\" (
endlocal
exit /b 1
) else (
endlocal
exit /b 0
)
goto :eof
:IsoFile
call :setValidPath "iso_File" "%~2" "Enter the iso file that will be saved in the %iso_Path% directory:" "relativePath" "mayExist" "file" "-w" "iso_Path"
call
if exist "%~1\%iso_File%" choice /M "Iso File exists; overwrite it? " /C:YN
if not "%errorlevel%" == "1" (
if "%errorlevel%" == "0" echo(
call :IsoFile "%~1" ""
)
goto :eof
Code: Select all
@echo off
setlocal enableExtensions disableDelayedExpansion
call :setValidPath "iso_Path" "%~1" "Enter the directory in which put the iso image file created:" "absolutePath" "mayExist" "directory" "--"
call :IsoFile "%iso_Path%" "%~2" "%~3" "%~4"
echo iso_Path : "%iso_Path%"
echo iso_File : "%iso_File%"
echo iso_Volume_Label : "%iso_Volume_Label%"
echo Timestamp : "%Timestamp%"
endlocal
goto :eof
:setValidPath
:: %~1 variable to set
:: %~2 default value
:: %~3 text if default value is invalid
:: %~4 Text equals: (forced to relativePath if %~6 equals file)
:: absolutePath if path must be absolute
:: relativePath if path must be relative
:: anyPath if path may be relative or absolute (any other value)
:: %~5 Text equals: (forced to mayExist if %~8 does not exist)
:: mustExist if file/directory must exist,
:: doesntExist if file/directory is not allowed to exist.
:: mayExist if file/directory may or may not exist (any other value).
:: %~6 Text equals:
:: file if object to test is a file
:: directory if object to test is a directory (any other value).
:: %~7 Text equals: (only checked if file/directory exists)
:: r check read access for specified file/directory
:: w check write access for specified file/directory
:: rw check read and write access for specified file/directory
:: - check no access for specified file/directory (any other value)
:: directory if object to test is a directory (any other value).
:: Note: testing write access on a directory creates a file "test.tmp"
:: %~8 Only if /I %~6 == "file": environment variable with an path to store the file to
:: (forced to empty word, if %~6 equals directory).
::
setlocal
set "firstTime=1"
set "input=%~2"
set "text=%~3"
if "%~4" == "absolutePath" ( set "pathType=%~4"
) else if "%~4" == "relativePath" ( set "pathType=%~4"
) else set "existType=anyPath"
if "%~5" == "mustExist" ( set "existType=%~5"
) else if "%~5" == "doesntExist" ( set "existType=%~5"
) else set "existType=mayExist"
setlocal enableDelayedExpansion
set "parent= "
if "%~6" == "file" (
set "parent= !%~8!"
if not "!parent:~-1!" == ":" (
set "parent=!parent!\"
if "!parent:~-2!" == "\\" set "parent=!parent:~0,-1!"
)
)
endlocal & set "parent=%parent:~1%"
if "%~6" == "file" (
set "fileType=file"
set "pathType=relativePath"
if defined parent (
if not exist "%parent%" set "existType=mayExist"
) else set "existType=mayExist"
) else set "fileType=directory"
if "%~7" == "r" ( set "checkAccess=r-"
) else if "%~7" == "w" ( set "checkAccess=-w"
) else if "%~7" == "rw" ( set "checkAccess=rw"
) else ( set "checkAccess=--"
)
:validatePath
:: validating
set "invalid="
call :isValidPathName "input" || goto :invalidatedPath
if /I "%pathType%" == "absolutePath" ( call :isAbsolutePathName "input" || ( set "invalid=Path must be absolute" & goto :invalidatedPath )
) else if /I "%pathType%" == "relativePath" ( call :isAbsolutePathName "input" && ( set "invalid=Path must be relative" & goto :invalidatedPath ) || >&2 >nul (echo @maybe: replace "<volume
label>:" in !input!)
)
setlocal enableExtensions enableDelayedExpansion
set "input=!parent!!input!"
if /I "%existType%" == "mustExist" ( if not exist "!input!" ( endlocal & set "invalid=Path must exist." & goto :invalidatedPath )
) else if /I "%existType%" == "doesntExist" ( if exist "!input!" ( endlocal & set "invalid=Path must be non existent." & goto :invalidatedPath )
)
if exist "!input!" for %%b in ("!input!") do (
set "attribs=%%~ab"
if /I "%fileType%" == "file" (
if not "!attribs:d=!" == "!attribs!" (
endlocal & set "invalid=Path must denote a file (not a directory)." & goto :invalidatedPath
) else (
if "%checkAccess:~0,1%" == "r" (
2>nul <"!input!" set /p "check=" || (
for %%a in ("!input!") do if "%%~za" == "0" (
>&2 echo(Warning: Could not verify read access: Reason filesize of "!input!" is 0.
) else (
endlocal & set "invalid=No read access (wanted)." & goto :invalidatedPath
)
)
) else if "%checkAccess:~1,1%" == "w" 2>nul (
>"!input!" <nul set /p "check=" || ( endlocal & set "invalid=No write access (wanted)." & goto :invalidatedPath )
)
)
) else (
if "!attribs:d=!" == "!attribs!" (
endlocal & set "invalid=Path must denote a directory (not a file)." & goto :invalidatedPath
) else (
if "%checkAccess:~0,1%" == "r" 2>nul (
>nul dir "!input!" || ( endlocal & set "invalid=No read access (wanted)." & goto :invalidatedPath )
)
if "%checkAccess:~1,1%" == "w" 2>nul (
>nul pushd "!input!"
>"test.tmp" echo test || ( >nul popd & endlocal & set "invalid=No write access (wanted)." & goto :invalidatedPath )
>nul del "test.tmp" || ( >nul popd & endlocal & set "invalid=No write access (wanted)." & goto :invalidatedPath )
>nul popd
)
)
)
)
endlocal
endlocal & set "%~1=%input%"
goto :eof
:invalidatedPath
if defined invalid echo(Invalid: %invalid%
set /P ^"input=%text:""="% "
goto :validatePath
goto :eof
:: Check if the pathname follows mainly the naming convention:
:: https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx
:: Exceptions:
:: - Only a drive descriptor (for example "C:") is allowed for volume names.
:: - Not tested if characters 0x00-0x31, or any other forbidden character (of the target filesystem) are present. (disallowed)
:: - Not tested on alternative data streams
:isValidPathName
:: %~1 environment variable containing the path to test.
setlocal enableExtensions enableDelayedExpansion
set "pathName=!%~1!"
set "invalid="
if not defined invalid if "!pathName!" == "" if defined firstTime (exit /b 1 & goto :test) else set "invalid=The pathname cannot be empty." & set "pathName= "
if not defined invalid for /f tokens^=1^*^ delims^=^/^<^>^|^*^?^" %%a in ("#!pathName!#") do if not "%%~b" == "" set "invalid=Invalid character found."
if not defined invalid set ^"pathname=!pathname:"=!"
if not defined invalid (
set "pathName= !pathName:/=\!"
>nul echo @maybe:set "pathName= !pathName:\..\=\!"
>nul echo @maybe:set "pathName= !pathName:\.\=\!"
>nul echo @maybe:if "%pathName:~-3%" == "\.." set "pathName= !pathName:~0,-3!"
>nul echo @maybe:if "%pathName:~-2%" == "\." set "pathName= !pathName:~0,-2!"
)
if not defined invalid if not "!pathName:\\=__!" == "!pathname!" set "invalid=Empty string is no valid path component."
if not defined invalid if "!pathName:~1,1!" == ":" (
for /f "tokens=1* delims=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" %%a in ("#!pathName:~0,1!#") do if not "%%~a" == "#" set "invalid=Invalid drive name."
set "pathName=!pathName:~2!"
)
if not defined invalid 2>nul (
echo(\!pathname!\|>nul findstr /I /R /C:"[\\]AUX[\\]" /C:"[\\]CON[\\]" /C:"[\\]NUL[\\]" /C:"[\\]PRN[\\]" /C:"[\\]COM[0-9][\\]" /C:"[\\]LPT[0-9][\\]" && (
set "invalid=The following names are not allowed for file/directory names: CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5,
LPT6, LPT7, LPT8, and LPT9."
)
)
if not defined invalid 2>nul (
echo(\!pathname!\|>nul findstr /R /C:"[\ ][\\]" /C:"[\.][\\]" && (
set "invalid=It is not allowed to end file/directory names with a space (' ') or a period ('.') character."
)
)
if not defined invalid (
endlocal
exit /b 0
) else (
endlocal & set "invalid=%invalid%"
exit /b 1
)
goto :eof
:: Using mainly the definition of the Windows Shell API, see:
:: https://msdn.microsoft.com/en-us/library/windows/desktop/bb773660(v=vs.85).aspx
:: Exception:
:: - Only accepts a drive descriptor (for example "C:") is allowed for volume names.
::
:: does not check validity (must be valid)
:isAbsolutePathName
:: %~1 environment variable containing the path to test.
setlocal enableExtensions enableDelayedExpansion
if not "!%~1:~1,2!" == ":\" (
endlocal
exit /b 1
) else (
endlocal
exit /b 0
)
goto :eof
:IsoFile
call :setValidPath "iso_File" "%~2" "Enter the iso file (in the UDF 1.02 format) that will be saved in the %iso_Path% directory:" "relativePath" "mayExist" "file" "-w" "iso_Path"
call :isoFileExist "%~1" "%~2"
call :setValidLabel "iso_Volume_Label" "%~3"
call :ValidTimestamp "Timestamp" "%~4" "Enter a timestamp ('mm/dd/yyyy,hh:mm:ss') for all files and directories in the %iso_File% : "
:isoFileExist
call
if exist "%~1\%iso_File%" choice /M "Iso File exists; overwrite it? " /C:YN
if not "%errorlevel%" == "1" (
if "%errorlevel%" == "0" echo(
call :IsoFile "%~1" ""
)
goto :eof
:ValidTimestamp
:: Caution!
:: This function creates two subdirectories "dummy\empty".
:: Don't use these directories!
:: These directories were deleted automatically.
:: %~1 environment variable to store the timestamp to
:: %~2 predefined timestamp value to test
:: %~3 text that is displayed to ask for the timestamp value
if "%~1" == "" echo missing parameter & exit /b 1
if not exist "dummy\empty" md "dummy\empty"
setlocal enableExtensions enableDelayedExpansion
set "ts=%~2"
if not defined ts set /P "ts=%~3"
(
set "ts"
) | (
>nul findstr /R /C:"^ts=../../....,[0-1][0-9]:[0-5][0-9]:[0-5][0-9]$" /C:"^ts=../../....,2[0-3]:[0-5][0-9]:[0-5][0-9]$"
) && (
2>nul xcopy /d:!ts:~0,10! /t "dummy\empty" "dummy"
) && (
rd /s /q dummy
endlocal & set "%~1=%ts%"
exit /b 0
)
echo Invalid timestamp: !ts!.
endlocal
if not "%~2" == "" (
call :ValidTimestamp "%~1" "" "%~3"
exit /b
)
goto :ValidTimestamp
:setValidLabel
:: %~1 variable to set
:: %~2 default value; MUST be in format "label:name"
setlocal disableDelayedExpansion
set "iso_Volume_Label=%~2"
set "first=1"
:validateLabel
set "invalid="
setlocal enableDelayedExpansion
set "iso_Volume_Label= !iso_Volume_Label!"
if "!iso_Volume_Label!" == " " set "invalid=Empty labels not allowed."
if not defined invalid if not "!iso_Volume_Label:~33!" == "" set "invalid=More than 32 characters are not allowed for the volume label."
if not defined invalid for /F "tokens=1-2 delims=_0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" %%a in ("!iso_Volume_Label!") do (
setlocal disableDelayedExpansion
if not "%%~a" == " " (
endlocal
set "invalid=The only allowed characters are '_', '0', ... '9', 'a', ..., 'z', 'A', ..., 'Z'."
) else if not "%%~b" == "" (
endlocal
set "invalid=The only allowed characters are '_', '0', ... '9', 'a', ..., 'z', 'A', ..., 'Z'."
) else endlocal
)
endlocal & set "invalid=%invalid%" & ( if not defined invalid set "iso_Volume_Label=%iso_Volume_Label:~1%" )
if defined invalid (
if not defined first echo(%invalid%
set "first="
set "iso_Volume_Label="
set /p "iso_Volume_Label=Please enter a valid volume label (UDF 1.02 volume identifier): "
goto :validateLabel
)
endlocal & set "%~1=%iso_Volume_Label%"
goto :eof
Code: Select all
) else if /I "%pathType%" == "relativePath" ( call :isAbsolutePathName "input" && ( set "invalid=Path must be relative" & goto :invalidatedPath ) || >&2 >nul (echo @maybe: replace "<volume
label>:" in !input!)
Code: Select all
set "invalid=The following names are not allowed for file/directory names: CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5,
LPT6, LPT7, LPT8, and LPT9."
Code: Select all
call :isoFileExist "%~1" "%~2"
call :setValidLabel "iso_Volume_Label" "%~3"
call :ValidTimestamp "Timestamp" "%~4" "Enter a timestamp ('mm/dd/yyyy,hh:mm:ss') for all files and directories in the %iso_File% : "
:isoFileExist
penpen wrote:On a first look, i can see you have added 3 changes (all are errors).
1: You have inserted line endings within the following echo command:Code: Select all
) else if /I "%pathType%" == "relativePath" ( call :isAbsolutePathName "input" && ( set "invalid=Path must be relative" & goto :invalidatedPath ) || >&2 >nul (echo @maybe: replace "<volume
label>:" in !input!)
2. You have inserted line endings within the following set command:Code: Select all
set "invalid=The following names are not allowed for file/directory names: CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5,
LPT6, LPT7, LPT8, and LPT9."
3. You have inserted the following code into the function ":isoFile":I'm not sure what you have planned to do, but you should notice, that every time the user (of this program) has a file, that she/he is not willing to overwrite,Code: Select all
call :isoFileExist "%~1" "%~2"
call :setValidLabel "iso_Volume_Label" "%~3"
call :ValidTimestamp "Timestamp" "%~4" "Enter a timestamp ('mm/dd/yyyy,hh:mm:ss') for all files and directories in the %iso_File% : "
:isoFileExist
the inserted code is executed an additional time:
I doubt this is your plan.
In addition you also have to add an "goto :eof" in a line before the label ":isoFileExist", else you again check a file that has been checked (and approved by user) before (probably confusing the user).
Another error is, that you are using "%~4" which is always empty (because you haven't set in when executing 'call ":IsoFile" ...' in the main routine).
I recommend you to remove that part from the subroutine, and add it to the main code (where it was before - if i remember right) again.
penpen
balubeto wrote:
Excuse me but I can not understand how it is the correct full script.
Thanks
Bye