首页 > 系统相关 >windows下c++遍历各个磁盘的所有文件,不知道为什么FindFirstFileA文件会报错,进而程序退出

windows下c++遍历各个磁盘的所有文件,不知道为什么FindFirstFileA文件会报错,进而程序退出

时间:2024-02-15 14:33:43浏览次数:27  
标签:std 文件 cout windows ATTRIBUTE 报错 FILE DWORD attr

下面的程序还有一些问题,比如360的一些目录就用FindFirstFileA函数打开错误;还有  C:\Windows\System32\WebThreatDefSvc  ,属性只有 DIRECTORY ,用 函数 _access 检查也没有问题,但是就是用FindFirstFileA打开的时候错误;至今没有想到解决办法,只能临时跳过这种目录。

 

#include <iostream>
#include <windows.h>
#include <strsafe.h>
#include <string>
#include <vector>
#include <stdio.h>
#include <aclapi.h>
#include <io.h>
#include <fileapi.h>
#include <winbase.h>

std::vector<std::string> v_files;


void ErrorExit(LPTSTR lpszFunction)
{
        // Retrieve the system error message for the last-error code

        LPVOID lpMsgBuf;
        LPVOID lpDisplayBuf;
        DWORD dw = GetLastError();

        FormatMessage(
                FORMAT_MESSAGE_ALLOCATE_BUFFER |
                FORMAT_MESSAGE_FROM_SYSTEM |
                FORMAT_MESSAGE_IGNORE_INSERTS,
                NULL,
                dw,
                MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                (LPTSTR)&lpMsgBuf,
        0, NULL);

        // Display the error message and exit the process

        lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
                (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR));
        StringCchPrintf((LPTSTR)lpDisplayBuf,
                LocalSize(lpDisplayBuf) / sizeof(TCHAR),
                TEXT("%s failed with error %d: %s"),
        lpszFunction, dw, lpMsgBuf);
        MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK);

        LocalFree(lpMsgBuf);
        LocalFree(lpDisplayBuf);
        ExitProcess(dw);
   }

std::vector<std::string> printMasks(DWORD Mask)
{
        // This evaluation of the ACCESS_MASK is an example.
        // Applications should evaluate the ACCESS_MASK as necessary.
        std::vector<std::string> access;
        std::wcout << "Effective Allowed Access Mask : " << Mask << std::hex << std::endl;
        if (((Mask & GENERIC_ALL) == GENERIC_ALL)
                || ((Mask & FILE_ALL_ACCESS) == FILE_ALL_ACCESS))
        {
                // wprintf_s(L"Full Control\n");
                access.push_back("Full Control");
                // return access;
        }
        if (((Mask & GENERIC_READ) == GENERIC_READ)
                || ((Mask & FILE_GENERIC_READ) == FILE_GENERIC_READ))
                // wprintf_s(L"Read\n");
                access.push_back("Read");
        if (((Mask & GENERIC_WRITE) == GENERIC_WRITE)
                || ((Mask & FILE_GENERIC_WRITE) == FILE_GENERIC_WRITE))

        access.push_back("Write");
        if (((Mask & GENERIC_EXECUTE) == GENERIC_EXECUTE)
                || ((Mask & FILE_GENERIC_EXECUTE) == FILE_GENERIC_EXECUTE))
        access.push_back("Execute");

        return access;
}

bool CanAccessFolder(LPCSTR folderName, DWORD genericAccessRights, DWORD& grantedRights)
{
        bool bRet = false;
        DWORD length = 0;
        if (!::GetFileSecurityA(folderName, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION
                | DACL_SECURITY_INFORMATION, NULL, NULL, &length) &&
                ERROR_INSUFFICIENT_BUFFER == ::GetLastError()) {
                PSECURITY_DESCRIPTOR security = static_cast<PSECURITY_DESCRIPTOR>(::malloc(length));
                if (security && ::GetFileSecurityA(folderName, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION
                        | DACL_SECURITY_INFORMATION, security, length, &length)) {
                                HANDLE hToken = NULL;
                                if (::OpenProcessToken(::GetCurrentProcess(), TOKEN_IMPERSONATE | TOKEN_QUERY |
                                        TOKEN_DUPLICATE | STANDARD_RIGHTS_READ, &hToken)) {
                                                HANDLE hImpersonatedToken = NULL;
                                                if (::DuplicateToken(hToken, SecurityImpersonation, &hImpersonatedToken)) {
                                                        GENERIC_MAPPING mapping = { 0xFFFFFFFF };
                                                        PRIVILEGE_SET privileges = { 0 };
                                                        DWORD grantedAccess = 0, privilegesLength = sizeof(privileges);
                                                         BOOL result = FALSE;

                                                         mapping.GenericRead = FILE_GENERIC_READ;
                                                          mapping.GenericWrite = FILE_GENERIC_WRITE;
                                                        mapping.GenericExecute = FILE_GENERIC_EXECUTE;
                                                        mapping.GenericAll = FILE_ALL_ACCESS;

                                                        ::MapGenericMask(&genericAccessRights, &mapping);
                                                        if (::AccessCheck(security, hImpersonatedToken, genericAccessRights,
                                                                &mapping, &privileges, &privilegesLength, &grantedAccess, &result))
                                                        {
                                                                bRet = (result == TRUE);
                                                                 grantedRights = grantedAccess;
                                                        }
                                                        ::CloseHandle(hImpersonatedToken);
                                               }
                                                ::CloseHandle(hToken);
                                        }
                                        ::free(security);
                                }
                        }

                        return bRet;
        }

BOOL CheckFileReadAccess(char* filePath)
{
                DWORD result = FALSE;
        BOOL bret = FALSE;
        DWORD infoLen = 0;
        std::string wuname = "CURRENT_USER";
        std::cout << " in CheckFileReadAccess file:" << filePath << std::endl
        
        PSECURITY_DESCRIPTOR pSD = NULL;
        if (!GetFileSecurityA(filePath, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, NULL, 0, &infoLen)&& ERROR_INSUFFICIENT_BUFFER == ::GetLastError())
        {
                std::cout << "infoLen:" << infoLen << std::endl;
                pSD = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, infoLen /*dwSizeNeeded*/);
                if (pSD && GetFileSecurityA(filePath, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, pSD, infoLen /*dwSizeNeeded*/, &result))
                {
                
                        if (result <= infoLen)
                        {
                        
                                EXPLICIT_ACCESS_A ea;
                                ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
                                ea.grfAccessPermissions = GENERIC_READ;
                                ea.grfAccessMode = SET_ACCESS;
                                ea.grfInheritance = NO_INHERITANCE;
                                ea.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
                                ea.Trustee.TrusteeType = TRUSTEE_IS_USER;
                                ea.Trustee.ptstrName = (char *)wuname.c_str(); // 这里检查当前用户的权限,你可以根据需要更改

                                BOOL lpbDaclPresent;
                                PACL pOldDACL = NULL;
                                BOOL csdResult = FALSE;
                                PACL pNewDACL = NULL;
                                if (GetSecurityDescriptorDacl(pSD, &lpbDaclPresent, &pOldDACL , &csdResult))
                                {
                
                                        if (SetEntriesInAclA(1, &ea, pOldDACL, &pNewDACL))
                                        {
                                                std::cout << __LINE__ << std::endl;

                                                GENERIC_MAPPING genericMapping;
                                                genericMapping.GenericRead = FILE_GENERIC_READ;
                                                 genericMapping.GenericWrite = FILE_GENERIC_WRITE;
                                                genericMapping.GenericExecute = FILE_GENERIC_EXECUTE;
                                                 genericMapping.GenericAll = FILE_ALL_ACCESS;
                                                PPRIVILEGE_SET pset = {0};
                                                DWORD dwPrivSetSize = sizeof(PRIVILEGE_SET);
                                                DWORD pdwAccessAllowed;
                                                BOOL fAccessGranted = FALSE;
                                                std::cout << " GetSecurityDescriptorDacl Ok, before AccessCheck" << std::endl;
                                                if (AccessCheck(pSD, &ea.Trustee, GENERIC_READ, &genericMapping, pset, &dwPrivSetSize, &pdwAccessAllowed, &fAccessGranted))    {

                                                        if ((fAccessGranted & GENERIC_READ) == GENERIC_READ)
                                                         {

                                                                        bret = TRUE; // 用户有读取权限
                                                          }
                                                }
                                                LocalFree(pNewDACL);
                                        }   else {
                                                std::wstring wstr = L"SetEntriesInAclA";
                                                ErrorExit((wchar_t *)wstr.c_str());
                                                 std::cout << "Err when SetEntriesInAclA" << std::endl;
                                        }
                                }                  else {
                                        std::wstring wstr = L"GetSecurityDescriptorDacl";
                                        ErrorExit((wchar_t*)wstr.c_str());
                                        std::cout << "err when GetSecurityDescriptorDacl" << std::endl;
                        }
                }               else {
                        std::wstring wstr = L"GetFileSecurityA";
                        ErrorExit((wchar_t*)wstr.c_str());
                        std::cout << "err when GetFileSecurityA" << std::endl;
                }

        }
        LocalFree(pSD);
}
else {
std::cout << "Err when GetFileSecurityA" << std::endl;
}
// CloseHandle(hFile);
//}
//else {
// std::cout << "Err when CreateFileA" << std::endl;
//}
return bret;
}

