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

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

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

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

#46 Post by penpen » 17 Sep 2016 18:26

balubeto wrote:At this point, I found this document http://www.osta.org/specs/pdf/udf102.pdf , but I found nothing on the volume label validity.

Since it seems to me impossible that there is nothing on the topic, you may look at this pdf as you are more experienced than me?
The udf1.02 label is noted as a "VolumeIdentifier" in your linked pdf-file.
But there is only the information that its maximum length is 32 characters (as we knew before).
Because of that i assume it has the same restrictions than the previous CD file systems.
So the following characters should be the only allowed ones (and used 0-32 times):
'_', '0', ... '9', 'A', ..., 'Z'

Under that assumption, the following may help you:

Code: Select all

@echo off
setlocal enableExtensions disableDelayedExpansion

call :setValidLabel "label" "%~1"

echo label: "%label%"

endlocal
endlocal
goto :eof

:setValidLabel
:: %~1   variable to set
:: %~2   default value
   setlocal disableDelayedExpansion
   set "label=%~2"
   set "first=1"

:validateLabel
   set "invalid="

   setlocal enableDelayedExpansion
   set "label= !label!"
   if not "!label:~33!" == "" set "invalid=More than 32 characters are not allowed for the volume label."
   for /F "delims=_0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" %%a in ("!label!") do (
      setlocal disableDelayedExpansion
      if not "%%~a" == " " (
         endlocal
         set "invalid=The only allowed characters are '_', '0', ... '9', 'A', ..., 'Z'."
      ) else endlocal
   )
   endlocal & set "invalid=%invalid%"

   if defined invalid (
      if not defined first echo(%invalid%
      set "first="
      set "label="
      set /p "label=Please enter a valid volume label (UDF 1.02 volume identifier): "
      goto :validateLabel
   )
   endlocal & set "%~1=%label%"
   goto :eof


penpen

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

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

#47 Post by Squashman » 17 Sep 2016 19:42

balubeto wrote:Now, I should solve the old problem on the volume label:

Yes you should instead of having others do everything for you.

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

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

#48 Post by balubeto » 19 Sep 2016 01:01

penpen wrote:
balubeto wrote:At this point, I found this document http://www.osta.org/specs/pdf/udf102.pdf , but I found nothing on the volume label validity.

Since it seems to me impossible that there is nothing on the topic, you may look at this pdf as you are more experienced than me?
The udf1.02 label is noted as a "VolumeIdentifier" in your linked pdf-file.
But there is only the information that its maximum length is 32 characters (as we knew before).
Because of that i assume it has the same restrictions than the previous CD file systems.
So the following characters should be the only allowed ones (and used 0-32 times):
'_', '0', ... '9', 'A', ..., 'Z'

Under that assumption, the following may help you:

Code: Select all

@echo off
setlocal enableExtensions disableDelayedExpansion

call :setValidLabel "label" "%~1"

echo label: "%label%"

endlocal
endlocal
goto :eof

:setValidLabel
:: %~1   variable to set
:: %~2   default value
   setlocal disableDelayedExpansion
   set "label=%~2"
   set "first=1"

:validateLabel
   set "invalid="

   setlocal enableDelayedExpansion
   set "label= !label!"
   if not "!label:~33!" == "" set "invalid=More than 32 characters are not allowed for the volume label."
   for /F "delims=_0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" %%a in ("!label!") do (
      setlocal disableDelayedExpansion
      if not "%%~a" == " " (
         endlocal
         set "invalid=The only allowed characters are '_', '0', ... '9', 'A', ..., 'Z'."
      ) else endlocal
   )
   endlocal & set "invalid=%invalid%"

   if defined invalid (
      if not defined first echo(%invalid%
      set "first="
      set "label="
      set /p "label=Please enter a valid volume label (UDF 1.02 volume identifier): "
      goto :validateLabel
   )
   endlocal & set "%~1=%label%"
   goto :eof


penpen


I wrote 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"
call :validateLabel   "%iso_Volume_Label%"     "%~3"  "Enter the volume label in the %iso_Path%\\%iso_File% : "

echo iso_Path          : "%iso_Path%"
echo iso_File          : "%iso_File%"
echo iso_Volume_Label  : "%iso_Volume_Label%"

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 in the UDF 1.02 format :"                         "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

:setValidLabel
:: %~1   variable to set
:: %~2   default value
   setlocal disableDelayedExpansion
   set "iso_Volume_Label=%~2"
   set "first=1"

:validateLabel
   set "invalid="

   setlocal enableDelayedExpansion
   set "iso_Volume_Label= !iso_Volume_Label!"
   if not "!iso_Volume_Label:~33!" == "" set "invalid=More than 32 characters are not allowed for the volume label."
   for /F "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 endlocal
   )
   endlocal & set "invalid=%invalid%"

   if defined invalid (
      if not defined first echo(%invalid%
      set "first="
      set "iso_Volume_Label="
      set /p "iso_Volume_Label="Enter the volume label in the %iso_Path%\\%iso_File% : "
      goto :validateLabel
   )
   endlocal & set "%~1=%iso_Volume_Label%"
   goto :eof


but, when I run it without arguments, the IsoFile routine is not executed. Why?

Thanks

Bye
Last edited by balubeto on 19 Sep 2016 10:36, edited 2 times in total.

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

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

#49 Post by penpen » 19 Sep 2016 06:12

balubeto wrote:but, when I run it without arguments, the IsoFile routine is not executed. Why?
I can't seee that.
The ":isoFile" routine is working just fine.

Could it be, that you've meant the function ":setValidLabel"?
This seems to do nothing, but because an empty label is valid, this works as intended.

One could change it to support en ampty string as a null value (and set a valuie using the notation "Label=str" while "str" is the desired label for that iso).


penpen

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

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

#50 Post by balubeto » 19 Sep 2016 10:11

penpen wrote:
balubeto wrote:but, when I run it without arguments, the IsoFile routine is not executed. Why?
I can't seee that.
The ":isoFile" routine is working just fine.

Could it be, that you've meant the function ":setValidLabel"?
This seems to do nothing, but because an empty label is valid, this works as intended.

One could change it to support en ampty string as a null value (and set a valuie using the notation "Label=str" while "str" is the desired label for that iso).


penpen


When I run this script the label request is not displayed as shown by this output:

Code: Select all

D:\Users\Public\Documents\Balubeto\Test_script>iso_file.bat
Enter the directory in which put the iso image file created:  D:\Users\Public\Documents\Balubeto\Test_script\iso
Enter the iso file that will be saved in the D:\Users\Public\Documents\Balubeto\Test_script\iso directory in the UDF 1.02 format : a.iso
Iso File exists; overwrite it? [Y,N]?Y
Syntax of the command is incorrect.
iso_Path          : "D:\Users\Public\Documents\Balubeto\Test_script\iso"
iso_File          : "a.iso"
iso_Volume_Label  : ""

D:\Users\Public\Documents\Balubeto\Test_script>iso_file.bat
Enter the directory in which put the iso image file created:  D:\Users\Public\Documents\Balubeto\Test_script\iso
Enter the iso file that will be saved in the D:\Users\Public\Documents\Balubeto\Test_script\iso directory in the UDF 1.02 format : f.iso
Syntax of the command is incorrect.
iso_Path          : "D:\Users\Public\Documents\Balubeto\Test_script\iso"
iso_File          : "f"
iso_Volume_Label  : ""

D:\Users\Public\Documents\Balubeto\Test_script>


How come?

I did not understand as I do to eliminate the setValidLabel routine continuing to manage also the empty labels.

Thanks

Bye

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

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

#51 Post by penpen » 19 Sep 2016 16:45

First, you should read my posts (and answer questions i had):
penpen wrote:Could it be, that you've meant the function ":setValidLabel"?
balubeto wrote:When I run this script the label request is not displayed
So the answer seems to be:
"Yes."


Second, i answered your question in my last post (which you quoted in the post right before you asked):
balubeto wrote:When I run this script the label request is not displayed as shown by this output:
(...)
How come?
penpen wrote:an empty label is valid
You've passed a valid label ("") to the function ":validateLabel".
=> This label is accepted by ":validateLabel".
=> There is no need to ask for another valid label.

And this is my suggestion how to solve this issue - all needed is the information whether you like this solution or not (maybe you have other suggestions):
penpen wrote:One could change it to support en ampty string as a null value (and set a valuie using the notation "Label=str" while "str" is the desired label for that iso).
This implementation solves your above issue, because in that case and empty label is represented by "Label:" while a null value (== no label specified) were an invalid value for the label and has this representation "".
(So this is an implicit question; one could also ask: "Shall i implement it this way?")


Beside that, i think there is a little flaw in your script - you used the variable content ("%iso_Volume_Label%") instead of its name ("iso_Volume_Label");
corrected line is as follows:

Code: Select all

call :validateLabel   "iso_Volume_Label"     "%~3"  "Enter the volume label in the %iso_Path%\\%iso_File% : "


penpen

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

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

#52 Post by balubeto » 20 Sep 2016 02:37

penpen wrote:First, you should read my posts (and answer questions i had):
penpen wrote:Could it be, that you've meant the function ":setValidLabel"?
balubeto wrote:When I run this script the label request is not displayed
So the answer seems to be:
"Yes."


Second, i answered your question in my last post (which you quoted in the post right before you asked):
balubeto wrote:When I run this script the label request is not displayed as shown by this output:
(...)
How come?
penpen wrote:an empty label is valid
You've passed a valid label ("") to the function ":validateLabel".
=> This label is accepted by ":validateLabel".
=> There is no need to ask for another valid label.

And this is my suggestion how to solve this issue - all needed is the information whether you like this solution or not (maybe you have other suggestions):
penpen wrote:One could change it to support en ampty string as a null value (and set a valuie using the notation "Label=str" while "str" is the desired label for that iso).
This implementation solves your above issue, because in that case and empty label is represented by "Label:" while a null value (== no label specified) were an invalid value for the label and has this representation "".
(So this is an implicit question; one could also ask: "Shall i implement it this way?")


Beside that, i think there is a little flaw in your script - you used the variable content ("%iso_Volume_Label%") instead of its name ("iso_Volume_Label");
corrected line is as follows:

Code: Select all

call :validateLabel   "iso_Volume_Label"     "%~3"  "Enter the volume label in the %iso_Path%\\%iso_File% : "


penpen


I deleted the setValidLabel routine and now the script is:

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"
call :validateLabel   "iso_Volume_Label"       "%~3"  "Enter the volume label in the %iso_Path%\\%iso_File% :"


echo iso_Path          : "%iso_Path%"
echo iso_File          : "%iso_File%"
echo iso_Volume_Label  : "%iso_Volume_Label%"

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 in the UDF 1.02 format :"                         "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

:validateLabel
   set "invalid="

   setlocal enableDelayedExpansion
   set "iso_Volume_Label= !iso_Volume_Label!"
   if not "!iso_Volume_Label:~33!" == "" set "invalid=More than 32 characters are not allowed for the volume label."
   for /F "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 endlocal
   )
   endlocal & set "invalid=%invalid%"

   if defined invalid (
      if not defined first echo(%invalid%
      set "first="
      set "iso_Volume_Label="
      set /p "iso_Volume_Label="Enter the volume label in the %iso_Path%\\%iso_File% :"
      goto :validateLabel
   )
   endlocal & set "%~1=%iso_Volume_Label%"
   goto :eof


I can not understand where I should put the "iso_Volume_Label=str" notation so that the validateLabel routine is able to also manage the empty labels?

Thanks and sorry again

Bye

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

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

#53 Post by penpen » 20 Sep 2016 06:48

balubeto wrote:I can not understand where I should put the "iso_Volume_Label=str" notation so that the validateLabel routine is able to also manage the empty labels?

Actually this is not implemented:
I don't want to implement it before i know you would accept such a solution.
(If you would say "NO, better do it this or that way", then i would have done useless work.)

If it once will be implemented you may call your "sample.bat" batch (above) using:

Code: Select all

:: using label "MayLabel"
call sample.bat "C:\isoPath" "isoFile.iso" "Label:MyLabel"
:: using (empty) label ""
call sample.bat "C:\isoPath" "isoFile.iso" "Label:"
:: using null label
call sample.bat "C:\isoPath" "isoFile.iso" ""
:: all params invalid
call sample.bat


penpen

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

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

#54 Post by balubeto » 20 Sep 2016 09:44

penpen wrote:
balubeto wrote:I can not understand where I should put the "iso_Volume_Label=str" notation so that the validateLabel routine is able to also manage the empty labels?

Actually this is not implemented:
I don't want to implement it before i know you would accept such a solution.
(If you would say "NO, better do it this or that way", then i would have done useless work.)

If it once will be implemented you may call your "sample.bat" batch (above) using:

Code: Select all

:: using label "MayLabel"
call sample.bat "C:\isoPath" "isoFile.iso" "Label:MyLabel"
:: using (empty) label ""
call sample.bat "C:\isoPath" "isoFile.iso" "Label:"
:: using null label
call sample.bat "C:\isoPath" "isoFile.iso" ""
:: all params invalid
call sample.bat


penpen


It is possible to create a single routine that also implements the management of an empty volume label and that asks the user to enter a label without that he should enter the "Label:" prefix? If so, how can I do this?

Thanks

Bye

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

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

#55 Post by penpen » 20 Sep 2016 13:09

balubeto wrote:I deleted the setValidLabel routine and now the script is:
I didn't notice it last time:
Why would you do that?

I noticed that my above code was Buggy.
Because of that i bugfixed it and applied the change i suggested:

Code: Select all

@echo off
setlocal enableExtensions disableDelayedExpansion

call :setValidLabel "label" "%~1"

echo label: "%label%"

endlocal
endlocal
goto :eof

:setValidLabel
:: %~1   variable to set
:: %~2   default value; MUST be in format "label:name"
   setlocal disableDelayedExpansion
   set "label=%~2"
   set "first=1"

:validateLabel
   set "invalid="

   setlocal enableDelayedExpansion
   set "label= !label!"
   if defined first (
      if /i not "!label:~1,6!" == "label:" ( set "invalid=Argument format mismatch"
      ) else set "label= !label:~7!"
   )
   if not defined invalid if not "!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 ("!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 "label=%label:~1%" )
   if defined invalid (
      if not defined first echo(%invalid%
      set "first="
      set "label="
      set /p "label=Please enter a valid volume label (UDF 1.02 volume identifier): "
      goto :validateLabel
   )
   endlocal & set "%~1=%label%"
   goto :eof


Sample call:

Code: Select all

Z:\>sample.bat "label:ABC"
label: "ABC"

Z:\>sample.bat "ABC"
Please enter a valid volume label (UDF 1.02 volume identifier): ABC
label: "ABC"

Z:\>sample.bat "Label:"
label: ""

Z:\>sample.bat ""
Please enter a valid volume label (UDF 1.02 volume identifier):
label: ""


penpen

Edit: Corrected one of the Outputs (was an old one).
Last edited by penpen on 21 Sep 2016 11:45, edited 1 time in total.

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

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

#56 Post by balubeto » 21 Sep 2016 09:14

penpen wrote:
balubeto wrote:I deleted the setValidLabel routine and now the script is:
I didn't notice it last time:
Why would you do that?

I noticed that my above code was Buggy.
Because of that i bugfixed it and applied the change i suggested:

Code: Select all

@echo off
setlocal enableExtensions disableDelayedExpansion

call :setValidLabel "label" "%~1"

echo label: "%label%"

endlocal
endlocal
goto :eof

:setValidLabel
:: %~1   variable to set
:: %~2   default value; MUST be in format "label:name"
   setlocal disableDelayedExpansion
   set "label=%~2"
   set "first=1"

:validateLabel
   set "invalid="

   setlocal enableDelayedExpansion
   set "label= !label!"
   if defined first (
      if /i not "!label:~1,6!" == "label:" ( set "invalid=Argument format mismatch"
      ) else set "label= !label:~7!"
   )
   if not defined invalid if not "!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 ("!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 "label=%label:~1%" )
   if defined invalid (
      if not defined first echo(%invalid%
      set "first="
      set "label="
      set /p "label=Please enter a valid volume label (UDF 1.02 volume identifier): "
      goto :validateLabel
   )
   endlocal & set "%~1=%label%"
   goto :eof


Sample call:

Code: Select all

Z:\>sample.bat "label:ABC"
label: "label:ABC"

Z:\>sample.bat "ABC"
Please enter a valid volume label (UDF 1.02 volume identifier): ABC
label: "ABC"

Z:\>sample.bat "Label:"
label: ""

Z:\>sample.bat ""
Please enter a valid volume label (UDF 1.02 volume identifier):
label: ""


penpen


Excuse me, but if I write the volume label on the command line (the second sample), the request of the script to re-enter this label is completely unnecessary. In other words, the request to enter a label will have to be displayed only when the script will run with no arguments.

Are you sure the UDF 1.02 format does not accept lowercase characters in the volume label?

Also, I noticed that the Oscdimg utility does not accept the null labels.

So, how can I modify this script?

Also, could you explain why you put twice the endlocal command in the main part of the script?

Thanks

Bye

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

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

#57 Post by penpen » 21 Sep 2016 12:43

balubeto wrote:Excuse me, but if I write the volume label on the command line (the second sample), the request of the script to re-enter this label is completely unnecessary. In other words, the request to enter a label will have to be displayed only when the script will run with no arguments.
Maybe my first example was very irritating:
This was an error the variable assignment/output is without the "label:".

It was an exemplary implementation only, but it should be better to use a consistent variable input format, else irritating users are only a matter of time.


balubeto wrote:Also, I noticed that the Oscdimg utility does not accept the null labels.
I think you mean empty labels (it just don't use the "label:XY" input format):
I bet oscdimg uses empty labels, if you dont use the the "-l" option.


balubeto wrote:Are you sure the UDF 1.02 format does not accept lowercase characters in the volume label?
penpen wrote:there is only the information that its maximum length is 32 characters (as we knew before).
Because of that i assume it has the same restrictions than the previous CD file systems.
So the following characters should be the only allowed ones (and used 0-32 times):
'_', '0', ... '9', 'A', ..., 'Z'
I'm not completely sure, but it's hard to believe that they have improved something (a part of ISO 9660), and had forgotten to mention it.


balubeto wrote:So, how can I modify this script?
Just replace the first "if defined first" code part (containing "invalid=Argument format mismatch") with:

Code: Select all

   if defined first (
      if "!label!" == " " ( set "invalid=Null labels not allowed: Empty labels must be set using "label:"."
      ) else if "!label!" == " label:" set "label= "
   )


balubeto wrote:Also, could you explain why you put twice the endlocal command in the main part of the script?
Just a copy paste error, but it should not harm anything.


penpen

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

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

#58 Post by balubeto » 25 Sep 2016 02:16

penpen wrote:
balubeto wrote:Excuse me, but if I write the volume label on the command line (the second sample), the request of the script to re-enter this label is completely unnecessary. In other words, the request to enter a label will have to be displayed only when the script will run with no arguments.
Maybe my first example was very irritating:
This was an error the variable assignment/output is without the "label:".

It was an exemplary implementation only, but it should be better to use a consistent variable input format, else irritating users are only a matter of time.


balubeto wrote:Also, I noticed that the Oscdimg utility does not accept the null labels.
I think you mean empty labels (it just don't use the "label:XY" input format):
I bet oscdimg uses empty labels, if you dont use the the "-l" option.


balubeto wrote:Are you sure the UDF 1.02 format does not accept lowercase characters in the volume label?
penpen wrote:there is only the information that its maximum length is 32 characters (as we knew before).
Because of that i assume it has the same restrictions than the previous CD file systems.
So the following characters should be the only allowed ones (and used 0-32 times):
'_', '0', ... '9', 'A', ..., 'Z'
I'm not completely sure, but it's hard to believe that they have improved something (a part of ISO 9660), and had forgotten to mention it.


balubeto wrote:So, how can I modify this script?
Just replace the first "if defined first" code part (containing "invalid=Argument format mismatch") with:

Code: Select all

   if defined first (
      if "!label!" == " " ( set "invalid=Null labels not allowed: Empty labels must be set using "label:"."
      ) else if "!label!" == " label:" set "label= "
   )


balubeto wrote:Also, could you explain why you put twice the endlocal command in the main part of the script?
Just a copy paste error, but it should not harm anything.


penpen


Your fix works but now I found that the script always 'eats' a letter:

Code: Select all

D:\Users\Public\Documents\Test_script>Volume_label.bat "HGLJ"
label: "GLJ"

D:\Users\Public\Documents\Test_script>Volume_label.bat
Please enter a valid volume label (UDF 1.02 volume identifier): LKJHH
label: "KJHH"

D:\Users\Public\Documents\Test_script>


How come?

Thanks

Bye

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

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

#59 Post by penpen » 25 Sep 2016 06:37

balubeto wrote:Your fix works but now I found that the script always 'eats' a letter:
(...)
How come?
I don't know:
I cannot see the code you are using.

If you apply the fix to my latest code, then this should not happen (tested under Win 10, 32/64 bit).


penpen

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

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

#60 Post by balubeto » 25 Sep 2016 09:59

penpen wrote:
balubeto wrote:Your fix works but now I found that the script always 'eats' a letter:
(...)
How come?
I don't know:
I cannot see the code you are using.

If you apply the fix to my latest code, then this should not happen (tested under Win 10, 32/64 bit).


penpen


Here:

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


Where did I go wrong?

Thanks

Bye

Post Reply