<?xml version='1.0' encoding="utf-8"?>
      <rss version='2.0'>
      <channel>
      <title>Форум на Исходниках.RU</title>
      <link>https://forum.sources.ru</link>
      <description>Форум на Исходниках.RU</description>
      <generator>Форум на Исходниках.RU</generator>
  	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=182195&amp;view=findpost&amp;p=1536940</guid>
        <pubDate>Mon, 23 Apr 2007 05:32:10 +0000</pubDate>
        <title>Добавить комментарий</title>
        <link>https://forum.sources.ru/index.php?showtopic=182195&amp;view=findpost&amp;p=1536940</link>
        <description><![CDATA[Rouse_: Короче вот вам примерный код, для изменения вместо ReadMultiple применять нужно WriteMultiple.<br>
Краткий смысл - все эти расширенные данные (такие как коментарий, автор файла, ключевые слова и т.д.) находятся в NTFS потоках.<br>
Выдернуть эти данные можно двумя способами, либо прямым чтением самого потока, либо через IPropertyStorage.<br>
Здесь показаны оба.<br>
Коментарии не ставил - не маленькие, так разберетесь.<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">////////////////////////////////////////////////////////////////////////////////</div><div class="code_line">//</div><div class="code_line">// &nbsp;****************************************************************************</div><div class="code_line">// &nbsp;* Project &nbsp; : NTFSThread</div><div class="code_line">// &nbsp;* Unit Name : uNTFSThreadMain</div><div class="code_line">// &nbsp;* Purpose &nbsp; : Демо чтения NTFS потоков + демонстрация чтения</div><div class="code_line">// &nbsp;* &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : расширенных свойств файла, хранящихся в них.</div><div class="code_line">// &nbsp;* Author &nbsp; &nbsp;: Александр (Rouse_) Багель</div><div class="code_line">// &nbsp;* Copyright : © Fangorn Wizards Lab 1998 - 2007 г.г.</div><div class="code_line">// &nbsp;* Version &nbsp; : 1.00</div><div class="code_line">// &nbsp;* Home Page : http://rouse.drkb.ru</div><div class="code_line">// &nbsp;****************************************************************************</div><div class="code_line">//</div><div class="code_line">&nbsp;</div><div class="code_line">unit uNTFSThreadMain;</div><div class="code_line">&nbsp;</div><div class="code_line">interface</div><div class="code_line">&nbsp;</div><div class="code_line">uses</div><div class="code_line">&nbsp;&nbsp;Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,</div><div class="code_line">&nbsp;&nbsp;Dialogs, StdCtrls, ExtCtrls;</div><div class="code_line">&nbsp;</div><div class="code_line">type</div><div class="code_line">&nbsp;&nbsp;TdlgNTFSThread = class(TForm)</div><div class="code_line">&nbsp;&nbsp; &nbsp;btnOpen: TButton;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Panel1: TPanel;</div><div class="code_line">&nbsp;&nbsp; &nbsp;GroupBox1: TGroupBox;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Splitter1: TSplitter;</div><div class="code_line">&nbsp;&nbsp; &nbsp;GroupBox2: TGroupBox;</div><div class="code_line">&nbsp;&nbsp; &nbsp;OpenDialog: TOpenDialog;</div><div class="code_line">&nbsp;&nbsp; &nbsp;lbStreams: TListBox;</div><div class="code_line">&nbsp;&nbsp; &nbsp;memStream: TMemo;</div><div class="code_line">&nbsp;&nbsp; &nbsp;procedure lbStreamsClick(Sender: TObject);</div><div class="code_line">&nbsp;&nbsp; &nbsp;procedure FormDestroy(Sender: TObject);</div><div class="code_line">&nbsp;&nbsp; &nbsp;procedure FormCreate(Sender: TObject);</div><div class="code_line">&nbsp;&nbsp; &nbsp;procedure btnOpenClick(Sender: TObject);</div><div class="code_line">&nbsp;&nbsp;private</div><div class="code_line">&nbsp;&nbsp; &nbsp;FileName: String;</div><div class="code_line">&nbsp;&nbsp; &nbsp;FileHandle: THandle;</div><div class="code_line">&nbsp;&nbsp; &nbsp;StreamsSize: array of Int64;</div><div class="code_line">&nbsp;&nbsp; &nbsp;procedure CloseFileHandle;</div><div class="code_line">&nbsp;&nbsp; &nbsp;procedure QueryStreams;</div><div class="code_line">&nbsp;&nbsp; &nbsp;procedure LoadStream(StreamIndex: Integer);</div><div class="code_line">&nbsp;&nbsp; &nbsp;function LoadSummaryInformation(AFileName: String): String;</div><div class="code_line">&nbsp;&nbsp; &nbsp;function LoadDocSummaryInformation(AFileName: String): String;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;dlgNTFSThread: TdlgNTFSThread;</div><div class="code_line">&nbsp;</div><div class="code_line">implementation</div><div class="code_line">&nbsp;</div><div class="code_line">{$R *.dfm}</div><div class="code_line">&nbsp;</div><div class="code_line">uses ActiveX, ComObj, gsstorage;</div><div class="code_line">&nbsp;</div><div class="code_line">const</div><div class="code_line">&nbsp;&nbsp;FILE_STREAM_INFORMATION = 22;</div><div class="code_line">&nbsp;&nbsp;IID_IPropertySetStorage: TGUID = &#39;{0000013A-0000-0000-C000-000000000046}&#39;;</div><div class="code_line">&nbsp;&nbsp;FMTID_SummaryInformation: TGUID = &#39;{F29F85E0-4FF9-1068-AB91-08002B27B3D9}&#39;;</div><div class="code_line">&nbsp;&nbsp;FMTID_DocSummaryInformation: &nbsp;TGUID = &nbsp;&#39;{D5CDD502-2E9C-101B-9397-08002B2CF9AE}&#39;;</div><div class="code_line">&nbsp;</div><div class="code_line">const</div><div class="code_line">&nbsp;&nbsp;PIDDSI_CATEGORY &nbsp; &nbsp; = &nbsp;2;</div><div class="code_line">&nbsp;&nbsp;PIDDSI_PRESFORMAT &nbsp; = &nbsp;3;</div><div class="code_line">&nbsp;&nbsp;PIDDSI_BYTECOUNT &nbsp; &nbsp;= &nbsp;4;</div><div class="code_line">&nbsp;&nbsp;PIDDSI_LINECOUNT &nbsp; &nbsp;= &nbsp;5;</div><div class="code_line">&nbsp;&nbsp;PIDDSI_PARCOUNT &nbsp; &nbsp; = &nbsp;6;</div><div class="code_line">&nbsp;&nbsp;PIDDSI_SLIDECOUNT &nbsp; = &nbsp;7;</div><div class="code_line">&nbsp;&nbsp;PIDDSI_NOTECOUNT &nbsp; &nbsp;= &nbsp;8;</div><div class="code_line">&nbsp;&nbsp;PIDDSI_HIDDENCOUNT &nbsp;= &nbsp;9;</div><div class="code_line">&nbsp;&nbsp;PIDDSI_MMCLIPCOUNT &nbsp;= &nbsp;10;</div><div class="code_line">&nbsp;&nbsp;PIDDSI_SCALE &nbsp; &nbsp; &nbsp; &nbsp;= &nbsp;11;</div><div class="code_line">&nbsp;&nbsp;PIDDSI_HEADINGPAIR &nbsp;= &nbsp;12;</div><div class="code_line">&nbsp;&nbsp;PIDDSI_DOCPARTS &nbsp; &nbsp; = &nbsp;13;</div><div class="code_line">&nbsp;&nbsp;PIDDSI_MANAGER &nbsp; &nbsp; &nbsp;= &nbsp;14;</div><div class="code_line">&nbsp;&nbsp;PIDDSI_COMPANY &nbsp; &nbsp; &nbsp;= &nbsp;15;</div><div class="code_line">&nbsp;&nbsp;PIDDSI_LINKSDIRTY &nbsp; = &nbsp;16;</div><div class="code_line">&nbsp;</div><div class="code_line">type</div><div class="code_line">&nbsp;&nbsp;STGFMT = (STGFMT_STORAGE = 0, STGFMT_FILE = 3,</div><div class="code_line">&nbsp;&nbsp; &nbsp;STGFMT_ANY = 4, STGFMT_DOCFILE = 5);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;NT_STATUS = Cardinal;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;PIO_STATUS_BLOCK = ^IO_STATUS_BLOCK;</div><div class="code_line">&nbsp;&nbsp;IO_STATUS_BLOCK = packed record</div><div class="code_line">&nbsp;&nbsp; &nbsp;Status: NT_STATUS;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Information: DWORD;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;PFileStreamInformation = ^TFileStreamInformation;</div><div class="code_line">&nbsp;&nbsp;_FILE_STREAM_INFORMATION = packed record</div><div class="code_line">&nbsp;&nbsp; &nbsp;NextEntryOffset: ULONG;</div><div class="code_line">&nbsp;&nbsp; &nbsp;StreamNameLength: ULONG;</div><div class="code_line">&nbsp;&nbsp; &nbsp;StreamSize: Int64;</div><div class="code_line">&nbsp;&nbsp; &nbsp;StreamAllocationSize: Int64;</div><div class="code_line">&nbsp;&nbsp; &nbsp;StreamName: WCHAR;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;&nbsp;TFileStreamInformation = _FILE_STREAM_INFORMATION;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;function NtQueryInformationFile(FileHandle: THandle;</div><div class="code_line">&nbsp;&nbsp; &nbsp;var IoStatusBlock: IO_STATUS_BLOCK; FileInformation: Pointer;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Length: DWORD; FileInformationClass: DWORD): NT_STATUS;</div><div class="code_line">&nbsp;&nbsp; &nbsp;stdcall; external &#39;ntdll.dll&#39;;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;function StgOpenStorageEx(pwcsName: POleStr; grfMode: Longint;</div><div class="code_line">&nbsp;&nbsp; &nbsp;stgfmt: STGFMT; grfAttrs: DWORD; pStgOptions: Pointer;</div><div class="code_line">&nbsp;&nbsp; &nbsp;reserved2: Pointer; riid : PGUID; out stgOpen: IStorage): HResult;</div><div class="code_line">&nbsp;&nbsp; &nbsp;stdcall; external &#39;ole32.dll&#39;;</div><div class="code_line">&nbsp;</div><div class="code_line">procedure TdlgNTFSThread.CloseFileHandle;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;if FileHandle &#60;&#62; INVALID_HANDLE_VALUE then</div><div class="code_line">&nbsp;&nbsp; &nbsp;CloseHandle(FileHandle);</div><div class="code_line">&nbsp;&nbsp;lbStreams.Clear;</div><div class="code_line">&nbsp;&nbsp;memStream.Text := &#39;&#39;;</div><div class="code_line">&nbsp;&nbsp;SetLength(StreamsSize, 0);</div><div class="code_line">&nbsp;&nbsp;FileName := &#39;&#39;;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">procedure TdlgNTFSThread.FormCreate(Sender: TObject);</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;FileHandle := INVALID_HANDLE_VALUE;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">procedure TdlgNTFSThread.FormDestroy(Sender: TObject);</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;CloseFileHandle;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">procedure TdlgNTFSThread.lbStreamsClick(Sender: TObject);</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;LoadStream(lbStreams.ItemIndex);</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">function TdlgNTFSThread.LoadDocSummaryInformation(AFileName: String): String;</div><div class="code_line">const</div><div class="code_line">&nbsp;&nbsp;NPID_DocSummaryInformation:</div><div class="code_line">&nbsp;&nbsp; &nbsp;array [PIDDSI_CATEGORY..PIDDSI_LINKSDIRTY] of String = (</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;&#39;Category&#39;, &#39;Presentation Target&#39;, &#39;Bytes&#39;, &#39;Lines&#39;, &#39;Paragraphs&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;&#39;Slides&#39;, &#39;Notes&#39;, &#39;Hidden Slides&#39;, &#39;MM Clips&#39;, &#39;Scale&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;&#39;Heading Pairs&#39;, &#39;Titles Of Parts&#39;, &#39;Manager&#39;, &#39;Company&#39;, &#39;Links Dirty&#39;);</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;Storage: IStorage;</div><div class="code_line">&nbsp;&nbsp;PropStorage: IPropertyStorage;</div><div class="code_line">&nbsp;&nbsp;PropSpec: TPropSpec;</div><div class="code_line">&nbsp;&nbsp;PropVariant: TPropVariant;</div><div class="code_line">&nbsp;&nbsp;EnumSTATPROPSTG: IEnumSTATPROPSTG;</div><div class="code_line">&nbsp;&nbsp;StatPropStg: TStatPropStg;</div><div class="code_line">&nbsp;&nbsp;Fetched: ULONG;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Result := &#39;&#39;;</div><div class="code_line">&nbsp;&nbsp;OleCheck(StgOpenStorageEx(StringToOleStr(AFileName),</div><div class="code_line">&nbsp;&nbsp; &nbsp;STGM_DIRECT or STGM_READ or STGM_SHARE_EXCLUSIVE, STGFMT_ANY, 0, nil, nil,</div><div class="code_line">&nbsp;&nbsp; &nbsp;@IID_IPropertySetStorage, Storage));</div><div class="code_line">&nbsp;&nbsp;OleCheck((Storage as IPropertySetStorage).Open(FMTID_DocSummaryInformation,</div><div class="code_line">&nbsp;&nbsp; &nbsp;STGM_DIRECT or STGM_READ or STGM_SHARE_EXCLUSIVE, PropStorage));</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;Result := &#39;&#39;;</div><div class="code_line">&nbsp;&nbsp;PropStorage.Enum(EnumSTATPROPSTG);</div><div class="code_line">&nbsp;&nbsp;PropSpec.ulKind := PRSPEC_PROPID;</div><div class="code_line">&nbsp;&nbsp;EnumSTATPROPSTG.Next(1, StatPropStg, @Fetched);</div><div class="code_line">&nbsp;&nbsp;repeat</div><div class="code_line">&nbsp;&nbsp; &nbsp;PropSpec.ulKind := PRSPEC_PROPID;</div><div class="code_line">&nbsp;&nbsp; &nbsp;PropSpec.propid := StatPropStg.propid;</div><div class="code_line">&nbsp;&nbsp; &nbsp;PropStorage.ReadMultiple(1, @PropSpec, @PropVariant);</div><div class="code_line">&nbsp;&nbsp; &nbsp;Result := Format(&#39;%s%s: %s&#39;#13#10, [Result,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;NPID_DocSummaryInformation[StatPropStg.propid], PropVariant.pszVal]);</div><div class="code_line">&nbsp;&nbsp; &nbsp;EnumSTATPROPSTG.Next(1, StatPropStg, @Fetched);</div><div class="code_line">&nbsp;&nbsp;until Fetched = 0;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">procedure TdlgNTFSThread.LoadStream(StreamIndex: Integer);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;function ByteToHexStr(Data: Pointer; Len: Integer): String;</div><div class="code_line">&nbsp;&nbsp;var</div><div class="code_line">&nbsp;&nbsp; &nbsp;I, Octets, PartOctets: Integer;</div><div class="code_line">&nbsp;&nbsp; &nbsp;DumpData: String;</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;if Len = 0 then Exit;</div><div class="code_line">&nbsp;&nbsp; &nbsp;I := 0;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Octets := 0;</div><div class="code_line">&nbsp;&nbsp; &nbsp;PartOctets := 0;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Result := &#39;&#39;;</div><div class="code_line">&nbsp;&nbsp; &nbsp;while I &#60; Len do</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;case PartOctets of</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;0: Result := Result + Format(&#39;%.4d: &#39;, [Octets]);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;9:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Inc(Octets, 10);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;PartOctets := -1;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Result := Result + &#39; &nbsp; &nbsp;&#39; + DumpData + sLineBreak;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;DumpData := &#39;&#39;;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Result := Result + Format(&#39;%s &#39;, [IntToHex(TByteArray(Data^)[I], 2)]);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if TByteArray(Data^)[I] in [..$FF] then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;DumpData := DumpData + Chr(TByteArray(Data^)[I])</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;DumpData := DumpData + &#39;.&#39;;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Inc(I);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Inc(PartOctets);</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; &nbsp;if PartOctets &#60;&#62; 0 then</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;PartOctets := (8 - Length(DumpData)) * 3;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Inc(PartOctets, 4);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Result := Result + StringOfChar(&#39; &#39;, PartOctets) +</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;DumpData</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;hFile: THandle;</div><div class="code_line">&nbsp;&nbsp;lpNumberOfBytesRead: DWORD;</div><div class="code_line">&nbsp;&nbsp;Buff: array of Byte;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;memStream.Text := &#39;&#39;;</div><div class="code_line">&nbsp;&nbsp;if lbStreams.Items.Strings[StreamIndex] = &#39;:&#39;#5&#39;SummaryInformation:$DATA&#39; then</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;memStream.Text := LoadSummaryInformation(FileName);</div><div class="code_line">&nbsp;&nbsp; &nbsp;memStream.Lines.Add(&#39;=================================================&#39;);</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;&nbsp;if lbStreams.Items.Strings[StreamIndex] = &#39;:&#39;#5&#39;DocumentSummaryInformation:$DATA&#39; then</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;memStream.Text := LoadDocSummaryInformation(FileName);</div><div class="code_line">&nbsp;&nbsp; &nbsp;memStream.Lines.Add(&#39;=================================================&#39;);</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;&nbsp;hFile := CreateFile(PChar(FileName + lbStreams.Items.Strings[StreamIndex]),</div><div class="code_line">&nbsp;&nbsp; &nbsp;GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);</div><div class="code_line">&nbsp;&nbsp;if hFile &#60;&#62; INVALID_HANDLE_VALUE then</div><div class="code_line">&nbsp;&nbsp;try</div><div class="code_line">&nbsp;&nbsp; &nbsp;SetLength(Buff, StreamsSize[StreamIndex]);</div><div class="code_line">&nbsp;&nbsp; &nbsp;ReadFile(hFile, Buff[0], StreamsSize[StreamIndex], lpNumberOfBytesRead, nil);</div><div class="code_line">&nbsp;&nbsp; &nbsp;memStream.Text := memStream.Text +</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;ByteToHexStr(@Buff[0], lpNumberOfBytesRead);</div><div class="code_line">&nbsp;&nbsp;finally</div><div class="code_line">&nbsp;&nbsp; &nbsp;CloseHandle(hFile);</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">function TdlgNTFSThread.LoadSummaryInformation(AFileName: String): String;</div><div class="code_line">const</div><div class="code_line">&nbsp;&nbsp;NPID_SummaryInformation: array [PIDSI_TITLE..PIDSI_DOC_SECURITY] of String = (</div><div class="code_line">&nbsp;&nbsp; &nbsp;&#39;Title&#39;, &#39;Subject&#39;, &#39;Author&#39;, &#39;Keywords&#39;, &#39;Comments&#39;, &#39;Template&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&#39;Last Saved By&#39;, &#39;Revision Number&#39;, &#39;Total Editing Time&#39;, &#39;Last Printed&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&#39;Create Time/Date&#39;, &#39;Last Saved Time/Date&#39;, &#39;Number of Pages&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&#39;Number of Words&#39;, &#39;Number of Characters&#39;, &#39;Thumbnail&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&#39;Application Name&#39;, &#39;Security&#39;);</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;Storage: IStorage;</div><div class="code_line">&nbsp;&nbsp;PropStorage: IPropertyStorage;</div><div class="code_line">&nbsp;&nbsp;PropSpec: TPropSpec;</div><div class="code_line">&nbsp;&nbsp;PropVariant: TPropVariant;</div><div class="code_line">&nbsp;&nbsp;EnumSTATPROPSTG: IEnumSTATPROPSTG;</div><div class="code_line">&nbsp;&nbsp;StatPropStg: TStatPropStg;</div><div class="code_line">&nbsp;&nbsp;Fetched: ULONG;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Result := &#39;&#39;;</div><div class="code_line">&nbsp;&nbsp;OleCheck(StgOpenStorageEx(StringToOleStr(AFileName),</div><div class="code_line">&nbsp;&nbsp; &nbsp;STGM_DIRECT or STGM_READ or STGM_SHARE_EXCLUSIVE, STGFMT_ANY, 0, nil, nil,</div><div class="code_line">&nbsp;&nbsp; &nbsp;@IID_IPropertySetStorage, Storage));</div><div class="code_line">&nbsp;&nbsp;OleCheck((Storage as IPropertySetStorage).Open(FMTID_SummaryInformation,</div><div class="code_line">&nbsp;&nbsp; &nbsp;STGM_DIRECT or STGM_READ or STGM_SHARE_EXCLUSIVE, PropStorage));</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;Result := &#39;&#39;;</div><div class="code_line">&nbsp;&nbsp;PropStorage.Enum(EnumSTATPROPSTG);</div><div class="code_line">&nbsp;&nbsp;PropSpec.ulKind := PRSPEC_PROPID;</div><div class="code_line">&nbsp;&nbsp;EnumSTATPROPSTG.Next(1, StatPropStg, @Fetched);</div><div class="code_line">&nbsp;&nbsp;repeat</div><div class="code_line">&nbsp;&nbsp; &nbsp;PropSpec.ulKind := PRSPEC_PROPID;</div><div class="code_line">&nbsp;&nbsp; &nbsp;PropSpec.propid := StatPropStg.propid;</div><div class="code_line">&nbsp;&nbsp; &nbsp;PropStorage.ReadMultiple(1, @PropSpec, @PropVariant);</div><div class="code_line">&nbsp;&nbsp; &nbsp;Result := Format(&#39;%s%s: %s&#39;#13#10, [Result,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;NPID_SummaryInformation[StatPropStg.propid], PropVariant.pszVal]);</div><div class="code_line">&nbsp;&nbsp; &nbsp;EnumSTATPROPSTG.Next(1, StatPropStg, @Fetched);</div><div class="code_line">&nbsp;&nbsp;until Fetched = 0;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">procedure TdlgNTFSThread.QueryStreams;</div><div class="code_line">const</div><div class="code_line">&nbsp;&nbsp;STATUS_BUFFER_OVERFLOW = 000005;</div><div class="code_line">&nbsp;&nbsp;STATUS_INFO_LENGTH_MISMATCH = $C0000004;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;IoStatusBlock: IO_STATUS_BLOCK;</div><div class="code_line">&nbsp;&nbsp;FileStreamInformation, FileStreamInformationReader: PFileStreamInformation;</div><div class="code_line">&nbsp;&nbsp;FileStreamInformationSize: DWORD;</div><div class="code_line">&nbsp;&nbsp;AResult: NT_STATUS;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;if FileHandle = INVALID_HANDLE_VALUE then Exit;</div><div class="code_line">&nbsp;&nbsp;AResult := STATUS_BUFFER_OVERFLOW;</div><div class="code_line">&nbsp;&nbsp;FileStreamInformationSize := MAXSHORT;</div><div class="code_line">&nbsp;&nbsp;GetMem(FileStreamInformation, FileStreamInformationSize);</div><div class="code_line">&nbsp;&nbsp;repeat</div><div class="code_line">&nbsp;&nbsp; &nbsp;if AResult = STATUS_INFO_LENGTH_MISMATCH then</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;FileStreamInformationSize := FileStreamInformationSize * 2;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;ReallocMem(FileStreamInformation, FileStreamInformationSize);</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; &nbsp;AResult := NtQueryInformationFile(FileHandle, IoStatusBlock, FileStreamInformation,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;FileStreamInformationSize, FILE_STREAM_INFORMATION);</div><div class="code_line">&nbsp;&nbsp;until AResult &#60;&#62; STATUS_INFO_LENGTH_MISMATCH;</div><div class="code_line">&nbsp;&nbsp;try</div><div class="code_line">&nbsp;&nbsp; &nbsp;if (AResult = NO_ERROR) or (AResult = STATUS_BUFFER_OVERFLOW) then</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;FileStreamInformationReader := FileStreamInformation;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;repeat</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;SetLength(StreamsSize, Length(StreamsSize) + 1);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;StreamsSize[Length(StreamsSize) - 1] :=</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;FileStreamInformationReader^.StreamSize;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;lbStreams.Items.Add(</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Copy(PWideChar(@FileStreamInformationReader^.StreamName),</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1, FileStreamInformationReader^.StreamNameLength div SizeOf(WideChar)));</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;FileStreamInformationReader :=</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Pointer(DWORD(FileStreamInformationReader) +</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;FileStreamInformationReader^.NextEntryOffset);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;until FileStreamInformationReader^.NextEntryOffset = 0; </div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp;finally</div><div class="code_line">&nbsp;&nbsp; &nbsp;FreeMem(FileStreamInformation);</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;&nbsp;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">procedure TdlgNTFSThread.btnOpenClick(Sender: TObject);</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;OpenDialog.InitialDir := ExtractFilePath(ParamStr(0));</div><div class="code_line">&nbsp;&nbsp;if OpenDialog.Execute then</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;CloseFileHandle;</div><div class="code_line">&nbsp;&nbsp; &nbsp;FileName := OpenDialog.FileName;</div><div class="code_line">&nbsp;&nbsp; &nbsp;FileHandle := CreateFile(PChar(FileName),</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;FILE_ATTRIBUTE_NORMAL, 0);</div><div class="code_line">&nbsp;&nbsp; &nbsp;QueryStreams;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">end.</div></ol></div></div></div></div><script>preloadCodeButtons('1');</script>]]></description>
        <author>Rouse_</author>
        <category>Системные функции, WinAPI, работа с железом</category>
      </item>
	
      </channel>
      </rss>
	