int wstr2mstr(std::wstring &wstr, std::string& mstr)
{

size_t wlen = wstr.length();
if (wlen == 0)
{
std::cout << "wstr len is zero " << std::endl;
return 0;
}
int mlen = WideCharToMultiByte(CP_UTF8, 0, (const wchar_t*)wstr.c_str(),(int) wlen, NULL, 0, NULL, NULL);
std::cout << "mlen+" << mlen << std::endl;
char* buf = (char*)malloc(mlen * sizeof(char) + 1);

if (buf == NULL)
{
std::cout << "malloc err" << std::endl;
return 0;
}
memset(buf, 0, mlen * sizeof(char) + 1);
int result = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), wlen, buf, mlen, NULL, NULL);
mstr = buf;
free(buf);
std::cout << "wstr to str len is :" << mlen << " driv:" << mstr << std::endl;
return mlen;
}


int printAttr(DWORD attr)
{
std::cout << "attr: " << attr << " ATTR START:"; // << std::endl;
if (attr & FILE_ATTRIBUTE_READONLY)
std::cout << " READONLY"; // << std::endl;
if (attr & FILE_ATTRIBUTE_HIDDEN)
std::cout << " HIDDEN"; // << std::endl;
if (attr & FILE_ATTRIBUTE_SYSTEM)
std::cout << " SYSTEM"; // << std::endl;
if (attr & FILE_ATTRIBUTE_DIRECTORY)
std::cout << " DIRECTORY"; // << std::endl;
if (attr & FILE_ATTRIBUTE_ARCHIVE)
std::cout << " ARCHIVE"; // << std::endl;
if (attr & FILE_ATTRIBUTE_DEVICE)
std::cout << " DEVICE"; // << std::endl;
if (attr & FILE_ATTRIBUTE_NORMAL)
std::cout << " NORMAL"; // << std::endl;
if (attr & FILE_ATTRIBUTE_TEMPORARY)
std::cout << " TEMPORARY";// << std::endl;
if (attr & FILE_ATTRIBUTE_SPARSE_FILE)
std::cout << " SPARSE_FILE"; // << std::endl;
if (attr & FILE_ATTRIBUTE_REPARSE_POINT)
std::cout << " REPARSE_POINT"; // << std::endl;
if (attr & FILE_ATTRIBUTE_COMPRESSED)
std::cout << " COMPRESSED"; // << std::endl;
if (attr & FILE_ATTRIBUTE_OFFLINE)
std::cout << " OFFLINE"; // << std::endl;
if (attr & FILE_ATTRIBUTE_NOT_CONTENT_INDEXED)
std::cout << " NOT_CONTENT_INDEXED"; // << std::endl;
if (attr & FILE_ATTRIBUTE_ENCRYPTED)
std::cout << " ENCRYPTED"; // << std::endl;
if (attr & FILE_ATTRIBUTE_INTEGRITY_STREAM)
std::cout << " INTEGRITY_STREAM"; // << std::endl;
if (attr & FILE_ATTRIBUTE_VIRTUAL)
std::cout << " VIRTUAL"; // << std::endl;
if (attr & FILE_ATTRIBUTE_NO_SCRUB_DATA)
std::cout << " NO_SCRUB_DATA"; // << std::endl;
if (attr & FILE_ATTRIBUTE_EA)
std::cout << " EA"; // << std::endl;
if (attr & FILE_ATTRIBUTE_PINNED)
std::cout << " PINNED"; // << std::endl;
if (attr & FILE_ATTRIBUTE_UNPINNED)
std::cout << " UNPINNED"; // << std::endl;
if (attr & FILE_ATTRIBUTE_RECALL_ON_OPEN)
std::cout << " RECALL_ON_OPEN"; // << std::endl;
if (attr & FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS)
std::cout << " ON_DATA_ACCESS"; // << std::endl;
std::cout << ": ATTR End " << std::endl;

return 1;
}

