Что нового

Надо разобрать простенький компаунд-файл

Cthulhu

Новичок
Сообщения
7
Репутация
0
Имена потоков знаю.
Надо получить сами потоки.
заранееблагодаренивсьотакоэ...
 
Автор
C

Cthulhu

Новичок
Сообщения
7
Репутация
0
Структуру можно считать одноуровневой. Потоки достаточно считать в виде plain text хотя бы.
неужели никто не заморачивался?
 
Автор
C

Cthulhu

Новичок
Сообщения
7
Репутация
0
Впервые в жизни продираясь через дебри типов параметров и способы использования функций из dll заткнулся...
Код:
#include <file.au3>
#include <Array.au3>
#Include <Security.au3>

Global $cUsrFile = "D:\tst.cmpnd"

If Not _isOleFile($cUsrFile1c) Then
	MsgBox(16, '<Error!>', $cUsrFile1c & " == НЕ iStorage-файл!");
	Exit -1
EndIf
MsgBox(64, '<Ok>', $cUsrFile1c & " == iStorage-файл...");

Local $tStg = DllStructCreate('int')
Local $pStg = DllStructGetPtr($tStg)
Global $aStgOpened = DllCall("Ole32.dll", 'int', 'StgOpenStorage', _
'wstr', $cUsrFile1c, 'ptr', 0, 'int', BitOR(0x00400000, 0, 0x00000040), 'ptr', 0, 'int', 0, 'ptr', $pStg )
_ArrayDisplay( $aStgOpened, '<StgOpenStorage>')

