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);
dwDesiredAccess [in] The requested access to the file or device, which can be summarized as read, write, both or neither zero).
The most commonly used values are GENERIC_READ, GENERIC_WRITE, or both (
GENERIC_READ | GENERIC_WRITE
). For more information, see Generic Access Rights, File Security and Access Rights, File Access Rights Constants, and ACCESS_MASK.If this parameter is zero, the application can query certain metadata such as file, directory, or device attributes without accessing that file or device, even if GENERIC_READ access would have been denied.
You cannot request an access mode that conflicts with the sharing mode that is specified by thedwShareMode parameter in an open request that already has an open handle.
For more information, see the Remarks section of this topic and Creating and Opening Files.
dwShareMode [in] The requested sharing mode of the file or device, which can be read, write, both, delete, all of these, or none (refer to the following table). Access requests to attributes or extended attributes are not affected by this flag.
If this parameter is zero and CreateFile succeeds, the file or device cannot be shared and cannot be opened again until the handle to the file or device is closed. For more information, see the Remarks section.
You cannot request a sharing mode that conflicts with the access mode that is specified in an existing request that has an open handle. CreateFile would fail and the GetLastError function would returnERROR_SHARING_VIOLATION.
To enable a process to share a file or device while another process has the file or device open, use a compatible combination of one or more of the following values. For more information about valid combinations of this parameter with the dwDesiredAccess parameter, see Creating and Opening Files.
Note The sharing options for each open handle remain in effect until that handle is closed, regardless of process context.
빨간 볼드친 부분을 주목해서 보시면 됩니다. 우리말로 풀어쓰면 다음과 같습니다.
1. CreateFile 호출 시 지정되는 dwDesiredAccess 인자는 기존에 열린 핸들의 dwShareMode와 충돌나면 안된다. (즉, 기존에 열린 모든 핸들의 dwShareMode의 부분집합이어야 한다는 뜻입니다.)
2. CreateFile 호출시 지정되는 dwShareMode 인자는 기존에 열린 핸들의 dwDesiredAccess와 충돌나면 안된다. (즉, 기존에 열린 모든 핸들의 dwDesiredAccess를 포함해야 한다는 뜻입니다..)
핵심은 "DesiredAccess"는 기존에 열린 핸들의 "ShareMode"와, "ShareMode"는 기존에 열린 핸들의 "DesiredAccess"와 비교된다는 점입니다.
(비교시 GENERIC_READ는 FILE_SHARE_READ와, GENERIC_WRITE는 FILE_SHARE_WRITE와 대응된다고 생각하시면 되겠습니다.)
한번 샘플코드를 보시죠.
위의 예제코드에서 두번째 CreateFile은 성공할까요? 네~ 실패합니다.
두번째 호출에서의 DesiredAccess(GENERIC_READ)가 첫번째 호출시의 ShareMode(FILE_SHARE_WRITE)와 충돌나기 때문입니다. (GENERIC_READ 가 FILE_SHARE_WRITE의 부분집합이 아님)
위의 예제코드는 어떨까요? 결과는 역시 "실패"입니다.
두번째 호출시의 ShareMode(FILE_SHARE_READ)가 첫번째 호출의 DesiredAccess(GENERIC_READ|GENERIC_WRITE)와 충돌나기 때문이죠. (GENERIC_READ|GENERIC_WRITE가 FILE_SHARE_READ 의 부분집합이 아님)
ShareMode를 다음과 같이 수정하면 두번째 호출을 성공시킬 수 있습니다.
이번에는 3단계 테스트입니다.
위의 샘플코드 역시 세번째 CreateFile이 실패합니다. 이유는 세번째 호출 시의 DesiredAccess(GENERIC_WRITE)가 첫번째 호출의 (FILE_SHARE_READ)와 충돌나기 때문인데요... 사실 첫번째, 두번째 호출에서 위와 같이 핸들이 열린 상태에서는 세번째 호출시 DesiredAccess를 "FILE_SHARE_READ" / "FILE_SHARE_WRITE" / "GENERIC_READ|FILE_SHARE_WRITE" 세가지 중 어떤 형태로 지정하더라도 모두 실패하게 됩니다. 첫번째 호출의 ShareMode 에서 FILE_SHARE_READ 가 지정되었으므로 세번째 호출의 DesiredAccess는 FILE_SHARE_READ 의 부분집합이어야 하는데, 두번째 호출의 ShareMode가 FILE_SHARE_WRITE 였으므로 세번째 호출의 DesiredAccess는 동시에 FILE_SHARE_WRITE 의 부분집합이기도 해야 하거든요.
이런 건 가능합니다.
CreateFile MSDN에 이렇게 나와 있네요. ^^
dwShareMode [in] The requested sharing mode of the file or device, which can be read, write, both, delete, all of these, or none (refer to the following table). Access requests to attributes or extended attributes are not affected by this flag.
마지막 퀴즈~
네~ 마지막 샘플코드를 실행하면 세 번의 CreateFile이 모두 성공합니다. 세번째 호출시의 DesiredAccess 는 첫번째 ShareMode (FILE_SHARE_READ)와 두번째 ShareMode (FILE_SHARE_READ | FILE_SHARE_WRITE)를 모두 만족시키고, 세번째 호출의 ShareMode (FILE_SHARE_READ|FILE_SHARE_WRITE)가 첫번째 호출의 DesiredAccess (GENERIC_WRITE)와 두번째 호출의 DesiredAccess (GENERIC_READ)를 모두 만족시키기 때문입니다.
'C++' 카테고리의 다른 글
VM환경에서 CoCreateGuid()의 GUID Dup 문제 (0) | 2018.05.10 |
---|---|
파일이 수정 (삭제) 가능한 상태인지 체크하는 방법 (How to Determine a File is Writable or Deletable) (2) | 2013.07.18 |
CreateProcessAsUser 시 ACCESS_DENIED 문제 (0) | 2013.06.13 |
DLL / LIB 에서의 함수 Export 시 Name Mangling (Decoration) 규칙 (0) | 2012.05.08 |
서비스를 svchost에 따로 실행하기 (0) | 2011.07.27 |