int notProcessfiles(DWORD attr)
{
DWORD rdonlyFile;
DWORD hiddenFile;
DWORD systemFile;
//DWORD archFile;
DWORD tmpFile;
DWORD offlineFile;
DWORD encryFile;
DWORD virtFile;
DWORD eaFile;
DWORD pinnedFile;
DWORD unpinedFile;
DWORD recallOpenFile;
DWORD recallAcceFile;
DWORD deviceFile;
DWORD sumAttr = 0;
DWORD notIndexed = 0;

rdonlyFile = attr & FILE_ATTRIBUTE_READONLY;
hiddenFile = attr & FILE_ATTRIBUTE_HIDDEN;
systemFile = attr & FILE_ATTRIBUTE_SYSTEM;
//archFile = attr & FILE_ATTRIBUTE_ARCHIVE;
tmpFile = attr & FILE_ATTRIBUTE_TEMPORARY;
offlineFile = attr & FILE_ATTRIBUTE_OFFLINE;
encryFile = attr & FILE_ATTRIBUTE_ENCRYPTED;
virtFile = attr & FILE_ATTRIBUTE_VIRTUAL;
eaFile = attr & FILE_ATTRIBUTE_EA;
pinnedFile = attr & FILE_ATTRIBUTE_PINNED;
unpinedFile = attr & FILE_ATTRIBUTE_UNPINNED;
recallOpenFile = attr & FILE_ATTRIBUTE_RECALL_ON_OPEN;
recallAcceFile = attr & FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS;
deviceFile = attr & FILE_ATTRIBUTE_DEVICE;
notIndexed = attr & FILE_ATTRIBUTE_NOT_CONTENT_INDEXED;

sumAttr = rdonlyFile | systemFile | tmpFile | offlineFile | encryFile | virtFile | eaFile | pinnedFile | unpinedFile | recallOpenFile | recallAcceFile | deviceFile | notIndexed | hiddenFile;
printAttr(attr);
return sumAttr;

}

std::vector<std::string> gv_skip_dirs={"RtBackup","WebThreatDefSvc"};

BOOL isSkipDirs(std::string dir)
{
for (auto it : gv_skip_dirs)
{
if (it == dir)
{
return TRUE;
}
}
return FALSE;
}