Global $pStream=0
Global $aRetStreamOpen = DllCall("Ole32.dll", 'int', 'OpenStream', _
"wstr", "Container.Contents", "ptr",  0, "int", 16, "int", 0, "ptr", $pStream );
If IsArray($aRetStreamOpen) Then
	MsgBox (64, "<OpenStream>", "Array = " & UBound($aRetStreamOpen) ; ТУТ: "Array = 0"
	_ArrayDisplay( $aRetStreamOpen, '<OpenStream>')
Else
	MsgBox (16, "<OpenStream>", "Array = " & UBound($aRetStreamOpen) )
EndIf

прим.: поток "Container.Contents" там точно есть в корне...
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Нужно описание, инструкция как извлекать.


Добавлено:
Сообщение автоматически объединено:

Вот тут https://msdn.microsoft.com/en-us/library/windows/desktop/aa380017(v=vs.85).aspx есть информация
 
Автор
C

Cthulhu

Новичок
Сообщения
7
Репутация
0
inververs сказал(а):
Да, спасибо, но перекопано по таким ссылкам все...
Я не программирую на сях, а там все примеры на них.
В дебрях Dll*** забился как Лаокоон в змеях, какой тип к какому типу и как туда-сюда...
Вот бы примеров хотя бы как в дельфях (там даже продукт готовый просмотра структуры компаунда есть) - возможно с дополнением извлечения текстового потока ....
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Может через функцию StgOpenStorageEx начать?


Добавлено:
Сообщение автоматически объединено:

Код:
Global Const $S_OK = 0

Local $sFileName = @ScriptDir & '\1.xls'

If Not _Ole32_StgIsStorageFile($sFileName) Then
	Exit MsgBox(0, '', 'Не StgIsStorageFile')
EndIf

Local $iMode = BitOR(0x00400000, 0, 0x00000040);
Local $aRet = DllCall("Ole32.dll", 'LONG', 'StgOpenStorage', 'wstr', $sFileName, 'ptr', 0, 'int', $iMode, 'ptr', 0, 'int', 0, 'ptr*', 0)
If @error Or Not IsArray($aRet) Then
	Exit MsgBox(0, '', 'DllCall ошибка ' & @error)
EndIf

If Not $aRet[0] = $S_OK Then
	Exit MsgBox(0, '', 'Результат не $S_OK ' & Hex($aRet[0]))
EndIf

Local $pIStorage = $aRet[6]
MsgBox(0, '', 'Указатель на IStorage ' & $pIStorage)
;~ ... и т.д.

Func _Ole32_StgIsStorageFile($sFileName)
	Local $aRet = DllCall("Ole32.dll", 'int', 'StgIsStorageFile', 'wstr', $sFileName)
	If $aRet[0] = $S_OK Then
		Return True
	Else
		Return False
	EndIf
EndFunc
 
Автор
C

Cthulhu

Новичок
Сообщения
7
Репутация
0
Спасибо за образец корректного вызова StgOpenStorage...
Код:
If StringLeft(_ArrayToString(DllCall("Ole32.dll", 'int', 'StgIsStorageFile', 'wstr', $cUsrFile1c), "#"),2) <> "0#" Then Exit MsgBox(16, '<Error!>', $cUsrFile1c & " == if NOT iStorage-file !");
MsgBox(64, '<Ok>', $cUsrFile1c & " is iStorage-file ...");

Local $iMode = BitOR(0x00400000, 0, 0x00000040);
Local $cMsg=""
Local $aStgOpened = DllCall("Ole32.dll", 'LONG', 'StgOpenStorage', 'wstr', $cUsrFile1c, 'ptr', 0, 'int', $iMode, 'ptr', 0, 'int', 0, 'ptr*', 0)
If @error Or Not IsArray($aStgOpened) Then Exit MsgBox(16, 'debug: <StgOpenStorage>', 'DllCall ошибка ' & @error)
If Not $aStgOpened[0] = $S_OK Then Exit MsgBox(16, 'debug: <StgOpenStorage>', 'Результат не $S_OK ' & Hex($aStgOpened[0]))
Local $pIStorage = $aStgOpened[6]
MsgBox(64, 'debug: <StgOpenStorage>', 'Указатель на IStorage ' & $pIStorage)
If Not IsArray($aStgOpened) Then Exit MsgBox (16, "debug: <StgOpenStorage>", $cMsg & @CRLF & "(ERROR) Return(" & VarGetType($aStgOpened) & ") = " & $aStgOpened )
$cMsg &= @CRLF & "Return Array = " & UBound($aStgOpened)
If UBound($aStgOpened) = 0 Then Exir MsgBox (16, "debug: <StgOpenStorage ERROR>", $cMsg)
MsgBox (64, "debug: <StgOpenStorage>", $cMsg & "  " & $aStgOpened[0])
_ArrayDisplay( $aStgOpened, 'debug: <StgOpenStorage>')
$cMsg = ""
Local $cStreamName = "Container.Contents" & ChrW(0x0000)
Local $aStreamOpened = DllCall("Ole32.dll", 'LONG', 'OpenStream', 'wstr', $cStreamName, 'ptr', 0, 'int', $iMode, 'ptr', 0, 'ptr*', 0)
If @error Or Not IsArray($StreamOpened) Then Exit MsgBox(16, 'debug: <OpenStream>', 'DllCall ошибка ' & @error)	; ТУТ: DllCall ошибка 3

причем ошибка 3 согласно Autoit.chm - "функция не найдена в файле DLL."
 
Автор
C

Cthulhu

Новичок
Сообщения
7
Репутация
0
inververs сказал(а):
Все правильно, в Ole32.dll нету функции OpenStream

(мне запрещено оставлять внешние ссылки, но мсдн.com/en-us/library/windows/desktop/aa380025%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396 говорит, что:
ну или если врут - то как надо?
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Не врут, но OpenStream это не экспортируемая функция которую можно вызывать через DLLCall.
Это метод объекта с интерфейсом IStorage, см. надпись сверху: IStorage::shok:penStream method

Cthulhu [?]
ну или если врут - то как надо?
А дальше мы вступаем на скользкую дорожку работы с объектами, причем не унаследованных от IDispatch и начинаем активно использовать функцию
Код:
ObjCreateInterface
ее добавили в язык с версией 3.3.8.0, поэтому если у вас более старая, то нужно обновляться.

Если вы хотите пройтись по ней и не разу не упасть, то вот что вам нужно сделать:
1) Зная указатель на IStorage создать этот объект.
2) У созданного объекта вызывать метод .OpenStream(все параметры), он вернет вам указатель на интерфейс IStream
3) Получив указатель, создать этот объект
4) У созданного объекта вызывать метод Read и считать данные.

Вариант не из простых, нужно точно понимать что делаете.
 
Автор
C

Cthulhu

Новичок
Сообщения
7
Репутация
0
убился об стену.
блин, пришлось нарыть в инетах приблуду для разборки компаунда в файлы и лопатить в три приема - разобрать - пропарсить файлы - удалить... в связи с чем мучительно терзаем своим треклятым перфекционизмом (хотя вроде и получил что надо но криво-крииивоооо)
:(
 
Верх