Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Блокировка USB-накопителей

47K
17 января 2013 года
CommanderRUS
17 / / 13.11.2009
Всем привет! Сейчас начинаю писать дипломный проект. Задача "минимум" состоит в написании ПО, которое после загрузки ОС (в качестве ОС используется Windows 7) будет:
1. Автоматически загружаться и работать процессом, который невозможно убить через диспетчер задач не обладая правами администратора;
2. Блокировать все USB-накопители кроме тех, что есть в своеобразном списке исключения (или, так сказать, доверенном списке);
3. Только от учетной записи администратора будет возможность добавлять и удалять из списка доверенные USB-накопители (или реализовать панельку, через которую можно давать права различным пользователям это делать).

В качестве среды разработки будет Microsoft Visual Studio 2010. В качестве языка программирования предположительно C#. Уже более года не садился за программирование, до этого последние небольшие программки-проекты писал на C#, но с задачами такого уровня еще не сталкивался.

Прошу Вашей помощи, что можно почитать, может где-то есть примеры с частично похожими задачами? Буду благодарен любой помощи, ибо год "непрограммирования" дает о себе знать. Уже вторую неделю нахожусь в режиме гугления, но ничего толкового по задаче №2 найти не удалось.

Буду очень благодарен за помощь!
7
17 января 2013 года
@pixo $oft
3.4K / / 20.09.2006
Собирался нечто типа такого реализовать, только в составе программного комплекса и с несколько другими задачами (а именно — просто наблюдение)

1. Служба, просто служба
2. Тут несколько путей. Пришедшие мне сразу на ум — либо открывать в монопольном доступе подключенные устройства, если они недозволены, либо отлавливать WM_DEVICEARRIVAL (или какое там, уже не помню) и просто устройство извлекать
3. Делается через общение с этой самой службой
297
18 января 2013 года
koodeer
1.2K / / 02.05.2009
По поводу второго пункта.
Обнаружить подключение флэшки можно с помощью технологии WMI: пример.
Получить параметры физического носителя опять же с помощью WMI: пример. Именно на основе этих параметров можно составить чёрный или белый список.
И то, и другое можно сделать функциями WinAPI вместо WMI.

А вот собственно заблокировать с помощью WMI не получится: не предусмотрено в этой технологии такой возможности (если я не ошибаюсь).
Полагаю, можно использовать через pinvoke функцию API SetupDiChangeState. Как только детектируется новая флэшка, проверяем её параметры, и если она не разрешена, отключаем устройство. Проверять лень, пробуй.
47K
02 февраля 2013 года
CommanderRUS
17 / / 13.11.2009
Цитата: @pixo $oft
открывать в монопольном доступе подключенные устройства, если они недозволены


А не подскажите, как это сделать или где можно почитать? Пока не получилось ничего найти по этому поводу.

Цитата: koodeer

Полагаю, можно использовать через pinvoke функцию API SetupDiChangeState. Как только детектируется новая флэшка, проверяем её параметры, и если она не разрешена, отключаем устройство.



Не смог найти ни одного работающего примера. Везде советуют использовать эту функцию для отключения устройств, но как ее использовать и как сформировать нужные параметры - ни слова. Буду очен благодарен за помощь.

Нашел только вот это http://stackoverflow.com/questions/4097000/how-do-i-disable-a-system-device-programatically
Но там как-то слишком много кода для этой задачи получается, везде пишут что можно обойтись SetupDiChangeState.
Да и не получилось у меня заставить работать этот код. Вставляю флешку, пытаюсь ее отключить с помощью этого кода, делаю все как написано, получаю это http://i49.tinypic.com/21doj9g.jpg

7
03 февраля 2013 года
@pixo $oft
3.4K / / 20.09.2006
CreateFile
В секции "Physical Disks and Volumes" рассказывается, как применять её по отношению к устройствам. Там же рассказано, каким должен быть параметр dwShareMode

Желаю удачи!
47K
07 апреля 2013 года
CommanderRUS
17 / / 13.11.2009
Получилось заставить блокировать флешки с помощью открытия их в монопольном доступе через CreateFile. Все работает замечательно, если не открыто окно "Мой компьютер" с перечислением всех подключенных дисков.
Если же окно "Мой компьютер" открыто, и в этот момент вставлять флешку, блокировка не происходит. Как только закрываю окно, и снова вставляю флешку, блокировка срабатывает.

