Sharing Folders: Difference between revisions

From NSIS Wiki
Jump to navigationJump to search
No edit summary
 
 
(9 intermediate revisions by 3 users not shown)
Line 1: Line 1:
* NSIS forum [http://forums.winamp.com/showthread.php?s=&threadid=269060 thread]
== Description ==
== 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)
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


== Macro ==
== Macro ==
These macros has been tested in Windows 2000 and XP and should be working in Windows NT and 2003 as well
These macros has been tested in Windows 2000 and XP and should be working in Windows NT and 2003 as well.
 
(1st macro) doesn't properly work on Windows 2008.
 
(2nd macro) works on Windows 2008.


=== Header and definitions ===
=== Header and definitions ===
Line 65: Line 70:
   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 '*${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'
   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
   ${If} $1 <> 0
  ${AndIf} $1 <> 2118
     MessageBox MB_OK|MB_ICONSTOP|MB_TOPMOST 'There was an error creating the share!'
     MessageBox MB_OK|MB_ICONSTOP|MB_TOPMOST 'There was an error creating the share!'
   ${EndIf}
   ${EndIf}
Line 80: Line 89:
=== Macro 2 [advanced share] ===
=== Macro 2 [advanced share] ===
<highlight-nsis>
<highlight-nsis>
!macro CreateNewShare USERNAME SHARENAME SHARE_TYPE SHARE_COMMENT SHARE_PERMISSIONS ACL_ACCESS MAX_USERS CURRENT_USES SHARE_PATH SHARE_PASS
!macro CreateNewShare ACCOUNTNAME ACCOUNTTYPE 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
# Get the user's SID from the username
   System::Call /NOUNLOAD '*(&w${NSIS_MAX_STRLEN})i.R9'
   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::LookupAccountNameA(,t "${ACCOUNTNAME}",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'
   System::Call /NOUNLOAD 'advapi32::ConvertSidToStringSid(i R9,*t .R8)i.r5'
${If} $R8 == ''
${If} $R8 == ''
   MessageBox MB_OK|MB_ICONSTOP|MB_TOPMOST 'User "${USERNAME}" does not exist!$\nAborting...'
   MessageBox MB_OK|MB_ICONSTOP|MB_TOPMOST 'User "${ACCOUNTNAME}" does not exist!$\nAborting...'
   System::Free $R9
   System::Free $R9
   Quit
   Quit
${EndIf}
${EndIf}
# Create an EXPLICIT_ACCESS structure and place it on $R6
# 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 '*${strEXPLICIT_ACCESS}(${ACL_ACCESS},${SET_ACCESS},${NO_INHERITANCE},0,${NO_MULTIPLE_TRUSTEE},${TRUSTEE_IS_SID},${ACCOUNTTYPE},$R9).R6'
   System::Call /NOUNLOAD 'advapi32::SetEntriesInAclA(i 1,i R6,,*i .R5)i.r1'
   System::Call /NOUNLOAD 'advapi32::SetEntriesInAclA(i 1,i R6,,*i .R5)i.r1'
   ${If} $1 <> 0
   ${If} $1 <> 0
Line 119: Line 128:
   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 '*${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'
   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
   ${If} $1 <> 0
  ${AndIf} $1 <> 2118
     MessageBox MB_OK|MB_ICONSTOP|MB_TOPMOST 'There was an error creating the share!'
     MessageBox MB_OK|MB_ICONSTOP|MB_TOPMOST 'There was an error creating the share!'
   ${EndIf}
   ${EndIf}
Line 133: Line 146:
Use the above macro from your NSIS installer if you want to create a share with read access for user jdoe
Use the above macro from your NSIS installer if you want to create a share with read access for user jdoe
<highlight-nsis>
<highlight-nsis>
!insertmacro CreateNewShare "jdoe" "Name for the share" ${STYPE_DISKTREE} "share description" ${ACCESS_ALL} ${GENERIC_READ}|${GENERIC_EXECUTE} -1 0 "X:\<folder_to_share>" ""
!insertmacro CreateNewShare "jdoe" ${TRUSTEE_IS_USER} "Name for the share" ${STYPE_DISKTREE} "share description" ${ACCESS_ALL} ${GENERIC_READ}|${GENERIC_EXECUTE} -1 0 "X:\<folder_to_share>" ""
</highlight-nsis>
 
Use the above macro from your NSIS installer if you want to create a share with read access for everyone (even on Windows 2008)
<highlight-nsis>
!insertmacro CreateNewShare "Everyone" ${TRUSTEE_IS_GROUP} "Name for the share" ${STYPE_DISKTREE} "share description" ${ACCESS_ALL} ${GENERIC_READ}|${GENERIC_EXECUTE} -1 0 "X:\<folder_to_share>" ""
</highlight-nsis>
 
=== Macro 3 [remove share] ===
<highlight-nsis>
!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
</highlight-nsis>
 
==== Usage ====
Use the above macro from your NSIS installer if you want to remove a share with name ShareName
<highlight-nsis>
!insertmacro RemoveShare "ShareName"
</highlight-nsis>
</highlight-nsis>


Line 140: Line 174:


API Functions used:
API Functions used:
* [http://msdn2.microsoft.com/en-us/library/aa380478.aspx NetShareAdd]
* [http://msdn.microsoft.com/en-us/library/bb525384(VS.85).aspx NetShareAdd]
* [http://msdn.microsoft.com/en-us/library/bb525386(VS.85).aspx NetShareDel]
* [http://msdn2.microsoft.com/en-us/library/aa379159.aspx LookupAccountName]
* [http://msdn2.microsoft.com/en-us/library/aa379159.aspx LookupAccountName]
* [http://msdn2.microsoft.com/en-us/library/aa376399.aspx ConvertSidToStringSid]
* [http://msdn2.microsoft.com/en-us/library/aa376399.aspx ConvertSidToStringSid]
Line 152: Line 187:
[[Category:Disk, Path & File Functions]]
[[Category:Disk, Path & File Functions]]


 
[[User:CancerFace|CancerFace]]
[[User:CancerFace|CancerFace]] 07:26, 24 April 2007 (PDT)

Latest revision as of 07:04, 4 November 2010

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)

Macro

These macros has been tested in Windows 2000 and XP and should be working in Windows NT and 2003 as well.

(1st macro) doesn't properly work on Windows 2008.

(2nd macro) works on Windows 2008.

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'

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

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>" ""

Macro 2 [advanced share]

!macro CreateNewShare  ACCOUNTNAME ACCOUNTTYPE 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 "${ACCOUNTNAME}",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 "${ACCOUNTNAME}" 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},${ACCOUNTTYPE},$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

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" ${TRUSTEE_IS_USER} "Name for the share" ${STYPE_DISKTREE} "share description" ${ACCESS_ALL} ${GENERIC_READ}|${GENERIC_EXECUTE} -1 0 "X:\<folder_to_share>" ""

Use the above macro from your NSIS installer if you want to create a share with read access for everyone (even on Windows 2008)

!insertmacro CreateNewShare "Everyone" ${TRUSTEE_IS_GROUP} "Name for the share" ${STYPE_DISKTREE} "share description" ${ACCESS_ALL} ${GENERIC_READ}|${GENERIC_EXECUTE} -1 0 "X:\<folder_to_share>" ""

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

Usage

Use the above macro from your NSIS installer if you want to remove a share with name ShareName

!insertmacro RemoveShare "ShareName"

Resources and Links

API Functions used:

CancerFace