DVD functions: Difference between revisions

From NSIS Wiki
Jump to navigationJump to search
mNo edit summary
Line 71: Line 71:
     goto break
     goto break


   ;If no parameter was supplied at all, assume we're starting at A:\.
   ;If no parameter was supplied at all, assume we're starting at A:\ and set the "no parameters" flag.
   StrCmp $R1 "" 0 +4
   StrCmp $R1 "" 0 +4
     StrCpy $R1 "0"
     StrCpy $R1 "0"
     StrCpy $R4 "0"
     StrCpy $R4 "-1" ;no parameters flag. If $R4 is -1, it will never equal the current drive letter, thus the alphabet cycle check will never kick in
     goto loop
     goto loop
    
    
Line 119: Line 119:
       goto break
       goto break
     IntOp $R1 $R1 + 1        ;increment driveletter
     IntOp $R1 $R1 + 1        ;increment driveletter
     StrCmp $R1 26 0 +2      ;if >Z
     StrCmp $R1 26 0 loop    ;if >Z
       StrCpy $R1 0          ;  return to A
      StrCmp $R4 "-1" 0 +3  ;  if there were no parameters
    goto loop
        StrCpy $R1 ""        ;    no CDROM drive found
        goto break
       StrCpy $R1 0          ;  else return to A
      goto loop
   break:
   break:



Revision as of 15:45, 26 July 2008

Author: Message (talk, contrib)


Description

Because the CDRom plug-in is unable to read any data from DVDs, these functions are meant as a replacement with two primary functions: Finding CD/DVD-ROM drives in the user's system and reading CD/DVD-ROM disc labels.

How To Use

/* --------------------------------
 
  DVD functions - a replacement for the CD-ROM plugin for NSIS
    Created by Message, 2007
 
  Usage example:
    push ""                       ;push input to stack
    call DVD_GetNextDrive         ;call function
    pop $0                        ;pop output from stack
 
    push $0                       ;push input to stack
    call DVD_GetLabel             ;call function
    pop $1                        ;pop output from stack
 
    call DVD_Unload               ;unload from memory
 
 
  DVD_GetNextDrive : Finds the first/next CD/DVD-ROM drive and returns its full path on the stack.
 
             input : The function will search for the first CD/DVD drive AFTER this specified
                     drive letter. So with input "C:\" the function will start searching at D:\.
                     Only the first character of the input is used, so it should be a Capital
                     letter from A to Z.
                     If the input does not start with A-Z, the function returns an empty string
                     ("") on the stack.
                     If the input is empty, the function starts scanning at A:\.
                     If the function reaches Z:\, it will continue searching at A:\.
            output : The full path of the first CD/DVD-ROM drive the function found, for example
                     "E:\".
                     If the function could not find any CD/DVD-ROM drive after (and before) the
                     specified input drive, it will return an empty string ("") on the stack.
                     If Windows could not find any drives at all (either CD-ROM or otherwise),
                     the function returns "ERROR". This should never happen.
 
  DVD_GetLabel     : Returns the label of the CD/DVD currently in the specified drive on the stack.
 
             input : The full path to the root of the CD/DVD-ROM drive, so for example "E:\".
            output : The full volume label of the disc in the drive. If there is no disc in the
                     drive, or there is some other error, the function will return
                     "DVDGetLabel_error" on the stack.
 
  DVD_CheckDrive   : Checks if the specified drive  is a CD/DVD-ROM drive.
 
             input : The full path to the root of the CD/DVD-ROM drive, so for example "E:\".
            output : If the drive is a CD/DVD-ROM drive, the function will return "CDROM" on the
                     stack. (For other possible outputs, see the function code.)
 
  DVD_Unload       : Unloads dlls used in other DVD functions. Call this function from .onGUIEnd
                     to prevent .dll files from remaining in the user's temp folder. No input or
                     output.
*/

The Functions

