Sharing Folders

From NSIS Wiki

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

API Functions used:

donate
ads