Index: /cpp/common/nonstd.h
===================================================================
--- /cpp/common/nonstd.h	(revision 294)
+++ /cpp/common/nonstd.h	(revision 295)
@@ -61,64 +61,4 @@
 #endif
 
-#ifdef IPHONE
- #include <string>
- std::string getAppHome();
- std::string getAppResources();
- #define GET_APP_HOME getAppHome()
- #define GET_APP_RESOURCES getAppResources()
-#endif
-
-#ifdef SHP
- #define GET_APP_HOME "/Home/"
- #define GET_APP_RESOURCES "/Res/"
-#endif
-
-#ifdef TIZEN
- #define GET_APP_HOME "/data/"
- #define GET_APP_RESOURCES "/res/"
-#endif
-
-#ifdef __ANDROID__
- #define GET_APP_HOME getAppHome()
- #define GET_APP_RESOURCES "/resrc/" //inside APK, resources are kept in the "assets" subdirectory (in the "res" subdirectory there is no support for subdirectories nor accessing files by name). The prefix /resrc/ is just an indication that lets mfile easily discriminate between HOME (r/w) and RESOURCES (r) locations
-#endif
-
-#ifdef LINUX
- #define GET_APP_HOME "./"
- #define GET_APP_RESOURCES "./"
-#endif
-
-#ifdef MACOS
-#ifdef MACOS_APP_DIR //separate home/resources
- #include <string>
- std::string getAppHome();
- #define GET_APP_HOME getAppHome()
-#else //old style
- #define GET_APP_HOME "./"
-#endif
- #define GET_APP_RESOURCES "./"
-#endif
-
-#if defined(_WIN32) && !defined(SHP)
-    #define GET_APP_HOME ".\\"
-    #define GET_APP_RESOURCES ".\\"
-#endif
-
-#ifdef INITIAL_DIR_IS_HOME
- #include "cwd.h"
- #ifdef GET_APP_HOME
-  #undef GET_APP_HOME
- #endif
- #define GET_APP_HOME getAppHome()
-#endif
-
-#ifdef INITIAL_DIR_IS_RES
- #include "cwd.h"
- #ifdef GET_APP_RESOURCES
-  #undef GET_APP_RESOURCES
- #endif
- #define GET_APP_RESOURCES getAppResources()
-#endif
-
 //typedef unsigned char boolean; //niestety nie mozna uzyc 'bool' bo VC w rpcndr.h wlasnie tak definiuje booleana, jako unsigned char
 //typedef char byte; //rozne srodowiska c++ definiuja byte jako unsigned char! w javie jest inaczej -> trzeba i tak zmienic w portowanych zrodlach byte na char.
Index: /cpp/common/nonstd_stdio.cpp
===================================================================
--- /cpp/common/nonstd_stdio.cpp	(revision 294)
+++ /cpp/common/nonstd_stdio.cpp	(revision 295)
@@ -8,7 +8,9 @@
 #include <common/stl-util.h>
 
-#if defined _WIN32 && !defined SHP
-//<unistd.h> not needed for unlink()
+#ifdef _WIN32
 #include "Shlwapi.h" //PathIsRelative()
+#ifdef __BORLANDC__
+#pragma link "Shlwapi.lib" //PathIsRelative()
+#endif
 #include <sys/stat.h> //_stat
 #else
@@ -29,7 +31,27 @@
 }
 
-bool directoryExists(const char* path)
+#ifdef _WIN32
+bool isDirWritable(const char* path) //dir must not end with '\'
+{
+	wstring dir = Convert::utf8ToUtf16(path);
+	CreateDirectoryW(dir.c_str(), 0);
+	dir += L"\\test_file.write";
+	_wunlink(dir.c_str());
+	FILE *f = _wfopen(dir.c_str(), L"wt");
+	if (f)
+	{
+		fclose(f);
+		_wunlink(dir.c_str());
+		return true;
+	}
+	else
+		return false;
+}
+#endif
+
+bool directoryExists(const char* path, bool is_writable)
 {
 	struct _stat s;
+	if (path[0] == 0) path = ".";
 #ifdef _WIN32
 	if (_wstat(Convert::utf8ToUtf16(path).c_str(), &s) != 0) return false;
@@ -37,5 +59,28 @@
 	if (_stat(path, &s) != 0) return false;
 #endif
-	return S_ISDIR(s.st_mode);
+	if (S_ISDIR(s.st_mode))
+	{
+		if (is_writable)
+		{
+#ifdef _WIN32
+#ifndef W_OK
+#define W_OK 2 //http://msdn.microsoft.com/en-us/library/1w06ktdy.aspx
+#endif
+			//under Windows, access() is not a reliable way to check if a directory is writable
+			//http://stackoverflow.com/questions/198071/code-for-checking-write-permissions-for-directories-in-win2k-xp
+			//bool writable_access = _waccess(Convert::utf8ToUtf16(path).c_str(), W_OK) == 0;
+			bool writable_trial = isDirWritable(path);
+			//printf("Checking '%s' for writing(%d) using access(): result=%d\n", path, is_writable, writable_access);
+			//printf("File creation test: result=%d\n", writable_trial);
+			//return writable_access;
+			return writable_trial;
+#else
+			return access(path, W_OK) == 0;
+#endif
+		}
+		else
+			return true;
+	}
+	return false;
 }
 
@@ -51,5 +96,5 @@
 bool makeDirectories(const char* path)
 {
-	if (directoryExists(path)) return true;
+	if (directoryExists(path,false)) return true;
 	string parentdir = getFileDir(path);
 	if (!makeDirectories(parentdir.c_str())) return false;
@@ -92,5 +137,5 @@
 {
 	if (fname == NULL) return false; //SplitFileSystem never passes NULL but this function is public so we never know
-#if defined _WIN32
+#ifdef _WIN32
 	return PathIsRelativeW(Convert::utf8ToUtf16(fname).c_str()) == FALSE; //http://msdn.microsoft.com/en-us/library/bb773660%28v=vs.85%29.aspx
 #else
@@ -201,7 +246,7 @@
 MFILE *mfopen(const char *path, const char *mode)
 {
-	string respath=GET_APP_RESOURCES; //the macro can be char* or std::string, we don't know (nonstd.h, INITIAL_DIR_IS_RES, cwd.cpp) so we convert it to std::string
+	string respath=getAppResources();
 	//printFM("Opening '%s', mode='%s'",path,mode);
-	//printFM("GET_APP_RESOURCES='%s'",respath.c_str());
+	//printFM("getAppResources()='%s'",respath.c_str());
 	NvFile *rfile=NULL; //can only read
 	FILE *rwfile=NULL;
Index: /cpp/common/nonstd_stdio.h
===================================================================
--- /cpp/common/nonstd_stdio.h	(revision 294)
+++ /cpp/common/nonstd_stdio.h	(revision 295)
@@ -7,5 +7,5 @@
 
 bool fileExists(const char* path);
-bool directoryExists(const char* path);
+bool directoryExists(const char* path,bool is_writable);
 bool makeDirectory(const char* path);
 bool makeDirectories(const char* path);
Index: /cpp/frams/virtfile/stdiofile.cpp
===================================================================
--- /cpp/frams/virtfile/stdiofile.cpp	(revision 294)
+++ /cpp/frams/virtfile/stdiofile.cpp	(revision 295)
@@ -37,5 +37,5 @@
 }
 
-int StdioFileSystem::Vfexists(const char* path)
+bool StdioFileSystem::Vfexists(const char* path)
 {
 	return fileExists(path);
Index: /cpp/frams/virtfile/stdiofile.h
===================================================================
--- /cpp/frams/virtfile/stdiofile.h	(revision 294)
+++ /cpp/frams/virtfile/stdiofile.h	(revision 295)
@@ -8,9 +8,5 @@
 #include "virtfile.h"
 #include <frams/util/sstring.h>
-#ifdef USE_MFILE
 #include <common/nonstd_stdio.h>
-#else
-#include <stdio.h>
-#endif
 #include <common/nonstd_dir.h>
 
@@ -19,6 +15,8 @@
 public:
 	VirtFILE *Vfopen(const char *path, const char *mode);
-	int Vfexists(const char* path);
+	bool Vfexists(const char* path);
 	VirtDIR *Vopendir(const char* path);
+	bool Vmkdir(const char* path) { return makeDirectory(path); }
+	bool Vdirexists(const char* path,bool is_writable) { return directoryExists(path,is_writable); }
 };
 
@@ -28,8 +26,7 @@
 protected:
 	MFILE *file;
-	SString path;
 public:
-	StdioFILE(MFILE *f) { file = f; }
-	StdioFILE(MFILE *f, const SString& p) { file = f; path = p; }
+	StdioFILE(MFILE *f):VirtFILE("") { file = f; }
+	StdioFILE(MFILE *f, const SString& p):VirtFILE(p) { file = f; }
 	static void setStdio();
 	size_t Vread(void *ptr, size_t size, size_t nmemb) { return mfread(ptr, size, nmemb, file); }
@@ -41,5 +38,4 @@
 	long Vtell() { return mftell(file); }
 	int Vflush() { return 0; /*NOT IMPLEMENTED!*/ }
-	const char* VgetPath() { return path; }
 
 	~StdioFILE() { if (file) mfclose(file); }
@@ -50,8 +46,7 @@
 protected:
 	FILE *file;
-	SString path;
 public:
-	StdioFILE(FILE *f) { file = f; }
-	StdioFILE(FILE *f, const SString& p) { file = f; path = p; }
+	StdioFILE(FILE *f):VirtFILE("") { file = f; }
+	StdioFILE(FILE *f, const SString& p):VirtFILE(p) { file = f; }
 	static void setStdio();
 	size_t Vread(void *ptr, size_t size, size_t nmemb) { return fread(ptr, size, nmemb, file); }
@@ -67,5 +62,4 @@
 	void Vrewind() { rewind(file); }
 	int Vflush() { return fflush(file); }
-	const char* VgetPath() { return path; }
 
 	~StdioFILE() { if (file) fclose(file); }
Index: /cpp/frams/virtfile/stringfile.cpp
===================================================================
--- /cpp/frams/virtfile/stringfile.cpp	(revision 294)
+++ /cpp/frams/virtfile/stringfile.cpp	(revision 295)
@@ -71,12 +71,2 @@
 	return (chain != NULL) ? chain->Vfopen(path, mode) : NULL;
 }
-
-int StringFileSystem::Vfexists(const char* path)
-{
-	return (chain != NULL) ? chain->Vfexists(path) : 0;
-}
-
-VirtDIR *StringFileSystem::Vopendir(const char* path)
-{
-	return (chain != NULL) ? chain->Vopendir(path) : NULL;
-}
Index: /cpp/frams/virtfile/stringfile.h
===================================================================
--- /cpp/frams/virtfile/stringfile.h	(revision 294)
+++ /cpp/frams/virtfile/stringfile.h	(revision 295)
@@ -15,5 +15,5 @@
 	long pos;
 public:
-	StringFILE(SString& s) :str(s), pos(0) {}
+	StringFILE(SString& s): VirtFILE(""), str(s), pos(0) {}
 	size_t Vread(void *ptr, size_t size, size_t nmemb);
 	size_t Vwrite(const void *ptr, size_t size, size_t nmemb) { str.append((const char*)ptr, (int)(size*nmemb)); return size*nmemb; }
@@ -38,12 +38,9 @@
 };
 
-class StringFileSystem : public VirtFileSystem
+class StringFileSystem : public ChainFileSystem
 {
 public:
-	VirtFileSystem *chain;
-	StringFileSystem(VirtFileSystem *_chain = NULL) :chain(_chain) {}
+	StringFileSystem(VirtFileSystem *_chain = NULL):ChainFileSystem(_chain) {}
 	VirtFILE *Vfopen(const char* path, const char*mode);
-	int Vfexists(const char* path);
-	VirtDIR *Vopendir(const char* path);
 	static const char PREFIX[];
 	static bool isStringPath(const char* path);
Index: /cpp/frams/virtfile/virtfile.cpp
===================================================================
--- /cpp/frams/virtfile/virtfile.cpp	(revision 294)
+++ /cpp/frams/virtfile/virtfile.cpp	(revision 295)
@@ -22,7 +22,22 @@
 }
 
-int Vfexists(const char* path)
+bool Vfexists(const char* path)
 {
-return VirtFILE::vfs ? VirtFILE::vfs->Vfexists(path) : 0;
+return VirtFILE::vfs ? VirtFILE::vfs->Vfexists(path) : false;
+}
+
+bool Vdirexists(const char* path,bool is_writable)
+{
+return VirtFILE::vfs ? VirtFILE::vfs->Vdirexists(path,is_writable) : false;
+}
+
+bool Vmkdir(const char* path)
+{
+return VirtFILE::vfs ? VirtFILE::vfs->Vmkdir(path) : false;
+}
+
+bool Vmkdirs(const char* path)
+{
+return VirtFILE::vfs ? VirtFILE::vfs->Vmkdirs(path) : false;
 }
 
@@ -65,6 +80,8 @@
 
 VirtFILE* VirtFileSystem::Vfopen(const char* path,const char*mode) {return 0;}
-int VirtFileSystem::Vfexists(const char* path) {return 0;}
+bool VirtFileSystem::Vfexists(const char* path) {return 0;}
 VirtDIR* VirtFileSystem::Vopendir(const char* path) {return 0;}
+bool VirtFileSystem::Vmkdir(const char* path) {return false;} //error - not supported
+bool VirtFileSystem::Vdirexists(const char* path,bool is_writable) {return false;}
 
 //////////////////////////////////////////////////////////////////////////
@@ -117,2 +134,43 @@
 dirent* readdir(VirtDIR* d) {return d->Vreaddir();}
 
+/////////
+
+bool VirtFileSystem::Vmkdirs(const char* path)
+{
+if (Vdirexists(path,true)) return true;
+string parentdir = getFileDir(path);
+if (!Vmkdirs(parentdir.c_str())) return false;
+return Vmkdir(path);
+}
+
+//////////
+
+VirtFILE *ChainFileSystem::Vfopen(const char* path, const char*mode)
+{
+	return (chain != NULL) ? chain->Vfopen(path, mode) : NULL;
+}
+
+bool ChainFileSystem::Vfexists(const char* path)
+{
+	return (chain != NULL) ? chain->Vfexists(path) : false;
+}
+
+VirtDIR *ChainFileSystem::Vopendir(const char* path)
+{
+	return (chain != NULL) ? chain->Vopendir(path) : NULL;
+}
+
+bool ChainFileSystem::Vmkdir(const char* path)
+{
+	return (chain != NULL) ? chain->Vmkdir(path) : false;
+}
+
+bool ChainFileSystem::Vmkdirs(const char* path)
+{
+	return (chain != NULL) ? chain->Vmkdirs(path) : false;
+}
+
+bool ChainFileSystem::Vdirexists(const char* path,bool is_writable)
+{
+	return (chain != NULL) ? chain->Vdirexists(path,is_writable) : false;
+}
Index: /cpp/frams/virtfile/virtfile.h
===================================================================
--- /cpp/frams/virtfile/virtfile.h	(revision 294)
+++ /cpp/frams/virtfile/virtfile.h	(revision 295)
@@ -9,4 +9,6 @@
 #include <stdarg.h>
 #include <common/nonstd_dir.h>
+#include <string>
+using std::string;
 //#include <dirent.h> //to jest inkludowane przez powyzsze 
 //struct dirent; //kiedys byla ta linia jak nie bylo jeszcze implementacji windowsowej dirent, ale borlandowi sie nie podoba jak s¹ obie
