Пример #1
0
        public bool SplitPrograms(Guid from, ProgramID progID)
        {
            ProgramSet from_prog;

            if (!ProgramSets.TryGetValue(from, out from_prog) || from_prog.IsSpecial())
            {
                return(false);
            }

            if (from_prog.Programs.Count == 1)
            {
                return(true); // nothing to do
            }
            Program prog = null;

            if (!from_prog.Programs.TryGetValue(progID, out prog))
            {
                return(true);                          // no found
            }
            ProgramSet to_prog = new ProgramSet(prog); // prog.AssignSet taked care of the internal associaltions

            to_prog.config.Category = from_prog.config.Category;
            ProgramSets.Add(to_prog.guid, to_prog);

            App.engine.FirewallManager.EvaluateRules(from_prog);
            App.engine.FirewallManager.EvaluateRules(to_prog);

            Changed?.Invoke(this, new ListEvent());

            return(true);
        }
Пример #2
0
        protected ProgramSet GetProgSet(byte[] value)
        {
            ProgramSet Progs = new ProgramSet();

            using (MemoryStream dataStream = new MemoryStream(value))
            {
                using (var dataReader = new BinaryReader(dataStream))
                {
                    Progs.guid = new Guid(dataReader.ReadBytes(16));

                    int    length = dataReader.ReadInt32();
                    byte[] data   = dataReader.ReadBytes(length);
                    Progs.config = GetConfig(data);

                    int count = dataReader.ReadInt32();
                    for (int i = 0; i < count; i++)
                    {
                        length = dataReader.ReadInt32();
                        Program prog = GetProg(dataReader.ReadBytes(length));
                        //Program knownProg;
                        //if (Progs.Programs.TryGetValue(prog.ID, out knownProg)) {...} else
                        prog.AssignSet(Progs);
                    }
                }
            }
            return(Progs);
        }
Пример #3
0
        public TrayIcon()
        {
            this.components  = new Container();
            this.contextMenu = new ContextMenu();

            // Initialize menuItem1
            this.menuBlock       = new MenuItem();
            this.menuBlock.Index = 0;
            this.menuBlock.Text  = Translate.fmt("mnu_block");

            ProgramID  id   = ProgramID.NewID(ProgramID.Types.Global);
            ProgramSet prog = App.client.GetProgram(id, true);

            if (prog == null)
            {
                this.menuBlock.Enabled = false;
            }
            else
            {
                this.menuBlock.Checked = (prog.config.CurAccess == ProgramSet.Config.AccessLevels.BlockAccess);
            }

            this.menuBlock.Click += new System.EventHandler(this.menuBlock_Click);

            // Initialize menuItem1
            this.menuExit        = new MenuItem();
            this.menuExit.Index  = 0;
            this.menuExit.Text   = Translate.fmt("mnu_exit");
            this.menuExit.Click += new System.EventHandler(this.menuExit_Click);

            // Initialize contextMenu1
            this.contextMenu.MenuItems.AddRange(new MenuItem[] { this.menuBlock, new MenuItem("-"), this.menuExit });

            // Create the NotifyIcon.
            this.notifyIcon = new NotifyIcon(this.components);

            string exePath = System.Reflection.Assembly.GetExecutingAssembly().Location;

            // The Icon property sets the icon that will appear
            // in the systray for this application.
            //notifyIcon1.Icon = new Icon("wu.ico");
            notifyIcon.Icon = System.Drawing.Icon.ExtractAssociatedIcon(exePath);

            // The ContextMenu property sets the menu that will
            // appear when the systray icon is right clicked.
            notifyIcon.ContextMenu = this.contextMenu;

            // The Text property sets the text that will be displayed,
            // in a tooltip, when the mouse hovers over the systray icon.
            notifyIcon.Text = FileVersionInfo.GetVersionInfo(exePath).FileDescription;

            // Handle the DoubleClick event to activate the form.
            notifyIcon.DoubleClick += new System.EventHandler(this.notifyIcon1_DoubleClick);
            notifyIcon.Click       += new System.EventHandler(this.notifyIcon1_Click);

            mTimer.Tick    += new EventHandler(OnTimerTick);
            mTimer.Interval = new TimeSpan(0, 0, 0, 0, 500);
            mTimer.Start();
        }
