Exemple #1
0
bool WINAPI DeleteReparsePoint(const wchar_t *Object)
{
	bool Result=false;
	DWORD ReparseTag;
	string strTmp;
	GetReparsePointInfo(Object,strTmp,&ReparseTag);
	File fObject;
	if (fObject.Open(Object, GENERIC_READ|GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT))
	{
		REPARSE_GUID_DATA_BUFFER rgdb={ReparseTag};
		DWORD dwBytes;
		Result=fObject.IoControl(FSCTL_DELETE_REPARSE_POINT,&rgdb,REPARSE_GUID_DATA_BUFFER_HEADER_SIZE,nullptr,0,&dwBytes);
		fObject.Close();
	}

	return Result;
}
Exemple #2
0
void QuickView::DisplayObject()
{
	if (m_Flags.Check(FSCROBJ_ISREDRAWING))
		return;

	m_Flags.Set(FSCROBJ_ISREDRAWING);

	if (!QView && !ProcessingPluginCommand)
		Parent()->GetAnotherPanel(this)->UpdateViewPanel();

	if (this->Destroyed())
		return;

	if (QView)
		QView->SetPosition(m_X1+1,m_Y1+1,m_X2-1,m_Y2-3);

	Box(m_X1,m_Y1,m_X2,m_Y2,colors::PaletteColorToFarColor(COL_PANELBOX),DOUBLE_BOX);
	SetScreen(m_X1+1,m_Y1+1,m_X2-1,m_Y2-1,L' ',colors::PaletteColorToFarColor(COL_PANELTEXT));
	SetColor(m_Focus ? COL_PANELSELECTEDTITLE:COL_PANELTITLE);

	string strTitle = GetTitle();
	if (!strTitle.empty())
	{
		GotoXY(m_X1+(m_X2-m_X1+1-(int)strTitle.size())/2,m_Y1);
		Text(strTitle);
	}

	DrawSeparator(m_Y2-2);
	SetColor(COL_PANELTEXT);
	GotoXY(m_X1+1,m_Y2-1);
	Global->FS << fmt::LeftAlign()<<fmt::ExactWidth(m_X2-m_X1-1)<<PointToName(strCurFileName);

	if (!strCurFileType.empty())
	{
		string strTypeText=L" ";
		strTypeText+=strCurFileType;
		strTypeText+=L" ";
		TruncStr(strTypeText,m_X2-m_X1-1);
		SetColor(COL_PANELSELECTEDINFO);
		GotoXY(m_X1+(m_X2-m_X1+1-(int)strTypeText.size())/2,m_Y2-2);
		Text(strTypeText);
	}

	if (Directory)
	{
		FormatString FString;
		string DisplayName(strCurFileName);
		TruncPathStr(DisplayName,std::max(0, m_X2-m_X1-1-StrLength(MSG(MQuickViewFolder))-5));
		FString<<MSG(MQuickViewFolder)<<L" \""<<DisplayName<<L"\"";
		SetColor(COL_PANELTEXT);
		GotoXY(m_X1+2,m_Y1+2);
		PrintText(FString);

		DWORD currAttr=os::GetFileAttributes(strCurFileName); // обламывается, если нет доступа
		if (currAttr != INVALID_FILE_ATTRIBUTES && (currAttr&FILE_ATTRIBUTE_REPARSE_POINT))
		{
			string Tmp, Target;
			DWORD ReparseTag=0;
			const wchar_t* PtrName;
			if (GetReparsePointInfo(strCurFileName, Target, &ReparseTag))
			{
				NormalizeSymlinkName(Target);
				switch(ReparseTag)
				{
				// 0xA0000003L = Directory Junction or Volume Mount Point
				case IO_REPARSE_TAG_MOUNT_POINT:
					{
						LNGID ID_Msg = MQuickViewJunction;
						bool Root;
						if(ParsePath(Target, nullptr, &Root) == PATH_VOLUMEGUID && Root)
						{
							ID_Msg=MQuickViewVolMount;
						}
						PtrName = MSG(ID_Msg);
					}
					break;
				// 0xA000000CL = Directory or File Symbolic Link
				case IO_REPARSE_TAG_SYMLINK:
					PtrName = MSG(MQuickViewSymlink);
					break;
				// 0x8000000AL = Distributed File System
				case IO_REPARSE_TAG_DFS:
					PtrName = MSG(MQuickViewDFS);
					break;
				// 0x80000012L = Distributed File System Replication
				case IO_REPARSE_TAG_DFSR:
					PtrName = MSG(MQuickViewDFSR);
					break;
				// 0xC0000004L = Hierarchical Storage Management
				case IO_REPARSE_TAG_HSM:
					PtrName = MSG(MQuickViewHSM);
					break;
				// 0x80000006L = Hierarchical Storage Management2
				case IO_REPARSE_TAG_HSM2:
					PtrName = MSG(MQuickViewHSM2);
					break;
				// 0x80000007L = Single Instance Storage
				case IO_REPARSE_TAG_SIS:
					PtrName = MSG(MQuickViewSIS);
					break;
				// 0x80000008L = Windows Imaging Format
				case IO_REPARSE_TAG_WIM:
					PtrName = MSG(MQuickViewWIM);
					break;
				// 0x80000009L = Cluster Shared Volumes
				case IO_REPARSE_TAG_CSV:
					PtrName = MSG(MQuickViewCSV);
					break;
				case IO_REPARSE_TAG_DEDUP:
					PtrName = MSG(MQuickViewDEDUP);
					break;
				case IO_REPARSE_TAG_NFS:
					PtrName = MSG(MQuickViewNFS);
					break;
				case IO_REPARSE_TAG_FILE_PLACEHOLDER:
					PtrName = MSG(MQuickViewPlaceholder);
					break;
					// 0x????????L = anything else
				default:
					if (Global->Opt->ShowUnknownReparsePoint)
					{
						Tmp = FormatString() << L":" << fmt::Radix(16) << fmt::ExactWidth(8) << fmt::FillChar(L'0') << ReparseTag;
						PtrName = Tmp.data();
					}
					else
					{
						PtrName=MSG(MQuickViewUnknownReparsePoint);
					}
				}
			}
			else
			{
				PtrName = MSG(MQuickViewUnknownReparsePoint);
				Target = MSG(MQuickViewNoData);
			}

			TruncPathStr(Target,std::max(0, m_X2-m_X1-1-StrLength(PtrName)-5));
			FString.clear();
			FString<<PtrName<<L" \""<<Target<<L"\"";
			SetColor(COL_PANELTEXT);
			GotoXY(m_X1+2,m_Y1+3);
			PrintText(FString);
		}

		if (Directory==1 || Directory==4)
		{
			const auto iColor = uncomplete_dirscan? COL_PANELHIGHLIGHTTEXT : COL_PANELINFOTEXT;
			const wchar_t *prefix = uncomplete_dirscan ? L"~" : L"";
			GotoXY(m_X1+2,m_Y1+4);
			PrintText(MSG(MQuickViewContains));
			GotoXY(m_X1+2,m_Y1+6);
			PrintText(MSG(MQuickViewFolders));
			SetColor(iColor);
			FString.clear();
			FString<<prefix<<Data.DirCount;
			PrintText(FString);
			SetColor(COL_PANELTEXT);
			GotoXY(m_X1+2,m_Y1+7);
			PrintText(MSG(MQuickViewFiles));
			SetColor(iColor);
			FString.clear();
			FString<<prefix<<Data.FileCount;
			PrintText(FString);
			SetColor(COL_PANELTEXT);
			GotoXY(m_X1+2,m_Y1+8);
			PrintText(MSG(MQuickViewBytes));
			SetColor(iColor);
			string strSize;
			InsertCommas(Data.FileSize,strSize);
			PrintText(prefix+strSize);
			SetColor(COL_PANELTEXT);
			GotoXY(m_X1+2,m_Y1+9);
			PrintText(MSG(MQuickViewAllocated));
			SetColor(iColor);
			InsertCommas(Data.AllocationSize,strSize);
			FString.clear();
			FString << prefix << strSize << L" (" << ToPercent(Data.AllocationSize,Data.FileSize) << L"%)";
			PrintText(FString);

			if (Directory!=4)
			{
				SetColor(COL_PANELTEXT);
				GotoXY(m_X1+2,m_Y1+11);
				PrintText(MSG(MQuickViewCluster));
				SetColor(iColor);
				InsertCommas(Data.ClusterSize,strSize);
				PrintText(prefix+strSize);

				SetColor(COL_PANELTEXT);
				GotoXY(m_X1+2,m_Y1+12);
				PrintText(MSG(MQuickViewSlack));
				SetColor(iColor);
				InsertCommas(Data.FilesSlack, strSize);
				FString.clear();
				FString << prefix << strSize << L" (" << ToPercent(Data.FilesSlack, Data.AllocationSize) << L"%)";
				PrintText(FString);

				SetColor(COL_PANELTEXT);
				GotoXY(m_X1+2,m_Y1+13);
				PrintText(MSG(MQuickViewMFTOverhead));
				SetColor(iColor);
				InsertCommas(Data.MFTOverhead, strSize);
				FString.clear();
				FString<<prefix<<strSize<<L" ("<<ToPercent(Data.MFTOverhead, Data.AllocationSize)<<L"%)";
				PrintText(FString);

			}
		}
	}
	else if (QView)
		QView->Show();

	m_Flags.Clear(FSCROBJ_ISREDRAWING);
}
Exemple #3
0
void ShellDelete(Panel *SrcPanel,int Wipe)
{
	ChangePriority ChPriority(Opt.DelThreadPriority);
	TPreRedrawFuncGuard preRedrawFuncGuard(PR_ShellDeleteMsg);
	FAR_FIND_DATA_EX FindData;
	string strDeleteFilesMsg;
	string strSelName;
	string strSelShortName;
	string strDizName;
	string strFullName;
	DWORD FileAttr;
	int SelCount,UpdateDiz;
	int DizPresent;
	int Ret;
	BOOL NeedUpdate=TRUE, NeedSetUpADir=FALSE;
	int Opt_DeleteToRecycleBin=Opt.DeleteToRecycleBin;
	/*& 31.05.2001 OT Запретить перерисовку текущего фрейма*/
	Frame *FrameFromLaunched=FrameManager->GetCurrentFrame();
	FrameFromLaunched->Lock();
	DeleteAllFolders=!Opt.Confirm.DeleteFolder;
	UpdateDiz=(Opt.Diz.UpdateMode==DIZ_UPDATE_ALWAYS ||
	           (SrcPanel->IsDizDisplayed() &&
	            Opt.Diz.UpdateMode==DIZ_UPDATE_IF_DISPLAYED));

	if (!(SelCount=SrcPanel->GetSelCount()))
		goto done;

	// Удаление в корзину только для  FIXED-дисков
	{
		string strRoot;
//    char FSysNameSrc[NM];
		SrcPanel->GetSelName(nullptr,FileAttr);
		SrcPanel->GetSelName(&strSelName,FileAttr);
		ConvertNameToFull(strSelName, strRoot);
		GetPathRoot(strRoot,strRoot);

//_SVS(SysLog(L"Del: SelName='%s' Root='%s'",SelName,Root));
		if (Opt.DeleteToRecycleBin && FAR_GetDriveType(strRoot) != DRIVE_FIXED)
			Opt.DeleteToRecycleBin=0;
	}

	if (SelCount==1)
	{
		SrcPanel->GetSelName(nullptr,FileAttr);
		SrcPanel->GetSelName(&strSelName,FileAttr);

		if (TestParentFolderName(strSelName) || strSelName.IsEmpty())
		{
			NeedUpdate=FALSE;
			goto done;
		}

		strDeleteFilesMsg = strSelName;
	}
	else
	{
		// в зависимости от числа ставим нужное окончание
		const wchar_t *Ends;
		wchar_t StrItems[16];
		_itow(SelCount,StrItems,10);
		Ends=MSG(MAskDeleteItemsA);
		int LenItems=StrLength(StrItems);

		if (LenItems > 0)
		{
			if ((LenItems >= 2 && StrItems[LenItems-2] == L'1') ||
			        StrItems[LenItems-1] >= L'5' ||
			        StrItems[LenItems-1] == L'0')
				Ends=MSG(MAskDeleteItemsS);
			else if (StrItems[LenItems-1] == L'1')
				Ends=MSG(MAskDeleteItems0);
		}

		strDeleteFilesMsg.Format(MSG(MAskDeleteItems),SelCount,Ends);
	}

	Ret=1;

	//   Обработка "удаления" линков
	if ((FileAttr & FILE_ATTRIBUTE_REPARSE_POINT) && SelCount==1)
	{
		string strJuncName;
		ConvertNameToFull(strSelName,strJuncName);

		if (GetReparsePointInfo(strJuncName, strJuncName)) // ? SelName ?
		{
			NormalizeSymlinkName(strJuncName);
			//SetMessageHelp(L"DeleteLink");
			string strAskDeleteLink=MSG(MAskDeleteLink);
			DWORD dwAttr=apiGetFileAttributes(strJuncName);

			if (dwAttr!=INVALID_FILE_ATTRIBUTES)
			{
				strAskDeleteLink+=L" ";
				strAskDeleteLink+=dwAttr&FILE_ATTRIBUTE_DIRECTORY?MSG(MAskDeleteLinkFolder):MSG(MAskDeleteLinkFile);
			}

			Ret=Message(0,3,MSG(MDeleteLinkTitle),
			            strDeleteFilesMsg,
			            strAskDeleteLink,
			            strJuncName,
			            MSG(MDeleteLinkDelete),MSG(MDeleteLinkUnlink),MSG(MCancel));

			if (Ret == 1)
			{
				ConvertNameToFull(strSelName, strJuncName);

				if (Opt.Confirm.Delete)
				{
					; //  ;-%
				}

				if ((NeedSetUpADir=CheckUpdateAnotherPanel(SrcPanel,strSelName)) != -1) //JuncName?
				{
					DeleteReparsePoint(strJuncName);
					ShellUpdatePanels(SrcPanel,NeedSetUpADir);
				}

				goto done;
			}

			if (Ret )
				goto done;
		}
	}

	if (Ret && (Opt.Confirm.Delete || SelCount>1 || (FileAttr & FILE_ATTRIBUTE_DIRECTORY)))
	{
		const wchar_t *DelMsg;
		const wchar_t *TitleMsg=MSG(Wipe?MDeleteWipeTitle:MDeleteTitle);
		/* $ 05.01.2001 IS
		   ! Косметика в сообщениях - разные сообщения в зависимости от того,
		     какие и сколько элементов выделено.
		*/
		BOOL folder=(FileAttr & FILE_ATTRIBUTE_DIRECTORY);

		if (SelCount==1)
		{
			if (Wipe && !(FileAttr & FILE_ATTRIBUTE_REPARSE_POINT))
				DelMsg=MSG(folder?MAskWipeFolder:MAskWipeFile);
			else
			{
				if (Opt.DeleteToRecycleBin && !(FileAttr & FILE_ATTRIBUTE_REPARSE_POINT))
					DelMsg=MSG(folder?MAskDeleteRecycleFolder:MAskDeleteRecycleFile);
				else
					DelMsg=MSG(folder?MAskDeleteFolder:MAskDeleteFile);
			}
		}
		else
		{
			if (Wipe && !(FileAttr & FILE_ATTRIBUTE_REPARSE_POINT))
			{
				DelMsg=MSG(MAskWipe);
				TitleMsg=MSG(MDeleteWipeTitle);
			}
			else if (Opt.DeleteToRecycleBin && !(FileAttr & FILE_ATTRIBUTE_REPARSE_POINT))
				DelMsg=MSG(MAskDeleteRecycle);
			else
				DelMsg=MSG(MAskDelete);
		}

		SetMessageHelp(L"DeleteFile");

		if (Message(0,2,TitleMsg,DelMsg,strDeleteFilesMsg,MSG(Wipe?MDeleteWipe:Opt.DeleteToRecycleBin?MDeleteRecycle:MDelete),MSG(MCancel)))
		{
			NeedUpdate=FALSE;
			goto done;
		}
	}

	if (Opt.Confirm.Delete && SelCount>1)
	{
		//SaveScreen SaveScr;
		SetCursorType(FALSE,0);
		SetMessageHelp(L"DeleteFile");

		if (Message(MSG_WARNING,2,MSG(Wipe?MWipeFilesTitle:MDeleteFilesTitle),MSG(Wipe?MAskWipe:MAskDelete),
		            strDeleteFilesMsg,MSG(MDeleteFileAll),MSG(MDeleteFileCancel)))
		{
			NeedUpdate=FALSE;
			goto done;
		}
	}

	if (UpdateDiz)
		SrcPanel->ReadDiz();

	SrcPanel->GetDizName(strDizName);
	DizPresent=(!strDizName.IsEmpty() && apiGetFileAttributes(strDizName)!=INVALID_FILE_ATTRIBUTES);
	DeleteTitle = new ConsoleTitle(MSG(MDeletingTitle));

	if ((NeedSetUpADir=CheckUpdateAnotherPanel(SrcPanel,strSelName)) == -1)
		goto done;

	if (SrcPanel->GetType()==TREE_PANEL)
		FarChDir(L"\\");

	{
		TaskBar TB;
		wakeful W;
		bool Cancel=false;
		//SaveScreen SaveScr;
		SetCursorType(FALSE,0);
		ReadOnlyDeleteMode=-1;
		SkipMode=-1;
		SkipWipeMode=-1;
		SkipFoldersMode=-1;
		ULONG ItemsCount=0;
		ProcessedItems=0;

		if (Opt.DelOpt.DelShowTotal)
		{
			SrcPanel->GetSelName(nullptr,FileAttr);
			DWORD StartTime=GetTickCount();
			bool FirstTime=true;

			while (SrcPanel->GetSelName(&strSelName,FileAttr,&strSelShortName) && !Cancel)
			{
				if (!(FileAttr&FILE_ATTRIBUTE_REPARSE_POINT))
				{
					if (FileAttr&FILE_ATTRIBUTE_DIRECTORY)
					{
						DWORD CurTime=GetTickCount();

						if (CurTime-StartTime>RedrawTimeout || FirstTime)
						{
							StartTime=CurTime;
							FirstTime=false;

							if (CheckForEscSilent() && ConfirmAbortOp())
							{
								Cancel=true;
								break;
							}

							ShellDeleteMsg(strSelName,Wipe,-1);
						}

						ULONG CurrentFileCount,CurrentDirCount,ClusterSize;
						UINT64 FileSize,CompressedFileSize,RealSize;

						if (GetDirInfo(nullptr,strSelName,CurrentDirCount,CurrentFileCount,FileSize,CompressedFileSize,RealSize,ClusterSize,-1,nullptr,0)>0)
						{
							ItemsCount+=CurrentFileCount+CurrentDirCount+1;
						}
						else
						{
							Cancel=true;
						}
					}
					else
					{
						ItemsCount++;
					}
				}
			}
		}

		SrcPanel->GetSelName(nullptr,FileAttr);
		DWORD StartTime=GetTickCount();
		bool FirstTime=true;

		while (SrcPanel->GetSelName(&strSelName,FileAttr,&strSelShortName) && !Cancel)
		{
			int Length=(int)strSelName.GetLength();

			if (!Length || (strSelName.At(0)==L'\\' && Length<2) ||
			        (strSelName.At(1)==L':' && Length<4))
				continue;

			DWORD CurTime=GetTickCount();

			if (CurTime-StartTime>RedrawTimeout || FirstTime)
			{
				StartTime=CurTime;
				FirstTime=false;

				if (CheckForEscSilent() && ConfirmAbortOp())
				{
					Cancel=true;
					break;
				}

				ShellDeleteMsg(strSelName,Wipe,Opt.DelOpt.DelShowTotal?(ItemsCount?(ProcessedItems*100/ItemsCount):0):-1);
			}

			if (FileAttr & FILE_ATTRIBUTE_DIRECTORY)
			{
				if (!DeleteAllFolders)
				{
					ConvertNameToFull(strSelName, strFullName);

					if (TestFolder(strFullName) == TSTFLD_NOTEMPTY)
					{
						int MsgCode=0;

						// для symlink`а не нужно подтверждение
						if (!(FileAttr & FILE_ATTRIBUTE_REPARSE_POINT))
							MsgCode=Message(MSG_WARNING,4,MSG(Wipe?MWipeFolderTitle:MDeleteFolderTitle),
							                MSG(Wipe?MWipeFolderConfirm:MDeleteFolderConfirm),strFullName,
							                MSG(Wipe?MDeleteFileWipe:MDeleteFileDelete),MSG(MDeleteFileAll),
							                MSG(MDeleteFileSkip),MSG(MDeleteFileCancel));

						if (MsgCode<0 || MsgCode==3)
						{
							NeedSetUpADir=FALSE;
							break;
						}

						if (MsgCode==1)
							DeleteAllFolders=1;

						if (MsgCode==2)
							continue;
					}
				}

				bool DirSymLink=(FileAttr&FILE_ATTRIBUTE_DIRECTORY && FileAttr&FILE_ATTRIBUTE_REPARSE_POINT);

				if (!DirSymLink && (!Opt.DeleteToRecycleBin || Wipe))
				{
					string strFullName;
					ScanTree ScTree(TRUE,TRUE,FALSE);
					string strSelFullName;

					if (IsAbsolutePath(strSelName))
					{
						strSelFullName=strSelName;
					}
					else
					{
						SrcPanel->GetCurDir(strSelFullName);
						AddEndSlash(strSelFullName);
						strSelFullName+=strSelName;
					}

					ScTree.SetFindPath(strSelFullName,L"*", 0);
					DWORD StartTime=GetTickCount();

					while (ScTree.GetNextName(&FindData,strFullName))
					{
						DWORD CurTime=GetTickCount();

						if (CurTime-StartTime>RedrawTimeout)
						{
							StartTime=CurTime;

							if (CheckForEscSilent())
							{
								int AbortOp = ConfirmAbortOp();

								if (AbortOp)
								{
									Cancel=true;
									break;
								}
							}

							ShellDeleteMsg(strFullName,Wipe,Opt.DelOpt.DelShowTotal?(ItemsCount?(ProcessedItems*100/ItemsCount):0):-1);
						}

						if (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
						{
							if (FindData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
							{
								if (FindData.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
									apiSetFileAttributes(strFullName,FILE_ATTRIBUTE_NORMAL);

								int MsgCode=ERemoveDirectory(strFullName,Wipe);

								if (MsgCode==DELETE_CANCEL)
								{
									Cancel=true;
									break;
								}
								else if (MsgCode==DELETE_SKIP)
								{
									ScTree.SkipDir();
									continue;
								}

								TreeList::DelTreeName(strFullName);

								if (UpdateDiz)
									SrcPanel->DeleteDiz(strFullName,strSelShortName);

								continue;
							}

							if (!DeleteAllFolders && !ScTree.IsDirSearchDone() && TestFolder(strFullName) == TSTFLD_NOTEMPTY)
							{
								int MsgCode=Message(MSG_WARNING,4,MSG(Wipe?MWipeFolderTitle:MDeleteFolderTitle),
								                    MSG(Wipe?MWipeFolderConfirm:MDeleteFolderConfirm),strFullName,
								                    MSG(Wipe?MDeleteFileWipe:MDeleteFileDelete),MSG(MDeleteFileAll),
								                    MSG(MDeleteFileSkip),MSG(MDeleteFileCancel));

								if (MsgCode<0 || MsgCode==3)
								{
									Cancel=true;
									break;
								}

								if (MsgCode==1)
									DeleteAllFolders=1;

								if (MsgCode==2)
								{
									ScTree.SkipDir();
									continue;
								}
							}

							if (ScTree.IsDirSearchDone())
							{
								if (FindData.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
									apiSetFileAttributes(strFullName,FILE_ATTRIBUTE_NORMAL);

								int MsgCode=ERemoveDirectory(strFullName,Wipe);

								if (MsgCode==DELETE_CANCEL)
								{
									Cancel=true;;
									break;
								}
								else if (MsgCode==DELETE_SKIP)
								{
									//ScTree.SkipDir();
									continue;
								}

								TreeList::DelTreeName(strFullName);
							}
						}
						else
						{
							int AskCode=AskDeleteReadOnly(strFullName,FindData.dwFileAttributes,Wipe);

							if (AskCode==DELETE_CANCEL)
							{
								Cancel=true;
								break;
							}

							if (AskCode==DELETE_YES)
								if (ShellRemoveFile(strFullName,Wipe)==DELETE_CANCEL)
								{
									Cancel=true;
									break;
								}
						}
					}
				}

				if (!Cancel)
				{
					if (FileAttr & FILE_ATTRIBUTE_READONLY)
						apiSetFileAttributes(strSelName,FILE_ATTRIBUTE_NORMAL);

					int DeleteCode;

					// нефига здесь выделываться, а надо учесть, что удаление
					// симлинка в корзину чревато потерей оригинала.
					if (DirSymLink || !Opt.DeleteToRecycleBin || Wipe)
					{
						DeleteCode=ERemoveDirectory(strSelName,Wipe);

						if (DeleteCode==DELETE_CANCEL)
							break;
						else if (DeleteCode==DELETE_SUCCESS)
						{
							TreeList::DelTreeName(strSelName);

							if (UpdateDiz)
								SrcPanel->DeleteDiz(strSelName,strSelShortName);
						}
					}
					else
					{
						DeleteCode=RemoveToRecycleBin(strSelName);

						if (!DeleteCode)
							Message(MSG_WARNING|MSG_ERRORTYPE,1,MSG(MError),
							        MSG(MCannotDeleteFolder),strSelName,MSG(MOk));
						else
						{
							TreeList::DelTreeName(strSelName);

							if (UpdateDiz)
								SrcPanel->DeleteDiz(strSelName,strSelShortName);
						}
					}
				}
			}
			else
			{
				int AskCode=AskDeleteReadOnly(strSelName,FileAttr,Wipe);

				if (AskCode==DELETE_CANCEL)
					break;

				if (AskCode==DELETE_YES)
				{
					int DeleteCode=ShellRemoveFile(strSelName,Wipe);

					if (DeleteCode==DELETE_SUCCESS && UpdateDiz)
					{
						SrcPanel->DeleteDiz(strSelName,strSelShortName);
					}

					if (DeleteCode==DELETE_CANCEL)
						break;
				}
			}
		}
	}

	if (UpdateDiz)
		if (DizPresent==(!strDizName.IsEmpty() && apiGetFileAttributes(strDizName)!=INVALID_FILE_ATTRIBUTES))
			SrcPanel->FlushDiz();

	delete DeleteTitle;
done:
	Opt.DeleteToRecycleBin=Opt_DeleteToRecycleBin;
	// Разрешить перерисовку фрейма
	FrameFromLaunched->Unlock();

	if (NeedUpdate)
	{
		ShellUpdatePanels(SrcPanel,NeedSetUpADir);
	}
}
Exemple #4
0
ShellDelete::ShellDelete(Panel *SrcPanel,bool Wipe):
	ReadOnlyDeleteMode(-1),
	m_SkipMode(-1),
	SkipWipeMode(-1),
	SkipFoldersMode(-1),
	ProcessedItems(0)
{
	SCOPED_ACTION(ChangePriority)(Global->Opt->DelThreadPriority);
	SCOPED_ACTION(TPreRedrawFuncGuard)(std::make_unique<DelPreRedrawItem>());
	os::FAR_FIND_DATA FindData;
	string strDeleteFilesMsg;
	string strSelName;
	string strSelShortName;
	string strDizName;
	DWORD FileAttr;
	size_t SelCount;
	int UpdateDiz;
	int DizPresent;
	int Ret;
	BOOL NeedUpdate=TRUE, NeedSetUpADir=FALSE;
	bool Opt_DeleteToRecycleBin=Global->Opt->DeleteToRecycleBin;
	/*& 31.05.2001 OT Запретить перерисовку текущего окна*/
	auto WindowFromLaunched = Global->WindowManager->GetCurrentWindow();
	WindowFromLaunched->Lock();
	bool DeleteAllFolders=!Global->Opt->Confirm.DeleteFolder;
	UpdateDiz=(Global->Opt->Diz.UpdateMode==DIZ_UPDATE_ALWAYS ||
	           (SrcPanel->IsDizDisplayed() &&
	            Global->Opt->Diz.UpdateMode==DIZ_UPDATE_IF_DISPLAYED));

	SCOPE_EXIT
	{
		Global->Opt->DeleteToRecycleBin=Opt_DeleteToRecycleBin;
		// Разрешить перерисовку окна
		WindowFromLaunched->Unlock();

		if (NeedUpdate)
		{
			ShellUpdatePanels(SrcPanel,NeedSetUpADir);
		}
	};

	if (!(SelCount=SrcPanel->GetSelCount()))
		return;

	// Удаление в корзину только для  FIXED-дисков
	{
		string strRoot;
		SrcPanel->GetSelName(nullptr,FileAttr);
		SrcPanel->GetSelName(&strSelName,FileAttr);
		ConvertNameToFull(strSelName, strRoot);
		GetPathRoot(strRoot,strRoot);

		if (Global->Opt->DeleteToRecycleBin && FAR_GetDriveType(strRoot) != DRIVE_FIXED)
			Global->Opt->DeleteToRecycleBin=0;
	}

	if (SelCount==1)
	{
		SrcPanel->GetSelName(nullptr,FileAttr);
		SrcPanel->GetSelName(&strSelName,FileAttr);

		if (TestParentFolderName(strSelName) || strSelName.empty())
		{
			NeedUpdate=FALSE;
			return;
		}

		strDeleteFilesMsg = strSelName;
		QuoteLeadingSpace(strDeleteFilesMsg);
	}
	else
	{
		// в зависимости от числа ставим нужное окончание
		const wchar_t *Ends;
		FormatString StrItems;
		StrItems << SelCount;
		Ends=MSG(MAskDeleteItemsA);
		size_t LenItems = StrItems.size();

		if (LenItems > 0)
		{
			if ((LenItems >= 2 && StrItems[LenItems-2] == L'1') ||
			        StrItems[LenItems-1] >= L'5' ||
			        StrItems[LenItems-1] == L'0')
				Ends=MSG(MAskDeleteItemsS);
			else if (StrItems[LenItems-1] == L'1')
				Ends=MSG(MAskDeleteItems0);
		}
		strDeleteFilesMsg = LangString(MAskDeleteItems) << SelCount << Ends;
	}

	Ret=1;

	//   Обработка "удаления" линков
	if ((FileAttr & FILE_ATTRIBUTE_REPARSE_POINT) && SelCount==1)
	{
		string strJuncName;
		ConvertNameToFull(strSelName,strJuncName);

		if (GetReparsePointInfo(strJuncName, strJuncName)) // ? SelName ?
		{
			NormalizeSymlinkName(strJuncName);
			string strAskDeleteLink=MSG(MAskDeleteLink);
			os::fs::file_status Status(strJuncName);
			if (os::fs::exists(Status))
			{
				strAskDeleteLink+=L" ";
				strAskDeleteLink += MSG(is_directory(Status)? MAskDeleteLinkFolder : MAskDeleteLinkFile);
			}

			Ret=Message(0,2,MSG(MDeleteLinkTitle),
			            strDeleteFilesMsg.data(),
			            strAskDeleteLink.data(),
			            strJuncName.data(),
						MSG(MDeleteLinkDelete), MSG(MCancel));
			if (Ret)
				return;
		}
	}

	if (Ret && Global->Opt->Confirm.Delete)
	{
		LNGID mTitle = Wipe ? MDeleteWipeTitle : MDeleteTitle;
		LNGID mDText;
		string tText;
		LNGID mDBttn = Wipe ? MDeleteWipe : Global->Opt->DeleteToRecycleBin ? MDeleteRecycle : MDelete;
		bool bHilite = Global->Opt->DelOpt.HighlightSelected;
		int mshow = std::min(std::max((int)Global->Opt->DelOpt.ShowSelected, 1), ScrY/2);
		
		std::vector<string> items;
		items.push_back(strDeleteFilesMsg);

		if (SelCount == 1)
		{
			bool folder = (FileAttr & FILE_ATTRIBUTE_DIRECTORY) != 0;

			if (Wipe && !(FileAttr & FILE_ATTRIBUTE_REPARSE_POINT))
				mDText = folder ? MAskWipeFolder : MAskWipeFile;
			else
			{
				if (Global->Opt->DeleteToRecycleBin)
					mDText = folder ? MAskDeleteRecycleFolder : MAskDeleteRecycleFile;
				else
					mDText = folder ? MAskDeleteFolder : MAskDeleteFile;
			}
			if (bHilite)
			{
				string name, sname;
				SrcPanel->GetCurName(name, sname);
				QuoteLeadingSpace(name);
				bHilite = strDeleteFilesMsg != name;
			}
		}
		else
		{
			if (Wipe)
			{
				mDText = MAskWipe;
				mTitle = MDeleteWipeTitle;
			}
			else
				mDText = Global->Opt->DeleteToRecycleBin ? MAskDeleteRecycle : MAskDelete;

			if (mshow > 1)
			{
				tText = MSG(mDText) + string(L" ") + strDeleteFilesMsg;
				items.clear();
				DWORD attr;
				string name;
				SrcPanel->GetSelName(nullptr, attr);

				for (size_t i = 0; i < SelCount; ++i)
				{
					if (i == (size_t)mshow-1 && i+1 < SelCount)
					{
						items.push_back(L"...");
						break;
					}
					SrcPanel->GetSelName(&name, attr);
					QuoteLeadingSpace(name);
					items.push_back(name);
				}
			}
		}

		intptr_t start_hilite = 0, end_hilite = 0;

		DialogBuilder Builder(mTitle, nullptr, [&](Dialog* Dlg, intptr_t Msg, intptr_t Param1, void* Param2) -> intptr_t
		{
			if (bHilite && Msg == DN_CTLCOLORDLGITEM && Param1 >= start_hilite && Param1 <= end_hilite)
			{
				auto Colors = static_cast<FarDialogItemColors*>(Param2);
				Colors->Colors[0] = Colors->Colors[1];
			}
			return Dlg->DefProc(Msg, Param1, Param2);
		});

		if (tText.empty())
			tText = MSG(mDText);

		Builder.AddText(tText.data())->Flags = DIF_CENTERTEXT;

		if (bHilite || (mshow > 1 && SelCount > 1))
			Builder.AddSeparator();

		std::for_each(RANGE(items, i)
		{
			TruncStrFromCenter(i, ScrX+1-6*2);
			auto dx = Builder.AddText(i.data());
			dx->Flags = (SelCount <= 1 || mshow <= 1 ? DIF_CENTERTEXT : 0) | DIF_SHOWAMPERSAND;
			size_t index = Builder.GetLastID();
			end_hilite = index;
			if (!start_hilite)
				start_hilite = index;
		});
Exemple #5
0
const string FormatStr_Size(__int64 FileSize, __int64 AllocationSize, __int64 StreamsSize, const string& strName,
							DWORD FileAttributes,DWORD ShowFolderSize,DWORD ReparseTag,int ColumnType,
							unsigned __int64 Flags,int Width,const wchar_t *CurDir)
{
	FormatString strResult;

	bool Packed=(ColumnType==PACKED_COLUMN);
	bool Streams=(ColumnType==STREAMSSIZE_COLUMN);

	if (ShowFolderSize==2)
	{
		Width--;
		strResult<<L"~";
	}

	if (!Streams && !Packed && (FileAttributes & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_REPARSE_POINT)) && !ShowFolderSize)
	{
		string strMsg;
		const wchar_t *PtrName=MSG(MListFolder);

		if (TestParentFolderName(strName))
		{
			PtrName=MSG(MListUp);
		}
		else
		{
			if (FileAttributes&FILE_ATTRIBUTE_REPARSE_POINT)
			{
				switch(ReparseTag)
				{
				// 0xA0000003L = Directory Junction or Volume Mount Point
				case IO_REPARSE_TAG_MOUNT_POINT:
					{
						LNGID ID_Msg = MListJunction;
						if (Opt.PanelDetailedJunction)
						{
							string strLinkName=CurDir?CurDir:L"";
							AddEndSlash(strLinkName);
							strLinkName+=PointToName(strName);

							if (GetReparsePointInfo(strLinkName, strLinkName))
							{
								NormalizeSymlinkName(strLinkName);
								bool Root;
								if(ParsePath(strLinkName, nullptr, &Root) == PATH_VOLUMEGUID && Root)
								{
									ID_Msg=MListVolMount;
								}
							}
						}
						PtrName=MSG(ID_Msg);
					}
					break;
				// 0xA000000CL = Directory or File Symbolic Link
				case IO_REPARSE_TAG_SYMLINK:
					PtrName = MSG(MListSymlink);
					break;
				// 0x8000000AL = Distributed File System
				case IO_REPARSE_TAG_DFS:
					PtrName = MSG(MListDFS);
					break;
				// 0x80000012L = Distributed File System Replication
				case IO_REPARSE_TAG_DFSR:
					PtrName = MSG(MListDFSR);
					break;
				// 0xC0000004L = Hierarchical Storage Management
				case IO_REPARSE_TAG_HSM:
					PtrName = MSG(MListHSM);
					break;
				// 0x80000006L = Hierarchical Storage Management2
				case IO_REPARSE_TAG_HSM2:
					PtrName = MSG(MListHSM2);
					break;
				// 0x80000007L = Single Instance Storage
				case IO_REPARSE_TAG_SIS:
					PtrName = MSG(MListSIS);
					break;
				// 0x80000008L = Windows Imaging Format
				case IO_REPARSE_TAG_WIM:
					PtrName = MSG(MListWIM);
					break;
				// 0x80000009L = Cluster Shared Volumes
				case IO_REPARSE_TAG_CSV:
					PtrName = MSG(MListCSV);
					break;
				// 0x????????L = anything else
				default:
					if (Opt.ShowUnknownReparsePoint)
					{
						strMsg = FormatString() << L":" << fmt::Radix(16) << fmt::ExactWidth(8) << fmt::FillChar(L'0') << ReparseTag;
						PtrName = strMsg;
					}
					else
					{
						PtrName=MSG(MListUnknownReparsePoint);
					}
				}
			}
		}

		FormatString strStr;
		if(*PtrName)
		{
			if (StrLength(PtrName) <= Width-2 && MSG(MListBrackets)[0] && MSG(MListBrackets)[1])
			{
				strStr << MSG(MListBrackets)[0] << PtrName << MSG(MListBrackets)[1];
			}
			else
			{
				strStr << PtrName;
			}
		}
		strResult<<fmt::ExactWidth(Width)<<strStr;
	}
	else
	{
		string strOutStr;
		strResult<<FileSizeToStr(strOutStr,Packed?AllocationSize:Streams?StreamsSize:FileSize,Width,Flags).CPtr();
	}

	return strResult;
}