DVD functions: Difference between revisions

From NSIS Wiki
Jump to navigationJump to search
 
(3 intermediate revisions by 2 users not shown)
Line 17: Line 17:
     call DVD_GetLabel            ;call function
     call DVD_GetLabel            ;call function
     pop $1                        ;pop output from stack
     pop $1                        ;pop output from stack
    call DVD_Unload              ;unload from memory




Line 25: Line 23:
             input : The function will search for the first CD/DVD drive AFTER this specified
             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:\.
                     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
                     Only the first character of the input is used, and this first character
                    letter from A to Z.
                    should be a Capital letter from A to Z.
                     If the input does not start with A-Z, the function returns an empty string
                     If the input does not start with A-Z, the function returns an empty string
                     ("") on the stack.
                     ("") on the stack.
                     If the input is empty, the function starts scanning at A:\.
                     If the input is empty, the function starts scanning at A:\.
                     If the function reaches Z:\, it will continue searching 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
             output : The full path of the first CD/DVD-ROM drive the function found (starting at
                    "E:\".
                    the inputted drive letter), for example "E:\".
                     If the function could not find any CD/DVD-ROM drive after (and before) the
                    If there is only one CD/DVD-ROM drive in the sytem, starting the search at
                    specified input drive, it will return an empty string ("") on the stack.
                    that drive letter will result in the same drive letter being returned.
                    If Windows could not find any drives at all (either CD-ROM or otherwise),
                     If the function could not find any CD/DVD-ROM drives in the system, it will
                    the function returns "ERROR". This should never happen.
                    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.
   DVD_GetLabel    : Returns the label of the CD/DVD currently in the specified drive on the stack.
Line 50: Line 50:
             output : If the drive is a CD/DVD-ROM drive, the function will return "CDROM" on the
             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.)
                     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.
*/
*/
</highlight-nsis>
</highlight-nsis>
== The Functions ==
== The Functions ==
<highlight-nsis>
<highlight-nsis>
Function DVD_CheckDrive
  Exch $R0
  Push $R1
  System::Call '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_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 '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_GetNextDrive
Function DVD_GetNextDrive
   Exch $R1
   Exch $R1
Line 66: Line 108:


   ;get all drives (return to $R0, bitwise)
   ;get all drives (return to $R0, bitwise)
   System::Call /NOUNLOAD 'kernel32::GetLogicalDrives() i .r10'
   System::Call 'kernel32::GetLogicalDrives() i .r10'
   StrCmp $R0 "0" 0 +3        ;if no drives found, error
   StrCmp $R0 "0" 0 +3        ;if no drives found, error
     StrCpy $R1 "ERROR"
     StrCpy $R1 "ERROR"
Line 78: Line 120:
    
    
   ;get ascii-number of first char in function parameter
   ;get ascii-number of first char in function parameter
   System::Call /NOUNLOAD "*(&t1 r11)i.r12"
   System::Call "*(&t1 r11)i.r12"
   System::Call /NOUNLOAD "*$R2(&i1 .r11)"
   System::Call "*$R2(&i1 .r11)"
   System::Free /NOUNLOAD $R2
   System::Free $R2
   IntOp $R1 $R1 - 65
   IntOp $R1 $R1 - 65


Line 89: Line 131:
     goto break
     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
   ;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
   IntOp $R1 $R1 + 1
   StrCmp $R1 26 0 +2        ;if >Z
   StrCmp $R1 26 0 +2        ;if >Z
     StrCpy $R1 0            ;  return to A
     StrCpy $R1 0            ;  return to A
  ;backup the (asciiconverted) starting driveletter, for detecting when we've cycled the entire alphabet.
  StrCpy $R4 $R1


   loop:
   loop:
Line 106: Line 148:
       IntFmt $R2 %c $R2
       IntFmt $R2 %c $R2
       ;get type of drive
       ;get type of drive
       System::Call /NOUNLOAD 'kernel32::GetDriveType(t "$R2:\") i .r13'
       System::Call 'kernel32::GetDriveType(t "$R2:\") i .r13'
       StrCmp $R3 5 0 NoDriveHere
       StrCmp $R3 5 0 NoDriveHere
         ;type is CDROM
         ;if 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 "$R2:\"
          StrCpy $R1 ""          ;  no more CDROM drives found
          goto break
         StrCpy $R1 "$R2:\"       ;else: next CDROM drive found
         goto break
         goto break
     NoDriveHere:
     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
     IntOp $R1 $R1 + 1        ;increment driveletter
     StrCmp $R1 26 0 loop    ;if >Z
     StrCmp $R1 26 0 cycle    ;if >Z
       StrCmp $R4 "-1" 0 +3  ;  if there were no parameters
       StrCmp $R4 "-1" 0 +3  ;  if there were no parameters
         StrCpy $R1 ""        ;    no CDROM drive found
         StrCpy $R1 ""        ;    no CDROM drive found
         goto break
         goto break
       StrCpy $R1 0          ;  else return to A
       StrCpy $R1 0          ;  else return to A
       goto loop
       goto loop             ;    and loop
    cycle:
    StrCmp $R1 $R4 0 loop    ;if we've cycled through the entire alphabet
      StrCpy $R1 ""          ;  no CDROM drives found at all
      goto break
   break:
   break:


Line 132: Line 172:
   Pop $R0
   Pop $R0
   Exch $R1
   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
FunctionEnd
</highlight-nsis>
</highlight-nsis>


[[Category:System Related Functions]]
[[Category:System Related Functions]]

Latest revision as of 06:45, 2 February 2010

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
 
 
  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, and this first character
                     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 (starting at
                     the inputted drive letter), for example "E:\".
                     If there is only one CD/DVD-ROM drive in the sytem, starting the search at
                     that drive letter will result in the same drive letter being returned.
                     If the function could not find any CD/DVD-ROM drives in the system, 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.)
*/

The Functions

Function DVD_CheckDrive
  Exch $R0
  Push $R1
  System::Call '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_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 '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_GetNextDrive
  Exch $R1
  Push $R0
  Push $R2
  Push $R3
  Push $R4
 
  ;get all drives (return to $R0, bitwise)
  System::Call '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 "*(&t1 r11)i.r12"
  System::Call "*$R2(&i1 .r11)"
  System::Free $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
 
  ;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
 
  ;backup the (asciiconverted) starting driveletter, for detecting when we've cycled the entire alphabet.
  StrCpy $R4 $R1
 
  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 'kernel32::GetDriveType(t "$R2:\") i .r13'
      StrCmp $R3 5 0 NoDriveHere
        ;if type is CDROM
        StrCpy $R1 "$R2:\"
        goto break
    NoDriveHere:
    IntOp $R1 $R1 + 1        ;increment driveletter
    StrCmp $R1 26 0 cycle    ;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              ;    and loop
    cycle:
    StrCmp $R1 $R4 0 loop    ;if we've cycled through the entire alphabet
      StrCpy $R1 ""          ;  no CDROM drives found at all
      goto break
  break:
 
  Pop $R4
  Pop $R3
  Pop $R2
  Pop $R0
  Exch $R1
FunctionEnd