// @pymethod <o PyIStream>|PyIStorage|OpenStream|Opens an existing stream object within this storage object in the specified access mode. PyObject *PyIStorage::OpenStream(PyObject *self, PyObject *args) { IStorage *pIS = GetI(self); if ( pIS == NULL ) return NULL; // @pyparm string|pwcsName||Description for pwcsName // @pyparm object|reserved1||A reserved param. Always pass None. NULL is always passed to the COM function // @pyparm int|grfMode||Specifies the access mode to be assigned to the open stream. See the STGM enumeration values for descriptions of the possible values. . Whatever other modes you may choose, you must at least specify STGM_SHARE_EXCLUSIVE when calling this method. // @pyparm int|reserved2|0|Reserved - must be zero. PyObject *obName; DWORD grfMode; PyObject *obreserved1; DWORD reserved2 = 0; if ( !PyArg_ParseTuple(args, "OOi|i:OpenStream", &obName, &obreserved1, &grfMode, &reserved2) ) return NULL; if (obreserved1 != Py_None) { PyErr_SetString(PyExc_TypeError, "The 'reserved' parameter (param 2) must be None"); return NULL; } IStream *ppstm; BOOL bPythonIsHappy = TRUE; BSTR name; bPythonIsHappy = PyWinObject_AsBstr(obName, &name); if (!bPythonIsHappy) return NULL; PY_INTERFACE_PRECALL; HRESULT hr = pIS->OpenStream( name, NULL, grfMode, reserved2, &ppstm ); PyWinObject_FreeBstr(name); PY_INTERFACE_POSTCALL; if ( FAILED(hr) ) return PyCom_BuildPyException(hr, pIS, IID_IStorage); return PyCom_PyObjectFromIUnknown(ppstm, IID_IStream, FALSE); }
HRESULT CDShowCtrl::LoadGraphFile(IGraphBuilder *pGraph, const WCHAR* wszName) { IStorage *pStorage = 0; if (S_OK != StgIsStorageFile(wszName)) { return E_FAIL; } HRESULT hr = StgOpenStorage(wszName, 0, STGM_TRANSACTED | STGM_READ | STGM_SHARE_DENY_WRITE, 0, 0, &pStorage); if (FAILED(hr)) { return hr; } IPersistStream *pPersistStream = 0; hr = pGraph->QueryInterface(IID_IPersistStream, reinterpret_cast<void**>(&pPersistStream)); if (SUCCEEDED(hr)) { IStream *pStream = 0; hr = pStorage->OpenStream(L"ActiveMovieGraph", 0, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &pStream); if(SUCCEEDED(hr)) { hr = pPersistStream->Load(pStream); pStream->Release(); } pPersistStream->Release(); } pStorage->Release(); return hr; }
BOOL CChildFrame::OpenCompositeDocument(LPCTSTR lpszFileName) { USES_CONVERSION; CWaitCursor wait; HRESULT hResult = E_FAIL; IStorage * ptrRootStg = NULL; // root storage HWND hWnd = (HWND)m_hWnd; hResult = ::StgIsStorageFile( T2COLE(m_szFileName) ); if( S_OK != hResult ) { TCHAR szFmt[MAX_PATH] = { 0 }; AtlLoadString(IDS_OPEN_ARCHIVE_ERROR, szFmt, _countof(szFmt)); TCHAR szOut[MAX_PATH*2] = { 0 }; wnsprintf(szOut, _countof(szOut), szFmt, lpszFileName); AtlMessageBox(m_hWnd, szOut, IDS_ERROR, MB_OK|MB_ICONSTOP); return FALSE; } // open the Compound document hResult = ::StgOpenStorage( T2COLE(m_szFileName), NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &ptrRootStg ); if( FAILED(hResult) ) { TCHAR szFmt[MAX_PATH] = { 0 }; AtlLoadString(IDS_OPEN_FILE_ERROR, szFmt, _countof(szFmt)); TCHAR szError[MAX_PATH] = { 0 }; TCHAR szOut[MAX_PATH*2] = { 0 }; wnsprintf(szOut, _countof(szOut), szFmt, lpszFileName, GetErrorString(S_OK, szError, _countof(szError))); AtlMessageBox(m_hWnd, szOut, IDS_ERROR, MB_OK|MB_ICONSTOP); return FALSE; } TREE_ITEM_DATA * pRootData = new TREE_ITEM_DATA(ptrRootStg, STGTY_STORAGE); HTREEITEM hRoot = m_wndCatalog.InsertItem ( TVIF_IMAGE|TVIF_TEXT|TVIF_PARAM|TVIF_SELECTEDIMAGE, PathFindFileName(m_szFileName), 0, 1, TVIS_EXPANDED, 0, reinterpret_cast<LPARAM>(pRootData), NULL, NULL); std::stack < StgInfo > FolderStack; HTREEITEM htiParent = hRoot; IEnumSTATSTG * ptrEnum = NULL; hResult = ptrRootStg->EnumElements( 0, NULL, 0, &ptrEnum ); if( FAILED(hResult) ) { ptrRootStg->Release(); return 0; } TCHAR szSwap[MAX_PATH] = { 0 }; LARGE_INTEGER nStorageLength; nStorageLength.QuadPart = 0; STATSTG StatStg = { 0 }; while( S_OK == hResult ) { hResult = ptrEnum->Next( 1, &StatStg, NULL ); if( S_FALSE == hResult ) { ptrRootStg->Release(); ptrEnum->Release(); // m_wndCatalog.Expand(strFolder); if( !FolderStack.empty() ) { TCHAR szCurText[MAX_PATH] = {0}; m_wndCatalog.GetItemText(htiParent, szCurText, _countof(szCurText)); CString strTotal; strTotal.Format(TEXT("%s(%ld)"), szCurText, nStorageLength); m_wndCatalog.SetItemText(htiParent, strTotal); ptrRootStg = FolderStack.top().pStg; ptrEnum = FolderStack.top().pEnum; htiParent = FolderStack.top().hParent; FolderStack.pop(); hResult = S_OK; } continue; } switch(StatStg.type) { case STGTY_STORAGE: // 是存储对象, "文件夹" { //先清零 nStorageLength.QuadPart = 0; IStorage * ptrChildStg = NULL; HRESULT hr = ptrRootStg->OpenStorage( StatStg.pwcsName, NULL, STGM_READWRITE|STGM_SHARE_EXCLUSIVE, 0, 0, &ptrChildStg ); if( SUCCEEDED(hr) ) { TREE_ITEM_DATA * pData = new TREE_ITEM_DATA(ptrChildStg, StatStg.type); HTREEITEM hFolder = m_wndCatalog.InsertItem ( TVIF_IMAGE|TVIF_TEXT|TVIF_PARAM|TVIF_SELECTEDIMAGE, WCHAR2TCHAR(StatStg.pwcsName, szSwap, _countof(szSwap)), 0, 1, TVIS_EXPANDED, 0, reinterpret_cast<LPARAM>(pData), htiParent, NULL); // 父存储入栈 FolderStack.push( StgInfo(ptrRootStg, ptrEnum, htiParent) ); // 子存储替代父存储 ptrRootStg = ptrChildStg; htiParent = hFolder; hr = ptrChildStg->EnumElements( 0, NULL, 0, &ptrEnum ); } } break; case STGTY_STREAM: // 是流, "文件" { CComPtr<IStream> spStream; HRESULT hr = ptrRootStg->OpenStream(StatStg.pwcsName, NULL, STGM_READWRITE|STGM_SHARE_EXCLUSIVE, 0, &spStream); ATLASSERT(SUCCEEDED(hr)); LARGE_INTEGER nSeekPos; nSeekPos.QuadPart = 0LL; ULARGE_INTEGER nLength = {0}; hr = spStream->Seek(nSeekPos, STREAM_SEEK_END, &nLength); CString strStreamName; WCHAR2TCHAR(StatStg.pwcsName, szSwap, _countof(szSwap)); if (SUCCEEDED(hr)) { nStorageLength.QuadPart += nLength.QuadPart; strStreamName.Format(TEXT("%s(%ld)"), szSwap, nLength); } else { strStreamName.Format(TEXT("%s(0)"), szSwap); } TREE_ITEM_DATA * pData = new TREE_ITEM_DATA(spStream, StatStg.type); m_wndCatalog.InsertItem ( TVIF_IMAGE|TVIF_TEXT|TVIF_PARAM|TVIF_SELECTEDIMAGE, strStreamName, 2, 2, TVIS_EXPANDED, 0, reinterpret_cast<LPARAM>(pData), htiParent, NULL); } break; case STGTY_LOCKBYTES: ATLTRACE(_T("===== STGTY_LOCKBYTES %d ====="), StatStg.type); break; case STGTY_PROPERTY: ATLTRACE(_T("===== STGTY_PROPERTY %d ====="), StatStg.type); break; default: ATLASSERT(!_T("Unknown storage type!!!")); break; } ::CoTaskMemFree( StatStg.pwcsName ); // 释放名称所使用的内存 } return 0; }
BOOL CDocFile::Load(TCHAR* wszFilePath) { IStorage *pStorage = NULL; IPropertySetStorage *pPropSetStg = NULL; IStream *pStream = NULL, *pTableStream = NULL; HRESULT hr; // Open the document as an OLE compound document. hr = ::StgOpenStorage(wszFilePath, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &pStorage); if(FAILED(hr)) { _tprintf( L"A file is locked by another program: [%s]\n", wszFilePath); return FALSE; } #ifdef CONTENT_EXTRACTION hr = pStorage->OpenStream(L"WordDocument", NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &pStream); if(FAILED(hr)) { _tprintf( L"A file is invalid or damaged: [%s]\n", wszFilePath); pStorage->Release(); return FALSE; } STATSTG stat; pStream->Stat(&stat, 0); UINT size = (UINT) stat.cbSize.QuadPart; BYTE *buffer = new BYTE[size]; USHORT usFlag; INT pdcOffset; UINT pdcLength; LARGE_INTEGER liTmpSeek; ULONG cbRead; liTmpSeek.QuadPart = 10; pStream->Seek(liTmpSeek, 0, NULL); pStream->Read(&usFlag, 2, &cbRead); liTmpSeek.QuadPart = 418; pStream->Seek(liTmpSeek, 0, NULL); pStream->Read(&pdcOffset, 4, &cbRead); pStream->Read(&pdcLength, 4, &cbRead); hr = pStorage->OpenStream((usFlag & (0x1 << 9)) ? L"1Table" : L"0Table", NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &pTableStream); liTmpSeek.QuadPart = pdcOffset; pTableStream->Seek(liTmpSeek, 0, NULL); INT nCount = 0; INT *aOffsets = NULL; struct Desc { BYTE Flags; BYTE Fn; UINT32 Fc; SHORT Prm; } *aDescs = NULL; UINT nPointer = 0; while (nPointer < pdcLength) { BYTE nType = 0; pTableStream->Read(&nType, 1, &cbRead); switch(nType) { case 0: BYTE nTmp; pTableStream->Read(&nTmp, 1, &cbRead); nPointer++; break; case 1: { SHORT cbGrpprl; BYTE *grpprlData = NULL; pTableStream->Read(&cbGrpprl, 2, &cbRead); nPointer+=2; grpprlData = new BYTE[cbGrpprl]; pTableStream->Read(grpprlData, cbGrpprl, &cbRead); nPointer+=cbGrpprl; delete grpprlData; break; } case 2: INT nTableLen = 0; pTableStream->Read(&nTableLen, 4, &cbRead); nPointer+=4; nCount = (nTableLen - 4) / (8 + 4) + 1; aOffsets = new INT[nCount]; for(int i = 0; i < nCount; i++) { pTableStream->Read(&aOffsets[i], 4, &cbRead); nPointer +=4; } aDescs = new Desc[nCount-1]; for(int i = 0; i < nCount-1; i++) { pTableStream->Read(&aDescs[i].Flags, 1, &cbRead); pTableStream->Read(&aDescs[i].Fn, 1, &cbRead); pTableStream->Read(&aDescs[i].Fc, 4, &cbRead); pTableStream->Read(&aDescs[i].Prm, 2, &cbRead); nPointer+=sizeof(struct Desc); } break; } } for (int i = 0; i < nCount - 1; i++) { UINT pieceStart = 0xffffffff; UINT pieceEnd = 0xffffffff; BOOL bUnicode = FALSE; bUnicode = (aDescs[i].Fc & (1 << 30)) == 0 ? 1 : 0; if (!bUnicode) pieceStart = (aDescs[i].Fc & ~(1 << 30)) / 2; else pieceStart = aDescs[i].Fc; UINT nLength = aOffsets[i + 1] - aOffsets[i]; pieceEnd = pieceStart + nLength * (bUnicode ? 2 : 1); liTmpSeek.QuadPart = pieceStart; hr = pStream->Seek(liTmpSeek, 0, NULL); //m_wszContent += ReadString(documentReader, pieceEnd - pieceStart, isUnicode); if (nLength == 0) continue; for (UINT i = 0; i < nLength; i++) { if (!bUnicode) { BYTE ch = 0; pStream->Read(&ch, 1, NULL); m_wszContent += (CHAR)ch; } else { SHORT ch = 0; pStream->Read(&ch, 2, NULL); m_wszContent += (WCHAR)ch; } } } pStream->Release(); pTableStream->Release(); #endif // Obtain the IPropertySetStorage interface. hr = pStorage->QueryInterface(IID_IPropertySetStorage, (void **)&pPropSetStg); IPropertyStorage *pPropStg = NULL; struct pidsiStruct { TCHAR *name; LONG pid; } pidsiArr[] = { {L"Author", PIDSI_AUTHOR}, {L"Title", PIDSI_TITLE}, {L"Subject", PIDSI_SUBJECT}, {L"Keywords", PIDSI_KEYWORDS}, {L"Status", PIDMSI_STATUS}, {L"AppName", PIDSI_APPNAME}, {L"Comments", PIDSI_COMMENTS}, {L"Template", PIDSI_TEMPLATE}, {L"Revision Number", PIDSI_REVNUMBER}, {L"Created", PIDSI_CREATE_DTM}, {L"Edit Time", PIDSI_EDITTIME}, {L"Last Saved", PIDSI_LASTSAVE_DTM}, {L"LastAuthor", PIDSI_LASTAUTHOR}, {L"Last printed", PIDSI_LASTPRINTED}, {L"Page Count", PIDSI_PAGECOUNT}, {L"Word Count", PIDSI_WORDCOUNT}, {L"Char Count", PIDSI_CHARCOUNT}, {L"Thumbnail", PIDSI_THUMBNAIL}, {L"Doc Security", PIDSI_DOC_SECURITY}, {0, 0} }, pidsdiArr[] = { {L"Company", PIDDSI_COMPANY}, {L"Slide notes", PIDDSI_SLIDECOUNT}, {0, 0} }; // Count elements in pidsiArr. INT nPidsi = 0, nPidsdi = 0; for(nPidsi=0; pidsiArr[nPidsi].name; nPidsi++); for(nPidsdi=0; pidsdiArr[nPidsdi].name; nPidsdi++); // Initialize PROPSPEC for the properties you want. PROPSPEC *pPropSpec = new PROPSPEC [nPidsi]; PROPVARIANT *pPropVar = new PROPVARIANT [nPidsi]; PROPSPEC *pDocPropSpec = new PROPSPEC [nPidsdi]; PROPVARIANT *pDocPropVar = new PROPVARIANT [nPidsdi]; for(INT i=0; i<nPidsi; i++) { ZeroMemory(&pPropSpec[i], sizeof(PROPSPEC)); pPropSpec[i].ulKind = PRSPEC_PROPID; pPropSpec[i].propid = pidsiArr[i].pid; } for(INT i=0; i<nPidsdi; i++) { ZeroMemory(&pDocPropSpec[i], sizeof(PROPSPEC)); pDocPropSpec[i].ulKind = PRSPEC_PROPID; pDocPropSpec[i].propid = pidsdiArr[i].pid; } // Obtain meta infos from FMTID_SummaryInformation hr = pPropSetStg->Open(FMTID_SummaryInformation, STGM_READ | STGM_SHARE_EXCLUSIVE, &pPropStg); // Read properties. hr = pPropStg->ReadMultiple(nPidsi, pPropSpec, pPropVar); if(FAILED(hr)) { _tprintf(L"IPropertyStg::ReadMultiple() failed w/error %08lx",hr); } pPropStg->Release(); pPropStg = NULL; // Obtain meta infos from FMTID_DocSummaryInformation hr = pPropSetStg->Open(FMTID_DocSummaryInformation, STGM_READ | STGM_SHARE_EXCLUSIVE, &pPropStg); // Read properties. hr = pPropStg->ReadMultiple(nPidsdi, pDocPropSpec, pDocPropVar); if(FAILED(hr)) { _tprintf(L"IPropertyStg::ReadMultiple() failed w/error %08lx",hr); } pPropStg->Release(); // Copy Meta fields out from FMTID_SummaryInformation for(int i = 0; i < nPidsi; i++) { switch(pidsiArr[i].pid) { case PIDSI_AUTHOR: DumpPropVariant(pPropVar + i, m_wszAuthor, MAX_META_LEN); break; case PIDSI_TITLE: DumpPropVariant(pPropVar + i, m_wszTitle, MAX_META_LEN); break; case PIDSI_SUBJECT: DumpPropVariant(pPropVar + i, m_wszSubject, MAX_META_LEN); break; case PIDSI_KEYWORDS: DumpPropVariant(pPropVar + i, m_wszKeywords, MAX_META_LEN); break; case PIDSI_APPNAME: DumpPropVariant(pPropVar + i, m_wszApplication, MAX_META_LEN); break; case PIDSI_COMMENTS: DumpPropVariant(pPropVar + i, m_wszComments, MAX_META_LEN); break; case PIDSI_TEMPLATE: DumpPropVariant(pPropVar + i, m_wszTemplateUsed, MAX_META_LEN); break; case PIDSI_REVNUMBER: DumpPropVariant(pPropVar + i, m_wszRevisionNumber, MAX_META_LEN); break; case PIDSI_EDITTIME: DumpPropVariant(pPropVar + i, m_wszTotalEditingTime, MAX_META_LEN); break; case PIDSI_LASTSAVE_DTM: DumpPropVariant(pPropVar + i, m_wszLastSaved, MAX_META_LEN); break; case PIDSI_LASTAUTHOR: DumpPropVariant(pPropVar + i, m_wszLastEditedBy, MAX_META_LEN); break; case PIDSI_LASTPRINTED: DumpPropVariant(pPropVar + i, m_wszLastPrinted, MAX_META_LEN); break; case PIDSI_PAGECOUNT: DumpPropVariant(pPropVar + i, m_wszPageCount, MAX_META_LEN); break; case PIDSI_WORDCOUNT: DumpPropVariant(pPropVar + i, m_wszWordCount, MAX_META_LEN); break; case PIDSI_CHARCOUNT: DumpPropVariant(pPropVar + i, m_wszCharacterCount, MAX_META_LEN); break; } } // Copy Meta fields out from FMTID_DocSummaryInformation for(int i = 0; i < nPidsdi; i++) { switch(pidsdiArr[i].pid) { case PIDDSI_COMPANY: DumpPropVariant(pDocPropVar + i, m_wszCompany, MAX_META_LEN); break; } } // De-allocate memory. delete [] pPropVar; delete [] pPropSpec; delete [] pDocPropVar; delete [] pDocPropSpec; // Release obtained interface. pPropSetStg->Release(); pStorage->Release(); return TRUE; }