Пример #4
0
        public override bool Sync(bool CleanUp = false)
        {
            var rules = App.client.GetRules(new List <Guid>()
            {
                ProgSetId
            });

            List <FirewallRuleEx> list;

            if (rules == null || !rules.TryGetValue(ProgSetId, out list))
            {
                return(false);
            }

            Dictionary <string, SingleRule> oldRules = new Dictionary <string, SingleRule>(Rules);

            foreach (var rule in list)
            {
                if (Rules.ContainsKey(rule.guid))
                {
                    oldRules.Remove(rule.guid);
                }
                else
                {
                    Rules.Add(rule.guid, new SingleRule()
                    {
                        RuleId = rule.guid
                    });
                }
            }

            if (CleanUp)
            {
                foreach (string key in oldRules.Keys)
                {
                    Rules.Remove(key);
                }
            }

            List <ProgramSet> progs = App.client.GetPrograms(new List <Guid>()
            {
                ProgSetId
            });

            if (progs.Count == 0)
            {
                return(false);
            }
            ProgramSet progSet = progs[0];

            Name = progSet.config.Name;
            if (Icon.Length == 0)
            {
                Icon = progSet.GetIcon();
            }

            return(true);
        }
Пример #5
0
        public bool LoadList()
        {
            if (!File.Exists(App.dataPath + @"\Programs.xml"))
            {
                return(false);
            }

            try
            {
                XmlDocument xDoc = new XmlDocument();
                xDoc.Load(App.dataPath + @"\Programs.xml");

                double fileVersion = 0.0;
                double.TryParse(xDoc.DocumentElement.GetAttribute("Version"), out fileVersion);
                if (fileVersion != xmlVersion)
                {
                    App.LogError("Failed to load programlist, unknown file version {0}, expected {1}", fileVersion, xmlVersion);
                    return(false);
                }

                int TotalCount = 0;
                int ErrorCount = 0;

                foreach (XmlNode node in xDoc.DocumentElement.ChildNodes)
                {
                    TotalCount++;
                    ProgramSet entry = new ProgramSet();
                    if (!entry.LoadSet(node))
                    {
                        ErrorCount++;
                        continue;
                    }

                    ProgramSets.Add(entry.guid, entry);

                    foreach (Program prog in entry.Programs.Values)
                    {
                        Programs.Add(prog.ID, prog);
                    }
                }

                if (ErrorCount != 0)
                {
                    App.LogError("Failed to load {0} program entry out of {1}", ErrorCount, TotalCount);
                }
                App.LogInfo("ProgramList loaded {0} entries", TotalCount - ErrorCount);
            }
            catch (Exception err)
            {
                AppLog.Exception(err);
                return(false);
            }
            return(true);
        }
Пример #6
0
        public void AssignSet(ProgramSet progSet)
        {
            // unlink old config
            if (ProgSet != null)
            {
                ProgSet.Programs.Remove(ID);
            }

            // link program with its config
            ProgSet = progSet;
            ProgSet.Programs.Add(ID, this);
        }
