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); }
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; });
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); } }
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; }