C++ 获取连接的目标路径似乎总是以“错误5拒绝访问”结束

C++ 获取连接的目标路径似乎总是以“错误5拒绝访问”结束,c++,winapi,reparsepoint,C++,Winapi,Reparsepoint,我有一个项目,我必须达到一个路口的目标。这是我想出的一些代码: #include "stdafx.h" #include <iostream> #include <Windows.h> #define BUFSIZE MAX_PATH using namespace std; int main() { TCHAR Path[BUFSIZE]; DWORD dwRet; HANDLE hFile; hFile = CreateFile(L"C:\\Users\\T

我有一个项目,我必须达到一个路口的目标。这是我想出的一些代码:

#include "stdafx.h"
#include <iostream>
#include <Windows.h>

#define BUFSIZE MAX_PATH

using namespace std;


int main()
{
TCHAR Path[BUFSIZE];
DWORD dwRet;
HANDLE hFile;

hFile = CreateFile(L"C:\\Users\\Test\\Documents\\My Videos",
    GENERIC_READ,
    FILE_SHARE_READ,
    0,
    OPEN_EXISTING,
    FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT,
    0);

if (hFile == INVALID_HANDLE_VALUE)
{
    printf("Could not open file (error %d)\n", GetLastError());
    return 0;
}
dwRet = GetFinalPathNameByHandle(hFile, Path, BUFSIZE, VOLUME_NAME_DOS);
if (dwRet < BUFSIZE)
{
    _tprintf(TEXT("\nThe final path is: %s\n"), Path);
}


CloseHandle(hFile);

//wcout << Path;

return 0;
}

现在,奇怪的是,除了连接/重分析点Documents\My Videos之外,代码很好地返回了每个目录的GetFinalPathNameByHandle。对于连接,它抛出一个错误5和GetLastError。有人知道是什么导致了这一切吗?

我已经追根究底了。首先,在任何C++ API打开文件系统对象的句柄之前,必须先进行ToWang/FC:\用户\测试\文档\ MyVist/R/D Y。p> 编辑2:

对于将来读到这篇文章的人。上面的代码可以工作,但只有在接合点上使用takeown命令时才能工作。在使用takeown之前,标准Windows连接上有一个Everyone:DENYS,RD策略,该策略拒绝所有用户的读取访问。接管后,该策略将消失,并且该连接也可在Windows资源管理器中使用

<>编辑:这是C++中的工作解决方案,不使用Sub命令:


此代码的产品是C:\users\test\Documents\My Music的目标路径

您确定在调用GetFinalPathNameByHandle时出错,但在调用CreateFile时没有出错吗?对我的音乐说,你没有错吗?不要用泛读;没必要。连接具有拒绝读取列表目录访问的ACE。@eryksun-yes。这是真的。拒绝为每个人阅读。如果我们没有备份权限,CreateFile将失败。但是CreateFile是fail,而不是GetFinalPathNameByHandle,它接受具有任何访问权限的文件句柄。如果您想要连接的最终解析路径,您不应该使用文件标志、打开、重新分析点。仅当需要打开重分析点并使用带有FSCTL_GET_repasse_point的DeviceIoControl读取其直接目标时,才使用该标志。感谢您的评论。我或多或少地解决了这个问题。所以确切地说是CreateFile返回错误,而不是GetFinalPathNameByHandle。要解决此问题,您需要或启用SE_BACKUP_特权(如果您有或没有请求文件列表目录访问)。和确定-您是否需要打开重分析点或it目标管理员、系统和测试对该连接具有完全访问权限-DACL中的一个条目拒绝每个人S-1-1-0读取目录列表的权利。拥有所有权并不能解决这个问题。您需要不请求访问,CreateFile将请求Windows API同步和读取属性的最小值。这就足够了访问权限—无论您是调用GetFinalPathNameByHandle来获取最终解析的路径—在这种情况下,都不要打开重新分析点,也不要调用DeviceIoControl来读取连接的直接目标。如果您不是管理员或以测试身份运行,那么很明显,您根本无权访问测试的用户配置文件。更改文件和目录的所有者不是答案。以管理员身份运行您的程序,并仅请求所需的最低访问权限。另外,检查icacls我的视频,查看交叉口上是否存在拒绝读取访问的ACE。它应该存在,但可能有人修改了安全性。请求无所需访问0以使CreateFile请求具有其允许的最小访问权限,该权限始终包括同步和读取属性的权限。如果您可以列出父目录,则会隐式授予您读取属性的权限,但父目录中的任何内容都不会隐式授予您同步的权限。也就是说,如果您没有这两个权限,作为管理员,您可以通过启用SeBackupPrivilege并请求备份语义来获得它们。您已经请求后者能够打开一个目录。仅供参考,您忘记了@notify me.GetFinalPathNameByHandle返回最终解析的路径,而不管CreateFile调用必须遍历多少重分析点。另一方面,打开重分析点本身并查询FSCTL_GET_repasse_point文件系统控制代码,可以读取立即替换路径,该路径不必是可访问的,甚至不存在。
#define BUFSIZE MAX_PATH

using namespace std;

int main()
{
TCHAR Path[BUFSIZE];
DWORD dwRet;
HANDLE hFile;

hFile = CreateFile(L"C:\\Users\\Test\\Documents\\My Music",
    0,
    0,
    0,
    OPEN_EXISTING,
    FILE_FLAG_BACKUP_SEMANTICS,
    0);

if (hFile == INVALID_HANDLE_VALUE)
{
    printf("Could not open file (error %d)\n", GetLastError());
    return 0;
}
dwRet = GetFinalPathNameByHandle(hFile, Path, BUFSIZE, VOLUME_NAME_DOS);
if (dwRet < BUFSIZE)
{
    _tprintf(TEXT("\nThe final path is: %s\n"), Path);
}

CloseHandle(hFile);

return 0;
}