Пример #7
0
        public override bool SetState(bool State)
        {
            List <ProgramSet> progs = App.client.GetPrograms(new List <Guid>()
            {
                ProgSetId
            });

            if (progs.Count == 0)
            {
                return(false);
            }
            ProgramSet progSet = progs[0];

            progSet.config.NetAccess = State ? this.OnState : this.OffState;

            if (!App.client.UpdateProgram(ProgSetId, progSet.config))
            {
                return(false);
            }

            if (progSet.config.NetAccess == ProgramConfig.AccessLevels.CustomConfig)
            {
                var progRules = App.client.GetRules(progs.Select(x => x.guid).ToList());

                foreach (var ruleList in progRules)
                {
                    foreach (FirewallRuleEx ruleEntry in ruleList.Value)
                    {
                        SingleRule rule;
                        if (Rules.TryGetValue(ruleEntry.guid, out rule))
                        {
                            bool RuleState = ruleEntry.Enabled;
                            if (State && rule.OnState != null)
                            {
                                RuleState = rule.OnState.Value;
                            }
                            else if (State == false && rule.OffState != null)
                            {
                                RuleState = rule.OffState.Value;
                            }
                            if (ruleEntry.Enabled != RuleState)
                            {
                                ruleEntry.Enabled = RuleState;
                                App.client.UpdateRule(ruleEntry);
                            }
                        }
                    }
                }
            }

            return(true);
        }
Пример #8
0
        public override bool Sync(bool CleanUp = false)
        {
            var rules = App.client.GetRules(new List <Guid>()
            {
                ProgSetId
            });

            if (rules == null)
            {
                return(false);
            }

            Dictionary <string, SingleRule> oldRules = new Dictionary <string, SingleRule>(Rules);

            foreach (var rule in rules[ProgSetId])
            {
                if (Rules.ContainsKey(rule.guid))
                {
                    oldRules.Remove(rule.guid);
                }
                else
                {
                    Rules.Add(rule.guid, new SingleRule()
                    {
                        RuleId = rule.guid
                    });
                }
            }

            if (CleanUp)
            {
                foreach (string key in oldRules.Keys)
                {
                    Rules.Remove(key);
                }
            }

            List <ProgramSet> progs = App.client.GetPrograms(new List <Guid>()
            {
                ProgSetId
            });

            if (progs.Count == 0)
            {
                return(false);
            }
            ProgramSet progSet = progs[0];

            Name = progSet.config.Name;

            return(true);
        }
Пример #9
0
        public bool RemoveProgram(Guid guid, ProgramID id = null)
        {
            ProgramSet progs = null;

            if (!ProgramSets.TryGetValue(guid, out progs) || progs.IsSpecial())
            {
                return(false); // already gone or can not be removed
            }
            List <ProgramID> IDs = new List <ProgramID>();

            if (id != null)
            {
                IDs.Add(id);
            }
            else
            {
                IDs = progs.Programs.Keys.ToList();
            }

            foreach (ProgramID progID in IDs)
            {
                Program prog;
                if (!Programs.TryGetValue(progID, out prog))
                {
                    continue; // already gone
                }
                progs.Programs.Remove(progID);

                Programs.Remove(progID);

                foreach (FirewallRule rule in prog.Rules.Values)
                {
                    App.engine.FirewallManager.RemoveRule(rule.guid);
                }

                foreach (NetworkSocket socket in prog.Sockets.Values)
                {
                    socket.Assigned = false;
                }
            }

            if (progs.Programs.Count == 0)
            {
                ProgramSets.Remove(guid);
            }

            Changed?.Invoke(this, new ListEvent());

            return(true);
        }
Пример #10
0
        private void UpdateFwMode()
        {
            ProgramID  id   = ProgramID.NewID(ProgramID.Types.Global);
            ProgramSet prog = App.client.GetProgram(id, true);

            if (prog == null)
            {
                this.menuBlock.Enabled = false;
            }
            else
            {
                this.menuBlock.Checked = prog.config.CurAccess == ProgramConfig.AccessLevels.BlockAccess;
            }

            UpdateMode();
        }
Пример #11
0
        private Program AddProgram(ProgramID progID)
        {
            Program prog = new Program(progID);

            Programs.Add(progID, prog);

            ProgramSet progs = new ProgramSet(prog);

            ProgramSets.Add(progs.guid, progs);

            Changed?.Invoke(this, new ListEvent()
            {
                guid = progs.guid
            });

            return(prog);
        }
