파일의 존재유무를 확인하고자 할때는 CreateFile을 사용하지 않는 것이 좋습니다.
CreateFile은 파일의 핸들을 얻어오는 함수이지 파일의 존재를 확인하는 함수가 아니기 때문입니다.

CreateFile이 핸들을 얻어오는데 실패하는 여러가지 경우가 존재합니다.

    1) 파일의 NTFS 권한이 없는 경우  (ERROR_ACCESS_DENIED)
    2) CreateFile함수의 인자에 핸들을 얻어오기 위한 적절한 권한이 설정되지 않은 경우 (ERROR_SHARING_VIOLATION)
    3) 파일이 존재하지 않는 경우 (ERROR_FILE_NOT_FOUND)
    4)  핸들 Leak이 발생하여 핸들 생성에 실패한 경우 (??)
    5) ... ??

HANDLE WINAPI CreateFile(
      __in      LPCTSTR lpFileName,
      __in      DWORD dwDesiredAccess,
      __in      DWORD dwShareMode,
      __in_opt  LPSECURITY_ATTRIBUTES lpSecurityAttributes,
      __in      DWORD dwCreationDisposition,
      __in      DWORD dwFlagsAndAttributes,
      __in_opt  HANDLE hTemplateFile
);


Visual Studio를 띄워놓은 상태에서 폴더를 복사하려고 시도하면 오류가 발생하는데 바로 3)번 관련된 상황입니다.

예를 들어 A.exe라는 프로세스가 CreateFile의 세번째 인자인 dwShareMode에 FILE_SHARE_WRITE 를 설정하여 CreateFile한 상태에서 B.exe라는 프로세스가 FILE_SHARE_READ만 준 상태에서 CreateFile을 시도하면 B.exe는 핸들을 얻어오는데 실패하게 됩니다. 요약하면 CreateFile의 두번째 인자는 반드시 세번째 인자에 포함되어야 하고, 세번째 인자는 이전에 호출된 CreateFile의 세번째 인자들을 포함해야 합니다.

아래의 MSDN을 참고하세요.

    http://msdn.microsoft.com/en-us/library/aa363858%28VS.85%29.aspx
    http://msdn.microsoft.com/en-us/library/aa363874%28VS.85%29.aspx


파일의 존재여부를 확인하고자 하신다면 다음과 같은 함수를 사용하시는게 좋습니다. 아래의 함수들은 파일의 핸들을 얻는게 아니라 Directory에 대한 읽기 작업을 통해 파일의 존재여부를 확인합니다. (따라서 파일 자체에 권한이 없어도 존재여부 확인이 가능한 반면에, 상위 디렉토리에 읽기 혹은 실행 권한이 없다면 실패할 수 있습니다.)

FindFirstFile
  - kernel32.dll에 들어있어 그냥 사용 가능하지만 얻어진 핸들에 대해 FindClose() 해주어야 함.
  - Windows2000 이상에서 지원
PathFileExists, PathIsFile, PathIsDirectory
  - 사용법이 가장 간단
  - shlwapi.h 에 들어있으며, shlwapi.lib (import library) 를 포함시켜줘야 함.
  - Windows95/98  지원

   
굳이 CreateFile을 사용하시려면,  CreateFile에 실패한 경우 GetLastError하여 실패코드가 ERROR_FILE_NOT_FOUND 인 경우에만 파일이 존재하지 않는 것으로 판단하시어 다른 조치를 취하시면 될 것 같습니다.

반면에, 만약 다른 프로세스가 먼저 Open한 파일이라도 핸들을 반드시 얻어야 한다면, 아래 코드처럼 처음부터 dwShareMode를 좀 쎄게(?) 주는 것도 방법이 될 수 있겠죠. ^^

Posted by kuaaan

댓글을 달아 주세요

  1. 구차니 2009.12.10 17:16 신고  댓글주소  수정/삭제  댓글쓰기

    앗 좋은내용이네요 +_+
    linux에서는 확인하는 API를 찾았었는데 윈도우는 못 찾았었거든요 ㅠ.ㅠ

  2. 큐브씨 2009.12.10 20:31 신고  댓글주소  수정/삭제  댓글쓰기

    전에 구현할 때는 _taccess 를 쓴 것 같은데.. 많은 방법이 있었군요 ^^;
    이제 CreateFile 을 봐도 기억이 가물가물..
    별일 없으시죠?

    • kuaaan 2009.12.10 21:00 신고  댓글주소  수정/삭제

      그럼 잘 지내지.. 지금 사무실에서 코딩중.. ^^
      여기와서 제일 먼저 바꾸기 시작한 것이 CRT 안쓰기야. 왠지는 잘 모르겠지만 쓰지말라고 그러더군. 그래서 대문자로 시작하는 함수들 위주로 쓰고 있지.
      어떻게 지내? 새 일은 재미있나?

  3. BlueBright 2018.09.11 13:16 신고  댓글주소  수정/삭제  댓글쓰기

    좋은 정보 잘 읽고 갑니다.
    링크로 담아가요.



사랑합니다. 편안히 잠드소서