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

View File

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