下面的程序还有一些问题,比如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;
}

posted on 2024-02-15 14:26  北京开发  阅读(27)  评论(0编辑  收藏  举报