void CShellBrowser::DetermineItemOwnerGroup(int iItemInternal,TCHAR *szGroupHeader,int cchMax) const { TCHAR FullFileName[MAX_PATH]; std::list<TypeGroup_t>::iterator itr; TCHAR szOwner[512]; StringCchCopy(FullFileName,SIZEOF_ARRAY(FullFileName),m_CurDir); PathAppend(FullFileName,m_pwfdFiles[iItemInternal].cFileName); BOOL ret = GetFileOwner(FullFileName,szOwner,SIZEOF_ARRAY(szOwner)); if(!ret) { StringCchCopy(szOwner,SIZEOF_ARRAY(szOwner),EMPTY_STRING); } StringCchCopy(szGroupHeader,cchMax,szOwner); }
char* GetUserFromPid(pid_t pid) { #if defined(__linux__) // Get effective owner of pid from procfs std::stringstream ss; ss << "/proc/" << pid; std::string path; ss >> path; return GetFileOwner(path.c_str()); #elif defined(__APPLE__) && defined(__MACH__) // Get effective owner of pid from sysctl struct kinfo_proc oldp; size_t oldlenp = sizeof(oldp); int name[] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid}; u_int namelen = sizeof(name)/sizeof(int); // Read-only query int ret = sysctl(name, namelen, &oldp, &oldlenp, NULL, 0); if (ret != 0 || oldlenp == 0) { errno = ERROR_GEN_FAILURE; return NULL; } return GetPwUid(oldp.kp_eproc.e_ucred.cr_uid); #else return NULL; #endif }
TEST(GetFileOwnerTest, CanGetOwnerOfRoot) { EXPECT_STREQ(GetFileOwner("/"), "root"); }
TEST(GetFileOwnerTest, CannotGetOwnerOfFakeFile) { EXPECT_STREQ(GetFileOwner("SomeMadeUpFileNameThatDoesNotExist"), NULL); EXPECT_EQ(ENOENT, errno); }
void FileList::ReadFileNames(int KeepSelection, int IgnoreVisible, int DrawMessage) { TPreRedrawFuncGuard preRedrawFuncGuard(PR_ReadFileNamesMsg); TaskBar TB(false); strOriginalCurDir=strCurDir; if (!IsVisible() && !IgnoreVisible) { UpdateRequired=TRUE; UpdateRequiredMode=KeepSelection; return; } UpdateRequired=FALSE; AccessTimeUpdateRequired=FALSE; DizRead=FALSE; FAR_FIND_DATA_EX fdata; FileListItem *CurPtr=0,**OldData=0; string strCurName, strNextCurName; int OldFileCount=0; StopFSWatcher(); if (this!=CtrlObject->Cp()->LeftPanel && this!=CtrlObject->Cp()->RightPanel) return; string strSaveDir; apiGetCurrentDirectory(strSaveDir); { string strOldCurDir = strCurDir; if (!SetCurPath()) { FlushInputBuffer(); // Очистим буффер ввода, т.к. мы уже можем быть в другом месте... if (!StrCmp(strCurDir, strOldCurDir)) //?? i?? { GetPathRoot(strOldCurDir,strOldCurDir); if (!apiIsDiskInDrive(strOldCurDir)) IfGoHome(strOldCurDir.At(0)); /* При смене каталога путь не изменился */ } return; } } SortGroupsRead=FALSE; if (GetFocus()) CtrlObject->CmdLine->SetCurDir(strCurDir); LastCurFile=-1; Panel *AnotherPanel=CtrlObject->Cp()->GetAnotherPanel(this); AnotherPanel->QViewDelTempName(); size_t PrevSelFileCount=SelFileCount; SelFileCount=0; SelFileSize=0; TotalFileCount=0; TotalFileSize=0; CacheSelIndex=-1; CacheSelClearIndex=-1; if (Opt.ShowPanelFree) { unsigned __int64 TotalSize,TotalFree; if (!apiGetDiskSize(strCurDir,&TotalSize,&TotalFree,&FreeDiskSize)) FreeDiskSize=0; } if (FileCount>0) { strCurName = ListData[CurFile]->strName; if (ListData[CurFile]->Selected) { for (int i=CurFile+1; i < FileCount; i++) { CurPtr = ListData[i]; if (!CurPtr->Selected) { strNextCurName = CurPtr->strName; break; } } } } if (KeepSelection || PrevSelFileCount>0) { OldData=ListData; OldFileCount=FileCount; } else DeleteListData(ListData,FileCount); ListData=nullptr; int ReadOwners=IsColumnDisplayed(OWNER_COLUMN); int ReadNumLinks=IsColumnDisplayed(NUMLINK_COLUMN); int ReadNumStreams=IsColumnDisplayed(NUMSTREAMS_COLUMN); int ReadStreamsSize=IsColumnDisplayed(STREAMSSIZE_COLUMN); string strComputerName; if (ReadOwners) { CurPath2ComputerName(strCurDir, strComputerName); // сбросим кэш SID`ов SIDCacheFlush(); } SetLastError(ERROR_SUCCESS); int AllocatedCount=0; FileListItem *NewPtr; // сформируем заголовок вне цикла wchar_t Title[2048]; int TitleLength=Min((int)X2-X1-1,(int)(ARRAYSIZE(Title))-1); //wmemset(Title,0x0CD,TitleLength); //BUGBUG //Title[TitleLength]=0; MakeSeparator(TitleLength, Title, 9, nullptr); BOOL IsShowTitle=FALSE; BOOL NeedHighlight=Opt.Highlight && PanelMode != PLUGIN_PANEL; if (!Filter) Filter=new FileFilter(this,FFT_PANEL); //Рефреш текущему времени для фильтра перед началом операции Filter->UpdateCurrentTime(); CtrlObject->HiFiles->UpdateCurrentTime(); bool bCurDirRoot = false; ParsePath(strCurDir, nullptr, &bCurDirRoot); PATH_TYPE Type = ParsePath(strCurDir, nullptr, &bCurDirRoot); bool NetRoot = bCurDirRoot && (Type == PATH_REMOTE || Type == PATH_REMOTEUNC); FileCount = 0; string strFind = strCurDir; AddEndSlash(strFind); strFind+=L'*'; ::FindFile Find(strFind, true); DWORD FindErrorCode = ERROR_SUCCESS; bool UseFilter=Filter->IsEnabledOnPanel(); bool ReadCustomData=IsColumnDisplayed(CUSTOM_COLUMN0)!=0; DWORD StartTime = GetTickCount(); while (Find.Get(fdata)) { FindErrorCode = GetLastError(); if ((Opt.ShowHidden || !(fdata.dwFileAttributes & (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM))) && (!UseFilter || Filter->FileInFilter(fdata, nullptr, &fdata.strFileName))) { if (FileCount>=AllocatedCount) { AllocatedCount+=4096; FileListItem **pTemp; if (!(pTemp=(FileListItem **)xf_realloc(ListData,AllocatedCount*sizeof(*ListData)))) break; ListData=pTemp; } ListData[FileCount] = new FileListItem; ListData[FileCount]->Clear(); NewPtr=ListData[FileCount]; NewPtr->FileAttr = fdata.dwFileAttributes; NewPtr->CreationTime = fdata.ftCreationTime; NewPtr->AccessTime = fdata.ftLastAccessTime; NewPtr->WriteTime = fdata.ftLastWriteTime; NewPtr->ChangeTime = fdata.ftChangeTime; NewPtr->FileSize = fdata.nFileSize; NewPtr->AllocationSize = fdata.nAllocationSize; NewPtr->strName = fdata.strFileName; NewPtr->strShortName = fdata.strAlternateFileName; NewPtr->Position=FileCount++; NewPtr->NumberOfLinks=1; if (fdata.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { NewPtr->ReparseTag=fdata.dwReserved0; //MSDN } if (!(fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { TotalFileSize += NewPtr->FileSize; if (ReadNumLinks) NewPtr->NumberOfLinks=GetNumberOfLinks(fdata.strFileName); } else { NewPtr->AllocationSize = 0; } NewPtr->SortGroup=DEFAULT_SORT_GROUP; if (ReadOwners) { string strOwner; GetFileOwner(strComputerName, NewPtr->strName,strOwner); NewPtr->strOwner = strOwner; } NewPtr->NumberOfStreams=NewPtr->FileAttr&FILE_ATTRIBUTE_DIRECTORY?0:1; NewPtr->StreamsSize=NewPtr->FileSize; if (ReadNumStreams||ReadStreamsSize) { EnumStreams(TestParentFolderName(fdata.strFileName)?strCurDir:fdata.strFileName,NewPtr->StreamsSize,NewPtr->NumberOfStreams); } if (ReadCustomData) CtrlObject->Plugins->GetCustomData(NewPtr); if (!(fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) TotalFileCount++; //memcpy(ListData+FileCount,&NewPtr,sizeof(NewPtr)); // FileCount++; DWORD CurTime = GetTickCount(); if (CurTime - StartTime > RedrawTimeout) { StartTime = CurTime; if (IsVisible()) { if (!IsShowTitle) { if (!DrawMessage) { Text(X1+1,Y1,ColorIndexToColor(COL_PANELBOX),Title); IsShowTitle=TRUE; SetColor(Focus ? COL_PANELSELECTEDTITLE:COL_PANELTITLE); } } LangString strReadMsg(MReadingFiles); strReadMsg << FileCount; if (DrawMessage) { ReadFileNamesMsg(strReadMsg); } else { TruncStr(strReadMsg,TitleLength-2); int MsgLength=(int)strReadMsg.GetLength(); GotoXY(X1+1+(TitleLength-MsgLength-1)/2,Y1); FS<<L" "<<strReadMsg<<L" "; } } if (CheckForEsc()) { break; } } } } if (!(FindErrorCode==ERROR_SUCCESS || FindErrorCode==ERROR_NO_MORE_FILES || FindErrorCode==ERROR_FILE_NOT_FOUND)) Message(MSG_WARNING|MSG_ERRORTYPE,1,MSG(MError),MSG(MReadFolderError),MSG(MOk)); if ((Opt.ShowDotsInRoot || !bCurDirRoot) || (NetRoot && CtrlObject->Plugins->FindPlugin(Opt.KnownIDs.Network))) // NetWork Plugin { if (FileCount>=AllocatedCount) { FileListItem **pTemp; if ((pTemp=(FileListItem **)xf_realloc(ListData,(FileCount+1)*sizeof(*ListData)))) ListData=pTemp; } if (ListData) { ListData[FileCount] = new FileListItem; string TwoDotsOwner; if (ReadOwners) { GetFileOwner(strComputerName,strCurDir,TwoDotsOwner); } FILETIME TwoDotsTimes[4]={}; if(apiGetFindDataEx(strCurDir,fdata)) { TwoDotsTimes[0]=fdata.ftCreationTime; TwoDotsTimes[1]=fdata.ftLastAccessTime; TwoDotsTimes[2]=fdata.ftLastWriteTime; TwoDotsTimes[3]=fdata.ftChangeTime; } AddParentPoint(ListData[FileCount],FileCount,TwoDotsTimes,TwoDotsOwner); FileCount++; } } if (IsColumnDisplayed(DIZ_COLUMN)) ReadDiz(); if (NeedHighlight) { CtrlObject->HiFiles->GetHiColor(ListData, FileCount); } if (AnotherPanel->GetMode()==PLUGIN_PANEL) { HANDLE hAnotherPlugin=AnotherPanel->GetPluginHandle(); PluginPanelItem *PanelData=nullptr; string strPath; size_t PanelCount=0; strPath = strCurDir; AddEndSlash(strPath); if (CtrlObject->Plugins->GetVirtualFindData(hAnotherPlugin,&PanelData,&PanelCount,strPath)) { FileListItem **pTemp; if ((pTemp=(FileListItem **)xf_realloc(ListData,(FileCount+PanelCount)*sizeof(*ListData)))) { ListData=pTemp; for (size_t i=0; i < PanelCount; i++) { CurPtr = ListData[FileCount+i]; PluginPanelItem &pfdata=PanelData[i]; PluginToFileListItem(&PanelData[i],CurPtr); CurPtr->Position=FileCount; TotalFileSize += pfdata.FileSize; CurPtr->PrevSelected=CurPtr->Selected=0; CurPtr->ShowFolderSize=0; CurPtr->SortGroup=CtrlObject->HiFiles->GetGroup(CurPtr); if (!TestParentFolderName(pfdata.FileName) && !(CurPtr->FileAttr & FILE_ATTRIBUTE_DIRECTORY)) TotalFileCount++; } // цветовую боевую раскраску в самом конце, за один раз CtrlObject->HiFiles->GetHiColor(&ListData[FileCount],PanelCount); FileCount+=static_cast<int>(PanelCount); } CtrlObject->Plugins->FreeVirtualFindData(hAnotherPlugin,PanelData,PanelCount); } } InitFSWatcher(false); CorrectPosition(); if (KeepSelection || PrevSelFileCount>0) { MoveSelection(ListData,FileCount,OldData,OldFileCount); DeleteListData(OldData,OldFileCount); } if (SortGroups) ReadSortGroups(false); if (!KeepSelection && PrevSelFileCount>0) { SaveSelection(); ClearSelection(); } SortFileList(FALSE); if (CurFile>=FileCount || StrCmpI(ListData[CurFile]->strName,strCurName)) if (!GoToFile(strCurName) && !strNextCurName.IsEmpty()) GoToFile(strNextCurName); /* $ 13.02.2002 DJ SetTitle() - только если мы текущий фрейм! */ if (CtrlObject->Cp() == FrameManager->GetCurrentFrame()) SetTitle(); FarChDir(strSaveDir); //??? }
void FileList::ReadFileNames(int KeepSelection, int UpdateEvenIfPanelInvisible, int DrawMessage) { SCOPED_ACTION(TPreRedrawFuncGuard)(std::make_unique<FileListPreRedrawItem>()); SCOPED_ACTION(TaskBar)(false); strOriginalCurDir = strCurDir; if (!IsVisible() && !UpdateEvenIfPanelInvisible) { UpdateRequired=TRUE; UpdateRequiredMode=KeepSelection; return; } UpdateRequired=FALSE; AccessTimeUpdateRequired=FALSE; DizRead=FALSE; api::FAR_FIND_DATA fdata; decltype(ListData) OldData; string strCurName, strNextCurName; StopFSWatcher(); if (this!=Global->CtrlObject->Cp()->LeftPanel && this!=Global->CtrlObject->Cp()->RightPanel) return; string strSaveDir; api::GetCurrentDirectory(strSaveDir); { string strOldCurDir(strCurDir); if (!SetCurPath()) { FlushInputBuffer(); // Очистим буффер ввода, т.к. мы уже можем быть в другом месте... if (strCurDir == strOldCurDir) //?? i?? { GetPathRoot(strOldCurDir,strOldCurDir); if (!api::IsDiskInDrive(strOldCurDir)) IfGoHome(strOldCurDir.front()); /* При смене каталога путь не изменился */ } return; } } SortGroupsRead=FALSE; if (GetFocus()) Global->CtrlObject->CmdLine->SetCurDir(strCurDir); LastCurFile=-1; Panel *AnotherPanel=Global->CtrlObject->Cp()->GetAnotherPanel(this); AnotherPanel->QViewDelTempName(); size_t PrevSelFileCount=SelFileCount; SelFileCount=0; SelFileSize=0; TotalFileCount=0; TotalFileSize=0; CacheSelIndex=-1; CacheSelClearIndex=-1; FreeDiskSize = -1; if (Global->Opt->ShowPanelFree) { api::GetDiskSize(strCurDir, nullptr, nullptr, &FreeDiskSize); } if (!ListData.empty()) { strCurName = ListData[CurFile].strName; if (ListData[CurFile].Selected && !ReturnCurrentFile) { for (size_t i=CurFile+1; i < ListData.size(); i++) { if (!ListData[i].Selected) { strNextCurName = ListData[i].strName; break; } } } } if (KeepSelection || PrevSelFileCount>0) { OldData.swap(ListData); } else DeleteListData(ListData); DWORD FileSystemFlags = 0; string PathRoot; GetPathRoot(strCurDir, PathRoot); api::GetVolumeInformation(PathRoot, nullptr, nullptr, nullptr, &FileSystemFlags, nullptr); ListData.clear(); bool ReadOwners = IsColumnDisplayed(OWNER_COLUMN); bool ReadNumLinks = IsColumnDisplayed(NUMLINK_COLUMN); bool ReadNumStreams = IsColumnDisplayed(NUMSTREAMS_COLUMN); bool ReadStreamsSize = IsColumnDisplayed(STREAMSSIZE_COLUMN); if (!(FileSystemFlags&FILE_SUPPORTS_HARD_LINKS) && IsWindows7OrGreater()) { ReadNumLinks = false; } if(!(FileSystemFlags&FILE_NAMED_STREAMS)) { ReadNumStreams = false; ReadStreamsSize = false; } string strComputerName; if (ReadOwners) { string strTemp; CurPath2ComputerName(strCurDir, strComputerName, strTemp); } SetLastError(ERROR_SUCCESS); // сформируем заголовок вне цикла string Title = MakeSeparator(X2-X1-1, 9, nullptr); BOOL IsShowTitle=FALSE; BOOL NeedHighlight=Global->Opt->Highlight && PanelMode != PLUGIN_PANEL; if (!Filter) Filter = std::make_unique<FileFilter>(this,FFT_PANEL); //Рефреш текущему времени для фильтра перед началом операции Filter->UpdateCurrentTime(); Global->CtrlObject->HiFiles->UpdateCurrentTime(); bool bCurDirRoot = false; ParsePath(strCurDir, nullptr, &bCurDirRoot); PATH_TYPE Type = ParsePath(strCurDir, nullptr, &bCurDirRoot); bool NetRoot = bCurDirRoot && (Type == PATH_REMOTE || Type == PATH_REMOTEUNC); string strFind(strCurDir); AddEndSlash(strFind); strFind+=L'*'; api::FindFile Find(strFind, true); DWORD FindErrorCode = ERROR_SUCCESS; bool UseFilter=Filter->IsEnabledOnPanel(); bool ReadCustomData=IsColumnDisplayed(CUSTOM_COLUMN0)!=0; DWORD StartTime = GetTickCount(); std::all_of(CONST_RANGE(Find, fdata) -> bool { Global->CatchError(); FindErrorCode = Global->CaughtError(); if ((Global->Opt->ShowHidden || !(fdata.dwFileAttributes & (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM))) && (!UseFilter || Filter->FileInFilter(fdata, nullptr, &fdata.strFileName))) { if (ListData.size() == ListData.capacity()) ListData.reserve(ListData.size() + 4096); ListData.emplace_back(VALUE_TYPE(ListData)()); auto& NewItem = ListData.back(); NewItem.FileAttr = fdata.dwFileAttributes; NewItem.CreationTime = fdata.ftCreationTime; NewItem.AccessTime = fdata.ftLastAccessTime; NewItem.WriteTime = fdata.ftLastWriteTime; NewItem.ChangeTime = fdata.ftChangeTime; NewItem.FileSize = fdata.nFileSize; NewItem.AllocationSize = fdata.nAllocationSize; NewItem.strName = fdata.strFileName; NewItem.strShortName = fdata.strAlternateFileName; NewItem.Position = ListData.size() - 1; NewItem.NumberOfLinks=1; if (fdata.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { NewItem.ReparseTag=fdata.dwReserved0; //MSDN } if (!(fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { TotalFileSize += NewItem.FileSize; if (ReadNumLinks) NewItem.NumberOfLinks = GetNumberOfLinks(fdata.strFileName, true); } else { NewItem.AllocationSize = 0; } NewItem.SortGroup=DEFAULT_SORT_GROUP; if (ReadOwners) { string strOwner; GetFileOwner(strComputerName, NewItem.strName,strOwner); NewItem.strOwner = strOwner; } NewItem.NumberOfStreams=NewItem.FileAttr&FILE_ATTRIBUTE_DIRECTORY?0:1; NewItem.StreamsSize=NewItem.FileSize; if (ReadNumStreams||ReadStreamsSize) { EnumStreams(TestParentFolderName(fdata.strFileName)? strCurDir : fdata.strFileName, NewItem.StreamsSize, NewItem.NumberOfStreams); } if (ReadCustomData) NewItem.strCustomData = Global->CtrlObject->Plugins->GetCustomData(NewItem.strName); if (!(fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) TotalFileCount++; DWORD CurTime = GetTickCount(); if (CurTime - StartTime > (DWORD)Global->Opt->RedrawTimeout) { StartTime = CurTime; if (IsVisible()) { if (!IsShowTitle) { if (!DrawMessage) { Text(X1+1,Y1,ColorIndexToColor(COL_PANELBOX),Title); IsShowTitle=TRUE; SetColor(Focus ? COL_PANELSELECTEDTITLE:COL_PANELTITLE); } } LangString strReadMsg(MReadingFiles); strReadMsg << ListData.size(); if (DrawMessage) { ReadFileNamesMsg(strReadMsg); } else { TruncStr(strReadMsg,static_cast<int>(Title.size())-2); int MsgLength=(int)strReadMsg.size(); GotoXY(X1+1+(static_cast<int>(Title.size())-MsgLength-1)/2,Y1); Global->FS << L" "<<strReadMsg<<L" "; } } Global->CtrlObject->Macro.SuspendMacros(true); bool check = CheckForEsc(); Global->CtrlObject->Macro.SuspendMacros(false); if (check) { // break loop return false; } } } return true; });