SF #3561464: Poco::File::isDevice() can throw due to sharing violation

This commit is contained in:
Aleksandar Fabijanic 2012-09-08 01:02:46 +00:00
parent 9ca1a770bc
commit 69bb6e4461
2 changed files with 58 additions and 52 deletions

View File

@ -191,15 +191,17 @@ bool FileImpl::isLinkImpl() const
bool FileImpl::isDeviceImpl() const
{
poco_assert (!_path.empty());
FileHandle fh(_path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, OPEN_EXISTING);
DWORD type = GetFileType(fh.get());
if (type == FILE_TYPE_CHAR)
return true;
else if (type == FILE_TYPE_UNKNOWN && GetLastError() != NO_ERROR)
handleLastErrorImpl(_path);
return false;
return
_path.compare(0, 4, "\\\\.\\") == 0 ||
icompare(_path, "CON") == 0 ||
icompare(_path, "PRN") == 0 ||
icompare(_path, "AUX") == 0 ||
icompare(_path, "NUL") == 0 ||
( (icompare(_path, 0, 3, "LPT") == 0 || icompare(_path, 0, 3, "COM") == 0) &&
_path.size() == 4 &&
_path[3] > 0x30 &&
isdigit(_path[3])
);
}
@ -373,48 +375,49 @@ bool FileImpl::createDirectoryImpl()
void FileImpl::handleLastErrorImpl(const std::string& path)
{
switch (GetLastError())
DWORD err = GetLastError();
switch (err)
{
case ERROR_FILE_NOT_FOUND:
throw FileNotFoundException(path);
throw FileNotFoundException(path, err);
case ERROR_PATH_NOT_FOUND:
case ERROR_BAD_NETPATH:
case ERROR_CANT_RESOLVE_FILENAME:
case ERROR_INVALID_DRIVE:
throw PathNotFoundException(path);
throw PathNotFoundException(path, err);
case ERROR_ACCESS_DENIED:
throw FileAccessDeniedException(path);
throw FileAccessDeniedException(path, err);
case ERROR_ALREADY_EXISTS:
case ERROR_FILE_EXISTS:
throw FileExistsException(path);
throw FileExistsException(path, err);
case ERROR_INVALID_NAME:
case ERROR_DIRECTORY:
case ERROR_FILENAME_EXCED_RANGE:
case ERROR_BAD_PATHNAME:
throw PathSyntaxException(path);
throw PathSyntaxException(path, err);
case ERROR_FILE_READ_ONLY:
throw FileReadOnlyException(path);
throw FileReadOnlyException(path, err);
case ERROR_CANNOT_MAKE:
throw CreateFileException(path);
throw CreateFileException(path, err);
case ERROR_DIR_NOT_EMPTY:
throw FileException("directory not empty", path);
throw FileException("directory not empty", path, err);
case ERROR_WRITE_FAULT:
throw WriteFileException(path);
throw WriteFileException(path, err);
case ERROR_READ_FAULT:
throw ReadFileException(path);
throw ReadFileException(path, err);
case ERROR_SHARING_VIOLATION:
throw FileException("sharing violation", path);
throw FileException("sharing violation", path, err);
case ERROR_LOCK_VIOLATION:
throw FileException("lock violation", path);
throw FileException("lock violation", path, err);
case ERROR_HANDLE_EOF:
throw ReadFileException("EOF reached", path);
throw ReadFileException("EOF reached", path, err);
case ERROR_HANDLE_DISK_FULL:
case ERROR_DISK_FULL:
throw WriteFileException("disk is full", path);
throw WriteFileException("disk is full", path, err);
case ERROR_NEGATIVE_SEEK:
throw FileException("negative seek", path);
throw FileException("negative seek", path, err);
default:
throw FileException(path);
throw FileException(path, err);
}
}

View File

@ -195,15 +195,17 @@ bool FileImpl::isLinkImpl() const
bool FileImpl::isDeviceImpl() const
{
poco_assert (!_path.empty());
FileHandle fh(_path, _upath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, OPEN_EXISTING);
DWORD type = GetFileType(fh.get());
if (type == FILE_TYPE_CHAR)
return true;
else if (type == FILE_TYPE_UNKNOWN && GetLastError() != NO_ERROR)
handleLastErrorImpl(_path);
return false;
return
_path.compare(0, 4, "\\\\.\\") == 0 ||
icompare(_path, "CON") == 0 ||
icompare(_path, "PRN") == 0 ||
icompare(_path, "AUX") == 0 ||
icompare(_path, "NUL") == 0 ||
( (icompare(_path, 0, 3, "LPT") == 0 || icompare(_path, 0, 3, "COM") == 0) &&
_path.size() == 4 &&
_path[3] > 0x30 &&
isdigit(_path[3])
);
}
@ -381,48 +383,49 @@ bool FileImpl::createDirectoryImpl()
void FileImpl::handleLastErrorImpl(const std::string& path)
{
switch (GetLastError())
DWORD err = GetLastError();
switch (err)
{
case ERROR_FILE_NOT_FOUND:
throw FileNotFoundException(path);
throw FileNotFoundException(path, err);
case ERROR_PATH_NOT_FOUND:
case ERROR_BAD_NETPATH:
case ERROR_CANT_RESOLVE_FILENAME:
case ERROR_INVALID_DRIVE:
throw PathNotFoundException(path);
throw PathNotFoundException(path, err);
case ERROR_ACCESS_DENIED:
throw FileAccessDeniedException(path);
throw FileAccessDeniedException(path, err);
case ERROR_ALREADY_EXISTS:
case ERROR_FILE_EXISTS:
throw FileExistsException(path);
throw FileExistsException(path, err);
case ERROR_INVALID_NAME:
case ERROR_DIRECTORY:
case ERROR_FILENAME_EXCED_RANGE:
case ERROR_BAD_PATHNAME:
throw PathSyntaxException(path);
throw PathSyntaxException(path, err);
case ERROR_FILE_READ_ONLY:
throw FileReadOnlyException(path);
throw FileReadOnlyException(path, err);
case ERROR_CANNOT_MAKE:
throw CreateFileException(path);
throw CreateFileException(path, err);
case ERROR_DIR_NOT_EMPTY:
throw FileException("directory not empty", path);
throw FileException("directory not empty", path, err);
case ERROR_WRITE_FAULT:
throw WriteFileException(path);
throw WriteFileException(path, err);
case ERROR_READ_FAULT:
throw ReadFileException(path);
throw ReadFileException(path, err);
case ERROR_SHARING_VIOLATION:
throw FileException("sharing violation", path);
throw FileException("sharing violation", path, err);
case ERROR_LOCK_VIOLATION:
throw FileException("lock violation", path);
throw FileException("lock violation", path, err);
case ERROR_HANDLE_EOF:
throw ReadFileException("EOF reached", path);
throw ReadFileException("EOF reached", path, err);
case ERROR_HANDLE_DISK_FULL:
case ERROR_DISK_FULL:
throw WriteFileException("disk is full", path);
throw WriteFileException("disk is full", path, err);
case ERROR_NEGATIVE_SEEK:
throw FileException("negative seek", path);
throw FileException("negative seek", path, err);
default:
throw FileException(path);
throw FileException(path, err);
}
}