static HRESULT WINAPI NoStatStreamImpl_Write( IStream* iface, const void* pv, /* [size_is][in] */ ULONG cb, /* [in] */ ULONG* pcbWritten) /* [out] */ { NoStatStreamImpl* const This=(NoStatStreamImpl*)iface; void* supportBuffer; ULARGE_INTEGER newSize; ULONG bytesWritten = 0; if (pcbWritten == 0) pcbWritten = &bytesWritten; if (cb == 0) return S_OK; newSize.u.HighPart = 0; newSize.u.LowPart = This->currentPosition.u.LowPart + cb; if (newSize.u.LowPart > This->streamSize.u.LowPart) IStream_SetSize(iface, newSize); supportBuffer = GlobalLock(This->supportHandle); memcpy((char *) supportBuffer+This->currentPosition.u.LowPart, pv, cb); This->currentPosition.u.LowPart+=cb; *pcbWritten = cb; GlobalUnlock(This->supportHandle); return S_OK; }
static HRESULT WINAPI IDirectMusicLoaderGenericStream_IStream_SetSize (LPSTREAM iface, ULARGE_INTEGER libNewSize) { ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream, StreamVtbl, iface); TRACE("(%p, 0x%08llX): redirecting to low-level stream\n", This, libNewSize.QuadPart); if (!This->pStream) return E_FAIL; return IStream_SetSize (This->pStream, libNewSize); }
static HRESULT WINAPI IWICStreamImpl_SetSize(IWICStream *iface, ULARGE_INTEGER libNewSize) { IWICStreamImpl *This = impl_from_IWICStream(iface); TRACE("(%p): relay\n", This); if (!This->pStream) return WINCODEC_ERR_NOTINITIALIZED; return IStream_SetSize(This->pStream, libNewSize); }
/* read the data in a file into an IStream */ static UINT RECORD_StreamFromFile(LPCWSTR szFile, IStream **pstm) { DWORD sz, szHighWord = 0, read; HANDLE handle; HGLOBAL hGlob = 0; HRESULT hr; ULARGE_INTEGER ulSize; TRACE("reading %s\n", debugstr_w(szFile)); /* read the file into memory */ handle = CreateFileW(szFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); if( handle == INVALID_HANDLE_VALUE ) return GetLastError(); sz = GetFileSize(handle, &szHighWord); if( sz != INVALID_FILE_SIZE && szHighWord == 0 ) { hGlob = GlobalAlloc(GMEM_FIXED, sz); if( hGlob ) { BOOL r = ReadFile(handle, hGlob, sz, &read, NULL) && read == sz; if( !r ) { GlobalFree(hGlob); hGlob = 0; } } } CloseHandle(handle); if( !hGlob ) return ERROR_FUNCTION_FAILED; /* make a stream out of it, and set the correct file size */ hr = CreateStreamOnHGlobal(hGlob, TRUE, pstm); if( FAILED( hr ) ) { GlobalFree(hGlob); return ERROR_FUNCTION_FAILED; } /* set the correct size - CreateStreamOnHGlobal screws it up */ ulSize.QuadPart = sz; IStream_SetSize(*pstm, ulSize); TRACE("read %s, %d bytes into IStream %p\n", debugstr_w(szFile), sz, *pstm); return ERROR_SUCCESS; }
static void test_freed_hglobal(void) { static const char teststring[] = "this is a test string"; HRESULT hr; IStream *pStream; HGLOBAL hglobal; char *p; char buffer[sizeof(teststring) + 8]; ULARGE_INTEGER ull; ULONG read, written; hglobal = GlobalAlloc(GMEM_DDESHARE|GMEM_NODISCARD|GMEM_MOVEABLE, strlen(teststring) + 1); ok(hglobal != NULL, "GlobalAlloc failed with error %d\n", GetLastError()); p = GlobalLock(hglobal); strcpy(p, teststring); GlobalUnlock(hglobal); hr = CreateStreamOnHGlobal(hglobal, FALSE, &pStream); ok_ole_success(hr, "CreateStreamOnHGlobal"); hr = IStream_Read(pStream, buffer, sizeof(buffer), &read); ok_ole_success(hr, "IStream_Read"); ok(!strcmp(buffer, teststring), "buffer data %s differs\n", buffer); ok(read == sizeof(teststring) || broken(read == ((sizeof(teststring) + 3) & ~3)), /* win9x rounds the size */ "read should be sizeof(teststring) instead of %d\n", read); GlobalFree(hglobal); memset(buffer, 0, sizeof(buffer)); read = -1; hr = IStream_Read(pStream, buffer, sizeof(buffer), &read); ok_ole_success(hr, "IStream_Read"); ok(buffer[0] == 0, "buffer data should be untouched\n"); ok(read == 0, "read should be 0 instead of %d\n", read); ull.QuadPart = sizeof(buffer); hr = IStream_SetSize(pStream, ull); ok(hr == E_OUTOFMEMORY, "IStream_SetSize with invalid HGLOBAL should return E_OUTOFMEMORY instead of 0x%08x\n", hr); hr = IStream_Write(pStream, buffer, sizeof(buffer), &written); ok(hr == E_OUTOFMEMORY, "IStream_Write with invalid HGLOBAL should return E_OUTOFMEMORY instead of 0x%08x\n", hr); ok(written == 0, "written should be 0 instead of %d\n", written); IStream_Release(pStream); }
static GpBitmap * gdip_buffer_to_bitmap (GdipContext *context, GError **error) { HRESULT hr; HGLOBAL hg = NULL; GpBitmap *bitmap = NULL; IStream *stream = NULL; GpStatus status; guint64 size64 = context->buffer->len; hg = gdip_buffer_to_hglobal (context->buffer->data, context->buffer->len, error); if (!hg) return NULL; hr = CreateStreamOnHGlobal (hg, FALSE, (LPSTREAM *)&stream); if (!SUCCEEDED (hr)) { gdip_set_error_from_hresult (error, GDK_PIXBUF_ERROR_FAILED, hr, _("Could not create stream: %s")); GlobalFree (hg); return NULL; } IStream_SetSize (stream, *(ULARGE_INTEGER *)&size64); status = GdipCreateBitmapFromStream (stream, &bitmap); if (Ok != status) { gdip_set_error_from_gpstatus (error, GDK_PIXBUF_ERROR_FAILED, status); IStream_Release (stream); GlobalFree (hg); return NULL; } context->stream = stream; context->hg = hg; return bitmap; }
static void test_createconfigstream(void) { IStream *stream = NULL; WCHAR file[] = {'c', 'o', 'n', 'f', '.', 'x', 'm', 'l', 0}; WCHAR nonexistent[] = {'n', 'o', 'n', 'e', 'x', 'i', 's', 't', '.', 'x', 'm', 'l', 0}; WCHAR path[MAX_PATH]; HRESULT hr; char buffer[256] = {0}; if (!pCreateConfigStream) { win_skip("CreateConfigStream not available\n"); return; } create_xml_file(file); GetFullPathNameW(file, MAX_PATH, path, NULL); hr = pCreateConfigStream(NULL, &stream); ok(hr == E_FAIL || broken(hr == HRESULT_FROM_WIN32(ERROR_PROC_NOT_FOUND)) || /* some WinXP, Win2K3 and Win7 */ broken(hr == S_OK && !stream), /* some Win2K3 */ "CreateConfigStream returned %x\n", hr); hr = pCreateConfigStream(path, NULL); ok(hr == COR_E_NULLREFERENCE, "CreateConfigStream returned %x\n", hr); hr = pCreateConfigStream(NULL, NULL); ok(hr == COR_E_NULLREFERENCE, "CreateConfigStream returned %x\n", hr); hr = pCreateConfigStream(nonexistent, &stream); ok(hr == COR_E_FILENOTFOUND, "CreateConfigStream returned %x\n", hr); ok(stream == NULL, "Expected stream to be NULL\n"); hr = pCreateConfigStream(path, &stream); ok(hr == S_OK, "CreateConfigStream failed, hr=%x\n", hr); ok(stream != NULL, "Expected non-NULL stream\n"); if (stream) { DWORD count; LARGE_INTEGER pos; ULARGE_INTEGER size; IStream *stream2 = NULL; ULONG ref; hr = IStream_Read(stream, buffer, strlen(xmldata), &count); ok(hr == S_OK, "IStream_Read failed, hr=%x\n", hr); ok(count == strlen(xmldata), "wrong count: %u\n", count); ok(!strcmp(buffer, xmldata), "Strings do not match\n"); hr = IStream_Read(stream, buffer, sizeof(buffer), &count); ok(hr == S_OK, "IStream_Read failed, hr=%x\n", hr); ok(!count, "wrong count: %u\n", count); hr = IStream_Write(stream, xmldata, strlen(xmldata), &count); ok(hr == E_FAIL, "IStream_Write returned hr=%x\n", hr); pos.QuadPart = strlen(xmldata); hr = IStream_Seek(stream, pos, STREAM_SEEK_SET, NULL); ok(hr == E_NOTIMPL, "IStream_Seek returned hr=%x\n", hr); size.QuadPart = strlen(xmldata); hr = IStream_SetSize(stream, size); ok(hr == E_NOTIMPL, "IStream_SetSize returned hr=%x\n", hr); hr = IStream_Clone(stream, &stream2); ok(hr == E_NOTIMPL, "IStream_Clone returned hr=%x\n", hr); hr = IStream_Commit(stream, STGC_DEFAULT); ok(hr == E_NOTIMPL, "IStream_Commit returned hr=%x\n", hr); hr = IStream_Revert(stream); ok(hr == E_NOTIMPL, "IStream_Revert returned hr=%x\n", hr); ref = IStream_Release(stream); ok(!ref, "IStream_Release returned %u\n", ref); } DeleteFileW(file); }
/*** * This method is part of the ISequentialStream interface. * * It writes a block of information to the stream at the current * position. It then moves the current position at the end of the * written block. If the stream is too small to fit the block, * the stream is grown to fit. * * See the documentation of ISequentialStream for more info. */ static HRESULT WINAPI HGLOBALStreamImpl_Write( IStream* iface, const void* pv, /* [size_is][in] */ ULONG cb, /* [in] */ ULONG* pcbWritten) /* [out] */ { HGLOBALStreamImpl* const This=(HGLOBALStreamImpl*)iface; void* supportBuffer; ULARGE_INTEGER newSize; ULONG bytesWritten = 0; TRACE("(%p, %p, %d, %p)\n", iface, pv, cb, pcbWritten); /* * If the caller is not interested in the number of bytes written, * we use another buffer to avoid "if" statements in the code. */ if (pcbWritten == 0) pcbWritten = &bytesWritten; if (cb == 0) goto out; *pcbWritten = 0; newSize.u.HighPart = 0; newSize.u.LowPart = This->currentPosition.u.LowPart + cb; /* * Verify if we need to grow the stream */ if (newSize.u.LowPart > This->streamSize.u.LowPart) { /* grow stream */ HRESULT hr = IStream_SetSize(iface, newSize); if (FAILED(hr)) { ERR("IStream_SetSize failed with error 0x%08x\n", hr); return hr; } } /* * Lock the buffer in position and copy the data. */ supportBuffer = GlobalLock(This->supportHandle); if (!supportBuffer) { WARN("write to invalid hglobal %p\n", This->supportHandle); return S_OK; } memcpy((char *) supportBuffer+This->currentPosition.u.LowPart, pv, cb); /* * Move the current position to the new position */ This->currentPosition.u.LowPart+=cb; /* * Cleanup */ GlobalUnlock(This->supportHandle); out: /* * Return the number of bytes read. */ *pcbWritten = cb; return S_OK; }
static void test_saxreader(void) { HRESULT hr; ISAXXMLReader *reader = NULL; VARIANT var; ISAXContentHandler *lpContentHandler; ISAXErrorHandler *lpErrorHandler; SAFEARRAY *pSA; SAFEARRAYBOUND SADim[1]; char *pSAData = NULL; IStream *iStream; ULARGE_INTEGER liSize; LARGE_INTEGER liPos; ULONG bytesWritten; HANDLE file; static const CHAR testXmlA[] = "test.xml"; static const WCHAR testXmlW[] = {'t','e','s','t','.','x','m','l',0}; IXMLDOMDocument *domDocument; BSTR bstrData; VARIANT_BOOL vBool; hr = CoCreateInstance(&CLSID_SAXXMLReader, NULL, CLSCTX_INPROC_SERVER, &IID_ISAXXMLReader, (LPVOID*)&reader); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); hr = ISAXXMLReader_getContentHandler(reader, NULL); ok(hr == E_POINTER, "Expected E_POINTER, got %08x\n", hr); hr = ISAXXMLReader_getErrorHandler(reader, NULL); ok(hr == E_POINTER, "Expected E_POINTER, got %08x\n", hr); hr = ISAXXMLReader_getContentHandler(reader, &lpContentHandler); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); ok(lpContentHandler == NULL, "Expected %p, got %p\n", NULL, lpContentHandler); hr = ISAXXMLReader_getErrorHandler(reader, &lpErrorHandler); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); ok(lpErrorHandler == NULL, "Expected %p, got %p\n", NULL, lpErrorHandler); hr = ISAXXMLReader_putContentHandler(reader, NULL); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); hr = ISAXXMLReader_putContentHandler(reader, &contentHandler); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); hr = ISAXXMLReader_putErrorHandler(reader, &errorHandler); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); hr = ISAXXMLReader_getContentHandler(reader, &lpContentHandler); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); ok(lpContentHandler == &contentHandler, "Expected %p, got %p\n", &contentHandler, lpContentHandler); V_VT(&var) = VT_BSTR; V_BSTR(&var) = SysAllocString(szSimpleXML); expectCall = contentHandlerTest1; hr = ISAXXMLReader_parse(reader, var); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); test_expect_call(CH_ENDTEST); VariantClear(&var); SADim[0].lLbound= 0; SADim[0].cElements= sizeof(szTestXML)-1; pSA = SafeArrayCreate(VT_UI1, 1, SADim); SafeArrayAccessData(pSA, (void**)&pSAData); memcpy(pSAData, szTestXML, sizeof(szTestXML)-1); SafeArrayUnaccessData(pSA); V_VT(&var) = VT_ARRAY|VT_UI1; V_ARRAY(&var) = pSA; expectCall = contentHandlerTest1; hr = ISAXXMLReader_parse(reader, var); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); test_expect_call(CH_ENDTEST); SafeArrayDestroy(pSA); CreateStreamOnHGlobal(NULL, TRUE, &iStream); liSize.QuadPart = strlen(szTestXML); IStream_SetSize(iStream, liSize); IStream_Write(iStream, szTestXML, strlen(szTestXML), &bytesWritten); liPos.QuadPart = 0; IStream_Seek(iStream, liPos, STREAM_SEEK_SET, NULL); V_VT(&var) = VT_UNKNOWN|VT_DISPATCH; V_UNKNOWN(&var) = (IUnknown*)iStream; expectCall = contentHandlerTest1; hr = ISAXXMLReader_parse(reader, var); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); test_expect_call(CH_ENDTEST); IStream_Release(iStream); V_VT(&var) = VT_BSTR; V_BSTR(&var) = SysAllocString(szCarriageRetTest); expectCall = contentHandlerTest2; hr = ISAXXMLReader_parse(reader, var); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); test_expect_call(CH_ENDTEST); VariantClear(&var); file = CreateFileA(testXmlA, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); ok(file != INVALID_HANDLE_VALUE, "Could not create file: %u\n", GetLastError()); WriteFile(file, szTestXML, sizeof(szTestXML)-1, &bytesWritten, NULL); CloseHandle(file); expectCall = contentHandlerTest1; hr = ISAXXMLReader_parseURL(reader, testXmlW); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); test_expect_call(CH_ENDTEST); DeleteFileA(testXmlA); hr = CoCreateInstance(&CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&domDocument); if(FAILED(hr)) { skip("Failed to create DOMDocument instance\n"); return; } bstrData = SysAllocString(szSimpleXML); hr = IXMLDOMDocument_loadXML(domDocument, bstrData, &vBool); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); V_VT(&var) = VT_UNKNOWN; V_UNKNOWN(&var) = (IUnknown*)domDocument; expectCall = contentHandlerTest2; hr = ISAXXMLReader_parse(reader, var); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); test_expect_call(CH_ENDTEST); IXMLDOMDocument_Release(domDocument); ISAXXMLReader_Release(reader); SysFreeString(bstrData); }
/*** * This method is part of the ISequentialStream interface. * * It writes a block of information to the stream at the current * position. It then moves the current position at the end of the * written block. If the stream is too small to fit the block, * the stream is grown to fit. * * See the documentation of ISequentialStream for more info. */ static HRESULT WINAPI StgStreamImpl_Write( IStream* iface, const void* pv, /* [size_is][in] */ ULONG cb, /* [in] */ ULONG* pcbWritten) /* [out] */ { StgStreamImpl* const This=(StgStreamImpl*)iface; ULARGE_INTEGER newSize; ULONG bytesWritten = 0; TRACE("(%p, %p, %ld, %p)\n", iface, pv, cb, pcbWritten); /* * Do we have permission to write to this stream? */ switch(STGM_ACCESS_MODE(This->grfMode)) { case STGM_WRITE: case STGM_READWRITE: break; default: WARN("access denied by flags: 0x%lx\n", STGM_ACCESS_MODE(This->grfMode)); return STG_E_ACCESSDENIED; } if (!pv) return STG_E_INVALIDPOINTER; if (!This->parentStorage) { WARN("storage reverted\n"); return STG_E_REVERTED; } /* * If the caller is not interested in the number of bytes written, * we use another buffer to avoid "if" statements in the code. */ if (pcbWritten == 0) pcbWritten = &bytesWritten; /* * Initialize the out parameter */ *pcbWritten = 0; if (cb == 0) { TRACE("<-- S_OK, written 0\n"); return S_OK; } else { newSize.u.HighPart = 0; newSize.u.LowPart = This->currentPosition.u.LowPart + cb; } /* * Verify if we need to grow the stream */ if (newSize.u.LowPart > This->streamSize.u.LowPart) { /* grow stream */ IStream_SetSize(iface, newSize); } /* * Depending on the type of chain that was opened when the stream was constructed, * we delegate the work to the method that readwrites to the block chains. */ if (This->smallBlockChain!=0) { SmallBlockChainStream_WriteAt(This->smallBlockChain, This->currentPosition, cb, pv, pcbWritten); } else if (This->bigBlockChain!=0) { BlockChainStream_WriteAt(This->bigBlockChain, This->currentPosition, cb, pv, pcbWritten); } else assert(FALSE); /* * Advance the position pointer for the number of positions written. */ This->currentPosition.u.LowPart += *pcbWritten; TRACE("<-- S_OK, written %lu\n", *pcbWritten); return S_OK; }
static void test_streamonhglobal(IStream *pStream) { const char data[] = "Test String"; ULARGE_INTEGER ull; LARGE_INTEGER ll; char buffer[128]; ULONG read; STATSTG statstg; HRESULT hr; ull.QuadPart = sizeof(data); hr = IStream_SetSize(pStream, ull); ok_ole_success(hr, "IStream_SetSize"); hr = IStream_Write(pStream, data, sizeof(data), NULL); ok_ole_success(hr, "IStream_Write"); ll.QuadPart = 0; hr = IStream_Seek(pStream, ll, STREAM_SEEK_SET, NULL); ok_ole_success(hr, "IStream_Seek"); /* should return S_OK, not S_FALSE */ hr = IStream_Read(pStream, buffer, sizeof(buffer), &read); ok_ole_success(hr, "IStream_Read"); ok(read == sizeof(data), "IStream_Read returned read %d\n", read); /* ignores HighPart */ ull.u.HighPart = -1; ull.u.LowPart = 0; hr = IStream_SetSize(pStream, ull); ok_ole_success(hr, "IStream_SetSize"); /* IStream_Seek -- NULL position argument */ ll.u.HighPart = 0; ll.u.LowPart = 0; hr = IStream_Seek(pStream, ll, STREAM_SEEK_CUR, NULL); ok_ole_success(hr, "IStream_Seek"); /* IStream_Seek -- valid position argument (seek from current position) */ ull.u.HighPart = 0xCAFECAFE; ull.u.LowPart = 0xCAFECAFE; ll.u.HighPart = 0; ll.u.LowPart = 0; hr = IStream_Seek(pStream, ll, STREAM_SEEK_CUR, &ull); ok_ole_success(hr, "IStream_Seek"); ok(ull.u.LowPart == sizeof(data), "LowPart set to %d\n", ull.u.LowPart); ok(ull.u.HighPart == 0, "should have set HighPart to 0 instead of %d\n", ull.u.HighPart); /* IStream_Seek -- invalid seek argument */ ull.u.HighPart = 0xCAFECAFE; ull.u.LowPart = 0xCAFECAFE; ll.u.HighPart = 0; ll.u.LowPart = 123; hr = IStream_Seek(pStream, ll, STREAM_SEEK_END+1, &ull); ok(hr == STG_E_SEEKERROR, "IStream_Seek should have returned STG_E_SEEKERROR instead of 0x%08x\n", hr); ok(ull.u.LowPart == sizeof(data), "LowPart set to %d\n", ull.u.LowPart); ok(ull.u.HighPart == 0, "should not have changed HighPart, got %d\n", ull.u.HighPart); /* IStream_Seek -- valid position argument (seek to beginning) */ ull.u.HighPart = 0xCAFECAFE; ull.u.LowPart = 0xCAFECAFE; ll.u.HighPart = 0; ll.u.LowPart = 0; hr = IStream_Seek(pStream, ll, STREAM_SEEK_SET, &ull); ok_ole_success(hr, "IStream_Seek"); ok(ull.u.LowPart == 0, "should have set LowPart to 0 instead of %d\n", ull.u.LowPart); ok(ull.u.HighPart == 0, "should have set HighPart to 0 instead of %d\n", ull.u.HighPart); /* IStream_Seek -- valid position argument (seek to end) */ ull.u.HighPart = 0xCAFECAFE; ull.u.LowPart = 0xCAFECAFE; ll.u.HighPart = 0; ll.u.LowPart = 0; hr = IStream_Seek(pStream, ll, STREAM_SEEK_END, &ull); ok_ole_success(hr, "IStream_Seek"); ok(ull.u.LowPart == 0, "should have set LowPart to 0 instead of %d\n", ull.u.LowPart); ok(ull.u.HighPart == 0, "should have set HighPart to 0 instead of %d\n", ull.u.HighPart); /* IStream_Seek -- ignore HighPart in the move value (seek from current position) */ ll.u.HighPart = 0; ll.u.LowPart = sizeof(data); hr = IStream_Seek(pStream, ll, STREAM_SEEK_SET, &ull); ok_ole_success(hr, "IStream_Seek"); ull.u.HighPart = 0xCAFECAFE; ull.u.LowPart = 0xCAFECAFE; ll.u.HighPart = -1; ll.u.LowPart = 0; hr = IStream_Seek(pStream, ll, STREAM_SEEK_CUR, &ull); ok_ole_success(hr, "IStream_Seek"); ok(ull.u.LowPart == sizeof(data), "LowPart set to %d\n", ull.u.LowPart); ok(ull.u.HighPart == 0, "should have set HighPart to 0 instead of %d\n", ull.u.HighPart); /* IStream_Seek -- ignore HighPart in the move value (seek to beginning) */ ll.u.HighPart = 0; ll.u.LowPart = sizeof(data); hr = IStream_Seek(pStream, ll, STREAM_SEEK_SET, &ull); ok_ole_success(hr, "IStream_Seek"); ull.u.HighPart = 0xCAFECAFE; ull.u.LowPart = 0xCAFECAFE; ll.u.HighPart = -1; ll.u.LowPart = 0; hr = IStream_Seek(pStream, ll, STREAM_SEEK_SET, &ull); ok_ole_success(hr, "IStream_Seek"); ok(ull.u.LowPart == 0, "should have set LowPart to 0 instead of %d\n", ull.u.LowPart); ok(ull.u.HighPart == 0, "should have set HighPart to 0 instead of %d\n", ull.u.HighPart); /* IStream_Seek -- invalid LowPart value (seek before start of stream) */ ll.u.HighPart = 0; ll.u.LowPart = sizeof(data); hr = IStream_Seek(pStream, ll, STREAM_SEEK_SET, &ull); ok_ole_success(hr, "IStream_Seek"); ull.u.HighPart = 0xCAFECAFE; ull.u.LowPart = 0xCAFECAFE; ll.u.HighPart = 0; ll.u.LowPart = 0x80000000; hr = IStream_Seek(pStream, ll, STREAM_SEEK_CUR, &ull); ok(hr == STG_E_SEEKERROR, "IStream_Seek should have returned STG_E_SEEKERROR instead of 0x%08x\n", hr); ok(ull.u.LowPart == sizeof(data), "LowPart set to %d\n", ull.u.LowPart); ok(ull.u.HighPart == 0, "should have set HighPart to 0 instead of %d\n", ull.u.HighPart); /* IStream_Seek -- valid LowPart value (seek to start of stream) */ ll.u.HighPart = 0; ll.u.LowPart = sizeof(data); hr = IStream_Seek(pStream, ll, STREAM_SEEK_SET, &ull); ok_ole_success(hr, "IStream_Seek"); ull.u.HighPart = 0xCAFECAFE; ull.u.LowPart = 0xCAFECAFE; ll.u.HighPart = 0; ll.u.LowPart = -(DWORD)sizeof(data); hr = IStream_Seek(pStream, ll, STREAM_SEEK_CUR, &ull); ok_ole_success(hr, "IStream_Seek"); ok(ull.u.LowPart == 0, "LowPart set to %d\n", ull.u.LowPart); ok(ull.u.HighPart == 0, "should have set HighPart to 0 instead of %d\n", ull.u.HighPart); /* IStream_Seek -- invalid LowPart value (seek to start of stream-1) */ ll.u.HighPart = 0; ll.u.LowPart = sizeof(data); hr = IStream_Seek(pStream, ll, STREAM_SEEK_SET, &ull); ok_ole_success(hr, "IStream_Seek"); ull.u.HighPart = 0xCAFECAFE; ull.u.LowPart = 0xCAFECAFE; ll.u.HighPart = 0; ll.u.LowPart = -(DWORD)sizeof(data)-1; hr = IStream_Seek(pStream, ll, STREAM_SEEK_CUR, &ull); ok(hr == STG_E_SEEKERROR, "IStream_Seek should have returned STG_E_SEEKERROR instead of 0x%08x\n", hr); ok(ull.u.LowPart == sizeof(data), "LowPart set to %d\n", ull.u.LowPart); ok(ull.u.HighPart == 0, "should have set HighPart to 0 instead of %d\n", ull.u.HighPart); /* IStream_Seek -- valid LowPart value (seek forward to 0x80000000) */ ll.u.HighPart = 0; ll.u.LowPart = sizeof(data); hr = IStream_Seek(pStream, ll, STREAM_SEEK_SET, &ull); ok_ole_success(hr, "IStream_Seek"); ull.u.HighPart = 0xCAFECAFE; ull.u.LowPart = 0xCAFECAFE; ll.u.HighPart = 0; ll.u.LowPart = 0x80000000 - sizeof(data); hr = IStream_Seek(pStream, ll, STREAM_SEEK_CUR, &ull); ok_ole_success(hr, "IStream_Seek"); ok(ull.u.LowPart == 0x80000000, "LowPart set to %d\n", ull.u.LowPart); ok(ull.u.HighPart == 0, "should have set HighPart to 0 instead of %d\n", ull.u.HighPart); /* IStream_Seek -- invalid LowPart value (seek to beginning) */ ll.u.HighPart = 0; ll.u.LowPart = sizeof(data); hr = IStream_Seek(pStream, ll, STREAM_SEEK_SET, &ull); ok_ole_success(hr, "IStream_Seek"); ull.u.HighPart = 0xCAFECAFE; ull.u.LowPart = 0xCAFECAFE; ll.u.HighPart = 0; ll.u.LowPart = 0x80000000; hr = IStream_Seek(pStream, ll, STREAM_SEEK_SET, &ull); ok(hr == STG_E_SEEKERROR, "IStream_Seek should have returned STG_E_SEEKERROR instead of 0x%08x\n", hr); ok(ull.u.LowPart == sizeof(data), "LowPart set to %d\n", ull.u.LowPart); ok(ull.u.HighPart == 0, "should have set HighPart to 0 instead of %d\n", ull.u.HighPart); /* IStream_Seek -- valid LowPart value (seek to beginning) */ ull.u.HighPart = 0xCAFECAFE; ull.u.LowPart = 0xCAFECAFE; ll.u.HighPart = 0; ll.u.LowPart = 0x7FFFFFFF; hr = IStream_Seek(pStream, ll, STREAM_SEEK_SET, &ull); ok_ole_success(hr, "IStream_Seek"); ok(ull.u.LowPart == 0x7FFFFFFF, "should have set LowPart to 0x7FFFFFFF instead of %08x\n", ull.u.LowPart); ok(ull.u.HighPart == 0, "should have set HighPart to 0 instead of %d\n", ull.u.HighPart); /* IStream_Seek -- valid LowPart value (seek from current position) */ ll.u.HighPart = 0; ll.u.LowPart = 0; hr = IStream_Seek(pStream, ll, STREAM_SEEK_SET, &ull); ok_ole_success(hr, "IStream_Seek"); ull.u.HighPart = 0xCAFECAFE; ull.u.LowPart = 0xCAFECAFE; ll.u.HighPart = 0; ll.u.LowPart = 0x7FFFFFFF; hr = IStream_Seek(pStream, ll, STREAM_SEEK_CUR, &ull); ok_ole_success(hr, "IStream_Seek"); ok(ull.u.LowPart == 0x7FFFFFFF, "should have set LowPart to 0x7FFFFFFF instead of %08x\n", ull.u.LowPart); ok(ull.u.HighPart == 0, "should have set HighPart to 0 instead of %d\n", ull.u.HighPart); /* IStream_Seek -- second seek allows you to go past 0x7FFFFFFF size */ ull.u.HighPart = 0xCAFECAFE; ull.u.LowPart = 0xCAFECAFE; ll.u.HighPart = 0; ll.u.LowPart = 9; hr = IStream_Seek(pStream, ll, STREAM_SEEK_CUR, &ull); ok_ole_success(hr, "IStream_Seek"); ok(ull.u.LowPart == 0x80000008, "should have set LowPart to 0x80000008 instead of %08x\n", ull.u.LowPart); ok(ull.u.HighPart == 0, "should have set HighPart to 0 instead of %d\n", ull.u.HighPart); /* IStream_Seek -- seek wraps position/size on integer overflow */ ull.u.HighPart = 0xCAFECAFE; ull.u.LowPart = 0xCAFECAFE; ll.u.HighPart = 0; ll.u.LowPart = 0x7FFFFFFF; hr = IStream_Seek(pStream, ll, STREAM_SEEK_CUR, &ull); ok_ole_success(hr, "IStream_Seek"); ok(ull.u.LowPart == 0x00000007, "should have set LowPart to 0x00000007 instead of %08x\n", ull.u.LowPart); ok(ull.u.HighPart == 0, "should have set HighPart to 0 instead of %d\n", ull.u.HighPart); hr = IStream_Commit(pStream, STGC_DEFAULT); ok_ole_success(hr, "IStream_Commit"); hr = IStream_Revert(pStream); ok_ole_success(hr, "IStream_Revert"); hr = IStream_LockRegion(pStream, ull, ull, LOCK_WRITE); ok(hr == STG_E_INVALIDFUNCTION, "IStream_LockRegion should have returned STG_E_INVALIDFUNCTION instead of 0x%08x\n", hr); hr = IStream_Stat(pStream, &statstg, STATFLAG_DEFAULT); ok_ole_success(hr, "IStream_Stat"); ok(statstg.type == STGTY_STREAM, "statstg.type should have been STGTY_STREAM instead of %d\n", statstg.type); /* test OOM condition */ ull.u.HighPart = -1; ull.u.LowPart = -1; hr = IStream_SetSize(pStream, ull); ok(hr == E_OUTOFMEMORY || broken(hr == S_OK), /* win9x */ "IStream_SetSize with large size should have returned E_OUTOFMEMORY instead of 0x%08x\n", hr); }