esd ---> iso script (Testing in progress)

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Message
Author
Squashman
Expert
Posts: 4484
Joined: 23 Dec 2011 13:59

Re: esd ---> iso script (Work in Progress)

#61 Post by Squashman » 26 Sep 2016 06:58

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.

Squashman
Expert
Posts: 4484
Joined: 23 Dec 2011 13:59

Re: esd ---> iso script (Work in Progress)

#62 Post by Squashman » 26 Sep 2016 07:03

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
Posts: 136
Joined: 08 Dec 2011 12:14

Re: esd ---> iso script (Work in Progress)

#63 Post by balubeto » 26 Sep 2016 09:11

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):


Even this change does not work. Why?

Thanks

Bye

Squashman
Expert
Posts: 4484
Joined: 23 Dec 2011 13:59

Re: esd ---> iso script (Work in Progress)

#64 Post by Squashman » 26 Sep 2016 09:42

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.

balubeto
Posts: 136
Joined: 08 Dec 2011 12:14

Re: esd ---> iso script (Work in Progress)

#65 Post by balubeto » 26 Sep 2016 10:49

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.


If I run this script:

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


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

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: esd ---> iso script (Work in Progress)

#66 Post by foxidrive » 26 Sep 2016 11:32

Are you attempting to check if the input is upper case and 0-9 and _
If so then try this code out:

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


The repeat variable allows a certain number of attempts before giving another message.
As a personal preference I've changed added text lines in the way I'd clarify the message to the readers.

Squashman
Expert
Posts: 4484
Joined: 23 Dec 2011 13:59

Re: esd ---> iso script (Work in Progress)

#67 Post by Squashman » 26 Sep 2016 12:11

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


I told you why in this post.
viewtopic.php?p=49285#p49276

penpen
Expert
Posts: 2009
Joined: 23 Jun 2013 06:15
Location: Germany

Re: esd ---> iso script (Work in Progress)

#68 Post by penpen » 26 Sep 2016 16:12

balubeto wrote:Where did I go wrong?
1.: You have removed too many lines (or better one line), this one:

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 :eof


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.
It may seem so, but balubeto has removed the important line for that part (see above under 1.: set "label= !label!").
(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

Edit: Corrected the first "quote.name".

Squashman
Expert
Posts: 4484
Joined: 23 Dec 2011 13:59

Re: esd ---> iso script (Work in Progress)

#69 Post by Squashman » 26 Sep 2016 19:39

Thanks Penpen. Hard to keep track of all the code he takes from you and changes it without understanding it.

balubeto
Posts: 136
Joined: 08 Dec 2011 12:14

Re: esd ---> iso script (Testing in progress)

#70 Post by balubeto » 27 Sep 2016 09:22

penpen wrote:
penpen wrote:Where did I go wrong?
1.: You have removed too many lines (or better one line), this one:

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 :eof


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.
It may seem so, but balubeto has removed the important line for that part (see above under 1.: set "label= !label!").
(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


Perfect.

Now, I have allowed also enter lowercase letters in this way:

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


I do not know how to edit it to make sure that the script prevents the user to enter an empty label. You could do to see how I can do this?

Thanks

Bye

penpen
Expert
Posts: 2009
Joined: 23 Jun 2013 06:15
Location: Germany

Re: esd ---> iso script (Testing in progress)

#71 Post by penpen » 27 Sep 2016 12:39

Replacing the following lines:

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= "
        )

With these line, should do that:

Code: Select all

   if "!iso_Volume_Label!" == " " set "invalid=Empty labels not allowed."


penpen

balubeto
Posts: 136
Joined: 08 Dec 2011 12:14

Re: esd ---> iso script (Testing in progress)

#72 Post by balubeto » 31 Oct 2016 03:44

I resumed my project, and I realized that I have a problem:

In this script

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


the IsoFile routine works.

While, in the script

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


the isoFileExist routine does not work. Where did I go wrong?

Thanks

Bye

penpen
Expert
Posts: 2009
Joined: 23 Jun 2013 06:15
Location: Germany

Re: esd ---> iso script (Testing in progress)

#73 Post by penpen » 31 Oct 2016 09:26

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":

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
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,
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
Posts: 136
Joined: 08 Dec 2011 12:14

Re: esd ---> iso script (Testing in progress)

#74 Post by balubeto » 31 Oct 2016 09:44

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":

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
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,
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


Excuse me but I can not understand how it is the correct full script.

Thanks

Bye

Squashman
Expert
Posts: 4484
Joined: 23 Dec 2011 13:59

Re: esd ---> iso script (Testing in progress)

#75 Post by Squashman » 31 Oct 2016 09:53

balubeto wrote:
Excuse me but I can not understand how it is the correct full script.

Thanks

Bye

What do you not understand about fixing problems 1 and 2? That is basic syntax that you should already understand.

Post Reply