3

NOTE: Please don't disregard based on the title being similar to others.

I'm trying to share a folder on a Windows 7 machine. And I want to give everyone full permissions to it via C#.

I've seen several articles on other pages including here, that tell how to do it. But like some others, it doesn’t work for me. Below is a snippet taken from SO.

    DirectorySecurity sec = Directory.GetAccessControl(path);
    // Using this instead of the "Everyone" string means we work on non-English systems.
    SecurityIdentifier everyone = new SecurityIdentifier(WellKnownSidType.WorldSid, null);
    sec.AddAccessRule(new FileSystemAccessRule(everyone, FileSystemRights.FullControl | FileSystemRights.Synchronize, InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, PropagationFlags.None, AccessControlType.Allow));
    Directory.SetAccessControl(path, sec);

Sharing the folder is already done before I invoke the code above. The below images are the results of what i get:

enter image description here

So far, so good. But on the next image you'll see that the the two remaining checkboxs are still unchecked.

enter image description here

What am I missing please?

Thanks!

EDIT: Below is the code used to do the actual sharing.

    private static void QshareFolder(string FolderPath, string ShareName, string Description)
    {
        try
        {
            ManagementClass managementClass = new ManagementClass("Win32_Share");
            ManagementBaseObject inParams = managementClass.GetMethodParameters("Create");
            ManagementBaseObject outParams;

            inParams["Description"] = Description;
            inParams["Name"] = ShareName;
            inParams["Path"] = FolderPath;
            inParams["MaximumAllowed"] = null;
            inParams["Password"] = null;
            inParams["Access"] = null;
            inParams["Type"] = 0x0; // Disk Drive

            // 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.");
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message, "error!");
        }
    }
Community
  • 1
  • 1
JimDel
  • 4,309
  • 11
  • 54
  • 99

2 Answers2

3

Permissions on share and underlying folder are separate - your code set ACL on files/folders... So you are missing portion of setting ACL on network share itself.

One gets minimum between permissions on file and share when finally accessing file via share.

I don't know how to set ACL on share but here is a related C++ question that may be good staring point on how to set permissions on shares: How to create read-only network share programmatically?.

Community
  • 1
  • 1
Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
0

Actually I had the opposite problem of yours and your first code snippets solved it for me... Your implementation is just missing a SecurityDescriptor.

 private static ManagementObject GetSecurityDescriptor()
 {
            ManagementObject Trustee = new ManagementClass(new ManagementPath("Win32_Trustee"), null);
            Trustee["SID"] = GetWellKnwonSid(WellKnownSidType.WorldSid);
            Trustee["Name"] = "Everyone";

            ManagementObject userACE = new ManagementClass(new ManagementPath("Win32_Ace"), null);
            userACE["AccessMask"] = 2032127;//Full access
            userACE["AceFlags"] = AceFlags.ObjectInherit | AceFlags.ContainerInherit;
            userACE["AceType"] = AceType.AccessAllowed;
            userACE["Trustee"] = Trustee;

            ManagementObject secDescriptor = new ManagementClass(new ManagementPath("Win32_SecurityDescriptor"), null);
            secDescriptor["ControlFlags"] = 4; //SE_DACL_PRESENT 
            secDescriptor["DACL"] = new object[] { userACE };
            secDescriptor["Group"] = Trustee;
            return secDescriptor;
  }

private static byte[] GetWellKnwonSid(WellKnownSidType SidType)
{
      SecurityIdentifier Result = new SecurityIdentifier(SidType, null);
      byte[] sidArray = new byte[Result.BinaryLength];
      Result.GetBinaryForm(sidArray, 0);

      return sidArray;
}

This you'd have to assign to the Access property the Win32_Share instance

Slime recipe
  • 2,223
  • 3
  • 32
  • 49