Пример #1
0
const wchar_t *PointToNameUNC(const wchar_t *lpwszPath)
{
	if (!lpwszPath)
		return nullptr;

	if (IsSlash(lpwszPath[0]) && IsSlash(lpwszPath[1]))
	{
		lpwszPath+=2;

		for (int i=0; i<2; i++)
		{
			while (*lpwszPath && !IsSlash(*lpwszPath))
				lpwszPath++;

			if (*lpwszPath)
				lpwszPath++;
		}
	}

	const wchar_t *lpwszNamePtr = lpwszPath;

	while (*lpwszPath)
	{
		if (IsSlash(*lpwszPath) || (*lpwszPath==L':' && lpwszPath == lpwszNamePtr+1))
			lpwszNamePtr = lpwszPath+1;

		lpwszPath++;
	}

	return lpwszNamePtr;
}
Пример #2
0
string &CutToNameUNC(string &strPath)
{
	wchar_t *lpwszPath = strPath.GetBuffer();

	if (IsSlash(lpwszPath[0]) && IsSlash(lpwszPath[1]))
	{
		lpwszPath+=2;

		for (int i=0; i<2; i++)
		{
			while (*lpwszPath && !IsSlash(*lpwszPath))
				lpwszPath++;

			if (*lpwszPath)
				lpwszPath++;
		}
	}

	wchar_t *lpwszNamePtr = lpwszPath;

	while (*lpwszPath)
	{
		if (IsSlash(*lpwszPath) || (*lpwszPath==L':' && lpwszPath == lpwszNamePtr+1))
			lpwszNamePtr = lpwszPath+1;

		lpwszPath++;
	}

	*lpwszNamePtr = 0;
	strPath.ReleaseBuffer();

	return strPath;
}
Пример #3
0
const wchar_t* PointToExt(const wchar_t *lpwszPath,const wchar_t *lpwszEndPtr)
{
	if (!lpwszPath || !lpwszEndPtr)
		return nullptr;

	const wchar_t *lpwszExtPtr = lpwszEndPtr;

	while (lpwszExtPtr != lpwszPath)
	{
		if (*lpwszExtPtr==L'.')
		{
			if (IsSlash(*(lpwszExtPtr-1)) || *(lpwszExtPtr-1)==L':')
				return lpwszEndPtr;
			else
				return lpwszExtPtr;
		}

		if (IsSlash(*lpwszExtPtr) || *lpwszExtPtr==L':')
			return lpwszEndPtr;

		lpwszExtPtr--;
	}

	return lpwszEndPtr;
}
Пример #4
0
const wchar_t* PointToName(const wchar_t *lpwszPath,const wchar_t *lpwszEndPtr)
{
	if (!lpwszPath)
		return nullptr;

	if (*lpwszPath && *(lpwszPath+1)==L':') lpwszPath+=2;

	const wchar_t *lpwszNamePtr = lpwszEndPtr;

	if (!lpwszNamePtr)
	{
		lpwszNamePtr=lpwszPath;

		while (*lpwszNamePtr) lpwszNamePtr++;
	}

	while (lpwszNamePtr != lpwszPath)
	{
		if (IsSlash(*lpwszNamePtr))
			return lpwszNamePtr+1;

		lpwszNamePtr--;
	}

	if (IsSlash(*lpwszPath))
		return lpwszPath+1;
	else
		return lpwszPath;
}
Пример #5
0
void DeleteDirTree(const wchar_t *Dir)
{
	if (!*Dir ||
	        (IsSlash(Dir[0]) && !Dir[1]) ||
	        (Dir[1]==L':' && IsSlash(Dir[2]) && !Dir[3]))
		return;

	string strFullName;
	FAR_FIND_DATA_EX FindData;
	ScanTree ScTree(TRUE,TRUE,FALSE);
	ScTree.SetFindPath(Dir,L"*",0);

	while (ScTree.GetNextName(&FindData, strFullName))
	{
		apiSetFileAttributes(strFullName,FILE_ATTRIBUTE_NORMAL);

		if (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
		{
			if (ScTree.IsDirSearchDone())
				apiRemoveDirectory(strFullName);
		}
		else
			apiDeleteFile(strFullName);
	}

	apiSetFileAttributes(Dir,FILE_ATTRIBUTE_NORMAL);
	apiRemoveDirectory(Dir);
}
Пример #6
0
void FileList::GetDeltaToCurrent(FileList *input, FileList *output, const char *dirSubset, const char *remoteSubdir)
{
	// For all files in this list that do not match the input list, write them to the output list.
	// dirSubset allows checking only a portion of the files in this list.
	unsigned thisIndex, inputIndex;
	unsigned dirSubsetLen, localPathLen, remoteSubdirLen;
	bool match;
	if (dirSubset)
		dirSubsetLen = (unsigned int) strlen(dirSubset);
	else
		dirSubsetLen = 0;
	if (remoteSubdir && remoteSubdir[0]) {
		remoteSubdirLen = (unsigned int) strlen(remoteSubdir);
		if (IsSlash(remoteSubdir[remoteSubdirLen - 1]))
			remoteSubdirLen--;
	} else
		remoteSubdirLen = 0;
	for (thisIndex = 0; thisIndex < fileList.Size(); thisIndex++) {
		localPathLen = (unsigned int) fileList[thisIndex].filename.GetLength();
		while (localPathLen > 0) {
			if (IsSlash(fileList[thisIndex].filename[localPathLen - 1])) {
				localPathLen--;
				break;
			}
			localPathLen--;
		}
		// fileList[thisIndex].filename has to match dirSubset and be shorter or equal to it in length.
		if (dirSubsetLen > 0 &&
		    (localPathLen < dirSubsetLen ||
		     _strnicmp(fileList[thisIndex].filename.C_String(), dirSubset, dirSubsetLen) != 0 ||
		     (localPathLen > dirSubsetLen && IsSlash(fileList[thisIndex].filename[dirSubsetLen]) == false)))
			continue;
		match = false;
		for (inputIndex = 0; inputIndex < input->fileList.Size(); inputIndex++) {
			// If the filenames, hashes, and lengths match then skip this element in fileList.  Otherwise write it to output
			if (_stricmp(input->fileList[inputIndex].filename.C_String() + remoteSubdirLen, fileList[thisIndex].filename.C_String() + dirSubsetLen) == 0) {
				match = true;
				if (input->fileList[inputIndex].fileLengthBytes == fileList[thisIndex].fileLengthBytes &&
				    input->fileList[inputIndex].dataLengthBytes == fileList[thisIndex].dataLengthBytes &&
				    memcmp(input->fileList[inputIndex].data, fileList[thisIndex].data, (size_t) fileList[thisIndex].dataLengthBytes) == 0) {
					// File exists on both machines and is the same.
					break;
				} else {
					// File exists on both machines and is not the same.
					output->AddFile(fileList[thisIndex].filename, fileList[thisIndex].fullPathToFile, 0, 0, fileList[thisIndex].fileLengthBytes, FileListNodeContext(0, 0), false);
					break;
				}
			}
		}
		if (match == false) {
			// Other system does not have the file at all
			output->AddFile(fileList[thisIndex].filename, fileList[thisIndex].fullPathToFile, 0, 0, fileList[thisIndex].fileLengthBytes, FileListNodeContext(0, 0), false);
		}
	}
}
Пример #7
0
const wchar_t *LastSlash(const wchar_t *String)
{
	const wchar_t *Start = String;

	while (*String++)
		;

	while (--String!=Start && !IsSlash(*String))
		;

	return IsSlash(*String)?String:nullptr;
}
Пример #8
0
const wchar_t *FirstSlash(const wchar_t *String)
{
	do
	{
		if (IsSlash(*String))
			return String;
	}
	while (*String++);

	return nullptr;
}
Пример #9
0
bool IsRootPath(const string &Path)
{
	size_t PathRootLen = GetPathRootLength(Path);

	if (Path.GetLength() == PathRootLen)
		return true;

	if (Path.GetLength() == PathRootLen + 1 && IsSlash(Path[Path.GetLength() - 1]))
		return true;

	return false;
}
Пример #10
0
bool FindSlash(size_t &Pos, const string &Str, size_t StartPos)
{
	for (size_t p = StartPos; p < Str.GetLength(); p++)
	{
		if (IsSlash(Str[p]))
		{
			Pos = p;
			return true;
		}
	}

	return false;
}
Пример #11
0
bool FindLastSlash(size_t &Pos, const string &Str)
{
	for (size_t p = Str.GetLength(); p > 0; p--)
	{
		if (IsSlash(Str[p - 1]))
		{
			Pos = p - 1;
			return true;
		}
	}

	return false;
}
Пример #12
0
bool DeleteEndSlash(wchar_t *Path, bool AllEndSlash)
{
	bool Ret = false;
	size_t len = StrLength(Path);

	while (len && IsSlash(Path[--len]))
	{
		Ret = true;
		Path[len] = L'\0';

		if (!AllEndSlash)
			break;
	}

	return Ret;
}
Пример #13
0
wchar_t* WINAPI TruncPathStr(wchar_t *Str, int MaxLength)
{
	assert(MaxLength >= 0);

	MaxLength=Max(0, MaxLength);

	if (Str)
	{
		int nLength = (int)wcslen(Str);

		if ((MaxLength > 0) && (nLength > MaxLength) && (nLength >= 2))
		{
			wchar_t *lpStart = nullptr;

			if (*Str && (Str[1] == L':') && IsSlash(Str[2]))
				lpStart = Str+3;
			else
			{
				if ((Str[0] == L'\\') && (Str[1] == L'\\'))
				{
					if ((lpStart = const_cast<wchar_t*>(FirstSlash(Str+2))) )
					{
						wchar_t *lpStart2=lpStart;

						if ((lpStart-Str < nLength) && ((lpStart=const_cast<wchar_t*>(FirstSlash(lpStart2+1)))))
							lpStart++;
					}
				}
			}

			if (!lpStart || (lpStart-Str > MaxLength-5))
				return TruncStr(Str, MaxLength);

			wchar_t *lpInPos = lpStart+3+(nLength-MaxLength);
			wmemmove(lpStart+3, lpInPos, (wcslen(lpInPos)+1));
			wmemcpy(lpStart, L"...", 3);
		}
	}

	return Str;
}
Пример #14
0
//   Аналог PointToName, только для строк типа
//   "name\" (оканчивается на слеш) возвращает указатель на name, а не на пустую
//   строку
const wchar_t* PointToFolderNameIfFolder(const wchar_t *Path)
{
	if (!Path)
		return nullptr;

	const wchar_t *NamePtr=Path, *prevNamePtr=Path;

	while (*Path)
	{
		if (IsSlash(*Path) ||
		        (*Path==L':' && Path==NamePtr+1))
		{
			prevNamePtr=NamePtr;
			NamePtr=Path+1;
		}

		++Path;
	}

	return ((*NamePtr)?NamePtr:prevNamePtr);
}
Пример #15
0
void CreatePath(const string &InputPath, bool Simple)
{
	string Path(InputPath);
	ConvertNameToFull(InputPath, Path);
	size_t DirOffset = 0;
	ParsePath(Path, &DirOffset);
	string Part;
	Part.reserve(Path.size());
	for (size_t i = DirOffset; i <= Path.size(); ++i)
	{
		if (i == Path.size() || IsSlash(Path[i]))
		{
			Part = Path.substr(0, i);
			if (!api::fs::exists(Part))
			{
				if(api::CreateDirectory(Part, nullptr) && !Simple)
					TreeList::AddTreeName(Part);
			}
		}
	}
}
Пример #16
0
BOOL DeleteEndSlash(string &strPath, bool AllEndSlash)
{
	BOOL Ret=FALSE;

	if (!strPath.IsEmpty())
	{
		size_t len=strPath.GetLength();
		wchar_t *lpwszPath = strPath.GetBuffer();

		while (len && IsSlash(lpwszPath[--len]))
		{
			Ret=TRUE;
			lpwszPath[len] = L'\0';

			if (!AllEndSlash)
				break;
		}

		strPath.ReleaseBuffer();
	}

	return Ret;
}
Пример #17
0
string &CutToFolderNameIfFolder(string &strPath)
{
	wchar_t *lpwszPath = strPath.GetBuffer();
	wchar_t *lpwszNamePtr=lpwszPath, *lpwszprevNamePtr=lpwszPath;

	while (*lpwszPath)
	{
		if (IsSlash(*lpwszPath) || (*lpwszPath==L':' && lpwszPath==lpwszNamePtr+1))
		{
			lpwszprevNamePtr=lpwszNamePtr;
			lpwszNamePtr=lpwszPath+1;
		}

		++lpwszPath;
	}

	if (*lpwszNamePtr)
		*lpwszNamePtr=0;
	else
		*lpwszprevNamePtr=0;

	strPath.ReleaseBuffer();
	return strPath;
}
Пример #18
0
void ShellMakeDir(Panel *SrcPanel)
{
	string strDirName;
	string strOriginalDirName;
	wchar_t *lpwszDirName;
	UserDefinedList DirList(0,0,ULF_UNIQUE);
	DialogDataEx MkDirDlgData[]=
	{
		DI_DOUBLEBOX,3,1,72,8,0,0,MSG(MMakeFolderTitle),
		DI_TEXT,     5,2, 0,2,0,0,MSG(MCreateFolder),
		DI_EDIT,     5,3,70,3,(DWORD_PTR)L"NewFolder",DIF_FOCUS|DIF_EDITEXPAND|DIF_HISTORY|DIF_USELASTHISTORY|DIF_EDITPATH,L"",
		DI_TEXT,     0,4, 0,4,0,DIF_SEPARATOR,L"",
		DI_CHECKBOX, 5,5, 0,5,Opt.MultiMakeDir,0,MSG(MMultiMakeDir),
		DI_TEXT,     0,6, 0,6,0,DIF_SEPARATOR,L"",
		DI_BUTTON,   0,7, 0,7,0,DIF_DEFAULT|DIF_CENTERGROUP,MSG(MOk),
		DI_BUTTON,   0,7, 0,7,0,DIF_CENTERGROUP,MSG(MCancel),
	};
	MakeDialogItemsEx(MkDirDlgData,MkDirDlg);
	Dialog Dlg(MkDirDlg,ARRAYSIZE(MkDirDlg),MkDirDlgProc,reinterpret_cast<LONG_PTR>(&DirList));
	Dlg.SetPosition(-1,-1,76,10);
	Dlg.SetHelp(L"MakeFolder");
	Dlg.SetId(MakeFolderId);
	Dlg.Process();

	if (Dlg.GetExitCode()==MKDIR_OK)
	{
		strDirName=MkDirDlg[MKDIR_EDIT].strData;
		const wchar_t *OneDir;
		DirList.Reset();

		while (nullptr!=(OneDir=DirList.GetNext()))
		{
			strDirName = OneDir;
			strOriginalDirName = strDirName;

			//Unquote(DirName);
			if (Opt.CreateUppercaseFolders && !IsCaseMixed(strDirName))
				strDirName.Upper();

			DeleteEndSlash(strDirName,true);
			lpwszDirName = strDirName.GetBuffer();
			bool bSuccess = false;

			if(HasPathPrefix(lpwszDirName))
			{
				lpwszDirName += 4;
			}
			for (wchar_t *ChPtr=lpwszDirName; *ChPtr; ChPtr++)
			{
				if (IsSlash(*ChPtr))
				{
					WCHAR Ch = ChPtr[1];
					ChPtr[1] = 0;

					if (*lpwszDirName &&
						(apiGetFileAttributes(lpwszDirName) == INVALID_FILE_ATTRIBUTES) &&
						apiCreateDirectory(lpwszDirName,nullptr))
					{
						TreeList::AddTreeName(lpwszDirName);
						bSuccess = true;
					}

					ChPtr[1] = Ch;
				}
			}

			strDirName.ReleaseBuffer();
			BOOL bSuccess2;
			bool bSkip=false;

			while (!(bSuccess2=apiCreateDirectory(strDirName,nullptr)))
			{
				int LastError=GetLastError();

				if (LastError==ERROR_ALREADY_EXISTS || LastError==ERROR_BAD_PATHNAME ||
				        LastError==ERROR_INVALID_NAME || LastError == ERROR_DIRECTORY)
				{
					int ret;

					if (DirList.IsEmpty())
						ret=Message(MSG_WARNING|MSG_ERRORTYPE,1,MSG(MError),MSG(MCannotCreateFolder),strOriginalDirName,MSG(MCancel));
					else
						ret=Message(MSG_WARNING|MSG_ERRORTYPE,2,MSG(MError),MSG(MCannotCreateFolder),strOriginalDirName,MSG(MOk),MSG(MSkip));

					bSkip = ret==1;

					if (bSuccess || bSkip)
						break;
					else
						return;
				}
				else
				{
					int ret;

					if (DirList.IsEmpty())
					{
						ret=Message(MSG_WARNING|MSG_ERRORTYPE,2,MSG(MError),MSG(MCannotCreateFolder),strOriginalDirName,MSG(MRetry),MSG(MCancel));
					}
					else
					{
						ret=Message(MSG_WARNING|MSG_ERRORTYPE,3,MSG(MError),MSG(MCannotCreateFolder),strOriginalDirName,MSG(MRetry),MSG(MSkip),MSG(MCancel));
						bSkip = ret==1;
					}

					if (ret)
					{
						if (bSuccess || bSkip) break;
						else return;
					}
				}
			}

			if (bSuccess2)
				TreeList::AddTreeName(strDirName);
			else if (!bSkip)
				break;
		}

		SrcPanel->Update(UPDATE_KEEP_SELECTION);

		if (!strDirName.IsEmpty())
		{
			size_t pos;

			if (FindSlash(pos,strDirName))
				strDirName.SetLength(pos);

			if (!SrcPanel->GoToFile(strDirName) && strDirName.At(strDirName.GetLength()-1)==L'.')
			{
				strDirName.SetLength(strDirName.GetLength()-1);
				SrcPanel->GoToFile(strDirName);
			}
		}

		SrcPanel->Redraw();
		Panel *AnotherPanel=CtrlObject->Cp()->GetAnotherPanel(SrcPanel);
		int AnotherType=AnotherPanel->GetType();

		if (AnotherPanel->NeedUpdatePanel(SrcPanel) || AnotherType==QVIEW_PANEL)
		{
			AnotherPanel->Update(UPDATE_KEEP_SELECTION|UPDATE_SECONDARY);
			AnotherPanel->Redraw();
		}
	}
}
Пример #19
0
static void MixToFullPath(string& strPath)
{
	//Skip all path to root (with slash if exists)
	size_t DirOffset = 0;
	ParsePath(strPath, &DirOffset);

	//Process "." and ".." if exists
	for (size_t Pos = DirOffset; Pos < strPath.size();)
	{
		//fragment "."
		if (strPath[Pos] == L'.' && (!Pos || IsSlash(strPath[Pos - 1])))
		{
			//fragment "." at the end
			if(strPath.size() == Pos + 1)
			{
				strPath.resize(Pos);
				// don't change x:\ to x:
				if (strPath[Pos - 2] != L':')
				{
					strPath.pop_back();
				}
				continue;
			}

			switch (strPath[Pos + 1])
			{
					//fragment ".\"
				case L'\\':
					//fragment "./"
				case L'/':
					strPath.erase(Pos, 2);
					continue;

				//fragment "..\" or "../" or ".." at the end
				case L'.':
				{
					if (Pos + 2 == strPath.size() || IsSlash(strPath[Pos + 2]))
					{
						//Calculate subdir name offset
						size_t n = strPath.find_last_of(L"\\/", Pos-2);
						n = (n == string::npos || n < DirOffset) ? DirOffset : n+1;

						//fragment "..\" or "../"
						if (Pos + 2 < strPath.size())
						{
							strPath.erase(n, Pos + 3 - n);
						}
						//fragment ".." at the end
						else
						{
							strPath.resize(n);
						}

						Pos = n;
						continue;
					}
				}
				break;
			}
		}

		++Pos;
	}
}
Пример #20
0
// Косметические преобразования строки пути.
// CheckFullPath используется в FCTL_SET[ANOTHER]PANELDIR
void PrepareDiskPath(string &strPath, bool CheckFullPath)
{
	// elevation not required during cosmetic operation
	SCOPED_ACTION(elevation::suppress);

	if (!strPath.empty())
	{
		if (strPath.size() > 1 && (strPath[1]==L':' || (IsSlash(strPath[0]) && IsSlash(strPath[1]))))
		{
			ReplaceSlashToBackslash(strPath);
			bool DoubleSlash = strPath[1]==L'\\';
			while(ReplaceStrings(strPath, L"\\\\"sv, L"\\"sv))
				;
			if(DoubleSlash)
			{
				strPath = L'\\' + strPath;
			}

			if (CheckFullPath)
			{
				strPath = ConvertNameToFull(strPath);

				size_t DirOffset = 0;
				const auto Type = ParsePath(strPath, &DirOffset);
				if (Type == root_type::unknown && HasPathPrefix(strPath))
				{
					DirOffset = 4;
				}

				size_t StartPos = DirOffset;

				if (StartPos < strPath.size())
				{
					string TmpStr;
					TmpStr.reserve(strPath.size());
					size_t LastPos = StartPos;
					const auto EndsWithSlash = IsSlash(strPath.back());

					for (size_t i = StartPos; i <= strPath.size(); ++i)
					{
						if ((i < strPath.size() && IsSlash(strPath[i])) || (i == strPath.size() && !EndsWithSlash))
						{
							TmpStr.assign(strPath, 0, i);
							os::fs::find_data fd;

							if (os::fs::get_find_data(TmpStr, fd))
							{
								strPath.replace(LastPos, i - LastPos, fd.FileName);
								i += fd.FileName.size() - (i - LastPos);
							}

							if (i != strPath.size())
							{
								LastPos = i + 1;
							}
						}
					}
				}
			}

			if (ParsePath(strPath) == root_type::drive_letter)
			{
				strPath[0] = upper(strPath[0]);
			}
		}
	}
}
Пример #21
0
static void MixToFullPath(const string_view stPath, string& Dest, const string_view stCurrentDir)
{
		string strDest;
		string_view pstCurrentDir;
		bool blIgnore = false;
		size_t PathDirOffset = 0;
		const auto PathType = ParsePath(stPath, &PathDirOffset);
		size_t PathOffset = PathDirOffset;
		switch (PathType)
		{
			case root_type::unknown:
			{
				if (HasPathPrefix(stPath)) // \\?\<ANY_UNKNOWN_FORMAT>
				{
					blIgnore = true;
				}
				else if (!stPath.empty() && IsSlash(stPath.front())) //"\" or "\abc"
				{
					++PathOffset;
					if (!stCurrentDir.empty())
					{
						size_t CurDirDirOffset = 0;
						if (ParsePath(stCurrentDir, &CurDirDirOffset) != root_type::unknown)
						{
							assign(strDest, stCurrentDir.substr(0, CurDirDirOffset));
						}
					}
				}
				else //"abc" or whatever
				{
					pstCurrentDir = stCurrentDir;
				}
			}
			break;
			case root_type::drive_letter: //"C:" or "C:abc"
			{
				if(stPath.size() > 2 && IsSlash(stPath[2]))
				{
					PathOffset = 0;
				}
				else
				{
					const auto Drive = os::fs::get_drive(stPath[0]);
					const auto Value = os::env::get(L'=' + Drive);

					if (!Value.empty())
					{
						strDest = Value;
					}
					else
					{
						if (upper(stPath[0])==upper(stCurrentDir[0]))
						{
							assign(strDest, stCurrentDir);
						}
						else
						{
							strDest = Drive;
						}
					}
					AddEndSlash(strDest);
				}
			}
			break;
			case root_type::remote: //"\\abc"
			{
				PathOffset = 0;
			}
			break;
			case root_type::unc_drive_letter: //"\\?\whatever"
			case root_type::unc_remote:
			case root_type::volume:
			case root_type::pipe:
			{
				blIgnore=true;
				PathOffset = 0;
			}
			break;
		}

		if (!pstCurrentDir.empty())
		{
			append(strDest, pstCurrentDir);
			AddEndSlash(strDest);
		}

		append(strDest, stPath.substr(PathOffset));

		if (!blIgnore && !HasPathPrefix(strDest))
			MixToFullPath(strDest);

		Dest = std::move(strDest);
}
Пример #22
0
void ShellMakeDir(Panel *SrcPanel)
{
	FarList ComboList={sizeof(FarList)};
	FarListItem LinkTypeItems[3]={};
	ComboList.ItemsNumber=ARRAYSIZE(LinkTypeItems);
	ComboList.Items=LinkTypeItems;
	ComboList.Items[0].Text=MSG(MMakeFolderLinkNone);
	ComboList.Items[1].Text=MSG(MMakeFolderLinkJunction);
	ComboList.Items[2].Text=MSG(MMakeFolderLinkSymlink);
	ComboList.Items[0].Flags|=LIF_SELECTED;

	#if 1
	//Maximus: поддержка "узких" дисплеев
	if (ScrX < 10)
	{
		_ASSERTE(ScrX>=10);
		return;
	}
	int BorderW = (72<(ScrX-1))?72:(ScrX-1); // 72
	int ElemW = BorderW - 2; // 70
	#endif

	FarDialogItem MkDirDlgData[]=
	{
		#if 1
		//Maximus: поддержка "узких" дисплеев
		{DI_DOUBLEBOX,3,1,BorderW,10,0,nullptr,nullptr,0,MSG(MMakeFolderTitle)},
		#else
		{DI_DOUBLEBOX,3,1,72,10,0,nullptr,nullptr,0,MSG(MMakeFolderTitle)},
		#endif
		{DI_TEXT,     5,2, 0,2,0,nullptr,nullptr,0,MSG(MCreateFolder)},
		#if 1
		//Maximus: поддержка "узких" дисплеев
		{DI_EDIT,     5,3,ElemW,3,0,L"NewFolder",nullptr,DIF_FOCUS|DIF_EDITEXPAND|DIF_HISTORY|DIF_USELASTHISTORY|DIF_EDITPATH,L""},
		#else
		{DI_EDIT,     5,3,70,3,0,L"NewFolder",nullptr,DIF_FOCUS|DIF_EDITEXPAND|DIF_HISTORY|DIF_USELASTHISTORY|DIF_EDITPATH,L""},
		#endif
		{DI_TEXT,    -1,4, 0,4,0,nullptr,nullptr,DIF_SEPARATOR,L""},
		{DI_TEXT,     5,5, 0,5,0,nullptr,nullptr,0,MSG(MMakeFolderLinkType)},
		#if 1
		//Maximus: поддержка "узких" дисплеев
		{DI_COMBOBOX,20,5,ElemW,5,0,nullptr,nullptr,DIF_DROPDOWNLIST|DIF_LISTNOAMPERSAND|DIF_LISTWRAPMODE,L""},
		#else
		{DI_COMBOBOX,20,5,70,5,0,nullptr,nullptr,DIF_DROPDOWNLIST|DIF_LISTNOAMPERSAND|DIF_LISTWRAPMODE,L""},
		#endif
		{DI_TEXT,     5,6, 0,6,0,nullptr,nullptr,0,MSG(MMakeFolderLinkTarget)},
		#if 1
		//Maximus: поддержка "узких" дисплеев
		{DI_EDIT,    20,6,ElemW,6,0,L"NewFolderLinkTarget",nullptr,DIF_DISABLE|DIF_EDITEXPAND|DIF_HISTORY|DIF_USELASTHISTORY|DIF_EDITPATH,L""},
		#else
		{DI_EDIT,    20,6,70,6,0,L"NewFolderLinkTarget",nullptr,DIF_DISABLE|DIF_EDITEXPAND|DIF_HISTORY|DIF_USELASTHISTORY|DIF_EDITPATH,L""},
		#endif
		{DI_CHECKBOX, 5,7, 0,7,Global->Opt->MultiMakeDir,nullptr,nullptr,0,MSG(MMultiMakeDir)},
		{DI_TEXT,    -1,8, 0,8,0,nullptr,nullptr,DIF_SEPARATOR,L""},
		{DI_BUTTON,   0,9, 0,9,0,nullptr,nullptr,DIF_DEFAULTBUTTON|DIF_CENTERGROUP,MSG(MOk)},
		{DI_BUTTON,   0,9, 0,9,0,nullptr,nullptr,DIF_CENTERGROUP,MSG(MCancel)},
	};
	auto MkDirDlg = MakeDialogItemsEx(MkDirDlgData);
	MkDirDlg[MKDIR_COMBOBOX_LINKTYPE].ListItems=&ComboList;
	std::vector<string> DirList;
	auto Dlg = Dialog::create(MkDirDlg, MkDirDlgProc, &DirList);
	#if 1
	//Maximus: поддержка "узких" дисплеев
	Dlg->SetPosition(-1,-1,BorderW+4,12);
	#else
	Dlg->SetPosition(-1,-1,76,12);
	#endif
	Dlg->SetHelp(L"MakeFolder");
	Dlg->SetId(MakeFolderId);
	Dlg->Process();

	if (Dlg->GetExitCode()==MKDIR_OK)
	{
		string strDirName=MkDirDlg[MKDIR_EDIT].strData;
		string strOriginalDirName;
		bool SkipAll = false;
		FOR(const auto& i, DirList)
		{
			// TODO: almost the same code in dirmix::CreatePath()

			strDirName = i;
			strOriginalDirName = strDirName;

			ConvertNameToFull(strDirName, strDirName);

			DeleteEndSlash(strDirName);
			bool bSuccess = false;

			size_t DirOffset = 0;
			ParsePath(strDirName, &DirOffset);
			string Part;
			Part.reserve(strDirName.size());

			for (size_t j = DirOffset; j <= strDirName.size(); ++j)
			{
				if (j == strDirName.size() || IsSlash(strDirName[j]))
				{
					Part = strDirName.substr(0, j);
					if (!os::fs::exists(Part) || j == strDirName.size()) // skip all intermediate dirs, but not last.
					{
						while(!(bSuccess=(os::CreateDirectory(Part, nullptr)!=FALSE)) && !SkipAll)
						{
							Global->CatchError();
							int Ret = OperationFailed(strOriginalDirName, MError, MSG(MCannotCreateFolder));
							if(Ret == 1) // skip
							{
								break;
							}
							else if(Ret == 2)
							{
								SkipAll = true;
								break;
							}
							else if (Ret < 0 || Ret == 3) // cancel
							{
								return;
							}
						}
						if(bSuccess)
						{
							TreeList::AddTreeName(Part);
						}
					}
				}
			}

			if (bSuccess)
			{
				if(MkDirDlg[MKDIR_COMBOBOX_LINKTYPE].ListPos)
				{
					string strTarget=MkDirDlg[MKDIR_EDIT_LINKPATH].strData;
					Unquote(strTarget);
					while(!CreateReparsePoint(strTarget, strDirName, MkDirDlg[MKDIR_COMBOBOX_LINKTYPE].ListPos==1?RP_JUNCTION:RP_SYMLINKDIR) && !SkipAll)
					{
						Global->CatchError();
						int Ret = OperationFailed(strDirName, MError, MSG(MCopyCannotCreateLink));
						if(Ret == 1) // skip
						{
							break;
						}
						else if(Ret == 2)
						{
							SkipAll = true;
							break;
						}
						else if (Ret < 0 || Ret == 3) // cancel
						{
							return;
						}
					}
				}
			}
		}
Пример #23
0
// Кусок для создания SymLink для каталогов.
int MkSymLink(const string& Target, const string& LinkName, ReparsePointTypes LinkType, bool Silent, bool HoldTarget)
{
	if (!Target.empty() && !LinkName.empty())
	{
		string strFullTarget;
		// выделим имя
		auto strSelOnlyName = Target;
		DeleteEndSlash(strSelOnlyName);
		const auto SlashPos = FindLastSlash(strSelOnlyName);

		const auto symlink = LinkType==RP_SYMLINK || LinkType==RP_SYMLINKFILE || LinkType==RP_SYMLINKDIR;

		if (Target[1] == L':' && (!Target[2] || (IsSlash(Target[2]) && !Target[3]))) // C: или C:/
		{
//      if(Flags&FCOPY_VOLMOUNT)
			{
				strFullTarget = Target;
				AddEndSlash(strFullTarget);
			}
			/*
			  Вот здесь - ну очень умное поведение!
			  Т.е. если в качестве SelName передали "C:", то в этом куске происходит
			  коррекция типа линка - с symlink`а на volmount
			*/
			LinkType=RP_VOLMOUNT;
		}
		else
			strFullTarget = ConvertNameToFull(Target);

		auto strFullLink = ConvertNameToFull(LinkName);

		if (IsSlash(strFullLink.back()))
		{
			if (LinkType != RP_VOLMOUNT)
			{
				const auto SelName = SlashPos != string::npos? string_view(strSelOnlyName).substr(SlashPos + 1) : string_view(strSelOnlyName);
				append(strFullLink, SelName);
			}
			else
			{
				append(strFullLink, L"Disk_"sv, Target.front());
			}
		}

		if (LinkType==RP_VOLMOUNT)
		{
			AddEndSlash(strFullTarget);
			AddEndSlash(strFullLink);
		}

			if (symlink)
			{
				// в этом случае создается путь, но не сам каталог
				string strPath=strFullLink;

				if (CutToSlash(strPath))
				{
					if (!os::fs::exists(strPath))
						CreatePath(strPath);
				}
			}
			else
			{
				bool CreateDir=true;

				if (LinkType==RP_EXACTCOPY)
				{
					// в этом случае создается или каталог, или пустой файл
					if (os::fs::is_file(strFullTarget))
						CreateDir=false;
				}

				if (CreateDir)
				{
					if (os::fs::create_directory(strFullLink))
						TreeList::AddTreeName(strFullLink);
					else
						CreatePath(strFullLink);
				}
				else
				{
					string strPath=strFullLink;

					if (CutToSlash(strPath))
					{
						if (!os::fs::exists(strPath))
							CreatePath(strPath);
						os::fs::file(strFullLink, 0, 0, nullptr, CREATE_NEW, os::fs::get_file_attributes(strFullTarget));
					}
				}

				if (!os::fs::exists(strFullLink))
				{
					if (!Silent)
					{
						const auto ErrorState = error_state::fetch();

						Message(MSG_WARNING, ErrorState,
							msg(lng::MError),
							{
								msg(lng::MCopyCannotCreateLink),
								strFullLink
							},
							{ lng::MOk });
					}

					return 0;
				}
			}

		if (LinkType!=RP_VOLMOUNT)
		{
			if (CreateReparsePoint(HoldTarget && symlink ? Target : strFullTarget, strFullLink, LinkType))
			{
				return 1;
			}
			else
			{
				if (!Silent)
				{
					const auto ErrorState = error_state::fetch();

					Message(MSG_WARNING, ErrorState,
						msg(lng::MError),
						{
							msg(lng::MCopyCannotCreateLink),
							strFullLink
						},
						{ lng::MOk });
				}

				return 0;
			}
		}
		else
		{
			if (CreateVolumeMountPoint(strFullTarget,strFullLink))
			{
				return 1;
			}
			else
			{
				if (!Silent)
				{
					const auto ErrorState = error_state::fetch();

					Message(MSG_WARNING, ErrorState,
						msg(lng::MError),
						{
							format(msg(lng::MCopyMountVolFailed), Target),
							format(msg(lng::MCopyMountVolFailed2), strFullLink)
						},
						{ lng::MOk });
				}

				return 0;
			}
		}
	}

	return 2;
}
Пример #24
0
// Кусок для создания SymLink для каталогов.
int MkSymLink(const wchar_t *SelName,const wchar_t *Dest,ReparsePointTypes LinkType,DWORD Flags)
{
	if (SelName && *SelName && Dest && *Dest)
	{
		string strSrcFullName, strDestFullName, strSelOnlyName;
		string strMsgBuf, strMsgBuf2;
		// выделим имя
		strSelOnlyName = SelName;
		DeleteEndSlash(strSelOnlyName);
		const wchar_t *PtrSelName=LastSlash(strSelOnlyName);

		if (!PtrSelName)
			PtrSelName=strSelOnlyName;
		else
			++PtrSelName;

		if (SelName[1] == L':' && (!SelName[2] || (IsSlash(SelName[2]) && !SelName[3]))) // C: или C:/
		{
//      if(Flags&FCOPY_VOLMOUNT)
			{
				strSrcFullName = SelName;
				AddEndSlash(strSrcFullName);
			}
			/*
			  Вот здесь - ну очень умное поведение!
			  Т.е. если в качестве SelName передали "C:", то в этом куске происходит
			  коррекция типа линка - с symlink`а на volmount
			*/
			LinkType=RP_VOLMOUNT;
		}
		else
			ConvertNameToFull(SelName,strSrcFullName);

		ConvertNameToFull(Dest,strDestFullName);

		if (IsSlash(strDestFullName.At(strDestFullName.GetLength()-1)))
		{
			if (LinkType!=RP_VOLMOUNT)
				strDestFullName += PtrSelName;
			else
			{
				const wchar_t Tmp[]={L'D',L'i',L's',L'k',L'_',*SelName,L'\0'};
				strDestFullName+=Tmp;
			}
		}

		if (LinkType==RP_VOLMOUNT)
		{
			AddEndSlash(strSrcFullName);
			AddEndSlash(strDestFullName);
		}

		DWORD JSAttr=apiGetFileAttributes(strDestFullName);

		if (JSAttr != INVALID_FILE_ATTRIBUTES) // Существует такой?
		{
			if ((JSAttr&FILE_ATTRIBUTE_DIRECTORY)!=FILE_ATTRIBUTE_DIRECTORY)
			{
				if (!(Flags&FCOPY_NOSHOWMSGLINK))
				{
					Message(MSG_WARNING,1,MSG(MError),
					        MSG(MCopyCannotCreateJunctionToFile),
					        strDestFullName,MSG(MOk));
				}

				return 0;
			}

			if (TestFolder(strDestFullName) == TSTFLD_NOTEMPTY) // а пустой?
			{
				// не пустой, ну что же, тогда пробуем сделать dest\srcname
				AddEndSlash(strDestFullName);

				if (LinkType==RP_VOLMOUNT)
				{
					string strTmpName;
					strTmpName.Format(MSG(MCopyMountName),*SelName);
					strDestFullName += strTmpName;
					AddEndSlash(strDestFullName);
				}
				else
					strDestFullName += PtrSelName;

				JSAttr=apiGetFileAttributes(strDestFullName);

				if (JSAttr != INVALID_FILE_ATTRIBUTES) // И такой тоже есть???
				{
					if (TestFolder(strDestFullName) == TSTFLD_NOTEMPTY) // а пустой?
					{
						if (!(Flags&FCOPY_NOSHOWMSGLINK))
						{
							if (LinkType==RP_VOLMOUNT)
							{
								strMsgBuf.Format(MSG(MCopyMountVolFailed), SelName);
								strMsgBuf2.Format(MSG(MCopyMountVolFailed2), strDestFullName.CPtr());
								Message(MSG_WARNING,1,MSG(MError),
								        strMsgBuf,
								        strMsgBuf2,
								        MSG(MCopyFolderNotEmpty),
								        MSG(MOk));
							}
							else
								Message(MSG_WARNING,1,MSG(MError),
								        MSG(MCopyCannotCreateLink),strDestFullName,
								        MSG(MCopyFolderNotEmpty),MSG(MOk));
						}

						return 0; // однозначно в морг
					}
				}
				else // создаем.
				{
					if (apiCreateDirectory(strDestFullName,nullptr))
						TreeList::AddTreeName(strDestFullName);
					else
						CreatePath(strDestFullName);
				}

				if (apiGetFileAttributes(strDestFullName) == INVALID_FILE_ATTRIBUTES) // так, все очень даже плохо.
				{
					if (!(Flags&FCOPY_NOSHOWMSGLINK))
					{
						Message(MSG_WARNING|MSG_ERRORTYPE,1,MSG(MError),
						        MSG(MCopyCannotCreateFolder),
						        strDestFullName,MSG(MOk));
					}

					return 0;
				}
			}
		}
		else
		{
			if (LinkType==RP_SYMLINK || LinkType==RP_SYMLINKFILE || LinkType==RP_SYMLINKDIR)
			{
				// в этом случае создается путь, но не сам каталог
				string strPath=strDestFullName;

				if (CutToSlash(strPath))
				{
					if (apiGetFileAttributes(strPath)==INVALID_FILE_ATTRIBUTES)
						CreatePath(strPath);
				}
			}
			else
			{
				bool CreateDir=true;

				if (LinkType==RP_EXACTCOPY)
				{
					// в этом случае создается или каталог, или пустой файл
					DWORD dwSrcAttr=apiGetFileAttributes(strSrcFullName);

					if (dwSrcAttr!=INVALID_FILE_ATTRIBUTES && !(dwSrcAttr&FILE_ATTRIBUTE_DIRECTORY))
						CreateDir=false;
				}

				if (CreateDir)
				{
					if (apiCreateDirectory(strDestFullName,nullptr))
						TreeList::AddTreeName(strDestFullName);
					else
						CreatePath(strDestFullName);
				}
				else
				{
					string strPath=strDestFullName;

					if (CutToSlash(strPath))
					{
						// создаём
						if (apiGetFileAttributes(strPath)==INVALID_FILE_ATTRIBUTES)
							CreatePath(strPath);

						File file;
						if(file.Open(strDestFullName, 0, 0, 0, CREATE_NEW, apiGetFileAttributes(strSrcFullName)))
						{
							file.Close();
						}
					}
				}

				if (apiGetFileAttributes(strDestFullName) == INVALID_FILE_ATTRIBUTES) // так. все очень даже плохо.
				{
					if (!(Flags&FCOPY_NOSHOWMSGLINK))
					{
						Message(MSG_WARNING|MSG_ERRORTYPE,1,MSG(MError),
						        MSG(MCopyCannotCreateLink),strDestFullName,MSG(MOk));
					}

					return 0;
				}
			}
		}

		if (LinkType!=RP_VOLMOUNT)
		{
			if (CreateReparsePoint(strSrcFullName,strDestFullName,LinkType))
			{
				return 1;
			}
			else
			{
				if (!(Flags&FCOPY_NOSHOWMSGLINK))
				{
					Message(MSG_WARNING|MSG_ERRORTYPE,1,MSG(MError),
					        MSG(MCopyCannotCreateLink),strDestFullName,MSG(MOk));
				}

				return 0;
			}
		}
		else
		{
			if (CreateVolumeMountPoint(strSrcFullName,strDestFullName))
			{
				return 1;
			}
			else
			{
				if (!(Flags&FCOPY_NOSHOWMSGLINK))
				{
					strMsgBuf.Format(MSG(MCopyMountVolFailed),SelName);
					strMsgBuf2.Format(MSG(MCopyMountVolFailed2),strDestFullName.CPtr());
					Message(MSG_WARNING|MSG_ERRORTYPE,1,MSG(MError),strMsgBuf,strMsgBuf2,MSG(MOk));
				}

				return 0;
			}
		}
	}

	return 2;
}
Пример #25
0
PATH_TYPE ParsePath(const wchar_t* path, const wchar_t** DirPtr, bool* Root)
{
	PATH_TYPE Result = PATH_UNKNOWN;

	static struct
	{
		PATH_TYPE Type;
		const wchar_t* REStr;
		RegExp re;
		bool Compiled;
	}
	PathTypes[] =
	{
		// x:<whatever>
		{PATH_DRIVELETTER, L"/(^.\\:)/"},
		// \\?\x: or \\?\x:\ or \\?\x:\<whatever>
		{PATH_DRIVELETTERUNC, L"/(^\\\\{2}[\\?\\.]\\\\.\\:)(?:[\\\\\\/]|$)/"},
		// \\server\share or \\server\share\ or \\server\share<whatever>
		{PATH_REMOTE, L"/(^\\\\{2}[^ \\\\\\/\\?\\.][^ \\\\\\/\\?]+?\\\\[^\\\\\\/]+?)(?:[\\\\\\/]|$)/"},
		// \\?\unc\server\share or \\?\unc\server\share\ or \\?\unc\server\share<whatever>
		{PATH_REMOTEUNC, L"/(^\\\\{2}[\\?\\.]\\\\unc\\\\[^ \\\\\\/]+?\\\\[^\\\\\\/]+?)(?:[\\\\\\/]|$)/"},
		// \\?\Volume{GUID} or \\?\Volume{GUID}\ or \\?\Volume{GUID}<whatever>
		{PATH_VOLUMEGUID, L"/(^\\\\{2}[\\?\\.]\\\\volume\\{[0-9A-Fa-f]{8}-(?:[0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}\\})(?:[\\\\\\/]|$)/"},
		// \\?\pipe\ or \\?\pipe
		{PATH_PIPE, L"/(^\\\\{2}[\\?\\.]\\\\pipe)(?:[\\\\\\/]|$)/"},
	};
	static bool REInit = false;
	if(!REInit)
	{
		for(size_t i = 0; i < ARRAYSIZE(PathTypes); ++i)
		{
			PathTypes[i].Compiled = PathTypes[i].re.Compile(PathTypes[i].REStr, OP_PERLSTYLE|OP_OPTIMIZE|OP_IGNORECASE) != 0;
			assert(PathTypes[i].Compiled);
		}
		REInit = true;
	}

	SMatch m[3];

	for(size_t i = 0; i < ARRAYSIZE(PathTypes); ++i)
	{
		if(PathTypes[i].Compiled)
		{
			int n = PathTypes[i].re.GetBracketsCount();
			if(PathTypes[i].re.Search(path, m, n))
			{
				if(DirPtr)
				{
					*DirPtr = path+m[1].end;
				}
				if(Root)
				{
					*Root = !path[m[1].end] || (IsSlash(path[m[1].end]) && !path[m[1].end+1]);
				}
				Result = PathTypes[i].Type;
				break;
			}
		}
	}

	return Result;
}
Пример #26
0
bool PathStartsWith(const string &Path, const string &Start)
{
	string PathPart(Start);
	DeleteEndSlash(PathPart, true);
	return Path.IsSubStrAt(0, PathPart) && (Path.GetLength() == PathPart.GetLength() || IsSlash(Path[PathPart.GetLength()]));
}
Пример #27
0
BOOL AddEndSlash(wchar_t *Path, wchar_t TypeSlash)
{
	BOOL Result=FALSE;

	if (Path)
	{
		/* $ 06.12.2000 IS
		  ! Теперь функция работает с обоими видами слешей, также происходит
		    изменение уже существующего конечного слеша на такой, который
		    встречается чаще.
		*/
		wchar_t *end;
		int Slash=0, BackSlash=0;

		if (!TypeSlash)
		{
			end=Path;

			while (*end)
			{
				Slash+=(*end==L'\\');
				BackSlash+=(*end==L'/');
				end++;
			}
		}
		else
		{
			end=Path+StrLength(Path);

			if (TypeSlash == L'\\')
				Slash=1;
			else
				BackSlash=1;
		}

		int Length=(int)(end-Path);
		char c=(Slash<BackSlash)?L'/':L'\\';
		Result=TRUE;

		if (!Length)
		{
			*end=c;
			end[1]=0;
		}
		else
		{
			end--;

			if (!IsSlash(*end))
			{
				end[1]=c;
				end[2]=0;
			}
			else
			{
				*end=c;
			}
		}
	}

	return Result;
}
Пример #28
0
bool IsAbsolutePath(const wchar_t *Path)
{
	PATH_TYPE Type = ParsePath(Path);
	return Type == PATH_DRIVELETTERUNC || Type == PATH_REMOTE || Type == PATH_REMOTEUNC || Type == PATH_VOLUMEGUID || (Type == PATH_DRIVELETTER && (IsSlash(Path[2]) || !Path[2]));
}
Пример #29
0
void ShellMakeDir(Panel *SrcPanel)
{
	FarList ComboList={sizeof(FarList)};
	FarListItem LinkTypeItems[3]={};
	ComboList.ItemsNumber=ARRAYSIZE(LinkTypeItems);
	ComboList.Items=LinkTypeItems;
	ComboList.Items[0].Text=MSG(MMakeFolderLinkNone);
	ComboList.Items[1].Text=MSG(MMakeFolderLinkJunction);
	ComboList.Items[2].Text=MSG(MMakeFolderLinkSymlink);
	ComboList.Items[0].Flags|=LIF_SELECTED;

	FarDialogItem MkDirDlgData[]=
	{
		{DI_DOUBLEBOX,3,1,72,10,0,nullptr,nullptr,0,MSG(MMakeFolderTitle)},
		{DI_TEXT,     5,2, 0,2,0,nullptr,nullptr,0,MSG(MCreateFolder)},
		{DI_EDIT,     5,3,70,3,0,L"NewFolder",nullptr,DIF_FOCUS|DIF_EDITEXPAND|DIF_HISTORY|DIF_USELASTHISTORY|DIF_EDITPATH,L""},
		{DI_TEXT,     0,4, 0,4,0,nullptr,nullptr,DIF_SEPARATOR,L""},
		{DI_TEXT,     5,5, 0,5,0,nullptr,nullptr,0,MSG(MMakeFolderLinkType)},
		{DI_COMBOBOX,20,5,70,5,0,nullptr,nullptr,DIF_DROPDOWNLIST|DIF_LISTNOAMPERSAND|DIF_LISTWRAPMODE,L""},
		{DI_TEXT,     5,6, 0,6,0,nullptr,nullptr,0,MSG(MMakeFolderLinkTarget)},
		{DI_EDIT,    20,6,70,6,0,L"NewFolderLinkTarget",nullptr,DIF_DISABLE|DIF_EDITEXPAND|DIF_HISTORY|DIF_USELASTHISTORY|DIF_EDITPATH,L""},
		{DI_CHECKBOX, 5,7, 0,7,Opt.MultiMakeDir,nullptr,nullptr,0,MSG(MMultiMakeDir)},
		{DI_TEXT,     0,8, 0,8,0,nullptr,nullptr,DIF_SEPARATOR,L""},
		{DI_BUTTON,   0,9, 0,9,0,nullptr,nullptr,DIF_DEFAULTBUTTON|DIF_CENTERGROUP,MSG(MOk)},
		{DI_BUTTON,   0,9, 0,9,0,nullptr,nullptr,DIF_CENTERGROUP,MSG(MCancel)},
	};
	MakeDialogItemsEx(MkDirDlgData,MkDirDlg);
	MkDirDlg[MKDIR_COMBOBOX_LINKTYPE].ListItems=&ComboList;
	UserDefinedList DirList(ULF_UNIQUE);
	Dialog Dlg(MkDirDlg,ARRAYSIZE(MkDirDlg),MkDirDlgProc,&DirList);
	Dlg.SetPosition(-1,-1,76,12);
	Dlg.SetHelp(L"MakeFolder");
	Dlg.SetId(MakeFolderId);
	Dlg.Process();

	if (Dlg.GetExitCode()==MKDIR_OK)
	{
		string strDirName=MkDirDlg[MKDIR_EDIT].strData;
		string strOriginalDirName;
		const wchar_t *OneDir;
		DirList.Reset();
		bool SkipAll = false;
		while (nullptr!=(OneDir=DirList.GetNext()))
		{
			strDirName = OneDir;
			strOriginalDirName = strDirName;

			//Unquote(DirName);
			if (Opt.CreateUppercaseFolders && !IsCaseMixed(strDirName))
				strDirName.Upper();

			DeleteEndSlash(strDirName,true);
			wchar_t* lpwszDirName = strDirName.GetBuffer();
			bool bSuccess = false;

			wchar_t *ChPtr;
			if(ParsePath(lpwszDirName, const_cast<const wchar_t **>(&ChPtr)) == PATH_UNKNOWN)
			{
				ChPtr = lpwszDirName;
			}

			for (; ; ChPtr++)
			{
				if (IsSlash(*ChPtr) || !*ChPtr)
				{
					WCHAR Ch=0;
					if(*ChPtr)
					{
						Ch = ChPtr[1];
						ChPtr[1] = 0;
					}
					if (*lpwszDirName)
					{
						string _strDirName(lpwszDirName);
						if (apiGetFileAttributes(_strDirName) == INVALID_FILE_ATTRIBUTES || !*ChPtr) // skip all intermediate dirs, but not last.
						{
							while(!(bSuccess=(apiCreateDirectory(_strDirName, nullptr)!=FALSE)) && !SkipAll)
							{
								int Ret = OperationFailed(strOriginalDirName, MError, MSG(MCannotCreateFolder));
								if(Ret == 1) // skip
								{
									break;
								}
								else if(Ret == 2)
								{
									SkipAll = true;
									break;
								}
								else if (Ret < 0 || Ret == 3) // cancel
								{
									return;
								}
							}
							if(bSuccess)
							{
								TreeList::AddTreeName(_strDirName);
							}
						}
					}
					if(*ChPtr)
					{
						ChPtr[1] = Ch;
					}
					else
					{
						break;
					}
				}
			}

			strDirName.ReleaseBuffer();

			if (bSuccess)
			{
				if(MkDirDlg[MKDIR_COMBOBOX_LINKTYPE].ListPos)
				{
					string strTarget=MkDirDlg[MKDIR_EDIT_LINKPATH].strData;
					Unquote(strTarget);
					while(!CreateReparsePoint(strTarget, strDirName, MkDirDlg[MKDIR_COMBOBOX_LINKTYPE].ListPos==1?RP_JUNCTION:RP_SYMLINKDIR) && !SkipAll)
					{
						int Ret = OperationFailed(strDirName, MError, MSG(MCopyCannotCreateLink));
						if(Ret == 1) // skip
						{
							break;
						}
						else if(Ret == 2)
						{
							SkipAll = true;
							break;
						}
						else if (Ret < 0 || Ret == 3) // cancel
						{
							return;
						}
					}
				}

				TreeList::AddTreeName(strDirName);
			}
		}

		SrcPanel->Update(UPDATE_KEEP_SELECTION);

		if (!strDirName.IsEmpty())
		{
			size_t pos;

			if (FindSlash(pos,strDirName))
				strDirName.SetLength(pos);

			if (!SrcPanel->GoToFile(strDirName) && strDirName.At(strDirName.GetLength()-1)==L'.')
			{
				strDirName.SetLength(strDirName.GetLength()-1);
				SrcPanel->GoToFile(strDirName);
			}
		}

		SrcPanel->Redraw();
		Panel *AnotherPanel=CtrlObject->Cp()->GetAnotherPanel(SrcPanel);
		int AnotherType=AnotherPanel->GetType();

		if (AnotherPanel->NeedUpdatePanel(SrcPanel) || AnotherType==QVIEW_PANEL)
		{
			AnotherPanel->Update(UPDATE_KEEP_SELECTION|UPDATE_SECONDARY);
			AnotherPanel->Redraw();
		}
	}
}
Пример #30
0
bool TestCurrentFolderName(const wchar_t *Name)
{
	return Name[0] == L'.' && (!Name[1] || (IsSlash(Name[1]) && !Name[2]));
}