This page has been machine-translated from the original page.
I wanted a tool that could obtain file handles with arbitrary settings for testing, so I created a simple one.
Table of Contents
Source Code
#include <windows.h>
#include <iostream>
#include <string>
# define FILE_SHARE_NONE 0x00000000
int isEmpty(std::wstring text) {
if (text.empty()) {
std::wcerr << L"Input is empty. Using default path." << std::endl;
return 1;
}
return 0;
}
std::wstring handleInput(std::wstring text) {
while (!text.empty() && (text.back() == L'\n' || text.back() == L'\r' || text.back() == L' '))
text.pop_back();
return text;
}
HANDLE createFileHandle(const std::wstring& path, std::wstring& desiredAccess, std::wstring& shareMode) {
DWORD dwDesiredAccess = 0;
DWORD dwShareMode = 0;
if (desiredAccess == L"1") {
dwDesiredAccess = GENERIC_READ;
}
else if (desiredAccess == L"2") {
dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
}
else {
std::wcerr << L"Invalid desired access input." << std::endl;
return NULL;
}
if (shareMode == L"1") {
dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
}
else if (shareMode == L"2") {
dwShareMode = FILE_SHARE_READ;
}
else if (shareMode == L"3") {
dwShareMode = FILE_SHARE_NONE;
}
else {
std::wcerr << L"Invalid share mode input." << std::endl;
return NULL;
}
HANDLE hFile = CreateFileW(
path.c_str(), // lpFileName
dwDesiredAccess, // dwDesiredAccess
dwShareMode, // dwShareMode
NULL, // lpSecurityAttributes
OPEN_ALWAYS, // dwCreationDisposition
FILE_ATTRIBUTE_NORMAL, // dwFlagsAndAttributes
NULL // hTemplateFile
);
if (hFile == INVALID_HANDLE_VALUE) {
std::wcerr << L"Failed to open file. Error: " << GetLastError() << std::endl;
return NULL;
}
std::wcout << L"File opened successfully." << std::endl;
return hFile;
}
int wmain()
{
// Input target file path
std::wcout << L"Input target file path(Default C:\\Windows\\Temp\\testfile.txt): ";
std::wstring path;
std::getline(std::wcin, path);
path = handleInput(path);
if (isEmpty(path)) {
path = L"C:\\Windows\\Temp\\testfile.txt";
}
// Input desired access
std::wcout << L"\nWhat is desired access?\n1:\"GENERIC_READ\"\n2:\"GENERIC_READ | GENERIC_WRITE\" : ";
std::wstring desiredAccess;
std::getline(std::wcin, desiredAccess);
desiredAccess = handleInput(desiredAccess);
if (isEmpty(desiredAccess))
return 1;
// Input share mode
std::wcout << L"\nWhat is share mode?\n1:\"FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE\"\n2:\"FILE_SHARE_READ\"\n3:\"FILE_SHARE_NONE\" : ";
std::wstring shareMode;
std::getline(std::wcin, shareMode);
shareMode = handleInput(shareMode);
if (isEmpty(shareMode))
return 1;
HANDLE hFile = createFileHandle(path, desiredAccess, shareMode);
std::wcout << L"\nPlease Enter key to close.";
std::wstring tmp;
std::getline(std::wcin, tmp);
CloseHandle(hFile);
return 0;
}Operation Check
When you run the tool built from the code above, you can execute CreateFileW by specifying the dwDesiredAccess and dwShareMode options as shown below.
This makes it easy to verify behaviors such as CreateFile failing with SHARING VIOLATION when you execute CreateFile with FILE_SHARE_NONE against a file whose handle has already been obtained with FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE.
Summary
GitHub Copilot’s development assistance is so intelligent that writing code has become incredibly easy.
I also wrote this article in 10 minutes.