Остановить выполнение DeviceIoControl

Тема в разделе "WASM.WIN32", создана пользователем salexn, 4 май 2006.

  1. salexn

    salexn New Member

    Публикаций:
    0
    Регистрация:
    4 май 2006
    Сообщения:
    5
    Есть Thread, в котором реализована некоторая процедура, в которой используется API функция

    DeviceIoControl (Handle, FSCTL_MOVE_FILE, ...);

    Как прервать выполнение данной функции(DeviceIoControl)? Делаю следующее

    private

    lSync: OVERLAPPED;

    ....

    constructor TmyThread.Create;

    ...

    FillChar(lSync, SizeOf(TOverlapped), 0);

    lSync.hEvent := CreateEvent(nil, true, FALSE, #0);

    .....



    unction UnNormilizeDrive(const ADrivePath: string): string;

    begin

    Result := '//./' + Copy(ADrivePath, 1, Pos('\', ADrivePath) — 1)

    end;



    DeviceHandle := CreateFile(PAnsiChar(UnNormilizeDrive(DriveName)), GENERIC_READ,

    FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE,

    nil, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);

    ...



    MoveParams.FileHandle := CreateFile(PAnsiChar(AFile.FileName), ; FILE_READ_ATTRIBUTES, FILE_SHAR E_READ OR FILE_SHARE_WRITE OR FILE_SHARE_DELETE, nil, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);



    if (MoveParams.FileHandle = INVALID_HANDLE_VALUE) then

    MoveParams.FileHandle := CreateFile(PAnsiChar(AFile.FileName), GENERIC_READ,

    FILE_SHARE_READ OR FILE_SHARE_WRITE OR FILE_SHARE_DELETE,

    nil, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);

    ....



    AResult := DeviceIoControl(DeviceHandle, FSCTL_MOVE_FILE, @MoveParams, sizeof(MoveParams), nil, 0, w, @lSync);

    if (not AResult) then

    begin

    ....

    end;



    //По идее сюда должно быть передано управление сразу же. Однако управление не предается, а ждет окончания выполнения функции

    //DeviceIoControl.. Что сделано не так? Как добиться того, чтобы можно было прервать операцию...

    //Далее идет код, который и должен прервать операцию



    procedure TmyThread.StopProc;

    begin

    SetEvent(lSync.hEvent);

    end;
     
  2. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine


    Event, на который указывает lSync предусмотрен не для прерывания, AFAIK. Система устанавливает его сигнальный статус по окончании выполнения команды. Т.е. этот event предусмотрен лишь для слежения за завершением операции.



    Чтоб прервать тред, можно использовать TerminateThread, но это чревато нехорошими последствиями. Лучше копировать файл поблочно и после каждого блока проверять состояние флага синхронизации.
     
  3. salexn

    salexn New Member

    Публикаций:
    0
    Регистрация:
    4 май 2006
    Сообщения:
    5
    >Лучше копировать файл поблочно и после каждого блока проверять состояние флага синхронизации.

    Это как?
     
  4. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    salexn

    Допустим, размер файла x байт. Делим файл на n кусков по k байт. k для большей эффективности будет кратно размеру кластера. Делаем цикл (псевдокод):
    Код (Text):
    1. for(i = 0; i < n; i++){
    2.    copy(/* следующий блок */);
    3.    if(flag == 1){
    4.       close_file();
    5.       clean_up();
    6.       // ***
    7.       exit_thread();
    8.    }
    9. }


    Для остановки этого треда достаточно выставить флаг (flag = 1) и подождать немного.
     
  5. salexn

    salexn New Member

    Публикаций:
    0
    Регистрация:
    4 май 2006
    Сообщения:
    5
    >Quantum

    Даа... А вы гарантируете, что после такого действия файл не будет фрагментированным... Я нет.
     
  6. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    salexn

    Причём тут фрагментация? Почитайте на досуге про файловые системы. Зато хладнокровно кильнуть тред, который копирует файл может, в лучшем случае, "засорить" ваш диск, а в худшем...