Function DVD_GetNextDrive
  Exch $R1
  Push $R0
  Push $R2
  Push $R3
  Push $R4
 
  ;get all drives (return to $R0, bitwise)
  System::Call /NOUNLOAD 'kernel32::GetLogicalDrives() i .r10'
  StrCmp $R0 "0" 0 +3        ;if no drives found, error
    StrCpy $R1 "ERROR"
    goto break
 
  ;If no parameter was supplied at all, assume we're starting at A:\ and set the "no parameters" flag.
  StrCmp $R1 "" 0 +4
    StrCpy $R1 "0"
    StrCpy $R4 "-1"  ;no parameters flag. If $R4 is -1, it will never equal the current drive letter, thus the alphabet cycle check will never kick in
    goto loop
 
  ;get ascii-number of first char in function parameter
  System::Call /NOUNLOAD "*(&t1 r11)i.r12"
  System::Call /NOUNLOAD "*$R2(&i1 .r11)"
  System::Free /NOUNLOAD $R2
  IntOp $R1 $R1 - 65
 
  ;check if parameter driveletter is between A and Z
  IntCmp $R1 0 0 +2
  IntCmp $R1 25 +3 +3
    StrCpy $R1 ""
    goto break
 
  ;backup the (asciiconverted) starting driveletter, for detecting when we've cycled the entire alphabet.
  StrCpy $R4 $R1
 
  ;If a valid parameter was supplied (ie we had a parameter and we survived so far), start at the driveletter directly after the supplied starting driveletter
  IntOp $R1 $R1 + 1
  StrCmp $R1 26 0 +2         ;if >Z
    StrCpy $R1 0             ;  return to A
 
  loop:
    IntOp $R2 0x01 << $R1
    IntOp $R3 $R2 & $R0
    ;if (0x01<<driveletter & drivesfound) == 0x01<<driveletter  (in other words, if there is a drive mounted at this driveletter)
    StrCmp $R3 $R2 0 NoDriveHere
      ;convert asciinumber of driveletter to character
      IntOp $R2 $R1 + 65
      IntFmt $R2 %c $R2
      ;get type of drive
      System::Call /NOUNLOAD 'kernel32::GetDriveType(t "$R2:\") i .r13'
      StrCmp $R3 5 0 NoDriveHere
        ;type is CDROM
        StrCmp $R1 $R4 0 +3      ;if we've cycled the entire alphabet (we ended up at the drive specified in the starting paramater)
          StrCpy $R1 ""          ;  no more CDROM drives found
          goto break
        StrCpy $R1 "$R2:\"       ;else: next CDROM drive found
        goto break
    NoDriveHere:
    StrCmp $R1 $R4 0 +3      ;if we've cycled the entire alphabet
      StrCpy $R1 ""          ;  no CDROM drive found
      goto break
    IntOp $R1 $R1 + 1        ;increment driveletter
    StrCmp $R1 26 0 loop     ;if >Z
      StrCmp $R4 "-1" 0 +3   ;  if there were no parameters
        StrCpy $R1 ""        ;    no CDROM drive found
        goto break
      StrCpy $R1 0           ;  else return to A
      goto loop
  break:
 
  Pop $R4
  Pop $R3
  Pop $R2
  Pop $R0
  Exch $R1
FunctionEnd
 
 
Function DVD_GetLabel
  Exch $R0
  Push $R1
  Push $R2
 
  ;leave function if no parameter was supplied
  StrCmp $R0 "" break
 
  ;get the label of the drive (return to $R1)
  System::Call /NOUNLOAD 'Kernel32::GetVolumeInformation(t r10,t.r11,i ${NSIS_MAX_STRLEN},*i,*i,*i,t.r12,i ${NSIS_MAX_STRLEN})i.r10'
  StrCmp $R0 0 0 +3
    StrCpy $R0 "DVDGetLabel_error"
    goto +2
  StrCpy $R0 $R1
  break:
 
  Pop $R2
  Pop $R1
  Exch $R0
FunctionEnd
 
 
Function DVD_CheckDrive
  Exch $R0
  Push $R1
  System::Call /NOUNLOAD 'kernel32::GetDriveType(t "$R0") i .r11'
  StrCmp $R1 0 0 +2
  StrCpy $R0 "UNKNOWN"
  StrCmp $R1 1 0 +2
  StrCpy $R0 "INVALID"
  StrCmp $R1 2 0 +2
  StrCpy $R0 "REMOVABLE"
  StrCmp $R1 3 0 +2
  StrCpy $R0 "FIXED"
  StrCmp $R1 4 0 +2
  StrCpy $R0 "REMOTE"
  StrCmp $R1 5 0 +2
  StrCpy $R0 "CDROM"
  StrCmp $R1 6 0 +2
  StrCpy $R0 "RAMDISK"
  Pop $R1
  Exch $R0
FunctionEnd
 
 
Function DVD_Unload
  Push $R0
  System::Call 'kernel32::GetLogicalDrives() i .r10 ? u'
  Pop $R0
FunctionEnd