2009-03-25 6 views
1

"빠른 제거를 위해 최적화"정책 세트가있는 루프의 파일을 USB 스틱에 복사하는 백그라운드 애플리케이션을 작성하고 있습니다. 그러나 응용 프로그램이 중단되면 스틱이이 프로세스 (특히 아래의 WriteFile() 호출에서 ERROR FILE NOT FOUND를 반환 함)를 통해 제거되면 드라이브가 다른 응용 프로그램에서 영구적으로 액세스 할 수 없으며 PC를 종료/로그 오프/재시작 등. 실행중인 모든 Windows 탐색기 인스턴스도 결과로 중지됩니다.USB 스틱에 파일을 쓰면 갑자기 꺼내지면 파일 손상/잠김이 발생합니다.

스틱이 제거되고 위의 오류가 발생한 후 CloseHandle() 호출에이 문제를 추적했습니다. 마치 막대기가 더 이상 존재하지 않기 때문에 CloseHandle()이 드라이버에서 무한정 차단하고있는 것처럼 보입니다. 어쨌든, WriteFile()이 ERROR FILE NOT FOUND를 반환하면 CloseHandle() 호출을 생략함으로써이 문제를 해결할 수있었습니다. 그러나 이렇게하면 파일이 복구 불가능하게 손상되고 chkdsk를 사용하거나 스틱을 다시 포맷하는 유일한 방법이있는 경우가 자주 있습니다.

XP (SP2 및 3)에서만 발생하며 Vista에서는 문제가없는 것 같습니다. 코드의 조각은 다음과 같습니다 : 나는 아무 소용를 CreateFile() 모든 플래그의 거의 모든 조합을 시도했습니다

HANDLE hFile = CreateFile(szFile, 
          GENERIC_WRITE, 
          FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, 
          NULL, 
          CREATE_ALWAYS, 
          FILE_FLAG_WRITE_THROUGH, 
          NULL); 
if (hFile != INVALID_HANDLE_VALUE) 
{ 
    if (!WriteFile(hFile, pBuffer, dwBufferSize, &dwWritten)) 
    { 
     int nLastError = GetLastError(); 
    } 

    // If usb stick is removed during WriteFile(), ERROR_FILE_NOT_FOUND usually  results. 
    // If handle is closed at this point then drive is inaccessible. 
    // If CloseHandle() is skipped, then file corruption occurs instead 
    if (nLastError != ERROR_FILE_NOT_FOUND) 
    { 
     CloseHandle(hFile); 
    } 
} 

. 아무도 이것을 본 적이 없거나 두 가지 문제 중 하나가 발생하지 않도록하는 좋은 아이디어가 있습니다. 나는 비스타에서 조용히 고쳐진 운전자 문제를보고있다.

도움 주셔서 감사합니다.

답변

2

그것의 거의하여 CloseHandle()가 무기한 차단 된 경우 등 어딘가에있는 드라이버에서 스틱이 더 이상 없기 때문에?

소리가 적당합니다. CloseHandle()은 궁극적으로 파일 시스템 IRP를 내보내고 논 블로킹 I/O를 사용하지 않으므로 IRP는 동기식이지만 실제 파일 시스템이 갑자기 파일 시스템 드라이버 아래에서 사라진 것처럼 보입니다. IRP는 완료되지 않습니다. 즉, 파일 시스템 IRP가 실행되는 사용자 모드 함수 호출이 반환되지 않습니다.

논 블로킹 I/O를 사용해보십시오. 적어도 걸려 있지 않은 점에서이 문제를 해결할 수 있습니다. IRP가 계속 전달 될 것이고 거의 확실하게 여전히 백업되지는 않을 것이기 때문에 여전히 리소스 손실 등이 발생할 것입니다. 그러나 적어도 당신은 그것을 막지 않을 것입니다.

BTW, 나는이게 아마도 손상의 가능성을 줄이기 위해 파일 시스템에 쓰기의 순서에 영향을 미칠 캐시의 양을 줄일 수 있도록 설계 말할 것입니다 "빠른 제거를 위해 최적화"; 나는 그것이 파일 시스템 출발의 경우에 파일 시스템을 보존하기위한 것이라고 의심한다. 쓰는 동안!

이것은 파일 시스템을 죽이면 놀랄 일이 아닙니다.

0

매달린 문제 : 쓰기를 위해 별도의 스레드를 생성하고 주 스레드에서 쓰기 프로세스를 감독하고 의심스러운만큼 오래 걸리면 쓰기 스레드를 중단 할 수 있습니다. 다른 말로하면 : 쓰기를 비동기 적으로 구현하고 제한 시간을 찾으십시오.

+0

답장을 보내 주셔서 감사합니다. 그것은 실제로 * my * 응용 프로그램의 매달리기 문제를 해결할 것이지만, 손상은 이미 파일 시스템의 마운트 된 드라이브에서도 이미 수행되었습니다. 다른 응용 프로그램에서는 여전히 액세스 할 수 없으므로 PC는 종료/로그 오프 등의 시간에 멈 춥니 다. –

+1

스레드를 중단하지 마십시오. 이것이 도움이 될만한 유스 케이스는 없습니다. 당신은 오직 '국가 부패'등의 위험이 있습니다. – Christopher

+0

스레드가 멈 추면 어떻게 할 수 있습니까? 나는이 완벽한 솔루션입니다 말을하지만, 스레드를 중단하고 위험 상태가 손상 IMO 확실히 전체 응용 프로그램을 매달려 뛰는 아니에요. –

1

이것은 드라이버 문제인 것으로 보입니다.

드라이버에 대한 모든 핸들을 자유롭게해서 정리할 수 있도록하고 창을 언로드해야합니다. 그렇게하지 않으면 운전자는 장치가 변경 되더라도 장치에 대한 책임이 있다고 생각합니다.

사용자 모드에서이 문제를 피할 수 없습니다. (창 모두 포기 열린 핸들을 닫습니다하려고 있도록 프로그램을 종료하기 예.) 핸들을 포기

단지 이후의 단계로 문제를 전달

0

하드웨어 드라이버가 아닌 파일 시스템 드라이버에 문제가 있습니까? NTFS를 사용하면 문제가 사라질 수 있습니다.