• 카테고리

    질문 & 답변
  • 세부 분야

    데스크톱 앱 개발

  • 해결 여부

    해결됨

파일 매핑 객체와 memcpy를 활용한 파일 복사 중, 왜 READ와 WRITE가 동시에 필요한가요?

23.08.06 21:03 작성 23.08.06 21:03 수정 조회수 267

0

안녕하십니까, 윈도우 시스템 프로그래밍 강의 듣고 있는 학생입니다. 메모리 맵 강의에서 소개해주신 숙제를 수행하던 중에 접근 모드를 설정하는 부분에 사소한 의문이 있어서 질문드립니다.

작성한 코드의 흐름은 대략 다음과 같습니다.

  1. CreateFile()

    src파일과 dst파일의 핸들을 획득.

  2. GetFileSizeEx()

    src파일의 크기를 획득

  3. SetFilePointer()

    dst파일의 크기를 설정, 2번의 값을 활용

  4. CreateFileMapping()

    각 파일의 매핑 객체 생성

  5. MapViewOfFile()

    각 파일 매핑 객체에 대한 포인터를 획득

  6. memcpy()

    각 파일에 대한 매핑 객체의 포인터와 파일의 크기로 파일의 복사

첫 시도에서 다음과 같이 1번과 4번을 수행했습니다.

<실패>

// 1번. dst 파일 생성 
	HANDLE hDst = CreateFile(
		TEXT("복사 대상 파일의 절대 경로"),
		GENERIC_WRITE,	
		0,
		NULL,
		CREATE_ALWAYS,
		FILE_ATTRIBUTE_NORMAL,
		NULL
	);
HANDLE hDstMap = 
CreateFileMapping(hDst, NULL, PAGE_WRITECOPY, 0, llFileSize.LowPart, NULL);
	if (hDstMap == NULL)
	{
		wprintf(L"Failed to create Dst file mapping obj [ERROR CODE: %d]\n",
			::GetLastError());

		CloseHandle(hSrcMap);
		CloseHandle(hSrc);
		CloseHandle(hDst);
		return 0;
	}

수행 결과, Dst파일에 대한 맵뷰 객체를 생성하는데 실패했고, ERROR_ACCESS_DENIED에러 코드를 받았습니다.

MSDN에서 CreateFileMapping()에 대해서 찾아본 결과, PAGE_WRITECOPY플래그가 PAGE_READONLY와 동일하다는 점을 확인하고 다음과 같이 수정하여 실행에 성공했습니다.

<성공>

HANDLE hDst = CreateFile(
		TEXT("복사 대상 파일의 절대 경로"),
		GENERIC_WRITE | GENERIC_READ,	// 왜 GENERIC_WRITE만 설정하면 ERROR_ACCESS_DENIED인가요?
		0,
		NULL,
		CREATE_ALWAYS,
		FILE_ATTRIBUTE_NORMAL,
		NULL
	);
HANDLE hDstMap 
= CreateFileMapping(hDst, NULL, PAGE_READWRITE, 0, llFileSize.LowPart, NULL);
	if (hDstMap == NULL)
	{
		wprintf(L"Failed to create Dst file mapping obj [ERROR CODE: %d]\n",
			::GetLastError());

		CloseHandle(hSrcMap);
		CloseHandle(hSrc);
		CloseHandle(hDst);
		return 0;
	}

MSDN에서 문제를 해결했지만, dst 파일에는 복사한 내용을 써넣기만 하는데 왜 dst파일에 대한 READ가 필요한지 의문이 들어서 이에 질문드립니다. 긴 글 읽어주셔서 감사드립니다.

답변 1

답변을 작성해보세요.

0

MapViewOfFile() 함수 호출 시 적용된 FILE_MAP_WRITE는 Read/Write 접근 권한을 모두 요구하기 때문입니다. 정확한 것은 알 수 없지만 어느 정도 추측은 할 수 있습니다. 파일에 쓰기 매핑을 하기 위해서 대상 파일에 대한 사전 읽기 접근이 내부적으로 필요하기 때문일 것으로 보입니다.

MapViewOfFile()함수가 포인터를 반환해주기 때문에 2차 메모리에 해당하는 파일을 1차 메모리 처럼 쓸 수 있습니다. 이 과정에서 대상 파일에 대한 정보를 가져오려면 대상에 대한 기본 정보를 읽는 것은 어쩔 수 없이 수반된다 하겠습니다. 참고하시기 바랍니다.

곽도훈님의 프로필

곽도훈

질문자

2023.08.07

답변 감사합니다. 좋은 하루 되시기 바랍니다!

채널톡 아이콘