Detect Drives

From NSIS Wiki
Jump to navigationJump to search
Author: deguix (talk, contrib)


Description

Superseded by: GetDrives function.
Requires: System plug-in.

This function detects available drives and return their letters (with colon and foward slash, like C:/).

Function Call

Push "([Hard Drives][CDROM Drives][Diskette Drives][RAM Drives][Network Drives]|All Drives|All Local Drives|Basic Drives|Disk Needed Drives)" ; Drive types used for the search. See "Drive Types".
Push $0
GetFunctionAddress $0 "CallbackFunction" ; Custom callback function name.
Exch $0
Call DetectDrives

Drive Types

  • Hard Drives
  • CDROM Drives
  • Diskette Drives
  • RAM Drives
  • Network Drives

You can format the string as you like, but have to be the above strings to work. Some examples:

  • Hard Drives and worst but useful Diskette Drives.
  • CDROM DrivesDiskette Drives.
  • Essential Network Drives and the really needed Hard Drives.

You can also use:

  • All Drives (= Hard Drives, CDROM Drives, Diskette Drives, RAM Drives, Network Drives)
  • All Local Drives (= Hard Drives, CDROM Drives, Diskette Drives, RAM Drives)
  • Basic Drives (= Hard Drives, CDROM Drives, Diskette Drives)
  • Disk Needed Drives (= CDROM Drives, Diskette Drives)

How to Use Callback Function

  • You have to push "Stop" to stop, or anything to continue the search, if you don't push, will occur the stack corruption.
  • Do not push values on the stack without poping them later unless it's the return value.
  • You can use any variables, but $R0 has function result, the drive letter detected.

Function Code

;----------------------------------------------------------------------------
; Superseded by     : GetDrives function.
;----------------------------------------------------------------------------
; Title             : Detect drives
; Short Name        : DetectDrives
; Last Changed      : 22/Feb/2005
; Code Type         : Function
; Code Sub-Type     : One-way Input, Callback Dependant
;----------------------------------------------------------------------------
; Required          : System plugin.
; Description       : Detects available drives and return their letters
;                     (with colon and foward slash, like C:/).
;----------------------------------------------------------------------------
; Function Call     : Push "([Hard Drives][CDROM Drives][Diskette Drives]
;                          [RAM Drives][Network Drives]|All Drives|All Local
;                          Drives|Basic Drives|Disk Needed Drives)"
;                       Drive types used for the search.
;
;                     Push $0
;
;                     GetFunctionAddress $0 "CallbackFunction"
;                       Custom callback function name where the search is
;                       returned to.
;
;                     Exch $0
;                     Call DetectDrives
;----------------------------------------------------------------------------
; Callback Variables: $R0 - Drive letter detected with ":/" (like C:/).
;----------------------------------------------------------------------------
; Author            : Diego Pedroso
; Author Reg. Name  : deguix
;----------------------------------------------------------------------------
 
Function DetectDrives
 
  Exch
  Exch $R0
  Exch
  Exch $R1
  Push $R2
  Push $R3
  Push $R4
  Push $R5
  Push $0
  Push $1
  StrCpy $R4 $R1
 
  # Drives Conversion
 
  StrCmp $R0 "All Drives" 0 +2
    StrCpy $R0 "Hard Drives, CDROM Drives, Diskette Drives, RAM Drives, \
    Network Drives"
 
  StrCmp $R0 "All Local Drives" 0 +2
    StrCpy $R0 "Hard Drives, CDROM Drives, Diskette Drives, RAM Drives"
 
  StrCmp $R0 "Basic Drives" 0 +2
    StrCpy $R0 "Hard Drives, CDROM Drives, Diskette Drives"
 
  StrCmp $R0 "Disk Needed Drives" 0 +2
    StrCpy $R0 "CDROM Drives, Diskette Drives"
 
  # Memory for paths
 
  System::Alloc 1024
  Pop $R1
 
  # Get drives
 
  System::Call 'kernel32::GetLogicalDriveStringsA(i, i) i(1024, R1)'
 
  enumok:
 
  # One more drive?
 
  System::Call 'kernel32::lstrlenA(t) i(i R1) .R2'
  IntCmp $R2 0 enumex
 
  # Now, search for drives according to user conditions
 
  System::Call 'kernel32::GetDriveTypeA(t) i (i R1) .R3'
 
  StrCpy $2 0
 
  Search:
 
  IntOp $2 $2 + 1
 
  StrCmp $2 1 0 +3
    StrCpy $0 "Hard Drives"
    StrCpy $1 3
 
  StrCmp $2 2 0 +3
    StrCpy $0 "CDROM Drives"
    StrCpy $1 5
 
  StrCmp $2 3 0 +3
    StrCpy $0 "Diskette Drives"
    StrCpy $1 2
 
  StrCmp $2 4 0 +3
    StrCpy $0 "RAM Drives"
    StrCpy $1 6
 
  StrCmp $2 5 0 +3
    StrCpy $0 "Network Drives"
    StrCpy $1 4
 
  IntCmp $2 6 enumnext 0 enumnext
 
    Push $R1
    Push $R2
    Push $R3
    Push $R4
    Push $R5
 
     StrLen $R3 $0
     StrCpy $R4 0
     loop:
       StrCpy $R5 $R0 $R3 $R4
       StrCmp $R5 $0 done
       StrCmp $R5 "" done
       IntOp $R4 $R4 + 1
       Goto loop
   done:
     StrCpy $R1 $R0 "" $R4
 
     StrCmp $R1 "" 0 +7
 
       Pop $R5
       Pop $R4
       Pop $R3
       Pop $R2
       Pop $R1
       Goto Search
 
     Pop $R5
     Pop $R4
     Pop $R3
     Pop $R2
     Pop $R1
 
     StrCmp $R3 $1 0 Search
 
  # Get drive path string
 
  System::Call '*$R1(&t1024 .R3)'
 
  # Prepare variables for the Callback function
 
  Push $R4
  Push $R3
  Push $R2
  Push $R1
  Push $R0
 
  StrCpy $R0 $R3
 
  # Call the Callback function
 
  Call $R4
 
  # Return variables
 
  Push $R5
  Exch
  Pop $R5
 
  Exch
  Pop $R0
  Exch
  Pop $R1
  Exch
  Pop $R2
  Exch
  Pop $R3
  Exch
  Pop $R4
 
  StrCmp $R5 "Stop" 0 +3
    Pop $R5
    Goto enumex
 
  Pop $R5
 
  enumnext:
 
  # Next drive path
 
  IntOp $R1 $R1 + $R2
  IntOp $R1 $R1 + 1
  goto enumok
 
  # End Search
 
  enumex:
 
  # Free memory used for paths
 
  System::Free $R1
 
  # Return original user variables
 
  Pop $0
  Pop $1
  Pop $R5
  Pop $R4
  Pop $R3
  Pop $R2
  Pop $R1
  Pop $R0
 
FunctionEnd