Как это можно победить? Я так полагаю это один из конретных случаев, и есть еще способы сделать блокировку похожим способом нерабочей.

Код:
using System;
using System.Management;
using System.IO;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;      

namespace WMIConsole
{
    class Program
    {
        [DllImport("kernel32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        public static extern SafeFileHandle CreateFile(
            string lpFileName,
            uint dwDesiredAccess,
            uint dwShareMode,
            IntPtr SecurityAttributes,
            uint dwCreationDisposition,
            uint dwFlagsAndAttributes,
            IntPtr hTemplateFile
        );

        public static SafeFileHandle ptr;

        const uint GENERIC_READ = 0x80000000;
        const uint GENERIC_WRITE = 0x40000000;
        const uint OPEN_EXISTING = 3;



        static void Main(string[] args)
        {
           
            ManagementEventWatcher watcher = null;
            try
            {
                // Bind to local machine
                ManagementScope scope = new ManagementScope("root\\CIMV2");
                scope.Options.EnablePrivileges = true; //set required privilege

                WqlEventQuery query = new WqlEventQuery();
                query.EventClassName = "__InstanceOperationEvent";
                query.WithinInterval = new TimeSpan(0, 0, 1);
                query.Condition = @"TargetInstance ISA 'Win32_DiskDrive'";
               
                watcher = new ManagementEventWatcher(scope, query);
                watcher.EventArrived += new EventArrivedEventHandler(watcher_EventArrived);
               
                watcher.Start();

                Console.ReadLine(); // block main thread for test purposes
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            finally
            {
                if (watcher != null)
                    watcher.Stop();
            }
            return;
        }

        static void watcher_EventArrived(object sender, EventArrivedEventArgs e)
        {            
                       
            //Get the Event object and display its properties (all)
            foreach (PropertyData pd in e.NewEvent.Properties)
            {
                ManagementBaseObject mbo = null;
                if ((mbo = pd.Value as ManagementBaseObject) != null)
                {                  
                    ManagementClass devs = new ManagementClass(@"Win32_Diskdrive");
                    ManagementObjectCollection moc = devs.GetInstances();
                    foreach (ManagementObject mo in moc)
                    {
                        if (mo["DeviceId"].ToString() == mbo.GetPropertyValue("DeviceId").ToString())
                        {
                            foreach (ManagementObject b in mo.GetRelated("Win32_DiskPartition"))
                            {
                                foreach (ManagementObject c in b.GetRelated("Win32_LogicalDisk"))
                                {                                    
                                    ptr = CreateFile(@"\\.\" + c["Name"].ToString(), GENERIC_READ | GENERIC_WRITE,
                                        0, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
                                }
                            }
                        }
                    }
                }
            }  
        }
    }
}
7
07 апреля 2013 года
@pixo $oft
3.4K / / 20.09.2006
Закрывать окно «Моего компьютера» :)
А почему блокировка не происходит, каково поведение программы при этом?
47K
07 апреля 2013 года
CommanderRUS
17 / / 13.11.2009
Пока программа ввиде консольного приложения, код ее выше. Запускаю программу, и вставляю флешки. Если при вставке флешки окно "Компьютер" закрыто, то все ок, при попытки октрыть флешку будет сказано что нет доступа. Причем главное чтобы окно "Компьютер" было закрыто в момент вставки флешки, после этого можно его открыть и попытаться открыть флешку, она будет заблокирована. Но если вставлять флешку при открытом окне "Компьютер", то блокировки не произойдет и можно спокойно ей пользоваться.
Ну а так как программа будет представлять собой, так сказать, средство защиты, то этот факт является большой дырой ))

UPDATE:
Так же обнаружил, что если во время блокировки открыта любая папка и сбоку этой папки есть панелька с перечислением содержимого компьютера (в данном случае жесткие диски и флешки), то блокировка тоже будет невозможна.

