FSCTL_LOOKUP_STREAM_FROM_CLUSTER returns ERROR_INVALID_PARAM

FSCTL_LOOKUP_STREAM_FROM_CLUSTER returns ERROR_INVALID_PARAMETER

本文关键字:ERROR INVALID PARAM returns FROM LOOKUP STREAM FSCTL CLUSTER      更新时间:2023-10-16

我的目标是从集群中获取文件名。为此,我使用函数FSCTL_LOOKUP_STREAM_FROM_CLUSTER。使用时,我会得到错误87,该错误代表 ERROR_INVALID_PARAMETER 根据MSDN。驱动器手柄是正确的,因为我在其他正常工作的功能中使用它。

#include <Windows.h>
#include <iostream>
using namespace std;
class Disk{
public:
    Disk();
    HANDLE hDisk;
    WCHAR *individualName;
    WCHAR *Letter;
};
bool searchFileByItCluster(Disk drive){
    LOOKUP_STREAM_FROM_CLUSTER_INPUT inpStruct;
    LOOKUP_STREAM_FROM_CLUSTER_ENTRY str;
    LOOKUP_STREAM_FROM_CLUSTER_OUTPUT str1;
    PNTFS_VOLUME_DATA_BUFFER info;
    PLARGE_INTEGER INT = (PLARGE_INTEGER)malloc(sizeof(LARGE_INTEGER));
    DWORD cbWritten;
    int size = (sizeof(DWORD) * 2 + sizeof(LARGE_INTEGER));
    inpStruct.NumberOfClusters = 1;
    inpStruct.Cluster[0].QuadPart = 26585528;
    bool ret = DeviceIoControl(drive.hDisk, FSCTL_LOOKUP_STREAM_FROM_CLUSTER, &inpStruct, (sizeof(DWORD) * 2 + sizeof(LARGE_INTEGER)), &str1, sizeof(LOOKUP_STREAM_FROM_CLUSTER_OUTPUT), &cbWritten, NULL);
    if (!ret){
        cout << GetLastError()<<endl<<sizeof(LOOKUP_STREAM_FROM_CLUSTER_INPUT);
        for (int i = 0; i < inpStruct.NumberOfClusters; i++){
            printf("%llin", inpStruct.Cluster[i]);
        }

        int i = 0;
    }
    return false;
}

相当古老的问题,并不特别有用。但这是Google为fsctl_lookup_stream_from_cluster找到的少数页面之一。所以现在我已经弄清楚了如何使用它,我已经传递了我学到的东西。


警告:正如文档指出的那样:

fsctl_lookup_stream_from_cluster是一个非常重要的操作,通常使用大量的磁盘带宽,内存和时间。

仍然,如果需要,您需要它(我肯定只是这样)。因此,这里有一些对我有用的代码以及我在途中学到的东西。

// Pick a plausible estimate.  Note: valid output sizes can be up to ~64k!
DWORD bufsize = 
    MAX_PATH + 
    sizeof(LOOKUP_STREAM_FROM_CLUSTER_OUTPUT) + 
    sizeof(LOOKUP_STREAM_FROM_CLUSTER_ENTRY);
LOOKUP_STREAM_FROM_CLUSTER_INPUT sfci;
LOOKUP_STREAM_FROM_CLUSTER_OUTPUT *sfco = 
    (LOOKUP_STREAM_FROM_CLUSTER_OUTPUT *)malloc(bufsize);
sfci.NumberOfClusters = 1;      // Only looking up one cluster
sfci.Flags = 0;                 // No flags are currently defined
sfci.Cluster[0].QuadPart = 123; // Cluster number being sought
// While some DeviceIoControl calls get away with 0 or FILE_READ_ATTRIBUTES,
// FSCTL_LOOKUP_STREAM_FROM_CLUSTER needs at least FILE_READ_DATA.  Also,
// while the docs claim you can use "a file on a NTFS volume," I believe a 
// volume handle is required, which requires running with admin rights.
HANDLE h1 = CreateFile(
    L"\\.\j:", 
    FILE_READ_DATA, 
    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 
    NULL, 
    OPEN_EXISTING, 
    FILE_FLAG_BACKUP_SEMANTICS, // Required, but the SE_BACKUP_NAME priv is not
    NULL);
if (h1 == INVALID_HANDLE_VALUE)
    ;  // Do something
DWORD ret;
BOOL B = DeviceIoControl(
    h1, 
    FSCTL_LOOKUP_STREAM_FROM_CLUSTER, 
    &sfci, 
    sizeof(sfci), 
    sfco, 
    bufsize, 
    &ret, 
    NULL);
if (!B && GetLastError() == ERROR_MORE_DATA)
    ; // bufsize too small. Resize to sfco->BufferSizeRequired and retry
if (!B)
    ; // Some other error
// Here's the data.
LOOKUP_STREAM_FROM_CLUSTER_ENTRY *sfce = 
    (LOOKUP_STREAM_FROM_CLUSTER_ENTRY *)((BYTE *)sfco + sfco->Offset);

那里。现在,下次有人搜索fsctl_lookup_stream_from_cluster时,至少他们会调出一个有效的示例。

相关文章: