Rumah > Soal Jawab > teks badan
功能:遍历指定目录(c:\windows\system32)下的所有文件夹,找出所有exe类型的文件
上代码
/*遍历文件夹,得到所有exe文件*/
void getFiles(string path, string exd, vector<WIN32_FIND_DATA>& files)
{
/************************************************************************/
/* 获取文件夹下所有文件名
输入:
path : 文件夹路径
exd : 所要获取的文件名后缀,如jpg、png等;
文件名, exd = ""
输出:
files : 获取的文件名列表
*/
/************************************************************************/
BOOL SetPrivilege(HANDLE hToken, LPCTSTR lpszPrivilege, BOOL bEnablePrivilege);
//文件句柄
HANDLE hFile = INVALID_HANDLE_VALUE,hExe = INVALID_HANDLE_VALUE;
//文件信息
WIN32_FIND_DATA fileinfo,exeinfo;
string pathName, exdName;
// 有无类型要求
if (0 != strcmp(exd.c_str(), ""))
{
exdName = "\\*." + exd;
}
else
{
exdName = "\\*";
}
PVOID OldValue = NULL;
// 关闭系统重定向
if (Wow64DisableWow64FsRedirection(&OldValue))
{
// 查找指定路径
hFile = FindFirstFile(pathName.assign(path).append(exdName).c_str(), &fileinfo);
if (FALSE == Wow64RevertWow64FsRedirection(OldValue))
{
return;
}
}
// 查找指定路径
// hFile = FindFirstFile(pathName.assign(path).append(exdName).c_str(), &fileinfo);
// 是否查找失败
if (hFile == INVALID_HANDLE_VALUE)
{
// 是否因为权限不足,若不足,则提升权限
if (GetLastError() == 5)
{
HANDLE hToken;
BOOL bRet = OpenProcessToken(
GetCurrentProcess(), // 进程句柄(当前进程)
TOKEN_ALL_ACCESS, // 全权访问令牌
&hToken // 返回的参数 进程令牌句柄 (就是AdjustTokenPrivileges的第一个参数)
); // 获取进程的令牌句柄
if (bRet != TRUE)
{
cout << "获取令牌句柄失败!" << endl;
return;
}
BOOL set = SetPrivilege(hToken, SE_DEBUG_NAME, TRUE);
if (!set || GetLastError() != ERROR_SUCCESS) {
// 设置权限失败
cout << "提升权限失败 error:" << GetLastError() << endl;
cout << "此文件夹缺少权限访问: " << pathName.assign(path).append("\\").c_str() << endl;
return;
}
// 权限设置成功,继续执行
hFile = FindFirstFile(pathName.assign(path).append(exdName).c_str(), &fileinfo);
cout << "权限设置完成" << endl;
cout << GetLastError()<<endl;
}
else
{
// 不是权限问题
cout << "FindFirstFile failed " << GetLastError() << endl;
system("pause");
return;
}
}
int flag = MY_NOT_CHECK;
int lastError = 0;
// 遍历
do
{
//如果是文件夹,迭代之
if ((fileinfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
{
if (strcmp(fileinfo.cFileName, ".") != 0 && strcmp(fileinfo.cFileName, "..") != 0)
getFiles(pathName.assign(path).append("\\").append(fileinfo.cFileName), exd, files);
}
else
{
//如果不是文件夹
/*
if (strcmp(fileinfo.cFileName, ".") != 0 && strcmp(fileinfo.cFileName, "..") != 0)
{
for (int i = 0; fileinfo.cFileName[i + 3] != '\0'; i++)
{
// 判断是否exe
if (fileinfo.cFileName[i] == '.'
&& (fileinfo.cFileName[i + 1] == 'e' || fileinfo.cFileName[i + 1] == 'E')
&& (fileinfo.cFileName[i + 2] == 'x' || fileinfo.cFileName[i + 2] == 'X')
&& (fileinfo.cFileName[i + 1] == 'e' || fileinfo.cFileName[i + 1] == 'E')
&& fileinfo.cFileName[i + 4] == '\0')
{
files.push_back(fileinfo);
break;
}
}
}
*/
// 如果当前目录还未查找过,查找当前目录的exe文件
if (flag)
{
// 关闭系统重定向
if (Wow64DisableWow64FsRedirection(&OldValue))
{
// 查找指定路径
hExe = FindFirstFile(pathName.assign(path).append("\\*.exe").c_str(), &exeinfo);
if (FALSE == Wow64RevertWow64FsRedirection(OldValue))
{
return;
}
}
// hExe = FindFirstFile(pathName.assign(path).append("\\*.exe").c_str(), &exeinfo);
if (hExe == INVALID_HANDLE_VALUE)
{
lastError = GetLastError();
if (lastError == 2)
{
//cout << setiosflags(ios::left) << setw(50) << path << " 此目录下没有exe " << endl;
}
else
{
cout << " 查找exe失败 " << lastError << endl;
return;
}
}
// 遍历所有本文件夹下的exe文件
if (lastError != 2)
{
do
{
files.push_back(exeinfo);
} while (FindNextFile(hExe, &exeinfo));
// 查找完成,此目录已不用遍历,跳出
flag = MY_CHECKED;
FindClose(hExe);
}
}
}
} while (FindNextFile(hFile, &fileinfo));
FindClose(hFile);
return;
}
在遍历的过程中,遇到某些文件夹无法打开,getlasterror提示5(拒绝访问),在其他盘正常,所以我猜测是因为c盘的某些文件夹需要权限访问,去网上搜索,使用了这个提高进程权限的方法SetPrivilege()
:
// 使用这组函数提升权限的前提是进程具备该权限,只是访问令牌中没有启用该权限。
// 如果进程的访问令牌中本身就没有关联该权限,这AdjustTokenPrivileges函数调用
// 将会返回ERROR_NOT_ALL_ASSIGNED(值为1300L)的错误码。
BOOL SetPrivilege(
HANDLE hToken, // 得到代表句柄 access token handle
LPCTSTR lpszPrivilege, // 要打开或关闭的权限名 name of privilege to enable/disable
BOOL bEnablePrivilege // 打开还是关闭权限 to enable or disable privilege
)
{
TOKEN_PRIVILEGES tp; // 该结构包含一个数组,数据组的每个项指明了权限的类型和要进行的操作
LUID luid;
// 查找
if (!LookupPrivilegeValue(
NULL, // 系统的名字,null,在本地系统上查找权限 lookup privilege on local system
lpszPrivilege, // 要找的权限名 privilege to lookup
&luid)) // 通过指针返回权限的LUID receives LUID of privilege
{
printf("LookupPrivilegeValue error: %u\n", GetLastError());
return FALSE;
}
tp.PrivilegeCount = 1; // 要修改的特权数目
tp.Privileges[0].Luid = luid; // 代表不同特权类型
if (bEnablePrivilege)
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
else
tp.Privileges[0].Attributes = 0;
// 调整访问令牌的权限 Enable the privilege or disable all privileges.
if (!AdjustTokenPrivileges(
hToken,// OpenProcessToken第三个指针参数传出的访问令牌的句柄
FALSE, // 是否禁用所有所有的特权
&tp, // 指明要修改的权限
sizeof(TOKEN_PRIVILEGES), // PreviousState的长度
(PTOKEN_PRIVILEGES)NULL, // 存放修改前的访问权限的信息,可空
(PDWORD)NULL)) // 实际PreviousState结构返回的大小
{
printf("AdjustTokenPrivileges error: %u\n", GetLastError());
return FALSE;
}
if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
{
printf("令牌没有这个权限 \n");
return FALSE;
}
return TRUE;
}
方法运行未报错,再次查询,打印getlasterror()的值,仍然是5,也就是说仍然拒绝访问。
请大牛提示下,我是哪里错误了?
或者如何正确的提高权限,让我能够访问权限受阻的文件夹
或者其他如何遍历c盘文件夹的方法
菜鸟感激不尽!
PHP中文网2017-04-17 13:06:25
找到答案了,在win64下,system32目录会重定向到SysWOW64,所以搜不到文件是因为我没有关闭重定向,至于c盘中的某些文件,的确是无法访问的,但是能够搜索到的文件就能够访问。
当程序权限不足时,自动就会询问你是否提升权限。
所以有的问题或许并不是你想的那样,理解错了会绕很大的弯子,尽量不要太过绝对。
PHPz2017-04-17 13:06:25
系统文件里面,管理员权限并不一定有用,还有另一个原因是这些文件的owner不是你,所以反正你是打不开的。
其中的一个例子是Windows 8.1锁屏画面的那张图,你会发现无论你怎么take ownership,都会失败,图片就是打不开。