C++ 来自\u集群的FSCTL\u查找\u流\u返回错误\u无效\u参数
我的目标是从集群中获取文件名。为此,我使用了函数C++ 来自\u集群的FSCTL\u查找\u流\u返回错误\u无效\u参数,c++,winapi,C++,Winapi,我的目标是从集群中获取文件名。为此,我使用了函数FSCTL\u LOOKUP\u STREAM\u FROM\u CLUSTER。使用它时,我得到了错误87,根据MSDN,它表示错误\u无效\u参数。驱动手柄是正确的,因为我使用它在其他功能正常工作 #include <Windows.h> #include <iostream> using namespace std; class Disk{ public: Disk(); HANDLE hDisk;
FSCTL\u LOOKUP\u STREAM\u FROM\u CLUSTER
。使用它时,我得到了错误87,根据MSDN,它表示错误\u无效\u参数
。驱动手柄是正确的,因为我使用它在其他功能正常工作
#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;
}
#包括
#包括
使用名称空间std;
类磁盘{
公众:
磁盘();
处理hDisk;
WCHAR*个人姓名;
WCHAR*信函;
};
bool searchFileByItCluster(磁盘驱动器){
从\u集群\u输入结构中查找\u流\u;
从\u集群\u条目str查找\u流\u;
从\u集群\u输出str1查找\u流\u;
PNTFS\u卷\u数据\u缓冲区信息;
PLARGE_INTEGER INT=(PLARGE_INTEGER)malloc(sizeof(LARGE_INTEGER));
德沃德;
int size=(sizeof(DWORD)*2+sizeof(大整数));
inpStruct.NumberOfClusters=1;
inpStruct.Cluster[0].QuadPart=26585528;
bool ret=DeviceIoControl(drive.hDisk、FSCTL\u LOOKUP\u STREAM\u FROM\u CLUSTER、&inpStruct,(sizeof(DWORD)*2+sizeof(大整数))、str1、sizeof(LOOKUP\u STREAM\u FROM\u CLUSTER\u OUTPUT)和cbwrite,NULL);
如果(!ret){
cout这是一个很老的问题,也不是特别有帮助。但这是谷歌从集群中为数不多的FSCTL_查找_流_页面之一。所以现在我已经知道了如何使用它,我正在把我学到的东西传给大家
警告:正如上面指出的:
来自集群的FSCTL_LOOKUP_STREAM_是一项资源密集型操作,通常会占用大量磁盘带宽、内存和时间
尽管如此,如果你需要它,你也需要它(我确实是这么做的)。出于这个原因,这里有一些代码对我有用,以及我在学习过程中学到的东西
// 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_,至少他们会找到一个工作样本。不相关,但PLARGE_INTEGER INT=(PLARGE_INTEGER)malloc(sizeof(LARGE_INTEGER));
几乎没有INT*pint=(INT*)malloc点(sizeof(INT))
。错误代码是不言自明的。出于这样或那样的原因,您传递给DeviceIoControl
的几乎每个参数都在运行。首先,结构的大小不一定与其成员大小之和相同。