65.9K
CodeProject 正在变化。 阅读更多。
Home

枚举备用数据流

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.82/5 (9投票s)

2006年4月3日

5分钟阅读

viewsIcon

70963

downloadIcon

2369

枚举 NTFS 文件中包含的备用数据流。

引言

备用数据流 (ADS) 有点争议。虽然我从未遇到过这个问题,但我见过不少网站明确表示 ADS 是邪恶的!

如果您以前没听过备用数据流这个词,那么这篇内容就是为您准备的:通常,当您将内容存储在文件中(例如文本文件)时,文件中就只有这些内容。然而,在 NTFS 中,存在一种功能,可以通过它将一套完全不同的数据保存为备用流。更糟糕的是,这种“备用”流不会被 Explorer 或 'dir' 等 DOS 命令报告。

因此,可以存在一个文件,其中有一个备用数据流,大小可能有数百兆字节,但主数据流中却没有任何数据。哦,我忘了提“主数据流”。这是您将数据保存到文件时通常写入/读取的默认流。

您可能会发现备用数据流的一些新颖用途,例如存储文件的元数据。虽然 Windows 不直接显示备用数据流,但可以使用一些 Win32 API 调用来获取它们。这就是我将在本文中讨论的内容。另外:网上有一些类似的文章,但大多数是用 C# 写的,我认为当我们想在 Win32 API 层面工作时,C++ 是最合适的,所以这是一篇完全基于 MFC 的文章。

基础知识

有两种 API 集可用于读取数据流。第一种包括调用 API - FindFirstStreamW()FindNextStreamW()。这一组函数与 FindFirstFile 类型的 API 非常相似。但是,问题在于它仅适用于 Windows 2003!

下一组函数属于 Backup API。它们是 BackupRead()BackupSeek()。这就是我们将在程序中使用的。

在我们深入了解更多细节之前,让我们快速看一下如何创建一个包含备用数据流的文件。输入以下命令:'notepad.exe c:\a_new_file.txt:TheStream' 将创建一个名为 'TheStream' 的备用数据流。

在记事本中,输入一些内容并保存文件。然后,转到 Windows Explorer 查看文件属性,文件大小将为零。

输入相同的内容,瞧,您将在记事本中看到内容。

主文件

  • AltDataStream.hAltDataStream.h.cpp - 定义了一个名为 CAltDataStream 的小型类,该类负责枚举文件的流数据。

该类的主要函数是 GetStreams(),它返回指向字节数组的指针列表。

该函数的工作原理如下:每个流(数据)之前都有一个流头。此头包含流的名称和大小等信息。因此,如果我们有两个备用数据流,我们将首先遇到第一个流的流头,然后是它的数据。紧接着第一个流的数据之后,我们将遇到第二个流的流头,然后是它的数据。因此,只需读取重要部分并跳过我们不需要的实际数据即可,因为我们只想获取流的名称和大小。然而,我们类中的函数确实会读取一部分数据,精确地说 64 字节,这充当了实际数据的预览。

因此,首先,我们需要打开一个文件并获取一个文件句柄;我们通过使用旧的 CreateFile() API 来实现此目的。

紧接着是对 BackupRead() 函数的调用。重要的是要读取比 winbase.h 中定义的 WIN32_STREAM_ID 结构(只需包含 Windows.h)更大的大小。

以下是 BackupRead() 的参数:

  • HANDLE hFile - 我们打开的文件的句柄。
  • LPBYTE lpBuffer - 数据将存储的缓冲区。
  • DWORD nNumberOfBytesToRead - 我们想读取多少字节。
  • LPDWORD lpNumberOfBytesRead - 实际读取了多少字节。
  • BOOL bAbort - 最初传递 FALSE;读取完成后,传递 TRUE
  • BOOL bProcessSecurity - 我们不需要这个。
  • LPVOID* lpContext - 帮助 API 跟踪其使用情况。确保在第一次调用 BackupRead() 之前将其初始化为 NULL。保存此指针并将其传递给所有后续的 BackupReadBackupSeek() 调用。

现在我们已经读取了第一个流头,我们存储元数据,即流的名称和流的大小。然后我们可以使用 BackupSeek()BackupSeek())定位到数据流的末尾。紧接着是下一个流头,所以我们重复这个过程。当没有更多数据可读时,BackupRead() 返回 FALSE

运行演示

要运行演示应用程序,请创建一个包含一个或多个备用数据流的文件。从 demo.zip 文件中解压缩 ADS.EXE 文件,然后以“ads.exe c:\stream.txt”的形式运行它。

重要提示 - 备用数据流仅在 NTFS 卷上工作,因此这一切在 FAT32 卷上将不起作用。

请将您的评论发送至 siddharth_b@yahoo.com。我很高兴收到您的来信。

© . All rights reserved.