;FUNCTION MapDrive
;
;ACTION Maps an UNC to a driveletter or removes a mapped UNC
;
;AUTHOR Jens Meyer (sealeopard@usa.net)
;
;VERSION 2.01 (added optional username/password macro)
; 2.0 (major rewrite, switched the label-creation code from COM to registry writes,
; enabled unmapping, enabled SUBST under NT4)
; 1.44 (removed issue where label was not applied when mapping to already mapped drive)
; 1.43
;
;DATE CREATED 2001/12/20
;
;DATE MODIFIED 2004/02/04
;
;KIXTART 4.22+
;
;SYNTAX MAPDRIVE(DRIVE [UNC , PERSIST, LABEL, USER, PASS])
;
;PARAMETERS DRIVE
; Required string containing driveletter or *
;
; UNC
; Optional string containing UNC name
;
; PERSIST
; Optional boolean indicating a persistent connection
;
; LABEL
; Optional integer/string to relabel a mapped share (Windows 2000/XP/2003 only)
; 0 = remove existing label
; 1 = apply Windows NT/2000-style label "sharename on 'computer name' (DriveLetter:)"
; otherwise a label (no more than 32 characters under Windows 2000)
;
; USER
; Optional string containing the username to be used to authenticate the UNC
;
; PASS
; Optional string containing the password for the username
;
;RETURNS 0 or the error code @error. If a share is being mapped to any available drive letter
; via '*', then @RESULT will contain the driveletter.
;
;REMARKS A) 'Persist' is not supported under Windows 9x to prevent different users
; from receiving drive shares they should not have access to.
; B) Deep mapping is not supported under Windows 9x.
; C) Deep mapping under Windows NT will require two driveletters (one for the main share,
; and a second one for SUBST to simulate the deep map)
; D) Omitting the LABEL parameter or providing an empty string will not change the
; existing label in Windows 2000/XP/2003.
; E) Providing only a driveletter will remove the share (persistently if PERSIST is true)
; F) UNCs and labels can contain macros, e.g '\\server\@USERID$'
;
;DEPENDENCIES none
;
;EXAMPLE ; persistent map of \\SERVER\share to Z:
; $rc = MAPDRIVE('z','\\SERVER\share',1)
; ;non-persistent map of \\SERVER\share to first available driveletter with NT/2000-style label
; $rc = MAPDRIVE('*','\\SERVER\share',0,1)
; ;non-persistent map of \\SERVER\share to first available driveletter with label 'whatever'
; $rc = MAPDRIVE('*','\\SERVER\share',0,'whatever')
; ;non-persistent map of \\SERVER\share to Z: with e.g. label "Jens Meyer's personal share"
; $rc = MAPDRIVE('P','\\SERVER\@USERID$',0,"@FULLNAME's personal share")
; ;removal of mapped drive N:
; $rc = MAPDRIVE('N',)
;
;KIXTART BBS http://www.kixtart.org/ubbthreads/showflat.php?Number=110547
;
function mapdrive($drive, optional $unc, optional $persist, optional $label, optional $user, optional $pass)
Dim $mount, $regvalue, $rc, $deep, $regkey, $comp, $share
; don't change label if none is provided
$label=iif(vartype($label)=0,-1,$label)
; set the persistent flag
$persist=iif(@INWIN=2,0,val($persist))
; reformat UNC to lowercase and remove trailing backslash
$unc=lcase(trim(iif(right($unc,1)='\',left($unc,-1),$unc)))
; check for a valid drive letter
$drive=ucase(trim(left($drive,1)))
; check whether we do a deep mapping
$deep=iif(ubound(split($unc,'\'))>3,1,0)
; translate macros in UNC
if instr($unc,'@@')
$rc=execute('$unc="'+$unc+'"')
endif
; translate macros in label
if instr($label,'@@')
$rc=execute('$label="'+$label+'"')
endif
select
case $drive='*'
$mount='*'
case $drive>='C' and $drive<='Z'
$mount=$drive+':'
if $persist and $unc and lcase(trim(readvalue('HKEY_CURRENT_USER\Network\'+$drive,'RemotePath')))=$unc
$mapdrive=1
endif
case 1
exit 15
endselect
; connect to UNC if the driveletter is not already mounted persistently
select
case not $mapdrive and $unc
select
case @INWIN=2 and ($deep or instr($unc,'\\'+@WKSTA+'\'))=1
;Windows 9x cannot deep map or map to its own shares
$mapdrive=3
exit 3
case $deep and val(@DOS)=4
$mapdrive=split($unc,'\')
redim preserve $mapdrive[3]
$mapdrive=join($mapdrive,'\')
use $mount /delete /persistent
if $user or $pass
use $mount $mapdrive /user:$user /password:$pass
else
use $mount $mapdrive
endif
use '*' $mapdrive
$rc=@RESULT
if @ERROR
$mapdrive=@ERROR
exit @ERROR
endif
use $mount /delete /persistent
$unc=$rc+substr($unc,len($mapdrive)+1)
shell 'subst '+$mount+' '+$unc
$mapdrive=@ERROR
use $rc /delete /persistent
exit $mapdrive
case 1
if $mount<>'*'
use $mount /delete /persistent
endif
if $persist
if $user or $pass
use $mount $unc /user:$user /password:$pass /persistent
else
use $mount $unc /persistent
endif
else
if $user or $pass
use $mount $unc /user:$user /password:$pass
else
use $mount $unc
endif
endif
endselect
if $mount='*'
$mount=@RESULT
$drive=left($mount,1)
endif
case not $unc
if $persist
use $mount /delete /persistent
else
use $mount /delete
endif
$mapdrive=@ERROR
exit @ERROR
endselect
if @ERROR
$mapdrive=@ERROR
exit @ERROR
endif
; labels can only be applied to Windows 2000/XP/2003
if val(@DOS)>4 and $unc and $label<>-1
$regkey='HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer'
if @DOS='5.0'
$regkey=$regkey+'\MountPoints\'+$drive+'\_LabelFromReg'
select
case $label=0
; remove label
$rc=delkey($regkey)
case $label<>1
; apply label
$rc=$label
redim preserve $label[31]
$label[0]=$rc
for $rc=2 to ubound($label)+1
$label[$rc-1]=iif($rc<=len($label[0]),dectohex(asc(substr($label[0],$rc,1))),'00')
next
$label[0]=dectohex(asc(left($label[0],1)))
$label=join($label,'00')+'000000'
$rc=0
while not keyexist($regkey) and $rc<10
$rc=0.01+$rc
sleep 0.01
loop
$rc=writevalue($regkey,'Cache',$label,'REG_BINARY')
$rc=writevalue($regkey,'Version',3,'REG_DWORD')
endselect
else
if $label
$comp=split($unc,'\')
$share=$comp[ubound($comp)]
redim preserve $comp[ubound($comp)-1]
$comp=substr(join($comp,'\'),3)
endif
$regkey=$regkey+'\MountPoints2\'+join(split($unc,'\'),'#')
select
case $label=0
; remove label
$rc=delvalue($regkey,'_LabelFromReg')
case $label=1
; apply NT/2000-style label
$rc=writevalue($regkey,'_LabelFromReg',$share+" on '"+ucase(left($comp,1))+lcase(substr($comp,2))+"'",'REG_SZ')
case $label
; apply label
$rc=writevalue($regkey,'_LabelFromReg',$label,'REG_SZ')
endselect
endif
endif
$mapdrive=@error
exit @error
endfunction