//****************************************************************************** // Демонстрационная программа прямого доступа к макросам внутри DOC-файлов // Компилятор Borland C/C++ v5.02 // (c) Климентьев К. aka DrMAD, Самара 2003 //****************************************************************************** #include "windows.h" #include "ole2.h" #include "iostream.h"
#define MAXBUF 0xFFFF #define NAMELEN 256
char Buf[MAXBUF]; // Буфер под поток char SBuf[MAXBUF]; // Буфер под распакованный текст
// Рекурсивный обход дерева потоков. (c) DrMad walk(char *s, LPSTORAGE ls) { OLECHAR FileName[NAMELEN];// Unicode-имя для structured storage char StreamName[NAMELEN];// ASCII-имя потока LPENUMSTATSTG lpEnum=NULL;// Интерфейс перечислителя LPSTORAGE pIStorage=NULL;// Интерфейс структурированного хранилища LPSTORAGE pIStorage2=NULL;// Интерфейс хранилища нижнего уровня LPSTREAM pIStream=NULL;// Интерфейс потока STATSTG stat;// Очередная запись в каталоге ULONG uCount;// Счетчик перечисления ULONG streamlen;// Реальная длина потока ULONG ch_pos;// Позиция чунка внутри потока
if (!ls) // Первый вызов { mbstowcs(FileName, s, 256); StgOpenStorage(FileName,NULL,STGM_READ|STGM_SHARE_EXCLUSIVE, NULL,0,& pIStorage); walk("", pIStorage); } else // Повторный рекурсивный вызов { ls->EnumElements(0,NULL,0,&lpEnum); if (lpEnum) while (lpEnum->Next(1,&stat,&uCount)==S_OK) { if (stat.type==STGTY_STORAGE) // Это хранилище { ls->OpenStorage(stat.pwcsName,NULL,STGM_READ|STGM_SHARE_EXCLUSIVE, NULL,0,&pIStorage2); walk("", pIStorage2); } else // Это поток { ls->OpenStream(stat.pwcsName,NULL,STGM_READ|STGM_SHARE_EXCLUSIVE,0, &pIStream); pIStream->Read(Buf, MAXBUF, &streamlen); wcstombs(StreamName, stat.pwcsName, 256); ch_pos = search_chunk(Buf, streamlen); // См. ниже! if (ch_pos) view_src(StreamName, Buf, ch_pos); // См. ниже! } }; ls->Release(); } }
int main(int argc, char* argv[]) { if (argc>1) walk(argv[1],NULL); }
|