Пример #1
0
MSIRECORD *MSI_CloneRecord(MSIRECORD *rec)
{
    MSIRECORD *clone;
    UINT r, i, count;

    count = MSI_RecordGetFieldCount(rec);
    clone = MSI_CreateRecord(count);
    if (!clone)
        return NULL;

    for (i = 0; i <= count; i++)
    {
        if (rec->fields[i].type == MSIFIELD_STREAM)
        {
            if (FAILED(IStream_Clone(rec->fields[i].u.stream,
                                     &clone->fields[i].u.stream)))
            {
                msiobj_release(&clone->hdr);
                return NULL;
            }
            clone->fields[i].type = MSIFIELD_STREAM;
        }
        else
        {
            r = MSI_RecordCopyField(rec, i, clone, i);
            if (r != ERROR_SUCCESS)
            {
                msiobj_release(&clone->hdr);
                return NULL;
            }
        }
    }

    return clone;
}
Пример #2
0
static HRESULT WINAPI IDirectMusicBandImpl_IDirectMusicObject_SetDescriptor (LPDIRECTMUSICOBJECT iface, LPDMUS_OBJECTDESC pDesc) {
	ICOM_THIS_MULTI(IDirectMusicBandImpl, ObjectVtbl, iface);
	TRACE("(%p, %p): setting descriptor:\n", This, pDesc); debug_DMUS_OBJECTDESC (pDesc);

	/* According to MSDN, we should copy only given values, not whole struct */	
	if (pDesc->dwValidData & DMUS_OBJ_OBJECT)
		This->pDesc->guidObject = pDesc->guidObject;
	if (pDesc->dwValidData & DMUS_OBJ_CLASS)
		This->pDesc->guidClass = pDesc->guidClass;
	if (pDesc->dwValidData & DMUS_OBJ_NAME)
		lstrcpynW (This->pDesc->wszName, pDesc->wszName, DMUS_MAX_NAME);
	if (pDesc->dwValidData & DMUS_OBJ_CATEGORY)
		lstrcpynW (This->pDesc->wszCategory, pDesc->wszCategory, DMUS_MAX_CATEGORY);
	if (pDesc->dwValidData & DMUS_OBJ_FILENAME)
		lstrcpynW (This->pDesc->wszFileName, pDesc->wszFileName, DMUS_MAX_FILENAME);
	if (pDesc->dwValidData & DMUS_OBJ_VERSION)
		This->pDesc->vVersion = pDesc->vVersion;
	if (pDesc->dwValidData & DMUS_OBJ_DATE)
		This->pDesc->ftDate = pDesc->ftDate;
	if (pDesc->dwValidData & DMUS_OBJ_MEMORY) {
		This->pDesc->llMemLength = pDesc->llMemLength;
		memcpy (This->pDesc->pbMemData, pDesc->pbMemData, pDesc->llMemLength);
	}
	if (pDesc->dwValidData & DMUS_OBJ_STREAM) {
		/* according to MSDN, we copy the stream */
		IStream_Clone (pDesc->pStream, &This->pDesc->pStream);	
	}
	
	/* add new flags */
	This->pDesc->dwValidData |= pDesc->dwValidData;

	return S_OK;
}
Пример #3
0
static HRESULT WINAPI IWICStreamImpl_Clone(IWICStream *iface,
    IStream **ppstm)
{
    IWICStreamImpl *This = impl_from_IWICStream(iface);
    TRACE("(%p): relay\n", This);

    if (!This->pStream) return WINCODEC_ERR_NOTINITIALIZED;
    return IStream_Clone(This->pStream, ppstm);
}
Пример #4
0
static void test_copyto(void)
{
    IStream *pStream, *pStream2;
    HRESULT hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
    static const char szHello[] = "Hello";
    ULARGE_INTEGER cb;
    static const char *methods_copyto[] =
    {
        "TestStream_Write",
        NULL
    };
    ULONG written;
    ULARGE_INTEGER ullRead;
    ULARGE_INTEGER ullWritten;
    ULARGE_INTEGER libNewPosition;
    static const LARGE_INTEGER llZero;
    char buffer[15];

    ok_ole_success(hr, "CreateStreamOnHGlobal");

    expected_method_list = methods_copyto;

    hr = IStream_Write(pStream, szHello, sizeof(szHello), &written);
    ok_ole_success(hr, "IStream_Write");
    ok(written == sizeof(szHello), "only %d bytes written\n", written);

    hr = IStream_Seek(pStream, llZero, STREAM_SEEK_SET, NULL);
    ok_ole_success(hr, "IStream_Seek");

    cb.QuadPart = sizeof(szHello);
    hr = IStream_CopyTo(pStream, &Test_Stream, cb, &ullRead, &ullWritten);
    ok(ullWritten.QuadPart == 5, "ullWritten was %d instead\n", (ULONG)ullWritten.QuadPart);
    ok(ullRead.QuadPart == sizeof(szHello), "only %d bytes read\n", (ULONG)ullRead.QuadPart);
    ok_ole_success(hr, "IStream_CopyTo");

    ok(!*expected_method_list, "Method sequence starting from %s not called\n", *expected_method_list);

    hr = IStream_Clone(pStream, &pStream2);
    ok_ole_success(hr, "IStream_Clone");

    hr = IStream_Seek(pStream2, llZero, STREAM_SEEK_CUR, &libNewPosition);
    ok_ole_success(hr, "IStream_Seek");
    ok(libNewPosition.QuadPart == sizeof(szHello), "libNewPosition wasn't set correctly for the cloned stream\n");

    hr = IStream_Seek(pStream2, llZero, STREAM_SEEK_SET, NULL);
    ok_ole_success(hr, "IStream_Seek");

    hr = IStream_Read(pStream2, buffer, sizeof(buffer), NULL);
    ok_ole_success(hr, "IStream_Read");
    ok(!strcmp(buffer, szHello), "read data \"%s\" didn't match originally written data\n", buffer);

    IStream_Release(pStream2);
    IStream_Release(pStream);
}
Пример #5
0
static HRESULT WINAPI IDirectMusicLoaderGenericStream_IStream_Clone (LPSTREAM iface, IStream** ppstm) {
	ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream, StreamVtbl, iface);
	LPSTREAM pOther = NULL;
	LPSTREAM pLowLevel = NULL;
	HRESULT result;

	TRACE("(%p, %p)\n", iface, ppstm);
	result = DMUSIC_CreateDirectMusicLoaderGenericStream ((LPVOID*)&pOther);
	if (FAILED(result)) return result;
	
	if (FAILED(IStream_Clone (This->pStream, &pLowLevel)))
		return E_FAIL;
	
	IDirectMusicLoaderGenericStream_Attach (pOther, pLowLevel, This->pLoader);

	TRACE(": succeeded\n");
	*ppstm = (IStream*)pOther;
	return S_OK;
}
Пример #6
0
/* Custom : */
HRESULT WINAPI IDirectMusicLoaderGenericStream_Attach (LPSTREAM iface, LPSTREAM pStream, LPDIRECTMUSICLOADER8 pLoader) {
	ICOM_THIS_MULTI(IDirectMusicLoaderGenericStream, StreamVtbl, iface);
    
	TRACE("(%p, %p, %p)\n", This, pStream, pLoader);
	if (!pStream) {
		WARN(": invalid pStream\n");
		return E_FAIL;
	}
	if (!pLoader) {
		WARN(": invalid pLoader\n");
		return E_FAIL;
	}	
	
	IDirectMusicLoaderGenericStream_Detach (iface);
	IStream_Clone (pStream, &This->pStream);
	This->pLoader = pLoader;
	
    return S_OK;
}
Пример #7
0
HRESULT WINAPI dmobj_IDirectMusicObject_SetDescriptor(IDirectMusicObject *iface,
        DMUS_OBJECTDESC *desc)
{
    struct dmobject *This = impl_from_IDirectMusicObject(iface);
    HRESULT ret = S_OK;

    TRACE("(%p, %p)\n", iface, desc);

    if (!desc)
        return E_POINTER;

    /* Immutable property */
    if (desc->dwValidData & DMUS_OBJ_CLASS)
    {
        desc->dwValidData &= ~DMUS_OBJ_CLASS;
        ret = S_FALSE;
    }
    /* Set only valid fields */
    if (desc->dwValidData & DMUS_OBJ_OBJECT)
        This->desc.guidObject = desc->guidObject;
    if (desc->dwValidData & DMUS_OBJ_NAME)
        lstrcpynW(This->desc.wszName, desc->wszName, DMUS_MAX_NAME);
    if (desc->dwValidData & DMUS_OBJ_CATEGORY)
        lstrcpynW(This->desc.wszCategory, desc->wszCategory, DMUS_MAX_CATEGORY);
    if (desc->dwValidData & DMUS_OBJ_FILENAME)
        lstrcpynW(This->desc.wszFileName, desc->wszFileName, DMUS_MAX_FILENAME);
    if (desc->dwValidData & DMUS_OBJ_VERSION)
        This->desc.vVersion = desc->vVersion;
    if (desc->dwValidData & DMUS_OBJ_DATE)
        This->desc.ftDate = desc->ftDate;
    if (desc->dwValidData & DMUS_OBJ_MEMORY) {
        This->desc.llMemLength = desc->llMemLength;
        memcpy(This->desc.pbMemData, desc->pbMemData, desc->llMemLength);
    }
    if (desc->dwValidData & DMUS_OBJ_STREAM)
        IStream_Clone(desc->pStream, &This->desc.pStream);

    This->desc.dwValidData |= desc->dwValidData;

    return ret;
}
Пример #8
0
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);
}
Пример #9
0
static HRESULT IDirectMusicStyle8Impl_IPersistStream_ParseStyleForm (LPPERSISTSTREAM iface, DMUS_PRIVATE_CHUNK* pChunk, IStream* pStm) {
  ICOM_THIS_MULTI(IDirectMusicStyle8Impl, PersistStreamVtbl, iface);

  HRESULT hr = E_FAIL;
  DMUS_PRIVATE_CHUNK Chunk;
  DWORD StreamSize, StreamCount, ListSize[3], ListCount[3];
  LARGE_INTEGER liMove; /* used when skipping chunks */

  IDirectMusicBand* pBand = NULL;

  if (pChunk->fccID != DMUS_FOURCC_STYLE_FORM) {
    ERR_(dmfile)(": %s chunk should be a STYLE form\n", debugstr_fourcc (pChunk->fccID));
    return E_FAIL;
  }  

  StreamSize = pChunk->dwSize - sizeof(FOURCC);
  StreamCount = 0;

  do {
    IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
    StreamCount += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
    TRACE_(dmfile)(": %s chunk (size = %d)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
    
    hr = IDirectMusicUtils_IPersistStream_ParseDescGeneric(&Chunk, pStm, This->pDesc);
    if (FAILED(hr)) return hr;

    if (hr == S_FALSE) {
      switch (Chunk.fccID) {
      case DMUS_FOURCC_STYLE_CHUNK: {
	TRACE_(dmfile)(": Style chunk\n");
	IStream_Read (pStm, &This->style, sizeof(DMUS_IO_STYLE), NULL);
	/** TODO dump DMUS_IO_TIMESIG style.timeSig */
	TRACE_(dmfile)(" - dblTempo: %g\n", This->style.dblTempo);
	break;
      }   
      case FOURCC_RIFF: {
	/**
	 * should be embedded Bands into style
	 */
	IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL);
	TRACE_(dmfile)(": RIFF chunk of type %s", debugstr_fourcc(Chunk.fccID));
	ListSize[0] = Chunk.dwSize - sizeof(FOURCC);
	ListCount[0] = 0;
	switch (Chunk.fccID) {
	case DMUS_FOURCC_BAND_FORM: { 
	  LPSTREAM pClonedStream = NULL;
	  LPDMUS_PRIVATE_STYLE_BAND pNewBand;

	  TRACE_(dmfile)(": BAND RIFF\n");
	  
	  IStream_Clone (pStm, &pClonedStream);
	    
	  liMove.QuadPart = 0;
	  liMove.QuadPart -= sizeof(FOURCC) + (sizeof(FOURCC)+sizeof(DWORD));
	  IStream_Seek (pClonedStream, liMove, STREAM_SEEK_CUR, NULL);
	  
	  hr = IDirectMusicStyle8Impl_IPersistStream_LoadBand (iface, pClonedStream, &pBand);
	  if (FAILED(hr)) {
	    ERR(": could not load track\n");
	    return hr;
	  }
	  IStream_Release (pClonedStream);
	  
	  pNewBand = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, sizeof(DMUS_PRIVATE_STYLE_BAND));
	  if (NULL == pNewBand) {
	    ERR(": no more memory\n");
	    return  E_OUTOFMEMORY;
	  }
	  pNewBand->pBand = pBand;
	  IDirectMusicBand_AddRef(pBand);
	  list_add_tail (&This->Bands, &pNewBand->entry);

	  IDirectMusicTrack_Release(pBand); pBand = NULL;  /* now we can release it as it's inserted */
	
	  /** now safely move the cursor */
	  liMove.QuadPart = ListSize[0];
	  IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
	  
	  break;
	}
	default: {
	  TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n");
	  liMove.QuadPart = ListSize[0];
	  IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
	  break;
	}
	}
	break;
      }
      case FOURCC_LIST: {
	IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL);
	TRACE_(dmfile)(": LIST chunk of type %s", debugstr_fourcc(Chunk.fccID));
	ListSize[0] = Chunk.dwSize - sizeof(FOURCC);
	ListCount[0] = 0;
	switch (Chunk.fccID) {
	case DMUS_FOURCC_UNFO_LIST: { 
	  TRACE_(dmfile)(": UNFO list\n");
	  do {
	    IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
	    ListCount[0] += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
            TRACE_(dmfile)(": %s chunk (size = %d)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
	    
	    hr = IDirectMusicUtils_IPersistStream_ParseUNFOGeneric(&Chunk, pStm, This->pDesc);
	    if (FAILED(hr)) return hr;
	    
	    if (hr == S_FALSE) {
	      switch (Chunk.fccID) {
	      default: {
		TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n");
		liMove.QuadPart = Chunk.dwSize;
		IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
		break;				
	      }
	      }
	    }  
            TRACE_(dmfile)(": ListCount[0] = %d < ListSize[0] = %d\n", ListCount[0], ListSize[0]);
	  } while (ListCount[0] < ListSize[0]);
	  break;
	}
	case DMUS_FOURCC_PART_LIST: {
	  TRACE_(dmfile)(": PART list\n");
	  hr = IDirectMusicStyle8Impl_IPersistStream_ParsePartList (iface, &Chunk, pStm);
	  if (FAILED(hr)) return hr;
	  break;
	}
	case  DMUS_FOURCC_PATTERN_LIST: {
	  TRACE_(dmfile)(": PATTERN list\n");
	  hr = IDirectMusicStyle8Impl_IPersistStream_ParsePatternList (iface, &Chunk, pStm);
	  if (FAILED(hr)) return hr;
	  break;
	}
	default: {
	  TRACE_(dmfile)(": unknown (skipping)\n");
	  liMove.QuadPart = Chunk.dwSize - sizeof(FOURCC);
	  IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
	  break;						
	}
	}
	break;
      }
      default: {
	TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n");
	liMove.QuadPart = Chunk.dwSize;
	IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
	break;						
      }
      }
    }
    TRACE_(dmfile)(": StreamCount[0] = %d < StreamSize[0] = %d\n", StreamCount, StreamSize);
  } while (StreamCount < StreamSize);  

  return S_OK;
}
Пример #10
0
static HRESULT IDirectMusicStyle8Impl_IPersistStream_ParsePatternList (LPPERSISTSTREAM iface, DMUS_PRIVATE_CHUNK* pChunk, IStream* pStm) {

  ICOM_THIS_MULTI(IDirectMusicStyle8Impl, PersistStreamVtbl, iface);
  HRESULT hr = E_FAIL;
  DMUS_PRIVATE_CHUNK Chunk;
  DWORD ListSize[3], ListCount[3];
  LARGE_INTEGER liMove; /* used when skipping chunks */

  DMUS_OBJECTDESC desc;
  IDirectMusicBand* pBand = NULL;
  LPDMUS_PRIVATE_STYLE_MOTIF pNewMotif = NULL;

  DM_STRUCT_INIT(&desc);

  if (pChunk->fccID != DMUS_FOURCC_PATTERN_LIST) {
    ERR_(dmfile)(": %s chunk should be a PATTERN list\n", debugstr_fourcc (pChunk->fccID));
    return E_FAIL;
  }  

  ListSize[0] = pChunk->dwSize - sizeof(FOURCC);
  ListCount[0] = 0;

  do {
    IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
    ListCount[0] += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
    TRACE_(dmfile)(": %s chunk (size = %d)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
    switch (Chunk.fccID) {
    case DMUS_FOURCC_PATTERN_CHUNK: {
      TRACE_(dmfile)(": Pattern chunk\n");
      /** alloc new motif entry */
      pNewMotif = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, sizeof(DMUS_PRIVATE_STYLE_MOTIF));
      list_add_tail (&This->Motifs, &pNewMotif->entry);
      if (NULL == pNewMotif) {
	ERR(": no more memory\n");
	return  E_OUTOFMEMORY;
      }

      IStream_Read (pStm, &pNewMotif->pattern, Chunk.dwSize, NULL);
      /** TODO trace pattern */

      /** reset all data, as a new pattern begin */
      DM_STRUCT_INIT(&pNewMotif->desc);
      list_init (&pNewMotif->Items);
      break;
    }
    case DMUS_FOURCC_RHYTHM_CHUNK: { 
      TRACE_(dmfile)(": Rhythm chunk\n");
      IStream_Read (pStm, &pNewMotif->dwRhythm, sizeof(DWORD), NULL);
      TRACE_(dmfile)(" - dwRhythm: %u\n", pNewMotif->dwRhythm);
      /** TODO understand why some Chunks have size > 4 */
      liMove.QuadPart = Chunk.dwSize - sizeof(DWORD);
      IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
      break;
    }
    case DMUS_FOURCC_MOTIFSETTINGS_CHUNK: {
      TRACE_(dmfile)(": MotifSettings chunk (skipping for now)\n");
      IStream_Read (pStm, &pNewMotif->settings, Chunk.dwSize, NULL);
      /** TODO trace settings */
      break;
    }
    case FOURCC_RIFF: {
      /**
       * should be embedded Bands into pattern
       */
      IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL);
      TRACE_(dmfile)(": RIFF chunk of type %s", debugstr_fourcc(Chunk.fccID));
      ListSize[1] = Chunk.dwSize - sizeof(FOURCC);
      ListCount[1] = 0;
      switch (Chunk.fccID) {
      case DMUS_FOURCC_BAND_FORM: { 
	LPSTREAM pClonedStream = NULL;
	
	TRACE_(dmfile)(": BAND RIFF\n");
	
	IStream_Clone (pStm, &pClonedStream);
	
	liMove.QuadPart = 0;
	liMove.QuadPart -= sizeof(FOURCC) + (sizeof(FOURCC)+sizeof(DWORD));
	IStream_Seek (pClonedStream, liMove, STREAM_SEEK_CUR, NULL);
	
	hr = IDirectMusicStyle8Impl_IPersistStream_LoadBand (iface, pClonedStream, &pBand);
	if (FAILED(hr)) {
	  ERR(": could not load track\n");
	  return hr;
	}
	IStream_Release (pClonedStream);
	
	pNewMotif->pBand = pBand;
	IDirectMusicBand_AddRef(pBand);

	IDirectMusicTrack_Release(pBand); pBand = NULL;  /* now we can release it as it's inserted */
	
	/** now safe move the cursor */
	liMove.QuadPart = ListSize[1];
	IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
	
	break;
      }
      default: {
	TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n");
	liMove.QuadPart = ListSize[1];
	IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
	break;
      }
      }
      break;
    }
    case FOURCC_LIST: {
      IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL);
      TRACE_(dmfile)(": LIST chunk of type %s", debugstr_fourcc(Chunk.fccID));
      ListSize[1] = Chunk.dwSize - sizeof(FOURCC);
      ListCount[1] = 0;
      switch (Chunk.fccID) {
      case DMUS_FOURCC_UNFO_LIST: { 
	TRACE_(dmfile)(": UNFO list\n");
	do {
	  IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
	  ListCount[1] += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
          TRACE_(dmfile)(": %s chunk (size = %d)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
	  
	  hr = IDirectMusicUtils_IPersistStream_ParseUNFOGeneric(&Chunk, pStm, &pNewMotif->desc);
	  if (FAILED(hr)) return hr;
	  
	  if (hr == S_FALSE) {
	    switch (Chunk.fccID) {
	    default: {
	      TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n");
	      liMove.QuadPart = Chunk.dwSize;
	      IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
	      break;				
	    }
	    }
	  }  
          TRACE_(dmfile)(": ListCount[1] = %d < ListSize[1] = %d\n", ListCount[1], ListSize[1]);
	} while (ListCount[1] < ListSize[1]);
	break;
      }
      case DMUS_FOURCC_PARTREF_LIST: {
	TRACE_(dmfile)(": PartRef list\n");
	hr = IDirectMusicStyle8Impl_IPersistStream_ParsePartRefList (iface, &Chunk, pStm, pNewMotif);
	if (FAILED(hr)) return hr;
	break;
      }
      default: {
	TRACE_(dmfile)(": unknown (skipping)\n");
	liMove.QuadPart = Chunk.dwSize - sizeof(FOURCC);
	IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
	break;						
      }
      }
      break;	
    }
    default: {
      TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n");
      liMove.QuadPart = Chunk.dwSize;
      IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
      break;						
    }
    }
    TRACE_(dmfile)(": ListCount[0] = %d < ListSize[0] = %d\n", ListCount[0], ListSize[0]);
  } while (ListCount[0] < ListSize[0]);

  return S_OK;
}
Пример #11
0
static HRESULT WINAPI IDirectMusicScriptImpl_IPersistStream_Load (LPPERSISTSTREAM iface, IStream* pStm) {
	ICOM_THIS_MULTI(IDirectMusicScriptImpl, PersistStreamVtbl, iface);

	DMUS_PRIVATE_CHUNK Chunk;
	DWORD StreamSize, StreamCount, ListSize[3], ListCount[3];
	LARGE_INTEGER liMove; /* used when skipping chunks */
	LPDIRECTMUSICGETLOADER pGetLoader = NULL;
	LPDIRECTMUSICLOADER pLoader = NULL;

	FIXME("(%p, %p): Loading not implemented yet\n", This, pStm);
	IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
	TRACE_(dmfile)(": %s chunk (size = %d)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
	switch (Chunk.fccID) {	
		case FOURCC_RIFF: {
			IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL);				
			TRACE_(dmfile)(": RIFF chunk of type %s", debugstr_fourcc(Chunk.fccID));
			StreamSize = Chunk.dwSize - sizeof(FOURCC);
			StreamCount = 0;
			switch (Chunk.fccID) {
				case DMUS_FOURCC_SCRIPT_FORM: {
					TRACE_(dmfile)(": script form\n");
					do {
						IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
						StreamCount += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
						TRACE_(dmfile)(": %s chunk (size = %d)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
						switch (Chunk.fccID) { 
						        case DMUS_FOURCC_SCRIPT_CHUNK: {
							        TRACE_(dmfile)(": script header chunk\n");
								This->pHeader = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, Chunk.dwSize);
								IStream_Read (pStm, This->pHeader, Chunk.dwSize, NULL);
								break;
						        }
						        case DMUS_FOURCC_SCRIPTVERSION_CHUNK: {
							        TRACE_(dmfile)(": script version chunk\n");
								This->pVersion = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, Chunk.dwSize);
								IStream_Read (pStm, This->pVersion, Chunk.dwSize, NULL); 
								TRACE_(dmfile)("version: 0x%08x.0x%08x\n", This->pVersion->dwVersionMS, This->pVersion->dwVersionLS);
								break;
						        }
						        case DMUS_FOURCC_SCRIPTLANGUAGE_CHUNK: {
							        TRACE_(dmfile)(": script language chunk\n");
								This->pwzLanguage = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, Chunk.dwSize);
								IStream_Read (pStm, This->pwzLanguage, Chunk.dwSize, NULL); 
								TRACE_(dmfile)("using language: %s\n", debugstr_w(This->pwzLanguage));
								break;
						        }
						        case DMUS_FOURCC_SCRIPTSOURCE_CHUNK: {
							        TRACE_(dmfile)(": script source chunk\n");
								This->pwzSource = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, Chunk.dwSize);
								IStream_Read (pStm, This->pwzSource, Chunk.dwSize, NULL); 
								if (TRACE_ON(dmscript)) {
								    int count = WideCharToMultiByte(CP_ACP, 0, This->pwzSource, -1, NULL, 0, NULL, NULL);
								    LPSTR str = HeapAlloc(GetProcessHeap (), 0, count);
								    WideCharToMultiByte(CP_ACP, 0, This->pwzSource, -1, str, count, NULL, NULL);
								    str[count-1] = '\n';
								    TRACE("source:\n");
								    write( 2, str, count );
								    HeapFree(GetProcessHeap(), 0, str);
								}
								break;
						        }
							case DMUS_FOURCC_GUID_CHUNK: {
								TRACE_(dmfile)(": GUID chunk\n");
								This->pDesc->dwValidData |= DMUS_OBJ_OBJECT;
								IStream_Read (pStm, &This->pDesc->guidObject, Chunk.dwSize, NULL);
								break;
							}
							case DMUS_FOURCC_VERSION_CHUNK: {
								TRACE_(dmfile)(": version chunk\n");
								This->pDesc->dwValidData |= DMUS_OBJ_VERSION;
								IStream_Read (pStm, &This->pDesc->vVersion, Chunk.dwSize, NULL);
								break;
							}
							case DMUS_FOURCC_CATEGORY_CHUNK: {
								TRACE_(dmfile)(": category chunk\n");
								This->pDesc->dwValidData |= DMUS_OBJ_CATEGORY;
								IStream_Read (pStm, This->pDesc->wszCategory, Chunk.dwSize, NULL);
								break;
							}
						        case FOURCC_RIFF: {
								IDirectMusicObject* pObject = NULL;
								DMUS_OBJECTDESC desc;

								ZeroMemory (&desc, sizeof(DMUS_OBJECTDESC));
								desc.dwSize = sizeof(DMUS_OBJECTDESC);
								desc.dwValidData = DMUS_OBJ_STREAM | DMUS_OBJ_CLASS;
								desc.guidClass = CLSID_DirectMusicContainer;
								desc.pStream = NULL;
								IStream_Clone (pStm, &desc.pStream);

								liMove.QuadPart = 0;
								liMove.QuadPart -= (sizeof(FOURCC) + sizeof(DWORD));
								IStream_Seek (desc.pStream, liMove, STREAM_SEEK_CUR, NULL);

								IStream_QueryInterface (pStm, &IID_IDirectMusicGetLoader, (LPVOID*)&pGetLoader);
								IDirectMusicGetLoader_GetLoader (pGetLoader, &pLoader);
								IDirectMusicGetLoader_Release (pGetLoader);

								if (SUCCEEDED(IDirectMusicLoader_GetObject (pLoader, &desc, &IID_IDirectMusicObject, (LPVOID*) &pObject))) {
								  IDirectMusicObject_Release (pObject);
								} else {
								  ERR_(dmfile)("Error on GetObject while trying to load Scrip SubContainer\n");
								}

								IDirectMusicLoader_Release (pLoader); pLoader = NULL; /* release loader */
								IStream_Release(desc.pStream); desc.pStream = NULL; /* release cloned stream */

								liMove.QuadPart = Chunk.dwSize;
								IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
								/*
							        IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL);				
								TRACE_(dmfile)(": RIFF chunk of type %s", debugstr_fourcc(Chunk.fccID));
								ListSize[0] = Chunk.dwSize - sizeof(FOURCC);
								ListCount[0] = 0;

								switch (Chunk.fccID) {
								        default: {
										TRACE_(dmfile)(": unknown (skipping)\n");
										liMove.QuadPart = Chunk.dwSize - sizeof(FOURCC);
										IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
										break;						
									}
								}
								*/
								break;
							}
							case FOURCC_LIST: {
								IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL);				
								TRACE_(dmfile)(": LIST chunk of type %s", debugstr_fourcc(Chunk.fccID));
								ListSize[0] = Chunk.dwSize - sizeof(FOURCC);
								ListCount[0] = 0;
								switch (Chunk.fccID) {
									case DMUS_FOURCC_UNFO_LIST: {
										TRACE_(dmfile)(": UNFO list\n");
										do {
											IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
											ListCount[0] += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
											TRACE_(dmfile)(": %s chunk (size = %d)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
											switch (Chunk.fccID) {
												/* don't ask me why, but M$ puts INFO elements in UNFO list sometimes
                                              (though strings seem to be valid unicode) */
												case mmioFOURCC('I','N','A','M'):
												case DMUS_FOURCC_UNAM_CHUNK: {
													TRACE_(dmfile)(": name chunk\n");
													This->pDesc->dwValidData |= DMUS_OBJ_NAME;
													IStream_Read (pStm, This->pDesc->wszName, Chunk.dwSize, NULL);
													break;
												}
												case mmioFOURCC('I','A','R','T'):
												case DMUS_FOURCC_UART_CHUNK: {
													TRACE_(dmfile)(": artist chunk (ignored)\n");
													liMove.QuadPart = Chunk.dwSize;
													IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
													break;
												}
												case mmioFOURCC('I','C','O','P'):
												case DMUS_FOURCC_UCOP_CHUNK: {
													TRACE_(dmfile)(": copyright chunk (ignored)\n");
													liMove.QuadPart = Chunk.dwSize;
													IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
													break;
												}
												case mmioFOURCC('I','S','B','J'):
												case DMUS_FOURCC_USBJ_CHUNK: {
													TRACE_(dmfile)(": subject chunk (ignored)\n");
													liMove.QuadPart = Chunk.dwSize;
													IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
													break;
												}
												case mmioFOURCC('I','C','M','T'):
												case DMUS_FOURCC_UCMT_CHUNK: {
													TRACE_(dmfile)(": comment chunk (ignored)\n");
													liMove.QuadPart = Chunk.dwSize;
													IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
													break;
												}
												default: {
													TRACE_(dmfile)(": unknown sub-chunk (irrelevant & skipping)\n");
													liMove.QuadPart = Chunk.dwSize;
													IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
													break;						
												}
											}
											TRACE_(dmfile)(": ListCount[0] = %d < ListSize[0] = %d\n", ListCount[0], ListSize[0]);
										} while (ListCount[0] < ListSize[0]);
										break;
									}
									default: {
										TRACE_(dmfile)(": unknown (skipping)\n");
										liMove.QuadPart = Chunk.dwSize - sizeof(FOURCC);
										IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
										break;						
									}
								}
								break;
							}	
							default: {
								TRACE_(dmfile)(": unknown chunk (irrelevant & skipping)\n");
								liMove.QuadPart = Chunk.dwSize;
								IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
								break;						
							}
						}
						TRACE_(dmfile)(": StreamCount[0] = %d < StreamSize[0] = %d\n", StreamCount, StreamSize);
					} while (StreamCount < StreamSize);
					break;
				}
				default: {
					TRACE_(dmfile)(": unexpected chunk; loading failed)\n");
					liMove.QuadPart = StreamSize;
					IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */
					return E_FAIL;
				}
			}
			TRACE_(dmfile)(": reading finished\n");
			break;
		}
		default: {
			TRACE_(dmfile)(": unexpected chunk; loading failed)\n");
			liMove.QuadPart = Chunk.dwSize;
			IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */
			return E_FAIL;
		}
	}

	return S_OK;
}
Пример #12
0
static HRESULT IDirectMusicBandTrack_IPersistStream_ParseBandsList (LPPERSISTSTREAM iface, DMUS_PRIVATE_CHUNK* pChunk, IStream* pStm) {

  /*ICOM_THIS_MULTI(IDirectMusicBandTrack, PersistStreamVtbl, iface);*/
  HRESULT hr = E_FAIL;
  DMUS_PRIVATE_CHUNK Chunk;
  DWORD StreamSize, ListSize[3], ListCount[3];
  LARGE_INTEGER liMove; /* used when skipping chunks */

  IDirectMusicBand* pBand = NULL;
  DMUS_PRIVATE_BAND_ITEM_HEADER header;

  memset(&header, 0, sizeof header);

  if (pChunk->fccID != DMUS_FOURCC_BANDS_LIST) {
    ERR_(dmfile)(": %s chunk should be a BANDS list\n", debugstr_fourcc (pChunk->fccID));
    return E_FAIL;
  }  

  ListSize[0] = pChunk->dwSize - sizeof(FOURCC);
  ListCount[0] = 0;

  do {
    IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
    ListCount[0] += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
    TRACE_(dmfile)(": %s chunk (size = %d)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
    switch (Chunk.fccID) {
    case FOURCC_LIST: {
      IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL);
      TRACE_(dmfile)(": LIST chunk of type %s", debugstr_fourcc(Chunk.fccID));
      ListSize[1] = Chunk.dwSize - sizeof(FOURCC);
      ListCount[1] = 0;
      do {
	IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
	ListCount[1] += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
	TRACE_(dmfile)(": %s chunk (size = %d)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
	switch (Chunk.fccID) { 
	case DMUS_FOURCC_BANDITEM_CHUNK: {
	  DMUS_IO_BAND_ITEM_HEADER tmp_header;
	  TRACE_(dmfile)(": Band Item chunk v1\n");
	  
	  IStream_Read (pStm, &tmp_header, sizeof(DMUS_IO_BAND_ITEM_HEADER), NULL);
	  TRACE_(dmfile)(" - lBandTime: %lu\n", tmp_header.lBandTime);
	  
	  header.dwVersion = 1;
	  header.lBandTime = tmp_header.lBandTime;
	  break;
	}
	case DMUS_FOURCC_BANDITEM_CHUNK2: { 
	  DMUS_IO_BAND_ITEM_HEADER2 tmp_header2;
	  TRACE_(dmfile)(": Band Item chunk v2\n");
	  
	  IStream_Read (pStm, &tmp_header2, sizeof(DMUS_IO_BAND_ITEM_HEADER2), NULL);
	  TRACE_(dmfile)(" - lBandTimeLogical: %lu\n", tmp_header2.lBandTimeLogical);
	  TRACE_(dmfile)(" - lBandTimePhysical: %lu\n", tmp_header2.lBandTimePhysical);
	  
	  header.dwVersion = 2;
	  header.lBandTimeLogical = tmp_header2.lBandTimeLogical;
	  header.lBandTimePhysical = tmp_header2.lBandTimePhysical;
	  break;
	}
	case FOURCC_RIFF: { 
	  IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL);
	  TRACE_(dmfile)(": RIFF chunk of type %s\n", debugstr_fourcc(Chunk.fccID));
	  StreamSize = Chunk.dwSize - sizeof(FOURCC);
	  switch (Chunk.fccID) {
	  case DMUS_FOURCC_BAND_FORM: {
	    LPSTREAM pClonedStream = NULL;
	    TRACE_(dmfile)(": BAND RIFF\n");
	    
	    IStream_Clone (pStm, &pClonedStream);
	    
	    liMove.QuadPart = 0;
	    liMove.QuadPart -= sizeof(FOURCC) + (sizeof(FOURCC)+sizeof(DWORD));
	    IStream_Seek (pClonedStream, liMove, STREAM_SEEK_CUR, NULL);
	    
	    hr = IDirectMusicBandTrack_IPersistStream_LoadBand (iface, pClonedStream, &pBand, &header);
	    if (FAILED(hr)) {
	      ERR(": could not load track\n");
	      return hr;
	    }
	    IStream_Release (pClonedStream);
	    
	    IDirectMusicTrack_Release(pBand); pBand = NULL; /* now we can release at as it inserted */
	    
	    /** now safe move the cursor */
	    liMove.QuadPart = StreamSize;
	    IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
	    break;
	  }
	  default: {
	    TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n");
	    liMove.QuadPart = StreamSize;
	    IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
	    break;						
	  }
	  }
	  break;
	}
	default: {
	  TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n");
	  liMove.QuadPart = Chunk.dwSize;
	  IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
	  break;						
	 }
	}
	TRACE_(dmfile)(": ListCount[1] = %d < ListSize[1] = %d\n", ListCount[1], ListSize[1]);
      } while (ListCount[1] < ListSize[1]);
      break;
    }
    default: {
      TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n");
      liMove.QuadPart = Chunk.dwSize;
      IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
      break;						
    }
    }
    TRACE_(dmfile)(": ListCount[0] = %d < ListSize[0] = %d\n", ListCount[0], ListSize[0]);
  } while (ListCount[0] < ListSize[0]);

  return S_OK;
}
Пример #13
0
static void test_IStream_invalid_operations(IStream * stream, DWORD mode)
{
    HRESULT ret;
    IStream * clone;
    ULONG refcount;
    ULARGE_INTEGER uzero;
    ULARGE_INTEGER uret;
    LARGE_INTEGER zero;
    ULONG count;
    char data[256];

    U(uzero).HighPart = 0;
    U(uzero).LowPart = 0;
    U(uret).HighPart = 0;
    U(uret).LowPart = 0;
    U(zero).HighPart = 0;
    U(zero).LowPart = 0;

    /* IStream::Read */

    /* IStream_Read from the COBJMACROS is undefined by shlwapi.h, replaced by the IStream_Read helper function. */

    ret = stream->lpVtbl->Read(stream, NULL, 0, &count);
    ok(ret == S_OK, "expected S_OK, got 0x%08x\n", ret);

    ret = stream->lpVtbl->Read(stream, data, 5, NULL);
    ok(ret == S_FALSE || ret == S_OK, "expected S_FALSE or S_OK, got 0x%08x\n", ret);

    ret = stream->lpVtbl->Read(stream, data, 0, NULL);
    ok(ret == S_OK, "expected S_OK, got 0x%08x\n", ret);

    ret = stream->lpVtbl->Read(stream, data, 3, &count);
    ok(ret == S_FALSE || ret == S_OK, "expected S_FALSE or S_OK, got 0x%08x\n", ret);

    /* IStream::Write */

    /* IStream_Write from the COBJMACROS is undefined by shlwapi.h, replaced by the IStream_Write helper function. */

    ret = stream->lpVtbl->Write(stream, NULL, 0, &count);
    if (mode == STGM_READ)
    {
        ok(ret == STG_E_ACCESSDENIED /* XP */ || broken(ret == S_OK) /* Win2000 + IE5 */,
           "expected STG_E_ACCESSDENIED, got 0x%08x\n", ret);
    }
    else
        ok(ret == S_OK, "expected S_OK, got 0x%08x\n", ret);

    strcpy(data, "Hello");
    ret = stream->lpVtbl->Write(stream, data, 5, NULL);
    if (mode == STGM_READ)
        ok(ret == STG_E_ACCESSDENIED,
           "expected STG_E_ACCESSDENIED, got 0x%08x\n", ret);
    else
        ok(ret == S_OK, "expected S_OK, got 0x%08x\n", ret);

    strcpy(data, "Hello");
    ret = stream->lpVtbl->Write(stream, data, 0, NULL);
    if (mode == STGM_READ)
        ok(ret == STG_E_ACCESSDENIED,
           "expected STG_E_ACCESSDENIED, got 0x%08x\n", ret);
    else
        ok(ret == S_OK, "expected S_OK, got 0x%08x\n", ret);

    strcpy(data, "Hello");
    ret = stream->lpVtbl->Write(stream, data, 0, &count);
    if (mode == STGM_READ)
        ok(ret == STG_E_ACCESSDENIED,
           "expected STG_E_ACCESSDENIED, got 0x%08x\n", ret);
    else
        ok(ret == S_OK, "expected S_OK, got 0x%08x\n", ret);

    strcpy(data, "Hello");
    ret = stream->lpVtbl->Write(stream, data, 3, &count);
    if (mode == STGM_READ)
        ok(ret == STG_E_ACCESSDENIED,
           "expected STG_E_ACCESSDENIED, got 0x%08x\n", ret);
    else
        ok(ret == S_OK, "expected S_OK, got 0x%08x\n", ret);

    /* IStream::Seek */

    ret = IStream_Seek(stream, zero, STREAM_SEEK_SET, NULL);
    ok(ret == S_OK, "expected S_OK, got 0x%08x\n", ret);

    ret = IStream_Seek(stream, zero, 20, NULL);
    ok(ret == E_INVALIDARG,
       "expected E_INVALIDARG, got 0x%08x\n", ret);

    /* IStream::CopyTo */

    ret = IStream_CopyTo(stream, NULL, uzero, &uret, &uret);
    ok(ret == S_OK, "expected S_OK, got 0x%08x\n", ret);

    clone = NULL;
    ret = IStream_CopyTo(stream, clone, uzero, &uret, &uret);
    ok(ret == S_OK, "expected S_OK, got 0x%08x\n", ret);

    ret = IStream_CopyTo(stream, stream, uzero, &uret, &uret);
    ok(ret == S_OK, "expected S_OK, got 0x%08x\n", ret);

    ret = IStream_CopyTo(stream, stream, uzero, &uret, NULL);
    ok(ret == S_OK, "expected S_OK, got 0x%08x\n", ret);

    ret = IStream_CopyTo(stream, stream, uzero, NULL, &uret);
    ok(ret == S_OK, "expected S_OK, got 0x%08x\n", ret);

    /* IStream::Commit */

    ret = IStream_Commit(stream, STGC_DEFAULT);
    ok(ret == S_OK, "expected S_OK, got 0x%08x\n", ret);

    /* IStream::Revert */

    ret = IStream_Revert(stream);
    ok(ret == E_NOTIMPL, "expected E_NOTIMPL, got 0x%08x\n", ret);

    /* IStream::LockRegion */

    ret = IStream_LockRegion(stream, uzero, uzero, 0);
    ok(ret == E_NOTIMPL /* XP */ || ret == S_OK /* Vista */,
      "expected E_NOTIMPL or S_OK, got 0x%08x\n", ret);

    /* IStream::UnlockRegion */

    if (ret == E_NOTIMPL) /* XP */ {
        ret = IStream_UnlockRegion(stream, uzero, uzero, 0);
        ok(ret == E_NOTIMPL, "expected E_NOTIMPL, got 0x%08x\n", ret);
    } else /* Vista */ {
        ret = IStream_UnlockRegion(stream, uzero, uzero, 0);
        ok(ret == S_OK, "expected S_OK, got 0x%08x\n", ret);

        ret = IStream_UnlockRegion(stream, uzero, uzero, 0);
        ok(ret == STG_E_LOCKVIOLATION, "expected STG_E_LOCKVIOLATION, got 0x%08x\n", ret);
    }

    /* IStream::Stat */

    ret = IStream_Stat(stream, NULL, 0);
    ok(ret == STG_E_INVALIDPOINTER,
       "expected STG_E_INVALIDPOINTER or E_NOTIMPL, got 0x%08x\n", ret);

    /* IStream::Clone */

    /* Passing a NULL pointer for the second IStream::Clone param crashes on Win7 */

    clone = NULL;
    ret = IStream_Clone(stream, &clone);
    ok(ret == E_NOTIMPL, "expected E_NOTIMPL, got 0x%08x\n", ret);
    ok(clone == NULL, "expected a NULL IStream object, got %p\n", stream);

    if (clone) {
        refcount = IStream_Release(clone);
        ok(refcount == 0, "expected 0, got %d\n", refcount);
    }
}