@@ -22,4 +24,6 @@
 class DLLEXP VirtFILE
 {
+  protected:
+string path;
   public:
 virtual size_t Vread(void *ptr, size_t size, size_t nmemb)=0;
@@ -36,6 +40,7 @@
 virtual int Vprintf(const char *format, va_list args);
 int printf(const char *format, ...);
-virtual const char *VgetPath() {return 0;} // 0=unspecified path
+virtual const char *VgetPath() {return path.c_str();}
 virtual int getSize();
+VirtFILE(const char* _path):path(_path) {}
 virtual ~VirtFILE();
 static VirtFILE *Vstdin,*Vstdout,*Vstderr;
@@ -48,4 +53,28 @@
 static VirtFileSystem *vfs;
 static void selectFileSystem(VirtFileSystem *s);
+};
+
+/** can be used directly or as a base class for implementations delegating VirtFILE calls to another VirtFILE object */
+class DLLEXP DelegatedFILE: public VirtFILE
+{
+VirtFILE *delegate;
+  public:
+size_t Vread(void *ptr, size_t size, size_t nmemb) {return delegate->Vread(ptr,size,nmemb);}
+size_t Vwrite(const void *ptr, size_t size, size_t nmemb) {return delegate->Vwrite(ptr,size,nmemb);}
+int Veof() {return delegate->Veof();}
+int Vputc(int c) {return delegate->Vputc(c);}
+int Vputs(const char *s) {return delegate->Vputs(s);}
+int Vgetc() {return delegate->Vgetc();}
+int Vseek(long offset, int whence) {return delegate->Vseek(offset,whence);}
+long Vtell() {return delegate->Vtell();}
+void Vrewind() {delegate->Vrewind();}
+int Vflush() {return delegate->Vflush();}
+char *Vgets(char *s, int size) {return delegate->Vgets(s,size);}
+int Vprintf(const char *format, va_list args) {return delegate->Vprintf(format,args);}
+int getSize() {return delegate->getSize();}
+// not overriden: VgetPath()
+
+DelegatedFILE(const char* _path,VirtFILE *_delegate):VirtFILE(_path),delegate(_delegate) {}
+virtual ~DelegatedFILE() {if (delegate) delete delegate; delegate=NULL;}
 };
 
@@ -61,11 +90,32 @@
 public:
 virtual VirtFILE *Vfopen(const char* path,const char*mode);
-virtual int Vfexists(const char* path);
+virtual bool Vfexists(const char* path);
 virtual VirtDIR *Vopendir(const char* path);
+virtual bool Vmkdir(const char* path);
+virtual bool Vmkdirs(const char* path);
+virtual bool Vdirexists(const char* path,bool is_writable);
 };
+
+/// base class for chained filesystems - redirect unimplemented calls -> chain
+class DLLEXP ChainFileSystem : public VirtFileSystem
+{
+public:
+	VirtFileSystem *chain;
+	ChainFileSystem(VirtFileSystem *_chain = NULL) :chain(_chain) {}
+	VirtFILE *Vfopen(const char* path, const char*mode);
+	bool Vfexists(const char* path);
+	VirtDIR *Vopendir(const char* path);
+	bool Vmkdir(const char* path);
+	bool Vmkdirs(const char* path);
+	bool Vdirexists(const char* path,bool is_writable);
+};
+
 
 DLLEXP VirtFILE *Vfopen(const char* path,const char*mode);
 DLLEXP VirtDIR *Vopendir(const char* path);
-DLLEXP int Vfexists(const char* path);
+DLLEXP bool Vfexists(const char* path);
+DLLEXP bool Vmkdir(const char* path);
+DLLEXP bool Vmkdirs(const char* path);
+DLLEXP bool Vdirexists(const char* path,bool is_writable);
 
 DLLEXP int fread(void *ptr, size_t size, size_t nmemb, VirtFILE* f);
