C++Builder
  Начало   Форум   Помощь Войти Регистрация  
Страниц: [1]   Вниз
  Печать  
Автор Тема: Отформатировать флешку  (Прочитано 5057 раз)
SilverFish
Участник


Сказали спасибо: +14/-6
Offline

Сообщений: 786


Отформатировать флешку
« : 22 Июнь 2014, 18:59:54 »

Кодом ниже определяю, что флешка вставлена.
Код
class TForm1 : public TForm
{
__published: // IDE-managed Components
private: // User declarations
 void virtual __fastcall WMDeviceChange(TMessage &Message);
public: // User declarations
BEGIN_MESSAGE_MAP
 MESSAGE_HANDLER(WM_DEVICECHANGE,TMessage,WMDeviceChange);
END_MESSAGE_MAP(TForm);
__fastcall TForm1(TComponent* Owner);
};
 

Код
#include 
void __fastcall TForm1::WMDeviceChange(TMessage& Message)
{
 if (Message.Msg == WM_DEVICECHANGE && Message.WParam == DBT_DEVICEARRIVAL)
 {
// как послать команду на форматирование?
       //или как удалить все данные с флешки?
ShowMessage("Привет");
 }
}
 

Подскажите, пожалуйста, как правильно послать команду на форматирование вставленной флешки?
« Последнее редактирование: 22 Июнь 2014, 19:08:06 от SilverFish » Записан
POV
Участник


Сказали спасибо: +107/-7
Offline

Сообщений: 640


Re: Отформатировать флешку
« Ответ #1 : 22 Июнь 2014, 22:02:46 »

format c:   
не? ))
Записан
SilverFish
Участник


Сказали спасибо: +14/-6
Offline

Сообщений: 786


Re: Отформатировать флешку
« Ответ #2 : 23 Июнь 2014, 11:45:10 »

Как правильно послать команду и как правильно определить букву вставленного флеш накопителя?
Записан
Rius
Давний друг


Сказали спасибо: +116/-5
Offline

Сообщений: 753


Re: Отформатировать флешку
« Ответ #3 : 23 Июнь 2014, 13:48:17 »

http://social.msdn.microsoft.com/Forums/vstudio/en-US/cc2ff1a4-e0c6-4a45-b03e-d84abb15d6f6/detecting-the-insertion-and-removal-of-a-usb-drive?forum=vcgeneral
Записан
Tantos
А ты воспользовался поиском перед тем, как спросить?!
Давний друг


Сказали спасибо: +350/-28
Offline

Сообщений: 2181


Re: Отформатировать флешку
« Ответ #4 : 23 Июнь 2014, 13:49:54 »

Без участия пользователя?
Команду-то через тот же CreateProcess/ShellExecute можно послать, а вот с флешкой велика вероятность ошибки. А если их несколько?
Записан
SilverFish
Участник


Сказали спасибо: +14/-6
Offline

Сообщений: 786


Re: Отформатировать флешку
« Ответ #5 : 23 Июнь 2014, 16:31:44 »

Rius, спасибо за ссылку, попробую разобраться...

Код
А если их несколько?
 
В медицинском учреждении запрет - запрещено вставлять флешки. Не взирая на запрет народ вставляет и все подряд вечно заражено вирусами. Решили наказать таким образом, а не опечатывать USB порты. Такая вот воспитательная мера...
Задача - или удалить или отформатировать всю информацию в момент вставления флешки в порт.
Записан
Tantos
А ты воспользовался поиском перед тем, как спросить?!
Давний друг


Сказали спасибо: +350/-28
Offline

Сообщений: 2181


Re: Отформатировать флешку
« Ответ #6 : 24 Июнь 2014, 02:26:56 »

Сурово. Я так понимаю, на антивирусное решение + ZLock начальство жмется?
Записан
Rius
Давний друг


Сказали спасибо: +116/-5
Offline

Сообщений: 753


Re: Отформатировать флешку
« Ответ #7 : 24 Июнь 2014, 06:35:48 »

А почему просто из операционной системы не выпилить поддержку USB накопителей? И админские права у юзеров отобрать.

http://support.microsoft.com/kb/823732

Или на GNU/Linux перевести, как максимум.
Записан
POV
Участник


Сказали спасибо: +107/-7
Offline

Сообщений: 640


Re: Отформатировать флешку
« Ответ #8 : 24 Июнь 2014, 08:17:11 »

Цитата: Rius от 24 Июнь 2014, 06:35:48
А почему просто из операционной системы не выпилить поддержку USB накопителей?

"Мы живёт в самой демократичной стране на свете" (С) Наша Раша
Потому запрещать нельзя.. можно "случайно" убить чьи-то данные.
Записан
S0mbre
Глобальный модератор


Сказали спасибо: +1113/-22
Offline

Сообщений: 2132

S0mbre


Re: Отформатировать флешку
« Ответ #9 : 24 Июнь 2014, 11:22:35 »

Я бы накидал скрипт на Python... надежно и быстро ) Если даже Python не установлен, можно скомпилировать скрипт при помощи PyExe и подобных ему.
Записан
SilverFish
Участник


Сказали спасибо: +14/-6
Offline

Сообщений: 786


Re: Отформатировать флешку
« Ответ #10 : 24 Июнь 2014, 11:39:37 »

Код
А почему просто из операционной системы не выпилить поддержку USB накопителей? 

Доп. информация:
Да потому что, помимо всего, эти сотрудники уже незаконно понакопировали себе истории болезней пациентов, и таким образом при следующей вставке своих флешек в их дежурство, все это воровство надо у них обнулить.
Цитировать
Я бы накидал скрипт на Python.

Можно ли решить такую задачу на С++ Builder?
"Посольство (python) мы не понимаем".
Цитата из Кин Дза За

« Последнее редактирование: 24 Июнь 2014, 13:43:52 от SilverFish » Записан
Rius
Давний друг


Сказали спасибо: +116/-5
Offline

Сообщений: 753


Re: Отформатировать флешку
« Ответ #11 : 24 Июнь 2014, 12:58:44 »

Проверить, что диск этот отключаемый - GetDriveType.
Потом стереть его разметку или отформатировать.

Под раздачу могут попасть смартфоны, фотоаппараты и ещё неизвестно что.
Записан
SilverFish
Участник


Сказали спасибо: +14/-6
Offline

Сообщений: 786


Re: Отформатировать флешку
« Ответ #12 : 24 Июнь 2014, 14:44:50 »

А как можно узнать правильно букву только что вставленной флешки в событии из первого поста?
Код
/*
var
 Drive: Char; //Буква диска
const
 pref = ':\';
begin
 for Drive := 'A' to 'Z' do
   if GetDriveType(PChar(Drive + pref)) = DRIVE_REMOVABLE then .... // в Drive Буква флешки
*/

void __fastcall TForm1::WMDeviceChange(TMessage& Message)
{
 if (Message.Msg == WM_DEVICECHANGE && Message.WParam == DBT_DEVICEARRIVAL)
 {
 
char Drive;
String pref = ":\\";
for (Drive = 'B'; Drive 'Z' ; Drive++)
{
if (GetDriveType((Drive + pref.c_str())) == DRIVE_REMOVABLE)
{
 String DISK = Drive + pref.c_str();
 ShowMessage("Имя диска: " + DISK);
}
}
 
 }
}
При вставке флешки ничего не происходит...
« Последнее редактирование: 24 Июнь 2014, 15:00:36 от SilverFish » Записан
SilverFish
Участник


Сказали спасибо: +14/-6
Offline

Сообщений: 786


Re: Отформатировать флешку
« Ответ #13 : 24 Июнь 2014, 15:35:35 »

Так, номер диска вроде получила:  
Код
void __fastcall TForm1::WMDeviceChange(TMessage& Message)
{
 if (Message.Msg == WM_DEVICECHANGE && Message.WParam == DBT_DEVICEARRIVAL)
 {
 
char Drive;
char pref = ':';
for (Drive = 'B'; Drive 'Z' ; Drive++)
{
String DISK = String(Drive) + String(pref);
        Memo1->Lines->Add("Имя диска: " + DISK);
if (GetDriveType(DISK.c_str()) == DRIVE_REMOVABLE)
{
 //послать команду на уничтожение данных
         ShowMessage("Имя диска: " + DISK);
}
}
 
 }
}
 
Записан
Rius
Давний друг


Сказали спасибо: +116/-5
Offline

Сообщений: 753


Re: Отформатировать флешку
« Ответ #14 : 24 Июнь 2014, 15:42:28 »

Если в эту функцию не попадает при вставке флешки, то окно не подписано на эти сообщения.

Из lparam можно вытащить другую инфу:
Код
void Main_OnDeviceChange (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  PDEV_BROADCAST_HDR lpdb = (PDEV_BROADCAST_HDR)lParam;
  char szMsg[80];
 
  switch(wParam)
  {
     case DBT_DEVICEARRIVAL:
        // Check whether a CD or DVD was inserted into a drive.
        if (lpdb -> dbch_devicetype == DBT_DEVTYP_VOLUME)
        {
           PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)lpdb;
 
           if (lpdbv -> dbcv_flags & DBTF_MEDIA)
           {
              wsprintf (szMsg, "Drive %c: Media has arrived.\n",
                        FirstDriveFromMask(lpdbv ->dbcv_unitmask));
 
              MessageBox (hwnd, szMsg, "WM_DEVICECHANGE", MB_OK);
           }
        }
        break;
...

Цитата: SilverFish от 24 Июнь 2014, 15:35:35
Так, номер диска вроде получила:  
Это первый попавшийся отключаемый диск)
Записан
SilverFish
Участник


Сказали спасибо: +14/-6
Offline

Сообщений: 786


Re: Отформатировать флешку
« Ответ #15 : 24 Июнь 2014, 16:10:29 »

А почему в этом коде не происходит форматирование?
Код
void __fastcall TForm1::WMDeviceChange(TMessage& Message)
{
 if (Message.Msg == WM_DEVICECHANGE && Message.WParam == DBT_DEVICEARRIVAL)
 {
 
char Drive;
char pref = ':';
for (Drive = 'B'; Drive 'Z' ; Drive++)
{
String DISK = String(Drive) + String(pref);
if (GetDriveType(DISK.c_str()) == DRIVE_REMOVABLE)
{
 Memo1->Lines->Add("Имя диска: " + DISK);
 Memo1->Lines->Add("format " + DISK + " /U");
 String FORMAT = "format " + DISK + " /U";
 String PROGRAM = "C:\\WINDOWS\\system32\\cmd.exe";
 String COMMAND = "open";
 ShellExecute (NULL, COMMAND.c_str(), PROGRAM.c_str(), FORMAT.c_str(), NULL, SW_HIDE);
}
}
 }
}
 
« Последнее редактирование: 24 Июнь 2014, 16:41:55 от SilverFish » Записан
S0mbre
Глобальный модератор


Сказали спасибо: +1113/-22
Offline

Сообщений: 2132

S0mbre


Re: Отформатировать флешку
« Ответ #16 : 24 Июнь 2014, 16:52:58 »

Я всегда стараюсь использовать не ShellExecute, а CreateProcess.
Записан
SilverFish
Участник


Сказали спасибо: +14/-6
Offline

Сообщений: 786


Re: Отформатировать флешку
« Ответ #17 : 24 Июнь 2014, 19:15:11 »

Цитата: S0mbre от 24 Июнь 2014, 16:52:58
Я всегда стараюсь использовать не ShellExecute, а CreateProcess.

Хорошо, как будет правильно с CreateProcess?
Вот так не работает:
Код
void __fastcall TForm1::WMDeviceChange(TMessage& Message)
{
 if (Message.Msg == WM_DEVICECHANGE && Message.WParam == DBT_DEVICEARRIVAL)
 {
STARTUPINFO StartInfo = {sizeof(TStartupInfo)};
PROCESS_INFORMATION ProcInfo;
StartInfo.cb = sizeof(StartInfo);
char Drive;
char pref = ':';
for (Drive = 'B'; Drive 'Z' ; Drive++)
{
String DISK = String(Drive) + String(pref);
if (GetDriveType(DISK.c_str()) == DRIVE_REMOVABLE)
{
 Memo1->Lines->Add("Имя диска: " + DISK);
 Memo1->Lines->Add("format " + DISK + " /U");
 
 String FORMAT = "format " + DISK + " /U";
 /*
 String PROGRAM = "C:\\WINDOWS\\system32\\cmd.exe";
 String COMMAND = "open";
 ShellExecute (NULL, COMMAND.c_str(), PROGRAM.c_str(), FORMAT.c_str(), NULL, SW_HIDE);
 */

 String PATH = "C:\\WINDOWS\\system32\\cmd.exe " + FORMAT;
 CreateProcess(NULL, PATH.c_str(),NULL,NULL,false,HIGH_PRIORITY_CLASS,NULL,NULL,&StartInfo, &ProcInfo);
 CloseHandle(ProcInfo.hProcess);
 
}
}
 }
}
 
Записан
Rius
Давний друг


Сказали спасибо: +116/-5
Offline

Сообщений: 753


Re: Отформатировать флешку
« Ответ #18 : 24 Июнь 2014, 19:53:06 »

CreateProcess тоже костыль. Надо пользоваться API.
http://stackoverflow.com/questions/7227835/how-i-could-to-run-formatting-disk-programmatically
Через WMI.
Записан
SilverFish
Участник


Сказали спасибо: +14/-6
Offline

Сообщений: 786


Re: Отформатировать флешку
« Ответ #19 : 24 Июнь 2014, 20:30:51 »

Цитата: Rius от 24 Июнь 2014, 19:53:06
CreateProcess тоже костыль. Надо пользоваться API.
http://stackoverflow.com/questions/7227835/how-i-could-to-run-formatting-disk-programmatically
Через WMI.

Там еще по ссылке есть вот это:
http://msdn.microsoft.com/en-us/library/aa390432%28v=VS.85%29.aspx
а как это можно прикрутить в С++ Builder?
Записан
Rius
Давний друг


Сказали спасибо: +116/-5
Offline

Сообщений: 753


Re: Отформатировать флешку
« Ответ #20 : 24 Июнь 2014, 21:48:21 »

Там по ссылке есть:
Цитировать
I don't have a code sample handy, but if you haven't use WMI in c++ before, this might help get you started: msdn.microsoft.com/en-us/library/aa394558%28v=VS.85%29.aspx –  Vijay Varadan Aug 29 '11 at 9:32
Записан
S0mbre
Глобальный модератор


Сказали спасибо: +1113/-22
Offline

Сообщений: 2132

S0mbre


Re: Отформатировать флешку
« Ответ #21 : 25 Июнь 2014, 10:32:34 »

Работа c  WMI требует специальных навыков, в первую очередь, общих навыков COM программирования, во вторую очередь, - специфика самой библиотеки WMI.

Про WMI в С++Builder см. замечательные статьи Малкольма Смита в BCBJ -
2006 №3, №4, №5, №7
Скачать можно здесь
Записан
S0mbre
Глобальный модератор


Сказали спасибо: +1113/-22
Offline

Сообщений: 2132

S0mbre


Re: Отформатировать флешку
« Ответ #22 : 25 Июнь 2014, 10:46:28 »

Для создания процессов Windows я использую функции-обертки, например:

Код
// объявление
unsigned long __fastcall ProcessRun(const String& AExename, unsigned long WaitFor=0);
// здесь:
// AExename - строка - команда (с параметрами, если есть); заключать в кавычки
// WaitFor - время ожидания команды: -1 = ждать бесконечно, 0 = не ждать, >0 = ждать столько-то мс
 
String __fastcall WinAPI_GetLastErrorMsg(); // функция для извлечения текста последней ошибки (WinAPI)
 
// реализация
 
unsigned long __fastcall ProcessRun(const String& AExename, unsigned long WaitFor)
{
STARTUPINFO si;                      // стартап данные
PROCESS_INFORMATION pi;       // инфа о процессе
DWORD exit_code = 1;             // возвращаемый код
 
try {
 
SecureZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(si);
si.wShowWindow = SW_HIDE;
si.dwFlags = STARTF_USESHOWWINDOW;
 
SecureZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
 
try {
if (!::CreateProcess(
NULL, TOCSTR(AExename),
NULL, NULL, FALSE,
CREATE_NEW_CONSOLE | NORMAL_PRIORITY_CLASS,
NULL, NULL, &si, &pi))
{
::CloseHandle(pi.hProcess);
::CloseHandle(pi.hThread);
throw Exception("Cannot create process '" + AExename + "'!\n" +
WinAPI_GetLastErrorMsg());
}
}
catch(...) {
::CloseHandle(pi.hProcess);
::CloseHandle(pi.hThread);
throw Exception("Error while creating process '" + AExename + "'!\n" +
WinAPI_GetLastErrorMsg());
       }
 
try {
::WaitForSingleObject( pi.hProcess, WaitFor? WaitFor : INFINITE );
::GetExitCodeProcess(pi.hProcess, &exit_code); // записываем возвращаемый код
}
__finally {
::CloseHandle(pi.hProcess);
::CloseHandle(pi.hThread);
}
 
}
 
catch(Exception&) {
throw;
}
catch(...) {
throw Exception("Error in function 'ProcessRun'");
   }
 
return exit_code;
}
 
//---------------------
 
String __fastcall WinAPI_GetLastErrorMsg()
{
const DWORD dwLastError = GetLastError();
if(dwLastError == 0) return "";
 
_TCHAR ErrText[1024];
 
HMODULE hModule = NULL; // default to system source
_TCHAR* MessageBuffer;
DWORD dwBufferLength;
 
DWORD dwFormatFlags =
FORMAT_MESSAGE_ALLOCATE_BUFFER |
       FORMAT_MESSAGE_IGNORE_INSERTS |
FORMAT_MESSAGE_FROM_SYSTEM;
 
dwBufferLength = FormatMessage(
       dwFormatFlags,
hModule, // module to get message from (NULL == system)
dwLastError,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // default language
MessageBuffer,
       0,
NULL);
 
if(dwBufferLength == 0) return "";
else {
_tcscpy(ErrText, MessageBuffer);
LocalFree(MessageBuffer);
}
 
// If we loaded a message source, unload it
if(hModule != NULL) FreeLibrary(hModule);
 
return String(ErrText);
}
 
Записан
S0mbre
Глобальный модератор


Сказали спасибо: +1113/-22
Offline

Сообщений: 2132

S0mbre


Re: Отформатировать флешку
« Ответ #23 : 25 Июнь 2014, 10:53:19 »

Пример использования функции (см. ап) для форматирования диска F:

Код
String sCommand = "cmd.exe";
sCommand += " \" /c format f: /fs:ntfs /q /x\"";
try {
  unsigned long Res = ProcessRun(sCommand, -1); // синхронный вызов: ждем окончания выполнения команды
}
catch(Exception& err) {
  ShowMessage(err.Message);
}
 
Записан
S0mbre
Глобальный модератор


Сказали спасибо: +1113/-22
Offline

Сообщений: 2132

S0mbre


Re: Отформатировать флешку
« Ответ #24 : 25 Июнь 2014, 11:04:38 »

И еще можно использовать Virtual Disk Service. Функция для форматирования описана на msdn.
Записан
S0mbre
Глобальный модератор


Сказали спасибо: +1113/-22
Offline

Сообщений: 2132

S0mbre


Re: Отформатировать флешку
« Ответ #25 : 25 Июнь 2014, 11:20:00 »

Наконец, "умные люди" советуют юзать библиотеку fmifs.dll (входит в дистрибутив винды).
Скачать заголовочный файл можно тут, а описание - здесь.
Записан
SilverFish
Участник


Сказали спасибо: +14/-6
Offline

Сообщений: 786


Re: Отформатировать флешку
« Ответ #26 : 25 Июнь 2014, 11:39:50 »

Спасибо, буду разбираться.
Записан
SilverFish
Участник


Сказали спасибо: +14/-6
Offline

Сообщений: 786


« Ответ #27 : 26 Июнь 2014, 14:53:26 »

Код
    void __fastcall TForm1::WMDeviceChange(TMessage& Message)
   {
       if (Message.WParam != DBT_DEVICEARRIVAL)
           return;
 
       DEV_BROADCAST_HDR *hdr = (DEV_BROADCAST_HDR*) Message.LParam;
       if (hdr->dbch_devicetype != DBT_DEVTYP_VOLUME)
           return;
 
       String CMD = GetEnvironmentVariable(L"COMSPEC");
       if (CMD.IsEmpty())
       {
           Memo1->Lines->Add(L"COMSPEC is not defined");
           return;
       }
 
       CMD = AnsiQuotedStr(CMD, L'"');
 
       DEV_BROADCAST_VOLUME *volume = (DEV_BROADCAST_VOLUME*) Message.LParam;
       WCHAR DISK[] = L"#:";
 
       for(int i = 0; i 32; ++i)
       {
           if (volume->dbcv_unitmask & (1 i))
           {
               DISK[0] = L'A' + i;
 
               String CmdLine = CMD + L" /C format " + String(DISK) + L" /U";
               Memo1->Lines->Add(CmdLine);
 
               STARTUPINFO StartInfo = {0};
               StartInfo.cb = sizeof(StartInfo);
               PROCESS_INFORMATION ProcInfo = {0};
 
               if (!CreateProcess(NULL, CmdLine.c_str()(), NULL, NULL, FALSE, HIGH_PRIORITY_CLASS, NULL, NULL, &StartInfo, &ProcInfo))
               {
                   Memo1->Lines->Add(L"Error: " + String(GetLastError()));
               }
               else
               {
                   CloseHandle(ProcInfo.hThread);
                   CloseHandle(ProcInfo.hProcess);
               }
           }
       }
   }
 
 
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  




....

Powered by SMF 1.1.21 | SMF © 2025, Simple Machines
Страница сгенерирована за 0.157 секунд. Запросов: 21.