我的目标是从群集中获取文件名。为此,我使用函数FSCTL_LOOKUP_STREAM_FROM_CLUSTER
。使用它时,根据MSDN,我收到的错误87代表 ERROR_INVALID_PARAMETER
。驱动器手柄是正确的,因为我在其他正常工作的功能中使用它。
#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("%lli\n", inpStruct.Cluster[i]);
}
int i = 0;
}
return false;
}
答案 0 :(得分:0)
相当古老的问题,并没有特别有帮助。但它是google为FSCTL_LOOKUP_STREAM_FROM_CLUSTER找到的为数不多的网页之一。所以现在我已经弄明白了如何使用它,我传递了我所学到的东西。
警告:docs指出:
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时,至少他们会打开工作样本。