На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! user posted image
Пожалуйста, выделяйте текст программы тегом [сode=pas] ... [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.

Соблюдайте общие правила форума

Следующие вопросы задаются очень часто, подробно разобраны в FAQ и, поэтому, будут безжалостно удаляться:
1. Преобразовать переменную типа String в тип PChar (PAnsiChar)
2. Как "свернуть" программу в трей.
3. Как "скрыться" от Ctrl + Alt + Del (заблокировать их и т.п.)
4. Как запустить программу/файл? (и дождаться ее завершения)
5. Как перехватить API-функции, поставить hook? (перехват сообщений от мыши, клавиатуры - внедрение в удаленное адресное прстранство)
... (продолжение следует) ...

Внимание:
Попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
Повторная попытка - 60 дней. Последующие попытки - бан.
Мат в разделе - бан на три месяца...

Полезные ссылки:
user posted image MSDN Library user posted image FAQ раздела user posted image Поиск по разделу user posted image Как правильно задавать вопросы


Выразить свое отношение к модераторам раздела можно здесь: user posted image Rouse_, user posted image Krid

Модераторы: Rouse_, Krid
  
> Добавить комментарий , Сводка файлов
    Передо мной встала такой вопрос:
    имметься большое кол-во файлов и каждому из этих файлов надо добавить комментарий (который находиться в "Сводка"), формат файлов различный, т.е. хоть *.exe хоть *.mp3 и.т.п. (файловая система NTFS)
    Можно ли это релизовать прогрмамным образом? (...хм или прийдеться ручками <_< )
      От файловой системы почти ничего в твоей задаче не зависит, на сколько я понял. Это первое. Второе- что значит "находится в Сводка"?
      Если тебе просто надо добавить некоторую запись в конец любого файла, то не вижу никакой проблемы:
      ExpandedWrap disabled
        assignfile([файловая переменная], [имя файла]);
        append([файловая переменная]);
        write([файловая переменная],[то, что нужно дописать]);
        closefile([файловая переменная]);

      Хотя технологий обработки файлов, я знаю, как минимум 4. И можно использовать любую. Надеюсь у тебя есть опыт , даже самый незначительный, работы с файлами.
      И третье - когда ты добавляешь какую-то запись в файл выше описанным образом, а тем более не текстовый, а типизированный, то нарушается структура файла, отсель екзешник не запуститься, а мр3-шник может не прочитаться плеером и т.д. Вообщем можешь более формализированно поставить ТЗ?
        NetVir, Во первых по моему не во всех фаловых системах есть у любого типа файлов, такая вещб как "Сводка"
        Во-вторых "Сводка", когда правой кнопкой жмешь на файле "Свойства"-> "Сводка"->"Комментарии"
        В -третьих мне не нужно добавлять ничего в конец файла....
        Помоему есть функции которыми можно получить и записать не только комментарии, но др.данные(название, тема...)
          Согласен. Сообщение от 24.03.07, 17:55 - ступил!!! ;) :D Не разобрался в вопросе.
          Сообщение от 24.03.07, 18:15 - более понятно поставлена задача. При случае постараюсь найти решение. Сам столкнулся с такой проблемой. :wall:
            Никто с этим не сталкивался?! :blink:
            А где вообще храняться эти данные?! (название, тема, автор,комментарии и.т.п.), откуда их хотя бы считывать?! <_<
              Цитата Trooper @
              А где вообще храняться эти данные?!
              В ярлыках, кои являются объектами СОМ класса CLSID_ShellLink с интерфейсом IShellLink.
                А можно ли добавить свой комментарий к файлу?
                  Можно. Используй IShellLink :ph34r:
                    Цитата Cinderella @
                    Можно. Используй IShellLink

                    IShellLink говоришь? :) Ок. Покажи пример :)
                      На Дельфи сейчас показать не могу, а для Билдера - вот:
                      ExpandedWrap disabled
                        void __fastcall TForm1::Button1Click(TObject *Sender) {
                          IShellLink *link;
                          CoInitialize(NULL);
                          char buf[1024];
                          HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void**)&link);
                          if (SUCCEEDED(hres)) {
                            link->SetPath("C:\\0000\\0000.txt");
                            link->SetWorkingDirectory("C:\\0000");
                            link->SetDescription("Тестовая строка для добавления в описание");
                            IPersistFile *ppf;
                            link->QueryInterface(IID_IPersistFile, (void**)&ppf);
                            ppf->Save(WideString("C:\\0000\\0000.dat"), false);
                          }
                          CoUninitialize();
                        }

                      На форме - кнопка. И всё :yes:
                      На диске С создана директория С:\\0000, в ней лежит файл 0000.txt. А в файл 0000.dat пишутся данные объекта-ярлыка. По крайней мере - он создаётся :D
                      ----------
                      Врать не буду - фрагмент кода взят из книги Архангельского и Тагина "Приемы программирования в C++ Builder. Механизмы Windows, сети".
                      Если найду CD от неё, попробую поиграть со всей прграммой.
                        Этим кодом ты создала ярлык, а человек спрашивает не про это.
                        Сводку файла можно получить через IPropertyStorage, но никак не через IShellLink
                          Rouse_, а разве имелась ввиду не вот эта информация ? :

                          Добавлено
                          Таки я домучила код по книге, исправила найденные ошибки и получила LNK-файл для своего же приложения при помощи IShellLink :D
                          Прикреплённый файлПрикреплённый файл1.JPG (19.91 Кбайт, скачиваний: 370)
                            ...

                            Добавлено
                            :ph34r: Не то :wall: :wall: :wall: Проводник этого не видит :(
                            Прикреплённый файлПрикреплённый файл2.JPG (19.99 Кбайт, скачиваний: 372)
                              А я так понял что не это.
                              Короче вот вам примерный код, для изменения вместо ReadMultiple применять нужно WriteMultiple.
                              Краткий смысл - все эти расширенные данные (такие как коментарий, автор файла, ключевые слова и т.д.) находятся в NTFS потоках.
                              Выдернуть эти данные можно двумя способами, либо прямым чтением самого потока, либо через IPropertyStorage.
                              Здесь показаны оба.
                              Коментарии не ставил - не маленькие, так разберетесь.

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


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0545 ]   [ 15 queries used ]   [ Generated: 16.09.25, 12:53 GMT ]