//unsigned long long generail_file =
void ListFilesRecursively(const std::string path, const std::string& searchPattern = "*")
{
WIN32_FIND_DATAA findData;
HANDLE hFind;
std::cout << __LINE__ << std::endl;
std::string searchPath = path + "\\" + searchPattern;
//不检查诸如 c: d: 这样的盘符
if (path[path.length() - 1] != ':')
{
//BOOL bret = CheckFileReadAccess((char*)path.c_str());
/* DWORD access_mask = FILE_GENERIC_READ | FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE | FILE_ALL_ACCESS;
DWORD grant = 0;
BOOL bret = CanAccessFolder((char *)path.c_str(), access_mask, grant);
std::cout << path << "; access right:" << bret << std::endl;
*/
if (_access(path.c_str(), 6) != 0)
{
std::cout << path << ", cannot access" << std::endl;
return;
}
else {
std::cout << path << ", CAN access" << std::endl;
}
}

DWORD dwAttr = GetFileAttributesA(path.c_str());
std::cout << path << "; dwAttr:" << dwAttr << std::endl;
if (notProcessfiles(dwAttr) != 0)
{
std::cout << "Skip directory: " << path << std::endl;
return;
}
hFind = FindFirstFileA((char *)searchPath.c_str(), &findData);
std::cout << searchPath << ", hFind :" << hFind << "; dwAttr:" << dwAttr << std::endl;
if (hFind != INVALID_HANDLE_VALUE)
{
std::cout << __LINE__ << std::endl;
do
{
std::string wFullPathName = findData.cFileName;
if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
if(wFullPathName != "." && wFullPathName != ".." && !isSkipDirs(findData.cFileName))
{
std::string newPath = path + "\\" + std::string(findData.cFileName);
std::string mstrNewPath;

if (1 /*mlen > 0*/)
{
std::cout << "dir:" << newPath << std::endl;
//if (notProcessfiles(findData.dwFileAttributes) == 0)
if (_access(newPath.c_str(), 6) == 0)
{
std::cout << __LINE__ << std::endl;
ListFilesRecursively(newPath);
std::cout << __LINE__ << std::endl;
}
else
{
std::cout << "Cannot access for path" << std::endl;
}
}
}
} else {
std::string newFilePath = path + "\\" + std::string(findData.cFileName);

if(1)
{
std::cout << "FILE: " << newFilePath << "; Attr:" << findData.dwFileAttributes << std::endl;
if (notProcessfiles(findData.dwFileAttributes) == 0)
{
std::cout << "Gather FILE: " << newFilePath << std::endl;
v_files.push_back(newFilePath);
}
else {
std::cout << "Skip FILE: " << newFilePath << std::endl;
}
}
}
} while (FindNextFileA(hFind, &findData));

FindClose(hFind);
std::wcout << __LINE__ << std::endl;
}
else {

std::wstring wstr = L"ListFilesRecursivelyW";
//ErrorExit((wchar_t *)wstr.c_str());
}
std::wcout << __LINE__ << std::endl;
}

int main() {
// 获取所有磁盘的驱动器字母
DWORD bufferSize = GetLogicalDriveStringsW(0, nullptr);
std::vector<wchar_t> buffer(bufferSize);
GetLogicalDriveStringsW(bufferSize, buffer.data());

std::wstring drives(buffer.begin(), buffer.end());
size_t pos = 0;
std::wstring drive;
std::string mdrive;
PVOID OldValue = NULL;
if (1 /* Wow64DisableWow64FsRedirection(&OldValue)*/ )
{
// 遍历所有磁盘,并列出文件
while ((pos = drives.find(L'\\', pos)) != std::wstring::npos) {
drive = drives.substr(0, pos);

Sleep(4);
mdrive.clear();
int len = wstr2mstr(drive, mdrive);
if (len > 0)
{
std::cout << "Harddisk drive:" << mdrive << std::endl;
ListFilesRecursively(mdrive);
}
else {
std::cout << "Error when Get Harddisk drive" << std::endl;
}
drives.erase(0, pos + 2);
}

// 处理最后一个驱动器(如果有的话)
if (!drives.empty())
{
ListFilesRecursively(mdrive);
}
//Wow64RevertWow64FsRedirection(OldValue);
}
else {
std::cout << "WoW64 Err" << std::endl;
}
return 0;
}

