static void PR_ShellDeleteMsg() { PreRedrawItem preRedrawItem=PreRedraw.Peek(); LARGE_INTEGER i; i.QuadPart = preRedrawItem.Param.Param5; ShellDeleteMsg(static_cast<const wchar_t*>(preRedrawItem.Param.Param1),static_cast<DEL_MODE>(reinterpret_cast<intptr_t>(preRedrawItem.Param.Param4)), i.LowPart, i.HighPart); }
static void PR_ShellDeleteMsg() { if (!PreRedrawStack().empty()) { auto item = dynamic_cast<const DelPreRedrawItem*>(PreRedrawStack().top()); ShellDeleteMsg(item->name, item->Mode, item->Percent, item->WipePercent, item->Title); } }
static void PR_ShellDeleteMsg() { if (!Global->PreRedraw->empty()) { auto item = dynamic_cast<const DelPreRedrawItem*>(Global->PreRedraw->top()); ShellDeleteMsg(item->name, item->Mode, item->Percent, item->WipePercent, item->Title); } }
static bool WipeFile(const string& Name, int TotalPercent, bool& Cancel, ConsoleTitle* DeleteTitle) { bool Result = false; api::SetFileAttributes(Name,FILE_ATTRIBUTE_NORMAL); api::FileWalker WipeFile; if(WipeFile.Open(Name, FILE_READ_DATA|FILE_WRITE_DATA, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_WRITE_THROUGH|FILE_FLAG_SEQUENTIAL_SCAN)) { const DWORD BufSize=65536; if(WipeFile.InitWalk(BufSize)) { static std::array<BYTE, BufSize> Buf; static bool BufInit = false; if(!BufInit) { Buf.fill(Global->Opt->WipeSymbol); // используем символ заполнитель BufInit = true; } DWORD StartTime=GetTickCount(); do { DWORD Written; WipeFile.Write(Buf.data(), WipeFile.GetChunkSize(), Written); DWORD CurTime=GetTickCount(); if (CurTime-StartTime>(DWORD)Global->Opt->RedrawTimeout) { StartTime=CurTime; if (CheckForEscSilent() && ConfirmAbortOp()) { Cancel=true; return false; } ShellDeleteMsg(Name, DEL_WIPEPROCESS, TotalPercent, WipeFile.GetPercent(), DeleteTitle); } } while(WipeFile.Step()); WipeFile.SetPointer(0,nullptr,FILE_BEGIN); WipeFile.SetEnd(); } WipeFile.Close(); string strTempName; FarMkTempEx(strTempName,nullptr,FALSE); Result = api::MoveFile(Name,strTempName) && api::DeleteFile(strTempName); } return Result; }
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); } }
static void PR_ShellDeleteMsg() { PreRedrawItem preRedrawItem=PreRedraw.Peek(); ShellDeleteMsg(static_cast<const wchar_t*>(preRedrawItem.Param.Param1),static_cast<int>(reinterpret_cast<INT_PTR>(preRedrawItem.Param.Param4)),static_cast<int>(preRedrawItem.Param.Param5)); }