Module: wine Branch: master Commit: c1513c6bde5165f6172b488cb64900eee635d4c0 URL: http://source.winehq.org/git/wine.git/?a=commit;h=c1513c6bde5165f6172b488cb6...
Author: Nikolay Sivov bunglehead@gmail.com Date: Mon Sep 14 11:16:06 2009 +0400
comctl32/dpa: Implement DPA_SaveStream() with tests.
---
dlls/comctl32/dpa.c | 79 +++++++++++++++++++++++++++++++++++------ dlls/comctl32/tests/dpa.c | 84 +++++++++++++++++++++++++++++++++++++-------- 2 files changed, 136 insertions(+), 27 deletions(-)
diff --git a/dlls/comctl32/dpa.c b/dlls/comctl32/dpa.c index ca28282..722e2fa 100644 --- a/dlls/comctl32/dpa.c +++ b/dlls/comctl32/dpa.c @@ -73,8 +73,8 @@ typedef struct _STREAMDATA * pData [I] pointer to callback data * * RETURNS - * Success: TRUE - * Failure: FALSE + * Success: S_OK, S_FALSE - partial success + * Failure: HRESULT error code * * NOTES * No more information available yet! @@ -91,7 +91,7 @@ HRESULT WINAPI DPA_LoadStream (HDPA *phDpa, PFNDPASTREAM loadProc, HDPA hDpa; PVOID *ptr;
- FIXME ("phDpa=%p loadProc=%p pStream=%p pData=%p\n", + TRACE ("phDpa=%p loadProc=%p pStream=%p pData=%p\n", phDpa, loadProc, pStream, pData);
if (!phDpa || !loadProc || !pStream) @@ -110,7 +110,7 @@ HRESULT WINAPI DPA_LoadStream (HDPA *phDpa, PFNDPASTREAM loadProc, if (errCode != S_OK) return errCode;
- FIXME ("dwSize=%u dwData2=%u dwItems=%u\n", + TRACE ("dwSize=%u dwData2=%u dwItems=%u\n", streamData.dwSize, streamData.dwData2, streamData.dwItems);
if (ulRead < sizeof(STREAMDATA) || @@ -150,7 +150,7 @@ HRESULT WINAPI DPA_LoadStream (HDPA *phDpa, PFNDPASTREAM loadProc,
/* store the handle to the dpa */ *phDpa = hDpa; - FIXME ("new hDpa=%p, errorcode=%x\n", hDpa, errCode); + TRACE ("new hDpa=%p, errorcode=%x\n", hDpa, errCode);
return errCode; } @@ -163,25 +163,80 @@ HRESULT WINAPI DPA_LoadStream (HDPA *phDpa, PFNDPASTREAM loadProc, * * PARAMS * hDpa [I] handle to a dynamic pointer array - * loadProc [I] pointer to a callback function + * saveProc [I] pointer to a callback function * pStream [I] pointer to a stream * pData [I] pointer to callback data * * RETURNS - * Success: TRUE - * Failure: FALSE + * Success: S_OK, S_FALSE - partial success + * Failure: HRESULT error code * * NOTES * No more information available yet! */ -HRESULT WINAPI DPA_SaveStream (const HDPA hDpa, PFNDPASTREAM loadProc, +HRESULT WINAPI DPA_SaveStream (const HDPA hDpa, PFNDPASTREAM saveProc, IStream *pStream, LPVOID pData) { + LARGE_INTEGER position; + ULARGE_INTEGER initial_pos, curr_pos; + STREAMDATA streamData; + DPASTREAMINFO streamInfo; + HRESULT hr; + PVOID *ptr; + + TRACE ("hDpa=%p saveProc=%p pStream=%p pData=%p\n", + hDpa, saveProc, pStream, pData); + + if (!hDpa || !saveProc || !pStream) return E_INVALIDARG; + + /* save initial position to write header after completion */ + position.QuadPart = 0; + hr = IStream_Seek (pStream, position, STREAM_SEEK_CUR, &initial_pos); + if (hr != S_OK) + return hr; + + /* write empty header */ + streamData.dwSize = sizeof(streamData); + streamData.dwData2 = 1; + streamData.dwItems = 0; + + hr = IStream_Write (pStream, &streamData, sizeof(streamData), NULL); + if (hr != S_OK) { + position.QuadPart = initial_pos.QuadPart; + IStream_Seek (pStream, position, STREAM_SEEK_SET, NULL); + return hr; + } + + /* no items - we're done */ + if (hDpa->nItemCount == 0) return S_OK; + + ptr = hDpa->ptrs; + for (streamInfo.iPos = 0; streamInfo.iPos < hDpa->nItemCount; streamInfo.iPos++) { + streamInfo.pvItem = *ptr; + hr = (saveProc)(&streamInfo, pStream, pData); + if (hr != S_OK) { + hr = S_FALSE; + break; + } + ptr++; + } + + /* write updated header */ + position.QuadPart = 0; + IStream_Seek (pStream, position, STREAM_SEEK_CUR, &curr_pos); + + streamData.dwSize = curr_pos.QuadPart - initial_pos.QuadPart; + streamData.dwData2 = 1; + streamData.dwItems = streamInfo.iPos; + + position.QuadPart = initial_pos.QuadPart; + IStream_Seek (pStream, position, STREAM_SEEK_SET, NULL); + IStream_Write (pStream, &streamData, sizeof(streamData), NULL);
- FIXME ("hDpa=%p loadProc=%p pStream=%p pData=%p\n", - hDpa, loadProc, pStream, pData); + position.QuadPart = curr_pos.QuadPart; + IStream_Seek (pStream, position, STREAM_SEEK_SET, NULL);
- return E_FAIL; + return hr; }
diff --git a/dlls/comctl32/tests/dpa.c b/dlls/comctl32/tests/dpa.c index 54e8d0e..1ba4c67 100644 --- a/dlls/comctl32/tests/dpa.c +++ b/dlls/comctl32/tests/dpa.c @@ -142,12 +142,12 @@ static INT CALLBACK CB_EnumFirstThree(PVOID pItem, PVOID lp) static HRESULT CALLBACK CB_Save(DPASTREAMINFO *pInfo, IStream *pStm, LPVOID lp) { HRESULT hRes; - + ok(lp == (LPVOID)0xdeadbeef, "lp=%p\n", lp); hRes = IStream_Write(pStm, &pInfo->iPos, sizeof(INT), NULL); - ok(hRes == S_OK, "hRes=0x%x\n", hRes); + expect(S_OK, hRes); hRes = IStream_Write(pStm, &pInfo->pvItem, sizeof(PVOID), NULL); - ok(hRes == S_OK, "hRes=0x%x\n", hRes); + expect(S_OK, hRes); return S_OK; }
@@ -159,10 +159,10 @@ static HRESULT CALLBACK CB_Load(DPASTREAMINFO *pInfo, IStream *pStm, LPVOID lp) iOldPos = pInfo->iPos; ok(lp == (LPVOID)0xdeadbeef, "lp=%p\n", lp); hRes = IStream_Read(pStm, &pInfo->iPos, sizeof(INT), NULL); - ok(hRes == S_OK, "hRes=0x%x\n", hRes); + expect(S_OK, hRes); ok(pInfo->iPos == iOldPos, "iPos=%d iOldPos=%d\n", pInfo->iPos, iOldPos); hRes = IStream_Read(pStm, &pInfo->pvItem, sizeof(PVOID), NULL); - ok(hRes == S_OK, "hRes=0x%x\n", hRes); + expect(S_OK, hRes); return S_OK; }
@@ -643,6 +643,62 @@ static void test_DPA_LoadStream(void) CoUninitialize(); }
+static void test_DPA_SaveStream(void) +{ + HDPA dpa; + static const WCHAR szStg[] = { 'S','t','g',0 }; + IStorage* pStg = NULL; + IStream* pStm = NULL; + DWORD dwMode; + HRESULT hRes; + ULONG ret; + + if(!pDPA_SaveStream) + { + win_skip("DPA_SaveStream() not available. Skipping stream tests.\n"); + return; + } + + hRes = CoInitialize(NULL); + if (hRes != S_OK) + { + ok(0, "hResult: %d\n", hRes); + return; + } + + dwMode = STGM_DIRECT|STGM_CREATE|STGM_READWRITE|STGM_SHARE_EXCLUSIVE; + hRes = StgCreateDocfile(NULL, dwMode|STGM_DELETEONRELEASE, 0, &pStg); + expect(S_OK, hRes); + + hRes = IStorage_CreateStream(pStg, szStg, dwMode, 0, 0, &pStm); + expect(S_OK, hRes); + + dpa = pDPA_Create(0); + + /* simple parameter check */ + hRes = pDPA_SaveStream(dpa, NULL, pStm, NULL); + ok(hRes == E_INVALIDARG || + broken(hRes == S_OK) /* XP and below */, "Wrong result, %d\n", hRes); +if (0) { + /* crashes on XP */ + hRes = pDPA_SaveStream(NULL, CB_Save, pStm, NULL); + expect(E_INVALIDARG, hRes); + + hRes = pDPA_SaveStream(dpa, CB_Save, NULL, NULL); + expect(E_INVALIDARG, hRes); +} + + pDPA_Destroy(dpa); + + ret = IStream_Release(pStm); + ok(!ret, "ret=%d\n", ret); + + ret = IStorage_Release(pStg); + ok(!ret, "ret=%d\n", ret); + + CoUninitialize(); +} + static void test_dpa_stream(void) { HDPA dpa; @@ -679,25 +735,22 @@ static void test_dpa_stream(void)
dwMode = STGM_DIRECT|STGM_CREATE|STGM_READWRITE|STGM_SHARE_EXCLUSIVE; hRes = StgCreateDocfile(NULL, dwMode|STGM_DELETEONRELEASE, 0, &pStg); - ok(hRes == S_OK, "hRes=0x%x\n", hRes); + expect(S_OK, hRes);
hRes = IStorage_CreateStream(pStg, szStg, dwMode, 0, 0, &pStm); - ok(hRes == S_OK, "hRes=0x%x\n", hRes); + expect(S_OK, hRes);
hRes = pDPA_SaveStream(dpa, CB_Save, pStm, (void*)0xdeadbeef); - todo_wine ok(hRes == S_OK, "hRes=0x%x\n", hRes); + ok(hRes == S_OK, "hRes=0x%x\n", hRes); pDPA_Destroy(dpa);
liZero.QuadPart = 0; hRes = IStream_Seek(pStm, liZero, STREAM_SEEK_SET, NULL); - ok(hRes == S_OK, "hRes=0x%x\n", hRes); + expect(S_OK, hRes); hRes = pDPA_LoadStream(&dpa, CB_Load, pStm, (void*)0xdeadbeef); - todo_wine - { - ok(hRes == S_OK, "hRes=0x%x\n", hRes); - rc = CheckDPA(dpa, 0x123456, &dw); - ok(rc, "dw=0x%x\n", dw); - } + expect(S_OK, hRes); + rc = CheckDPA(dpa, 0x123456, &dw); + ok(rc, "dw=0x%x\n", dw); pDPA_Destroy(dpa);
ret = IStream_Release(pStm); @@ -726,5 +779,6 @@ START_TEST(dpa) test_DPA_EnumCallback(); test_DPA_DestroyCallback(); test_DPA_LoadStream(); + test_DPA_SaveStream(); test_dpa_stream(); }