DVD functions
From NSIS Wiki
Jump to navigationJump to search
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