Пример #12
0
        protected byte[] PutProgSet(ProgramSet Progs)
        {
            using (MemoryStream dataStream = new MemoryStream())
            {
                using (var dataWriter = new BinaryWriter(dataStream))
                {
                    dataWriter.Write(Progs.guid.ToByteArray());

                    byte[] data = PutConfig(Progs.config);
                    dataWriter.Write(data.Length);
                    dataWriter.Write(data);

                    dataWriter.Write(Progs.Programs.Count);
                    foreach (var item in Progs.Programs)
                    {
                        data = PutProg(item.Value);
                        dataWriter.Write(data.Length);
                        dataWriter.Write(data);
                    }
                }
                return(dataStream.ToArray());
            }
        }
Пример #13
0
        public void ApplyRules(ProgramSet progSet, UInt64 expiration = 0)
        {
            EvaluateRules(progSet, true);

            if (progSet.config.NetAccess == ProgramConfig.AccessLevels.Unconfigured)
            {
                return;
            }

            if (progSet.config.NetAccess == progSet.config.CurAccess)
            {
                return;
            }

            foreach (Program prog in progSet.Programs.Values)
            {
                ClearRules(prog, progSet.config.NetAccess != ProgramConfig.AccessLevels.CustomConfig);

                if (progSet.config.NetAccess == ProgramConfig.AccessLevels.CustomConfig)
                {
                    continue; // dont create any rules
                }
                for (int i = 1; i <= 2; i++)
                {
                    FirewallRule.Directions direction = (FirewallRule.Directions)i;

                    if ((progSet.config.NetAccess == ProgramConfig.AccessLevels.InBoundAccess && direction != FirewallRule.Directions.Inbound) ||
                        (progSet.config.NetAccess == ProgramConfig.AccessLevels.OutBoundAccess && direction != FirewallRule.Directions.Outbound))
                    {
                        continue;
                    }

                    switch (progSet.config.NetAccess)
                    {
                    case ProgramConfig.AccessLevels.FullAccess:
                    case ProgramConfig.AccessLevels.InBoundAccess:
                    case ProgramConfig.AccessLevels.OutBoundAccess:
                    {
                        // add and enable allow all rule
                        FirewallRule rule = new FirewallRule();
                        FirewallRuleEx.SetProgID(rule, prog.ID);
                        rule.Name      = MakeRuleName(AllowAllName, expiration != 0, prog.Description);
                        rule.Grouping  = RuleGroup;
                        rule.Action    = FirewallRule.Actions.Allow;
                        rule.Direction = direction;
                        rule.Enabled   = true;
                        ApplyRule(prog, rule, expiration);
                        break;
                    }

                    case ProgramConfig.AccessLevels.LocalOnly:
                    {
                        // create block rule only of we operate in blacklist mode
                        //if (GetFilteringMode() == FilteringModes.BlackList)
                        //{
                        //add and enable block rules for the internet
                        FirewallRule rule1 = new FirewallRule();
                        FirewallRuleEx.SetProgID(rule1, prog.ID);
                        rule1.Name      = MakeRuleName(BlockInet, expiration != 0, prog.Description);
                        rule1.Grouping  = RuleGroup;
                        rule1.Action    = FirewallRule.Actions.Block;
                        rule1.Direction = direction;
                        rule1.Enabled   = true;
                        if (UwpFunc.IsWindows7OrLower)
                        {
                            rule1.RemoteAddresses = GetSpecialNet(FirewallRule.AddrKeywordIntErnet);
                        }
                        else
                        {
                            rule1.RemoteAddresses = FirewallRule.AddrKeywordIntErnet;
                        }
                        ApplyRule(prog, rule1, expiration);
                        //}

                        //add and enable allow rules for the lan
                        FirewallRule rule2 = new FirewallRule();
                        FirewallRuleEx.SetProgID(rule2, prog.ID);
                        rule2.Name      = MakeRuleName(AllowLan, expiration != 0, prog.Description);
                        rule2.Grouping  = RuleGroup;
                        rule2.Action    = FirewallRule.Actions.Allow;
                        rule2.Direction = direction;
                        rule2.Enabled   = true;
                        //rule.RemoteAddresses = FirewallRule.GetSpecialNet(FirewallRule.AddrKeywordLocalSubnet);
                        rule2.RemoteAddresses = FirewallRule.AddrKeywordLocalSubnet;
                        ApplyRule(prog, rule2, expiration);
                        break;
                    }

                    case ProgramConfig.AccessLevels.BlockAccess:
                    {
                        // add and enable broad block rules
                        FirewallRule rule = new FirewallRule();
                        FirewallRuleEx.SetProgID(rule, prog.ID);
                        rule.Name      = MakeRuleName(BlockAllName, expiration != 0, prog.Description);
                        rule.Grouping  = RuleGroup;
                        rule.Action    = FirewallRule.Actions.Block;
                        rule.Direction = direction;
                        rule.Enabled   = true;
                        ApplyRule(prog, rule, expiration);
                        break;
                    }
                    }
                }
            }

            progSet.config.CurAccess = progSet.config.NetAccess;

            App.engine.OnRulesUpdated(progSet);
        }
Пример #14
0
        public void EvaluateRules(ProgramSet progSet, bool StrictTest = false)
        {
            String InetRanges = FirewallRule.AddrKeywordIntErnet;

            if (UwpFunc.IsWindows7OrLower)
            {
                InetRanges = GetSpecialNet(InetRanges);
            }

            progSet.config.CurAccess = ProgramConfig.AccessLevels.Unconfigured;

            SortedDictionary <ProgramID, RuleStat> RuleStats = new SortedDictionary <ProgramID, RuleStat>();
            int enabledCound = 0;

            foreach (Program prog in progSet.Programs.Values)
            {
                RuleStat Stat = new RuleStat();

                foreach (FirewallRule rule in prog.Rules.Values)
                {
                    if (!rule.Enabled)
                    {
                        continue;
                    }

                    enabledCound++;

                    if (!FirewallRule.IsEmptyOrStar(rule.LocalAddresses))
                    {
                        continue;
                    }
                    if (!FirewallRule.IsEmptyOrStar(rule.LocalPorts) || !FirewallRule.IsEmptyOrStar(rule.RemotePorts))
                    {
                        continue;
                    }
                    if (rule.IcmpTypesAndCodes != null && rule.IcmpTypesAndCodes.Length > 0)
                    {
                        continue;
                    }

                    bool AllProts  = (rule.Protocol == (int)NetFunc.KnownProtocols.Any);
                    bool InetProts = AllProts || (rule.Protocol == (int)FirewallRule.KnownProtocols.TCP) || (rule.Protocol == (int)FirewallRule.KnownProtocols.UDP);

                    if (!InetProts)
                    {
                        continue;
                    }

                    //if (rule.Profile != (int)FirewallRule.Profiles.All && (rule.Profile != ((int)FirewallRule.Profiles.Public | (int)FirewallRule.Profiles.Private | (int)FirewallRule.Profiles.Domain)))
                    //    continue;
                    if (rule.Interface != (int)FirewallRule.Interfaces.All)
                    {
                        continue;
                    }

                    if (FirewallRule.IsEmptyOrStar(rule.RemoteAddresses))
                    {
                        if (rule.Action == FirewallRule.Actions.Allow && InetProts)
                        {
                            Stat.AllowAll.Add(rule.Profile, rule.Direction);
                        }
                        else if (rule.Action == FirewallRule.Actions.Block && AllProts)
                        {
                            Stat.BlockAll.Add(rule.Profile, rule.Direction);
                        }
                    }
                    else if (rule.RemoteAddresses == InetRanges)
                    {
                        if (rule.Action == FirewallRule.Actions.Block && AllProts)
                        {
                            Stat.BlockInet.Add(rule.Profile, rule.Direction);
                        }
                    }
                    else if (rule.RemoteAddresses == FirewallRule.AddrKeywordLocalSubnet)
                    {
                        if (rule.Action == FirewallRule.Actions.Allow && InetProts)
                        {
                            Stat.AllowLan.Add(rule.Profile, rule.Direction);
                        }
                    }
                }

                RuleStats.Add(prog.ID, Stat);
            }

            if (RuleStats.Count == 0 || enabledCound == 0)
            {
                return;
            }

            RuleStat MergedStat = RuleStats.Values.First();

            for (int i = 1; i < RuleStats.Count; i++)
            {
                RuleStat Stat = RuleStats.Values.ElementAt(i);

                MergedStat.AllowAll.Merge(Stat.AllowAll);
                MergedStat.BlockAll.Merge(Stat.BlockAll);
                MergedStat.AllowLan.Merge(Stat.AllowLan);
                MergedStat.BlockInet.Merge(Stat.BlockInet);
            }

            if (MergedStat.BlockAll.IsOutbound(IgnoreDomain) && (!StrictTest || MergedStat.BlockAll.IsInbound(IgnoreDomain)))
            {
                progSet.config.CurAccess = ProgramConfig.AccessLevels.BlockAccess;
            }
            //else if (MergedStat.AllowAll.IsOutbound(SkipDomain) && (!StrictTest || MergedStat.AllowAll.IsInbound(SkipDomain)))
            else if (MergedStat.AllowAll.IsOutbound(IgnoreDomain) && MergedStat.AllowAll.IsInbound(IgnoreDomain))
            {
                progSet.config.CurAccess = ProgramConfig.AccessLevels.FullAccess;
            }
            else if (MergedStat.AllowLan.IsOutbound(IgnoreDomain) && (!StrictTest || (MergedStat.AllowLan.IsInbound(IgnoreDomain) && MergedStat.AllowLan.IsInbound(IgnoreDomain))))
            {
                progSet.config.CurAccess = ProgramConfig.AccessLevels.LocalOnly;
            }
            else if (MergedStat.AllowAll.IsOutbound(IgnoreDomain))
            {
                progSet.config.CurAccess = ProgramConfig.AccessLevels.OutBoundAccess;
            }
            else if (MergedStat.AllowAll.IsInbound(IgnoreDomain))
            {
                progSet.config.CurAccess = ProgramConfig.AccessLevels.InBoundAccess;
            }
            else if (enabledCound > 0)
            {
                progSet.config.CurAccess = ProgramConfig.AccessLevels.CustomConfig;
            }
        }
Пример #15
0
        public bool Load()
        {
            if (!File.Exists(App.dataPath + @"\Programs.xml"))
            {
                return(false);
            }

            try
            {
                XmlDocument xDoc = new XmlDocument();
                xDoc.Load(App.dataPath + @"\Programs.xml");

                double fileVersion = 0.0;
                double.TryParse(xDoc.DocumentElement.GetAttribute("Version"), out fileVersion);
                if (fileVersion != xmlVersion)
                {
                    Priv10Logger.LogError("Failed to load programlist, unknown file version {0}, expected {1}", fileVersion, xmlVersion);
                    return(false);
                }

                int TotalCount = 0;
                int ErrorCount = 0;

                foreach (XmlNode node in xDoc.DocumentElement.ChildNodes)
                {
                    TotalCount++;
                    ProgramSet entry = new ProgramSet();
                    if (!entry.LoadSet(node))
                    {
                        ErrorCount++;
                        continue;
                    }

                    foreach (Program prog in entry.Programs.Values.ToList())
                    {
                        // COMPAT: merge "duplicates"
                        Program knownProg;
                        if (App.engine.ProgramList.Programs.TryGetValue(prog.ID, out knownProg))
                        {
                            foreach (var rule in prog.Rules)
                            {
                                knownProg.Rules.Add(rule.Key, rule.Value);
                            }

                            entry.Programs.Remove(prog.ID);
                        }
                        else
                        {
                            Programs.Add(prog.ID, prog);
                        }
                    }

                    if (entry.Programs.Count > 0)
                    {
                        ProgramSets.Add(entry.guid, entry);
                    }
                }

                if (ErrorCount != 0)
                {
                    Priv10Logger.LogError("Failed to load {0} program entry out of {1}", ErrorCount, TotalCount);
                }
                Priv10Logger.LogInfo("ProgramList loaded {0} entries", TotalCount - ErrorCount);
            }
            catch (Exception err)
            {
                AppLog.Exception(err);
                return(false);
            }
            return(true);
        }