标签:std,文件,cout,windows,ATTRIBUTE,报错,FILE,DWORD,attr
From: https://www.cnblogs.com/yyybill/p/18016242

相关文章

  • c文件
    C语言调用另一个文件的方法当一个项目比较大之后,我们希望分模块管理,这个时候就需要把一部分方法放在独立的文件中。在main方法中如何引用这些文件呢?一、gcc比如我有一个function.c文件,里面包含了我的函数体#include"function.h"intadd(inta,intb){returna+b;}......
  • Python:处理大数据量文件心得
    --javascripttypescriptbashsqljsonhtmlcssccppjavarubypythongorustmarkdown完成大文件按规则拆解。使用python实现将5个多g,总共五千万行数据的csv文件进行按照某个特殊时属性进行拆解。问题难点:文件过大,服务器内存资源不足,需要分块读入内存并处理。之前想着......
  • Android 未root时 文件的selinux权限和日志查看办法
     getenforce 获取当前SELinux状态cas:/$getenforceEnforcingdmesg可以查看日志,但是没有root权限不能用,会显示cas:/$dmesgdmesg:klogctl:Permissiondeniedhttps://android.stackexchange.com/questions/218223/how-to-fix-dmesg-klogctl-permission-denied-for-nor......
  • 掌握C语言文件操作:从入门到精通的完整指南!
    ✨✨欢迎大家来到贝蒂大讲堂✨✨......
  • 关于extern和模块化编程全局变量、函数、对象不同源文件之间的使用说明
    extern的使用在C语言中,extern关键字用于在多个源文件之间声明全局变量、函数或对象,实现模块间的交互和数据共享。即告诉编译器该变量或函数是在其他源文件中定义的,并且可以在当前源文件中使用。而局部函数的作用域限定在其定义所在的作用域内,无法被其他源文件直接访问或调用。因......
  • ini文件
    windows.ini配置文件的用法为什么要使用ini文件避免重新编译如果我们程序没有任何配置文件时,这样的程序对外是全封闭的一旦程序需要修改一些参数必须要修改程序代码本身并重新编译,为了避免这样,所以要用配置文件灵活性程序出厂后还能根据需要进行必要的配置,还可以使用系统......
  • 第24天:安全开发-PHP应用&文件管理模块&显示上传&黑白名单类型过滤&访问控制
    #文件管理模块-上传-过滤机制1、无过滤机制2、黑名单过滤机制3、白名单过滤机制4、文件类型过滤机制 $_FILES:PHP中一个预定义的超全局变量,用于在上传文件时从客户端接收文件,并将其保存到服务器上。它是一个包含上传文件信息的数组,包括文件名、类型、大小、临时文件名等信息......
  • Linux 目录磁盘满了,怎么查找大文件
    在Linux系统中,如果你的根目录(/)磁盘满了,你可以使用以下方法来查找占用空间最大的文件和目录。使用du(磁盘使用)命令来查找占用空间最大的目录:sudodu-h/--max-depth=1|sort-h这个命令会列出根目录下每个一级子目录的大小,并通过sort命令进行排序,-h标志表示“人类可读”的......
  • 开源.NetCore通用工具库Xmtool使用连载 - OSS文件上传篇
    【Github源码】《上一篇》介绍了Xmtool工具库中的图像处理类库,今天我们继续为大家介绍其中的OSS文件上传类库。将本地文件上传到服务器是软件系统经常会遇到的需求,例如:设置用户头像,上传Excel报表等等;涉及到网络访问性能、存储空间等因素的考虑,通常我们会选择使用第三方的对象......
  • day06_文件管理操作练习
    作业解析关于[email protected]关于登录,退出登录1.登录的概念的第一种形式1.比如你登录系统[email protected]#退出该会话登录exit#退出登录2.第二种登录,如用于切换,root>yuchao01验证该用户是否存在系......