void VHTTPServerProject::_AddVirtualFoldersFromSettings (VVirtualHost *ioVirtualHost)
{
	if (fSettings->GetUseWALibVirtualFolder())
	{
		XBOX::VRefPtr<VFolder>	wakandaServerFolder;
#if VERSIONWIN
		wakandaServerFolder.Adopt (XBOX::VProcess::Get()->RetainFolder (XBOX::VProcess::eFS_Executable));
#else
		XBOX::VFilePath path (VProcess::Get()->GetExecutableFolderPath());

#if VERSION_LINUX
		//jmo - Check that : It should break on Mac !
		XBOX::VFolder *folder = new VFolder (path);
#else
		XBOX::VFolder *folder = new VFolder (path.ToParent());
#endif
		wakandaServerFolder.Adopt (folder);
#endif

		if (NULL != wakandaServerFolder)
		{
			XBOX::VString	indexFileName;
			XBOX::VString	keyword (CVSTR ("walib"));
			XBOX::VFilePath	waLibPath (wakandaServerFolder->GetPath());
			VVirtualFolder *virtualFolder = NULL;

			waLibPath.ToSubFolder (keyword);
			virtualFolder = fHTTPServer->RetainVirtualFolder (waLibPath.GetPath(), indexFileName, keyword);
			if (NULL != virtualFolder)
				ioVirtualHost->AddVirtualFolder (virtualFolder);

			XBOX::ReleaseRefCountable (&virtualFolder);

			// Temp for WAK3 - Support "webComponents" VirtualFolder
			// TODO: Use .waResources settings later
			XBOX::VFilePath	webComponentsPath (wakandaServerFolder->GetPath());
			webComponentsPath.ToSubFolder (CVSTR ("resources")).ToSubFolder (CVSTR ("Web Components"));
			virtualFolder = fHTTPServer->RetainVirtualFolder (webComponentsPath.GetPath(), indexFileName, CVSTR ("webComponents"));
			if (NULL != virtualFolder)
				ioVirtualHost->AddVirtualFolder (virtualFolder);

			XBOX::ReleaseRefCountable (&virtualFolder);
		}

		// Load Virtual Folders from settings
		const VVirtualFolderSettingsVector&	virtualFolderSettings = fSettings->GetVirtualFoldersVector();
		for (VVirtualFolderSettingsVector::const_iterator it = virtualFolderSettings.begin(); it != virtualFolderSettings.end(); ++it)
		{
			VVirtualFolder *virtualFolder = fHTTPServer->RetainVirtualFolder ((*it)->GetLocation(), (*it)->GetIndex(), (*it)->GetName());
			if (NULL != virtualFolder)
				ioVirtualHost->AddVirtualFolder (virtualFolder);

			XBOX::ReleaseRefCountable (&virtualFolder);
		}
	}
}
static
void BuildFolderPath (const XBOX::VFilePath& inBaseFolder, const XBOX::VString& inPath, XBOX::VFilePath& outPath)
{
	if (inPath.IsEmpty())
	{
		outPath.FromFilePath (inBaseFolder);
	}
	else
	{
		XBOX::VString	pathString (inPath);
		
		if ((pathString[0] == CHAR_SOLIDUS) // POSIX Path ?
#if VERSIONWIN
			|| ((pathString.GetLength() > 2) && (pathString[1] == CHAR_COLON) && (pathString[2] == CHAR_SOLIDUS)) // POSIX path like c:/blahblah/
#endif
		)
		{
			if (!pathString.IsEmpty() && (pathString[pathString.GetLength()-1] != CHAR_SOLIDUS))
				pathString.AppendUniChar (CHAR_SOLIDUS);
			
			outPath.FromFullPath (pathString, XBOX::FPS_POSIX);
		}
		else if ((pathString[0] != CHAR_FULL_STOP) && (pathString.FindUniChar (XBOX::FOLDER_SEPARATOR) > 0))
		{
			if (!pathString.IsEmpty() && (pathString[pathString.GetLength()-1] != XBOX::FOLDER_SEPARATOR))
				pathString.AppendUniChar (XBOX::FOLDER_SEPARATOR);
			
			outPath.FromFullPath (pathString, XBOX::FPS_SYSTEM);
		}
		else
		{
			XBOX::VFilePath baseFolder (inBaseFolder);
			
			if ((pathString[0] == CHAR_FULL_STOP) && (pathString[1] == CHAR_SOLIDUS))
				pathString.Remove (1, 2);
			
			while ((pathString[0] == CHAR_FULL_STOP) && (pathString[1] == CHAR_FULL_STOP) && (pathString[2] == CHAR_SOLIDUS))
			{
				pathString.Remove (1, 3);
				baseFolder = baseFolder.ToParent();
			}
			
			pathString.ExchangeAll (CHAR_SOLIDUS, XBOX::FOLDER_SEPARATOR);
			
			if (!pathString.IsEmpty() && (pathString[pathString.GetLength()-1] != XBOX::FOLDER_SEPARATOR))
				pathString.AppendUniChar (XBOX::FOLDER_SEPARATOR);
			
			outPath.FromRelativePath (baseFolder, pathString);
		}
	}
}
XBOX::VError VHTTPServerLog::_RotateFile()
{
	XBOX::VError	error = XBOX::VE_OK;
	XBOX::VFilePath	logFilePath;
	XBOX::VTime		curTime;

	curTime.FromSystemTime();

	_GetLogFilePath (logFilePath);

	if (fLogFileAccessLock.Lock())
	{
		if (NULL == fLogFile)
			fLogFile = new XBOX::VFile (logFilePath);

		if (fLogFile->Exists())
		{
			// the backup fileName will look like "HTTPServer_DAAAAMMJJT00000000.waLog" => "HTTPServer_D20100122T113307.waLog"
			// I used this format to have the files sorted by time thanks to their name

			XBOX::VString	newFileName;
			XBOX::VString	dateTimeString;

			GetFormatedDateTimeString (curTime, dateTimeString);

			fLogFile->GetNameWithoutExtension (newFileName);
			newFileName.AppendUniChar (CHAR_LOW_LINE);
			newFileName.AppendString (dateTimeString);
			newFileName.AppendUniChar (CHAR_FULL_STOP);
			newFileName.AppendString (fSettings.GetLogFileNameExtension());

			if (fSettings.GetArchivesFolderName().IsEmpty())
			{
				error = fLogFile->Rename (newFileName);
			}
			else
			{
				XBOX::VFilePath	destinationFilePath;

				fLogFile->GetPath (destinationFilePath);
				destinationFilePath.ToParent().ToSubFolder (fSettings.GetArchivesFolderName());

				if (destinationFilePath.IsFolder())
				{
					XBOX::VFolder *	destinationFolder = new XBOX::VFolder (destinationFilePath);
					if (NULL != destinationFolder)
					{
						if (!destinationFolder->Exists())
							error = destinationFolder->CreateRecursive();
						XBOX::ReleaseRefCountable (&destinationFolder);

						if (XBOX::VE_OK == error)
						{
							destinationFilePath.SetFileName (newFileName);

							error = fLogFile->Move (destinationFilePath, NULL, XBOX::FCP_Overwrite);
						}
					}
					else
					{
						error = XBOX::VE_MEMORY_FULL;
					}
				}
			}

			XBOX::ReleaseRefCountable (&fLogFile);
		}

		//Creating the log file
		if ((XBOX::VE_OK == error) && (NULL == fLogFile))
		{
			fLogFile = new XBOX::VFile (logFilePath);
			if (NULL != fLogFile)
			{
				error = fLogFile->Create();

				// Set correct dates & times (used later to determine the next backup time)
				if (XBOX::VE_OK == error)
					error = fLogFile->SetTimeAttributes (&curTime, &curTime, &curTime);
				fLogFileSize = 0;
				
				fLastFileRotationTime.FromTime (curTime);
				_CalculateNextFileRotationTime();
			}
			else
			{
				error = VE_CANNOT_CREATE_LOG_FILE;
			}
		}
		else
		{
			error = VE_CANNOT_OPEN_LOG_FILE;
		}

		fNeedSplit = false;
		fLogFileAccessLock.Unlock();
	}

	return error;
}
XBOX::VError VVirtualFolder::GetFilePathFromURL (const XBOX::VString& inURL, XBOX::VString& outLocationPath)
{
	if (!fLocalFolder)
	{
		XBOX::VString URL (inURL);
		sLONG pos = HTTPServerTools::FindASCIIVString (URL, fName);

		if (pos > 0)
			URL.Remove (1, pos + fName.GetLength() - 1);

		if ((URL.GetLength() == 1) && (URL.GetUniChar (1) == CHAR_SOLIDUS) && (!fIndexFileName.IsEmpty()))
			URL.AppendString (fIndexFileName);
		
		outLocationPath.FromString (fLocationPath);
		if (outLocationPath.GetUniChar (outLocationPath.GetLength()) == CHAR_SOLIDUS)
			outLocationPath.Truncate (outLocationPath.GetLength() - 1);
		outLocationPath.AppendString (URL);

		return VE_HTTP_PROTOCOL_FOUND;
	}

	XBOX::VError	error = XBOX::VE_FILE_NOT_FOUND;
	XBOX::VFilePath	path (fFolder->GetPath());
	XBOX::VString	pathString (inURL);
	XBOX::VString	folder;
	XBOX::VString	docName;

	if ((pathString.GetLength() == 1) && (pathString.GetUniChar (1) == CHAR_SOLIDUS))
	{
		docName.FromString (fIndexFileName);
	}
	else
	{
		bool	notDone = true;
		sLONG	folderLen = 0;
		sLONG	pos = 0;
		sLONG	curPos = 0;

		// YT 16-Nov-2011 - ACI0073914
		if (pathString.FindUniChar (CHAR_COLON) > 0) // ':'
			pathString.ExchangeAll (CHAR_COLON, CHAR_SOLIDUS);

		if (pathString.FindUniChar (CHAR_REVERSE_SOLIDUS) > 0) // '\'
			pathString.ExchangeAll (CHAR_REVERSE_SOLIDUS, CHAR_SOLIDUS);

		while (notDone)
		{
			if ((pos = pathString.FindUniChar (CHAR_SOLIDUS, curPos + 1)) > 0)	// '/'
			{
				HTTPServerTools::GetSubString (pathString, curPos, pos - 2, folder);
				folderLen = folder.GetLength();
				if (folderLen > 0)
				{
					/* If URL first folder equals Virtual Folder Name or Project Pattern... Do nothing... */
					if ((curPos == 1) && !fName.IsEmpty() && HTTPServerTools::EqualASCIIVString (fName, folder))
						;
					/* YT 24-Feb-2011 - ACI0069901 - Project Pattern is already removed from URL in VHTTPResponse::_UpdateRequestURL()
					else if ((curPos == 1) && !fProjectPattern.IsEmpty() && HTTPServerTools::EqualASCIIVString (fProjectPattern, folder))
					{
						pathString.SubString (curPos + fProjectPattern.GetLength() + 1, pathString.GetLength() - fProjectPattern.GetLength() + 1); // YT 24-Nov-2010 - ACI0068942 - Remove Project Pattern from URL...
						folderLen = 0;
						curPos = -1;
					}
					*/
					else if ((folderLen == 2) && (folder[0] == CHAR_FULL_STOP) && (folder[1] == CHAR_FULL_STOP)) // ".."
						path = path.ToParent();
					else if  ((folderLen == 1) && (folder[0] == CHAR_FULL_STOP)) // "."
						;	// unchanged
					else
						path = path.ToSubFolder (folder);

					curPos += (folderLen + 1);
				}
				else
					curPos += 1;
			}
			else
				notDone = false;

			if (curPos >= pathString.GetLength())
				break;
		}
		
		if (curPos < pathString.GetLength())
			HTTPServerTools::GetSubString (pathString, curPos, pathString.GetLength() - 1, docName);
	}

	/* if URL does not include a filename, try using the index file name set in prefs */
	if (docName.IsEmpty())
		docName.FromString (fIndexFileName);

	path = path.ToSubFile (docName);

	/*
		at this stage path should contain a full path pointing to the wanted file
		check that this is inside the web folder (if it's a web connection)
	*/
	// SECURITY CHECK - change it with great care
	if (path.GetPath().BeginsWith (fFolder->GetPath().GetPath()))
	{
		outLocationPath.FromString (path.GetPath());
		error = VE_OK;
	}
	else
	{
		// UNDER ATTACK !!!
		path.Clear();
		error = VE_HTTP_PROTOCOL_FORBIDDEN;
	}

	return error;
}