;; 
;;=====================================================================================----- 
;; 
;;FUNCTION      MapDrive() 
;; 
;;ACTION        Maps a UNC path to the specified drive letter 
;; 
;;AUTHOR        Glenn Barnas 
;;		 (Inspired by Jens Meyer) 
;; 
;;VERSION       1.5  - 2013/03/30 
;; 
;;HISTORY       1.0  - 2003/08/20 - Initial release 
;;              1.1  - 2003/10/31 - Added security credentials option 
;;              1.2  - 2006/03/07 - used external fn for defining TMP files 
;;              1.3  - 2007/01/09 - Changed to NET USE to eliminate Execute function 
;;                                  (better status returned) 
;;                                  Changed return value - 0 for fail, 1/-1 for success 
;;                                  to permit "If MapDrive()" processing 
;;                                  Removed dependency on external UDF 
;;              1.4  - 2009/03/18 - Removed file dependency, Fixed problem when mapping 
;;                                  shares w/ spaces 
;;              1.5  - 2013/03/30 - Utilized WSH to invoke shell (often faster); 
;;                                  Changed Shell redirect method to prevent output 
;; 
;;SYNTAX        MAPDRIVE(DRIVE, UNC [, Persistence] [, Label] [, ReMap] [, User] [, Password]) 
;; 
;;PARAMETERS    Drive - REQUIRED - String 
;;              - Contains driveletter or * 
;; 
;;              UNCPath	- REQUIRED - String 
;;              - Contains containing UNC path name 
;; 
;;              Persist	- OPTIONAL - Integer 
;;              - Value requesting a persistent connection 
;; 
;;              Label - OPTIONAL - String 
;;              Text to relabel a mapped share (Win 2K/XP & higher only) 
;; 
;;              ReMap - OPTIONAL - Integer 
;;              - When true, allows an existing connection to be remapped. 
;; 
;;              ID/Pass	- OPTIONAL - String 
;;              - User credentials to employ when mapping 
;; 
;;RETURNS       0 if failure, 1 if successful mapping, or -1 if mapping was already  
;;              present, (both return true, so If Mapdrive() will work) 
;; 
;;REMARKS       Support for Win9x is limited.  
;;              Persistent - NT4+, ignored on Win9x 
;;              Deep Map - Win2K+, exits with error on NT and Win9x 
;;              Drive Label - Win2K+, ignored on NT and Win9x 
;; 
;;DEPENDENCIES  WSH 
;; 
;;EXAMPLE       $rc = MAPDRIVE('z','\\SERVER\share', 1, '', 1) 
;;              $rc = MAPDRIVE('*','\\SERVER\share', 0, 'some name', 'DOM\user', 'PassWord') 
;; 
; 
Function MapDrive($_Drive, $_UNCPath, Optional $_Persist, Optional $_Label, Optional $_ReMap, Optional $_User, Optional $_Passwd)
 
  Dim $_Persistent			; PERSISTENT parameter value 
  Dim $_Credentials			; Credentials parameter values 
  Dim $_DeepMap				; Flag indicating deep-mapping request 
  Dim $_P, $_Idx			; index pointers 
  Dim $_M				; status of drive map logic, 1 for map, 0 for reuse 
  Dim $_DriveObj			; object pointer for drive labeling 
  Dim $_MDrive				; drive letter to map 
  Dim $_Line				; array enumerator 
  Dim $_Cmd				; command string to executed 
  Dim $_aTmp				; array of temp values 
  Dim $_Mappings			; array of current mapped drives 
  Dim $_oExec				; WSH object pointer 
  Dim $_Error				; error code 
 
  ; default return value, not successful 
  $MapDrive = 0				
 
  ; Insure drive letter is only 1 character 
  $_Drive = Left($_Drive, 1)
 
  ; Define explicit user credentials for this connection 
  If $_User <> '' And $_Passwd <> ''
    $_Credentials = ' /USER:' + Chr(34) + $_User + Chr(34) + ' ' + Chr(34) + $_Passwd + Chr(34)
  EndIf
 
  ; Set Persistent flag 
  $_Persistent = IIf(@INWIN = 1 And $_Persist, '/PERSISTENT:YES', '/PERSISTENT:NO')
 
  ; Validate the drive letter, assign the MapDrive letter with ":" 
  $_Drive = UCase(Trim($_Drive))
  If ($_Drive < 'A' Or $_Drive > 'Z') And $_Drive <> '*'
    Exit 15
  EndIf
  $_MDrive = $_Drive + ':'
 
  ; Trim trailing "\" if necessary 
  $_UNCPath = IIf(Right($_UNCPath, 1) = '\', Left($_UNCPath, Len($_UNCPath) -1), $_UNCPath)
 
  ; Determine if a deep map has been requested. Abort if not 2K+ 
  $_DeepMap = Split($_UNCPath, '\')
  $_DeepMap = IIF(UBound($_DeepMap) > 3, 1, 0)
  If $_DeepMap
    If (@INWIN = 1 And Val(@DOS) < 5) Or (@INWIN = 2)
      Exit 3
    EndIf
  EndIf
 
  ; Abort if W9x and UNCPath is the local system - mapping to local shares is not permitted 
  If InStr($_UNCPath, @WKSTA) And @INWIN = 2
    Exit 3
  EndIf
 
  ; check for current connections 
  $_oExec = CreateObject("WScript.Shell").Exec('%COMSPEC% /c net use | %WINDIR%\System32\find.exe "\\"')
  If VarType($_oExec) = 9
    $_aTmp = Split($_oExec.StdOut.ReadAll, @CRLF)
    $_Idx = -1
    For Each $_Line in $_aTmp
      If $_Line
        $_Idx = $_Idx + 1
        ReDim Preserve $_Mappings[$_Idx]
        $_Mappings[$_Idx] = SubStr($_Line, 14, 1),  Trim(Split(SubStr($_Line, 24), 'Micro')[0])
      EndIf
    Next
  Else
    Exit 10
  EndIf
 
  $_M = 1
  For $_P = 0 to $_Idx
    If $_Drive = $_Mappings[$_P][0]
      If $_UNCPath = $_Mappings[$_P][1]
        ; Selected drive already mapped to desired share - no action required 
        $_M = 0
      Else
        ; Selected drive already mapped to different share! 
        If $_ReMap
          ; OK to unmap & remap 
          ; use NET command - Kix statment does not completely remove the definition 
          ; Use $MDrive /DELETE $Persistent  
          $_Cmd = '%COMSPEC% /c Net Use ' + $_MDrive + ' /Delete '
          $_oExec = CreateObject("WScript.Shell").Exec($_Cmd)
          While Not $_oExec.Status
            Sleep 0.002
          Loop
          $_Error = $_oExec.ExitCode
          ; Check for correct vartype returned 
          If Not VarType($_oExec) = 9
            Shell $_Cmd + ' 2>NUL: 1>NUL:' 
            $_Error = @ERROR
          EndIf
          If $_Error
            Exit $_Error
          EndIf
        Else
          ; remapping not permitted - error exit! 
          Exit 170
        EndIf
      EndIf
      $_P = 99
    Else
      ; Selected drive is not in use - ok to continue with mapping 
    EndIf
  Next
 
  ; Map Flag ($_M) will be "0" or "1" at this point 
  ;  1 = OK to map 
  ;  0 = Already correctly mapped - no action required 
  If $_M
    $_Cmd = '%COMSPEC% /c Net Use ' + $_MDrive + ' "' + $_UNCPath + '" ' + $_Persistent + ' ' + $_Credentials
    $_oExec = CreateObject("WScript.Shell").Exec($_Cmd)
    While Not $_oExec.Status
      Sleep 0.005
    Loop
    $_Error = $_oExec.ExitCode
    ; Check for correct vartype returned 
    If Not VarType($_oExec) = 9
      Shell $_Cmd + ' 2>NUL: 1>NUL:'
      $_Error = @ERROR
    EndIf
 
    If $_Error
      Exit $_Error
    EndIf
  EndIf
 
  ; good mapping - try to label the share 
  ; labels can only be applied to Windows 2000 or higher platforms 
  If $_Label And Val(@DOS) > 4 And @INWIN = 1
    $_DriveObj = CreateObject('Shell.Application')
    If Not @ERROR
      ;$_Label = Left($_Label + '                              ', 20) 
      $_DriveObj.NameSpace($_Drive + ':').Self.Name = $_Label
    EndIf
    $_DriveObj = ''
  EndIf
 
  ; success exit - show 1 if mapped, and -1 if previous connection was used 
  $MapDrive = IIf($_M, 1, -1)
  Exit 0
 
EndFunction