Универсальное извлечение метаданных из файлов
Универсальное извлечение метаданных из файлов
За последнее время на сайте появилось немало статей, посвященных работе с метаданными файлов различных форматов. Но там рассматривались только определенные форматы и использовались методы, заточенные под определенную структуру файлов. Но в Windows есть очень мощные инструменты, которые позволяют получить множество полезной информации практически из любого файла, независимо от его структуры и типа.
Начинаем, как обычно, с описания задействованных структур, интерфейсов и констант. Даже интересно, когда-нибудь в "коробочном" FASM появится поддержка структур и констант хотя бы до уровня WinXP SP3?
Code (Assembler) : Убрать нумерацию
- ; GUID {886D8EEB-8CF2-4446-8D02-CDBA1DBDCF99}
- IID_IPropertyStore \
- dd 0886D8EEBh
- dw 08CF2h
- dw 04446h
- db 08Dh, 002h, 0CDh, 0BAh, 01Dh, 0BDh, 0CFh, 099h
- ; GUID {CA724E8A-C3E6-442B-88A4-6FB0DB8035A3}
- IID_IPropertySystem \
- dd 0CA724E8Ah
- dw 0C3E6h
- dw 0442Bh
- db 088h, 0A4h, 06Fh, 0B0h, 0DBh, 080h, 035h, 0A3h
- ; IID_IPropertySystem Interface
- struct IPropertySystem
- ; IUnknown
- QueryInterface dd ? ; 000h
- AddRef dd ? ; 004h
- Release dd ? ; 008h
- ; IPropertySystem
- GetPropertyDescription dd ? ; 00Ch
- GetPropertyDescriptionByName dd ? ; 010h
- GetPropertyDescriptionListFromString dd ? ; 014h
- EnumeratePropertyDescriptions dd ? ; 018h
- FormatForDisplay dd ? ; 01Ch
- FormatForDisplayAlloc dd ? ; 020h
- RegisterPropertySchema dd ? ; 024h
- UnregisterPropertySchema dd ? ; 028h
- RefreshPropertySchema dd ? ; 02Ch
- ends
- ; GUID {1F9FC1D0-C39B-4B26-817F-011967D3440E}
- IID_IPropertyDescriptionList \
- dd 01F9FC1D0h
- dw 0C39Bh
- dw 04B26h
- db 081h, 07Fh, 001h, 019h, 067h, 0D3h, 044h, 00Eh
- ; IID_IPropertyDescriptionList Interface
- struct IPropertyDescriptionList
- ; IUnknown
- QueryInterface dd ? ; 000h
- AddRef dd ? ; 004h
- Release dd ? ; 008h
- ; IPropertyDescriptionList
- GetCount dd ? ; 00Ch
- GetAt dd ? ; 010h
- ends
- ; GUID {6F79D558-3E96-4549-A1D1-7D75D2288814}
- IID_IPropertyDescription \
- dd 06F79D558h
- dw 03E96h
- dw 04549h
- db 0A1h, 0D1h, 07Dh, 075h, 0D2h, 028h, 088h, 014h
- ; IID_IPropertyDescription Interface
- struct IPropertyDescription
- ; IUnknown
- QueryInterface dd ? ; 000h
- AddRef dd ? ; 004h
- Release dd ? ; 008h
- ; IPropertyDescription
- GetPropertyKey dd ? ; 00Ch
- GetCanonicalName dd ? ; 010h
- GetPropertyType dd ? ; 014h
- GetDisplayName dd ? ; 018h
- GetEditInvitation dd ? ; 01Ch
- GetTypeFlags dd ? ; 020h
- GetViewFlags dd ? ; 024h
- GetDefaultColumnWidth dd ? ; 028h
- GetDisplayType dd ? ; 02Ch
- GetColumnState dd ? ; 030h
- GetGroupingRange dd ? ; 034h
- GetRelativeDescriptionType dd ? ; 038h
- GetRelativeDescription dd ? ; 03Ch
- GetSortDescription dd ? ; 040h
- GetSortDescriptionLabel dd ? ; 044h
- GetAggregationType dd ? ; 048h
- GetConditionType dd ? ; 04Ch
- GetEnumTypeList dd ? ; 050h
- CoerceToCanonicalValue dd ? ; 054h
- FormatForDisplay dd ? ; 058h
- IsValueCanonical dd ? ; 05Ch
- ends
- PDFF_DEFAULT = 0
- PDEF_VIEWABLE = 3
- GPS_READWRITE = 2
Начнем с теории. Для получения доступа к системным свойствам используется функция PSGetPropertySystem, которая возвращает интерфейс IPropertySystem для работы с ними. Дальше получаем объект списка всех свойств IPropertyDescriptionList, их количество, а потом поочередно перебираем все свойства в этом списке. Для каждого свойства можно получить его каноническое имя, человекопонятное название и, соответственно, значение. Для конвертации значения свойства из системного представления в привычный для человека вид используется функция PSFormatPropertyValue. Получив объект свойств выбранного файла, можно поочередно запрашивать каждое из перечисляемых системных свойств. Если результат получен, то такое свойство у файла имеется, если нет, то нет. Таким образом можно получить все имеющиеся системные свойства, они же метаданные, для любого файла.
Code (Assembler) : Убрать нумерацию
- invoke CoInitialize,0
- ; Получить полный путь к файлу
- invoke GetFullPathName,sample,MAX_PATH,fname,NULL
- ; Получить доступ к его свойствам
- invoke SHGetPropertyStoreFromParsingName,fname,\
- NULL,GPS_READWRITE,IID_IPropertyStore,pStore
- ; Получить объект для работы с системными свойствами
- invoke PSGetPropertySystem,IID_IPropertySystem,pPSys
- ; Получить список системных свойств
- mov eax,[pPSys]
- mov eax,[eax]
- stdcall [eax+IPropertySystem.EnumeratePropertyDescriptions],[pPSys],\
- PDEF_VIEWABLE,\
- IID_IPropertyDescriptionList,pPropList
- ; Получить количество системных свойств
- mov eax,[pPropList]
- mov eax,[eax]
- stdcall [eax+IPropertyDescriptionList.GetCount],[pPropList],\
- nProp
- ; Перебрать все свойства по очереди
- xor ebx,ebx
- loc_loop:
- ; Получить очередное свойство
- mov eax,[pPropList]
- mov eax,[eax]
- stdcall [eax+IPropertyDescriptionList.GetAt],[pPropList],\
- ebx,IID_IPropertyDescription,pProp
- or eax,eax
- jnz loc_next
- ; Получить каноническое имя свойства
- mov eax,[pProp]
- mov eax,[eax]
- stdcall [eax+IPropertyDescription.GetCanonicalName],[pProp],\
- lpCanon
- ; Получить отображаемое имя свойства
- mov eax,[pProp]
- mov eax,[eax]
- stdcall [eax+IPropertyDescription.GetDisplayName],[pProp],\
- lpProp
- ; Получить и отформатировать строку значения свойства
- invoke PSFormatPropertyValue,[pStore],[pProp],PDFF_DEFAULT,lpVal
- ; Такое свойство есть у файла?
- or eax,eax
- jnz loc_next
- ...
- ...
- ; [lpCanon] -> каноническое имя
- ; [lpProp] -> человекопонятное название
- ; [lpVal] -> значение
- ...
- ...
- loc_next:
- ; Следующее свойство
- inc ebx
- cmp ebx,[nProp]
- jb loc_loop
- invoke CoUninitialize
В приложении пример программы с исходным текстом, которая получает все доступные системные свойства из файла.
Просмотров: 712 | Комментариев: 0
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
Комментариeв нет
Добавить комментарий
Заполните форму для добавления комментария