Пример #16
0
        public ProgramControl(ProgramSet prog, CategoryModel Categories)
        {
            InitializeComponent();

            chkNotify.Content = Translate.fmt("lbl_notify");
            btnAdd.Content    = Translate.fmt("lbl_add");
            btnSplit.Content  = Translate.fmt("lbl_split");
            btnRemove.Content = Translate.fmt("lbl_remove");

            progGrid.Columns[1].Header = Translate.fmt("lbl_name");
            progGrid.Columns[2].Header = Translate.fmt("lbl_program");

            SuspendChange++;

            progArea.Visibility = Visibility.Collapsed;

            CatModel = Categories;
            //category.ItemsSource = CatModel.Categorys;
            category.ItemsSource = CatModel.GetCategorys();

            //mBorderBrush = name.BorderBrush;
            //name.BorderBrush = Brushes.Transparent;

            cmbAccess.Items.Add(new ComboBoxItem()
            {
                Content = Translate.fmt("acl_none"), Tag = ProgramSet.Config.AccessLevels.Unconfigured
            });
            cmbAccess.Items.Add(new ComboBoxItem()
            {
                Content = Translate.fmt("acl_allow"), Tag = ProgramSet.Config.AccessLevels.FullAccess
            });
            cmbAccess.Items.Add(new ComboBoxItem()
            {
                Content = Translate.fmt("acl_edit"), Tag = ProgramSet.Config.AccessLevels.CustomConfig
            });
            cmbAccess.Items.Add(new ComboBoxItem()
            {
                Content = Translate.fmt("acl_lan"), Tag = ProgramSet.Config.AccessLevels.LocalOnly
            });
            cmbAccess.Items.Add(new ComboBoxItem()
            {
                Content = Translate.fmt("acl_block"), Tag = ProgramSet.Config.AccessLevels.BlockAccess
            });
            foreach (ComboBoxItem item in cmbAccess.Items)
            {
                item.Background = GetAccessColor((ProgramSet.Config.AccessLevels)item.Tag);
            }

            SuspendChange--;

            progSet = prog;

            DoUpdate();

            ProgramID id = prog.Programs.First().Key;

            if (id.Type == ProgramID.Types.Global || id.Type == ProgramID.Types.System)
            {
                btnIDs.IsEnabled = false;
                //btnCustimize.Visibility = Visibility.Hidden;
                cmbAccess.Visibility = Visibility.Hidden;
                //category.Visibility = Visibility.Hidden;
            }
            if (id.Type == ProgramID.Types.Global)
            {
                chkNotify.Visibility = Visibility.Hidden;
            }

            rect.MouseDown += new MouseButtonEventHandler(rect_Click);
            //name.MouseDown += new MouseButtonEventHandler(rect_Click);
            name.PreviewMouseDown += new MouseButtonEventHandler(rect_Click);
            //progGrid.PreviewMouseDown += new MouseButtonEventHandler(rect_Click);
            icon.MouseDown += new MouseButtonEventHandler(rect_Click);
            info.MouseDown += new MouseButtonEventHandler(rect_Click);

            category.PreviewMouseWheel += ctrl_PreviewMouseWheel;
            //progGrid.PreviewMouseWheel += ctrl_PreviewMouseWheel;
        }