From 3ff07edb0bc8969f580d543ee0de674df8325e16 Mon Sep 17 00:00:00 2001 From: Robert Roebling Date: Thu, 5 Oct 2006 17:28:31 +0000 Subject: [PATCH] [ 1560785 ] wxFileName::IsReadable/Writable/Executable git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@41638 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/latex/wx/filename.tex | 70 ++++++++++++++++++++++++++++++++++-- include/wx/filefn.h | 5 +++ include/wx/filename.h | 28 ++++++++++++--- src/common/filefn.cpp | 73 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 170 insertions(+), 6 deletions(-) diff --git a/docs/latex/wx/filename.tex b/docs/latex/wx/filename.tex index 311783e728..ba2c91213b 100644 --- a/docs/latex/wx/filename.tex +++ b/docs/latex/wx/filename.tex @@ -93,7 +93,15 @@ class are \helpref{GetVolumeSeparator}{wxfilenamegetvolumeseparator},\rtfsp \membersection{File name construction}\label{filenameconstruction} -TODO. +You can initialize a wxFileName instance using one of the following functions: + +\helpref{wxFileName constructors}{wxfilenamewxfilename}\\ +\helpref{Assign}{wxfilenameassign}\\ +\helpref{AssignCwd}{wxfilenameassigncwd}\\ +\helpref{AssignDir}{wxfilenameassigndir}\\ +\helpref{AssignHomeDir}{wxfilenameassignhomedir}\\ +\helpref{AssignHomeTempFileName}{wxfilenameassigntempfilename}\\ +\helpref{operator $=$}{wxfilenameoperatorassign} \membersection{File tests}\label{filetests} @@ -105,7 +113,15 @@ with such name exists and \helpref{DirExists}{wxfilenamedirexists} can be used to test for directory existence. File names should be compared using \helpref{SameAs}{wxfilenamesameas} method -or \helpref{$==$}{wxfilenameoperatorequal}. +or \helpref{operator $==$}{wxfilenameoperatorequal}. + +For testing basic access modes, you can use: + +\helpref{IsDirWritable}{wxfilenameisdirwritable}\\ +\helpref{IsDirReadable}{wxfilenameisdirreadable}\\ +\helpref{IsFileWritable}{wxfilenameisfilewritable}\\ +\helpref{IsFileReadable}{wxfilenameisfilereadable}\\ +\helpref{IsFileExecutable}{wxfilenameisfileexecutable} \membersection{File name components}\label{filenamecomponents} @@ -619,6 +635,56 @@ Returns {\tt true} if this filename is absolute. Returns {\tt true} if the file names of this type are case-sensitive. +\membersection{wxFileName::IsDirReadable}\label{wxfilenameisdirreadable} + +\constfunc{bool}{IsDirReadable}{\void} + +\func{static bool}{IsDirReadable}{\param{const wxString\& }{dir}} + +Returns {\tt true} if the directory component of this instance (or given \arg{dir}) +is an existing directory and this process has read permissions on it. +Read permissions on a directory mean that you can list the directory contents but it +doesn't imply that you have read permissions on the files contained. + + +\membersection{wxFileName::IsDirWritable}\label{wxfilenameisdirwritable} + +\constfunc{bool}{IsDirWritable}{\void} + +\func{static bool}{IsDirWritable}{\param{const wxString\& }{dir}} + +Returns {\tt true} if the directory component of this instance (or given \arg{dir}) +is an existing directory and this process has write permissions on it. +Write permissions on a directory mean that you can create new files in the directory. + + +\membersection{wxFileName::IsFileExecutable}\label{wxfilenameisfileexecutable} + +\constfunc{bool}{IsFileExecutable}{\void} + +\func{static bool}{IsFileExecutable}{\param{const wxString\& }{file}} + +Returns {\tt true} if a file with this name exists and if this process has execute permissions on it. + + +\membersection{wxFileName::IsFileReadable}\label{wxfilenameisfilereadable} + +\constfunc{bool}{IsFileReadable}{\void} + +\func{static bool}{IsFileReadable}{\param{const wxString\& }{file}} + +Returns {\tt true} if a file with this name exists and if this process has read permissions on it. + + +\membersection{wxFileName::IsFileWritable}\label{wxfilenameisfilewritable} + +\constfunc{bool}{IsFileWritable}{\void} + +\func{static bool}{IsFileWritable}{\param{const wxString\& }{file}} + +Returns {\tt true} if a file with this name exists and if this process has write permissions on it. + + \membersection{wxFileName::IsOk}\label{wxfilenameisok} \constfunc{bool}{IsOk}{\void} diff --git a/include/wx/filefn.h b/include/wx/filefn.h index 5839b81095..3915a0176b 100644 --- a/include/wx/filefn.h +++ b/include/wx/filefn.h @@ -472,6 +472,11 @@ inline bool wxPathExists(const wxChar *pszPathName) } #endif //WXWIN_COMPATIBILITY_2_6 +// permissions; these functions work both on files and directories: +WXDLLIMPEXP_BASE bool wxIsWritable(const wxString &path); +WXDLLIMPEXP_BASE bool wxIsReadable(const wxString &path); +WXDLLIMPEXP_BASE bool wxIsExecutable(const wxString &path); + // ---------------------------------------------------------------------------- // separators in file names // ---------------------------------------------------------------------------- diff --git a/include/wx/filename.h b/include/wx/filename.h index 5154ed057e..801529327d 100644 --- a/include/wx/filename.h +++ b/include/wx/filename.h @@ -19,9 +19,7 @@ 2. more file operations: a) chmod() b) [acm]time() - get and set - c) file permissions with readable accessors for most common bits - such as IsReadable() &c - d) rename()? + c) rename()? 3. SameFileAs() function to compare inodes under Unix */ @@ -86,6 +84,7 @@ enum extern wxULongLong wxInvalidSize; + // ---------------------------------------------------------------------------- // wxFileName: encapsulates a file path // ---------------------------------------------------------------------------- @@ -193,7 +192,28 @@ public: bool DirExists() const; static bool DirExists( const wxString &dir ); - // VZ: also need: IsDirWritable(), IsFileExecutable() &c (TODO) + // checks on most common flags for files/directories; + // more platform-specific features (like e.g. Unix permissions) are not + // available in wxFileName + + bool IsDirWritable() const { return wxIsWritable(GetPath()); } + static bool IsDirWritable(const wxString &path) { return wxDirExists(path) && wxIsWritable(path); } + + bool IsDirReadable() const { return wxIsReadable(GetPath()); } + static bool IsDirReadable(const wxString &path) { return wxDirExists(path) && wxIsReadable(path); } + + // NOTE: IsDirExecutable() is not present because the meaning of "executable" + // directory is very platform-dependent and also not so useful + + bool IsFileWritable() const { return wxIsWritable(GetFullPath()); } + static bool IsFileWritable(const wxString &path) { return wxFileExists(path) && wxIsWritable(path); } + + bool IsFileReadable() const { return wxIsReadable(GetFullPath()); } + static bool IsFileReadable(const wxString &path) { return wxFileExists(path) && wxIsReadable(path); } + + bool IsFileExecutable() const { return wxIsExecutable(GetFullPath()); } + static bool IsFileExecutable(const wxString &path) { return wxFileExists(path) && wxIsExecutable(path); } + // time functions #if wxUSE_DATETIME diff --git a/src/common/filefn.cpp b/src/common/filefn.cpp index 6fe03ab10a..6b0c967cca 100644 --- a/src/common/filefn.cpp +++ b/src/common/filefn.cpp @@ -1759,6 +1759,79 @@ int WXDLLEXPORT wxParseCommonDialogsFilter(const wxString& filterStr, return filters.GetCount(); } +#if defined( __WINDOWS__ ) +bool wxCheckGenericPermission(const wxString &path, DWORD access) +{ + // quoting the MSDN: "To obtain a handle to a directory, call the + // CreateFile function with the FILE_FLAG_BACKUP_SEMANTICS flag" + wxWinVersion ver = wxGetWinVersion(); + bool isdir = wxDirExists(path); + if (isdir && (ver == wxWinVersion_95 || ver == wxWinVersion_98 || ver == wxWinVersion_ME)) + { + // however Win95/98/ME do not support FILE_FLAG_BACKUP_SEMANTICS... + if (access == GENERIC_READ) + { + WIN32_FILE_ATTRIBUTE_DATA data; + if (GetFileAttributesEx(path.c_str(), GetFileExInfoStandard, &data) == 0) + return false; // cannot query attributes + return (data.dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0; + } + + // FIXME: is it true that directories are always writable & executable on Win9X family ? + return true; + } + else + { + HANDLE h = CreateFile(path.c_str(), access, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, + OPEN_EXISTING, isdir ? FILE_FLAG_BACKUP_SEMANTICS : 0, NULL); + if (h != INVALID_HANDLE_VALUE) + CloseHandle(h); + + return h != INVALID_HANDLE_VALUE; + } +} +#endif + +bool wxIsWritable(const wxString &path) +{ +#if defined( __UNIX__ ) + // access() will take in count also symbolic links + return access(wxConvFile.cWX2MB(path), W_OK) == 0; +#elif defined( __WINDOWS__ ) + return wxCheckGenericPermission(path, GENERIC_WRITE); +#else + // TODO + return false; +#endif +} + +bool wxIsReadable(const wxString &path) +{ +#if defined( __UNIX__ ) + // access() will take in count also symbolic links + return access(wxConvFile.cWX2MB(path), R_OK) == 0; +#elif defined( __WINDOWS__ ) + return wxCheckGenericPermission(path, GENERIC_READ); +#else + // TODO + return false; +#endif +} + +bool wxIsExecutable(const wxString &path) +{ +#if defined( __UNIX__ ) + // access() will take in count also symbolic links + return access(wxConvFile.cWX2MB(path), X_OK) == 0; +#elif defined( __WINDOWS__ ) + return wxCheckGenericPermission(path, GENERIC_EXECUTE); +#else + // TODO + return false; +#endif +} + //------------------------------------------------------------------------ // wild character routines -- 2.45.2