Т.е. что бы блокировка успешно сработала необходимо чтобы были закрыты все окна, в которых обозначена наша флешка, и из которых непосредственнно можно открыть ее.
7
07 апреля 2013 года
@pixo $oft
3.4K / / 20.09.2006
Спасибо, что потрудился соорудить такое описание, но я понял смысл оного изначально. Мне интересно было поведение самой программы, т.е. что под отладчиком такого происходит, что не проходит блокировка. Я так полагаю, тебя этот вопрос тоже интересует, поэтому рекомендую настоятельно в целях борьбы с потенциальными дырами ☺
47K
08 апреля 2013 года
CommanderRUS
17 / / 13.11.2009
Цитата: @pixo $oft
Спасибо, что потрудился соорудить такое описание, но я понял смысл оного изначально. Мне интересно было поведение самой программы, т.е. что под отладчиком такого происходит, что не проходит блокировка. Я так полагаю, тебя этот вопрос тоже интересует, поэтому рекомендую настоятельно в целях борьбы с потенциальными дырами ☺



Эхх, знать бы как этим пользоваться

UPDATE:
Похоже заставил работать код, как требуется. Пришлось использовать DeviceIoControl. По карйней мере проблема описанная выше изчезла, будем тестить)

Код:
[DllImport("kernel32.dll", SetLastError = true)]
        static extern IntPtr CreateFile(
            string lpFileName,
            uint dwDesiredAccess,
            uint dwShareMode,
            IntPtr lpSecurityAttributes,
            uint dwCreationDisposition,
            uint dwFlagsAndAttributes,
            IntPtr hTemplateFile);


IntPtr ptr;


[DllImport("kernel32.dll", SetLastError = true)]
static extern bool DeviceIoControl(
    IntPtr hDevice,
    uint dwIoControlCode,
    IntPtr lpInBuffer,
    uint nInBufferSize,
    [Out] IntPtr lpOutBuffer,
    uint nOutBufferSize,
    ref uint lpBytesReturned,
    IntPtr lpOverlapped);



        private void button1_Click(object sender, EventArgs e)
        {
            const uint FILE_SHARE_READ = 0x00000001;
            const uint FILE_SHARE_WRITE = 0x00000002;
            const uint OPEN_EXISTING = 3;
            const uint GENERIC_READ = 0x80000000;
            const uint GENERIC_WRITE = 0x40000000;

            const uint FSCTL_LOCK_VOLUME = 0x00090018;

            string str = @"\\.\E:";
           
            ptr = CreateFile(str, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
           
            uint byteReturned=0;
            DeviceIoControl(ptr, FSCTL_LOCK_VOLUME, IntPtr.Zero, 0, IntPtr.Zero, 0, ref byteReturned, IntPtr.Zero);
47K
23 апреля 2013 года
CommanderRUS
17 / / 13.11.2009
Столкнулся с новой проблемой. Пишу приложение для управления "белым списком". Стоит задача отображать в ListView все USB-накопители, активные в системе.
Написал для этого функцию printDevices(). Если запускаю ее по нажатию кнопки, то она отрабатывает нормально, и загружает в ListView список подключенных к ПК USB-накопителей.
Как только запускаю ее по событию DBT_DEVICEARRIVAL или DBT_DEVICEREMOVECOMPLETE, то программа крашится с ошибкой
Цитата:
Context 0x497548 is disconnected. No proxy will be used to service the request on the COM component. This may cause corruption or data loss. To avoid this problem, please ensure that all contexts/apartments stay alive until the application is completely done with the RuntimeCallableWrappers that represent COM components that live inside them.

, указывая на

Цитата:
searcher.Get()



Прошу Вашей помощи, самому разобраться не получилось(

Код:
protected override void WndProc(ref Message m)
        {
            if ((m.WParam.ToInt32() == DBT_DEVICEARRIVAL)||(m.WParam.ToInt32() == DBT_DEVICEREMOVECOMPLETE))
            {
                //printDevices();
            }
            base.WndProc(ref m);
        }

        void printDevices()
        {
            listView1.Items.Clear();
            DriveIndexList.Clear();

            try
            {
                ManagementObjectSearcher searcher =
                    new ManagementObjectSearcher("root\\CIMV2",
                    "SELECT * FROM Win32_DiskDrive WHERE InterfaceType = 'USB'");


                foreach (ManagementObject queryObj in searcher.Get())
                {
                    listView1.Items.Add(new ListViewItem(new[] { queryObj["Caption"].ToString(), queryObj["Index"].ToString(), "" }));
                    DriveIndexList.Add((UInt32)queryObj["Index"]);
                }          

            }
            catch (ManagementException ee)
            {
                MessageBox.Show("An error occurred while querying for WMI data: " + ee.Message);
            }

        }

        private void btn_Add_Click(object sender, EventArgs e)
        {
            printDevices();
        }
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог