C语言 正在打开不匹配文件的目标符号链接

frebpwbc  于 2023-02-15  发布在  其他
关注(0)|答案(2)|浏览(156)

我看过一些相关的问题,但没有找到问题的确切解决方案...
不管怎样,我有一个无效的符号链接是这样的:

mklink link path/to/dir

这意味着我正在链接到一个目录**,而没有/D标志**。
但是,当我尝试使用WinApi CreateFile打开目标文件时失败了。我需要将符号链接作为文件还是作为目录打开?

CreateFile(path_to_link, 
0,
0,
NULL,
OPEN_EXISTING,
[*],
NULL)

当我在[*]指定目录时,函数失败(GetLastError()拒绝访问。我相信这是因为路径本身被配置为文件,因为我对所有相关文件都有有效权限)。
要处理path/to/dir,我需要在[*]处输入什么?
注:

  • 我必须处理这种mklink的无效使用
  • 我的最终目标是得到path/to/dir的绝对路径。如果有没有CreateFile的另一种方法,我很乐意听到它:)
xfyts7mz

xfyts7mz1#

正如注解中所解释的,它的行为类似于Shell Link。下面是解析目标路径的一种方法,它使用IShellItem2 COM接口和System.Link.TargetParsingPath属性。
C++版本:

#include <windows.h>
#include <stdio.h>
#include <shobjidl_core.h>
#include <Propkey.h>

int main()
{
  CoInitialize(NULL);
  {
    IShellItem2* item;
    if (SUCCEEDED(SHCreateItemFromParsingName(L"c:\\mypath\\link", NULL, IID_PPV_ARGS(&item))))
    {
      LPWSTR path = NULL;
      if (SUCCEEDED(item->GetString(PKEY_Link_TargetParsingPath, &path)))
      {
        wprintf(L"Target: %s\n", path); // x:\path\to\dir
        CoTaskMemFree(name);
      }
      item->Release();
    }
  }
  CoUninitialize();
  return 0;
}

C版本:

#include <windows.h>
#include <stdio.h>
#include <shobjidl_core.h>
#include <Propkey.h>

int main()
{
  CoInitialize(NULL);
  {
    IShellItem2* item;
    if (SUCCEEDED(SHCreateItemFromParsingName(L"c:\\mypath\\link", NULL, &IID_IShellItem2, &item)))
    {
      LPWSTR path = NULL;
      if (SUCCEEDED(item->lpVtbl->GetString(item, &PKEY_Link_TargetParsingPath, &path)))
      {
        wprintf(L"Target: %s\n", path); // x:\path\to\dir
        CoTaskMemFree(path);
      }

      item->lpVtbl->Release(item);
    }
  }
  CoUninitialize();
  return 0;
}
zpgglvta

zpgglvta2#

链接到***目录***的***文件***符号链接无法与*CreateFile*协同工作。
mklink默认创建一个文件符号链接,根据符号链接对文件系统函数的影响,对于
CreateFile和CreateFileTransacted

如果指定了文件标志打开重新解析点,并且:

  • 如果打开了一个现有文件,并且该文件是一个符号链接,则返回的句柄是该符号链接的句柄。
  • 如果指定了CREATE_ALWAYS、TRUNCATE_EXISTING或FILE_FLAG_DELETE_ON_CLOSE,则受影响的文件是符号链接。
    如果未指定FILE_FLAG_OPEN_REPARSE_POINT并且:
  • 如果打开了一个现有文件,并且它是一个符号链接,则返回的句柄是目标的句柄。
  • 如果指定了CREATE_ALWAYS、TRUNCATE_EXISTING或FILE_FLAG_DELETE_ON_CLOSE,则受影响的文件为目标。

而 * 硬链接 * 是文件的文件系统表示,通过它,多个路径引用同一卷中的单个文件。
下面的代码读取一个目录符号链接为我工作。

HANDLE h =CreateFile(L"C:\\Users\\SymbolicLink\\To\\MyFolder", GENERIC_READ, FILE_SHARE_READ,NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS,NULL);

相关问题