从高级别的角度来看(意味着只关心结果和界面,而不是实现),指向目录的NTFS重分析点与指向目录的符号链接之间的行为有何不同(如果有的话)同一目录?
它们是否在堆栈中的同一级别上解析,或者在另一个可以解析的某个时间(如启动时)是否可能无法解析?
(我知道符号链接也适用于文件,但我在这里询问目录的区别.)
我真的希望以下内容能在我们没有想法时敲响警钟。关于如何进一步诊断的答案或建议将不胜感激。
我们有一个 Java 应用程序,它已经运行了 18 个月没有问题。它现在正在迁移到运行 Windows Server 2019 Standard 作为 VM 的新平台。第一次安装时,一切正常,但应用程序会定期启动失败,只能通过重新复制所有 jar 文件来修复。这是暂时的,因为最终它再次失败。
经过大量监控,我们注意到有一个 Windows 进程会定期在所有文件上设置“L”文件属性并创建重新解析数据。这应该不是问题,但是一旦发生这种情况,JVM 将无法启动应用程序。(任何 Windows 高手都知道这是做什么的?)
一个关键点是应用程序是通过指定 JPMS 参数来启动的,例如:
java -p MyApp.jar;MyApp_mods -m mymodule/mypackage.StartGUI
Run Code Online (Sandbox Code Playgroud)
这运行良好,在 jar 文件上设置了“L”属性,然后失败并显示消息:
Error occurred during initialization of boot layer
java.lang.module.FindException: Module format not recognized: MyApp.jar
Run Code Online (Sandbox Code Playgroud)
将 MyApp.jar 重命名为其他名称,然后将其复制回 MyApp.jar 可以解决问题,因为它会创建一个没有 L 属性和重新解析数据的文件(直到进程重新应用它)
此行为不仅适用于这一操作,还适用于使用模块系统的任何地方,例如:
java --list-modules any-jar-in-the-app.jar
Run Code Online (Sandbox Code Playgroud)
有趣的是(!),如果我们尝试一个更简单的非模块化应用程序并运行:
java -jar MySimpleApp.jar
Run Code Online (Sandbox Code Playgroud)
那么即使设置了 L 属性,应用程序也能正常运行。
显然我们并不完全理解,但看起来好像通过模块系统运行以某种方式意味着无法读取具有 L 属性/重新解析数据的文件(?)
我们已经尝试了各种版本的 OpenJDK 热点和 OpenJ9 JVM,但结果相同。有任何想法吗?
有谁知道如何检查文件或目录是符号链接,连接点,挂载点还是硬链接?
据我所知,通过检查文件的"ReparsePoint"属性来检测符号链接.通过检查目录中的"ReparsePoint"属性来检测连接点.因此,如果在文件上设置"ReparsePoint"属性,它必须是符号链接,否则如果它在目录上设置,它只能是一个连接点......对吗?
好到目前为止,但我仍然不知道如何检测"挂载点"和"硬链接".谁能告诉我怎么做?
Microsoft OneDrive 允许本地、远程或两种方式存储文件。这是由 Windows 10 中出现的新文件属性决定的:
FILE_ATTRIBUTE_PINNED 0x00080000
FILE_ATTRIBUTE_UNPINNED 0x00100000
FILE_ATTRIBUTE_RECALL_ON_OPEN 0x00040000
FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS 0x00400000
Run Code Online (Sandbox Code Playgroud)
以及从以前版本的 Windows 继承的一些文件属性:
FILE_ATTRIBUTE_SPARSE_FILE 0x00000200
FILE_ATTRIBUTE_REPARSE_POINT 0x00000400
FILE_ATTRIBUTE_OFFLINE 0x00001000
Run Code Online (Sandbox Code Playgroud)
问题是我无法找到通过 Win32 API 或 NT Native API 检索这些新文件属性的方法。到目前为止我已经尝试过:
GetFileAttributes()
FindFirstFile()
NtQueryAttributesFile()
Run Code Online (Sandbox Code Playgroud)
对于设置为始终远程存储的 OneDrive 文件,所有这些方法都返回 0x00500020,而真实属性为 0x00501620(REPARSE_POINT、SPARSE_FILE 和 OFFLINE 被屏蔽)。可以使用以下 PowerShell 命令检索真实的文件属性:
[Convert]::ToString( (Get-ItemProperty -Path 'C:\Users\username\OneDrive\test.txt').Attributes.Value__, 16 )
Run Code Online (Sandbox Code Playgroud)
attrib.exe系统命令还能够显示一些新的 OneDrive 相关文件属性(O脱机、U取消固定、P固定)。
有没有办法在我的软件中检索这些文件属性?也许我需要在清单中添加一些内容?
如何跟踪文件的硬链接(重新分析点?)?管道传输到格式列表不会显示目标。至少在 powershell 7 中,你会得到一个小 ascii 箭头。该文件夹位于 $env:path 中。如果您没有 Windows 终端,则 MicrosoftEdge.exe 链接在同一文件夹中。我的是win10 20h2。
get-item $env:LOCALAPPDATA\Microsoft\WindowsApps\wt.exe
Directory: C:\Users\admin\AppData\Local\Microsoft\WindowsApps
Mode LastWriteTime Length Name
---- ------------- ------ ----
la--- 3/31/2022 1:27 PM 0 wt.exe ->
get-item $env:LOCALAPPDATA\Microsoft\WindowsApps\wt.exe | % attributes
Archive, ReparsePoint
Run Code Online (Sandbox Code Playgroud)
这只是给出了很多二进制文件:
fsutil reparsepoint query $env:LOCALAPPDATA\Microsoft\WindowsApps\wt.exe
Reparse Tag Value : 0x8000001b
Tag value: Microsoft
Reparse Data Length: 0x192
Reparse Data:
0000: 03 00 00 00 4d 00 69 00 63 00 72 00 6f 00 73 00 ....M.i.c.r.o.s.
0010: 6f 00 66 …Run Code Online (Sandbox Code Playgroud) 我使用下面的代码在我的应用程序中检索重新分析点信息。这对于符号链接和连接非常有效,但对于 OneDrive 文件夹及其所有子项目来说会失败,并显示“不是重新分析点”。
using (SafeFileHandle srcHandle = NativeMethods.CreateFile(@"C:\Users\UserName\OneDrive",
0,
System.IO.FileShare.Read,
IntPtr.Zero,
System.IO.FileMode.Open,
NativeMethods.FileFlags.BackupSemantics | NativeMethods.FileFlags.OpenReparsePoint,
IntPtr.Zero))
{
if (!srcHandle.IsInvalid)
{
NativeMethods.REPARSE_DATA_BUFFER rdb = new NativeMethods.REPARSE_DATA_BUFFER();
IntPtr pMem = Marshal.AllocHGlobal(Marshal.SizeOf(rdb) + sizeof(uint) + sizeof(ushort) + sizeof(ushort) + 0xFFFF);
var outBufferSize = Marshal.SizeOf(typeof(NativeMethods.REPARSE_DATA_BUFFER));
var outBuffer = Marshal.AllocHGlobal(outBufferSize);
// Determine if it's a symbolic link or a junction point
try
{
int bytesRet = 0;
if (NativeMethods.DeviceIoControl(srcHandle, NativeMethods.FSCTL_GET_REPARSE_POINT, IntPtr.Zero, 0, outBuffer, outBufferSize, ref bytesRet, IntPtr.Zero) != 0)
{
rdb = (NativeMethods.REPARSE_DATA_BUFFER)Marshal.PtrToStructure(pMem, rdb.GetType());
... …Run Code Online (Sandbox Code Playgroud) 我的功能几乎是一个标准的搜索功能...我已将它包含在下面.
在函数中,我有一行代码负责清除重新分配NTFS点.
if (attributes.ToString().IndexOf("ReparsePoint") == -1)
Run Code Online (Sandbox Code Playgroud)
问题是现在我收到了一个错误
Access to the path 'c:\System Volume Information' is denied.
我调试了代码,运行时该目录的唯一属性是:
System.IO.FileAttributes.Hidden
| System.IO.FileAttributes.System
| System.IO.FileAttributes.Directory
Run Code Online (Sandbox Code Playgroud)
我正在Windows 2008服务器上执行此代码,任何想法我能做些什么来治愈这个失败?
public void DirSearch(string sDir)
{
foreach (string d in Directory.GetDirectories(sDir))
{
DirectoryInfo dInfo = new DirectoryInfo(d);
FileAttributes attributes = dInfo.Attributes;
if (attributes.ToString().IndexOf("ReparsePoint") == -1)
{
foreach (string f in Directory.GetFiles(d, searchString))
{
//lstFilesFound.Items.Add(f);
ListViewItem lvi;
ListViewItem.ListViewSubItem lvsi;
lvi = new ListViewItem();
lvi.Text = f;
lvi.ImageIndex = 1;
lvi.Tag = "tag";
lvsi = new ListViewItem.ListViewSubItem();
lvsi.Text = …Run Code Online (Sandbox Code Playgroud) 当我运行以下代码时,我无法访问内存位置
WIN32_FIND_DATAW FD;
WCHAR cPath[MAX_PATH], cFindPath[MAX_PATH];
if (!GetCurrentDirectoryW(MAX_PATH, cPath))
ErrorExit("GetCurrentDirectory");
else
printf("Current Path: %s\n", cPath);
StringCchCopyW(cFindPath, MAX_PATH, cPath);
StringCchCatW(cFindPath, MAX_PATH, L"\\*");
BOOL bsuccess;
HANDLE hFind = FindFirstFileW(cFindPath, &FD);
if (INVALID_HANDLE_VALUE != hFind)
{
vector<wstring> links;
do
{
WCHAR fullFileName[MAX_PATH];
StringCchPrintfW(fullFileName, MAX_PATH, L"\\\\?\\%s\\%s", cPath, FD.cFileName);
DWORD dwBufSize = MAXIMUM_REPARSE_DATA_BUFFER_SIZE;
REPARSE_DATA_BUFFER* rdata;
rdata = (REPARSE_DATA_BUFFER*)malloc(dwBufSize);
DWORD bytesReturned;
HANDLE hFile = CreateFileW(fullFileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, NULL);
if (INVALID_HANDLE_VALUE != hFile)
{
if (DeviceIoControl(hFile, FSCTL_GET_REPARSE_POINT, NULL, …Run Code Online (Sandbox Code Playgroud) reparsepoint ×8
c# ×3
ntfs ×3
winapi ×3
.net ×2
windows ×2
attributes ×1
c++ ×1
directory ×1
filesystems ×1
java ×1
java-platform-module-system ×1
junction ×1
onedrive ×1
powershell ×1
symlink ×1
uwp ×1
windows-10 ×1