You can use this code to get list of users from shared folder of source path and also add users to destination path. It will also make destination folder shared.
It is useful to copy folder from one path to another with all its permissions.
Expand|Select|Wrap|Line Numbers
- public void SetPermissions(string srcPath, string destPath)
- {
- string unc;
- string sharedName = string.Empty;
- if (TryGetLocalFromUncDirectory(srcPath, out unc, out sharedName))
- {
- sharedName = Path.GetFileName(unc);
- if (!Directory.Exists(destPath))
- {
- Directory.CreateDirectory(destPath);
- }
- string userName = Environment.UserName;
- string domainName = Environment.UserDomainName;
- AddPermissions(sharedName, domainName, userName, destPath);
- }
- }
- /// <summary>
- /// Remove the share.
- /// </summary>
- private uint RemoveShare(string shareName)
- {
- try
- {
- using (ManagementObject o = new ManagementObject("root\\cimv2",
- "Win32_Share.Name='" + shareName + "'", null))
- {
- ManagementBaseObject outParams = o.InvokeMethod("delete", null, null);
- return (uint)(outParams.Properties["ReturnValue"].Value);
- }
- }
- catch (Exception ex)
- {
- return 1;
- }
- }
- /// <summary>
- /// Creates the share.
- /// </summary>
- private void AddPermissions(string sharedFolderName, string domain, string userName, string destPath)
- {
- // Step 1 - Getting the user Account Object
- ManagementObject sharedFolder = GetSharedFolderObject(sharedFolderName);
- if (sharedFolder==null)
- {
- System.Diagnostics.Trace.WriteLine("The shared folder with given name does not exist");
- return;
- }
- ManagementBaseObject securityDescriptorObject = sharedFolder.InvokeMethod("GetSecurityDescriptor", null, null);
- if (securityDescriptorObject == null)
- {
- System.Diagnostics.Trace.WriteLine(string.Format(CultureInfo.InvariantCulture, "Error extracting security descriptor of the shared path {0}.", sharedFolderName));
- return;
- }
- int returnCode = Convert.ToInt32(securityDescriptorObject.Properties["ReturnValue"].Value);
- if (returnCode != 0)
- {
- System.Diagnostics.Trace.WriteLine(string.Format(CultureInfo.InvariantCulture, "Error extracting security descriptor of the shared path {0}. Error Code{1}.", sharedFolderName, returnCode.ToString()));
- return;
- }
- ManagementBaseObject securityDescriptor = securityDescriptorObject.Properties["Descriptor"].Value as ManagementBaseObject;
- // Step 2 -- Extract Access Control List from the security descriptor
- int existingAcessControlEntriesCount = 0;
- ManagementBaseObject[] accessControlList = securityDescriptor.Properties["DACL"].Value as ManagementBaseObject[];
- if (accessControlList == null)
- {
- // If there aren't any entries in access control list or the list is empty - create one
- accessControlList = new ManagementBaseObject[1];
- }
- else
- {
- // Otherwise, resize the list to allow for all new users.
- existingAcessControlEntriesCount = accessControlList.Length;
- Array.Resize(ref accessControlList, accessControlList.Length + 1);
- }
- // Step 3 - Getting the user Account Object
- ManagementObject userAccountObject = GetUserAccountObject(domain, userName);
- ManagementObject securityIdentfierObject = new ManagementObject(string.Format("Win32_SID.SID='{0}'", (string)userAccountObject.Properties["SID"].Value));
- securityIdentfierObject.Get();
- // Step 4 - Create Trustee Object
- ManagementObject trusteeObject = CreateTrustee(domain, userName, securityIdentfierObject);
- // Step 5 - Create Access Control Entry
- ManagementObject accessControlEntry = CreateAccessControlEntry(trusteeObject, false);
- // Step 6 - Add Access Control Entry to the Access Control List
- accessControlList[existingAcessControlEntriesCount] = accessControlEntry;
- // Step 7 - Assign access Control list to security desciptor
- securityDescriptor.Properties["DACL"].Value = accessControlList;
- // Step 8 - Assign access Control list to security desciptor
- ManagementBaseObject parameterForSetSecurityDescriptor = sharedFolder.GetMethodParameters("SetSecurityDescriptor");
- parameterForSetSecurityDescriptor["Descriptor"] = securityDescriptor;
- sharedFolder.InvokeMethod("SetSecurityDescriptor", parameterForSetSecurityDescriptor, null);
- // Step 9 - Remove Shared Folder
- RemoveShare(sharedFolderName);
- // Step 10 - Create Shared Folder
- CreateSharedFolderWithUserPermissions(securityDescriptor, sharedFolderName, destPath);
- }
- /// <summary>
- /// Gets the UNC path for a local path passed to it. empty string if folder isn't shared
- ///
- /// </summary>
- /// <param name="local">The local path</param>
- /// <param name="unc">The UNC path</param>
- /// <returns>True if UNC is valid, false otherwise</returns>
- ///
- private bool TryGetLocalFromUncDirectory(string local, out string unc, out string sharedName)
- {
- unc = string.Empty;
- sharedName = string.Empty;
- if (string.IsNullOrEmpty(local))
- {
- throw new ArgumentNullException("local");
- }
- ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT Name FROM Win32_share WHERE path ='" + local.Replace("\\", "\\\\") + "'");
- ManagementObjectCollection coll = searcher.Get();
- if (coll.Count == 1)
- {
- foreach (ManagementObject share in searcher.Get())
- {
- sharedName = share["Name"] as String;
- unc = "\\\\" + SystemInformation.ComputerName + "\\" + sharedName;
- return true;
- }
- }
- return false;
- }
- /// <summary>
- /// The method returns ManagementObject object for the shared folder with given name
- /// </summary>
- /// <param name="sharedFolderName">string containing name of shared folder</param>
- /// <returns>Object of type ManagementObject for the shared folder.</returns>
- private static ManagementObject GetSharedFolderObject(string sharedFolderName)
- {
- ManagementObject sharedFolderObject = null;
- //Creating a searcher object to search
- ManagementObjectSearcher searcher = new ManagementObjectSearcher("Select * from Win32_LogicalShareSecuritySetting where Name = '" + sharedFolderName + "'");
- ManagementObjectCollection resultOfSearch = searcher.Get();
- if (resultOfSearch.Count > 0)
- {
- //The search might return a number of objects with same shared name. I assume there is just going to be one
- foreach (ManagementObject sharedFolder in resultOfSearch)
- {
- sharedFolderObject = sharedFolder;
- break;
- }
- }
- return sharedFolderObject;
- }
- /// <summary>
- /// The method returns ManagementObject object for the user folder with given name
- /// </summary>
- /// <param name="domain">string containing domain name of user </param>
- /// <param name="alias">string containing the user's network name </param>
- /// <returns>Object of type ManagementObject for the user folder.</returns>
- private static ManagementObject GetUserAccountObject(string domain, string alias)
- {
- ManagementObject userAccountObject = null;
- ManagementObjectSearcher searcher = new ManagementObjectSearcher(string.Format("select * from Win32_Account where Name = '{0}' and Domain='{1}'", alias, domain));
- ManagementObjectCollection resultOfSearch = searcher.Get();
- if (resultOfSearch.Count > 0)
- {
- foreach (ManagementObject userAccount in resultOfSearch)
- {
- userAccountObject = userAccount;
- break;
- }
- }
- return userAccountObject;
- }
- /// <summary>
- /// Returns the Security Identifier Sid of the given user
- /// </summary>
- /// <param name="userAccountObject">The user object who's Sid needs to be returned</param>
- /// <returns></returns>
- private static ManagementObject GetAccountSecurityIdentifier(ManagementBaseObject userAccountObject)
- {
- ManagementObject securityIdentfierObject = new ManagementObject(string.Format("Win32_SID.SID='{0}'", (string)userAccountObject.Properties["SID"].Value));
- securityIdentfierObject.Get();
- return securityIdentfierObject;
- }
- /// <summary>
- /// Create a trustee object for the given user
- /// </summary>
- /// <param name="domain">name of domain</param>
- /// <param name="userName">the network name of the user</param>
- /// <param name="securityIdentifierOfUser">Object containing User'sid</param>
- /// <returns></returns>
- private static ManagementObject CreateTrustee(string domain, string userName, ManagementObject securityIdentifierOfUser)
- {
- ManagementObject trusteeObject = new ManagementClass("Win32_Trustee").CreateInstance();
- trusteeObject.Properties["Domain"].Value = domain;
- trusteeObject.Properties["Name"].Value = userName;
- trusteeObject.Properties["SID"].Value = securityIdentifierOfUser.Properties["BinaryRepresentation"].Value;
- trusteeObject.Properties["SidLength"].Value = securityIdentifierOfUser.Properties["SidLength"].Value;
- trusteeObject.Properties["SIDString"].Value = securityIdentifierOfUser.Properties["SID"].Value;
- return trusteeObject;
- }
- /// <summary>
- /// Create an Access Control Entry object for the given user
- /// </summary>
- /// <param name="trustee">The user's trustee object</param>
- /// <param name="deny">boolean to say if user permissions should be assigned or denied</param>
- /// <returns></returns>
- private static ManagementObject CreateAccessControlEntry(ManagementObject trustee, bool deny)
- {
- ManagementObject aceObject = new ManagementClass("Win32_ACE").CreateInstance();
- aceObject.Properties["AccessMask"].Value = 0x1U | 0x2U | 0x4U | 0x8U | 0x10U | 0x20U | 0x40U | 0x80U | 0x100U | 0x10000U | 0x20000U | 0x40000U | 0x80000U | 0x100000U; // all permissions
- aceObject.Properties["AceFlags"].Value = 0x0U; // no flags
- aceObject.Properties["AceType"].Value = deny ? 1U : 0U; // 0 = allow, 1 = deny
- aceObject.Properties["Trustee"].Value = trustee;
- return aceObject;
- }
- /// <summary>
- /// Creates the shared folder with all user permissions.
- /// </summary>
- private void CreateSharedFolderWithUserPermissions(ManagementBaseObject securityDescriptor, string sharedFolderName, string destPath)
- {
- // Create a ManagementClass object
- ManagementClass managementClass = new ManagementClass("Win32_Share");
- // Create ManagementBaseObjects for in and out parameters
- ManagementBaseObject inParams = managementClass.GetMethodParameters("Create");
- ManagementBaseObject outParams;
- // Set the input parameters
- inParams["Description"] = "My Files Share";
- inParams["Name"] = sharedFolderName;
- inParams["Path"] = destPath;
- inParams["Type"] = 0x0; // Disk Drive
- inParams["Access"] = securityDescriptor;
- // Invoke the method on the ManagementClass object
- outParams = managementClass.InvokeMethod("Create", inParams, null);
- // Check to see if the method invocation was successful
- if ((uint)(outParams.Properties["ReturnValue"].Value) != 0)
- {
- throw new Exception("Unable to share directory.");
- }
- }