- 아티클
- 2023. 07. 17.
이 문서의 내용
증상
대상 파일이 쓰기 공유 모드(FILE_SHARE_WRITE)로 열려 있는 동안 Windows 환경에서 함수를 사용하여 LockFileEx 파일을 잠급니다. 이 시나리오에서 파일 콘텐츠는 다른 프로세스에 의해 덮어씁니다.
다음 예제에서는 이 시나리오가 발생할 수 있는 방법을 설명합니다.
프로세스 A에서 쓰기 공유 모드에서 대상 파일을 연 다음 함수를 사용하여 LockFileEx 파일을 잠급니다. 파일 탐색기 동일한 파일을 복사하고 덮어쓰는 경우 오류 메시지가 표시됩니다. 취소를 선택한 다음 종료하는 경우 대상 파일의 크기는 동일하게 유지됩니다. 그러나 파일 콘텐츠는 0x00 대체됩니다.
오류 메시지는 다음과 같이 읽습니다.
예기치 않은 오류는 파일을 복사하지 못하게 하는 것입니다. 이 오류가 계속 발생하면 오류 코드를 사용하여 이 문제에 대한 도움말을 검색할 수 있습니다.
오류 0x80070021:
다른 프로세스가 파일의 일부를 잠갔기 때문에 프로세스에서 파일에 액세스할 수 없습니다.
프로세스 A에 대한 샘플 코드:
int wmain
(
int argc,
TCHAR* argv[]
)
{
HANDLE fh, h;
BOOL ret;
OVERLAPPED mOv= { 0 };
if (argc < 2) {
printf("Usage: LockFile Filename\n");
return 1;
}
fh =CreateFileW(argv[1],
GENERIC_READ | READ_CONTROL,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (fh == INVALID_HANDLE_VALUE) {
printf("CreateFileW failed with error: 0x%0x\n", GetLastError());
goto Exit;
}
ret = LockFileEx(fh, LOCKFILE_FAIL_IMMEDIATELY, 0, 0xffffffff, 0xffffffff, &mOv);
if (!ret) {
printf("LockFileEx failed with erro: 0x%0x\n", GetLastError());
CloseHandle(fh);
goto Exit;
}
getchar();
Exit:
return 0;
}
원인
이 문제는 Windows 파일 시스템 구현의 제한으로 인해 발생합니다. 함수를 LockFileEx 사용하는 경우 잠금은 세 번째 및 네 번째 인수에 지정된 바이트 범위의 읽기/쓰기 잠금입니다.
파일 탐색기 "파일 덮어쓰기" 복사 프로세스는 해당 및 CopyFileEx 함수를 사용하고 CreateFile 내부적으로 함수에 의해 NtSetFileInformation 파일 크기를 줄이거나 변경합니다. 함수의 LockFileEx 바이트 범위 잠금 기능은 함수가 파일 크기를 변경할 때 NtSetFileInformation 파일을 잠글 수 없습니다. 따라서 쓰기 공유 모드를 설정하여 데이터를 변경할 수 있습니다.
해결 방법
이 문제를 해결하려면 함수를 사용하여 CreateFile 파일을 열 때 쓰기 공유 모드(FILE_SHARE_WRITE)를 지정하지 않음으로써 파일에서 데이터 쓰기 작업을 보호할 수 있습니다.
'[Microsoft]' 카테고리의 다른 글
메모리가 해제된 후 힙 관리자는 메모리를 커밋 해제하지 않을 수 있습니다. (1) | 2023.11.03 |
---|---|
GetTickCount는 약 776일 후에 0으로 다시 설정됩니다. (0) | 2023.11.03 |
CreateProcess는 lpEnvironment 매개 변수의 환경 블록에서 중복된 변수를 제거하지 않습니다. (0) | 2023.11.03 |
핵심 OS 프로세스에 대한 추가 기능 구성 요소 지침 (0) | 2023.11.03 |
Windows에서 비동기 디스크 I/O가 동기로 표시됨 (0) | 2023.11.03 |