static HRESULT WINAPI ITS_IMonikerImpl_BindToStorage( IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, void** ppvObj) { ITS_IMonikerImpl *This = (ITS_IMonikerImpl *)iface; DWORD grfMode = STGM_SIMPLE | STGM_READ | STGM_SHARE_EXCLUSIVE; HRESULT r; IStorage *stg = NULL; TRACE("%p %p %p %s %p\n", This, pbc, pmkToLeft, debugstr_guid(riid), ppvObj); r = ITSS_StgOpenStorage( This->szFile, NULL, grfMode, 0, 0, &stg ); if( r == S_OK ) { TRACE("Opened storage %s\n", debugstr_w( This->szFile ) ); if (IsEqualGUID(riid, &IID_IStream)) r = IStorage_OpenStream( stg, This->szHtml, NULL, grfMode, 0, (IStream**)ppvObj ); else if (IsEqualGUID(riid, &IID_IStorage)) r = IStorage_OpenStorage( stg, This->szHtml, NULL, grfMode, NULL, 0, (IStorage**)ppvObj ); else r = STG_E_ACCESSDENIED; IStorage_Release( stg ); } return r; }
static void test_olestream(void) { HRESULT hr; const CLSID non_existent_class = {0xa5f1772f, 0x3772, 0x490f, {0x9e, 0xc6, 0x77, 0x13, 0xe8, 0xb3, 0x4b, 0x5d}}; IOleObject *ole_obj; IPersistStorage *persist; IStorage *stg; IStream *stm; static const WCHAR olestream[] = {1,'O','l','e',0}; ULONG read; ole_stream_header_t header; hr = create_storage(&stg); ok(hr == S_OK, "got %08x\n", hr); hr = IStorage_OpenStream(stg, olestream, NULL, STGM_SHARE_EXCLUSIVE | STGM_READ, 0, &stm); ok(hr == STG_E_FILENOTFOUND, "got %08x\n", hr); hr = OleCreateDefaultHandler(&non_existent_class, 0, &IID_IOleObject, (void**)&ole_obj); ok(hr == S_OK, "got %08x\n", hr); hr = IOleObject_QueryInterface(ole_obj, &IID_IPersistStorage, (void**)&persist); ok(hr == S_OK, "got %08x\n", hr); hr = IPersistStorage_InitNew(persist, stg); ok(hr == S_OK, "got %08x\n", hr); hr = IStorage_OpenStream(stg, olestream, NULL, STGM_SHARE_EXCLUSIVE | STGM_READ, 0, &stm); ok(hr == S_OK, "got %08x\n", hr); hr = IStream_Read(stm, &header, sizeof(header), &read); ok(hr == S_OK, "got %08x\n", hr); ok(read == sizeof(header), "read %d\n", read); ok(header.version == 0x02000001, "got version %08x\n", header.version); ok(header.flags == 0x0, "got flags %08x\n", header.flags); ok(header.link_update_opt == 0x0, "got link update option %08x\n", header.link_update_opt); ok(header.res == 0x0, "got reserved %08x\n", header.res); ok(header.moniker_size == 0x0, "got moniker size %08x\n", header.moniker_size); IStream_Release(stm); IPersistStorage_Release(persist); IOleObject_Release(ole_obj); IStorage_Release(stg); }
/* Reads a string from the #STRINGS section in the CHM file */ static LPWSTR CHM_ReadString(CHMInfo *pChmInfo, DWORD dwOffset) { LARGE_INTEGER liOffset; IStorage *pStorage = pChmInfo->pStorage; IStream *pStream; DWORD cbRead; ULONG iPos; DWORD dwSize; LPSTR szString; LPWSTR stringW; const int CB_READ_BLOCK = 64; static const WCHAR stringsW[] = {'#','S','T','R','I','N','G','S',0}; dwSize = CB_READ_BLOCK; szString = HeapAlloc(GetProcessHeap(), 0, dwSize); if (FAILED(IStorage_OpenStream(pStorage, stringsW, NULL, STGM_READ, 0, &pStream))) return NULL; liOffset.QuadPart = dwOffset; if (FAILED(IStream_Seek(pStream, liOffset, STREAM_SEEK_SET, NULL))) { IStream_Release(pStream); return NULL; } while (SUCCEEDED(IStream_Read(pStream, szString, CB_READ_BLOCK, &cbRead))) { if (!cbRead) return NULL; for (iPos = 0; iPos < cbRead; iPos++) { if (!szString[iPos]) { stringW = CHM_ANSIToUnicode(szString); HeapFree(GetProcessHeap(), 0, szString); return stringW; } } dwSize *= 2; szString = HeapReAlloc(GetProcessHeap(), 0, szString, dwSize); szString += cbRead; } /* didn't find a string */ return NULL; }
/* Loads the HH_WINTYPE data from the CHM file * * FIXME: There may be more than one window type in the file, so * add the ability to choose a certain window type */ BOOL CHM_LoadWinTypeFromCHM(CHMInfo *pChmInfo, HH_WINTYPEW *pHHWinType) { LARGE_INTEGER liOffset; IStorage *pStorage = pChmInfo->pStorage; IStream *pStream; HRESULT hr; DWORD cbRead; static const WCHAR windowsW[] = {'#','W','I','N','D','O','W','S',0}; hr = IStorage_OpenStream(pStorage, windowsW, NULL, STGM_READ, 0, &pStream); if (FAILED(hr)) return FALSE; /* jump past the #WINDOWS header */ liOffset.QuadPart = sizeof(DWORD) * 2; hr = IStream_Seek(pStream, liOffset, STREAM_SEEK_SET, NULL); if (FAILED(hr)) goto done; /* read the HH_WINTYPE struct data */ hr = IStream_Read(pStream, pHHWinType, sizeof(*pHHWinType), &cbRead); if (FAILED(hr)) goto done; /* convert the #STRINGS offsets to actual strings */ pHHWinType->pszType = CHM_ReadString(pChmInfo, (DWORD)pHHWinType->pszType); pHHWinType->pszCaption = CHM_ReadString(pChmInfo, (DWORD)pHHWinType->pszCaption); pHHWinType->pszToc = CHM_ReadString(pChmInfo, (DWORD)pHHWinType->pszToc); pHHWinType->pszIndex = CHM_ReadString(pChmInfo, (DWORD)pHHWinType->pszIndex); pHHWinType->pszFile = CHM_ReadString(pChmInfo, (DWORD)pHHWinType->pszFile); pHHWinType->pszHome = CHM_ReadString(pChmInfo, (DWORD)pHHWinType->pszHome); pHHWinType->pszJump1 = CHM_ReadString(pChmInfo, (DWORD)pHHWinType->pszJump1); pHHWinType->pszJump2 = CHM_ReadString(pChmInfo, (DWORD)pHHWinType->pszJump2); pHHWinType->pszUrlJump1 = CHM_ReadString(pChmInfo, (DWORD)pHHWinType->pszUrlJump1); pHHWinType->pszUrlJump2 = CHM_ReadString(pChmInfo, (DWORD)pHHWinType->pszUrlJump2); /* FIXME: pszCustomTabs is a list of multiple zero-terminated strings so ReadString won't * work in this case */ #if 0 pHHWinType->pszCustomTabs = CHM_ReadString(pChmInfo, (DWORD)pHHWinType->pszCustomTabs); #endif done: IStream_Release(pStream); return SUCCEEDED(hr); }
/*********************************************************************** * MsiSIPGetSignedDataMsg (MSISIP.@) */ BOOL WINAPI MsiSIPGetSignedDataMsg(SIP_SUBJECTINFO *pSubjectInfo, DWORD *pdwEncodingType, DWORD dwIndex, DWORD *pcbSignedDataMsg, BYTE *pbSignedDataMsg) { static const WCHAR digitalSig[] = { 5,'D','i','g','i','t','a','l', 'S','i','g','n','a','t','u','r','e',0 }; BOOL ret = FALSE; IStorage *stg = NULL; HRESULT r; IStream *stm = NULL; BYTE hdr[2], len[sizeof(DWORD)]; DWORD count, lenBytes, dataBytes; TRACE("(%p %p %d %p %p)\n", pSubjectInfo, pdwEncodingType, dwIndex, pcbSignedDataMsg, pbSignedDataMsg); r = StgOpenStorage(pSubjectInfo->pwsFileName, NULL, STGM_DIRECT|STGM_READ|STGM_SHARE_DENY_WRITE, NULL, 0, &stg); if (FAILED(r)) { TRACE("couldn't open %s\n", debugstr_w(pSubjectInfo->pwsFileName)); goto end; } r = IStorage_OpenStream(stg, digitalSig, 0, STGM_READ|STGM_SHARE_EXCLUSIVE, 0, &stm); if (FAILED(r)) { TRACE("couldn't find digital signature stream\n"); goto freestorage; } r = IStream_Read(stm, hdr, sizeof(hdr), &count); if (FAILED(r) || count != sizeof(hdr)) goto freestream; if (hdr[0] != 0x30) { WARN("unexpected data in digital sig: 0x%02x%02x\n", hdr[0], hdr[1]); goto freestream; } /* Read the asn.1 length from the stream. Only supports definite-length * values, which DER-encoded signatures should be. */ if (hdr[1] == 0x80) { WARN("indefinite-length encoding not supported!\n"); goto freestream; } else if (hdr[1] & 0x80) { DWORD temp; LPBYTE ptr; lenBytes = hdr[1] & 0x7f; if (lenBytes > sizeof(DWORD)) { WARN("asn.1 length too long (%d)\n", lenBytes); goto freestream; } r = IStream_Read(stm, len, lenBytes, &count); if (FAILED(r) || count != lenBytes) goto freestream; dataBytes = 0; temp = lenBytes; ptr = len; while (temp--) { dataBytes <<= 8; dataBytes |= *ptr++; } } else { lenBytes = 0; dataBytes = hdr[1]; } if (!pbSignedDataMsg) { *pcbSignedDataMsg = 2 + lenBytes + dataBytes; ret = TRUE; } else if (*pcbSignedDataMsg < 2 + lenBytes + dataBytes) { SetLastError(ERROR_INSUFFICIENT_BUFFER); *pcbSignedDataMsg = 2 + lenBytes + dataBytes; } else { LPBYTE ptr = pbSignedDataMsg; memcpy(ptr, hdr, sizeof(hdr)); ptr += sizeof(hdr); if (lenBytes) { memcpy(ptr, len, lenBytes); ptr += lenBytes; } r = IStream_Read(stm, ptr, dataBytes, &count); if (SUCCEEDED(r) && count == dataBytes) { *pdwEncodingType = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING; *pcbSignedDataMsg = 2 + lenBytes + dataBytes; ret = TRUE; } } freestream: IStream_Release(stm); freestorage: IStorage_Release(stg); end: TRACE("returning %d\n", ret); return ret; }
/* Search the CHM storage stream (an HTML file) for the requested text. * * Before searching the HTML file all HTML tags are removed so that only * the content of the document is scanned. If the search string is found * then the title of the document is returned. */ static WCHAR *SearchCHM_File(IStorage *pStorage, const WCHAR *file, const char *needle) { char *buffer = heap_alloc(BLOCK_SIZE); strbuf_t content, node, node_name; IStream *temp_stream = NULL; DWORD i, buffer_size = 0; WCHAR *title = NULL; BOOL found = FALSE; stream_t stream; HRESULT hres; hres = IStorage_OpenStream(pStorage, file, NULL, STGM_READ, 0, &temp_stream); if(FAILED(hres)) { FIXME("Could not open '%s' stream: %08x\n", debugstr_w(file), hres); goto cleanup; } strbuf_init(&node); strbuf_init(&content); strbuf_init(&node_name); stream_init(&stream, temp_stream); /* Remove all HTML formatting and record the title */ while(next_node(&stream, &node)) { get_node_name(&node, &node_name); if(next_content(&stream, &content) && content.len > 1) { char *text = &content.buf[1]; int textlen = content.len-1; if(!strcasecmp(node_name.buf, "title")) { int wlen = MultiByteToWideChar(CP_ACP, 0, text, textlen, NULL, 0); title = heap_alloc((wlen+1)*sizeof(WCHAR)); MultiByteToWideChar(CP_ACP, 0, text, textlen, title, wlen); title[wlen] = 0; } buffer = heap_realloc(buffer, buffer_size + textlen + 1); memcpy(&buffer[buffer_size], text, textlen); buffer[buffer_size + textlen] = '\0'; buffer_size += textlen; } strbuf_zero(&node); strbuf_zero(&content); } /* Convert the buffer to lower case for comparison against the * requested text (already in lower case). */ for(i=0;i<buffer_size;i++) buffer[i] = tolower(buffer[i]); /* Search the decoded buffer for the requested text */ if(strstr(buffer, needle)) found = TRUE; strbuf_free(&node); strbuf_free(&content); strbuf_free(&node_name); cleanup: heap_free(buffer); if(temp_stream) IStream_Release(temp_stream); if(!found) { heap_free(title); return NULL; } return title; }