共有フォルダの作成、アクセス権の設定、編集。

中身はWMI
元ねたはどっかの海外サイト。(ごめんURL手元にないや)


参照設定は Systesm.Managemant
vista 以降は管理者での起動が必要。
まずはアクセス権限

/// <summary>
/// ユーザのアクセス権限
/// </summary>
public enum ShareMode : uint {
  /// <summary>
  /// 読み取り。
  /// </summary>
  SHARE_READ = 0x1200A9,

  /// <summary>
  /// 変更。
  /// </summary>
  SHARE_CHANGE = 0x1301BF,

  /// <summary>
  /// フルアクセス。
  /// </summary>
  SHARE_FULL = 0x1F01FF,
}


ユーザーとアクセス権限

/// <summary>
/// 共有ユーザー。
/// </summary>
public struct ShareUser {
  /// <summary>
  /// 共有権限を取得または設定します。
  /// </summary>
  public ShareMode ShareMode { get; set; }

  /// <summary>
  /// アカウント名を取得または設定します。
  /// </summary>
  public string AccountName { get; set; }
}

んで本体。

/// <summary>
/// フォルダ共有に関する設定。
/// </summary>
static public class Share {
  /// <summary>
  /// 共有フォルダを作成します。
  /// </summary>
  /// <param name="path">共有するフォルダのパス。</param>
  /// <param name="sharename">共有名。</param>
  /// <param name="description">共有</param>
  /// <param name="description">設定する共有フォルダのコメントを指定します。</param>
  /// <param name="shareUsers">設定フル共有フォルダのアクセス権を指定します。</param>
  public static void Create( string path, string sharename, string description, params ShareUser[] shareUsers ) {
    ManagementClass mc = new ManagementClass( "Win32_Share" );
    // Create ManagementBaseObjects for in and out parameters
    ManagementBaseObject inParams = mc.GetMethodParameters( "Create" );
    // Set the input parameters
    inParams["Description"] = description;
    inParams["Name"] = sharename;
    inParams["Path"] = path;
    inParams["Type"] = 0x0; // Disk Drive
    inParams["Access"] = GetSecurityDescriptor( shareUsers );
    // Invoke the method on the ManagementClass object
    ManagementBaseObject outParams = mc.InvokeMethod( "Create", inParams, null );
    // Check to see if the method invocation was successful
    uint result = (uint)( outParams.Properties["ReturnValue"].Value );

    if ( result != 0 ) {
      throw new ManagementException( String.Format( "Error code : {0}.", result ) );
    }
  }

  /// <summary>
  /// 共有フォルダの設定を変更します。
  /// </summary>
  /// <param name="shareName">設定する共有名を指定します。</param>
  /// <param name="shareUsers">設定フル共有フォルダのアクセス権を指定します。</param>
  public static void ChangeStatus( string shareName, params ShareUser[] shareUsers ) {
    ChangeStatus( shareName, null, null, shareUsers );
  }

  /// <summary>
  /// 共有フォルダの設定を変更します。
  /// </summary>
  /// <param name="shareName">設定する共有名を指定します。</param>
  /// <param name="shareUserCount">設定する同時共有ユーザー数。</param>
  /// <param name="description">設定する共有フォルダのコメント。</param>
  /// <param name="shareUsers">設定フル共有フォルダのアクセス権。</param>
  public static void ChangeStatus( string shareName, int? shareUserCount, string description, params ShareUser[] shareUsers ) {
    ManagementBaseObject descriptor = GetDescriptor( shareName );
    descriptor["DACL"] = GetAces( shareUsers );

    ManagementObject share = new ManagementObject(
      string.Format( @"\root\cimv2:Win32_Share.Name='{0}'", shareName )
    );

    uint result = (uint)share.InvokeMethod( "SetShareInfo", new object[] { shareUserCount, description, descriptor } );

    if ( result != 0 ) {
      throw new ManagementException( String.Format( "Error code : {0}.", result ) );
    }
  }

  /// <summary>
  /// アカウント名を元に SID のバイト配列を作成します。
  /// </summary>
  /// <param name="accountName">アカウント名。</param>
  /// <returns>作成された SID のバイト配列。</returns>
  private static byte[] CreateSidBinary( string accountName ) {
    NTAccount account = new NTAccount( accountName );
    SecurityIdentifier sid = (SecurityIdentifier)account.Translate( typeof( SecurityIdentifier ) );
    byte[] sidArray = new byte[sid.BinaryLength];
    sid.GetBinaryForm( sidArray, 0 );
    return sidArray;
  }

  /// <summary>
  /// Access Control Entry の配列を取得します。
  /// </summary>
  /// <param name="shareUsers">Access Control Entry を取得する複数のユーザ。</param>
  /// <returns>取得された Access Control Entry の配列。</returns>
  private static ManagementBaseObject[] GetAces( ShareUser[] shareUsers ) {
    ManagementBaseObject[] aces = new ManagementBaseObject[shareUsers.Length];
    for ( int i = 0; i < shareUsers.Length; i++ ) {
      aces[i] = GetAce( shareUsers[i] );
    }

    return aces;
  }

  /// <summary>
  /// Access Control Entry を取得します。
  /// </summary>
  /// <param name="shareUsers">Access Control Entry を取得するユーザ。</param>
  /// <returns>取得された Access Control Entry。</returns>
  private static ManagementObject GetAce( ShareUser shareUser ) {
    ManagementObject trustee = new ManagementClass( new ManagementPath( "Win32_Trustee" ), null );
    trustee["SID"] = CreateSidBinary( shareUser.AccountName );

    ManagementObject ace = new ManagementClass( new ManagementPath( "Win32_Ace" ), null );
    ace["AccessMask"] = shareUser.ShareMode;
    ace["AceFlags"] = AceFlags.ObjectInherit | AceFlags.ContainerInherit;
    ace["AceType"] = AceType.AccessAllowed;
    ace["Trustee"] = trustee;
    return ace;
  }

  /// <summary>
  /// Security Descriptor を取得します。
  /// </summary>
  /// <param name="shareUsers">Security Descriptor を取得するユーザ。</param>
  /// <returns>取得された Security Descriptor。</returns>
  private static ManagementBaseObject GetSecurityDescriptor( params ShareUser[] shareUsers ) {
    ManagementObject securityDescriptor = new ManagementClass( new ManagementPath( "Win32_SecurityDescriptor" ), null );
    securityDescriptor["ControlFlags"] = 4; //SE_DACL_PRESENT
    securityDescriptor["DACL"] = GetAces( shareUsers );
    return securityDescriptor;
  }

  /// <summary>
  /// 指定された共有フォルダの Security Descriptor を取得します。 
  /// </summary>
  /// <param name="shareName">Security Descriptor を取得する共有名。</param>
  /// <returns>取得された共有フォルダの Security Descriptor。</returns>
  private static ManagementBaseObject GetDescriptor( string shareName ) {
    //After we have the new Win_32Ace, now we need to get the existing Ace instances (DACL).
    //Create an instance of Win32_LogicalSecuritySetting, set the path to the server and the share.
    ManagementObject win32LogicalSecuritySetting = new ManagementObject(
      string.Format( @"\root\cimv2:Win32_LogicalShareSecuritySetting.Name='{0}'", shareName )
    );

    //Call the GetSecurityDescriptor method. This method returns one out parameter.
    ManagementBaseObject securityDescriptor = win32LogicalSecuritySetting.InvokeMethod( "GetSecurityDescriptor", null, null );

    //The return value of that call above has two properties, ReturnValue, which you can use
    //to read the status of the call (failed, success, etc.), and Descriptor, which is an instance
    //of Win32_SecurityDescriptor.
    uint result = (uint)securityDescriptor.Properties["ReturnValue"].Value;

    if ( result != 0 ) {
      throw new ManagementException( String.Format( "Error code : {0}.", result ) );
    }

    //Retrieve the array of DACL from the Security Descriptor.
    return (ManagementBaseObject)securityDescriptor.Properties["Descriptor"].Value;
  }
}

使い方

// TestってユーザーとEveryoneってユーザーにフル権限を与える。
// d:\temp を temp って名前でフォルダを共有化する。アクセス権の設定はなし。
Share.Create( @"d:\temp", "temp", "" );

// アクセス権を与えるユーザの設定。
ShareUser[] shareUsers = new [] {
  new ShareUser { ShareMode = ShareMode.SHARE_FULL, AccountName = "test" },
  new ShareUser { ShareMode = ShareMode.SHARE_FULL, AccountName = "everyone" },
};

// temp って共有に対してアクセス権の付与
Share.ChangeStatus( "temp", shareUsers );

// temp って共有に対してアクセス権の削除
Share.ChangeStatus( "temp" );

ツール(DOSコマンド)でやるなら
net share