647 lines
24 KiB
C#
647 lines
24 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using Intel.Management.Wsman;
|
|
using System.Collections.ObjectModel;
|
|
using System.Management.Automation;
|
|
|
|
namespace Intel.Management.Module.Amt
|
|
{
|
|
class StorageAdminItem : DriveContainer
|
|
{
|
|
|
|
public class EnterpriseAcl : DriveItem
|
|
{
|
|
StorageAdminItem _storageItem;
|
|
|
|
|
|
public EnterpriseAcl(string handle, StorageAdminItem item)
|
|
: base(handle)
|
|
{
|
|
_storageItem = item;
|
|
IManagedInstance outObj = _storageItem.GetEaclEntry(handle);
|
|
_name = outObj.GetProperty("EnterpriseName").ToString();
|
|
_value = uint.Parse(handle);
|
|
}
|
|
|
|
public override void RemoveItem( bool force)
|
|
{
|
|
_storageItem.RemoveEaclEntry(_name);
|
|
_storageItem.RemoveItem(this);
|
|
}
|
|
}
|
|
|
|
private class EnterpriseContainer : DriveContainer
|
|
{
|
|
StorageAdminItem _storageItem;
|
|
|
|
public EnterpriseContainer(StorageAdminItem item) : base("Enterprises")
|
|
{
|
|
_storageItem = item;
|
|
_items = null;
|
|
}
|
|
|
|
public override DriveItem[] GetChildItems(bool force)
|
|
{
|
|
|
|
if (_items == null || force )
|
|
{
|
|
IManagedInstance outObj = _storageItem.GetEaclList();
|
|
|
|
List<DriveItem> list = new List<DriveItem>();
|
|
|
|
IWsmanItem handles = outObj.GetProperty("Handles");
|
|
if (handles!= null)
|
|
{
|
|
foreach (IWsmanItem handle in handles)
|
|
{
|
|
list.Add(new EnterpriseAcl(handle.ToString(), _storageItem));
|
|
}
|
|
}
|
|
list.Sort(_defaultComparer);
|
|
_items = list.ToArray();
|
|
}
|
|
return _items;
|
|
}
|
|
|
|
public override DriveItem NewItem( string name, string type, object newItem, bool force)
|
|
{
|
|
if (!name.Equals(string.Empty))
|
|
{
|
|
string handle = _storageItem.AddEaclEntry(name);
|
|
EnterpriseAcl result = new EnterpriseAcl(handle, _storageItem);
|
|
_storageItem.AddEnterpriseItem(result);
|
|
return result;
|
|
}
|
|
return this;
|
|
}
|
|
}
|
|
|
|
public class PartnerAclDynamicParameters
|
|
{
|
|
public PartnerAclDynamicParameters()
|
|
{
|
|
_maxSize=48*1024; //default to 48K storage
|
|
}
|
|
|
|
[Parameter(Mandatory = false, Position = 2, HelpMessage = "Maximum size in bytes the partner can allocate")]
|
|
public uint TotalAllocationSize
|
|
{
|
|
get
|
|
{
|
|
return _maxSize;
|
|
}
|
|
set
|
|
{
|
|
uint blocksize = (value / (4 * 1024));
|
|
blocksize = blocksize * (4 * 1024);
|
|
if (value > blocksize)
|
|
blocksize = blocksize + (4 * 1024);
|
|
_maxSize = blocksize;
|
|
}
|
|
|
|
}
|
|
uint _maxSize;
|
|
}
|
|
|
|
public class PartnerAcl : DriveItem
|
|
{
|
|
StorageAdminItem _storageItem;
|
|
PartnerAclDynamicParameters _dynamicParams;
|
|
Dictionary<string, object> _props;
|
|
|
|
|
|
public PartnerAcl(Dictionary<string, object> props, StorageAdminItem item)
|
|
: base(props["ApplicationName"].ToString(), "ParnterAcl")
|
|
{
|
|
_props = props;
|
|
_storageItem = item;
|
|
}
|
|
|
|
public override string[] Properties
|
|
{
|
|
get { return _props.Keys.ToArray(); }
|
|
}
|
|
|
|
public override object GetProperty(Collection<string> propList,bool force)
|
|
{
|
|
return GetProperties(_props, propList);
|
|
}
|
|
|
|
public override void SetProperty(PSObject propertyValue, bool force)
|
|
{
|
|
_storageItem.UpdateFpaclEntry(_props["Handle"].ToString(),
|
|
propertyValue.Properties["TotalAllocationSize"].Value.ToString());
|
|
|
|
_props["TotalAllocationSize"] = propertyValue.Properties["TotalAllocationSize"].Value.ToString();
|
|
}
|
|
|
|
public override void RemoveItem( bool force)
|
|
{
|
|
_storageItem.RemoveFpaclEntry(_props["Handle"].ToString());
|
|
_storageItem.RemoveItem(this);
|
|
}
|
|
|
|
public override DriveItem NewItem(string name, string type, object newItem, bool force)
|
|
{
|
|
PartnerAclDynamicParameters localParams = _dynamicParams;
|
|
_dynamicParams=null;
|
|
|
|
if (name.Equals(string.Empty) &&
|
|
!_dynamicParams.TotalAllocationSize.Equals(_props["TotalAllocationSize"]))
|
|
{
|
|
|
|
_storageItem.UpdateFpaclEntry(_props["Handle"].ToString(),
|
|
localParams.TotalAllocationSize.ToString());
|
|
|
|
_props["TotalAllocationSize"] = localParams.TotalAllocationSize;
|
|
|
|
}
|
|
return base.NewItem(name, type, newItem, force);
|
|
}
|
|
public override object NewItemDynamicParameters(string itemTypeName, object newItemValue)
|
|
{
|
|
return _dynamicParams = new PartnerAclDynamicParameters();
|
|
}
|
|
}
|
|
|
|
|
|
public class VendorContainer : DriveContainer
|
|
{
|
|
StorageAdminItem _storageItem;
|
|
|
|
public VendorContainer(string name, StorageAdminItem item)
|
|
: base(name)
|
|
{
|
|
_storageItem = item;
|
|
}
|
|
|
|
public VendorContainer(string handle, Dictionary<string,object> props, StorageAdminItem item)
|
|
: base(props["VendorName"].ToString())
|
|
{
|
|
_storageItem = item;
|
|
|
|
List<DriveItem> list = new List<DriveItem>();
|
|
if (_items != null) list.AddRange(_items);
|
|
|
|
list.Add( new PartnerAcl(props,_storageItem) );
|
|
|
|
_items = list.ToArray();
|
|
}
|
|
|
|
public void RemovePartnerItem(PartnerAcl item)
|
|
{
|
|
List<DriveItem> list = new List<DriveItem>();
|
|
if (_items != null) list.AddRange(_items);
|
|
if (list.Remove(item)) _items = list.ToArray();
|
|
}
|
|
}
|
|
|
|
public class PartnerContainer : DriveContainer
|
|
{
|
|
StorageAdminItem _storageItem;
|
|
PartnerAclDynamicParameters _dynamicParams = null;
|
|
|
|
public PartnerContainer(StorageAdminItem item)
|
|
: base("Partners")
|
|
{
|
|
_storageItem = item;
|
|
_items = null;
|
|
}
|
|
|
|
public override DriveItem[] GetChildItems(bool force)
|
|
{
|
|
if (_items == null || force)
|
|
{
|
|
IManagedInstance outObj = _storageItem.GetFpaclList();
|
|
List<DriveItem> list = new List<DriveItem>();
|
|
|
|
IWsmanItem handles = outObj.GetProperty("Handles");
|
|
if (handles != null)
|
|
{
|
|
foreach (IWsmanItem handle in handles)
|
|
{
|
|
IManagedInstance entryObj = _storageItem.GetFpaclEntry(handle.ToString());
|
|
string vendorName= entryObj.GetProperty("VendorName").ToString();
|
|
|
|
Dictionary<string, object> props = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
|
|
|
|
props.Add("ApplicationName",entryObj.GetProperty("ApplicationName").ToString());
|
|
props.Add("TotalAllocationSize",uint.Parse(entryObj.GetProperty("TotalAllocationSize").ToString()));
|
|
props.Add("VendorName", vendorName);
|
|
props.Add("IsPartner", bool.Parse(entryObj.GetProperty("IsPartner").ToString()));
|
|
props.Add("AttrType", uint.Parse(entryObj.GetProperty("AttrType").ToString()));
|
|
props.Add("Handle", uint.Parse(handle.ToString()));
|
|
|
|
AddPartner(list, props);
|
|
}
|
|
}
|
|
list.Sort(_defaultComparer);
|
|
_items = list.ToArray();
|
|
}
|
|
return _items;
|
|
}
|
|
|
|
private PartnerAcl AddPartner(List<DriveItem> list, Dictionary<string, object> props)
|
|
{
|
|
PartnerAcl result = null;
|
|
string vendorName = props["VendorName"].ToString();
|
|
|
|
//find the vendor container using anynomous delegate
|
|
DriveContainer vendorItem =
|
|
(DriveContainer)list.Find(
|
|
delegate(DriveItem item) { return string.Compare(item.Name, vendorName, true) == 0; }
|
|
);
|
|
|
|
// No vendor container so add one
|
|
if (vendorItem == null)
|
|
{
|
|
vendorItem = new VendorContainer(vendorName, _storageItem);
|
|
list.Add(vendorItem);
|
|
}
|
|
|
|
result = new PartnerAcl(props, _storageItem);
|
|
vendorItem.AddChildItem(result);
|
|
return result;
|
|
|
|
}
|
|
|
|
public override DriveItem NewItem(string name, string type, object newItem, bool force)
|
|
{
|
|
PartnerAclDynamicParameters localParams = _dynamicParams;
|
|
_dynamicParams=null;
|
|
|
|
char[] pathChar = { '\\', '/' };
|
|
string[] names = name.Split(pathChar, StringSplitOptions.RemoveEmptyEntries);
|
|
if (names.Length == 2)
|
|
{
|
|
Dictionary<string, object> props = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
|
|
|
|
props.Add("ApplicationName", names[1]);
|
|
props.Add("TotalAllocationSize", localParams.TotalAllocationSize);
|
|
props.Add("VendorName", names[0]);
|
|
props.Add("IsPartner", true);
|
|
props.Add("AttrType", (uint)1);
|
|
|
|
string handle = _storageItem.AddFpaclEntry(names[1], names[0],
|
|
localParams.TotalAllocationSize.ToString());
|
|
|
|
props.Add("Handle", uint.Parse(handle));
|
|
|
|
List<DriveItem> list = new List<DriveItem>();
|
|
if (_items != null) list.AddRange(_items);
|
|
PartnerAcl result = AddPartner(list, props);
|
|
_items = list.ToArray();
|
|
return result;
|
|
}
|
|
return base.NewItem(name, type, newItem, force);
|
|
|
|
}
|
|
|
|
public override object NewItemDynamicParameters(string itemTypeName, object newItemValue)
|
|
{
|
|
return _dynamicParams = new PartnerAclDynamicParameters();
|
|
}
|
|
|
|
public void RemovePartnerItem(PartnerAcl item)
|
|
{
|
|
foreach (VendorContainer vendor in _items)
|
|
{
|
|
vendor.RemovePartnerItem(item);
|
|
}
|
|
}
|
|
}
|
|
|
|
public class RegisteredItem : DriveItem
|
|
{
|
|
StorageAdminItem _storageItem;
|
|
Dictionary<string, object> _props;
|
|
|
|
public RegisteredItem(string name, StorageAdminItem item)
|
|
: base(name, "StorgeApplication")
|
|
{
|
|
_props = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
|
|
_props.Add("AttrType", null);
|
|
_props.Add("UUID", null);
|
|
_props.Add("VendorName", null);
|
|
_props.Add("ApplicationName", null);
|
|
_props.Add("EnterpriseName", null);
|
|
_props.Add("CurrentAllocationSize", null);
|
|
_props.Add("ActiveSession", null);
|
|
_props.Add("Partner", null);
|
|
_props.Add("Handle", null);
|
|
|
|
_storageItem = item;
|
|
}
|
|
|
|
|
|
public override string[] Properties
|
|
{
|
|
get { return _props.Keys.ToArray(); }
|
|
}
|
|
|
|
|
|
public override object GetProperty(Collection<string> propList, bool force)
|
|
{
|
|
if (_props["ApplicationName"] == null)
|
|
{
|
|
IManagedInstance outObj = _storageItem.GetApplicationAttributes(_name);
|
|
_props["VendorName"] = outObj.GetProperty("VendorName").ToString();
|
|
//convert UUID to string
|
|
Guid uuid = new Guid(Convert.FromBase64String(outObj.GetProperty("UUID").ToString()));
|
|
_props["UUID"] = uuid.ToString();
|
|
|
|
_props["ApplicationName"] = outObj.GetProperty("ApplicationName").ToString();
|
|
_props["EnterpriseName"] = outObj.GetProperty("EnterpriseName").ToString();
|
|
_props["CurrentAllocationSize"] = uint.Parse(outObj.GetProperty("CurrentAllocationSize").ToString());
|
|
_props["ActiveSession"] = bool.Parse(outObj.GetProperty("ActiveSession").ToString());
|
|
_props["Partner"] = bool.Parse(outObj.GetProperty("Partner").ToString());
|
|
_props["AttrType"] = uint.Parse(outObj.GetProperty("AttrType").ToString());
|
|
_props["Handle"] = uint.Parse(_name);
|
|
}
|
|
|
|
return GetProperties(_props, propList);
|
|
}
|
|
|
|
public override void SetProperty(PSObject propertyValue, bool force)
|
|
{
|
|
_storageItem.UpdateFpaclEntry(_name,
|
|
propertyValue.Properties["TotalAllocationSize"].Value.ToString());
|
|
}
|
|
}
|
|
|
|
|
|
public class RegistrationsContainer : DriveContainer
|
|
{
|
|
StorageAdminItem _storageItem;
|
|
|
|
|
|
public RegistrationsContainer(StorageAdminItem item)
|
|
: base("Registrations")
|
|
{
|
|
_storageItem = item;
|
|
_items = null;
|
|
}
|
|
|
|
public override DriveItem[] GetChildItems(bool force)
|
|
{
|
|
if (_items == null || force)
|
|
{
|
|
IManagedInstance outObj = _storageItem.GetRegisteredApps();
|
|
|
|
List<DriveItem> list = new List<DriveItem>();
|
|
|
|
IWsmanItem handles = outObj.GetProperty("ApplicationHandles");
|
|
if (handles != null)
|
|
{
|
|
foreach (IWsmanItem handle in handles)
|
|
{
|
|
list.Add(new RegisteredItem(handle.ToString(), _storageItem));
|
|
}
|
|
}
|
|
_items = list.ToArray();
|
|
}
|
|
return _items;
|
|
}
|
|
}
|
|
|
|
|
|
IManagedReference _storageAdminRef;
|
|
EnterpriseContainer _enterprises;
|
|
PartnerContainer _partners;
|
|
string[] _properties;
|
|
|
|
public StorageAdminItem(AmtDriveInfo info) : base("Storage")
|
|
{
|
|
_items = null;
|
|
_storageAdminRef = info.WsmanConnection.NewReference("AMT_ThirdPartyDataStorageAdministrationService");
|
|
}
|
|
|
|
public override DriveItem[] GetChildItems(bool force)
|
|
{
|
|
if (_items == null)
|
|
{
|
|
|
|
//RemoveEaclEntry("\\Microsoft");
|
|
//RemoveEaclEntry("\\bubba");
|
|
//RemoveEaclEntry("\\bubba2");
|
|
|
|
List<DriveItem> list = new List<DriveItem>();
|
|
_enterprises = new EnterpriseContainer(this);
|
|
_partners = new PartnerContainer(this);
|
|
|
|
list.Add(_enterprises);
|
|
list.Add(_partners);
|
|
list.Add(new RegistrationsContainer(this));
|
|
|
|
list.Sort(_defaultComparer);
|
|
_items = list.ToArray();
|
|
}
|
|
return _items;
|
|
|
|
}
|
|
|
|
|
|
private void RemoveItem(DriveItem item)
|
|
{
|
|
if (item is EnterpriseAcl)
|
|
{
|
|
_enterprises.RemoveChildItem(item);
|
|
}
|
|
else if (item is PartnerAcl)
|
|
{
|
|
_partners.RemovePartnerItem((PartnerAcl)item);
|
|
}
|
|
//else if (item is P
|
|
}
|
|
|
|
|
|
private void AddEnterpriseItem(DriveItem item)
|
|
{
|
|
_enterprises.AddChildItem(item);
|
|
}
|
|
|
|
|
|
|
|
public override string[] Properties
|
|
{
|
|
get
|
|
{
|
|
if (_properties == null)
|
|
{
|
|
String[] props = {"TotalStorage",
|
|
"TotalAllocatedStorage",
|
|
"MaxPartnerStorage",
|
|
"TotalPartnerAllocatedStorage",
|
|
"MaxNonPartnerStorage",
|
|
"MaxFpaclEntries",
|
|
"MaxAslEntries",
|
|
"MaxEaclEntries",
|
|
"MaxGroupsPerBlock",
|
|
"MaxMembersPerGroup",
|
|
"MaxNonPartnerTotalAllocationSize",};
|
|
_properties = props;
|
|
}
|
|
return _properties;
|
|
}
|
|
}
|
|
|
|
|
|
private IManagedInstance GetGlobalStorageAttributes()
|
|
{
|
|
IManagedInstance inputObj = _storageAdminRef.CreateMethodInput("GetGlobalStorageAttributes");
|
|
IManagedInstance outObj = _storageAdminRef.InvokeMethod(inputObj);
|
|
StorageItem.StorageOperationException.CheckResult(outObj);
|
|
return outObj;
|
|
}
|
|
|
|
|
|
private IManagedInstance SetGlobalStorageAttributes(string name, string value)
|
|
{
|
|
IManagedInstance inputObj = _storageAdminRef.CreateMethodInput("SetGlobalStorageAttributes");
|
|
inputObj.SetProperty(name, value);
|
|
IManagedInstance outObj = _storageAdminRef.InvokeMethod(inputObj);
|
|
StorageItem.StorageOperationException.CheckResult(outObj);
|
|
return outObj;
|
|
}
|
|
|
|
|
|
private IManagedInstance GetEaclEntry(string handle)
|
|
{
|
|
IManagedInstance inputObj = _storageAdminRef.CreateMethodInput("GetStorageEaclEntry");
|
|
inputObj.SetProperty("Handle", handle);
|
|
IManagedInstance outObj = _storageAdminRef.InvokeMethod(inputObj);
|
|
StorageItem.StorageOperationException.CheckResult(outObj);
|
|
return outObj;
|
|
}
|
|
|
|
private IManagedInstance GetFpaclEntry(string handle)
|
|
{
|
|
IManagedInstance inputObj = _storageAdminRef.CreateMethodInput("GetStorageAllocEntry");
|
|
inputObj.SetProperty("Handle", handle);
|
|
IManagedInstance outObj = _storageAdminRef.InvokeMethod(inputObj);
|
|
StorageItem.StorageOperationException.CheckResult(outObj);
|
|
return outObj;
|
|
}
|
|
|
|
|
|
private IManagedInstance GetEaclList()
|
|
{
|
|
IManagedInstance inputObj = _storageAdminRef.CreateMethodInput("EnumerateStorageEaclEntries");
|
|
IManagedInstance outObj = _storageAdminRef.InvokeMethod(inputObj);
|
|
StorageItem.StorageOperationException.CheckResult(outObj);
|
|
return outObj;
|
|
}
|
|
|
|
private IManagedInstance GetFpaclList()
|
|
{
|
|
IManagedInstance inputObj = _storageAdminRef.CreateMethodInput("EnumerateStorageAllocEntries");
|
|
IManagedInstance outObj = _storageAdminRef.InvokeMethod(inputObj);
|
|
StorageItem.StorageOperationException.CheckResult(outObj);
|
|
|
|
return outObj;
|
|
}
|
|
|
|
private IManagedInstance GetRegisteredApps()
|
|
{
|
|
IManagedInstance inputObj = _storageAdminRef.CreateMethodInput("AdminGetRegisteredApplications");
|
|
IManagedInstance outObj = _storageAdminRef.InvokeMethod(inputObj);
|
|
StorageItem.StorageOperationException.CheckResult(outObj);
|
|
return outObj;
|
|
}
|
|
|
|
private string AddEaclEntry(string name)
|
|
{
|
|
IManagedInstance inputObj = _storageAdminRef.CreateMethodInput("AddStorageEaclEntry");
|
|
inputObj.SetProperty("EnterpriseName",name);
|
|
IManagedInstance outObj = _storageAdminRef.InvokeMethod(inputObj);
|
|
StorageItem.StorageOperationException.CheckResult(outObj);
|
|
return outObj.GetProperty("Handle").ToString();
|
|
}
|
|
|
|
private string AddFpaclEntry(string appName, string vendor, string size)
|
|
{
|
|
IManagedInstance inputObj = _storageAdminRef.CreateMethodInput("AddStorageFpaclEntry");
|
|
inputObj = _storageAdminRef.CreateMethodInput("AddStorageFpaclEntry");
|
|
inputObj.SetProperty("AttrType","1");
|
|
inputObj.SetProperty("ApplicationName",appName);
|
|
inputObj.SetProperty("VendorName",vendor);
|
|
inputObj.SetProperty("IsPartner", "true");
|
|
inputObj.SetProperty("TotalAllocationSize",size);
|
|
IManagedInstance outObj = _storageAdminRef.InvokeMethod(inputObj);
|
|
StorageItem.StorageOperationException.CheckResult(outObj);
|
|
return outObj.GetProperty("Handle").ToString();
|
|
}
|
|
|
|
private void RemoveEaclEntry(string handle)
|
|
{
|
|
IManagedInstance inputObj = _storageAdminRef.CreateMethodInput("RemoveStorageEaclEntry");
|
|
inputObj.SetProperty("Handle", handle);
|
|
IManagedInstance outObj = _storageAdminRef.InvokeMethod(inputObj);
|
|
StorageItem.StorageOperationException.CheckResult(outObj);
|
|
}
|
|
|
|
private void RemoveFpaclEntry(string handle)
|
|
{
|
|
IManagedInstance inputObj = _storageAdminRef.CreateMethodInput("RemoveStorageFpaclEntry");
|
|
inputObj.SetProperty("Handle", handle);
|
|
IManagedInstance outObj = _storageAdminRef.InvokeMethod(inputObj);
|
|
StorageItem.StorageOperationException.CheckResult(outObj);
|
|
}
|
|
|
|
private void UpdateFpaclEntry(string handle, string newSize)
|
|
{
|
|
IManagedInstance inputObj = _storageAdminRef.CreateMethodInput("UpdateStorageFpaclEntry");
|
|
inputObj.SetProperty("Handle", handle);
|
|
inputObj.SetProperty("NewAllocationSize", newSize);
|
|
IManagedInstance outObj = _storageAdminRef.InvokeMethod(inputObj);
|
|
StorageItem.StorageOperationException.CheckResult(outObj);
|
|
}
|
|
|
|
private IManagedInstance GetApplicationAttributes(string handle)
|
|
{
|
|
IManagedInstance inputObj = _storageAdminRef.CreateMethodInput("AdminGetApplicationAttributes");
|
|
inputObj.SetProperty("Handle", handle);
|
|
IManagedInstance outObj = _storageAdminRef.InvokeMethod(inputObj);
|
|
StorageItem.StorageOperationException.CheckResult(outObj);
|
|
return outObj;
|
|
}
|
|
|
|
|
|
public override object GetProperty(Collection<string> propList, bool force)
|
|
{
|
|
IManagedInstance outObj = GetGlobalStorageAttributes();
|
|
Dictionary<string, object> props = new Dictionary<string, object>();
|
|
|
|
foreach (string propName in Properties)
|
|
{
|
|
props.Add(propName, uint.Parse(outObj.GetProperty(propName).ToString()));
|
|
}
|
|
return GetProperties(props, propList);
|
|
}
|
|
|
|
public override void SetProperty(PSObject propertyValue, bool force)
|
|
{
|
|
string name=null;
|
|
string value=null;
|
|
foreach (PSPropertyInfo propInfo in propertyValue.Properties)
|
|
{
|
|
name=propInfo.Name;
|
|
value = propInfo.Value.ToString();
|
|
|
|
}
|
|
|
|
if (name == null ||
|
|
(string.Compare("MaxPartnerStorage", name, true) != 0 &&
|
|
string.Compare("MaxNonPartnerTotalAllocationSize", name, true) != 0))
|
|
new PSArgumentException();
|
|
|
|
SetGlobalStorageAttributes(name, value);
|
|
|
|
}
|
|
|
|
|
|
}
|
|
}
|