DVD functions: Difference between revisions
From NSIS Wiki
Jump to navigationJump to search
Line 61: | Line 61: | ||
== The Functions == | == The Functions == | ||
<highlight-nsis> | <highlight-nsis> | ||
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 | |||
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_GetNextDrive | Function DVD_GetNextDrive | ||
Exch $R1 | Exch $R1 | ||
Line 92: | Line 144: | ||
goto break | 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 | ;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 111: | Line 163: | ||
System::Call /NOUNLOAD 'kernel32::GetDriveType(t "$R2:\") i .r13' | System::Call /NOUNLOAD 'kernel32::GetDriveType(t "$R2:\") i .r13' | ||
StrCmp $R3 5 0 NoDriveHere | StrCmp $R3 5 0 NoDriveHere | ||
;type is CDROM | ;if type is CDROM | ||
StrCpy $R1 "$R2:\" | |||
StrCpy $R1 "$R2:\" | |||
goto break | goto break | ||
NoDriveHere: | NoDriveHere: | ||
IntOp $R1 $R1 + 1 ;increment driveletter | IntOp $R1 $R1 + 1 ;increment driveletter | ||
StrCmp $R1 26 0 | 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 135: | Line 185: | ||
Pop $R0 | Pop $R0 | ||
Exch $R1 | Exch $R1 | ||
FunctionEnd | FunctionEnd | ||
</highlight-nsis> | </highlight-nsis> | ||
[[Category:System Related Functions]] | [[Category:System Related Functions]] |
Revision as of 08:44, 28 October 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, 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.)
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_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 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_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 ;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 /NOUNLOAD '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