Sharing Folders
From NSIS Wiki
- NSIS forum thread
Contents |
[edit] Description
These macros will share a folder on the local network giving either full access (1st macro) or user-specified permissions on a per-user level (2nd macro) Note that it can be easily modified so that the permissions reflect groups instead of users
[edit] Macro
These macros has been tested in Windows 2000 and XP and should be working in Windows NT and 2003 as well
[edit] Header and definitions
# Header Files !include "LogicLib.nsh" # Definitions and user flags !define STYPE_DISKTREE 0 !define ACCESS_READ 0x01 !define ACCESS_WRITE 0x02 !define ACCESS_CREATE 0x04 !define ACCESS_EXEC 0x08 !define ACCESS_DELETE 0x10 !define ACCESS_ATRIB 0x20 !define ACCESS_PERM 0x40 !define ACCESS_ALL 0x7F !define GENERIC_READ 0x80000000 !define GENERIC_WRITE 0x40000000 !define GENERIC_EXECUTE 0x20000000 !define GENERIC_ALL 0x10000000 !define NO_INHERITANCE 0x0 !define SECURITY_DESCRIPTOR_REVISION 1 # ACCESS_MODE values !define NOT_USED_ACCESS 0 !define GRANT_ACCESS 1 !define SET_ACCESS 2 !define DENY_ACCESS 3 !define REVOKE_ACCESS 4 !define SET_AUDIT_SUCCESS 5 !define SET_AUDIT_FAILURE 6 # MULTIPLE_TRUSTEE_OPERATION values !define NO_MULTIPLE_TRUSTEE 0 !define TRUSTEE_IS_IMPERSONATE 1 # TRUSTEE_FORM values !define TRUSTEE_IS_SID 0 !define TRUSTEE_IS_NAME 1 !define TRUSTEE_BAD_FORM 2 !define TRUSTEE_IS_OBJECTS_AND_SID 3 !define TRUSTEE_IS_OBJECTS_AND_NAME 4 # TRUSTEE_TYPE values !define TRUSTEE_IS_UNKNOWN 0 !define TRUSTEE_IS_USER 1 !define TRUSTEE_IS_GROUP 2 !define TRUSTEE_IS_DOMAIN 3 !define TRUSTEE_IS_ALIAS 4 !define TRUSTEE_IS_WELL_KNOWN_GROUP 5 !define TRUSTEE_IS_DELETED 6 !define TRUSTEE_IS_INVALID 7 !define TRUSTEE_IS_COMPUTER 8 # Structure Definitions !define strSHARE_INFO_2 '(w,i,w,i,i,i,w,w)i' !define strSHARE_INFO_502 '(w,i,w,i,i,i,w,w,i,i)i' !define strEXPLICIT_ACCESS '(i,i,i,i,i,i,i,i)i'
[edit] Macro 1 [basic share]
!macro CreateNewFullShare SHARENAME SHARE_TYPE SHARE_COMMENT SHARE_PERMISSIONS MAX_USERS CURRENT_USES SHARE_PATH SHARE_PASS System::Call /NOUNLOAD '*${strSHARE_INFO_2}("${SHARENAME}",${SHARE_TYPE},"${SHARE_COMMENT}",${SHARE_PERMISSIONS},${MAX_USERS},${CURRENT_USES},"${SHARE_PATH}","${SHARE_PASS}")i.R0' System::Call /NOUNLOAD 'netapi32::NetShareAdd(,i 2,i R0,*i .R1)i .r1' ${If} $1 = 2118 MessageBox MB_OK|MB_ICONSTOP|MB_TOPMOST 'Folder "${SHARE_PATH}" has already been shared!' ${EndIf} ${If} $1 <> 0 ${AndIf} $1 <> 2118 MessageBox MB_OK|MB_ICONSTOP|MB_TOPMOST 'There was an error creating the share!' ${EndIf} System::Free $R0 !macroend
[edit] Usage
Use the above macro from your NSIS installer if you want to create a share with full access for everyone
!insertmacro CreateNewFullShare "Share Name" ${STYPE_DISKTREE} "Share Description" 0 -1 0 "X:\<folder_to_share>" ""
[edit] Macro 2 [advanced share]
!macro CreateNewShare USERNAME SHARENAME SHARE_TYPE SHARE_COMMENT SHARE_PERMISSIONS ACL_ACCESS MAX_USERS CURRENT_USES SHARE_PATH SHARE_PASS # Get the user's SID from the username System::Call /NOUNLOAD '*(&w${NSIS_MAX_STRLEN})i.R9' System::Call /NOUNLOAD 'advapi32::LookupAccountNameA(,t "${USERNAME}",i R9,*i ${NSIS_MAX_STRLEN},w .R8,*i ${NSIS_MAX_STRLEN},*i .r4)i.r5' System::Call /NOUNLOAD 'advapi32::ConvertSidToStringSid(i R9,*t .R8)i.r5' ${If} $R8 == '' MessageBox MB_OK|MB_ICONSTOP|MB_TOPMOST 'User "${USERNAME}" does not exist!$\nAborting...' System::Free $R9 Quit ${EndIf} # Create an EXPLICIT_ACCESS structure and place it on $R6 System::Call /NOUNLOAD '*${strEXPLICIT_ACCESS}(${ACL_ACCESS},${SET_ACCESS},${NO_INHERITANCE},0,${NO_MULTIPLE_TRUSTEE},${TRUSTEE_IS_SID},${TRUSTEE_IS_USER},$R9).R6' System::Call /NOUNLOAD 'advapi32::SetEntriesInAclA(i 1,i R6,,*i .R5)i.r1' ${If} $1 <> 0 System::Free $R9 System::Free $R6 Quit ${EndIf} # Create an empty security descriptor and place it in R4. System::Alloc ${NSIS_MAX_STRLEN} Pop $R4 System::Call /NOUNLOAD 'advapi32::InitializeSecurityDescriptor(i R4,i ${SECURITY_DESCRIPTOR_REVISION})i.r1' ${If} $1 == 0 System::Free $R9 System::Free $R6 System::Call 'kernel32::LocalFree(i R5)i.r0' Quit ${EndIf} # Add the ACL to the security descriptor System::Call /NOUNLOAD 'advapi32::SetSecurityDescriptorDacl(i R4,i 1,i R5,i 0)i.r1' ${If} $1 == 0 System::Free $R9 System::Free $R6 System::Call 'kernel32::LocalFree(i R5)i.r0' Quit ${EndIf} # Generate the structure that holds the share info and place it on $R0 System::Call /NOUNLOAD '*${strSHARE_INFO_502}("${SHARENAME}",${SHARE_TYPE},"${SHARE_COMMENT}",${SHARE_PERMISSIONS},${MAX_USERS},${CURRENT_USES},"${SHARE_PATH}","${SHARE_PASS}",0,R4).R0' System::Call /NOUNLOAD 'netapi32::NetShareAdd(, i 502, i R0, *i .R1) i .r1' ${If} $1 = 2118 MessageBox MB_OK|MB_ICONSTOP|MB_TOPMOST 'Folder "${SHARE_PATH}" has already been shared!' ${EndIf} ${If} $1 <> 0 ${AndIf} $1 <> 2118 MessageBox MB_OK|MB_ICONSTOP|MB_TOPMOST 'There was an error creating the share!' ${EndIf} # Cleanup System::Free $R9 System::Free $R6 System::Call 'kernel32::LocalFree(i R5)i.r0' System::Free $R0 !macroend
[edit] Usage
Use the above macro from your NSIS installer if you want to create a share with read access for user jdoe
!insertmacro CreateNewShare "jdoe" "Name for the share" ${STYPE_DISKTREE} "share description" ${ACCESS_ALL} ${GENERIC_READ}|${GENERIC_EXECUTE} -1 0 "X:\<folder_to_share>" ""
[edit] Macro 3 [remove share]
!macro RemoveShare SHARENAME System::Call /NOUNLOAD 'netapi32::NetShareDel(, w "${SHARENAME}",i 0) i .r1' ${If} $1 <> 0 MessageBox MB_OK|MB_ICONSTOP|MB_TOPMOST 'There was an error removing the share!"' ${EndIf} !macroend
[edit] Usage
Use the above macro from your NSIS installer if you want to remove a share with name ShareName
!insertmacro RemoveShare "ShareName"
[edit] Resources and Links
- NSIS forum thread
API Functions used:

