ReactOS.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2025
June
May
April
March
February
January
2024
December
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
February
January
2012
December
November
October
September
August
July
June
May
April
March
February
January
2011
December
November
October
September
August
July
June
May
April
March
February
January
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008
December
November
October
September
August
July
June
May
April
March
February
January
2007
December
November
October
September
August
July
June
May
April
March
February
January
2006
December
November
October
September
August
July
June
May
April
March
February
January
2005
December
November
October
September
August
July
June
May
April
March
February
January
2004
December
November
October
September
August
July
June
May
April
March
February
List overview
Download
Ros-diffs
January 2018
----- 2025 -----
June 2025
May 2025
April 2025
March 2025
February 2025
January 2025
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
----- 2010 -----
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
June 2010
May 2010
April 2010
March 2010
February 2010
January 2010
----- 2009 -----
December 2009
November 2009
October 2009
September 2009
August 2009
July 2009
June 2009
May 2009
April 2009
March 2009
February 2009
January 2009
----- 2008 -----
December 2008
November 2008
October 2008
September 2008
August 2008
July 2008
June 2008
May 2008
April 2008
March 2008
February 2008
January 2008
----- 2007 -----
December 2007
November 2007
October 2007
September 2007
August 2007
July 2007
June 2007
May 2007
April 2007
March 2007
February 2007
January 2007
----- 2006 -----
December 2006
November 2006
October 2006
September 2006
August 2006
July 2006
June 2006
May 2006
April 2006
March 2006
February 2006
January 2006
----- 2005 -----
December 2005
November 2005
October 2005
September 2005
August 2005
July 2005
June 2005
May 2005
April 2005
March 2005
February 2005
January 2005
----- 2004 -----
December 2004
November 2004
October 2004
September 2004
August 2004
July 2004
June 2004
May 2004
April 2004
March 2004
February 2004
ros-diffs@reactos.org
37 participants
372 discussions
Start a n
N
ew thread
01/01: [OLEAUT32_WINETEST] Sync with Wine 3.0. CORE-14225
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=5f28af7188c133fd14ac5…
commit 5f28af7188c133fd14ac5e958aa33fd375f8a72f Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Sat Jan 20 13:00:17 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Sat Jan 20 13:00:17 2018 +0100 [OLEAUT32_WINETEST] Sync with Wine 3.0. CORE-14225 --- modules/rostests/winetests/oleaut32/olepicture.c | 176 +++------------------- modules/rostests/winetests/oleaut32/test_reg.idl | 11 ++ modules/rostests/winetests/oleaut32/tmarshal.c | 48 +----- modules/rostests/winetests/oleaut32/typelib.c | 183 +++++++++++++++-------- modules/rostests/winetests/oleaut32/vartest.c | 5 + modules/rostests/winetests/oleaut32/vartype.c | 3 + 6 files changed, 166 insertions(+), 260 deletions(-) diff --git a/modules/rostests/winetests/oleaut32/olepicture.c b/modules/rostests/winetests/oleaut32/olepicture.c index 02d68a4171..149dfc357f 100644 --- a/modules/rostests/winetests/oleaut32/olepicture.c +++ b/modules/rostests/winetests/oleaut32/olepicture.c @@ -77,7 +77,7 @@ static const unsigned char pngimage[285] = { 0xe7,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82 }; -/* 1bpp BI_RGB 1x1 pixel bmp */ +/* 1x1 pixel bmp */ static const unsigned char bmpimage[66] = { 0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00, 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00, @@ -86,15 +86,6 @@ static const unsigned char bmpimage[66] = { 0x00,0x00 }; -/* 8bpp BI_RLE8 1x1 pixel bmp */ -static const unsigned char bmpimage_rle8[] = { -0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00, -0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x08,0x00,0x01,0x00, -0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00, -0x00,0x00,0x02,0x00,0x00,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x00,0x01, -0x00,0x00 -}; - /* 2x2 pixel gif */ static const unsigned char gif4pixel[42] = { 0x47,0x49,0x46,0x38,0x37,0x61,0x02,0x00,0x02,0x00,0xa1,0x00,0x00,0x00,0x00,0x00, @@ -228,7 +219,7 @@ test_pic_with_stream(LPSTREAM stream, unsigned int imgsize) { BITMAP bmp; GetObjectA(UlongToHandle(handle), sizeof(BITMAP), &bmp); - ok(bmp.bmBits != 0, "not a dib\n"); + todo_wine ok(bmp.bmBits != 0, "not a dib\n"); } width = 0; @@ -710,7 +701,8 @@ static void test_Render(void) HDC hdc = create_render_dc(); /* test IPicture::Render return code on uninitialized picture */ - OleCreatePictureIndirect(NULL, &IID_IPicture, TRUE, (VOID**)&pic); + hres = OleCreatePictureIndirect(NULL, &IID_IPicture, TRUE, (void **)&pic); + ok(hres == S_OK, "Failed to create a picture, hr %#x.\n", hres); hres = IPicture_get_Type(pic, &type); ok(hres == S_OK, "IPicture_get_Type does not return S_OK, but 0x%08x\n", hres); ok(type == PICTYPE_UNINITIALIZED, "Expected type = PICTYPE_UNINITIALIZED, got = %d\n", type); @@ -743,7 +735,8 @@ static void test_Render(void) return; } - OleCreatePictureIndirect(&desc, &IID_IPicture, TRUE, (VOID**)&pic); + hres = OleCreatePictureIndirect(&desc, &IID_IPicture, TRUE, (void **)&pic); + ok(hres == S_OK, "Failed to create a picture, hr %#x.\n", hres); /* zero dimensions, PICTYPE_ICON */ hres = picture_render(pic, hdc, 0, 0, 0, 0, 0, 0, 0, 0, NULL); ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE); @@ -797,7 +790,8 @@ static void test_get_Attributes(void) short type; DWORD attr; - OleCreatePictureIndirect(NULL, &IID_IPicture, TRUE, (VOID**)&pic); + hres = OleCreatePictureIndirect(NULL, &IID_IPicture, TRUE, (void **)&pic); + ok(hres == S_OK, "Failed to create a picture, hr %#x.\n", hres); hres = IPicture_get_Type(pic, &type); ok(hres == S_OK, "IPicture_get_Type does not return S_OK, but 0x%08x\n", hres); ok(type == PICTYPE_UNINITIALIZED, "Expected type = PICTYPE_UNINITIALIZED, got = %d\n", type); @@ -818,8 +812,8 @@ static void test_get_Handle(void) IPicture *pic; HRESULT hres; - OleCreatePictureIndirect(NULL, &IID_IPicture, TRUE, (VOID**)&pic); - + hres = OleCreatePictureIndirect(NULL, &IID_IPicture, TRUE, (void **)&pic); + ok(hres == S_OK, "Failed to create a picture, hr %#x.\n", hres); hres = IPicture_get_Handle(pic, NULL); ole_expect(hres, E_POINTER); @@ -831,7 +825,8 @@ static void test_get_Type(void) IPicture *pic; HRESULT hres; - OleCreatePictureIndirect(NULL, &IID_IPicture, TRUE, (VOID**)&pic); + hres = OleCreatePictureIndirect(NULL, &IID_IPicture, TRUE, (void **)&pic); + ok(hres == S_OK, "Failed to create a picture, hr %#x.\n", hres); hres = IPicture_get_Type(pic, NULL); ole_expect(hres, E_POINTER); @@ -852,7 +847,6 @@ static void test_OleLoadPicturePath(void) HANDLE file; DWORD size; WCHAR *ptr; - VARIANT var; const struct { @@ -919,14 +913,6 @@ static void test_OleLoadPicturePath(void) if (pic) IPicture_Release(pic); - VariantInit(&var); - V_VT(&var) = VT_BSTR; - V_BSTR(&var) = SysAllocString(temp_fileW + 8); - hres = OleLoadPictureFile(var, (IDispatch **)&pic); - ok(hres == S_OK, "OleLoadPictureFile error %#x\n", hres); - IPicture_Release(pic); - VariantClear(&var); - /* Try a DOS path with tacked on "file:". */ hres = OleLoadPicturePath(temp_fileW, NULL, 0, 0, &IID_IPicture, (void **)&pic); ok(hres == S_OK || @@ -935,13 +921,6 @@ static void test_OleLoadPicturePath(void) if (pic) IPicture_Release(pic); - VariantInit(&var); - V_VT(&var) = VT_BSTR; - V_BSTR(&var) = SysAllocString(temp_fileW); - hres = OleLoadPictureFile(var, (IDispatch **)&pic); - ok(hres == CTL_E_PATHFILEACCESSERROR, "wrong error %#x\n", hres); - VariantClear(&var); - DeleteFileA(temp_file); /* Try with a nonexistent file. */ @@ -951,26 +930,12 @@ static void test_OleLoadPicturePath(void) broken(hres == E_FAIL), /*Win2k */ "Expected OleLoadPicturePath to return INET_E_RESOURCE_NOT_FOUND, got 0x%08x\n", hres); - VariantInit(&var); - V_VT(&var) = VT_BSTR; - V_BSTR(&var) = SysAllocString(temp_fileW + 8); - hres = OleLoadPictureFile(var, (IDispatch **)&pic); - ok(hres == CTL_E_FILENOTFOUND, "wrong error %#x\n", hres); - VariantClear(&var); - hres = OleLoadPicturePath(temp_fileW, NULL, 0, 0, &IID_IPicture, (void **)&pic); ok(hres == INET_E_RESOURCE_NOT_FOUND || /* XP+ */ broken(hres == E_UNEXPECTED) || /* NT4 */ broken(hres == E_FAIL), /* Win2k */ "Expected OleLoadPicturePath to return INET_E_RESOURCE_NOT_FOUND, got 0x%08x\n", hres); - VariantInit(&var); - V_VT(&var) = VT_BSTR; - V_BSTR(&var) = SysAllocString(temp_fileW); - hres = OleLoadPictureFile(var, (IDispatch **)&pic); - ok(hres == CTL_E_PATHFILEACCESSERROR, "wrong error %#x\n", hres); - VariantClear(&var); - file = CreateFileA(temp_file, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); WriteFile(file, bmpimage, sizeof(bmpimage), &size, NULL); @@ -992,13 +957,6 @@ static void test_OleLoadPicturePath(void) if (pic) IPicture_Release(pic); - VariantInit(&var); - V_VT(&var) = VT_BSTR; - V_BSTR(&var) = SysAllocString(temp_fileW); - hres = OleLoadPictureFile(var, (IDispatch **)&pic); - ok(hres == CTL_E_PATHFILEACCESSERROR, "wrong error %#x\n", hres); - VariantClear(&var); - DeleteFileA(temp_file); /* Try with a nonexistent file. */ @@ -1007,22 +965,6 @@ static void test_OleLoadPicturePath(void) broken(hres == E_UNEXPECTED) || /* NT4 */ broken(hres == E_FAIL), /* Win2k */ "Expected OleLoadPicturePath to return INET_E_RESOURCE_NOT_FOUND, got 0x%08x\n", hres); - - VariantInit(&var); - V_VT(&var) = VT_BSTR; - V_BSTR(&var) = SysAllocString(temp_fileW); - hres = OleLoadPictureFile(var, (IDispatch **)&pic); - ok(hres == CTL_E_PATHFILEACCESSERROR, "wrong error %#x\n", hres); - VariantClear(&var); - - VariantInit(&var); - V_VT(&var) = VT_INT; - V_INT(&var) = 762; - hres = OleLoadPictureFile(var, (IDispatch **)&pic); - ok(hres == CTL_E_FILENOTFOUND, "wrong error %#x\n", hres); - -if (0) /* crashes under Windows */ - hres = OleLoadPictureFile(var, NULL); } static void test_himetric(void) @@ -1134,14 +1076,18 @@ static void test_load_save_bmp(void) size = -1; hr = IPicture_SaveAsFile(pic, dst_stream, TRUE, &size); ok(hr == S_OK, "IPicture_SaveasFile error %#x\n", hr); +todo_wine ok(size == 66, "expected 66, got %d\n", size); mem = GlobalLock(hmem); +todo_wine ok(!memcmp(&mem[0], "BM", 2), "got wrong bmp header %04x\n", mem[0]); GlobalUnlock(hmem); size = -1; hr = IPicture_SaveAsFile(pic, dst_stream, FALSE, &size); +todo_wine ok(hr == E_FAIL, "expected E_FAIL, got %#x\n", hr); +todo_wine ok(size == -1, "expected -1, got %d\n", size); offset.QuadPart = 0; @@ -1208,12 +1154,15 @@ static void test_load_save_icon(void) todo_wine ok(size == 766, "expected 766, got %d\n", size); mem = GlobalLock(hmem); +todo_wine ok(mem[0] == 0x00010000, "got wrong icon header %04x\n", mem[0]); GlobalUnlock(hmem); size = -1; hr = IPicture_SaveAsFile(pic, dst_stream, FALSE, &size); +todo_wine ok(hr == E_FAIL, "expected E_FAIL, got %#x\n", hr); +todo_wine ok(size == -1, "expected -1, got %d\n", size); offset.QuadPart = 0; @@ -1279,11 +1228,13 @@ static void test_load_save_empty_picture(void) size = -1; hr = IPicture_SaveAsFile(pic, dst_stream, TRUE, &size); ok(hr == S_OK, "IPicture_SaveasFile error %#x\n", hr); +todo_wine ok(size == -1, "expected -1, got %d\n", size); size = -1; hr = IPicture_SaveAsFile(pic, dst_stream, FALSE, &size); ok(hr == S_OK, "IPicture_SaveasFile error %#x\n", hr); +todo_wine ok(size == -1, "expected -1, got %d\n", size); hr = IPicture_QueryInterface(pic, &IID_IPersistStream, (void **)&src_stream); @@ -1351,89 +1302,6 @@ static void test_load_save_empty_picture(void) IStream_Release(stream); } -static void test_load_save_emf(void) -{ - HDC hdc; - IPicture *pic; - PICTDESC desc; - short type; - OLE_HANDLE handle; - HGLOBAL hmem; - DWORD *mem; - ENHMETAHEADER *emh; - IPersistStream *src_stream; - IStream *dst_stream; - LARGE_INTEGER offset; - HRESULT hr; - LONG size; - - hdc = CreateEnhMetaFileA(0, NULL, NULL, NULL); - ok(hdc != 0, "CreateEnhMetaFileA failed\n"); - - desc.cbSizeofstruct = sizeof(desc); - desc.picType = PICTYPE_ENHMETAFILE; - desc.emf.hemf = CloseEnhMetaFile(hdc); - ok(desc.emf.hemf != 0, "CloseEnhMetaFile failed\n"); - hr = OleCreatePictureIndirect(&desc, &IID_IPicture, FALSE, (void**)&pic); - ok(hr == S_OK, "OleCreatePictureIndirect error %#x\n", hr); - - type = -1; - hr = IPicture_get_Type(pic, &type); - ok(hr == S_OK,"get_Type error %#8x\n", hr); - ok(type == PICTYPE_ENHMETAFILE,"expected PICTYPE_ENHMETAFILE, got %d\n", type); - - hr = IPicture_get_Handle(pic, &handle); - ok(hr == S_OK,"get_Handle error %#8x\n", hr); - ok(IntToPtr(handle) == desc.emf.hemf, "get_Handle returned wrong handle %#x\n", handle); - - hmem = GlobalAlloc(GMEM_MOVEABLE, 0); - hr = CreateStreamOnHGlobal(hmem, FALSE, &dst_stream); - ok(hr == S_OK, "createstreamonhglobal error %#x\n", hr); - - size = -1; - hr = IPicture_SaveAsFile(pic, dst_stream, TRUE, &size); - ok(hr == S_OK, "IPicture_SaveasFile error %#x\n", hr); - ok(size == 128, "expected 128, got %d\n", size); - emh = GlobalLock(hmem); -if (size) -{ - ok(emh->iType == EMR_HEADER, "wrong iType %04x\n", emh->iType); - ok(emh->dSignature == ENHMETA_SIGNATURE, "wrong dSignature %08x\n", emh->dSignature); -} - GlobalUnlock(hmem); - - size = -1; - hr = IPicture_SaveAsFile(pic, dst_stream, FALSE, &size); - ok(hr == E_FAIL, "expected E_FAIL, got %#x\n", hr); - ok(size == -1, "expected -1, got %d\n", size); - - offset.QuadPart = 0; - hr = IStream_Seek(dst_stream, offset, SEEK_SET, NULL); - ok(hr == S_OK, "IStream_Seek %#x\n", hr); - - hr = IPicture_QueryInterface(pic, &IID_IPersistStream, (void **)&src_stream); - ok(hr == S_OK, "QueryInterface error %#x\n", hr); - - hr = IPersistStream_Save(src_stream, dst_stream, TRUE); - ok(hr == S_OK, "Save error %#x\n", hr); - - IPersistStream_Release(src_stream); - IStream_Release(dst_stream); - - mem = GlobalLock(hmem); - ok(!memcmp(mem, "lt\0\0", 4), "got wrong stream header %04x\n", mem[0]); - ok(mem[1] == 128, "expected 128, got %u\n", mem[1]); - emh = (ENHMETAHEADER *)(mem + 2); - ok(emh->iType == EMR_HEADER, "wrong iType %04x\n", emh->iType); - ok(emh->dSignature == ENHMETA_SIGNATURE, "wrong dSignature %08x\n", emh->dSignature); - - GlobalUnlock(hmem); - GlobalFree(hmem); - - DeleteEnhMetaFile(desc.emf.hemf); - IPicture_Release(pic); -} - START_TEST(olepicture) { hOleaut32 = GetModuleHandleA("oleaut32.dll"); @@ -1449,7 +1317,6 @@ START_TEST(olepicture) test_pic(gifimage, sizeof(gifimage)); test_pic(jpgimage, sizeof(jpgimage)); test_pic(bmpimage, sizeof(bmpimage)); - test_pic(bmpimage_rle8, sizeof(bmpimage_rle8)); test_pic(gif4pixel, sizeof(gif4pixel)); /* FIXME: No PNG support in Windows... */ if (0) test_pic(pngimage, sizeof(pngimage)); @@ -1474,7 +1341,6 @@ START_TEST(olepicture) test_load_save_bmp(); test_load_save_icon(); test_load_save_empty_picture(); - test_load_save_emf(); } diff --git a/modules/rostests/winetests/oleaut32/test_reg.idl b/modules/rostests/winetests/oleaut32/test_reg.idl index 179d8c51a4..c9be76b027 100644 --- a/modules/rostests/winetests/oleaut32/test_reg.idl +++ b/modules/rostests/winetests/oleaut32/test_reg.idl @@ -130,6 +130,15 @@ library register_test interface Iole_from_disp; } + [ + uuid(fed318b2-c2ed-11e7-abc4-cec278b6b50a) + ] + interface ICollection : IDispatch + { + [id(DISPID_VALUE)] + HRESULT Item([in] int i, [out, retval] int *p); + } + [ uuid(f1b68c3b-02a3-4110-bc4c-cf9bc7e7f177) ] @@ -143,6 +152,8 @@ library register_test LONG testprop2([in] IUnknown *i); [id(3)] HRESULT testfunc([in] int i, [out, retval] int *p); + [propget, id(4)] + HRESULT testget([out, retval] ICollection **p); } /* uuid is same as for test_struct2 in test_tlb.idl, fields are different */ diff --git a/modules/rostests/winetests/oleaut32/tmarshal.c b/modules/rostests/winetests/oleaut32/tmarshal.c index c801494c49..ad29d95780 100644 --- a/modules/rostests/winetests/oleaut32/tmarshal.c +++ b/modules/rostests/winetests/oleaut32/tmarshal.c @@ -1355,7 +1355,7 @@ static void test_typelibmarshal(void) ok(!lstrcmpW(bstr, szCat), "IWidget_get_Name should have returned string \"Cat\" instead of %s\n", wine_dbgstr_w(bstr)); SysFreeString(bstr); - /* call DoSomething without optional arguments */ + /* call DoSomething */ VariantInit(&vararg[0]); VariantInit(&vararg[1]); V_VT(&vararg[1]) = VT_R8; @@ -1370,43 +1370,6 @@ static void test_typelibmarshal(void) ok(V_VT(&varresult) == VT_EMPTY, "varresult should be VT_EMPTY\n"); VariantClear(&varresult); - /* call DoSomething with optional argument set to VT_EMPTY */ - VariantInit(&vararg[0]); - VariantInit(&vararg[1]); - VariantInit(&vararg[2]); - V_VT(&vararg[2]) = VT_R8; - V_R8(&vararg[2]) = 3.141; - dispparams.cNamedArgs = 0; - dispparams.cArgs = 3; - dispparams.rgdispidNamedArgs = NULL; - dispparams.rgvarg = vararg; - VariantInit(&varresult); - hr = IDispatch_Invoke(pDispatch, DISPID_TM_DOSOMETHING, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL); - ok_ole_success(hr, IDispatch_Invoke); - ok(V_VT(&varresult) == VT_EMPTY, "varresult should be VT_EMPTY\n"); - VariantClear(&varresult); - - /* call DoSomething with optional arguments set to VT_ERROR/DISP_E_PARAMNOTFOUND */ - VariantInit(&vararg[0]); - VariantInit(&vararg[1]); - VariantInit(&vararg[2]); - VariantInit(&vararg[3]); - V_VT(&vararg[3]) = VT_R8; - V_R8(&vararg[3]) = 3.141; - V_VT(&vararg[1]) = VT_ERROR; - V_ERROR(&vararg[1]) = DISP_E_PARAMNOTFOUND; - V_VT(&vararg[0]) = VT_ERROR; - V_ERROR(&vararg[0]) = DISP_E_PARAMNOTFOUND; - dispparams.cNamedArgs = 0; - dispparams.cArgs = 4; - dispparams.rgdispidNamedArgs = NULL; - dispparams.rgvarg = vararg; - VariantInit(&varresult); - hr = IDispatch_Invoke(pDispatch, DISPID_TM_DOSOMETHING, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL); - ok_ole_success(hr, IDispatch_Invoke); - ok(V_VT(&varresult) == VT_EMPTY, "varresult should be VT_EMPTY\n"); - VariantClear(&varresult); - /* call get_State */ dispparams.cNamedArgs = 0; dispparams.cArgs = 0; @@ -1542,15 +1505,11 @@ static void test_typelibmarshal(void) dispparams.rgvarg = vararg; VariantInit(&varresult); hr = IDispatch_Invoke(pDispatch, DISPID_TM_COCLASS, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL); - ok_ole_success(hr, IDispatch_Invoke); + todo_wine ok_ole_success(hr, IDispatch_Invoke); ok(excepinfo.wCode == 0x0 && excepinfo.scode == S_OK, "EXCEPINFO differs from expected: wCode = 0x%x, scode = 0x%08x\n", excepinfo.wCode, excepinfo.scode); VariantClear(&varresult); - - /* call CoClass (direct) */ - hr = IWidget_Coclass(pWidget, (void *)V_DISPATCH(&vararg[0])); - ok_ole_success(hr, IWidget_Coclass); VariantClear(&vararg[0]); /* call Value with a VT_VARIANT|VT_BYREF type */ @@ -2043,7 +2002,8 @@ static void test_external_connection(void) todo_wine ok(external_connections == 2, "external_connections = %d\n", external_connections); - ITestSecondDisp_Release(second); + if (hres == S_OK) + ITestSecondDisp_Release(second); todo_wine ok(external_connections == 2, "external_connections = %d\n", external_connections); diff --git a/modules/rostests/winetests/oleaut32/typelib.c b/modules/rostests/winetests/oleaut32/typelib.c index c6626991c0..5f7e599a5d 100644 --- a/modules/rostests/winetests/oleaut32/typelib.c +++ b/modules/rostests/winetests/oleaut32/typelib.c @@ -74,6 +74,97 @@ static WCHAR wszguid[] = {'g','u','i','d',0}; static const BOOL is_win64 = sizeof(void *) > sizeof(int); +#ifdef __i386__ +static const BOOL abi_supports_stdcall = TRUE; +#else +static const BOOL abi_supports_stdcall = FALSE; +#endif + +static HRESULT WINAPI collection_QueryInterface(ICollection *iface, REFIID riid, void **ret) +{ + if (IsEqualIID(riid, &IID_IUnknown) || + IsEqualIID(riid, &IID_IDispatch) || + IsEqualIID(riid, &IID_ICollection)) + { + *ret = iface; + return S_OK; + } + + return E_NOINTERFACE; +} + +static ULONG WINAPI collection_AddRef(ICollection *iface) +{ + return 2; +} + +static ULONG WINAPI collection_Release(ICollection *iface) +{ + return 1; +} + +static HRESULT WINAPI collection_GetTypeInfoCount(ICollection *iface, UINT *cnt) +{ + ok(0, "unexpected call\n"); + *cnt = 0; + return E_NOTIMPL; +} + +static HRESULT WINAPI collection_GetTypeInfo(ICollection *iface, UINT index, LCID lcid, ITypeInfo **ti) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI collection_GetIDsOfNames(ICollection *iface, REFIID riid, LPOLESTR *names, + UINT cnt, LCID lcid, DISPID *dispid) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI collection_Invoke(ICollection *iface, DISPID dispid, REFIID riid, + LCID lcid, WORD flags, DISPPARAMS *dispparams, VARIANT *res, EXCEPINFO *ei, UINT *argerr) +{ + if(dispid != DISPID_VALUE) { + ok(0, "unexpected call\n"); + return E_NOTIMPL; + } + + ok(flags == (DISPATCH_METHOD|DISPATCH_PROPERTYGET), "flags = %x\n", flags); + ok(dispparams != NULL, "dispparams == NULL\n"); + ok(!dispparams->rgdispidNamedArgs, "dispparams->rgdispidNamedArgs != NULL\n"); + ok(dispparams->cArgs == 1, "dispparams->cArgs = %d\n", dispparams->cArgs); + ok(!dispparams->cNamedArgs, "dispparams->cNamedArgs = %d\n", dispparams->cNamedArgs); + ok(V_VT(dispparams->rgvarg) == VT_I4, "V_VT(dispparams->rgvarg) = %d\n", V_VT(dispparams->rgvarg)); + ok(V_I4(dispparams->rgvarg) == 7, "V_I4(dispparams->rgvarg) = %d\n", V_I4(dispparams->rgvarg)); + ok(res != NULL, "res == NULL\n"); + ok(V_VT(res) == VT_EMPTY, "V_VT(res) = %d\n", V_VT(res)); + + V_VT(res) = VT_I4; + V_I4(res) = 15; + return S_OK; +} + +static HRESULT WINAPI collection_Item(ICollection *iface, int i, int *p) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static const ICollectionVtbl collectionvtbl = { + collection_QueryInterface, + collection_AddRef, + collection_Release, + collection_GetTypeInfoCount, + collection_GetTypeInfo, + collection_GetIDsOfNames, + collection_Invoke, + collection_Item +}; + +static ICollection collection = { &collectionvtbl }; + static HRESULT WINAPI invoketest_QueryInterface(IInvokeTest *iface, REFIID riid, void **ret) { if (IsEqualIID(riid, &IID_IUnknown) || @@ -145,6 +236,13 @@ static HRESULT WINAPI invoketest_testfunc(IInvokeTest *iface, int i, int *p) return S_OK; } +static HRESULT WINAPI invoketest_testget(IInvokeTest *iface, ICollection **p) +{ + *p = &collection; + ICollection_AddRef(&collection); + return S_OK; +} + static const IInvokeTestVtbl invoketestvtbl = { invoketest_QueryInterface, invoketest_AddRef, @@ -156,7 +254,8 @@ static const IInvokeTestVtbl invoketestvtbl = { invoketest_get_test, invoketest_putref_testprop, invoketest_putref_testprop2, - invoketest_testfunc + invoketest_testfunc, + invoketest_testget }; static IInvokeTest invoketest = { &invoketestvtbl }; @@ -944,6 +1043,22 @@ static void test_TypeInfo(void) ok(V_VT(&res) == VT_I4, "got %d\n", V_VT(&res)); ok(V_I4(&res) == 1, "got %d\n", V_I4(&res)); + /* call propget with DISPATCH_METHOD|DISPATCH_PROPERTYGET flags */ + V_VT(&args[0]) = VT_I4; + V_I4(&args[0]) = 7; + + dispparams.cArgs = 1; + dispparams.rgvarg = args; + + i = 0; + V_VT(&res) = VT_EMPTY; + V_I4(&res) = 0; + hr = ITypeInfo_Invoke(pTypeInfo, &invoketest, 4, DISPATCH_METHOD|DISPATCH_PROPERTYGET, &dispparams, &res, NULL, &i); + ok(hr == S_OK, "got 0x%08x, %d\n", hr, i); + ok(V_VT(&res) == VT_I4, "got %d\n", V_VT(&res)); + ok(V_I4(&res) == 15, "got %d\n", V_I4(&res)); + + /* DISPATCH_PROPERTYPUTREF */ l = 1; V_VT(&args[0]) = VT_I4|VT_BYREF; @@ -1066,41 +1181,11 @@ static HRESULT WINAPI ret_false_func(void) return S_FALSE; } -static const WCHAR testW[] = { 'T','e','s','t',0 }; - -static void WINAPI variant_func2(VARIANT *ret, VARIANT v1, VARIANT v2) -{ - ok(V_VT(&v1) == VT_I4, "unexpected %d\n", V_VT(&v1)); - ok(V_I4(&v1) == 2, "unexpected %d\n", V_I4(&v1)); - ok(V_VT(&v2) == VT_BSTR, "unexpected %d\n", V_VT(&v2)); - ok(lstrcmpW(V_BSTR(&v2), testW) == 0, "unexpected %s\n", wine_dbgstr_w(V_BSTR(&v2))); - - V_VT(ret) = VT_UI4; - V_I4(ret) = 4321; -} - -static void WINAPI inst_func2(void *inst, VARIANT *ret, VARIANT v1, VARIANT v2) -{ - ok( (*(void ***)inst)[3] == inst_func2, "wrong ptr %p\n", inst ); - - ok(V_VT(ret) == VT_I4 || broken(V_VT(ret) == VT_VARIANT) /* win64 */, "unexpected %d\n", V_VT(ret)); - ok(V_I4(ret) == 1234, "unexpected %d\n", V_I4(ret)); - - ok(V_VT(&v1) == VT_I4, "unexpected %d\n", V_VT(&v1)); - ok(V_I4(&v1) == 2, "unexpected %d\n", V_I4(&v1)); - ok(V_VT(&v2) == VT_BSTR, "unexpected %d\n", V_VT(&v2)); - ok(lstrcmpW(V_BSTR(&v2), testW) == 0, "unexpected %s\n", wine_dbgstr_w(V_BSTR(&v2))); - - V_VT(ret) = VT_UI4; - V_I4(ret) = 4321; -} - -static void *vtable[] = { NULL, NULL, NULL, inst_func }; -static void *vtable2[] = { NULL, NULL, NULL, inst_func2 }; +static const void *vtable[] = { NULL, NULL, NULL, inst_func }; static void test_DispCallFunc(void) { - void **inst; + const void **inst = vtable; HRESULT res; VARIANT result, args[5]; VARIANTARG *pargs[5]; @@ -1109,30 +1194,6 @@ static void test_DispCallFunc(void) for (i = 0; i < 5; i++) pargs[i] = &args[i]; - memset( args, 0x55, sizeof(args) ); - - types[0] = VT_VARIANT; - V_VT(&args[0]) = VT_I4; - V_I4(&args[0]) = 2; - types[1] = VT_VARIANT; - V_VT(&args[1]) = VT_BSTR; - V_BSTR(&args[1]) = SysAllocString(testW); - memset( &result, 0xcc, sizeof(result) ); - res = DispCallFunc(NULL, (ULONG_PTR)variant_func2, CC_STDCALL, VT_VARIANT, 2, types, pargs, &result); - ok(res == S_OK, "DispCallFunc error %#x\n", res); - ok(V_VT(&result) == VT_UI4, "wrong result type %d\n", V_VT(&result)); - ok(V_UI4(&result) == 4321, "wrong result %u\n", V_UI4(&result)); - - V_VT(&result) = VT_I4; - V_UI4(&result) = 1234; - inst = vtable2; - res = DispCallFunc(&inst, 3 * sizeof(void *), CC_STDCALL, VT_VARIANT, 2, types, pargs, &result); - ok(res == S_OK, "DispCallFunc error %#x\n", res); - ok(V_VT(&result) == VT_UI4, "wrong result type %d\n", V_VT(&result)); - ok(V_UI4(&result) == 4321, "wrong result %u\n", V_UI4(&result)); - - VariantClear(&args[1]); - memset( args, 0x55, sizeof(args) ); types[0] = VT_UI4; V_UI4(&args[0]) = 1; @@ -1151,7 +1212,7 @@ static void test_DispCallFunc(void) ok( V_UI4(&result) == 4321, "wrong result %u\n", V_UI4(&result) ); /* the function checks the argument sizes for stdcall */ - if (!is_win64) /* no stdcall on 64-bit */ + if (abi_supports_stdcall) { res = DispCallFunc( NULL, (ULONG_PTR)stdcall_func, CC_STDCALL, VT_UI4, 0, types, pargs, &result ); ok( res == DISP_E_BADCALLEE, "DispCallFunc wrong error %x\n", res ); @@ -1231,7 +1292,6 @@ static void test_DispCallFunc(void) types[0] = VT_I4; V_I4(&args[0]) = 3; memset( &result, 0xcc, sizeof(result) ); - inst = vtable; res = DispCallFunc( &inst, 3 * sizeof(void*), CC_STDCALL, VT_I4, 1, types, pargs, &result ); ok( res == S_OK, "DispCallFunc failed %x\n", res ); ok( V_VT(&result) == VT_I4, "wrong result type %d\n", V_VT(&result) ); @@ -4868,7 +4928,7 @@ static void test_register_typelib(BOOL system_registration) { TYPEKIND kind; WORD flags; - } attrs[13] = + } attrs[] = { { TKIND_INTERFACE, 0 }, { TKIND_INTERFACE, TYPEFLAG_FDISPATCHABLE }, @@ -4882,6 +4942,7 @@ static void test_register_typelib(BOOL system_registration) { TKIND_DISPATCH, TYPEFLAG_FDISPATCHABLE }, { TKIND_DISPATCH, TYPEFLAG_FDISPATCHABLE }, { TKIND_INTERFACE, TYPEFLAG_FDISPATCHABLE }, + { TKIND_INTERFACE, TYPEFLAG_FDISPATCHABLE }, { TKIND_RECORD, 0 } }; @@ -4917,7 +4978,7 @@ static void test_register_typelib(BOOL system_registration) ok(hr == S_OK, "got %08x\n", hr); count = ITypeLib_GetTypeInfoCount(typelib); - ok(count == 13, "got %d\n", count); + ok(count == 14, "got %d\n", count); for(i = 0; i < count; i++) { diff --git a/modules/rostests/winetests/oleaut32/vartest.c b/modules/rostests/winetests/oleaut32/vartest.c index 38eb1806a8..0d0d76012e 100644 --- a/modules/rostests/winetests/oleaut32/vartest.c +++ b/modules/rostests/winetests/oleaut32/vartest.c @@ -1930,6 +1930,11 @@ static void test_VarNumFromParseNum(void) /* Currency is preferred over decimal */ SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_CY|VTBIT_DECIMAL); EXPECT_CY(1); + + /* Underflow test */ + SETRGB(0, 1); CONVERT(1,0,NUMPRS_EXPONENT,1,0,-94938484, VTBIT_R4); EXPECT_R4(0.0); + SETRGB(0, 1); CONVERT(1,0,NUMPRS_EXPONENT,1,0,-94938484, VTBIT_R8); EXPECT_R8(0.0); + SETRGB(0, 1); CONVERT(1,0,NUMPRS_EXPONENT,1,0,-94938484, VTBIT_CY); EXPECT_CY(0); } diff --git a/modules/rostests/winetests/oleaut32/vartype.c b/modules/rostests/winetests/oleaut32/vartype.c index 5086e4b500..a831393858 100644 --- a/modules/rostests/winetests/oleaut32/vartype.c +++ b/modules/rostests/winetests/oleaut32/vartype.c @@ -2722,6 +2722,7 @@ static void test_VarR8FromStr(void) CONVERT_STR(VarR8FromStr,"0.5",LOCALE_NOUSEROVERRIDE); EXPECT(0.5); CONVERT_STR(VarR8FromStr,"0.6",LOCALE_NOUSEROVERRIDE); EXPECT(0.6); CONVERT_STR(VarR8FromStr,"1.5",LOCALE_NOUSEROVERRIDE); EXPECT(1.5); + CONVERT_STR(VarR8FromStr,"1e-94938484",LOCALE_NOUSEROVERRIDE); EXPECT(0); /* We already have exhaustive tests for number parsing, so skip those tests here */ } @@ -3102,6 +3103,8 @@ static void test_VarDateFromStr(void) DFS("6/30/2011 01:20:34"); EXPECT_DBL(40724.05594907407); DFS("6/30/2011 01:20:34 AM"); EXPECT_DBL(40724.05594907407); DFS("6/30/2011 01:20:34 PM"); EXPECT_DBL(40724.55594907407); + DFS("2013-05-14 02:04:12"); EXPECT_DBL(41408.08625000001); + DFS("2013-05-14 02:04:12.017000000"); EXPECT_MISMATCH; /* Native fails "1999 January 3, 9AM". I consider that a bug in native */ /* test a data with ideographic space */
7 years, 4 months
1
0
0
0
01/01: [OLEAUT32] Sync with Wine 3.0. CORE-14225
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=13fd286c1840f80c0fca1…
commit 13fd286c1840f80c0fca1dbfedd600a0f8a4478b Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Sat Jan 20 12:59:23 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Sat Jan 20 12:59:23 2018 +0100 [OLEAUT32] Sync with Wine 3.0. CORE-14225 --- dll/win32/oleaut32/oleaut.c | 2 +- dll/win32/oleaut32/olepicture.c | 355 ++++++++++---------------- dll/win32/oleaut32/tmarshal.c | 216 ++++------------ dll/win32/oleaut32/typelib.c | 536 +++++++++++++++++++++------------------- dll/win32/oleaut32/typelib.h | 6 +- dll/win32/oleaut32/variant.c | 14 +- dll/win32/oleaut32/vartype.c | 2 +- media/doc/README.WINE | 2 +- 8 files changed, 474 insertions(+), 659 deletions(-) diff --git a/dll/win32/oleaut32/oleaut.c b/dll/win32/oleaut32/oleaut.c index 349a64da61..0c3679491c 100644 --- a/dll/win32/oleaut32/oleaut.c +++ b/dll/win32/oleaut32/oleaut.c @@ -100,7 +100,7 @@ static inline size_t bstr_alloc_size(size_t size) static inline bstr_t *bstr_from_str(BSTR str) { - return CONTAINING_RECORD((void *)str, bstr_t, u.str); + return CONTAINING_RECORD(str, bstr_t, u.str); } static inline bstr_cache_entry_t *get_cache_entry_from_idx(unsigned cache_idx) diff --git a/dll/win32/oleaut32/olepicture.c b/dll/win32/oleaut32/olepicture.c index 878fd18292..b687fdf201 100644 --- a/dll/win32/oleaut32/olepicture.c +++ b/dll/win32/oleaut32/olepicture.c @@ -246,18 +246,6 @@ static void OLEPictureImpl_SetIcon(OLEPictureImpl * This) } } -static void OLEPictureImpl_SetEMF(OLEPictureImpl *This) -{ - ENHMETAHEADER emh; - - GetEnhMetaFileHeader(This->desc.u.emf.hemf, sizeof(emh), &emh); - - This->origWidth = 0; - This->origHeight = 0; - This->himetricWidth = emh.rclFrame.right - emh.rclFrame.left; - This->himetricHeight = emh.rclFrame.bottom - emh.rclFrame.top; -} - /************************************************************************ * OLEPictureImpl_Construct * @@ -339,11 +327,7 @@ static OLEPictureImpl* OLEPictureImpl_Construct(LPPICTDESC pictDesc, BOOL fOwn) case PICTYPE_ICON: OLEPictureImpl_SetIcon(newObject); break; - case PICTYPE_ENHMETAFILE: - OLEPictureImpl_SetEMF(newObject); - break; - default: FIXME("Unsupported type %d\n", pictDesc->picType); newObject->himetricWidth = newObject->himetricHeight = 0; @@ -829,6 +813,19 @@ static HRESULT WINAPI OLEPictureImpl_PictureChanged(IPicture *iface) return S_OK; } +/************************************************************************ + * OLEPictureImpl_SaveAsFile + */ +static HRESULT WINAPI OLEPictureImpl_SaveAsFile(IPicture *iface, + IStream *pstream, + BOOL SaveMemCopy, + LONG *pcbSize) +{ + OLEPictureImpl *This = impl_from_IPicture(iface); + FIXME("(%p)->(%p, %d, %p), hacked stub.\n", This, pstream, SaveMemCopy, pcbSize); + return IStream_Write(pstream,This->data,This->datalen,(ULONG*)pcbSize); +} + /************************************************************************ * OLEPictureImpl_get_Attributes */ @@ -978,13 +975,40 @@ static HRESULT WINAPI OLEPictureImpl_IsDirty( return E_NOTIMPL; } +static HRESULT OLEPictureImpl_LoadDIB(OLEPictureImpl *This, BYTE *xbuf, ULONG xread) +{ + BITMAPFILEHEADER *bfh = (BITMAPFILEHEADER*)xbuf; + BITMAPINFO *bi = (BITMAPINFO*)(bfh+1); + HDC hdcref; + + /* Does not matter whether this is a coreheader or not, we only use + * components which are in both + */ + hdcref = GetDC(0); + This->desc.u.bmp.hbitmap = CreateDIBitmap( + hdcref, + &(bi->bmiHeader), + CBM_INIT, + xbuf+bfh->bfOffBits, + bi, + DIB_RGB_COLORS + ); + ReleaseDC(0, hdcref); + if (This->desc.u.bmp.hbitmap == 0) + return E_FAIL; + This->desc.picType = PICTYPE_BITMAP; + OLEPictureImpl_SetBitmap(This); + return S_OK; +} + static HRESULT OLEPictureImpl_LoadWICSource(OLEPictureImpl *This, IWICBitmapSource *src) { HRESULT hr; BITMAPINFOHEADER bih; + HDC hdcref; UINT width, height; UINT stride, buffersize; - BYTE *bits, *mask = NULL; + LPBYTE bits=NULL; WICRect rc; IWICBitmapSource *real_source; UINT x, y; @@ -1012,28 +1036,34 @@ static HRESULT OLEPictureImpl_LoadWICSource(OLEPictureImpl *This, IWICBitmapSour stride = 4 * width; buffersize = stride * height; - mask = HeapAlloc(GetProcessHeap(), 0, buffersize); - if (!mask) + bits = HeapAlloc(GetProcessHeap(), 0, buffersize); + if (!bits) { hr = E_OUTOFMEMORY; goto end; } - This->desc.u.bmp.hbitmap = CreateDIBSection(0, (BITMAPINFO*)&bih, DIB_RGB_COLORS, (void **)&bits, NULL, 0); - if (This->desc.u.bmp.hbitmap == 0) - { - hr = E_FAIL; - goto end; - } - rc.X = 0; rc.Y = 0; rc.Width = width; rc.Height = height; hr = IWICBitmapSource_CopyPixels(real_source, &rc, stride, buffersize, bits); if (FAILED(hr)) + goto end; + + hdcref = GetDC(0); + This->desc.u.bmp.hbitmap = CreateDIBitmap( + hdcref, + &bih, + CBM_INIT, + bits, + (BITMAPINFO*)&bih, + DIB_RGB_COLORS); + + if (This->desc.u.bmp.hbitmap == 0) { - DeleteObject(This->desc.u.bmp.hbitmap); + hr = E_FAIL; + ReleaseDC(0, hdcref); goto end; } @@ -1047,25 +1077,23 @@ static HRESULT OLEPictureImpl_LoadWICSource(OLEPictureImpl *This, IWICBitmapSour if((*pixel & 0x80000000) == 0) { has_alpha = TRUE; - *(DWORD *)(mask + stride * y + 4 * x) = black; + *pixel = black; } else - *(DWORD *)(mask + stride * y + 4 * x) = white; + *pixel = white; } } if (has_alpha) { - HDC hdcref, hdcBmp, hdcXor, hdcMask; + HDC hdcBmp, hdcXor, hdcMask; HBITMAP hbmoldBmp, hbmoldXor, hbmoldMask; - hdcref = GetDC(0); - This->hbmXor = CreateDIBitmap( hdcref, &bih, CBM_INIT, - mask, + bits, (BITMAPINFO*)&bih, DIB_RGB_COLORS ); @@ -1090,11 +1118,12 @@ static HRESULT OLEPictureImpl_LoadWICSource(OLEPictureImpl *This, IWICBitmapSour DeleteDC(hdcBmp); DeleteDC(hdcXor); DeleteDC(hdcMask); - ReleaseDC(0, hdcref); } + ReleaseDC(0, hdcref); + end: - HeapFree(GetProcessHeap(), 0, mask); + HeapFree(GetProcessHeap(), 0, bits); IWICBitmapSource_Release(real_source); return hr; } @@ -1458,7 +1487,7 @@ static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface, IStream *pStm) hr = OLEPictureImpl_LoadWICDecoder(This, &CLSID_WICJpegDecoder, xbuf, xread); break; case BITMAP_FORMAT_BMP: /* Bitmap */ - hr = OLEPictureImpl_LoadWICDecoder(This, &CLSID_WICBmpDecoder, xbuf, xread); + hr = OLEPictureImpl_LoadDIB(This, xbuf, xread); break; case BITMAP_FORMAT_PNG: /* PNG */ hr = OLEPictureImpl_LoadWICDecoder(This, &CLSID_WICPngDecoder, xbuf, xread); @@ -1713,17 +1742,6 @@ static BOOL serializeIcon(HICON hIcon, void ** ppBuffer, unsigned int * pLength) return success; } -static BOOL serializeEMF(HENHMETAFILE hemf, void **buf, unsigned *size) -{ - *size = GetEnhMetaFileBits(hemf, 0, NULL); - if (!*size) return FALSE; - - *buf = HeapAlloc(GetProcessHeap(), 0, *size); - if (!*buf) return FALSE; - - return GetEnhMetaFileBits(hemf, *size, *buf) != 0; -} - static HRESULT WINAPI OLEPictureImpl_Save( IPersistStream* iface,IStream*pStm,BOOL fClearDirty) { @@ -1799,31 +1817,12 @@ static HRESULT WINAPI OLEPictureImpl_Save( IStream_Write(pStm, This->data, This->datalen, &dummy); hResult = S_OK; break; - - case PICTYPE_ENHMETAFILE: - if (This->bIsDirty || !This->data) - { - serializeResult = serializeEMF(This->desc.u.emf.hemf, &pIconData, &iDataSize); - if (!serializeResult) - { - hResult = E_FAIL; - break; - } - - HeapFree(GetProcessHeap(), 0, This->data); - This->data = pIconData; - This->datalen = iDataSize; - } - header[0] = 0x0000746c; - header[1] = This->datalen; - IStream_Write(pStm, header, 2 * sizeof(DWORD), &dummy); - IStream_Write(pStm, This->data, This->datalen, &dummy); - hResult = S_OK; - break; - case PICTYPE_METAFILE: FIXME("(%p,%p,%d), PICTYPE_METAFILE not implemented!\n",This,pStm,fClearDirty); break; + case PICTYPE_ENHMETAFILE: + FIXME("(%p,%p,%d),PICTYPE_ENHMETAFILE not implemented!\n",This,pStm,fClearDirty); + break; default: FIXME("(%p,%p,%d), [unknown type] not implemented!\n",This,pStm,fClearDirty); break; @@ -1840,98 +1839,6 @@ static HRESULT WINAPI OLEPictureImpl_GetSizeMax( return E_NOTIMPL; } -/************************************************************************ - * OLEPictureImpl_SaveAsFile - */ -static HRESULT WINAPI OLEPictureImpl_SaveAsFile(IPicture *iface, - IStream *stream, BOOL mem_copy, LONG *size) -{ - OLEPictureImpl *This = impl_from_IPicture(iface); - void *data; - unsigned data_size; - ULONG written; - HRESULT hr; - - FIXME("(%p)->(%p,%d,%p): semi-stub\n", This, stream, mem_copy, size); - - switch (This->desc.picType) - { - case PICTYPE_NONE: - return S_OK; - - case PICTYPE_ICON: - if (!mem_copy) return E_FAIL; - - if (This->bIsDirty || !This->data) - { - if (!serializeIcon(This->desc.u.icon.hicon, &data, &data_size)) - return E_FAIL; - HeapFree(GetProcessHeap(), 0, This->data); - This->data = data; - This->datalen = data_size; - } - hr = IStream_Write(stream, This->data, This->datalen, &written); - if (hr == S_OK && size) *size = written; - return hr; - - case PICTYPE_BITMAP: - if (!mem_copy) return E_FAIL; - - if (This->bIsDirty || !This->data) - { - switch (This->keepOrigFormat ? This->loadtime_format : BITMAP_FORMAT_BMP) - { - case BITMAP_FORMAT_BMP: - if (!serializeBMP(This->desc.u.bmp.hbitmap, &data, &data_size)) - return E_FAIL; - break; - case BITMAP_FORMAT_JPEG: - FIXME("BITMAP_FORMAT_JPEG is not implemented\n"); - return E_NOTIMPL; - case BITMAP_FORMAT_GIF: - FIXME("BITMAP_FORMAT_GIF is not implemented\n"); - return E_NOTIMPL; - case BITMAP_FORMAT_PNG: - FIXME("BITMAP_FORMAT_PNG is not implemented\n"); - return E_NOTIMPL; - default: - FIXME("PICTYPE_BITMAP/%#x is not implemented\n", This->loadtime_format); - return E_NOTIMPL; - } - - HeapFree(GetProcessHeap(), 0, This->data); - This->data = data; - This->datalen = data_size; - } - hr = IStream_Write(stream, This->data, This->datalen, &written); - if (hr == S_OK && size) *size = written; - return hr; - - case PICTYPE_METAFILE: - FIXME("PICTYPE_METAFILE is not implemented\n"); - return E_NOTIMPL; - - case PICTYPE_ENHMETAFILE: - if (!mem_copy) return E_FAIL; - - if (This->bIsDirty || !This->data) - { - if (!serializeEMF(This->desc.u.emf.hemf, &data, &data_size)) - return E_FAIL; - HeapFree(GetProcessHeap(), 0, This->data); - This->data = data; - This->datalen = data_size; - } - hr = IStream_Write(stream, This->data, This->datalen, &written); - if (hr == S_OK && size) *size = written; - return hr; - - default: - FIXME("%#x is not implemented\n", This->desc.picType); - break; - } - return E_NOTIMPL; -} /************************************************************************ * IDispatch @@ -2388,70 +2295,13 @@ HRESULT WINAPI OleLoadPictureEx( LPSTREAM lpstream, LONG lSize, BOOL fRunmode, return hr; } -static HRESULT create_stream(const WCHAR *filename, IStream **stream) -{ - HANDLE hFile; - DWORD dwFileSize; - HGLOBAL hGlobal = NULL; - DWORD dwBytesRead; - HRESULT hr = S_OK; - - hFile = CreateFileW(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); - if (hFile == INVALID_HANDLE_VALUE) - return HRESULT_FROM_WIN32(GetLastError()); - - dwFileSize = GetFileSize(hFile, NULL); - if (dwFileSize != INVALID_FILE_SIZE) - { - hGlobal = GlobalAlloc(GMEM_FIXED, dwFileSize); - if (!hGlobal) - hr = E_OUTOFMEMORY; - else - { - if (!ReadFile(hFile, hGlobal, dwFileSize, &dwBytesRead, NULL)) - { - GlobalFree(hGlobal); - hr = HRESULT_FROM_WIN32(GetLastError()); - } - } - } - - CloseHandle(hFile); - - if (FAILED(hr)) return hr; - - hr = CreateStreamOnHGlobal(hGlobal, TRUE, stream); - if (FAILED(hr)) - GlobalFree(hGlobal); - - return hr; -} - /*********************************************************************** * OleLoadPictureFile (OLEAUT32.422) */ -HRESULT WINAPI OleLoadPictureFile(VARIANT filename, IDispatch **picture) +HRESULT WINAPI OleLoadPictureFile(VARIANT file, LPDISPATCH *picture) { - IStream *stream; - HRESULT hr; - - TRACE("(%s,%p)\n", wine_dbgstr_variant(&filename), picture); - - if (V_VT(&filename) != VT_BSTR) - return CTL_E_FILENOTFOUND; - - hr = create_stream(V_BSTR(&filename), &stream); - if (hr != S_OK) - { - if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) - return CTL_E_FILENOTFOUND; - - return CTL_E_PATHFILEACCESSERROR; - } - - hr = OleLoadPicture(stream, 0, FALSE, &IID_IDispatch, (void **)picture); - IStream_Release(stream); - return hr; + FIXME("(%s %p): stub\n", wine_dbgstr_variant(&file), picture); + return E_NOTIMPL; } /*********************************************************************** @@ -2471,8 +2321,16 @@ HRESULT WINAPI OleLoadPicturePath( LPOLESTR szURLorPath, LPUNKNOWN punkCaller, LPVOID *ppvRet ) { static const WCHAR file[] = { 'f','i','l','e',':',0 }; + IPicture *ipicture; + HANDLE hFile; + DWORD dwFileSize; + HGLOBAL hGlobal = NULL; + DWORD dwBytesRead; IStream *stream; + BOOL bRead; + IPersistStream *pStream; HRESULT hRes; + HRESULT init_res; WCHAR *file_candidate; WCHAR path_buf[MAX_PATH]; @@ -2500,9 +2358,36 @@ HRESULT WINAPI OleLoadPicturePath( LPOLESTR szURLorPath, LPUNKNOWN punkCaller, /* Handle candidate DOS paths separately. */ if (file_candidate[1] == ':') { - hRes = create_stream(file_candidate, &stream); - if (FAILED(hRes)) + hFile = CreateFileW(file_candidate, GENERIC_READ, 0, NULL, OPEN_EXISTING, + 0, NULL); + if (hFile == INVALID_HANDLE_VALUE) + return INET_E_RESOURCE_NOT_FOUND; + + dwFileSize = GetFileSize(hFile, NULL); + if (dwFileSize != INVALID_FILE_SIZE ) + { + hGlobal = GlobalAlloc(GMEM_FIXED,dwFileSize); + if ( hGlobal) + { + bRead = ReadFile(hFile, hGlobal, dwFileSize, &dwBytesRead, NULL) && dwBytesRead == dwFileSize; + if (!bRead) + { + GlobalFree(hGlobal); + hGlobal = 0; + } + } + } + CloseHandle(hFile); + + if (!hGlobal) return INET_E_RESOURCE_NOT_FOUND; + + hRes = CreateStreamOnHGlobal(hGlobal, TRUE, &stream); + if (FAILED(hRes)) + { + GlobalFree(hGlobal); + return hRes; + } } else { IMoniker *pmnk; IBindCtx *pbc; @@ -2522,10 +2407,32 @@ HRESULT WINAPI OleLoadPicturePath( LPOLESTR szURLorPath, LPUNKNOWN punkCaller, return hRes; } - hRes = OleLoadPicture(stream, 0, FALSE, riid, ppvRet); + init_res = CoInitialize(NULL); + + hRes = CoCreateInstance(&CLSID_StdPicture, punkCaller, CLSCTX_INPROC_SERVER, + &IID_IPicture, (LPVOID*)&ipicture); + if (SUCCEEDED(hRes)) { + hRes = IPicture_QueryInterface(ipicture, &IID_IPersistStream, (LPVOID*)&pStream); + + if (SUCCEEDED(hRes)) { + hRes = IPersistStream_Load(pStream, stream); + + if (SUCCEEDED(hRes)) { + hRes = IPicture_QueryInterface(ipicture, riid, ppvRet); + + if (FAILED(hRes)) + ERR("Failed to get interface %s from IPicture.\n", debugstr_guid(riid)); + } + IPersistStream_Release(pStream); + } + IPicture_Release(ipicture); + } IStream_Release(stream); + if (SUCCEEDED(init_res)) + CoUninitialize(); + return hRes; } diff --git a/dll/win32/oleaut32/tmarshal.c b/dll/win32/oleaut32/tmarshal.c index 7a085f1fa2..ca8c0db150 100644 --- a/dll/win32/oleaut32/tmarshal.c +++ b/dll/win32/oleaut32/tmarshal.c @@ -471,6 +471,7 @@ static HRESULT num_of_funcs(ITypeInfo *tinfo, unsigned int *num, #ifdef __i386__ #include "pshpack1.h" + typedef struct _TMAsmProxy { DWORD lealeax; BYTE pushleax; @@ -482,30 +483,7 @@ typedef struct _TMAsmProxy { WORD bytestopop; WORD nop; } TMAsmProxy; -#include "poppack.h" -#elif defined(__x86_64__) - -#include "pshpack1.h" -typedef struct _TMAsmProxy { - BYTE pushq_rbp; - BYTE movq_rsp_rbp[3]; - DWORD subq_0x20_rsp; - DWORD movq_rcx_0x10rbp; - DWORD movq_rdx_0x18rbp; - DWORD movq_r8_0x20rbp; - DWORD movq_r9_0x28rbp; - BYTE movq_rcx[3]; - DWORD nr; - DWORD leaq_0x10rbp_rdx; - WORD movq_rax; - void *xcall; - WORD callq_rax; - BYTE movq_rbp_rsp[3]; - BYTE popq_rbp; - BYTE ret; - DWORD nop; -} TMAsmProxy; #include "poppack.h" #else /* __i386__ */ @@ -641,51 +619,42 @@ static const IRpcProxyBufferVtbl tmproxyvtable = { TMProxyImpl_Disconnect }; -/* how much space do we use on stack in DWORD_PTR steps. */ +/* how much space do we use on stack in DWORD steps. */ static int _argsize(TYPEDESC *tdesc, ITypeInfo *tinfo) { - DWORD ret; switch (tdesc->vt) { case VT_I8: case VT_UI8: - ret = 8; - break; + return 8/sizeof(DWORD); case VT_R8: - ret = sizeof(double); - break; + return sizeof(double)/sizeof(DWORD); case VT_CY: - ret = sizeof(CY); - break; + return sizeof(CY)/sizeof(DWORD); case VT_DATE: - ret = sizeof(DATE); - break; + return sizeof(DATE)/sizeof(DWORD); case VT_DECIMAL: - ret = sizeof(DECIMAL); - break; + return (sizeof(DECIMAL)+3)/sizeof(DWORD); case VT_VARIANT: - ret = sizeof(VARIANT); - break; + return (sizeof(VARIANT)+3)/sizeof(DWORD); case VT_USERDEFINED: { ITypeInfo *tinfo2; TYPEATTR *tattr; HRESULT hres; + DWORD ret; hres = ITypeInfo_GetRefTypeInfo(tinfo,tdesc->u.hreftype,&tinfo2); if (FAILED(hres)) return 0; /* should fail critically in serialize_param */ ITypeInfo_GetTypeAttr(tinfo2,&tattr); - ret = tattr->cbSizeInstance; + ret = (tattr->cbSizeInstance+3)/sizeof(DWORD); ITypeInfo_ReleaseTypeAttr(tinfo2, tattr); ITypeInfo_Release(tinfo2); - break; + return ret; } default: - ret = sizeof(DWORD_PTR); - break; + return 1; } - - return (ret + sizeof(DWORD_PTR) - 1) / sizeof(DWORD_PTR); } /* how much space do we use on the heap (in bytes) */ @@ -734,7 +703,7 @@ _xsize(const TYPEDESC *td, ITypeInfo *tinfo) { return ret; } default: - return sizeof(DWORD_PTR); + return 4; } } @@ -753,7 +722,7 @@ serialize_param( BOOL debugout, BOOL dealloc, TYPEDESC *tdesc, - DWORD_PTR *arg, + DWORD *arg, marshal_state *buf) { HRESULT hres = S_OK; @@ -772,7 +741,7 @@ serialize_param( case VT_R8: case VT_CY: hres = S_OK; - if (debugout) TRACE_(olerelay)("%s\n", wine_dbgstr_longlong(*(ULONGLONG *)arg)); + if (debugout) TRACE_(olerelay)("%x%x\n",arg[0],arg[1]); if (writeit) hres = xbuf_add(buf,(LPBYTE)arg,8); return hres; @@ -783,7 +752,7 @@ serialize_param( case VT_R4: case VT_UI4: hres = S_OK; - if (debugout) TRACE_(olerelay)("%x\n", *(DWORD *)arg); + if (debugout) TRACE_(olerelay)("%x\n",*arg); if (writeit) hres = xbuf_add(buf,(LPBYTE)arg,sizeof(DWORD)); return hres; @@ -791,14 +760,14 @@ serialize_param( case VT_UI2: case VT_BOOL: hres = S_OK; - if (debugout) TRACE_(olerelay)("%04x\n", *(WORD *)arg); + if (debugout) TRACE_(olerelay)("%04x\n",*arg & 0xffff); if (writeit) hres = xbuf_add(buf,(LPBYTE)arg,sizeof(DWORD)); return hres; case VT_I1: case VT_UI1: hres = S_OK; - if (debugout) TRACE_(olerelay)("%02x\n", *(BYTE *)arg); + if (debugout) TRACE_(olerelay)("%02x\n",*arg & 0xff); if (writeit) hres = xbuf_add(buf,(LPBYTE)arg,sizeof(DWORD)); return hres; @@ -868,9 +837,7 @@ serialize_param( return hres; } ITypeInfo_GetTypeAttr(tinfo2,&tattr); - derefhere = (tattr->typekind != TKIND_DISPATCH && - tattr->typekind != TKIND_INTERFACE && - tattr->typekind != TKIND_COCLASS); + derefhere = (tattr->typekind != TKIND_DISPATCH && tattr->typekind != TKIND_INTERFACE); } break; case TKIND_ENUM: /* confirmed */ @@ -878,7 +845,6 @@ serialize_param( break; case TKIND_DISPATCH: /* will be done in VT_USERDEFINED case */ case TKIND_INTERFACE: /* will be done in VT_USERDEFINED case */ - case TKIND_COCLASS: /* will be done in VT_USERDEFINED case */ derefhere=FALSE; break; default: @@ -901,19 +867,19 @@ serialize_param( if (debugout) TRACE_(olerelay)("NULL"); return S_OK; } - hres = serialize_param(tinfo,writeit,debugout,dealloc,tdesc->u.lptdesc,(DWORD_PTR *)*arg,buf); + hres = serialize_param(tinfo,writeit,debugout,dealloc,tdesc->u.lptdesc,(DWORD*)*arg,buf); if (derefhere && dealloc) HeapFree(GetProcessHeap(),0,(LPVOID)*arg); return hres; } case VT_UNKNOWN: - if (debugout) TRACE_(olerelay)("unk(0x%lx)", *arg); + if (debugout) TRACE_(olerelay)("unk(0x%x)",*arg); if (writeit) hres = _marshal_interface(buf,&IID_IUnknown,(LPUNKNOWN)*arg); if (dealloc && *(IUnknown **)arg) IUnknown_Release((LPUNKNOWN)*arg); return hres; case VT_DISPATCH: - if (debugout) TRACE_(olerelay)("idisp(0x%lx)", *arg); + if (debugout) TRACE_(olerelay)("idisp(0x%x)",*arg); if (writeit) hres = _marshal_interface(buf,&IID_IDispatch,(LPUNKNOWN)*arg); if (dealloc && *(IUnknown **)arg) @@ -940,36 +906,6 @@ serialize_param( if (dealloc) IUnknown_Release((LPUNKNOWN)arg); break; - case TKIND_COCLASS: { - GUID iid = tattr->guid; - unsigned int i; - int type_flags; - - for(i = 0; i < tattr->cImplTypes; i++) { - if(SUCCEEDED(ITypeInfo_GetImplTypeFlags(tinfo2, i, &type_flags)) && - type_flags == (IMPLTYPEFLAG_FSOURCE|IMPLTYPEFLAG_FDEFAULT)) { - ITypeInfo *tinfo3; - TYPEATTR *tattr2; - HREFTYPE href; - if(FAILED(ITypeInfo_GetRefTypeOfImplType(tinfo2, i, &href))) - break; - if(FAILED(ITypeInfo_GetRefTypeInfo(tinfo2, href, &tinfo3))) - break; - if(SUCCEEDED(ITypeInfo_GetTypeAttr(tinfo3, &tattr2))) { - iid = tattr2->guid; - ITypeInfo_ReleaseTypeAttr(tinfo3, tattr2); - } - ITypeInfo_Release(tinfo3); - break; - } - } - - if(writeit) - hres=_marshal_interface(buf, &iid, (LPUNKNOWN)arg); - if(dealloc) - IUnknown_Release((LPUNKNOWN)arg); - break; - } case TKIND_RECORD: { int i; if (debugout) TRACE_(olerelay)("{"); @@ -991,7 +927,7 @@ serialize_param( debugout, dealloc, tdesc2, - (DWORD_PTR *)(((LPBYTE)arg)+vdesc->u.oInst), + (DWORD*)(((LPBYTE)arg)+vdesc->u.oInst), buf ); ITypeInfo_ReleaseVarDesc(tinfo2, vdesc); @@ -1008,7 +944,7 @@ serialize_param( break; case TKIND_ENUM: hres = S_OK; - if (debugout) TRACE_(olerelay)("%x", *(DWORD *)arg); + if (debugout) TRACE_(olerelay)("%x",*arg); if (writeit) hres = xbuf_add(buf,(LPBYTE)arg,sizeof(DWORD)); break; @@ -1034,7 +970,7 @@ serialize_param( if (debugout) TRACE_(olerelay)("["); for (i=0;i<arrsize;i++) { LPBYTE base = _passbyref(&adesc->tdescElem, tinfo) ? (LPBYTE) *arg : (LPBYTE) arg; - hres = serialize_param(tinfo, writeit, debugout, dealloc, &adesc->tdescElem, (DWORD_PTR *)((LPBYTE)base+i*_xsize(&adesc->tdescElem, tinfo)), buf); + hres = serialize_param(tinfo, writeit, debugout, dealloc, &adesc->tdescElem, (DWORD*)((LPBYTE)base+i*_xsize(&adesc->tdescElem, tinfo)), buf); if (hres) return hres; if (debugout && (i<arrsize-1)) TRACE_(olerelay)(","); @@ -1073,7 +1009,7 @@ deserialize_param( BOOL debugout, BOOL alloc, TYPEDESC *tdesc, - DWORD_PTR *arg, + DWORD *arg, marshal_state *buf) { HRESULT hres = S_OK; @@ -1106,7 +1042,7 @@ deserialize_param( hres = xbuf_get(buf,(LPBYTE)arg,8); if (hres) ERR("Failed to read integer 8 byte\n"); } - if (debugout) TRACE_(olerelay)("%s", wine_dbgstr_longlong(*(ULONGLONG *)arg)); + if (debugout) TRACE_(olerelay)("%x%x",arg[0],arg[1]); return hres; case VT_ERROR: case VT_I4: @@ -1118,7 +1054,7 @@ deserialize_param( hres = xbuf_get(buf,(LPBYTE)arg,sizeof(DWORD)); if (hres) ERR("Failed to read integer 4 byte\n"); } - if (debugout) TRACE_(olerelay)("%x", *(DWORD *)arg); + if (debugout) TRACE_(olerelay)("%x",*arg); return hres; case VT_I2: case VT_UI2: @@ -1129,7 +1065,7 @@ deserialize_param( if (hres) ERR("Failed to read integer 4 byte\n"); else memcpy(arg,&x,2); } - if (debugout) TRACE_(olerelay)("%04x", *(WORD *)arg); + if (debugout) TRACE_(olerelay)("%04x",*arg & 0xffff); return hres; case VT_I1: case VT_UI1: @@ -1139,7 +1075,7 @@ deserialize_param( if (hres) ERR("Failed to read integer 4 byte\n"); else memcpy(arg,&x,1); } - if (debugout) TRACE_(olerelay)("%02x", *(BYTE *)arg); + if (debugout) TRACE_(olerelay)("%02x",*arg & 0xff); return hres; case VT_BSTR: { if (readit) @@ -1179,9 +1115,7 @@ deserialize_param( return hres; } ITypeInfo_GetTypeAttr(tinfo2,&tattr); - derefhere = (tattr->typekind != TKIND_DISPATCH && - tattr->typekind != TKIND_INTERFACE && - tattr->typekind != TKIND_COCLASS); + derefhere = (tattr->typekind != TKIND_DISPATCH && tattr->typekind != TKIND_INTERFACE); } break; case TKIND_ENUM: /* confirmed */ @@ -1189,7 +1123,6 @@ deserialize_param( break; case TKIND_DISPATCH: /* will be done in VT_USERDEFINED case */ case TKIND_INTERFACE: /* will be done in VT_USERDEFINED case */ - case TKIND_COCLASS: /* will be done in VT_USERDEFINED case */ derefhere=FALSE; break; default: @@ -1218,17 +1151,17 @@ deserialize_param( if (alloc) { /* Allocate space for the referenced struct */ if (derefhere) - *arg=(DWORD_PTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,_xsize(tdesc->u.lptdesc, tinfo)); + *arg=(DWORD)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,_xsize(tdesc->u.lptdesc, tinfo)); } if (derefhere) - return deserialize_param(tinfo, readit, debugout, alloc, tdesc->u.lptdesc, (DWORD_PTR *)*arg, buf); + return deserialize_param(tinfo, readit, debugout, alloc, tdesc->u.lptdesc, (LPDWORD)*arg, buf); else return deserialize_param(tinfo, readit, debugout, alloc, tdesc->u.lptdesc, arg, buf); } case VT_UNKNOWN: /* FIXME: UNKNOWN is unknown ..., but allocate 4 byte for it */ if (alloc) - *arg=(DWORD_PTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(DWORD_PTR)); + *arg=(DWORD)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(DWORD)); hres = S_OK; if (readit) hres = _unmarshal_interface(buf,&IID_IUnknown,(LPUNKNOWN*)arg); @@ -1264,34 +1197,6 @@ deserialize_param( if (readit) hres = _unmarshal_interface(buf,&(tattr->guid),(LPUNKNOWN*)arg); break; - case TKIND_COCLASS: { - GUID iid = tattr->guid; - unsigned int i; - int type_flags; - - for(i = 0; i < tattr->cImplTypes; i++) { - if(SUCCEEDED(ITypeInfo_GetImplTypeFlags(tinfo2, i, &type_flags)) && - type_flags == (IMPLTYPEFLAG_FSOURCE|IMPLTYPEFLAG_FDEFAULT)) { - ITypeInfo *tinfo3; - TYPEATTR *tattr2; - HREFTYPE href; - if(FAILED(ITypeInfo_GetRefTypeOfImplType(tinfo2, i, &href))) - break; - if(FAILED(ITypeInfo_GetRefTypeInfo(tinfo2, href, &tinfo3))) - break; - if(SUCCEEDED(ITypeInfo_GetTypeAttr(tinfo3, &tattr2))) { - iid = tattr2->guid; - ITypeInfo_ReleaseTypeAttr(tinfo3, tattr2); - } - ITypeInfo_Release(tinfo3); - break; - } - } - - if(readit) - hres = _unmarshal_interface(buf, &iid, (LPUNKNOWN*)arg); - break; - } case TKIND_RECORD: { int i; @@ -1312,7 +1217,7 @@ deserialize_param( debugout, alloc, &vdesc->elemdescVar.tdesc, - (DWORD_PTR *)(((LPBYTE)arg)+vdesc->u.oInst), + (DWORD*)(((LPBYTE)arg)+vdesc->u.oInst), buf ); ITypeInfo_ReleaseVarDesc(tinfo2, vdesc); @@ -1329,7 +1234,7 @@ deserialize_param( hres = xbuf_get(buf,(LPBYTE)arg,sizeof(DWORD)); if (hres) ERR("Failed to read enum (4 byte)\n"); } - if (debugout) TRACE_(olerelay)("%x", *(DWORD *)arg); + if (debugout) TRACE_(olerelay)("%x",*arg); break; default: ERR("Unhandled typekind %d\n",tattr->typekind); @@ -1355,7 +1260,7 @@ deserialize_param( if (_passbyref(&adesc->tdescElem, tinfo)) { base = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,_xsize(tdesc->u.lptdesc, tinfo) * arrsize); - *arg = (DWORD_PTR)base; + *arg = (DWORD) base; } for (i=0;i<arrsize;i++) deserialize_param( @@ -1364,7 +1269,7 @@ deserialize_param( debugout, alloc, &adesc->tdescElem, - (DWORD_PTR *)(base + i*_xsize(&adesc->tdescElem, tinfo)), + (DWORD*)(base + i*_xsize(&adesc->tdescElem, tinfo)), buf ); return S_OK; @@ -1494,7 +1399,7 @@ static inline BOOL is_out_elem(const ELEMDESC *elem) static DWORD WINAPI xCall(int method, void **args) { TMProxyImpl *tpinfo = args[0]; - DWORD_PTR *xargs; + DWORD *xargs; const FUNCDESC *fdesc; HRESULT hres; int i; @@ -1554,7 +1459,7 @@ static DWORD WINAPI xCall(int method, void **args) if (nrofnames > sizeof(names)/sizeof(names[0])) ERR("Need more names!\n"); - xargs = (DWORD_PTR *)(args + 1); + xargs = (DWORD *)(args + 1); for (i=0;i<fdesc->cParams;i++) { ELEMDESC *elem = fdesc->lprgelemdescParam+i; if (TRACE_ON(olerelay)) { @@ -1621,7 +1526,7 @@ static DWORD WINAPI xCall(int method, void **args) buf.curoff = 0; /* generic deserializer using typelib description */ - xargs = (DWORD_PTR *)(args + 1); + xargs = (DWORD *)(args + 1); status = S_OK; for (i=0;i<fdesc->cParams;i++) { ELEMDESC *elem = fdesc->lprgelemdescParam+i; @@ -1917,34 +1822,6 @@ static HRESULT init_proxy_entry_point(TMProxyImpl *proxy, unsigned int num) xasm->bytestopop = nrofargs * 4; xasm->nop = 0x9090; proxy->lpvtbl[fdesc->oVft / sizeof(void *)] = xasm; - -#elif defined(__x86_64__) - - xasm->pushq_rbp = 0x55; /* pushq %rbp */ - xasm->movq_rsp_rbp[0] = 0x48; /* movq %rsp,%rbp */ - xasm->movq_rsp_rbp[1] = 0x89; - xasm->movq_rsp_rbp[2] = 0xe5; - xasm->subq_0x20_rsp = 0x20ec8348; /* subq 0x20,%rsp */ - xasm->movq_rcx_0x10rbp = 0x104d8948; /* movq %rcx,0x10(%rbp) */ - xasm->movq_rdx_0x18rbp = 0x18558948; /* movq %rdx,0x18(%rbp) */ - xasm->movq_r8_0x20rbp = 0x2045894c; /* movq %r8,0x20(%rbp) */ - xasm->movq_r9_0x28rbp = 0x284d894c; /* movq %r9,0x28(%rbp) */ - xasm->movq_rcx[0] = 0x48; /* movq <num>,%rcx */ - xasm->movq_rcx[1] = 0xc7; - xasm->movq_rcx[2] = 0xc1; - xasm->nr = num; - xasm->leaq_0x10rbp_rdx = 0x10558d48; /* leaq 0x10(%rbp),%rdx */ - xasm->movq_rax = 0xb848; /* movq <xCall>,%rax */ - xasm->xcall = xCall; - xasm->callq_rax = 0xd0ff; /* callq *%rax */ - xasm->movq_rbp_rsp[0] = 0x48; /* movq %rbp,%rsp */ - xasm->movq_rbp_rsp[1] = 0x89; - xasm->movq_rbp_rsp[2] = 0xec; - xasm->popq_rbp = 0x5d; /* popq %rbp */ - xasm->ret = 0xc3; /* ret */ - xasm->nop = 0x90909090; /* nop */ - proxy->lpvtbl[fdesc->oVft / sizeof(void *)] = xasm; - #else FIXME("not implemented on non i386\n"); return E_FAIL; @@ -2171,13 +2048,12 @@ static HRESULT WINAPI TMStubImpl_Invoke( LPRPCSTUBBUFFER iface, RPCOLEMESSAGE* xmsg,IRpcChannelBuffer*rpcchanbuf) { -#if defined(__i386__) || defined(__x86_64__) +#ifdef __i386__ int i; const FUNCDESC *fdesc; TMStubImpl *This = impl_from_IRpcStubBuffer(iface); HRESULT hres; - DWORD_PTR *args = NULL, *xargs; - DWORD res, nrofargs; + DWORD *args = NULL, res, *xargs, nrofargs; marshal_state buf; UINT nrofnames = 0; BSTR names[10]; @@ -2242,7 +2118,7 @@ TMStubImpl_Invoke( nrofargs = 0; for (i=0;i<fdesc->cParams;i++) nrofargs += _argsize(&fdesc->lprgelemdescParam[i].tdesc, tinfo); - args = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (nrofargs+1)*sizeof(DWORD_PTR)); + args = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(nrofargs+1)*sizeof(DWORD)); if (!args) { hres = E_OUTOFMEMORY; @@ -2270,12 +2146,12 @@ TMStubImpl_Invoke( } } - args[0] = (DWORD_PTR)This->pUnk; + args[0] = (DWORD)This->pUnk; __TRY { res = _invoke( - (*((FARPROC**)args[0]))[fdesc->oVft / sizeof(DWORD_PTR)], + (*((FARPROC**)args[0]))[fdesc->oVft/4], fdesc->callconv, (xargs-args), args diff --git a/dll/win32/oleaut32/typelib.c b/dll/win32/oleaut32/typelib.c index 4f2fa47924..0d2376ce49 100644 --- a/dll/win32/oleaut32/typelib.c +++ b/dll/win32/oleaut32/typelib.c @@ -403,21 +403,11 @@ HRESULT WINAPI QueryPathOfRegTypeLib( REFGUID guid, WORD wMaj, WORD wMin, LCID l * Success: S_OK * Failure: Status */ -HRESULT WINAPI CreateTypeLib(SYSKIND syskind, LPCOLESTR file, ICreateTypeLib **ctlib) -{ - ICreateTypeLib2 *typelib2; - HRESULT hres; - - FIXME("(%d, %s, %p): forwarding to CreateTypeLib2\n", syskind, debugstr_w(file), ctlib); - - hres = CreateTypeLib2(syskind, file, &typelib2); - if(SUCCEEDED(hres)) - { - hres = ICreateTypeLib2_QueryInterface(typelib2, &IID_ICreateTypeLib, (void **)&ctlib); - ICreateTypeLib2_Release(typelib2); - } - - return hres; +HRESULT WINAPI CreateTypeLib( + SYSKIND syskind, LPCOLESTR szFile, ICreateTypeLib** ppctlib +) { + FIXME("(%d,%s,%p), stub!\n",syskind,debugstr_w(szFile),ppctlib); + return E_FAIL; } /****************************************************************************** @@ -3501,10 +3491,6 @@ static ITypeLib2* ITypeLib2_Constructor_MSFT(LPVOID pLib, DWORD dwTLBLength) /* name, eventually add to a hash table */ pTypeLibImpl->Name = MSFT_ReadName(&cx, tlbHeader.NameOffset); - TRACE("%s, syskind %d, version %d.%d, flags %04x\n", - debugstr_w(pTypeLibImpl->Name->str), pTypeLibImpl->syskind, - pTypeLibImpl->ver_major, pTypeLibImpl->ver_minor, pTypeLibImpl->libflags); - /* help info */ pTypeLibImpl->DocString = MSFT_ReadString(&cx, tlbHeader.helpstring); pTypeLibImpl->HelpFile = MSFT_ReadString(&cx, tlbHeader.helpfile); @@ -3675,87 +3661,6 @@ static BOOL TLB_GUIDFromString(const char *str, GUID *guid) return TRUE; } -struct bitstream -{ - const BYTE *buffer; - DWORD length; - WORD current; -}; - -static const char *lookup_code(const BYTE *table, DWORD table_size, struct bitstream *bits) -{ - const BYTE *p = table; - - while (p < table + table_size && *p == 0x80) - { - if (p + 2 >= table + table_size) return NULL; - - if (!(bits->current & 0xff)) - { - if (!bits->length) return NULL; - bits->current = (*bits->buffer << 8) | 1; - bits->buffer++; - bits->length--; - } - - if (bits->current & 0x8000) - { - p += 3; - } - else - { - p = table + (*(p + 2) | (*(p + 1) << 8)); - } - - bits->current <<= 1; - } - - if (p + 1 < table + table_size && *(p + 1)) - { - /* FIXME: Whats the meaning of *p? */ - const BYTE *q = p + 1; - while (q < table + table_size && *q) q++; - return (q < table + table_size) ? (const char *)(p + 1) : NULL; - } - - return NULL; -} - -static const TLBString *decode_string(const BYTE *table, const char *stream, DWORD stream_length, ITypeLibImpl *lib) -{ - DWORD buf_size, table_size; - const char *p; - struct bitstream bits; - BSTR buf; - TLBString *tlbstr; - - if (!stream_length) return NULL; - - bits.buffer = (const BYTE *)stream; - bits.length = stream_length; - bits.current = 0; - - buf_size = *(const WORD *)table; - table += sizeof(WORD); - table_size = *(const DWORD *)table; - table += sizeof(DWORD); - - buf = SysAllocStringLen(NULL, buf_size); - buf[0] = 0; - - while ((p = lookup_code(table, table_size, &bits))) - { - static const WCHAR spaceW[] = { ' ',0 }; - if (buf[0]) strcatW(buf, spaceW); - MultiByteToWideChar(CP_ACP, 0, p, -1, buf + strlenW(buf), buf_size - strlenW(buf)); - } - - tlbstr = TLB_append_str(&lib->string_list, buf); - SysFreeString(buf); - - return tlbstr; -} - static WORD SLTG_ReadString(const char *ptr, const TLBString **pStr, ITypeLibImpl *lib) { WORD bytelen; @@ -4087,7 +3992,7 @@ static char *SLTG_DoImpls(char *pBlk, ITypeInfoImpl *pTI, } static void SLTG_DoVars(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, unsigned short cVars, - const char *pNameTable, const sltg_ref_lookup_t *ref_lookup, const BYTE *hlp_strings) + const char *pNameTable, const sltg_ref_lookup_t *ref_lookup) { TLBVarDesc *pVarDesc; const TLBString *prevName = NULL; @@ -4117,12 +4022,6 @@ static void SLTG_DoVars(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, unsign TRACE_(typelib)("byte_offs = 0x%x\n", pItem->byte_offs); TRACE_(typelib)("memid = 0x%x\n", pItem->memid); - if (pItem->helpstring != 0xffff) - { - pVarDesc->HelpString = decode_string(hlp_strings, pBlk + pItem->helpstring, pNameTable - pBlk, pTI->pTypeLib); - TRACE_(typelib)("helpstring = %s\n", debugstr_w(pVarDesc->HelpString->str)); - } - if(pItem->flags & 0x02) pType = &pItem->type; else @@ -4204,8 +4103,7 @@ static void SLTG_DoVars(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, unsign } static void SLTG_DoFuncs(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, - unsigned short cFuncs, char *pNameTable, const sltg_ref_lookup_t *ref_lookup, - const BYTE *hlp_strings) + unsigned short cFuncs, char *pNameTable, const sltg_ref_lookup_t *ref_lookup) { SLTG_Function *pFunc; unsigned short i; @@ -4242,8 +4140,6 @@ static void SLTG_DoFuncs(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, pFuncDesc->funcdesc.cParams = pFunc->nacc >> 3; pFuncDesc->funcdesc.cParamsOpt = (pFunc->retnextopt & 0x7e) >> 1; pFuncDesc->funcdesc.oVft = pFunc->vtblpos & ~1; - if (pFunc->helpstring != 0xffff) - pFuncDesc->HelpString = decode_string(hlp_strings, pBlk + pFunc->helpstring, pNameTable - pBlk, pTI->pTypeLib); if(pFunc->magic & SLTG_FUNCTION_FLAGS_PRESENT) pFuncDesc->funcdesc.wFuncFlags = pFunc->funcflags; @@ -4262,7 +4158,7 @@ static void SLTG_DoFuncs(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, pArg = (WORD*)(pBlk + pFunc->arg_off); for(param = 0; param < pFuncDesc->funcdesc.cParams; param++) { - char *paramName = pNameTable + (*pArg & ~1); + char *paramName = pNameTable + *pArg; BOOL HaveOffs; /* If arg type follows then paramName points to the 2nd letter of the name, else the next WORD is an offset to @@ -4273,21 +4169,26 @@ static void SLTG_DoFuncs(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, meaning that the next WORD is the type, the latter meaning that the next WORD is an offset to the type. */ - if(*pArg == 0xffff || *pArg == 0xfffe) + HaveOffs = FALSE; + if(*pArg == 0xffff) + paramName = NULL; + else if(*pArg == 0xfffe) { paramName = NULL; + HaveOffs = TRUE; + } + else if(paramName[-1] && !isalnum(paramName[-1])) + HaveOffs = TRUE; - HaveOffs = !(*pArg & 1); pArg++; - TRACE_(typelib)("param %d: paramName %s, *pArg %#x\n", - param, debugstr_a(paramName), *pArg); - if(HaveOffs) { /* the next word is an offset to type */ pType = (WORD*)(pBlk + *pArg); SLTG_DoElem(pType, pBlk, &pFuncDesc->funcdesc.lprgelemdescParam[param], ref_lookup); pArg++; } else { + if(paramName) + paramName--; pArg = SLTG_DoElem(pArg, pBlk, &pFuncDesc->funcdesc.lprgelemdescParam[param], ref_lookup); } @@ -4331,7 +4232,7 @@ static void SLTG_ProcessCoClass(char *pBlk, ITypeInfoImpl *pTI, static void SLTG_ProcessInterface(char *pBlk, ITypeInfoImpl *pTI, char *pNameTable, SLTG_TypeInfoHeader *pTIHeader, - const SLTG_TypeInfoTail *pTITail, const BYTE *hlp_strings) + const SLTG_TypeInfoTail *pTITail) { char *pFirstItem; sltg_ref_lookup_t *ref_lookup = NULL; @@ -4348,7 +4249,7 @@ static void SLTG_ProcessInterface(char *pBlk, ITypeInfoImpl *pTI, } if (pTITail->funcs_off != 0xffff) - SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable, ref_lookup, hlp_strings); + SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable, ref_lookup); heap_free(ref_lookup); @@ -4358,9 +4259,9 @@ static void SLTG_ProcessInterface(char *pBlk, ITypeInfoImpl *pTI, static void SLTG_ProcessRecord(char *pBlk, ITypeInfoImpl *pTI, const char *pNameTable, SLTG_TypeInfoHeader *pTIHeader, - const SLTG_TypeInfoTail *pTITail, const BYTE *hlp_strings) + const SLTG_TypeInfoTail *pTITail) { - SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, NULL, hlp_strings); + SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, NULL); } static void SLTG_ProcessAlias(char *pBlk, ITypeInfoImpl *pTI, @@ -4393,7 +4294,7 @@ static void SLTG_ProcessAlias(char *pBlk, ITypeInfoImpl *pTI, static void SLTG_ProcessDispatch(char *pBlk, ITypeInfoImpl *pTI, char *pNameTable, SLTG_TypeInfoHeader *pTIHeader, - const SLTG_TypeInfoTail *pTITail, const BYTE *hlp_strings) + const SLTG_TypeInfoTail *pTITail) { sltg_ref_lookup_t *ref_lookup = NULL; if (pTIHeader->href_table != 0xffffffff) @@ -4401,10 +4302,10 @@ static void SLTG_ProcessDispatch(char *pBlk, ITypeInfoImpl *pTI, pNameTable); if (pTITail->vars_off != 0xffff) - SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, ref_lookup, hlp_strings); + SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, ref_lookup); if (pTITail->funcs_off != 0xffff) - SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable, ref_lookup, hlp_strings); + SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable, ref_lookup); if (pTITail->impls_off != 0xffff) SLTG_DoImpls(pBlk + pTITail->impls_off, pTI, FALSE, ref_lookup); @@ -4421,14 +4322,14 @@ static void SLTG_ProcessDispatch(char *pBlk, ITypeInfoImpl *pTI, static void SLTG_ProcessEnum(char *pBlk, ITypeInfoImpl *pTI, const char *pNameTable, SLTG_TypeInfoHeader *pTIHeader, - const SLTG_TypeInfoTail *pTITail, const BYTE *hlp_strings) + const SLTG_TypeInfoTail *pTITail) { - SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, NULL, hlp_strings); + SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, NULL); } static void SLTG_ProcessModule(char *pBlk, ITypeInfoImpl *pTI, char *pNameTable, SLTG_TypeInfoHeader *pTIHeader, - const SLTG_TypeInfoTail *pTITail, const BYTE *hlp_strings) + const SLTG_TypeInfoTail *pTITail) { sltg_ref_lookup_t *ref_lookup = NULL; if (pTIHeader->href_table != 0xffffffff) @@ -4436,10 +4337,10 @@ static void SLTG_ProcessModule(char *pBlk, ITypeInfoImpl *pTI, pNameTable); if (pTITail->vars_off != 0xffff) - SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, ref_lookup, hlp_strings); + SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, ref_lookup); if (pTITail->funcs_off != 0xffff) - SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable, ref_lookup, hlp_strings); + SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable, ref_lookup); heap_free(ref_lookup); if (TRACE_ON(typelib)) dump_TypeInfo(pTI); @@ -4448,17 +4349,17 @@ static void SLTG_ProcessModule(char *pBlk, ITypeInfoImpl *pTI, /* Because SLTG_OtherTypeInfo is such a painful struct, we make a more manageable copy of it into this */ typedef struct { + WORD small_no; char *index_name; char *other_name; WORD res1a; WORD name_offs; - WORD hlpstr_len; + WORD more_bytes; char *extra; WORD res20; DWORD helpcontext; WORD res26; GUID uuid; - WORD typekind; } SLTG_InternalOtherTypeInfo; /**************************************************************************** @@ -4477,8 +4378,8 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength) LPVOID pBlk, pFirstBlk; SLTG_LibBlk *pLibBlk; SLTG_InternalOtherTypeInfo *pOtherTypeInfoBlks; + char *pAfterOTIBlks = NULL; char *pNameTable, *ptr; - const BYTE *hlp_strings; int i; DWORD len, order; ITypeInfoImpl **ppTypeInfoImpl; @@ -4544,55 +4445,53 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength) len += 0x40; /* And now TypeInfoCount of SLTG_OtherTypeInfo */ - pTypeLibImpl->TypeInfoCount = *(WORD *)((char *)pLibBlk + len); - len += sizeof(WORD); pOtherTypeInfoBlks = heap_alloc_zero(sizeof(*pOtherTypeInfoBlks) * pTypeLibImpl->TypeInfoCount); + ptr = (char*)pLibBlk + len; for(i = 0; i < pTypeLibImpl->TypeInfoCount; i++) { WORD w, extra; len = 0; - w = *(WORD*)ptr; + pOtherTypeInfoBlks[i].small_no = *(WORD*)ptr; + + w = *(WORD*)(ptr + 2); if(w != 0xffff) { len += w; pOtherTypeInfoBlks[i].index_name = heap_alloc(w+1); - memcpy(pOtherTypeInfoBlks[i].index_name, ptr + 2, w); + memcpy(pOtherTypeInfoBlks[i].index_name, ptr + 4, w); pOtherTypeInfoBlks[i].index_name[w] = '\0'; } - w = *(WORD*)(ptr + 2 + len); + w = *(WORD*)(ptr + 4 + len); if(w != 0xffff) { - TRACE_(typelib)("\twith %s\n", debugstr_an(ptr + 4 + len, w)); + TRACE_(typelib)("\twith %s\n", debugstr_an(ptr + 6 + len, w)); + len += w; pOtherTypeInfoBlks[i].other_name = heap_alloc(w+1); - memcpy(pOtherTypeInfoBlks[i].other_name, ptr + 4 + len, w); + memcpy(pOtherTypeInfoBlks[i].other_name, ptr + 6 + len, w); pOtherTypeInfoBlks[i].other_name[w] = '\0'; - len += w; } - pOtherTypeInfoBlks[i].res1a = *(WORD*)(ptr + 4 + len); - pOtherTypeInfoBlks[i].name_offs = *(WORD*)(ptr + 6 + len); - extra = pOtherTypeInfoBlks[i].hlpstr_len = *(WORD*)(ptr + 8 + len); + pOtherTypeInfoBlks[i].res1a = *(WORD*)(ptr + len + 6); + pOtherTypeInfoBlks[i].name_offs = *(WORD*)(ptr + len + 8); + extra = pOtherTypeInfoBlks[i].more_bytes = *(WORD*)(ptr + 10 + len); if(extra) { pOtherTypeInfoBlks[i].extra = heap_alloc(extra); - memcpy(pOtherTypeInfoBlks[i].extra, ptr + 10 + len, extra); + memcpy(pOtherTypeInfoBlks[i].extra, ptr + 12, extra); len += extra; } - pOtherTypeInfoBlks[i].res20 = *(WORD*)(ptr + 10 + len); - pOtherTypeInfoBlks[i].helpcontext = *(DWORD*)(ptr + 12 + len); - pOtherTypeInfoBlks[i].res26 = *(WORD*)(ptr + 16 + len); - memcpy(&pOtherTypeInfoBlks[i].uuid, ptr + 18 + len, sizeof(GUID)); - pOtherTypeInfoBlks[i].typekind = *(WORD*)(ptr + 18 + sizeof(GUID) + len); + pOtherTypeInfoBlks[i].res20 = *(WORD*)(ptr + 12 + len); + pOtherTypeInfoBlks[i].helpcontext = *(DWORD*)(ptr + 14 + len); + pOtherTypeInfoBlks[i].res26 = *(WORD*)(ptr + 18 + len); + memcpy(&pOtherTypeInfoBlks[i].uuid, ptr + 20 + len, sizeof(GUID)); len += sizeof(SLTG_OtherTypeInfo); ptr += len; } - /* Get the next DWORD */ - len = *(DWORD*)ptr; + pAfterOTIBlks = ptr; - hlp_strings = (const BYTE *)ptr + sizeof(DWORD); - TRACE("max help string length %#x, help strings length %#x\n", - *(WORD *)hlp_strings, *(DWORD *)(hlp_strings + 2)); + /* Skip this WORD and get the next DWORD */ + len = *(DWORD*)(pAfterOTIBlks + 2); /* Now add this to pLibBLk look at what we're pointing at and possibly add 0x20, then add 0x216, sprinkle a bit a magic @@ -4658,7 +4557,6 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength) (*ppTypeInfoImpl)->index = i; (*ppTypeInfoImpl)->Name = SLTG_ReadName(pNameTable, pOtherTypeInfoBlks[i].name_offs, pTypeLibImpl); (*ppTypeInfoImpl)->dwHelpContext = pOtherTypeInfoBlks[i].helpcontext; - (*ppTypeInfoImpl)->DocString = decode_string(hlp_strings, pOtherTypeInfoBlks[i].extra, pOtherTypeInfoBlks[i].hlpstr_len, pTypeLibImpl); (*ppTypeInfoImpl)->guid = TLB_append_guid(&pTypeLibImpl->guid_list, &pOtherTypeInfoBlks[i].uuid, 2); (*ppTypeInfoImpl)->typeattr.typekind = pTIHeader->typekind; (*ppTypeInfoImpl)->typeattr.wMajorVerNum = pTIHeader->major_version; @@ -4691,17 +4589,17 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength) switch(pTIHeader->typekind) { case TKIND_ENUM: SLTG_ProcessEnum((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable, - pTIHeader, pTITail, hlp_strings); + pTIHeader, pTITail); break; case TKIND_RECORD: SLTG_ProcessRecord((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable, - pTIHeader, pTITail, hlp_strings); + pTIHeader, pTITail); break; case TKIND_INTERFACE: SLTG_ProcessInterface((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable, - pTIHeader, pTITail, hlp_strings); + pTIHeader, pTITail); break; case TKIND_COCLASS: @@ -4716,12 +4614,12 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength) case TKIND_DISPATCH: SLTG_ProcessDispatch((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable, - pTIHeader, pTITail, hlp_strings); + pTIHeader, pTITail); break; case TKIND_MODULE: SLTG_ProcessModule((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable, - pTIHeader, pTITail, hlp_strings); + pTIHeader, pTITail); break; default: @@ -6430,15 +6328,15 @@ static double (* const call_double_method)(void*,int,const DWORD*,int*) = (void * Invokes a method, or accesses a property of an object, that implements the * interface described by the type description. */ -DWORD _invoke(FARPROC func, CALLCONV callconv, int nrargs, DWORD_PTR *args) -{ +DWORD +_invoke(FARPROC func,CALLCONV callconv, int nrargs, DWORD *args) { DWORD res; int stack_offset; if (TRACE_ON(ole)) { int i; TRACE("Calling %p(",func); - for (i=0;i<min(nrargs,30);i++) TRACE("%08lx,",args[i]); + for (i=0;i<min(nrargs,30);i++) TRACE("%08x,",args[i]); if (nrargs > 30) TRACE("..."); TRACE(")\n"); } @@ -6446,7 +6344,7 @@ DWORD _invoke(FARPROC func, CALLCONV callconv, int nrargs, DWORD_PTR *args) switch (callconv) { case CC_STDCALL: case CC_CDECL: - res = call_method(func, nrargs, (DWORD *)args, &stack_offset); + res = call_method( func, nrargs, args, &stack_offset ); break; default: FIXME("unsupported calling convention %d\n",callconv); @@ -6503,33 +6401,43 @@ __ASM_GLOBAL_FUNC( call_method, /* same function but returning floating point */ static double (CDECL * const call_double_method)(void*,int,const DWORD_PTR*) = (void *)call_method; -DWORD _invoke(FARPROC func, CALLCONV callconv, int nrargs, DWORD_PTR *args) -{ - DWORD res; +#elif defined(__arm__) - if (TRACE_ON(ole)) - { - int i; - TRACE("Calling %p(", func); - for (i=0; i<min(nrargs, 30); i++) TRACE("%016lx,", args[i]); - if (nrargs > 30) TRACE("..."); - TRACE(")\n"); - } +extern LONGLONG CDECL call_method( void *func, int nb_stk_args, const DWORD *stk_args, const DWORD *reg_args ); +__ASM_GLOBAL_FUNC( call_method, + /* r0 = *func + * r1 = nb_stk_args + * r2 = *stk_args (pointer to 'nb_stk_args' DWORD values to push on stack) + * r3 = *reg_args (pointer to 8, 64-bit d0-d7 (double) values OR as 16, 32-bit s0-s15 (float) values, followed by 4, 32-bit (DWORD) r0-r3 values) + */ + + "push {fp, lr}\n\t" /* Save frame pointer and return address (stack still aligned to 8 bytes) */ + "mov fp, sp\n\t" /* Save stack pointer as our frame for cleaning the stack on return */ + + "lsls r1, r1, #2\n\t" /* r1 = nb_stk_args * sizeof(DWORD) */ + "beq 1f\n\t" /* Skip allocation if no stack args */ + "add r2, r2, r1\n" /* Calculate ending address of incoming stack data */ + "2:\tldr ip, [r2, #-4]!\n\t" /* Get next value */ + "str ip, [sp, #-4]!\n\t" /* Push it on the stack */ + "subs r1, r1, #4\n\t" /* Decrement count */ + "bgt 2b\n\t" /* Loop till done */ + + "1:\n\t" +#ifndef __SOFTFP__ + "vldm r3!, {s0-s15}\n\t" /* Load the s0-s15/d0-d7 arguments */ +#endif + "mov ip, r0\n\t" /* Save the function call address to ip before we nuke r0 with arguments to pass */ + "ldm r3, {r0-r3}\n\t" /* Load the r0-r3 arguments */ - switch (callconv) { - case CC_STDCALL: - case CC_CDECL: - res = call_method(func, nrargs, args); - break; - default: - FIXME("unsupported calling convention %d\n", callconv); - res = -1; - break; - } + "blx ip\n\t" /* Call the target function */ - TRACE("returns %08x\n", res); - return res; -} + "mov sp, fp\n\t" /* Clean the stack using fp */ + "pop {fp, pc}\n\t" /* Restore fp and return */ + ) + +/* same function but returning single/double floating point */ +static float (CDECL * const call_float_method)(void *, int, const DWORD *, const DWORD *) = (void *)call_method; +static double (CDECL * const call_double_method)(void *, int, const DWORD *, const DWORD *) = (void *)call_method; #endif /* __x86_64__ */ @@ -6562,7 +6470,6 @@ static HRESULT userdefined_to_variantvt(ITypeInfo *tinfo, const TYPEDESC *tdesc, break; case TKIND_ALIAS: - tdesc = &tattr->tdescAlias; hr = typedescvt_to_variantvt(tinfo2, &tattr->tdescAlias, vt); break; @@ -6668,13 +6575,13 @@ static HRESULT typedescvt_to_variantvt(ITypeInfo *tinfo, const TYPEDESC *tdesc, return hr; } -static HRESULT get_iface_guid(ITypeInfo *tinfo, HREFTYPE href, GUID *guid) +static HRESULT get_iface_guid(ITypeInfo *tinfo, const TYPEDESC *tdesc, GUID *guid) { ITypeInfo *tinfo2; TYPEATTR *tattr; HRESULT hres; - hres = ITypeInfo_GetRefTypeInfo(tinfo, href, &tinfo2); + hres = ITypeInfo_GetRefTypeInfo(tinfo, tdesc->u.hreftype, &tinfo2); if(FAILED(hres)) return hres; @@ -6686,7 +6593,7 @@ static HRESULT get_iface_guid(ITypeInfo *tinfo, HREFTYPE href, GUID *guid) switch(tattr->typekind) { case TKIND_ALIAS: - hres = get_iface_guid(tinfo2, tattr->tdescAlias.u.hreftype, guid); + hres = get_iface_guid(tinfo2, &tattr->tdescAlias, guid); break; case TKIND_INTERFACE: @@ -6694,21 +6601,6 @@ static HRESULT get_iface_guid(ITypeInfo *tinfo, HREFTYPE href, GUID *guid) *guid = tattr->guid; break; - case TKIND_COCLASS: { - unsigned int i; - int type_flags; - - for(i = 0; i < tattr->cImplTypes; i++) - if(SUCCEEDED(ITypeInfo_GetImplTypeFlags(tinfo2, i, &type_flags)) && - type_flags == (IMPLTYPEFLAG_FSOURCE|IMPLTYPEFLAG_FDEFAULT)) break; - - if(i < tattr->cImplTypes) { - hres = ITypeInfo_GetRefTypeOfImplType(tinfo2, i, &href); - if(SUCCEEDED(hres)) hres = get_iface_guid(tinfo2, href, guid); - } else hres = E_UNEXPECTED; - break; - } - default: ERR("Unexpected typekind %d\n", tattr->typekind); hres = E_UNEXPECTED; @@ -6836,17 +6728,8 @@ DispCallFunc( break; case VT_DECIMAL: case VT_VARIANT: - if (pvInstance) - { - args[0] = (DWORD)pvInstance; /* arg 0 is a pointer to the instance */ - args[1] = (DWORD)pvargResult; /* arg 1 is a pointer to the result */ - call_method( func, argspos, args, &stack_offset ); - } - else - { - args[0] = (DWORD)pvargResult; /* arg 0 is a pointer to the result */ - call_method( func, argspos, args, &stack_offset ); - } + args[0] = (DWORD)pvargResult; /* arg 0 is a pointer to the result */ + call_method( func, argspos, args, &stack_offset ); break; case VT_I8: case VT_UI8: @@ -6931,17 +6814,8 @@ DispCallFunc( break; case VT_DECIMAL: case VT_VARIANT: - if (pvInstance) - { - args[0] = (DWORD_PTR)pvInstance; /* arg 0 is a pointer to the instance */ - args[1] = (DWORD_PTR)pvargResult; /* arg 1 is a pointer to the result */ - call_method( func, argspos, args ); - } - else - { - args[0] = (DWORD_PTR)pvargResult; /* arg 0 is a pointer to the result */ - call_method( func, argspos, args ); - } + args[0] = (DWORD_PTR)pvargResult; /* arg 0 is a pointer to the result */ + call_method( func, argspos, args ); break; case VT_HRESULT: WARN("invalid return type %u\n", vtReturn); @@ -6956,6 +6830,182 @@ DispCallFunc( TRACE("retval: %s\n", debugstr_variant(pvargResult)); return S_OK; +#elif defined(__arm__) + int argspos; + void *func; + UINT i; + DWORD *args; + struct { +#ifndef __SOFTFP__ + union { + float s[16]; + double d[8]; + } sd; +#endif + DWORD r[4]; + } regs; + int rcount; /* 32-bit register index count */ +#ifndef __SOFTFP__ + int scount = 0; /* single-precision float register index count */ + int dcount = 0; /* double-precision float register index count */ +#endif + + TRACE("(%p, %ld, %d, %d, %d, %p, %p, %p (vt=%d))\n", + pvInstance, oVft, cc, vtReturn, cActuals, prgvt, prgpvarg, pvargResult, V_VT(pvargResult)); + + if (cc != CC_STDCALL && cc != CC_CDECL) + { + FIXME("unsupported calling convention %d\n",cc); + return E_INVALIDARG; + } + + argspos = 0; + rcount = 0; + + /* Determine if we need to pass a pointer for the return value as arg 0. If so, do that */ + /* first as it will need to be in the 'r' registers: */ + switch (vtReturn) + { + case VT_DECIMAL: + case VT_VARIANT: + regs.r[rcount++] = (DWORD)pvargResult; /* arg 0 is a pointer to the result */ + break; + case VT_HRESULT: + WARN("invalid return type %u\n", vtReturn); + return E_INVALIDARG; + default: /* And all others are in 'r', 's', or 'd' registers or have no return value */ + break; + } + + if (pvInstance) + { + const FARPROC *vtable = *(FARPROC **)pvInstance; + func = vtable[oVft/sizeof(void *)]; + regs.r[rcount++] = (DWORD)pvInstance; /* the This pointer is always the first parameter */ + } + else func = (void *)oVft; + + /* maximum size for an argument is sizeof(VARIANT). Also allow for return pointer and stack alignment. */ + args = heap_alloc( sizeof(VARIANT) * cActuals + sizeof(DWORD) * 4 ); + + for (i = 0; i < cActuals; i++) + { + VARIANT *arg = prgpvarg[i]; + DWORD *pdwarg = (DWORD *)(arg); /* a reinterpret_cast of the variant, used for copying structures when they are split between registers and stack */ + int ntemp; /* Used for counting words split between registers and stack */ + + switch (prgvt[i]) + { + case VT_EMPTY: + break; + case VT_R8: /* these must be 8-byte aligned, and put in 'd' regs or stack, as they are double-floats */ + case VT_DATE: +#ifndef __SOFTFP__ + dcount = max( (scount + 1) / 2, dcount ); + if (dcount < 8) + { + regs.sd.d[dcount++] = V_R8(arg); + } + else + { + argspos += (argspos % 2); /* align argspos to 8-bytes */ + memcpy( &args[argspos], &V_R8(arg), sizeof(V_R8(arg)) ); + argspos += sizeof(V_R8(arg)) / sizeof(DWORD); + } + break; +#endif + case VT_I8: /* these must be 8-byte aligned, and put in 'r' regs or stack, as they are long-longs */ + case VT_UI8: + case VT_CY: + if (rcount < 3) + { + rcount += (rcount % 2); /* align rcount to 8-byte register pair */ + memcpy( ®s.r[rcount], &V_UI8(arg), sizeof(V_UI8(arg)) ); + rcount += sizeof(V_UI8(arg)) / sizeof(DWORD); + } + else + { + rcount = 4; /* Make sure we flag that all 'r' regs are full */ + argspos += (argspos % 2); /* align argspos to 8-bytes */ + memcpy( &args[argspos], &V_UI8(arg), sizeof(V_UI8(arg)) ); + argspos += sizeof(V_UI8(arg)) / sizeof(DWORD); + } + break; + case VT_DECIMAL: /* these structures are 8-byte aligned, and put in 'r' regs or stack, can be split between the two */ + case VT_VARIANT: + /* 8-byte align 'r' and/or stack: */ + if (rcount < 3) + rcount += (rcount % 2); + else + { + rcount = 4; + argspos += (argspos % 2); + } + ntemp = sizeof(*arg) / sizeof(DWORD); + while (ntemp > 0) + { + if (rcount < 4) + regs.r[rcount++] = *pdwarg++; + else + args[argspos++] = *pdwarg++; + --ntemp; + } + break; + case VT_BOOL: /* VT_BOOL is 16-bit but BOOL is 32-bit, needs to be extended */ + if (rcount < 4) + regs.r[rcount++] = V_BOOL(arg); + else + args[argspos++] = V_BOOL(arg); + break; + case VT_R4: /* these must be 4-byte aligned, and put in 's' regs or stack, as they are single-floats */ +#ifndef __SOFTFP__ + if (!(scount % 2)) scount = max( scount, dcount * 2 ); + if (scount < 16) + regs.sd.s[scount++] = V_R4(arg); + else + args[argspos++] = V_UI4(arg); + break; +#endif + default: + if (rcount < 4) + regs.r[rcount++] = V_UI4(arg); + else + args[argspos++] = V_UI4(arg); + break; + } + TRACE("arg %u: type %s %s\n", i, debugstr_vt(prgvt[i]), debugstr_variant(arg)); + } + + argspos += (argspos % 2); /* Make sure stack function alignment is 8-byte */ + + switch (vtReturn) + { + case VT_EMPTY: /* EMPTY = no return value */ + case VT_DECIMAL: /* DECIMAL and VARIANT already have a pointer argument passed (see above) */ + case VT_VARIANT: + call_method( func, argspos, args, (DWORD*)®s ); + break; + case VT_R4: + V_R4(pvargResult) = call_float_method( func, argspos, args, (DWORD*)®s ); + break; + case VT_R8: + case VT_DATE: + V_R8(pvargResult) = call_double_method( func, argspos, args, (DWORD*)®s ); + break; + case VT_I8: + case VT_UI8: + case VT_CY: + V_UI8(pvargResult) = call_method( func, argspos, args, (DWORD*)®s ); + break; + default: + V_UI4(pvargResult) = call_method( func, argspos, args, (DWORD*)®s ); + break; + } + heap_free( args ); + if (vtReturn != VT_VARIANT) V_VT(pvargResult) = vtReturn; + TRACE("retval: %s\n", debugstr_variant(pvargResult)); + return S_OK; + #else FIXME( "(%p, %ld, %d, %d, %d, %p, %p, %p (vt=%d)): not implemented for this CPU\n", pvInstance, oVft, cc, vtReturn, cActuals, prgvt, prgpvarg, pvargResult, V_VT(pvargResult)); @@ -7049,7 +7099,6 @@ static HRESULT WINAPI ITypeInfo_fnInvoke( UINT cNamedArgs = pDispParams->cNamedArgs; DISPID *rgdispidNamedArgs = pDispParams->rgdispidNamedArgs; UINT vargs_converted=0; - ULONG_PTR offset; hres = S_OK; @@ -7147,8 +7196,7 @@ static HRESULT WINAPI ITypeInfo_fnInvoke( break; } } - else if (src_arg && !((wParamFlags & PARAMFLAG_FOPT) && - V_VT(src_arg) == VT_ERROR && V_ERROR(src_arg) == DISP_E_PARAMNOTFOUND)) + else if (src_arg) { TRACE("%s\n", debugstr_variant(src_arg)); @@ -7247,10 +7295,7 @@ static HRESULT WINAPI ITypeInfo_fnInvoke( IUnknown *userdefined_iface; GUID guid; - if (tdesc->vt == VT_PTR) - tdesc = tdesc->u.lptdesc; - - hres = get_iface_guid((ITypeInfo*)iface, tdesc->u.hreftype, &guid); + hres = get_iface_guid((ITypeInfo*)iface, tdesc->vt == VT_PTR ? tdesc->u.lptdesc : tdesc, &guid); if(FAILED(hres)) break; @@ -7298,11 +7343,7 @@ static HRESULT WINAPI ITypeInfo_fnInvoke( break; } } - if (FAILED(hres)) - { - ERR("failed: %08x\n", hres); - goto func_fail; /* FIXME: we don't free changed types here */ - } + if (FAILED(hres)) goto func_fail; /* FIXME: we don't free changed types here */ /* VT_VOID is a special case for return types, so it is not * handled in the general function */ @@ -7315,16 +7356,7 @@ static HRESULT WINAPI ITypeInfo_fnInvoke( if (FAILED(hres)) goto func_fail; /* FIXME: we don't free changed types here */ } - offset = func_desc->oVft & 0xFFFC; -#ifdef _WIN64 - if (This->pTypeLib->syskind == SYS_WIN32) - { - offset *= 2; - TRACE("extended offset to %#lx for SYS_WIN32\n", offset); - } -#endif - TRACE("func_desc->oVft %#x, offset %#lx\n", func_desc->oVft, offset); - hres = DispCallFunc(pIUnk, offset, func_desc->callconv, + hres = DispCallFunc(pIUnk, func_desc->oVft & 0xFFFC, func_desc->callconv, V_VT(&varresult), func_desc->cParams, rgvt, prgpvarg, &varresult); @@ -7451,7 +7483,7 @@ static HRESULT WINAPI ITypeInfo_fnInvoke( * pointer to be valid */ VariantInit(pVarResult); hres = IDispatch_Invoke(pDispatch, DISPID_VALUE, &IID_NULL, - GetSystemDefaultLCID(), INVOKE_PROPERTYGET, + GetSystemDefaultLCID(), wFlags, pDispParams, pVarResult, pExcepInfo, pArgErr); IDispatch_Release(pDispatch); } diff --git a/dll/win32/oleaut32/typelib.h b/dll/win32/oleaut32/typelib.h index 100e15a145..37561807f8 100644 --- a/dll/win32/oleaut32/typelib.h +++ b/dll/win32/oleaut32/typelib.h @@ -381,18 +381,18 @@ typedef struct { /* we then get 0x40 bytes worth of 0xffff or small numbers followed by nrOfFileBlks - 2 of these */ typedef struct { + WORD small_no; SLTG_Name index_name; /* This refers to a name in the directory */ SLTG_Name other_name; /* Another one of these weird names */ WORD res1a; /* 0xffff */ WORD name_offs; /* offset to name in name table */ - WORD hlpstr_len; /* if this is non-zero we get this many + WORD more_bytes; /* if this is non-zero we get this many bytes before the next element, which seem to reference the docstring of the type ? */ WORD res20; /* 0xffff */ DWORD helpcontext; WORD res26; /* 0xffff */ GUID uuid; - WORD typekind; } SLTG_OtherTypeInfo; /* Next we get WORD 0x0003 followed by a DWORD which if we add to @@ -612,7 +612,7 @@ static inline BOOL heap_free( LPVOID mem ) HRESULT ITypeInfoImpl_GetInternalFuncDesc( ITypeInfo *iface, UINT index, const FUNCDESC **ppFuncDesc ) DECLSPEC_HIDDEN; -extern DWORD _invoke(FARPROC func, CALLCONV callconv, int nrargs, DWORD_PTR *args) DECLSPEC_HIDDEN; +extern DWORD _invoke(FARPROC func,CALLCONV callconv, int nrargs, DWORD *args) DECLSPEC_HIDDEN; HRESULT TMARSHAL_DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID *ppv) DECLSPEC_HIDDEN; diff --git a/dll/win32/oleaut32/variant.c b/dll/win32/oleaut32/variant.c index 05818bcfd6..3d0840e801 100644 --- a/dll/win32/oleaut32/variant.c +++ b/dll/win32/oleaut32/variant.c @@ -2145,7 +2145,7 @@ HRESULT WINAPI VarNumFromParseNum(NUMPARSE *pNumprs, BYTE *rgbDig, multiplier10, divisor10); if (dwVtBits & (INTEGER_VTBITS|VTBIT_DECIMAL) && - (!fractionalDigits || !(dwVtBits & (REAL_VTBITS|VTBIT_CY|VTBIT_DECIMAL)))) + (!fractionalDigits || !(dwVtBits & (REAL_VTBITS|VTBIT_DECIMAL)))) { /* We have one or more integer output choices, and either: * 1) An integer input value, or @@ -2259,7 +2259,7 @@ HRESULT WINAPI VarNumFromParseNum(NUMPARSE *pNumprs, BYTE *rgbDig, V_I8(pVarDst) = -ul64; return S_OK; } - else if ((dwVtBits & REAL_VTBITS) == VTBIT_DECIMAL) + else if ((dwVtBits & (REAL_VTBITS|VTBIT_DECIMAL)) == VTBIT_DECIMAL) { /* Decimal is only output choice left - fast path */ V_VT(pVarDst) = VT_DECIMAL; @@ -2321,7 +2321,7 @@ HRESULT WINAPI VarNumFromParseNum(NUMPARSE *pNumprs, BYTE *rgbDig, V_UI8(pVarDst) = ul64; return S_OK; } - else if ((dwVtBits & REAL_VTBITS) == VTBIT_DECIMAL) + else if ((dwVtBits & (REAL_VTBITS|VTBIT_DECIMAL)) == VTBIT_DECIMAL) { /* Decimal is only output choice left - fast path */ V_VT(pVarDst) = VT_DECIMAL; @@ -2376,8 +2376,8 @@ HRESULT WINAPI VarNumFromParseNum(NUMPARSE *pNumprs, BYTE *rgbDig, { if (whole < dblMinimums[10] && whole != 0) { - dwVtBits &= ~(VTBIT_R4|VTBIT_R8|VTBIT_CY); /* Underflow */ - bOverflow = TRUE; + whole = 0; /* ignore underflow */ + divisor10 = 0; break; } whole = whole / dblMultipliers[10]; @@ -2387,8 +2387,8 @@ HRESULT WINAPI VarNumFromParseNum(NUMPARSE *pNumprs, BYTE *rgbDig, { if (whole < dblMinimums[divisor10] && whole != 0) { - dwVtBits &= ~(VTBIT_R4|VTBIT_R8|VTBIT_CY); /* Underflow */ - bOverflow = TRUE; + whole = 0; /* ignore underflow */ + divisor10 = 0; } else whole = whole / dblMultipliers[divisor10]; diff --git a/dll/win32/oleaut32/vartype.c b/dll/win32/oleaut32/vartype.c index 3d07a277a4..70b1b63dd9 100644 --- a/dll/win32/oleaut32/vartype.c +++ b/dll/win32/oleaut32/vartype.c @@ -5362,7 +5362,7 @@ static HRESULT VARIANT_DI_normalize(VARIANT_DI * val, int exponent2, BOOL isDoub end of the bit representation, down to the precision guaranteed by the floating point number. */ if (isDouble) { - while (exponent10 < 0 && (val->bitsnum[2] != 0 || (val->bitsnum[2] == 0 && (val->bitsnum[1] & 0xFFE00000) != 0))) { + while (exponent10 < 0 && (val->bitsnum[2] != 0 || (val->bitsnum[1] & 0xFFE00000) != 0)) { int rem10; rem10 = VARIANT_int_divbychar(val->bitsnum, 3, 10); diff --git a/media/doc/README.WINE b/media/doc/README.WINE index 4b324f3b1d..d7b5451b3c 100644 --- a/media/doc/README.WINE +++ b/media/doc/README.WINE @@ -141,7 +141,7 @@ reactos/dll/win32/odbc32 # Synced to WineStaging-2.9. Depends on po reactos/dll/win32/odbccp32 # Synced to WineStaging-2.9 reactos/dll/win32/ole32 # Synced to Wine-3.0 reactos/dll/win32/oleacc # Synced to WineStaging-2.9 -reactos/dll/win32/oleaut32 # Synced to WineStaging-2.16 +reactos/dll/win32/oleaut32 # Synced to Wine-3.0 reactos/dll/win32/olecli32 # Synced to WineStaging-2.9 reactos/dll/win32/oledlg # Synced to WineStaging-2.9 reactos/dll/win32/olepro32 # Synced to WineStaging-2.9
7 years, 4 months
1
0
0
0
01/01: [OLE32_WINETEST] Sync with Wine 3.0. CORE-14225
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=b44b1afb813634b7e4da9…
commit b44b1afb813634b7e4da9cf79cd4e393a355f3ca Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Sat Jan 20 12:58:03 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Sat Jan 20 12:58:03 2018 +0100 [OLE32_WINETEST] Sync with Wine 3.0. CORE-14225 --- modules/rostests/winetests/ole32/hglobalstream.c | 230 --- modules/rostests/winetests/ole32/marshal.c | 8 +- modules/rostests/winetests/ole32/ole2.c | 1649 +++++++++++++++++++--- modules/rostests/winetests/ole32/usrmarshal.c | 201 ++- 4 files changed, 1631 insertions(+), 457 deletions(-) diff --git a/modules/rostests/winetests/ole32/hglobalstream.c b/modules/rostests/winetests/ole32/hglobalstream.c index 8789623869..9974cd3200 100644 --- a/modules/rostests/winetests/ole32/hglobalstream.c +++ b/modules/rostests/winetests/ole32/hglobalstream.c @@ -2,7 +2,6 @@ * Stream on HGLOBAL Tests * * Copyright 2006 Robert Shearman (for CodeWeavers) - * Copyright 2016 Dmitry Timoshkov * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -501,240 +500,11 @@ static void test_freed_hglobal(void) IStream_Release(pStream); } -static void stream_info(IStream *stream, HGLOBAL *hmem, int *size, int *pos) -{ - HRESULT hr; - STATSTG stat; - LARGE_INTEGER offset; - ULARGE_INTEGER newpos; - - *hmem = 0; - *size = *pos = -1; - - hr = GetHGlobalFromStream(stream, hmem); - ok(hr == S_OK, "unexpected %#x\n", hr); - - memset(&stat, 0x55, sizeof(stat)); - hr = IStream_Stat(stream, &stat, STATFLAG_DEFAULT); - ok(hr == S_OK, "unexpected %#x\n", hr); - ok(stat.type == STGTY_STREAM, "unexpected %#x\n", stat.type); - ok(!stat.pwcsName, "unexpected %p\n", stat.pwcsName); - ok(IsEqualIID(&stat.clsid, &GUID_NULL), "unexpected %s\n", wine_dbgstr_guid(&stat.clsid)); - ok(!stat.cbSize.HighPart, "unexpected %#x\n", stat.cbSize.HighPart); - *size = stat.cbSize.LowPart; - - offset.QuadPart = 0; - hr = IStream_Seek(stream, offset, STREAM_SEEK_CUR, &newpos); - ok(hr == S_OK, "unexpected %#x\n", hr); - ok(!newpos.HighPart, "unexpected %#x\n", newpos.HighPart); - *pos = newpos.LowPart; -} - -static void test_IStream_Clone(void) -{ - static const char hello[] = "Hello World!"; - char buf[32]; - HRESULT hr; - IStream *stream, *clone; - HGLOBAL orig_hmem, hmem, hmem_clone; - ULARGE_INTEGER newsize; - LARGE_INTEGER offset; - int size, pos, ret; - - /* test simple case for Clone */ - orig_hmem = GlobalAlloc(GMEM_MOVEABLE, 0); - ok(orig_hmem != 0, "unexpected %p\n", orig_hmem); - hr = CreateStreamOnHGlobal(orig_hmem, TRUE, &stream); - ok(hr == S_OK, "unexpected %#x\n", hr); - - hr = GetHGlobalFromStream(stream, NULL); - ok(hr == E_INVALIDARG, "unexpected %#x\n", hr); - - hr = GetHGlobalFromStream(NULL, &hmem); - ok(hr == E_INVALIDARG, "unexpected %#x\n", hr); - - stream_info(stream, &hmem, &size, &pos); - ok(hmem == orig_hmem, "handles should match\n"); - ok(size == 0, "unexpected %d\n", size); - ok(pos == 0, "unexpected %d\n", pos); - - hr = IStream_Clone(stream, &clone); - ok(hr == S_OK, "unexpected %#x\n", hr); - - hr = IStream_Write(stream, hello, sizeof(hello), NULL); - ok(hr == S_OK, "unexpected %#x\n", hr); - - stream_info(stream, &hmem, &size, &pos); - ok(hmem != 0, "unexpected %p\n", hmem); - ok(size == 13, "unexpected %d\n", size); - ok(pos == 13, "unexpected %d\n", pos); - - stream_info(clone, &hmem_clone, &size, &pos); - ok(hmem_clone == hmem, "handles should match\n"); - ok(size == 13, "unexpected %d\n", size); - ok(pos == 0, "unexpected %d\n", pos); - - buf[0] = 0; - hr = IStream_Read(clone, buf, sizeof(buf), NULL); - ok(hr == S_OK, "unexpected %#x\n", hr); - ok(!strcmp(buf, hello), "wrong stream contents\n"); - - newsize.QuadPart = 0x8000; - hr = IStream_SetSize(stream, newsize); - ok(hr == S_OK, "unexpected %#x\n", hr); - - stream_info(stream, &hmem, &size, &pos); - ok(hmem != 0, "unexpected %p\n", hmem); - ok(hmem == orig_hmem, "unexpected %p\n", hmem); - ok(size == 0x8000, "unexpected %#x\n", size); - ok(pos == 13, "unexpected %d\n", pos); - - stream_info(clone, &hmem_clone, &size, &pos); - ok(hmem_clone == hmem, "handles should match\n"); - ok(size == 0x8000, "unexpected %#x\n", size); - ok(pos == 13, "unexpected %d\n", pos); - - IStream_Release(clone); - IStream_Release(stream); - - /* exploit GMEM_FIXED forced move for the same base streams */ - orig_hmem = GlobalAlloc(GMEM_FIXED, 1); - ok(orig_hmem != 0, "unexpected %p\n", orig_hmem); - hr = CreateStreamOnHGlobal(orig_hmem, TRUE, &stream); - ok(hr == S_OK, "unexpected %#x\n", hr); - - hr = IStream_Clone(stream, &clone); - ok(hr == S_OK, "unexpected %#x\n", hr); - - stream_info(stream, &hmem, &size, &pos); - ok(hmem != 0, "unexpected %p\n", hmem); - ok(size == 1, "unexpected %d\n", size); - ok(pos == 0, "unexpected %d\n", pos); - - stream_info(clone, &hmem_clone, &size, &pos); - ok(hmem_clone == hmem, "handles should match\n"); - ok(size == 1, "unexpected %d\n", size); - ok(pos == 0, "unexpected %d\n", pos); - - newsize.QuadPart = 0x8000; - hr = IStream_SetSize(stream, newsize); - ok(hr == S_OK, "unexpected %#x\n", hr); - - stream_info(stream, &hmem, &size, &pos); - ok(hmem != 0, "unexpected %p\n", hmem); - ok(hmem != orig_hmem, "unexpected %p\n", hmem); - ok(size == 0x8000, "unexpected %#x\n", size); - ok(pos == 0, "unexpected %d\n", pos); - - stream_info(clone, &hmem_clone, &size, &pos); - ok(hmem_clone == hmem, "handles should match\n"); - ok(size == 0x8000, "unexpected %#x\n", size); - ok(pos == 0, "unexpected %d\n", pos); - - IStream_Release(stream); - IStream_Release(clone); - - /* exploit GMEM_FIXED forced move for different base streams */ - orig_hmem = GlobalAlloc(GMEM_FIXED, 1); - ok(orig_hmem != 0, "unexpected %p\n", orig_hmem); - hr = CreateStreamOnHGlobal(orig_hmem, TRUE, &stream); - ok(hr == S_OK, "unexpected %#x\n", hr); - - hr = CreateStreamOnHGlobal(orig_hmem, TRUE, &clone); - ok(hr == S_OK, "unexpected %#x\n", hr); - - stream_info(stream, &hmem, &size, &pos); - ok(hmem != 0, "unexpected %p\n", hmem); - ok(size == 1, "unexpected %d\n", size); - ok(pos == 0, "unexpected %d\n", pos); - - stream_info(clone, &hmem_clone, &size, &pos); - ok(hmem_clone == hmem, "handles should match\n"); - ok(size == 1, "unexpected %d\n", size); - ok(pos == 0, "unexpected %d\n", pos); - - newsize.QuadPart = 0x8000; - hr = IStream_SetSize(stream, newsize); - ok(hr == S_OK, "unexpected %#x\n", hr); - - stream_info(stream, &hmem, &size, &pos); - ok(hmem != 0, "unexpected %p\n", hmem); - ok(hmem != orig_hmem, "unexpected %p\n", hmem); - ok(size == 0x8000, "unexpected %#x\n", size); - ok(pos == 0, "unexpected %d\n", pos); - - stream_info(clone, &hmem_clone, &size, &pos); - ok(hmem_clone != hmem, "handles should not match\n"); - ok(size == 1, "unexpected %#x\n", size); - ok(pos == 0, "unexpected %d\n", pos); - - IStream_Release(stream); - /* releasing clone leads to test termination under windows - IStream_Release(clone); - */ - - /* test Release for a being cloned stream */ - hr = CreateStreamOnHGlobal(0, TRUE, &stream); - ok(hr == S_OK, "unexpected %#x\n", hr); - - hr = IStream_Clone(stream, &clone); - ok(hr == S_OK, "unexpected %#x\n", hr); - - stream_info(stream, &hmem, &size, &pos); - ok(hmem != 0, "unexpected %p\n", hmem); - ok(size == 0, "unexpected %d\n", size); - ok(pos == 0, "unexpected %d\n", pos); - - stream_info(clone, &hmem_clone, &size, &pos); - ok(hmem_clone == hmem, "handles should match\n"); - ok(size == 0, "unexpected %#x\n", size); - ok(pos == 0, "unexpected %d\n", pos); - - ret = IStream_Release(stream); - ok(ret == 0, "unexpected %d\n", ret); - - newsize.QuadPart = 0x8000; - hr = IStream_SetSize(clone, newsize); - ok(hr == S_OK, "unexpected %#x\n", hr); - - stream_info(clone, &hmem_clone, &size, &pos); - ok(hmem_clone == hmem, "handles should match\n"); - ok(size == 0x8000, "unexpected %#x\n", size); - ok(pos == 0, "unexpected %d\n", pos); - - hr = IStream_Write(clone, hello, sizeof(hello), NULL); - ok(hr == S_OK, "unexpected %#x\n", hr); - - stream_info(clone, &hmem_clone, &size, &pos); - ok(hmem_clone == hmem, "handles should match\n"); - ok(size == 0x8000, "unexpected %#x\n", size); - ok(pos == 13, "unexpected %d\n", pos); - - offset.QuadPart = 0; - hr = IStream_Seek(clone, offset, STREAM_SEEK_SET, NULL); - ok(hr == S_OK, "unexpected %#x\n", hr); - - buf[0] = 0; - hr = IStream_Read(clone, buf, sizeof(buf), NULL); - ok(hr == S_OK, "unexpected %#x\n", hr); - ok(!strcmp(buf, hello), "wrong stream contents\n"); - - stream_info(clone, &hmem_clone, &size, &pos); - ok(hmem_clone == hmem, "handles should match\n"); - ok(size == 0x8000, "unexpected %#x\n", size); - ok(pos == 32, "unexpected %d\n", pos); - - ret = IStream_Release(clone); - ok(ret == 0, "unexpected %d\n", ret); -} - START_TEST(hglobalstream) { HRESULT hr; IStream *pStream; - test_IStream_Clone(); - hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream); ok_ole_success(hr, "CreateStreamOnHGlobal"); diff --git a/modules/rostests/winetests/ole32/marshal.c b/modules/rostests/winetests/ole32/marshal.c index 10564cd536..2a29e66efe 100644 --- a/modules/rostests/winetests/ole32/marshal.c +++ b/modules/rostests/winetests/ole32/marshal.c @@ -2955,6 +2955,12 @@ static HRESULT WINAPI local_server_GetClassID(IPersist *iface, CLSID *clsid) hr = CoDisconnectObject((IUnknown *)iface, 0); ok(hr == S_OK, "got %08x\n", hr); + /* Initialize and uninitialize the apartment to show that we + * remain in the autojoined mta */ + hr = pCoInitializeEx( NULL, COINIT_MULTITHREADED ); + ok( hr == S_FALSE, "got %08x\n", hr ); + CoUninitialize(); + return S_OK; } @@ -3736,7 +3742,7 @@ START_TEST(marshal) argc = winetest_get_mainargs( &argv ); if (argc > 2 && (!strcmp(argv[2], "-Embedding"))) { - pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED); + pCoInitializeEx(NULL, COINIT_MULTITHREADED); test_register_local_server(); CoUninitialize(); diff --git a/modules/rostests/winetests/ole32/ole2.c b/modules/rostests/winetests/ole32/ole2.c index 288517c7d9..d6dafc0f63 100644 --- a/modules/rostests/winetests/ole32/ole2.c +++ b/modules/rostests/winetests/ole32/ole2.c @@ -2,6 +2,7 @@ * Object Linking and Embedding Tests * * Copyright 2005 Robert Shearman + * Copyright 2017 Dmitry Timoshkov * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -56,9 +57,15 @@ DEFINE_GUID(CLSID_Picture_EnhMetafile,0x319,0,0,0xc0,0,0,0,0,0,0,0x46); DEFINE_EXPECT(Storage_Stat); DEFINE_EXPECT(Storage_OpenStream_CompObj); +DEFINE_EXPECT(Storage_OpenStream_OlePres); DEFINE_EXPECT(Storage_SetClass); DEFINE_EXPECT(Storage_CreateStream_CompObj); +DEFINE_EXPECT(Storage_CreateStream_OlePres); DEFINE_EXPECT(Storage_OpenStream_Ole); +DEFINE_EXPECT(Storage_DestroyElement); + +static const CLSID *Storage_SetClass_CLSID; +static int Storage_DestroyElement_limit; static IPersistStorage OleObjectPersistStg; static IOleCache *cache; @@ -95,6 +102,7 @@ struct expected_method { const char *method; unsigned int flags; + FORMATETC fmt; }; static const struct expected_method *expected_method_list; @@ -107,6 +115,8 @@ static HRESULT g_QIFailsWith; static UINT cf_test_1, cf_test_2, cf_test_3; +static FORMATETC *g_dataobject_fmts; + /**************************************************************************** * PresentationDataHeader * @@ -123,7 +133,8 @@ typedef struct PresentationDataHeader * DWORD length; * CHAR format_name[length]; (null-terminated) */ - DWORD unknown3; /* 4, possibly TYMED_ISTREAM */ + DWORD tdSize; /* This is actually a truncated DVTARGETDEVICE, if tdSize > sizeof(DWORD) + then there are tdSize - sizeof(DWORD) more bytes before dvAspect */ DVASPECT dvAspect; DWORD lindex; DWORD advf; @@ -133,27 +144,43 @@ typedef struct PresentationDataHeader DWORD dwSize; } PresentationDataHeader; -#define CHECK_EXPECTED_METHOD(method_name) \ - do { \ - trace("%s\n", method_name); \ - ok(expected_method_list->method != NULL, "Extra method %s called\n", method_name); \ - if (!strcmp(expected_method_list->method, "WINE_EXTRA")) \ - { \ - todo_wine ok(0, "Too many method calls.\n"); \ - break; \ - } \ - if (expected_method_list->method) \ - { \ - while (expected_method_list->flags & TEST_OPTIONAL && \ - strcmp(expected_method_list->method, method_name) != 0) \ - expected_method_list++; \ - todo_wine_if (expected_method_list->flags & TEST_TODO) \ - ok(!strcmp(expected_method_list->method, method_name), \ - "Expected %s to be called instead of %s\n", \ - expected_method_list->method, method_name); \ - expected_method_list++; \ - } \ - } while(0) +static inline void check_expected_method_fmt(const char *method_name, const FORMATETC *fmt) +{ + trace("%s\n", method_name); + ok(expected_method_list->method != NULL, "Extra method %s called\n", method_name); + if (!strcmp(expected_method_list->method, "WINE_EXTRA")) + { + todo_wine ok(0, "Too many method calls.\n"); + return; + } + if (expected_method_list->method) + { + while (expected_method_list->flags & TEST_OPTIONAL && + strcmp(expected_method_list->method, method_name) != 0) + expected_method_list++; + todo_wine_if (expected_method_list->flags & TEST_TODO) + { + ok(!strcmp(expected_method_list->method, method_name), + "Expected %s to be called instead of %s\n", + expected_method_list->method, method_name); + if (fmt) + { + ok(fmt->cfFormat == expected_method_list->fmt.cfFormat, "got cf %04x vs %04x\n", + fmt->cfFormat, expected_method_list->fmt.cfFormat ); + ok(fmt->dwAspect == expected_method_list->fmt.dwAspect, "got aspect %d vs %d\n", + fmt->dwAspect, expected_method_list->fmt.dwAspect ); + ok(fmt->lindex == expected_method_list->fmt.lindex, "got lindex %d vs %d\n", + fmt->lindex, expected_method_list->fmt.lindex ); + ok(fmt->tymed == expected_method_list->fmt.tymed, "got tymed %d vs %d\n", + fmt->tymed, expected_method_list->fmt.tymed ); + } + } + expected_method_list++; + } +} + +#define CHECK_EXPECTED_METHOD(method_name) check_expected_method_fmt(method_name, NULL) +#define CHECK_EXPECTED_METHOD_FMT(method_name, fmt) check_expected_method_fmt(method_name, fmt) #define CHECK_NO_EXTRA_METHODS() \ do { \ @@ -162,6 +189,64 @@ typedef struct PresentationDataHeader ok(!expected_method_list->method, "Method sequence starting from %s not called\n", expected_method_list->method); \ } while (0) +/* 2 x 1 x 32 bpp dib. PelsPerMeter = 200x400 */ +static const BYTE dib[] = +{ + 0x28, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xc8, 0x00, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff +}; + +static void create_dib( STGMEDIUM *med ) +{ + void *ptr; + + med->tymed = TYMED_HGLOBAL; + U(med)->hGlobal = GlobalAlloc( GMEM_MOVEABLE, sizeof(dib) ); + ptr = GlobalLock( U(med)->hGlobal ); + memcpy( ptr, dib, sizeof(dib) ); + GlobalUnlock( U(med)->hGlobal ); + med->pUnkForRelease = NULL; +} + +static void create_bitmap( STGMEDIUM *med ) +{ + med->tymed = TYMED_GDI; + U(med)->hBitmap = CreateBitmap( 1, 1, 1, 1, NULL ); + med->pUnkForRelease = NULL; +} + +static void create_emf(STGMEDIUM *med) +{ + HDC hdc = CreateEnhMetaFileW(NULL, NULL, NULL, NULL); + + Rectangle(hdc, 0, 0, 150, 300); + med->tymed = TYMED_ENHMF; + U(med)->hEnhMetaFile = CloseEnhMetaFile(hdc); + med->pUnkForRelease = NULL; +} + +static void create_mfpict(STGMEDIUM *med) +{ + METAFILEPICT *mf; + HDC hdc = CreateMetaFileW(NULL); + + Rectangle(hdc, 0, 0, 100, 200); + + med->tymed = TYMED_MFPICT; + U(med)->hMetaFilePict = GlobalAlloc(GMEM_MOVEABLE, sizeof(METAFILEPICT)); + mf = GlobalLock(U(med)->hMetaFilePict); + mf->mm = MM_ANISOTROPIC; + mf->xExt = 100; + mf->yExt = 200; + mf->hMF = CloseMetaFile(hdc); + GlobalUnlock(U(med)->hMetaFilePict); + med->pUnkForRelease = NULL; +} + static HRESULT WINAPI OleObject_QueryInterface(IOleObject *iface, REFIID riid, void **ppv) { CHECK_EXPECTED_METHOD("OleObject_QueryInterface"); @@ -1213,7 +1298,7 @@ static void test_OleLoad(IStorage *pStorage) break; } - header.unknown3 = 4; + header.tdSize = sizeof(header.tdSize); header.dvAspect = DVASPECT_CONTENT; header.lindex = -1; header.advf = 1 << i; @@ -1368,13 +1453,40 @@ static ULONG WINAPI DataObject_Release( return 1; } -static HRESULT WINAPI DataObject_GetData( - IDataObject* iface, - LPFORMATETC pformatetcIn, - STGMEDIUM* pmedium) +static inline BOOL fmtetc_equal( const FORMATETC *a, const FORMATETC *b ) { - CHECK_EXPECTED_METHOD("DataObject_GetData"); - return E_NOTIMPL; + /* FIXME ptd */ + return a->cfFormat == b->cfFormat && a->dwAspect == b->dwAspect && + a->lindex == b->lindex && a->tymed == b->tymed; + +} + +static HRESULT WINAPI DataObject_GetData( IDataObject *iface, FORMATETC *fmt_in, + STGMEDIUM *med ) +{ + FORMATETC *fmt; + + CHECK_EXPECTED_METHOD_FMT("DataObject_GetData", fmt_in); + + for (fmt = g_dataobject_fmts; fmt && fmt->cfFormat != 0; fmt++) + { + if (fmtetc_equal( fmt_in, fmt )) + { + switch (fmt->cfFormat) + { + case CF_DIB: + create_dib( med ); + return S_OK; + case CF_BITMAP: + create_bitmap( med ); + return S_OK; + default: + trace( "unhandled fmt %d\n", fmt->cfFormat ); + } + } + } + + return S_FALSE; } static HRESULT WINAPI DataObject_GetDataHere( @@ -1386,12 +1498,16 @@ static HRESULT WINAPI DataObject_GetDataHere( return E_NOTIMPL; } -static HRESULT WINAPI DataObject_QueryGetData( - IDataObject* iface, - LPFORMATETC pformatetc) +static HRESULT WINAPI DataObject_QueryGetData( IDataObject *iface, FORMATETC *fmt_in ) { - CHECK_EXPECTED_METHOD("DataObject_QueryGetData"); - return S_OK; + FORMATETC *fmt; + + CHECK_EXPECTED_METHOD_FMT("DataObject_QueryGetData", fmt_in); + + for (fmt = g_dataobject_fmts; fmt && fmt->cfFormat != 0; fmt++) + if (fmtetc_equal( fmt_in, fmt )) return S_OK; + + return S_FALSE; } static HRESULT WINAPI DataObject_GetCanonicalFormatEtc( @@ -1550,7 +1666,7 @@ static void test_data_cache(void) IOleCache2 *pOleCache; IOleCache *olecache; IStorage *pStorage; - IUnknown *unk; + IUnknown *unk, *unk2; IPersistStorage *pPS; IViewObject *pViewObject; IOleCacheControl *pOleCacheControl; @@ -1584,9 +1700,9 @@ static void test_data_cache(void) { "draw_continue", 1 }, { "draw_continue", 1 }, { "draw_continue", 1 }, - { "DataObject_GetData", 0 }, - { "DataObject_GetData", 0 }, - { "DataObject_GetData", 0 }, + { "DataObject_GetData", 0, { CF_DIB, NULL, DVASPECT_THUMBNAIL, -1, TYMED_HGLOBAL} }, + { "DataObject_GetData", 0, { CF_BITMAP, NULL, DVASPECT_THUMBNAIL, -1, TYMED_GDI} }, + { "DataObject_GetData", 0, { CF_METAFILEPICT, NULL, DVASPECT_ICON, -1, TYMED_MFPICT} }, { NULL, 0 } }; static const struct expected_method methods_cachethenrun[] = @@ -1594,7 +1710,6 @@ static void test_data_cache(void) { "DataObject_DAdvise", 0 }, { "DataObject_DAdvise", 0 }, { "DataObject_DAdvise", 0 }, - { "DataObject_QueryGetData", 1 }, /* called by win9x and nt4 */ { "DataObject_DAdvise", 0 }, { "DataObject_DUnadvise", 0 }, { "DataObject_DUnadvise", 0 }, @@ -1641,10 +1756,12 @@ static void test_data_cache(void) ok(hr == S_OK, "got 0x%08x\n", hr); hr = IUnknown_QueryInterface(unk, &IID_IOleCache2, (void**)&pOleCache); ok(hr == S_OK, "got 0x%08x\n", hr); -todo_wine { + hr = IUnknown_QueryInterface(unk, &IID_IUnknown, (void**)&unk2); + ok(hr == S_OK, "got 0x%08x\n", hr); ok(unk == (IUnknown*)olecache, "got %p, expected %p\n", olecache, unk); ok(unk == (IUnknown*)pOleCache, "got %p, expected %p\n", pOleCache, unk); -} + ok(unk == unk2, "got %p, expected %p\n", unk2, unk); + IUnknown_Release(unk2); IOleCache2_Release(pOleCache); IOleCache_Release(olecache); IUnknown_Release(unk); @@ -1860,18 +1977,14 @@ todo_wine { DeleteDC(hdcMem); - todo_wine { hr = IOleCache2_InitCache(pOleCache, &DataObject); ok(hr == CACHE_E_NOCACHE_UPDATED, "IOleCache_InitCache should have returned CACHE_E_NOCACHE_UPDATED instead of 0x%08x\n", hr); - } IPersistStorage_Release(pPS); IViewObject_Release(pViewObject); IOleCache2_Release(pOleCache); - todo_wine { CHECK_NO_EXTRA_METHODS(); - } hr = CreateDataCache(NULL, &CLSID_NULL, &IID_IOleCache2, (LPVOID *)&pOleCache); ok_ole_success(hr, "CreateDataCache"); @@ -1939,21 +2052,17 @@ todo_wine { IStorage_Release(pStorage); } - static const WCHAR CONTENTS[] = {'C','O','N','T','E','N','T','S',0}; /* 2 x 1 x 32 bpp dib. PelsPerMeter = 200x400 */ -static BYTE dib[] = +static BYTE file_dib[] = { 0x42, 0x4d, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x28, 0x00, - 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; @@ -1973,27 +2082,15 @@ static IStorage *create_storage( int num ) ok( hr == S_OK, "got %08x\n", hr); if (num == 1) /* Set biXPelsPerMeter = 0 */ { - dib[0x26] = 0; - dib[0x27] = 0; + file_dib[0x26] = 0; + file_dib[0x27] = 0; } - hr = IStream_Write( stm, dib, sizeof(dib), &written ); + hr = IStream_Write( stm, file_dib, sizeof(file_dib), &written ); ok( hr == S_OK, "got %08x\n", hr); IStream_Release( stm ); return stg; } -static HGLOBAL create_dib( void ) -{ - HGLOBAL h; - void *ptr; - - h = GlobalAlloc( GMEM_MOVEABLE, sizeof(dib) - sizeof(BITMAPFILEHEADER) ); - ptr = GlobalLock( h ); - memcpy( ptr, dib + sizeof(BITMAPFILEHEADER), sizeof(dib) - sizeof(BITMAPFILEHEADER) ); - GlobalUnlock( h ); - return h; -} - static void test_data_cache_dib_contents_stream(int num) { HRESULT hr; @@ -2043,7 +2140,7 @@ static void test_data_cache_dib_contents_stream(int num) "got %lu\n", GlobalSize( U(med).hGlobal ) ); ptr = GlobalLock( U(med).hGlobal ); - expect_info = *(BITMAPINFOHEADER *)(dib + sizeof(BITMAPFILEHEADER)); + expect_info = *(BITMAPINFOHEADER *)(file_dib + sizeof(BITMAPFILEHEADER)); if (expect_info.biXPelsPerMeter == 0 || expect_info.biYPelsPerMeter == 0) { HDC hdc = GetDC( 0 ); @@ -2052,8 +2149,8 @@ static void test_data_cache_dib_contents_stream(int num) ReleaseDC( 0, hdc ); } ok( !memcmp( ptr, &expect_info, sizeof(expect_info) ), "mismatch\n" ); - ok( !memcmp( ptr + sizeof(expect_info), dib + sizeof(BITMAPFILEHEADER) + sizeof(expect_info), - sizeof(dib) - sizeof(BITMAPFILEHEADER) - sizeof(expect_info) ), "mismatch\n" ); + ok( !memcmp( ptr + sizeof(expect_info), file_dib + sizeof(BITMAPFILEHEADER) + sizeof(expect_info), + sizeof(file_dib) - sizeof(BITMAPFILEHEADER) - sizeof(expect_info) ), "mismatch\n" ); GlobalUnlock( U(med).hGlobal ); ReleaseStgMedium( &med ); @@ -2103,7 +2200,7 @@ static void check_dib_size( HGLOBAL h, int cx, int cy ) GlobalUnlock( h ); } -static void test_data_cache_bitmap(void) +static void test_data_cache_cache(void) { HRESULT hr; IOleCache2 *cache; @@ -2118,6 +2215,13 @@ static void test_data_cache_bitmap(void) {{ CF_METAFILEPICT, 0, DVASPECT_CONTENT, -1, TYMED_MFPICT }, 0, NULL, 0 }, {{ CF_ENHMETAFILE, 0, DVASPECT_CONTENT, -1, TYMED_ENHMF }, 0, NULL, 0 } }; + STATDATA view_caching[] = + { + {{ 0, 0, DVASPECT_CONTENT, -1, TYMED_ENHMF }, 0, NULL, 0 }, + {{ 0, 0, DVASPECT_THUMBNAIL, -1, TYMED_HGLOBAL }, 0, NULL, 0 }, + {{ 0, 0, DVASPECT_DOCPRINT, -1, TYMED_HGLOBAL }, 0, NULL, 0 }, + {{ CF_METAFILEPICT, 0, DVASPECT_ICON, -1, TYMED_MFPICT }, 0, NULL, 0 } + }; hr = CreateDataCache( NULL, &CLSID_NULL, &IID_IOleCache2, (void **)&cache ); ok( hr == S_OK, "got %08x\n", hr ); @@ -2194,9 +2298,7 @@ static void test_data_cache_bitmap(void) hr = IOleCache2_QueryInterface( cache, &IID_IDataObject, (void **) &data ); ok( hr == S_OK, "got %08x\n", hr ); - med.tymed = TYMED_GDI; - U(med).hBitmap = CreateBitmap( 1, 1, 1, 1, NULL ); - med.pUnkForRelease = NULL; + create_bitmap( &med ); hr = IOleCache2_SetData( cache, &fmt, &med, TRUE ); ok( hr == S_OK, "got %08x\n", hr ); @@ -2218,8 +2320,7 @@ static void test_data_cache_bitmap(void) /* Now set a 2x1 dib */ fmt.cfFormat = CF_DIB; fmt.tymed = TYMED_HGLOBAL; - med.tymed = TYMED_HGLOBAL; - U(med).hGlobal = create_dib(); + create_dib( &med ); hr = IOleCache2_SetData( cache, &fmt, &med, TRUE ); ok( hr == S_OK, "got %08x\n", hr ); @@ -2240,6 +2341,79 @@ static void test_data_cache_bitmap(void) check_dib_size( U(med).hGlobal, 2, 1 ); ReleaseStgMedium( &med ); + /* uncache everything */ + hr = IOleCache2_Uncache( cache, conn ); + ok( hr == S_OK, "got %08x\n", hr ); + + /* view caching */ + fmt.cfFormat = 0; + fmt.tymed = TYMED_ENHMF; + hr = IOleCache2_Cache( cache, &fmt, 0, &conn ); + ok( hr == S_OK, "got %08x\n", hr ); + view_caching[0].dwConnection = conn; + + fmt.tymed = TYMED_HGLOBAL; + hr = IOleCache2_Cache( cache, &fmt, 0, &conn ); + ok( hr == CACHE_S_SAMECACHE, "got %08x\n", hr ); + + fmt.dwAspect = DVASPECT_THUMBNAIL; + hr = IOleCache2_Cache( cache, &fmt, 0, &conn ); + ok( hr == S_OK, "got %08x\n", hr ); + view_caching[1].dwConnection = conn; + + fmt.dwAspect = DVASPECT_DOCPRINT; + hr = IOleCache2_Cache( cache, &fmt, 0, &conn ); + ok( hr == S_OK, "got %08x\n", hr ); + view_caching[2].dwConnection = conn; + + /* DVASPECT_ICON view cache gets mapped to CF_METAFILEPICT */ + fmt.dwAspect = DVASPECT_ICON; + hr = IOleCache2_Cache( cache, &fmt, 0, &conn ); + ok( hr == S_OK, "got %08x\n", hr ); + view_caching[3].dwConnection = conn; + + check_enum_cache( cache, view_caching, 4 ); + + /* uncache everything */ + hr = IOleCache2_Uncache( cache, view_caching[3].dwConnection ); + ok( hr == S_OK, "got %08x\n", hr ); + hr = IOleCache2_Uncache( cache, view_caching[2].dwConnection ); + ok( hr == S_OK, "got %08x\n", hr ); + hr = IOleCache2_Uncache( cache, view_caching[1].dwConnection ); + ok( hr == S_OK, "got %08x\n", hr ); + hr = IOleCache2_Uncache( cache, view_caching[0].dwConnection ); + ok( hr == S_OK, "got %08x\n", hr ); + + /* Only able to set cfFormat == CF_METAFILEPICT (or == 0, see above) for DVASPECT_ICON */ + fmt.dwAspect = DVASPECT_ICON; + fmt.cfFormat = CF_DIB; + fmt.tymed = TYMED_HGLOBAL; + hr = IOleCache2_Cache( cache, &fmt, 0, &conn ); + ok( hr == DV_E_FORMATETC, "got %08x\n", hr ); + fmt.cfFormat = CF_BITMAP; + fmt.tymed = TYMED_GDI; + hr = IOleCache2_Cache( cache, &fmt, 0, &conn ); + ok( hr == DV_E_FORMATETC, "got %08x\n", hr ); + fmt.cfFormat = CF_ENHMETAFILE; + fmt.tymed = TYMED_ENHMF; + hr = IOleCache2_Cache( cache, &fmt, 0, &conn ); + ok( hr == DV_E_FORMATETC, "got %08x\n", hr ); + fmt.cfFormat = CF_METAFILEPICT; + fmt.tymed = TYMED_MFPICT; + hr = IOleCache2_Cache( cache, &fmt, 0, &conn ); + ok( hr == S_OK, "got %08x\n", hr ); + + /* uncache everything */ + hr = IOleCache2_Uncache( cache, conn ); + ok( hr == S_OK, "got %08x\n", hr ); + + /* tymed == 0 */ + fmt.cfFormat = CF_ENHMETAFILE; + fmt.dwAspect = DVASPECT_CONTENT; + fmt.tymed = 0; + hr = IOleCache2_Cache( cache, &fmt, 0, &conn ); + ok( hr == DV_E_TYMED, "got %08x\n", hr ); + IDataObject_Release( data ); IOleCache2_Release( cache ); } @@ -2404,111 +2578,412 @@ static void test_data_cache_initnew(void) IOleCache2_Release( cache ); } -static void test_default_handler(void) +static void test_data_cache_updatecache( void ) { HRESULT hr; - IOleObject *pObject; - IRunnableObject *pRunnableObject; - IOleClientSite *pClientSite; - IDataObject *pDataObject; - SIZEL sizel; - DWORD dwStatus; - CLSID clsid; - LPOLESTR pszUserType; - LOGPALETTE palette; - DWORD dwAdvConn; - IMoniker *pMoniker; - FORMATETC fmtetc; - IOleInPlaceObject *pInPlaceObj; - IEnumOLEVERB *pEnumVerbs; - DWORD dwRegister; - static const WCHAR wszUnknown[] = {'U','n','k','n','o','w','n',0}; - static const WCHAR wszHostName[] = {'W','i','n','e',' ','T','e','s','t',' ','P','r','o','g','r','a','m',0}; - static const WCHAR wszDelim[] = {'!',0}; + IOleCache2 *cache; + FORMATETC fmt; + DWORD conn[4]; - static const struct expected_method methods_embeddinghelper[] = + static const struct expected_method methods_dib[] = { - { "OleObject_QueryInterface", 0 }, - { "OleObject_AddRef", 0 }, - { "OleObject_QueryInterface", 0 }, - { "OleObject_QueryInterface", TEST_TODO }, - { "OleObject_QueryInterface", 0 }, - { "OleObject_QueryInterface", 0 }, - { "OleObject_QueryInterface", TEST_OPTIONAL }, /* Win95/98/NT4 */ - { "OleObject_Release", TEST_TODO }, - { "WINE_EXTRA", TEST_OPTIONAL }, - { NULL, 0 } + { "DataObject_GetData", 0, { CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL } }, + { "DataObject_GetData", 0, { CF_BITMAP, NULL, DVASPECT_CONTENT, -1, TYMED_GDI } }, + { NULL } }; - hr = CoCreateInstance(&CLSID_WineTest, NULL, CLSCTX_INPROC_HANDLER, &IID_IOleObject, (void **)&pObject); - ok(hr == REGDB_E_CLASSNOTREG, "CoCreateInstance should have failed with REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr); + static const struct expected_method methods_dib_emf[] = + { + { "DataObject_GetData", 0, { CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL } }, + { "DataObject_GetData", 0, { CF_ENHMETAFILE, NULL, DVASPECT_CONTENT, -1, TYMED_ENHMF } }, + { "DataObject_GetData", 0, { CF_METAFILEPICT, NULL, DVASPECT_CONTENT, -1, TYMED_MFPICT } }, + { NULL } + }; + static const struct expected_method methods_dib_wmf[] = + { + { "DataObject_GetData", 0, { CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL } }, + { "DataObject_GetData", 0, { CF_METAFILEPICT, NULL, DVASPECT_CONTENT, -1, TYMED_MFPICT } }, + { NULL } + }; + static const struct expected_method methods_viewcache[] = + { + { "DataObject_QueryGetData", 0, { CF_METAFILEPICT, NULL, DVASPECT_CONTENT, -1, TYMED_MFPICT } }, + { "DataObject_QueryGetData", 0, { CF_ENHMETAFILE, NULL, DVASPECT_CONTENT, -1, TYMED_ENHMF } }, + { "DataObject_QueryGetData", 0, { CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL } }, + { "DataObject_QueryGetData", 0, { CF_BITMAP, NULL, DVASPECT_CONTENT, -1, TYMED_GDI } }, + { NULL } + }; + static const struct expected_method methods_viewcache_with_dib[] = + { + { "DataObject_QueryGetData", 0, { CF_METAFILEPICT, NULL, DVASPECT_CONTENT, -1, TYMED_MFPICT } }, + { "DataObject_QueryGetData", 0, { CF_ENHMETAFILE, NULL, DVASPECT_CONTENT, -1, TYMED_ENHMF } }, + { "DataObject_QueryGetData", 0, { CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL } }, + { "DataObject_GetData", 0, { CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL } }, + { NULL } + }; + static const struct expected_method methods_flags_all[] = + { + { "DataObject_GetData", 0, { CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL } }, + { "DataObject_GetData", 0, { CF_ENHMETAFILE, NULL, DVASPECT_CONTENT, -1, TYMED_ENHMF } }, + { "DataObject_GetData", 0, { CF_METAFILEPICT, NULL, DVASPECT_CONTENT, -1, TYMED_MFPICT } }, + { "DataObject_GetData", 0, { CF_METAFILEPICT, NULL, DVASPECT_CONTENT, -1, TYMED_MFPICT } }, + { NULL } + }; + static const struct expected_method methods_flags_ifblank_1[] = + { + { "DataObject_GetData", 0, { CF_METAFILEPICT, NULL, DVASPECT_CONTENT, -1, TYMED_MFPICT } }, + { NULL } + }; + static const struct expected_method methods_flags_ifblank_2[] = + { + { "DataObject_GetData", 0, { CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL } }, + { "DataObject_GetData", 0, { CF_METAFILEPICT, NULL, DVASPECT_CONTENT, -1, TYMED_MFPICT } }, + { NULL } + }; + static const struct expected_method methods_flags_normal[] = + { + { "DataObject_GetData", 0, { CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL } }, + { NULL } + }; + static const struct expected_method methods_initcache[] = + { + { "DataObject_GetData", 0, { CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL } }, + { "DataObject_GetData", 0, { CF_METAFILEPICT, NULL, DVASPECT_CONTENT, -1, TYMED_MFPICT } }, + { NULL } + }; + static const struct expected_method methods_empty[] = + { + { NULL } + }; - hr = OleCreateDefaultHandler(&CLSID_WineTest, NULL, &IID_IOleObject, (void **)&pObject); - ok_ole_success(hr, "OleCreateDefaultHandler"); + static STATDATA view_cache[] = + { + {{ 0, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 0 } + }; + static STATDATA view_cache_after_dib[] = + { + {{ CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 0 }, + {{ CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_GDI }, 0, NULL, 0 } + }; - hr = IOleObject_QueryInterface(pObject, &IID_IOleInPlaceObject, (void **)&pInPlaceObj); - ok(hr == E_NOINTERFACE, "IOleObject_QueryInterface(&IID_IOleInPlaceObject) should return E_NOINTERFACE instead of 0x%08x\n", hr); + static FORMATETC dib_fmt[] = + { + { CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, + { 0 } + }; - hr = IOleObject_Advise(pObject, &AdviseSink, &dwAdvConn); - ok_ole_success(hr, "IOleObject_Advise"); + hr = CreateDataCache( NULL, &CLSID_WineTestOld, &IID_IOleCache2, (void **)&cache ); + ok( hr == S_OK, "got %08x\n", hr ); - hr = IOleObject_Close(pObject, OLECLOSE_NOSAVE); - ok_ole_success(hr, "IOleObject_Close"); + /* No cache slots */ + g_dataobject_fmts = NULL; + expected_method_list = NULL; - /* FIXME: test IOleObject_EnumAdvise */ + hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_ALL, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); - hr = IOleObject_EnumVerbs(pObject, &pEnumVerbs); - ok(hr == REGDB_E_CLASSNOTREG, "IOleObject_EnumVerbs should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr); + /* A dib cache slot */ + fmt.cfFormat = CF_DIB; + fmt.ptd = NULL; + fmt.dwAspect = DVASPECT_CONTENT; + fmt.lindex = -1; + fmt.tymed = TYMED_HGLOBAL; - hr = IOleObject_GetClientSite(pObject, &pClientSite); - ok_ole_success(hr, "IOleObject_GetClientSite"); + hr = IOleCache2_Cache( cache, &fmt, 0, &conn[0] ); + ok( hr == S_OK, "got %08x\n", hr ); - hr = IOleObject_SetClientSite(pObject, pClientSite); - ok_ole_success(hr, "IOleObject_SetClientSite"); + expected_method_list = methods_dib; - hr = IOleObject_GetClipboardData(pObject, 0, &pDataObject); - ok(hr == OLE_E_NOTRUNNING, - "IOleObject_GetClipboardData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", - hr); + hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_ALL, NULL ); + ok( hr == CACHE_E_NOCACHE_UPDATED, "got %08x\n", hr ); - hr = IOleObject_GetExtent(pObject, DVASPECT_CONTENT, &sizel); - ok(hr == OLE_E_BLANK, "IOleObject_GetExtent should have returned OLE_E_BLANK instead of 0x%08x\n", - hr); + CHECK_NO_EXTRA_METHODS(); - hr = IOleObject_GetMiscStatus(pObject, DVASPECT_CONTENT, &dwStatus); - ok(hr == REGDB_E_CLASSNOTREG, "IOleObject_GetMiscStatus should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr); + /* Now with a dib available */ + g_dataobject_fmts = dib_fmt; + expected_method_list = methods_dib; - hr = IOleObject_GetUserClassID(pObject, &clsid); - ok_ole_success(hr, "IOleObject_GetUserClassID"); - ok(IsEqualCLSID(&clsid, &CLSID_WineTest), "clsid != CLSID_WineTest\n"); + hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_ALL, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); - hr = IOleObject_GetUserType(pObject, USERCLASSTYPE_FULL, &pszUserType); - todo_wine { - ok_ole_success(hr, "IOleObject_GetUserType"); - ok(!lstrcmpW(pszUserType, wszUnknown), "Retrieved user type was wrong\n"); - } + /* Add an EMF cache slot */ + fmt.cfFormat = CF_ENHMETAFILE; + fmt.ptd = NULL; + fmt.dwAspect = DVASPECT_CONTENT; + fmt.lindex = -1; + fmt.tymed = TYMED_ENHMF; - hr = IOleObject_InitFromData(pObject, NULL, TRUE, 0); - ok(hr == OLE_E_NOTRUNNING, "IOleObject_InitFromData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr); + hr = IOleCache2_Cache( cache, &fmt, 0, &conn[1] ); + ok( hr == S_OK, "got %08x\n", hr ); - hr = IOleObject_IsUpToDate(pObject); - ok(hr == OLE_E_NOTRUNNING, "IOleObject_IsUpToDate should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr); + g_dataobject_fmts = dib_fmt; + expected_method_list = methods_dib_emf; - palette.palNumEntries = 1; - palette.palVersion = 2; - memset(&palette.palPalEntry[0], 0, sizeof(palette.palPalEntry[0])); - hr = IOleObject_SetColorScheme(pObject, &palette); - ok(hr == OLE_E_NOTRUNNING, "IOleObject_SetColorScheme should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr); + /* Two slots to fill, only the dib will succeed */ + hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_ALL, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); - sizel.cx = sizel.cy = 0; - hr = IOleObject_SetExtent(pObject, DVASPECT_CONTENT, &sizel); - ok(hr == OLE_E_NOTRUNNING, "IOleObject_SetExtent should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr); + CHECK_NO_EXTRA_METHODS(); - hr = IOleObject_SetHostNames(pObject, wszHostName, NULL); - ok_ole_success(hr, "IOleObject_SetHostNames"); + /* Replace the emf slot with a wmf */ + hr = IOleCache2_Uncache( cache, conn[1] ); + ok( hr == S_OK, "got %08x\n", hr ); - hr = CreateItemMoniker(wszDelim, wszHostName, &pMoniker); - ok_ole_success(hr, "CreateItemMoniker"); + fmt.cfFormat = CF_METAFILEPICT; + fmt.ptd = NULL; + fmt.dwAspect = DVASPECT_CONTENT; + fmt.lindex = -1; + fmt.tymed = TYMED_MFPICT; + + hr = IOleCache2_Cache( cache, &fmt, 0, &conn[1] ); + ok( hr == S_OK, "got %08x\n", hr ); + + g_dataobject_fmts = dib_fmt; + expected_method_list = methods_dib_wmf; + + hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_ALL, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = IOleCache2_Uncache( cache, conn[1] ); + ok( hr == S_OK, "got %08x\n", hr ); + hr = IOleCache2_Uncache( cache, conn[0] ); + ok( hr == S_OK, "got %08x\n", hr ); + + /* View caching */ + fmt.cfFormat = 0; + fmt.ptd = NULL; + fmt.dwAspect = DVASPECT_CONTENT; + fmt.lindex = -1; + fmt.tymed = TYMED_HGLOBAL; + + hr = IOleCache2_Cache( cache, &fmt, 0, &conn[0] ); + ok( hr == S_OK, "got %08x\n", hr ); + view_cache[0].dwConnection = conn[0]; + + g_dataobject_fmts = NULL; + expected_method_list = methods_viewcache; + + hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_ALL, NULL ); + ok( hr == CACHE_E_NOCACHE_UPDATED, "got %08x\n", hr ); + + CHECK_NO_EXTRA_METHODS(); + check_enum_cache( cache, view_cache, 1 ); + + g_dataobject_fmts = dib_fmt; + expected_method_list = methods_viewcache_with_dib; + + hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_ALL, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + CHECK_NO_EXTRA_METHODS(); + view_cache_after_dib[0].dwConnection = view_cache_after_dib[1].dwConnection = view_cache[0].dwConnection; + check_enum_cache( cache, view_cache_after_dib, 2 ); + + hr = IOleCache2_Uncache( cache, conn[0] ); + ok( hr == S_OK, "got %08x\n", hr ); + + /* Try some different flags */ + + fmt.cfFormat = CF_DIB; + fmt.ptd = NULL; + fmt.dwAspect = DVASPECT_CONTENT; + fmt.lindex = -1; + fmt.tymed = TYMED_HGLOBAL; + + hr = IOleCache2_Cache( cache, &fmt, 0, &conn[0] ); + ok( hr == S_OK, "got %08x\n", hr ); + + fmt.cfFormat = CF_ENHMETAFILE; + fmt.ptd = NULL; + fmt.dwAspect = DVASPECT_CONTENT; + fmt.lindex = -1; + fmt.tymed = TYMED_ENHMF; + + hr = IOleCache2_Cache( cache, &fmt, ADVF_NODATA, &conn[1] ); + ok( hr == S_OK, "got %08x\n", hr ); + + fmt.cfFormat = CF_METAFILEPICT; + fmt.ptd = NULL; + fmt.dwAspect = DVASPECT_CONTENT; + fmt.lindex = -1; + fmt.tymed = TYMED_MFPICT; + + hr = IOleCache2_Cache( cache, &fmt, ADVFCACHE_ONSAVE, &conn[2] ); + ok( hr == S_OK, "got %08x\n", hr ); + + g_dataobject_fmts = dib_fmt; + expected_method_list = methods_flags_all; + + hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_ALL, NULL ); + + CHECK_NO_EXTRA_METHODS(); + + expected_method_list = methods_flags_all; + + hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_ALL, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + CHECK_NO_EXTRA_METHODS(); + + expected_method_list = methods_flags_ifblank_1; + + hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_IFBLANK , NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + CHECK_NO_EXTRA_METHODS(); + + hr = IOleCache2_DiscardCache( cache, DISCARDCACHE_NOSAVE ); + ok( hr == S_OK, "got %08x\n", hr ); + + expected_method_list = methods_flags_ifblank_2; + + hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_IFBLANK , NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + CHECK_NO_EXTRA_METHODS(); + + hr = IOleCache2_DiscardCache( cache, DISCARDCACHE_NOSAVE ); + ok( hr == S_OK, "got %08x\n", hr ); + + expected_method_list = methods_flags_all; + + hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_IFBLANK | UPDFCACHE_NODATACACHE, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + CHECK_NO_EXTRA_METHODS(); + + expected_method_list = methods_empty; + + hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_ONLYIFBLANK | UPDFCACHE_NORMALCACHE, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + CHECK_NO_EXTRA_METHODS(); + + hr = IOleCache2_DiscardCache( cache, DISCARDCACHE_NOSAVE ); + ok( hr == S_OK, "got %08x\n", hr ); + + expected_method_list = methods_flags_normal; + + hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_ONLYIFBLANK | UPDFCACHE_NORMALCACHE, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + CHECK_NO_EXTRA_METHODS(); + + expected_method_list = methods_initcache; + + hr = IOleCache2_InitCache( cache, &DataObject ); + ok( hr == S_OK, "got %08x\n", hr ); + + CHECK_NO_EXTRA_METHODS(); + + IOleCache2_Release( cache ); +} + +static void test_default_handler(void) +{ + HRESULT hr; + IOleObject *pObject; + IRunnableObject *pRunnableObject; + IOleClientSite *pClientSite; + IDataObject *pDataObject; + SIZEL sizel; + DWORD dwStatus; + CLSID clsid; + LPOLESTR pszUserType; + LOGPALETTE palette; + DWORD dwAdvConn; + IMoniker *pMoniker; + FORMATETC fmtetc; + IOleInPlaceObject *pInPlaceObj; + IEnumOLEVERB *pEnumVerbs; + DWORD dwRegister; + static const WCHAR wszUnknown[] = {'U','n','k','n','o','w','n',0}; + static const WCHAR wszHostName[] = {'W','i','n','e',' ','T','e','s','t',' ','P','r','o','g','r','a','m',0}; + static const WCHAR wszDelim[] = {'!',0}; + + static const struct expected_method methods_embeddinghelper[] = + { + { "OleObject_QueryInterface", 0 }, + { "OleObject_AddRef", 0 }, + { "OleObject_QueryInterface", 0 }, + { "OleObject_QueryInterface", TEST_TODO }, + { "OleObject_QueryInterface", 0 }, + { "OleObject_QueryInterface", 0 }, + { "OleObject_QueryInterface", TEST_OPTIONAL }, /* Win95/98/NT4 */ + { "OleObject_Release", TEST_TODO }, + { "WINE_EXTRA", TEST_OPTIONAL }, + { NULL, 0 } + }; + + hr = CoCreateInstance(&CLSID_WineTest, NULL, CLSCTX_INPROC_HANDLER, &IID_IOleObject, (void **)&pObject); + ok(hr == REGDB_E_CLASSNOTREG, "CoCreateInstance should have failed with REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr); + + hr = OleCreateDefaultHandler(&CLSID_WineTest, NULL, &IID_IOleObject, (void **)&pObject); + ok_ole_success(hr, "OleCreateDefaultHandler"); + + hr = IOleObject_QueryInterface(pObject, &IID_IOleInPlaceObject, (void **)&pInPlaceObj); + ok(hr == E_NOINTERFACE, "IOleObject_QueryInterface(&IID_IOleInPlaceObject) should return E_NOINTERFACE instead of 0x%08x\n", hr); + + hr = IOleObject_Advise(pObject, &AdviseSink, &dwAdvConn); + ok_ole_success(hr, "IOleObject_Advise"); + + hr = IOleObject_Close(pObject, OLECLOSE_NOSAVE); + ok_ole_success(hr, "IOleObject_Close"); + + /* FIXME: test IOleObject_EnumAdvise */ + + hr = IOleObject_EnumVerbs(pObject, &pEnumVerbs); + ok(hr == REGDB_E_CLASSNOTREG, "IOleObject_EnumVerbs should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr); + + hr = IOleObject_GetClientSite(pObject, &pClientSite); + ok_ole_success(hr, "IOleObject_GetClientSite"); + + hr = IOleObject_SetClientSite(pObject, pClientSite); + ok_ole_success(hr, "IOleObject_SetClientSite"); + + hr = IOleObject_GetClipboardData(pObject, 0, &pDataObject); + ok(hr == OLE_E_NOTRUNNING, + "IOleObject_GetClipboardData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", + hr); + + hr = IOleObject_GetExtent(pObject, DVASPECT_CONTENT, &sizel); + ok(hr == OLE_E_BLANK, "IOleObject_GetExtent should have returned OLE_E_BLANK instead of 0x%08x\n", + hr); + + hr = IOleObject_GetMiscStatus(pObject, DVASPECT_CONTENT, &dwStatus); + ok(hr == REGDB_E_CLASSNOTREG, "IOleObject_GetMiscStatus should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr); + + hr = IOleObject_GetUserClassID(pObject, &clsid); + ok_ole_success(hr, "IOleObject_GetUserClassID"); + ok(IsEqualCLSID(&clsid, &CLSID_WineTest), "clsid != CLSID_WineTest\n"); + + hr = IOleObject_GetUserType(pObject, USERCLASSTYPE_FULL, &pszUserType); + todo_wine { + ok_ole_success(hr, "IOleObject_GetUserType"); + ok(!lstrcmpW(pszUserType, wszUnknown), "Retrieved user type was wrong\n"); + } + + hr = IOleObject_InitFromData(pObject, NULL, TRUE, 0); + ok(hr == OLE_E_NOTRUNNING, "IOleObject_InitFromData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr); + + hr = IOleObject_IsUpToDate(pObject); + ok(hr == OLE_E_NOTRUNNING, "IOleObject_IsUpToDate should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr); + + palette.palNumEntries = 1; + palette.palVersion = 2; + memset(&palette.palPalEntry[0], 0, sizeof(palette.palPalEntry[0])); + hr = IOleObject_SetColorScheme(pObject, &palette); + ok(hr == OLE_E_NOTRUNNING, "IOleObject_SetColorScheme should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr); + + sizel.cx = sizel.cy = 0; + hr = IOleObject_SetExtent(pObject, DVASPECT_CONTENT, &sizel); + ok(hr == OLE_E_NOTRUNNING, "IOleObject_SetExtent should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr); + + hr = IOleObject_SetHostNames(pObject, wszHostName, NULL); + ok_ole_success(hr, "IOleObject_SetHostNames"); + + hr = CreateItemMoniker(wszDelim, wszHostName, &pMoniker); + ok_ole_success(hr, "CreateItemMoniker"); hr = IOleObject_SetMoniker(pObject, OLEWHICHMK_CONTAINER, pMoniker); ok_ole_success(hr, "IOleObject_SetMoniker"); IMoniker_Release(pMoniker); @@ -2764,9 +3239,12 @@ static void test_OleDraw(void) ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); } +static const WCHAR olepres0W[] = {2,'O','l','e','P','r','e','s','0','0','0',0}; static const WCHAR comp_objW[] = {1,'C','o','m','p','O','b','j',0}; static IStream *comp_obj_stream; static IStream *ole_stream; +static IStream *olepres_stream; +static IStream *contents_stream; static HRESULT WINAPI Storage_QueryInterface(IStorage *iface, REFIID riid, void **ppvObject) { @@ -2792,18 +3270,40 @@ static HRESULT WINAPI Storage_CreateStream(IStorage *iface, LPCOLESTR pwcsName, LARGE_INTEGER pos = {{0}}; HRESULT hr; - CHECK_EXPECT(Storage_CreateStream_CompObj); - ok(!lstrcmpW(pwcsName, comp_objW), "pwcsName = %s\n", wine_dbgstr_w(pwcsName)); - todo_wine ok(grfMode == (STGM_CREATE|STGM_SHARE_EXCLUSIVE|STGM_READWRITE), "grfMode = %x\n", grfMode); + if (!lstrcmpW(pwcsName, comp_objW)) + { + CHECK_EXPECT(Storage_CreateStream_CompObj); + *ppstm = comp_obj_stream; + + todo_wine ok(grfMode == (STGM_CREATE|STGM_SHARE_EXCLUSIVE|STGM_READWRITE), "grfMode = %x\n", grfMode); + } + else if (!lstrcmpW(pwcsName, olepres0W)) + { + CHECK_EXPECT(Storage_CreateStream_OlePres); + *ppstm = olepres_stream; + + todo_wine ok(grfMode == (STGM_SHARE_EXCLUSIVE|STGM_READWRITE), "grfMode = %x\n", grfMode); + } + else + { +todo_wine + ok(0, "unexpected stream name %s\n", wine_dbgstr_w(pwcsName)); +#if 0 /* FIXME: return NULL once Wine is fixed */ + *ppstm = NULL; + return E_NOTIMPL; +#else + *ppstm = contents_stream; +#endif + } + ok(!reserved1, "reserved1 = %x\n", reserved1); ok(!reserved2, "reserved2 = %x\n", reserved2); ok(!!ppstm, "ppstm = NULL\n"); - *ppstm = comp_obj_stream; - IStream_AddRef(comp_obj_stream); - hr = IStream_Seek(comp_obj_stream, pos, STREAM_SEEK_SET, NULL); + IStream_AddRef(*ppstm); + hr = IStream_Seek(*ppstm, pos, STREAM_SEEK_SET, NULL); ok(hr == S_OK, "IStream_Seek returned %x\n", hr); - hr = IStream_SetSize(comp_obj_stream, size); + hr = IStream_SetSize(*ppstm, size); ok(hr == S_OK, "IStream_SetSize returned %x\n", hr); return S_OK; } @@ -2830,6 +3330,15 @@ static HRESULT WINAPI Storage_OpenStream(IStorage *iface, LPCOLESTR pwcsName, vo return S_OK; }else if(!lstrcmpW(pwcsName, ole1W)) { CHECK_EXPECT(Storage_OpenStream_Ole); + + if (!ole_stream) + { + ok(grfMode == (STGM_SHARE_EXCLUSIVE|STGM_READ), "grfMode = %x\n", grfMode); + + *ppstm = NULL; + return STG_E_FILENOTFOUND; + } + ok(grfMode == (STGM_SHARE_EXCLUSIVE|STGM_READWRITE), "grfMode = %x\n", grfMode); *ppstm = ole_stream; @@ -2837,6 +3346,16 @@ static HRESULT WINAPI Storage_OpenStream(IStorage *iface, LPCOLESTR pwcsName, vo hr = IStream_Seek(ole_stream, pos, STREAM_SEEK_SET, NULL); ok(hr == S_OK, "IStream_Seek returned %x\n", hr); return S_OK; + + }else if(!lstrcmpW(pwcsName, olepres0W)) { + CHECK_EXPECT(Storage_OpenStream_OlePres); + ok(grfMode == (STGM_SHARE_EXCLUSIVE|STGM_READWRITE), "grfMode = %x\n", grfMode); + + *ppstm = olepres_stream; + IStream_AddRef(olepres_stream); + hr = IStream_Seek(olepres_stream, pos, STREAM_SEEK_SET, NULL); + ok(hr == S_OK, "IStream_Seek returned %x\n", hr); + return S_OK; } ok(0, "unexpected call to OpenStream: %s\n", wine_dbgstr_w(pwcsName)); @@ -2887,8 +3406,20 @@ static HRESULT WINAPI Storage_EnumElements(IStorage *iface, DWORD reserved1, voi static HRESULT WINAPI Storage_DestroyElement(IStorage *iface, LPCOLESTR pwcsName) { - ok(0, "unexpected call to DestroyElement\n"); - return E_NOTIMPL; + char name[32]; + int stream_n, cmp; + + CHECK_EXPECT2(Storage_DestroyElement); + cmp = CompareStringW(LOCALE_NEUTRAL, 0, pwcsName, 8, olepres0W, 8); + ok(cmp == CSTR_EQUAL, + "unexpected call to DestroyElement(%s)\n", wine_dbgstr_w(pwcsName)); + + WideCharToMultiByte(CP_ACP, 0, pwcsName, -1, name, sizeof(name), NULL, NULL); + stream_n = atol(name + 8); + if (stream_n <= Storage_DestroyElement_limit) + return S_OK; + + return STG_E_FILENOTFOUND; } static HRESULT WINAPI Storage_RenameElement(IStorage *iface, LPCOLESTR pwcsOldName, LPCOLESTR pwcsNewName) @@ -2906,7 +3437,8 @@ static HRESULT WINAPI Storage_SetElementTimes(IStorage *iface, LPCOLESTR pwcsNam static HRESULT WINAPI Storage_SetClass(IStorage *iface, REFCLSID clsid) { CHECK_EXPECT(Storage_SetClass); - ok(IsEqualIID(clsid, &CLSID_WineTest), "clsid = %s\n", wine_dbgstr_guid(clsid)); + ok(IsEqualIID(clsid, Storage_SetClass_CLSID), "expected %s, got %s\n", + wine_dbgstr_guid(Storage_SetClass_CLSID), wine_dbgstr_guid(clsid)); return S_OK; } @@ -3121,6 +3653,787 @@ static void test_OleDoAutoConvert(void) RegCloseKey(root); } +/* 1x1 pixel bmp */ +static const unsigned char bmpimage[] = +{ + 0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00, + 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00, + 0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00, + 0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b, + 0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00, + 0x00,0x00,0x02,0x00,0x00,0x00,0xff,0xff, + 0xff,0x00,0xff,0xff,0xff,0x00,0x00,0x00, + 0x00,0x00 +}; + +static const unsigned char mf_blank_bits[] = +{ + 0x01,0x00,0x09,0x00,0x00,0x03,0x0c,0x00, + 0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00, + 0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00 +}; + +static void test_data_cache_save(void) +{ + static const WCHAR contentsW[] = { 'C','o','n','t','e','n','t','s',0 }; + HRESULT hr; + ILockBytes *ilb; + IStorage *doc; + IStream *stm; + IOleCache2 *cache; + IPersistStorage *stg; + DWORD clipformat[2]; + PresentationDataHeader hdr; + + hr = CreateILockBytesOnHGlobal(0, TRUE, &ilb); + ok(hr == S_OK, "unexpected %#x\n", hr); + hr = StgCreateDocfileOnILockBytes(ilb, STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &doc); + ok(hr == S_OK, "unexpected %#x\n", hr); + + ILockBytes_Release(ilb); + + hr = IStorage_SetClass(doc, &CLSID_WineTest); + ok(hr == S_OK, "unexpected %#x\n", hr); + + hr = IStorage_CreateStream(doc, contentsW, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm); + ok(hr == S_OK, "unexpected %#x\n", hr); + hr = IStream_Write(stm, bmpimage, sizeof(bmpimage), NULL); + ok(hr == S_OK, "unexpected %#x\n", hr); + IStream_Release(stm); + + hr = IStorage_CreateStream(doc, olepres0W, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm); + ok(hr == S_OK, "unexpected %#x\n", hr); + + clipformat[0] = -1; + clipformat[1] = CF_METAFILEPICT; + hr = IStream_Write(stm, clipformat, sizeof(clipformat), NULL); + ok(hr == S_OK, "unexpected %#x\n", hr); + + hdr.tdSize = sizeof(hdr.tdSize); + hdr.dvAspect = DVASPECT_CONTENT; + hdr.lindex = -1; + hdr.advf = ADVF_PRIMEFIRST; + hdr.unknown7 = 0; + hdr.dwObjectExtentX = 0; + hdr.dwObjectExtentY = 0; + hdr.dwSize = sizeof(mf_blank_bits); + hr = IStream_Write(stm, &hdr, sizeof(hdr), NULL); + ok(hr == S_OK, "unexpected %#x\n", hr); + hr = IStream_Write(stm, mf_blank_bits, sizeof(mf_blank_bits), NULL); + ok(hr == S_OK, "unexpected %#x\n", hr); + + IStream_Release(stm); + + hr = CreateDataCache(NULL, &CLSID_NULL, &IID_IUnknown, (void **)&cache); + ok(hr == S_OK, "unexpected %#x\n", hr); + hr = IOleCache2_QueryInterface(cache, &IID_IPersistStorage, (void **)&stg); + ok(hr == S_OK, "unexpected %#x\n", hr); + hr = IPersistStorage_Load(stg, doc); + ok(hr == S_OK, "unexpected %#x\n", hr); + + IStorage_Release(doc); + + hr = IPersistStorage_IsDirty(stg); + ok(hr == S_FALSE, "unexpected %#x\n", hr); + + ole_stream = NULL; + hr = CreateStreamOnHGlobal(NULL, TRUE, &olepres_stream); + ok(hr == S_OK, "unexpected %#x\n", hr); + + /* FIXME: remove this stream once Wine is fixed */ + hr = CreateStreamOnHGlobal(NULL, TRUE, &contents_stream); + ok(hr == S_OK, "unexpected %#x\n", hr); + + SET_EXPECT(Storage_CreateStream_OlePres); + SET_EXPECT(Storage_OpenStream_OlePres); + SET_EXPECT(Storage_OpenStream_Ole); + SET_EXPECT(Storage_DestroyElement); + Storage_DestroyElement_limit = 50; + Storage_SetClass_CLSID = &CLSID_NULL; + trace("IPersistStorage_Save:\n"); + hr = IPersistStorage_Save(stg, &Storage, FALSE); + ok(hr == S_OK, "unexpected %#x\n", hr); + CHECK_CALLED(Storage_CreateStream_OlePres); +todo_wine + CHECK_CALLED(Storage_OpenStream_OlePres); +todo_wine + CHECK_CALLED(Storage_OpenStream_Ole); +todo_wine + CHECK_CALLED(Storage_DestroyElement); + + IStream_Release(olepres_stream); + IStream_Release(contents_stream); + + IPersistStorage_Release(stg); + IOleCache2_Release(cache); +} + +#define MAX_STREAM 16 + +struct stream_def +{ + const char *name; + int cf; + DVASPECT dvAspect; + ADVF advf; + const void *data; + size_t data_size; +}; + +struct storage_def +{ + const CLSID *clsid; + int stream_count; + struct stream_def stream[MAX_STREAM]; +}; + +static const struct storage_def stg_def_0 = +{ + &CLSID_NULL, 1, + {{ "Contents", -1, 0, 0, bmpimage, sizeof(bmpimage) }} +}; +static const struct storage_def stg_def_0_saved = +{ + &CLSID_NULL, 0, {{ 0 }} +}; +static const struct storage_def stg_def_1 = +{ + &CLSID_NULL, 2, + {{ "Contents", -1, 0, 0, NULL, 0 }, + { "\2OlePres000", 0, DVASPECT_ICON, ADVF_PRIMEFIRST | ADVF_ONLYONCE, NULL, 0 }} +}; +static const struct storage_def stg_def_1_saved = +{ + &CLSID_NULL, 1, + {{ "\2OlePres000", 0, DVASPECT_ICON, ADVF_PRIMEFIRST | ADVF_ONLYONCE, NULL, 0 }} +}; +static const struct storage_def stg_def_2 = +{ + &CLSID_ManualResetEvent, 2, + {{ "Contents", -1, 0, 0, bmpimage, sizeof(bmpimage) }, + { "\2OlePres000", 0, DVASPECT_ICON, ADVF_PRIMEFIRST | ADVF_ONLYONCE, NULL, 0 }} +}; +static const struct storage_def stg_def_2_saved = +{ + &CLSID_NULL, 1, + {{ "\2OlePres000", 0, DVASPECT_ICON, ADVF_PRIMEFIRST | ADVF_ONLYONCE, NULL, 0 }} +}; +static const struct storage_def stg_def_3 = +{ + &CLSID_NULL, 5, + {{ "Contents", -1, 0, 0, bmpimage, sizeof(bmpimage) }, + { "\2OlePres000", 0, DVASPECT_ICON, ADVF_PRIMEFIRST | ADVF_ONLYONCE, NULL, 0 }, + { "\2OlePres001", CF_METAFILEPICT, DVASPECT_CONTENT, ADVF_PRIMEFIRST, mf_blank_bits, sizeof(mf_blank_bits) }, + { "\2OlePres002", CF_DIB, DVASPECT_CONTENT, ADVF_PRIMEFIRST, bmpimage, sizeof(bmpimage) }, + { "MyStream", -1, 0, 0, "Hello World!", 13 }} +}; +static const struct storage_def stg_def_3_saved = +{ + &CLSID_NULL, 3, + {{ "\2OlePres000", 0, DVASPECT_ICON, ADVF_PRIMEFIRST | ADVF_ONLYONCE, NULL, 0 }, + { "\2OlePres001", CF_METAFILEPICT, DVASPECT_CONTENT, ADVF_PRIMEFIRST, mf_blank_bits, sizeof(mf_blank_bits) }, + { "\2OlePres002", CF_DIB, DVASPECT_CONTENT, ADVF_PRIMEFIRST, bmpimage, sizeof(bmpimage) }} +}; +static const struct storage_def stg_def_4 = +{ + &CLSID_Picture_EnhMetafile, 5, + {{ "Contents", -1, 0, 0, bmpimage, sizeof(bmpimage) }, + { "\2OlePres000", 0, DVASPECT_ICON, ADVF_PRIMEFIRST | ADVF_ONLYONCE, NULL, 0 }, + { "\2OlePres001", CF_METAFILEPICT, DVASPECT_CONTENT, ADVF_PRIMEFIRST, mf_blank_bits, sizeof(mf_blank_bits) }, + { "\2OlePres002", CF_DIB, DVASPECT_CONTENT, ADVF_PRIMEFIRST, bmpimage, sizeof(bmpimage) }, + { "MyStream", -1, 0, 0, "Hello World!", 13 }} +}; +static const struct storage_def stg_def_4_saved = +{ + &CLSID_NULL, 1, + {{ "\2OlePres000", 0, DVASPECT_ICON, ADVF_PRIMEFIRST | ADVF_ONLYONCE, NULL, 0 }} +}; +static const struct storage_def stg_def_5 = +{ + &CLSID_Picture_Dib, 5, + {{ "Contents", -1, 0, 0, bmpimage, sizeof(bmpimage) }, + { "\2OlePres002", CF_DIB, DVASPECT_CONTENT, ADVF_PRIMEFIRST, bmpimage, sizeof(bmpimage) }, + { "\2OlePres001", CF_METAFILEPICT, DVASPECT_CONTENT, ADVF_PRIMEFIRST, mf_blank_bits, sizeof(mf_blank_bits) }, + { "\2OlePres000", 0, DVASPECT_ICON, ADVF_PRIMEFIRST | ADVF_ONLYONCE, NULL, 0 }, + { "MyStream", -1, 0, 0, "Hello World!", 13 }} +}; +static const struct storage_def stg_def_5_saved = +{ + &CLSID_NULL, 1, + {{ "\2OlePres000", 0, DVASPECT_ICON, ADVF_PRIMEFIRST | ADVF_ONLYONCE, NULL, 0 }} +}; +static const struct storage_def stg_def_6 = +{ + &CLSID_Picture_Metafile, 5, + {{ "Contents", -1, 0, 0, bmpimage, sizeof(bmpimage) }, + { "\2OlePres001", CF_METAFILEPICT, DVASPECT_CONTENT, ADVF_PRIMEFIRST, mf_blank_bits, sizeof(mf_blank_bits) }, + { "\2OlePres000", 0, DVASPECT_ICON, ADVF_PRIMEFIRST | ADVF_ONLYONCE, NULL, 0 }, + { "\2OlePres002", CF_DIB, DVASPECT_CONTENT, ADVF_PRIMEFIRST, bmpimage, sizeof(bmpimage) }, + { "MyStream", -1, 0, 0, "Hello World!", 13 }} +}; +static const struct storage_def stg_def_6_saved = +{ + &CLSID_NULL, 1, + {{ "\2OlePres000", 0, DVASPECT_ICON, ADVF_PRIMEFIRST | ADVF_ONLYONCE, NULL, 0 }} +}; +static const struct storage_def stg_def_7 = +{ + &CLSID_Picture_Dib, 1, + {{ "Contents", -1, 0, 0, bmpimage, sizeof(bmpimage) }} +}; +static const struct storage_def stg_def_7_saved = +{ + &CLSID_NULL, 0, {{ 0 }} +}; +static const struct storage_def stg_def_8 = +{ + &CLSID_Picture_Metafile, 1, + {{ "Contents", -1, 0, 0, mf_blank_bits, sizeof(mf_blank_bits) }} +}; +static const struct storage_def stg_def_8_saved = +{ + &CLSID_NULL, 0, {{ 0 }} +}; +static const struct storage_def stg_def_9 = +{ + &CLSID_Picture_EnhMetafile, 1, + {{ "Contents", -1, 0, 0, bmpimage, sizeof(bmpimage) }} +}; +static const struct storage_def stg_def_9_saved = +{ + &CLSID_NULL, 0, {{ 0 }} +}; + +static int read_clipformat(IStream *stream) +{ + HRESULT hr; + ULONG bytes; + int length, clipformat = -2; + + hr = IStream_Read(stream, &length, sizeof(length), &bytes); + if (hr != S_OK || bytes != sizeof(length)) + return -2; + if (length == 0) + return 0; + if (length == -1) + { + hr = IStream_Read(stream, &clipformat, sizeof(clipformat), &bytes); + if (hr != S_OK || bytes != sizeof(clipformat)) + return -2; + } + else + ok(0, "unhandled clipformat length %d\n", length); + + return clipformat; +} + +static void check_storage_contents(IStorage *stg, const struct storage_def *stg_def, + int *enumerated_streams, int *matched_streams) +{ + HRESULT hr; + IEnumSTATSTG *enumstg; + IStream *stream; + STATSTG stat; + int i, seen_stream[MAX_STREAM] = { 0 }; + + if (winetest_debug > 1) + trace("check_storage_contents:\n=============================================\n"); + + *enumerated_streams = 0; + *matched_streams = 0; + + hr = IStorage_Stat(stg, &stat, STATFLAG_NONAME); + ok(hr == S_OK, "unexpected %#x\n", hr); + ok(IsEqualCLSID(stg_def->clsid, &stat.clsid), "expected %s, got %s\n", + wine_dbgstr_guid(stg_def->clsid), wine_dbgstr_guid(&stat.clsid)); + + hr = IStorage_EnumElements(stg, 0, NULL, 0, &enumstg); + ok(hr == S_OK, "unexpected %#x\n", hr); + + for (;;) + { + ULONG bytes; + int clipformat = -1; + PresentationDataHeader header; + char name[32]; + BYTE data[1024]; + + memset(&header, 0, sizeof(header)); + + hr = IEnumSTATSTG_Next(enumstg, 1, &stat, NULL); + if(hr == S_FALSE) break; + ok(hr == S_OK, "unexpected %#x\n", hr); + + if (winetest_debug > 1) + trace("name %s, type %u, size %d, clsid %s\n", + wine_dbgstr_w(stat.pwcsName), stat.type, stat.cbSize.u.LowPart, wine_dbgstr_guid(&stat.clsid)); + + ok(stat.type == STGTY_STREAM, "unexpected %#x\n", stat.type); + + WideCharToMultiByte(CP_ACP, 0, stat.pwcsName, -1, name, sizeof(name), NULL, NULL); + + hr = IStorage_OpenStream(stg, stat.pwcsName, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stream); + ok(hr == S_OK, "unexpected %#x\n", hr); + + if (!memcmp(name, "\2OlePres", 7)) + { + clipformat = read_clipformat(stream); + + hr = IStream_Read(stream, &header, sizeof(header), &bytes); + ok(hr == S_OK, "unexpected %#x\n", hr); + ok(bytes >= 24, "read %u bytes\n", bytes); + + if (winetest_debug > 1) + trace("header: tdSize %#x, dvAspect %#x, lindex %#x, advf %#x, unknown7 %#x, dwObjectExtentX %#x, dwObjectExtentY %#x, dwSize %#x\n", + header.tdSize, header.dvAspect, header.lindex, header.advf, header.unknown7, + header.dwObjectExtentX, header.dwObjectExtentY, header.dwSize); + } + + memset(data, 0, sizeof(data)); + hr = IStream_Read(stream, data, sizeof(data), &bytes); + ok(hr == S_OK, "unexpected %#x\n", hr); + if (winetest_debug > 1) + trace("stream data (%u bytes): %02x %02x %02x %02x\n", bytes, data[0], data[1], data[2], data[3]); + + for (i = 0; i < stg_def->stream_count; i++) + { + if (seen_stream[i]) continue; + + if (winetest_debug > 1) + trace("%s/%s, %d/%d, %d/%d, %d/%d\n", + stg_def->stream[i].name, name, + stg_def->stream[i].cf, clipformat, + stg_def->stream[i].dvAspect, header.dvAspect, + stg_def->stream[i].advf, header.advf); + + if (!strcmp(stg_def->stream[i].name, name) && + stg_def->stream[i].cf == clipformat && + stg_def->stream[i].dvAspect == header.dvAspect && + stg_def->stream[i].advf == header.advf && + stg_def->stream[i].data_size <= bytes && + (!stg_def->stream[i].data_size || + (!memcmp(stg_def->stream[i].data, data, min(stg_def->stream[i].data_size, bytes))))) + { + if (winetest_debug > 1) + trace("stream %d matches def stream %d\n", *enumerated_streams, i); + seen_stream[i] = 1; + *matched_streams += 1; + } + } + + CoTaskMemFree(stat.pwcsName); + IStream_Release(stream); + + *enumerated_streams += 1; + } +} + +static IStorage *create_storage_from_def(const struct storage_def *stg_def) +{ + HRESULT hr; + IStorage *stg; + IStream *stm; + int i; + + hr = StgCreateDocfile(NULL, STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_DELETEONRELEASE, 0, &stg); + ok(hr == S_OK, "unexpected %#x\n", hr); + + hr = IStorage_SetClass(stg, stg_def->clsid); + ok(hr == S_OK, "unexpected %#x\n", hr); + + for (i = 0; i < stg_def->stream_count; i++) + { + WCHAR name[32]; + + MultiByteToWideChar(CP_ACP, 0, stg_def->stream[i].name, -1, name, 32); + hr = IStorage_CreateStream(stg, name, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm); + ok(hr == S_OK, "unexpected %#x\n", hr); + + if (stg_def->stream[i].cf != -1) + { + int clipformat[2]; + PresentationDataHeader hdr; + + if (stg_def->stream[i].cf) + { + clipformat[0] = -1; + clipformat[1] = stg_def->stream[i].cf; + hr = IStream_Write(stm, clipformat, sizeof(clipformat), NULL); + } + else + { + clipformat[0] = 0; + hr = IStream_Write(stm, &clipformat[0], sizeof(clipformat[0]), NULL); + } + ok(hr == S_OK, "unexpected %#x\n", hr); + + hdr.tdSize = sizeof(hdr.tdSize); + hdr.dvAspect = stg_def->stream[i].dvAspect; + hdr.lindex = -1; + hdr.advf = stg_def->stream[i].advf; + hdr.unknown7 = 0; + hdr.dwObjectExtentX = 0; + hdr.dwObjectExtentY = 0; + hdr.dwSize = stg_def->stream[i].data_size; + hr = IStream_Write(stm, &hdr, sizeof(hdr), NULL); + ok(hr == S_OK, "unexpected %#x\n", hr); + } + + if (stg_def->stream[i].data_size) + { + hr = IStream_Write(stm, stg_def->stream[i].data, stg_def->stream[i].data_size, NULL); + ok(hr == S_OK, "unexpected %#x\n", hr); + } + + IStream_Release(stm); + } + + return stg; +} + +static const BYTE dib_inf[] = +{ + 0x42, 0x4d, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x36, 0x00, 0x00, 0x00 +}; + +static const BYTE mf_rec[] = +{ + 0xd7, 0xcd, 0xc6, 0x9a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x16, 0x00, 0x2d, 0x00, 0x40, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x6a, 0x55 +}; + +static void get_stgdef(struct storage_def *stg_def, CLIPFORMAT cf, STGMEDIUM *stg_med, int stm_idx) +{ + BYTE *data; + int data_size; + METAFILEPICT *mfpict; + HDC hdc; + + switch (cf) + { + case CF_DIB: + data_size = sizeof(dib); + if (!strcmp(stg_def->stream[stm_idx].name, "CONTENTS")) + { + data_size += sizeof(dib_inf); + data = HeapAlloc(GetProcessHeap(), 0, data_size); + memcpy(data, dib_inf, sizeof(dib_inf)); + memcpy(data + sizeof(dib_inf), dib, sizeof(dib)); + } + else + { + data = HeapAlloc(GetProcessHeap(), 0, data_size); + memcpy(data, dib, sizeof(dib)); + } + stg_def->stream[stm_idx].data = data; + stg_def->stream[stm_idx].data_size = data_size; + break; + case CF_METAFILEPICT: + mfpict = GlobalLock(U(stg_med)->hMetaFilePict); + data_size = GetMetaFileBitsEx(mfpict->hMF, 0, NULL); + if (!strcmp(stg_def->stream[stm_idx].name, "CONTENTS")) + { + data = HeapAlloc(GetProcessHeap(), 0, data_size + sizeof(mf_rec)); + memcpy(data, mf_rec, sizeof(mf_rec)); + GetMetaFileBitsEx(mfpict->hMF, data_size, data + sizeof(mf_rec)); + data_size += sizeof(mf_rec); + } + else + { + data = HeapAlloc(GetProcessHeap(), 0, data_size); + GetMetaFileBitsEx(mfpict->hMF, data_size, data); + } + GlobalUnlock(U(stg_med)->hMetaFilePict); + stg_def->stream[stm_idx].data_size = data_size; + stg_def->stream[stm_idx].data = data; + break; + case CF_ENHMETAFILE: + if (!strcmp(stg_def->stream[stm_idx].name, "CONTENTS")) + { + data_size = GetEnhMetaFileBits(U(stg_med)->hEnhMetaFile, 0, NULL); + data = HeapAlloc(GetProcessHeap(), 0, sizeof(DWORD) + sizeof(ENHMETAHEADER) + data_size); + *((DWORD *)data) = sizeof(ENHMETAHEADER); + GetEnhMetaFileBits(U(stg_med)->hEnhMetaFile, data_size, data + sizeof(DWORD) + sizeof(ENHMETAHEADER)); + memcpy(data + sizeof(DWORD), data + sizeof(DWORD) + sizeof(ENHMETAHEADER), sizeof(ENHMETAHEADER)); + data_size += sizeof(DWORD) + sizeof(ENHMETAHEADER); + } + else + { + hdc = GetDC(NULL); + data_size = GetWinMetaFileBits(U(stg_med)->hEnhMetaFile, 0, NULL, MM_ANISOTROPIC, hdc); + data = HeapAlloc(GetProcessHeap(), 0, data_size); + GetWinMetaFileBits(U(stg_med)->hEnhMetaFile, data_size, data, MM_ANISOTROPIC, hdc); + ReleaseDC(NULL, hdc); + } + stg_def->stream[stm_idx].data_size = data_size; + stg_def->stream[stm_idx].data = data; + break; + } +} + +static void get_stgmedium(CLIPFORMAT cfFormat, STGMEDIUM *stgmedium) +{ + switch (cfFormat) + { + case CF_DIB: + create_dib(stgmedium); + break; + case CF_METAFILEPICT: + create_mfpict(stgmedium); + break; + case CF_ENHMETAFILE: + create_emf(stgmedium); + break; + default: + ok(0, "cf %x not implemented\n", cfFormat); + } +} + +#define MAX_FMTS 5 +static void test_data_cache_save_data(void) +{ + HRESULT hr; + STGMEDIUM stgmed; + ILockBytes *ilb; + IStorage *doc; + IOleCache2 *cache; + IPersistStorage *persist; + int enumerated_streams, matched_streams, i; + DWORD dummy; + struct tests_data_cache + { + FORMATETC fmts[MAX_FMTS]; + int num_fmts, num_set; + const CLSID *clsid; + struct storage_def stg_def; + }; + + static struct tests_data_cache *pdata, data[] = + { + { + { + { CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, + { CF_METAFILEPICT, 0, DVASPECT_CONTENT, -1, TYMED_MFPICT }, + { CF_ENHMETAFILE, 0, DVASPECT_CONTENT, -1, TYMED_ENHMF }, + }, + 3, 3, &CLSID_WineTest, + { + &CLSID_WineTestOld, 3, { { "\2OlePres000", CF_DIB, DVASPECT_CONTENT, 0, NULL, 0 }, + { "\2OlePres001", CF_METAFILEPICT, DVASPECT_CONTENT, 0, NULL, 0 }, + { "\2OlePres002", CF_ENHMETAFILE, DVASPECT_CONTENT, 0, NULL, 0 } } + } + }, + /* without setting data */ + { + { + { CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, + { CF_METAFILEPICT, 0, DVASPECT_CONTENT, -1, TYMED_MFPICT }, + { CF_ENHMETAFILE, 0, DVASPECT_CONTENT, -1, TYMED_ENHMF }, + }, + 3, 0, &CLSID_WineTest, + { + &CLSID_WineTestOld, 3, { { "\2OlePres000", CF_DIB, DVASPECT_CONTENT, 0, NULL, 0 }, + { "\2OlePres001", CF_METAFILEPICT, DVASPECT_CONTENT, 0, NULL, 0 }, + { "\2OlePres002", CF_ENHMETAFILE, DVASPECT_CONTENT, 0, NULL, 0 } } + } + }, + /* static picture clsids */ + { + { + { CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, + }, + 1, 1, &CLSID_Picture_Dib, + { + &CLSID_WineTestOld, 1, { { "CONTENTS", -1, 0, 0, NULL, 0 } } + } + }, + { + { + { CF_METAFILEPICT, 0, DVASPECT_CONTENT, -1, TYMED_MFPICT }, + }, + 1, 1, &CLSID_Picture_Metafile, + { + &CLSID_WineTestOld, 1, { { "CONTENTS", -1, 0, 0, NULL, 0 } } + } + }, + { + { + { CF_ENHMETAFILE, 0, DVASPECT_CONTENT, -1, TYMED_ENHMF }, + }, + 1, 1, &CLSID_Picture_EnhMetafile, + { + &CLSID_WineTestOld, 1, { { "CONTENTS", -1, 0, 0, NULL, 0 } } + } + }, + /* static picture clsids without setting any data */ + { + { + { CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, + }, + 1, 0, &CLSID_Picture_Dib, + { + &CLSID_WineTestOld, 1, { { "CONTENTS", -1, 0, 0, NULL, 0 } } + } + }, + { + { + { CF_METAFILEPICT, 0, DVASPECT_CONTENT, -1, TYMED_MFPICT }, + }, + 1, 0, &CLSID_Picture_Metafile, + { + &CLSID_WineTestOld, 1, { { "CONTENTS", -1, 0, 0, NULL, 0 } } + } + }, + { + { + { CF_ENHMETAFILE, 0, DVASPECT_CONTENT, -1, TYMED_ENHMF }, + }, + 1, 0, &CLSID_Picture_EnhMetafile, + { + &CLSID_WineTestOld, 1, { { "CONTENTS", -1, 0, 0, NULL, 0 } } + } + }, + { + { + { 0 } + } + } + }; + + /* test _Save after caching directly through _Cache + _SetData */ + for (pdata = data; pdata->clsid != NULL; pdata++) + { + hr = CreateDataCache(NULL, pdata->clsid, &IID_IOleCache2, (void **)&cache); + ok(hr == S_OK, "unexpected %#x\n", hr); + + for (i = 0; i < pdata->num_fmts; i++) + { + hr = IOleCache2_Cache(cache, &pdata->fmts[i], 0, &dummy); + ok(SUCCEEDED(hr), "unexpected %#x\n", hr); + if (i < pdata->num_set) + { + get_stgmedium(pdata->fmts[i].cfFormat, &stgmed); + get_stgdef(&pdata->stg_def, pdata->fmts[i].cfFormat, &stgmed, i); + hr = IOleCache2_SetData(cache, &pdata->fmts[i], &stgmed, TRUE); + ok(hr == S_OK, "unexpected %#x\n", hr); + } + } + + /* create Storage in memory where we'll save cache */ + hr = CreateILockBytesOnHGlobal(0, TRUE, &ilb); + ok(hr == S_OK, "unexpected %#x\n", hr); + hr = StgCreateDocfileOnILockBytes(ilb, STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &doc); + ok(hr == S_OK, "unexpected %#x\n", hr); + ILockBytes_Release(ilb); + hr = IStorage_SetClass(doc, &CLSID_WineTestOld); + ok(hr == S_OK, "unexpected %#x\n", hr); + + hr = IOleCache2_QueryInterface(cache, &IID_IPersistStorage, (void **)&persist); + ok(hr == S_OK, "unexpected %#x\n", hr); + + /* cache entries are dirty. test saving them to stg */ + trace("IPersistStorage_Save:\n"); + hr = IPersistStorage_Save(persist, doc, FALSE); + ok(hr == S_OK, "unexpected %#x\n", hr); + + hr = IPersistStorage_IsDirty(persist); + ok(hr == S_OK, "unexpected %#x\n", hr); + + check_storage_contents(doc, &pdata->stg_def, &enumerated_streams, &matched_streams); + ok(enumerated_streams == matched_streams, "enumerated %d != matched %d\n", + enumerated_streams, matched_streams); + ok(enumerated_streams == pdata->stg_def.stream_count, "created %d != def streams %d\n", + enumerated_streams, pdata->stg_def.stream_count); + + for (i = 0; i < pdata->num_set; i++) + HeapFree(GetProcessHeap(), 0, (void *)pdata->stg_def.stream[i].data); + + IPersistStorage_Release(persist); + IStorage_Release(doc); + IOleCache2_Release(cache); + } +} + +static void test_data_cache_contents(void) +{ + HRESULT hr; + IStorage *doc1, *doc2; + IOleCache2 *cache; + IPersistStorage *stg; + int i, enumerated_streams, matched_streams; + static const struct + { + const struct storage_def *in; + const struct storage_def *out; + } test_data[] = + { + { &stg_def_0, &stg_def_0_saved }, + { &stg_def_1, &stg_def_1_saved }, + { &stg_def_2, &stg_def_2_saved }, + { &stg_def_3, &stg_def_3_saved }, + { &stg_def_4, &stg_def_4_saved }, + { &stg_def_5, &stg_def_5_saved }, + { &stg_def_6, &stg_def_6_saved }, + { &stg_def_7, &stg_def_7_saved }, + { &stg_def_8, &stg_def_8_saved }, + { &stg_def_9, &stg_def_9_saved }, + }; + + for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++) + { + if (winetest_debug > 1) + trace("start testing storage def %d\n", i); + + doc1 = create_storage_from_def(test_data[i].in); + if (!doc1) continue; + + enumerated_streams = matched_streams = -1; + check_storage_contents(doc1, test_data[i].in, &enumerated_streams, &matched_streams); + ok(enumerated_streams == matched_streams, "%d in: enumerated %d != matched %d\n", i, + enumerated_streams, matched_streams); + ok(enumerated_streams == test_data[i].in->stream_count, "%d: created %d != def streams %d\n", i, + enumerated_streams, test_data[i].in->stream_count); + + hr = CreateDataCache(NULL, &CLSID_NULL, &IID_IUnknown, (void **)&cache); + ok(hr == S_OK, "unexpected %#x\n", hr); + hr = IOleCache2_QueryInterface(cache, &IID_IPersistStorage, (void **)&stg); + ok(hr == S_OK, "unexpected %#x\n", hr); + hr = IPersistStorage_Load(stg, doc1); + ok(hr == S_OK, "unexpected %#x\n", hr); + + IStorage_Release(doc1); + + hr = StgCreateDocfile(NULL, STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_DELETEONRELEASE, 0, &doc2); + ok(hr == S_OK, "unexpected %#x\n", hr); + + hr = IPersistStorage_IsDirty(stg); +todo_wine_if(test_data[i].in == &stg_def_4 || test_data[i].in == &stg_def_8 || test_data[i].in == &stg_def_9) + ok(hr == S_FALSE, "%d: unexpected %#x\n", i, hr); + + hr = IPersistStorage_Save(stg, doc2, FALSE); + ok(hr == S_OK, "unexpected %#x\n", hr); + + IPersistStorage_Release(stg); + + enumerated_streams = matched_streams = -1; + check_storage_contents(doc2, test_data[i].out, &enumerated_streams, &matched_streams); +todo_wine_if(!(test_data[i].in == &stg_def_0 || test_data[i].in == &stg_def_1 || test_data[i].in == &stg_def_2)) + ok(enumerated_streams == matched_streams, "%d out: enumerated %d != matched %d\n", i, + enumerated_streams, matched_streams); +todo_wine_if(!(test_data[i].in == &stg_def_0 || test_data[i].in == &stg_def_5)) + ok(enumerated_streams == test_data[i].out->stream_count, "%d: saved streams %d != def streams %d\n", i, + enumerated_streams, test_data[i].out->stream_count); + + IStorage_Release(doc2); + + if (winetest_debug > 1) + trace("done testing storage def %d\n", i); + } +} + START_TEST(ole2) { DWORD dwRegister; @@ -3153,18 +4466,24 @@ START_TEST(ole2) hr = CoRevokeClassObject(dwRegister); ok_ole_success(hr, "CoRevokeClassObject"); + Storage_SetClass_CLSID = &CLSID_WineTest; + test_data_cache(); test_data_cache_dib_contents_stream( 0 ); test_data_cache_dib_contents_stream( 1 ); - test_data_cache_bitmap(); + test_data_cache_cache(); test_data_cache_init(); test_data_cache_initnew(); + test_data_cache_updatecache(); test_default_handler(); test_runnable(); test_OleRun(); test_OleLockRunning(); test_OleDraw(); test_OleDoAutoConvert(); + test_data_cache_save(); + test_data_cache_save_data(); + test_data_cache_contents(); CoUninitialize(); } diff --git a/modules/rostests/winetests/ole32/usrmarshal.c b/modules/rostests/winetests/ole32/usrmarshal.c index bc9525914e..8576ed78f2 100644 --- a/modules/rostests/winetests/ole32/usrmarshal.c +++ b/modules/rostests/winetests/ole32/usrmarshal.c @@ -178,31 +178,32 @@ static void test_marshal_CLIPFORMAT(void) USER_MARSHAL_CB umcb; MIDL_STUB_MESSAGE stub_msg; RPC_MESSAGE rpc_msg; - unsigned char *buffer; + unsigned char *buffer, *buffer_end; ULONG i, size; CLIPFORMAT cf = RegisterClipboardFormatA("MyFormat"); CLIPFORMAT cf2; init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE); - size = CLIPFORMAT_UserSize(&umcb.Flags, 0, &cf); - ok(size == 8 + sizeof(cf_marshaled) || - broken(size == 12 + sizeof(cf_marshaled)) || /* win64 adds 4 extra (unused) bytes */ - broken(size == 8 + sizeof(cf_marshaled) - 2), /* win9x and winnt don't include the '\0' */ + size = CLIPFORMAT_UserSize(&umcb.Flags, 1, &cf); + ok(size == 12 + sizeof(cf_marshaled) || + broken(size == 16 + sizeof(cf_marshaled)), /* win64 adds 4 extra (unused) bytes */ "CLIPFORMAT: Wrong size %d\n", size); buffer = HeapAlloc(GetProcessHeap(), 0, size); memset( buffer, 0xcc, size ); init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE); - CLIPFORMAT_UserMarshal(&umcb.Flags, buffer, &cf); - ok(*(LONG *)(buffer + 0) == WDT_REMOTE_CALL, "CLIPFORMAT: Context should be WDT_REMOTE_CALL instead of 0x%08x\n", *(LONG *)(buffer + 0)); - ok(*(DWORD *)(buffer + 4) == cf, "CLIPFORMAT: Marshaled value should be 0x%04x instead of 0x%04x\n", cf, *(DWORD *)(buffer + 4)); - ok(!memcmp(buffer + 8, cf_marshaled, min( sizeof(cf_marshaled), size-8 )), "Marshaled data differs\n"); - if (size > sizeof(cf_marshaled) + 8) /* make sure the extra bytes are not used */ - for (i = sizeof(cf_marshaled) + 8; i < size; i++) + buffer_end = CLIPFORMAT_UserMarshal(&umcb.Flags, buffer + 1, &cf); + ok(buffer_end == buffer + 12 + sizeof(cf_marshaled), "got %p buffer %p\n", buffer_end, buffer); + ok(*(LONG *)(buffer + 4) == WDT_REMOTE_CALL, "CLIPFORMAT: Context should be WDT_REMOTE_CALL instead of 0x%08x\n", *(LONG *)(buffer + 0)); + ok(*(DWORD *)(buffer + 8) == cf, "CLIPFORMAT: Marshaled value should be 0x%04x instead of 0x%04x\n", cf, *(DWORD *)(buffer + 4)); + ok(!memcmp(buffer + 12, cf_marshaled, min( sizeof(cf_marshaled), size-12 )), "Marshaled data differs\n"); + if (size > sizeof(cf_marshaled) + 12) /* make sure the extra bytes are not used */ + for (i = sizeof(cf_marshaled) + 12; i < size; i++) ok( buffer[i] == 0xcc, "buffer offset %u has been set to %x\n", i, buffer[i] ); init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE); - CLIPFORMAT_UserUnmarshal(&umcb.Flags, buffer, &cf2); + buffer_end = CLIPFORMAT_UserUnmarshal(&umcb.Flags, buffer + 1, &cf2); + ok(buffer_end == buffer + 12 + sizeof(cf_marshaled), "got %p buffer %p\n", buffer_end, buffer); ok(cf == cf2, "CLIPFORMAT: Didn't unmarshal properly\n"); HeapFree(GetProcessHeap(), 0, buffer); @@ -215,25 +216,27 @@ static void test_marshal_HWND(void) USER_MARSHAL_CB umcb; MIDL_STUB_MESSAGE stub_msg; RPC_MESSAGE rpc_msg; - unsigned char *buffer; + unsigned char *buffer, *buffer_end; ULONG size; HWND hwnd = GetDesktopWindow(); HWND hwnd2; wireHWND wirehwnd; init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL); - size = HWND_UserSize(&umcb.Flags, 0, &hwnd); - ok(size == sizeof(*wirehwnd), "Wrong size %d\n", size); + size = HWND_UserSize(&umcb.Flags, 1, &hwnd); + ok(size == 4 + sizeof(*wirehwnd), "Wrong size %d\n", size); buffer = HeapAlloc(GetProcessHeap(), 0, size); init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL); - HWND_UserMarshal(&umcb.Flags, buffer, &hwnd); - wirehwnd = (wireHWND)buffer; + buffer_end = HWND_UserMarshal(&umcb.Flags, buffer + 1, &hwnd); + ok(buffer_end == buffer + size, "got %p buffer %p\n", buffer_end, buffer); + wirehwnd = (wireHWND)(buffer + 4); ok(wirehwnd->fContext == WDT_INPROC_CALL, "Context should be WDT_INPROC_CALL instead of 0x%08x\n", wirehwnd->fContext); ok(wirehwnd->u.hInproc == (LONG_PTR)hwnd, "Marshaled value should be %p instead of %x\n", hwnd, wirehwnd->u.hRemote); init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL); - HWND_UserUnmarshal(&umcb.Flags, buffer, &hwnd2); + buffer_end = HWND_UserUnmarshal(&umcb.Flags, buffer + 1, &hwnd2); + ok(buffer_end == buffer + size, "got %p buffer %p\n", buffer_end, buffer); ok(hwnd == hwnd2, "Didn't unmarshal properly\n"); HeapFree(GetProcessHeap(), 0, buffer); @@ -335,7 +338,7 @@ static void test_marshal_HENHMETAFILE(void) USER_MARSHAL_CB umcb; MIDL_STUB_MESSAGE stub_msg; RPC_MESSAGE rpc_msg; - unsigned char *buffer; + unsigned char *buffer, *buffer_end; ULONG size; HENHMETAFILE hemf; HENHMETAFILE hemf2 = NULL; @@ -344,26 +347,28 @@ static void test_marshal_HENHMETAFILE(void) hemf = create_emf(); init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE); - size = HENHMETAFILE_UserSize(&umcb.Flags, 0, &hemf); - ok(size > 20, "size should be at least 20 bytes, not %d\n", size); + size = HENHMETAFILE_UserSize(&umcb.Flags, 1, &hemf); + ok(size > 24, "size should be at least 24 bytes, not %d\n", size); buffer = HeapAlloc(GetProcessHeap(), 0, size); init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE); - HENHMETAFILE_UserMarshal(&umcb.Flags, buffer, &hemf); - wirehemf = buffer; + buffer_end = HENHMETAFILE_UserMarshal(&umcb.Flags, buffer + 1, &hemf); + ok(buffer_end == buffer + size, "got %p buffer %p\n", buffer_end, buffer); + wirehemf = buffer + 4; ok(*(DWORD *)wirehemf == WDT_REMOTE_CALL, "wirestgm + 0x0 should be WDT_REMOTE_CALL instead of 0x%08x\n", *(DWORD *)wirehemf); wirehemf += sizeof(DWORD); ok(*(DWORD *)wirehemf == (DWORD)(DWORD_PTR)hemf, "wirestgm + 0x4 should be hemf instead of 0x%08x\n", *(DWORD *)wirehemf); wirehemf += sizeof(DWORD); - ok(*(DWORD *)wirehemf == (size - 0x10), "wirestgm + 0x8 should be size - 0x10 instead of 0x%08x\n", *(DWORD *)wirehemf); + ok(*(DWORD *)wirehemf == (size - 0x14), "wirestgm + 0x8 should be size - 0x14 instead of 0x%08x\n", *(DWORD *)wirehemf); wirehemf += sizeof(DWORD); - ok(*(DWORD *)wirehemf == (size - 0x10), "wirestgm + 0xc should be size - 0x10 instead of 0x%08x\n", *(DWORD *)wirehemf); + ok(*(DWORD *)wirehemf == (size - 0x14), "wirestgm + 0xc should be size - 0x14 instead of 0x%08x\n", *(DWORD *)wirehemf); wirehemf += sizeof(DWORD); ok(*(DWORD *)wirehemf == EMR_HEADER, "wirestgm + 0x10 should be EMR_HEADER instead of %d\n", *(DWORD *)wirehemf); /* ... rest of data not tested - refer to tests for GetEnhMetaFileBits * at this point */ init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE); - HENHMETAFILE_UserUnmarshal(&umcb.Flags, buffer, &hemf2); + buffer_end = HENHMETAFILE_UserUnmarshal(&umcb.Flags, buffer + 1, &hemf2); + ok(buffer_end == buffer + size, "got %p buffer %p\n", buffer_end, buffer); ok(hemf2 != NULL, "HENHMETAFILE didn't unmarshal\n"); HeapFree(GetProcessHeap(), 0, buffer); init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE); @@ -374,18 +379,20 @@ static void test_marshal_HENHMETAFILE(void) hemf = NULL; init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE); - size = HENHMETAFILE_UserSize(&umcb.Flags, 0, &hemf); - ok(size == 8, "size should be 8 bytes, not %d\n", size); + size = HENHMETAFILE_UserSize(&umcb.Flags, 1, &hemf); + ok(size == 12, "size should be 12 bytes, not %d\n", size); buffer = HeapAlloc(GetProcessHeap(), 0, size); init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE); - HENHMETAFILE_UserMarshal(&umcb.Flags, buffer, &hemf); - wirehemf = buffer; + buffer_end = HENHMETAFILE_UserMarshal(&umcb.Flags, buffer + 1, &hemf); + ok(buffer_end == buffer + size, "got %p buffer %p\n", buffer_end, buffer); + wirehemf = buffer + 4; ok(*(DWORD *)wirehemf == WDT_REMOTE_CALL, "wirestgm + 0x0 should be WDT_REMOTE_CALL instead of 0x%08x\n", *(DWORD *)wirehemf); wirehemf += sizeof(DWORD); ok(*(DWORD *)wirehemf == (DWORD)(DWORD_PTR)hemf, "wirestgm + 0x4 should be hemf instead of 0x%08x\n", *(DWORD *)wirehemf); init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE); - HENHMETAFILE_UserUnmarshal(&umcb.Flags, buffer, &hemf2); + buffer_end = HENHMETAFILE_UserUnmarshal(&umcb.Flags, buffer + 1, &hemf2); + ok(buffer_end == buffer + size, "got %p buffer %p\n", buffer_end, buffer); ok(hemf2 == NULL, "NULL HENHMETAFILE didn't unmarshal\n"); HeapFree(GetProcessHeap(), 0, buffer); init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE); @@ -486,12 +493,12 @@ static void test_marshal_HMETAFILEPICT(void) GlobalUnlock(hmfp); init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE); - size = HMETAFILEPICT_UserSize(&umcb.Flags, 0, &hmfp); - ok(size > 20, "size should be at least 20 bytes, not %d\n", size); + size = HMETAFILEPICT_UserSize(&umcb.Flags, 1, &hmfp); + ok(size > 24, "size should be at least 24 bytes, not %d\n", size); buffer = HeapAlloc(GetProcessHeap(), 0, size); init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE); - buffer_end = HMETAFILEPICT_UserMarshal(&umcb.Flags, buffer, &hmfp); - wirehmfp = buffer; + buffer_end = HMETAFILEPICT_UserMarshal(&umcb.Flags, buffer + 1, &hmfp); + wirehmfp = buffer + 4; ok(*(DWORD *)wirehmfp == WDT_REMOTE_CALL, "wirestgm + 0x0 should be WDT_REMOTE_CALL instead of 0x%08x\n", *(DWORD *)wirehmfp); wirehmfp += sizeof(DWORD); ok(*(DWORD *)wirehmfp == (DWORD)(DWORD_PTR)hmfp, "wirestgm + 0x4 should be hmf instead of 0x%08x\n", *(DWORD *)wirehmfp); @@ -512,16 +519,16 @@ static void test_marshal_HMETAFILEPICT(void) wirehmfp += sizeof(DWORD); /* Note use (buffer_end - buffer) instead of size here, because size is an * overestimate with native */ - ok(*(DWORD *)wirehmfp == (buffer_end - buffer - 0x28), "wirestgm + 0x20 should be size - 0x34 instead of 0x%08x\n", *(DWORD *)wirehmfp); + ok(*(DWORD *)wirehmfp == (buffer_end - buffer - 0x2c), "wirestgm + 0x20 should be size - 0x34 instead of 0x%08x\n", *(DWORD *)wirehmfp); wirehmfp += sizeof(DWORD); - ok(*(DWORD *)wirehmfp == (buffer_end - buffer - 0x28), "wirestgm + 0x24 should be size - 0x34 instead of 0x%08x\n", *(DWORD *)wirehmfp); + ok(*(DWORD *)wirehmfp == (buffer_end - buffer - 0x2c), "wirestgm + 0x24 should be size - 0x34 instead of 0x%08x\n", *(DWORD *)wirehmfp); wirehmfp += sizeof(DWORD); ok(*(WORD *)wirehmfp == 1, "wirehmfp + 0x28 should be 1 instead of 0x%08x\n", *(DWORD *)wirehmfp); /* ... rest of data not tested - refer to tests for GetMetaFileBits * at this point */ init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE); - HMETAFILEPICT_UserUnmarshal(&umcb.Flags, buffer, &hmfp2); + HMETAFILEPICT_UserUnmarshal(&umcb.Flags, buffer + 1, &hmfp2); ok(hmfp2 != NULL, "HMETAFILEPICT didn't unmarshal\n"); HeapFree(GetProcessHeap(), 0, buffer); init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE); @@ -535,12 +542,13 @@ static void test_marshal_HMETAFILEPICT(void) hmfp = NULL; init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE); - size = HMETAFILEPICT_UserSize(&umcb.Flags, 0, &hmfp); - ok(size == 8, "size should be 8 bytes, not %d\n", size); + size = HMETAFILEPICT_UserSize(&umcb.Flags, 1, &hmfp); + ok(size == 12, "size should be 12 bytes, not %d\n", size); buffer = HeapAlloc(GetProcessHeap(), 0, size); init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE); - HMETAFILEPICT_UserMarshal(&umcb.Flags, buffer, &hmfp); - wirehmfp = buffer; + buffer_end = HMETAFILEPICT_UserMarshal(&umcb.Flags, buffer + 1, &hmfp); + ok(buffer_end == buffer + size, "got %p buffer %p\n", buffer_end, buffer); + wirehmfp = buffer + 4; ok(*(DWORD *)wirehmfp == WDT_REMOTE_CALL, "wirestgm + 0x0 should be WDT_REMOTE_CALL instead of 0x%08x\n", *(DWORD *)wirehmfp); wirehmfp += sizeof(DWORD); ok(*(DWORD *)wirehmfp == (DWORD)(DWORD_PTR)hmfp, "wirestgm + 0x4 should be hmf instead of 0x%08x\n", *(DWORD *)wirehmfp); @@ -548,7 +556,8 @@ static void test_marshal_HMETAFILEPICT(void) hmfp2 = NULL; init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE); - HMETAFILEPICT_UserUnmarshal(&umcb.Flags, buffer, &hmfp2); + buffer_end = HMETAFILEPICT_UserUnmarshal(&umcb.Flags, buffer + 1, &hmfp2); + ok(buffer_end == buffer + size, "got %p buffer %p\n", buffer_end, buffer); ok(hmfp2 == NULL, "NULL HMETAFILE didn't unmarshal\n"); HeapFree(GetProcessHeap(), 0, buffer); init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE); @@ -1082,23 +1091,25 @@ static void test_marshal_HDC(void) HDC hdc = GetDC(0), hdc2; USER_MARSHAL_CB umcb; RPC_MESSAGE rpc_msg; - unsigned char *buffer; + unsigned char *buffer, *buffer_end; wireHDC wirehdc; ULONG size; init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL); - size = HDC_UserSize(&umcb.Flags, 0, &hdc); - ok(size == sizeof(*wirehdc), "Wrong size %d\n", size); + size = HDC_UserSize(&umcb.Flags, 1, &hdc); + ok(size == 4 + sizeof(*wirehdc), "Wrong size %d\n", size); buffer = HeapAlloc(GetProcessHeap(), 0, size); init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL); - HDC_UserMarshal(&umcb.Flags, buffer, &hdc); - wirehdc = (wireHDC)buffer; + buffer_end = HDC_UserMarshal(&umcb.Flags, buffer + 1, &hdc); + ok(buffer_end == buffer + 4 + sizeof(*wirehdc), "got %p buffer %p\n", buffer_end, buffer); + wirehdc = (wireHDC)(buffer + 4); ok(wirehdc->fContext == WDT_INPROC_CALL, "Context should be WDT_INPROC_CALL instead of 0x%08x\n", wirehdc->fContext); ok(wirehdc->u.hInproc == (LONG_PTR)hdc, "Marshaled value should be %p instead of %x\n", hdc, wirehdc->u.hRemote); init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL); - HDC_UserUnmarshal(&umcb.Flags, buffer, &hdc2); + buffer_end = HDC_UserUnmarshal(&umcb.Flags, buffer + 1, &hdc2); + ok(buffer_end == buffer + 4 + sizeof(*wirehdc), "got %p buffer %p\n", buffer_end, buffer); ok(hdc == hdc2, "Didn't unmarshal properly\n"); HeapFree(GetProcessHeap(), 0, buffer); @@ -1114,7 +1125,7 @@ static void test_marshal_HICON(void) HICON hIcon, hIcon2; USER_MARSHAL_CB umcb; RPC_MESSAGE rpc_msg; - unsigned char *buffer; + unsigned char *buffer, *buffer_end; wireHICON wirehicon; ULONG size; @@ -1122,18 +1133,20 @@ static void test_marshal_HICON(void) ok(hIcon != 0, "CreateIcon failed\n"); init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL); - size = HICON_UserSize(&umcb.Flags, 0, &hIcon); - ok(size == sizeof(*wirehicon), "Wrong size %d\n", size); + size = HICON_UserSize(&umcb.Flags, 1, &hIcon); + ok(size == 4 + sizeof(*wirehicon), "Wrong size %d\n", size); buffer = HeapAlloc(GetProcessHeap(), 0, size); init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL); - HICON_UserMarshal(&umcb.Flags, buffer, &hIcon); - wirehicon = (wireHICON)buffer; + buffer_end = HICON_UserMarshal(&umcb.Flags, buffer + 1, &hIcon); + ok(buffer_end == buffer + 4 + sizeof(*wirehicon), "got %p buffer %p\n", buffer_end, buffer); + wirehicon = (wireHICON)(buffer + 4); ok(wirehicon->fContext == WDT_INPROC_CALL, "Context should be WDT_INPROC_CALL instead of 0x%08x\n", wirehicon->fContext); ok(wirehicon->u.hInproc == (LONG_PTR)hIcon, "Marshaled value should be %p instead of %x\n", hIcon, wirehicon->u.hRemote); init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL); - HICON_UserUnmarshal(&umcb.Flags, buffer, &hIcon2); + buffer_end = HICON_UserUnmarshal(&umcb.Flags, buffer + 1, &hIcon2); + ok(buffer_end == buffer + 4 + sizeof(*wirehicon), "got %p buffer %p\n", buffer_end, buffer); ok(hIcon == hIcon2, "Didn't unmarshal properly\n"); HeapFree(GetProcessHeap(), 0, buffer); @@ -1148,7 +1161,7 @@ static void test_marshal_HBRUSH(void) HBRUSH hBrush, hBrush2; USER_MARSHAL_CB umcb; RPC_MESSAGE rpc_msg; - unsigned char *buffer; + unsigned char *buffer, *buffer_end; LOGBRUSH logbrush; wireHBRUSH wirehbrush; ULONG size; @@ -1161,18 +1174,20 @@ static void test_marshal_HBRUSH(void) ok(hBrush != 0, "CreateBrushIndirect failed\n"); init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL); - size = HBRUSH_UserSize(&umcb.Flags, 0, &hBrush); - ok(size == sizeof(*wirehbrush), "Wrong size %d\n", size); + size = HBRUSH_UserSize(&umcb.Flags, 1, &hBrush); + ok(size == 4 + sizeof(*wirehbrush), "Wrong size %d\n", size); buffer = HeapAlloc(GetProcessHeap(), 0, size); init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL); - HBRUSH_UserMarshal(&umcb.Flags, buffer, &hBrush); - wirehbrush = (wireHBRUSH)buffer; + buffer_end = HBRUSH_UserMarshal(&umcb.Flags, buffer + 1, &hBrush); + ok(buffer_end == buffer + 4 + sizeof(*wirehbrush), "got %p buffer %p\n", buffer_end, buffer); + wirehbrush = (wireHBRUSH)(buffer + 4); ok(wirehbrush->fContext == WDT_INPROC_CALL, "Context should be WDT_INPROC_CALL instead of 0x%08x\n", wirehbrush->fContext); ok(wirehbrush->u.hInproc == (LONG_PTR)hBrush, "Marshaled value should be %p instead of %x\n", hBrush, wirehbrush->u.hRemote); init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL); - HBRUSH_UserUnmarshal(&umcb.Flags, buffer, &hBrush2); + buffer_end = HBRUSH_UserUnmarshal(&umcb.Flags, buffer + 1, &hBrush2); + ok(buffer_end == buffer + 4 + sizeof(*wirehbrush), "got %p buffer %p\n", buffer_end, buffer); ok(hBrush == hBrush2, "Didn't unmarshal properly\n"); HeapFree(GetProcessHeap(), 0, buffer); @@ -1181,6 +1196,69 @@ static void test_marshal_HBRUSH(void) DeleteObject(hBrush); } +static void test_marshal_HBITMAP(void) +{ + static const ULONG header_size = FIELD_OFFSET(userBITMAP, cbSize); + static BYTE bmp_bits[1024]; + MIDL_STUB_MESSAGE stub_msg; + HBITMAP hBitmap, hBitmap2; + USER_MARSHAL_CB umcb; + RPC_MESSAGE rpc_msg; + unsigned char *buffer, *buffer_end; + unsigned char bitmap[1024]; + ULONG size, bitmap_size; + + hBitmap = CreateBitmap(16, 16, 1, 1, bmp_bits); + ok(hBitmap != 0, "CreateBitmap failed\n"); + size = GetObjectA(hBitmap, sizeof(bitmap), bitmap); + ok(size != 0, "GetObject failed\n"); + bitmap_size = GetBitmapBits(hBitmap, 0, NULL); + ok(bitmap_size != 0, "GetBitmapBits failed\n"); + + init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_INPROC); + size = HBITMAP_UserSize(&umcb.Flags, 1, &hBitmap); + ok(size == 0xc, "Wrong size %d\n", size); + buffer = HeapAlloc(GetProcessHeap(), 0, size + 4); + init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_INPROC); + buffer_end = HBITMAP_UserMarshal(&umcb.Flags, buffer + 1, &hBitmap); + ok(buffer_end == buffer + 0xc, "HBITMAP_UserMarshal() returned wrong size %d\n", (LONG)(buffer_end - buffer)); + ok(*(ULONG *)(buffer + 0x4) == WDT_INPROC_CALL, "Context should be WDT_INPROC_CALL instead of 0x%08x\n", *(ULONG *)(buffer + 0x4)); + ok(*(ULONG *)(buffer + 0x8) == (ULONG)(ULONG_PTR)hBitmap, "wirestgm + 0x4 should be bitmap handle instead of 0x%08x\n", *(ULONG *)(buffer + 0x8)); + + init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_INPROC); + HBITMAP_UserUnmarshal(&umcb.Flags, buffer + 1, &hBitmap2); + ok(hBitmap2 != NULL, "Didn't unmarshal properly\n"); + HeapFree(GetProcessHeap(), 0, buffer); + + init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_INPROC); + HBITMAP_UserFree(&umcb.Flags, &hBitmap2); + + init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL); + size = HBITMAP_UserSize(&umcb.Flags, 1, &hBitmap); + ok(size == 0x10 + header_size + bitmap_size || + broken(size == 0x14 + header_size + bitmap_size), /* Windows adds 4 extra (unused) bytes */ + "Wrong size %d\n", size); + + buffer = HeapAlloc(GetProcessHeap(), 0, size + 4); + init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL); + buffer_end = HBITMAP_UserMarshal(&umcb.Flags, buffer + 1, &hBitmap); + ok(buffer_end == buffer + 0x10 + header_size + bitmap_size, "HBITMAP_UserMarshal() returned wrong size %d\n", (LONG)(buffer_end - buffer)); + ok(*(ULONG *)(buffer + 0x4) == WDT_REMOTE_CALL, "Context should be WDT_REMOTE_CALL instead of 0x%08x\n", *(ULONG *)buffer); + ok(*(ULONG *)(buffer + 0x8) == (ULONG)(ULONG_PTR)hBitmap, "wirestgm + 0x4 should be bitmap handle instead of 0x%08x\n", *(ULONG *)(buffer + 0x4)); + ok(*(ULONG *)(buffer + 0xc) == (ULONG)(ULONG_PTR)bitmap_size, "wirestgm + 0x8 should be bitmap size instead of 0x%08x\n", *(ULONG *)(buffer + 0x4)); + ok(!memcmp(buffer + 0x10, bitmap, header_size), "buffer mismatch\n"); + ok(!memcmp(buffer + 0x10 + header_size, bmp_bits, bitmap_size), "buffer mismatch\n"); + + init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL); + HBITMAP_UserUnmarshal(&umcb.Flags, buffer + 1, &hBitmap2); + ok(hBitmap2 != NULL, "Didn't unmarshal properly\n"); + HeapFree(GetProcessHeap(), 0, buffer); + + init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL); + HBITMAP_UserFree(&umcb.Flags, &hBitmap2); + DeleteObject(hBitmap); +} + struct obj { IDataObject IDataObject_iface; @@ -1344,6 +1422,7 @@ START_TEST(usrmarshal) test_marshal_HDC(); test_marshal_HICON(); test_marshal_HBRUSH(); + test_marshal_HBITMAP(); test_GetDataHere_Proxy();
7 years, 4 months
1
0
0
0
01/01: [OLE32] Sync with Wine 3.0. CORE-14225
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=2178977b544fe2737850b…
commit 2178977b544fe2737850b3590174ea1942865ecb Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Sat Jan 20 12:57:25 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Sat Jan 20 12:57:25 2018 +0100 [OLE32] Sync with Wine 3.0. CORE-14225 --- dll/win32/ole32/compobj.c | 70 +++-- dll/win32/ole32/compobj_private.h | 4 +- dll/win32/ole32/datacache.c | 627 +++++++++++++++++++++++++++----------- dll/win32/ole32/enumx.c | 16 +- dll/win32/ole32/enumx.h | 5 +- dll/win32/ole32/hglobalstream.c | 372 ++++++++++------------ dll/win32/ole32/rpc.c | 9 +- dll/win32/ole32/stg_prop.c | 52 +--- dll/win32/ole32/storage32.c | 4 +- dll/win32/ole32/storage32.h | 11 +- dll/win32/ole32/usrmarshal.c | 178 +++++++++-- media/doc/README.WINE | 2 +- 12 files changed, 827 insertions(+), 523 deletions(-) diff --git a/dll/win32/ole32/compobj.c b/dll/win32/ole32/compobj.c index cdadd0f349..fd912d4e73 100644 --- a/dll/win32/ole32/compobj.c +++ b/dll/win32/ole32/compobj.c @@ -1702,12 +1702,6 @@ HWND apartment_getwindow(const struct apartment *apt) return apt->win; } -void apartment_joinmta(void) -{ - apartment_addref(MTA); - COM_CurrentInfo()->apt = MTA; -} - static void COM_TlsDestroy(void) { struct oletls *info = NtCurrentTeb()->ReservedForOle; @@ -1812,6 +1806,40 @@ HRESULT WINAPI CoRevokeInitializeSpy(ULARGE_INTEGER cookie) return S_OK; } +HRESULT enter_apartment( struct oletls *info, DWORD model ) +{ + HRESULT hr = S_OK; + + if (!info->apt) + { + if (!apartment_get_or_create( model )) + return E_OUTOFMEMORY; + } + else if (!apartment_is_model( info->apt, model )) + { + WARN( "Attempt to change threading model of this apartment from %s to %s\n", + info->apt->multi_threaded ? "multi-threaded" : "apartment threaded", + model & COINIT_APARTMENTTHREADED ? "apartment threaded" : "multi-threaded" ); + return RPC_E_CHANGED_MODE; + } + else + hr = S_FALSE; + + info->inits++; + + return hr; +} + +void leave_apartment( struct oletls *info ) +{ + if (!--info->inits) + { + if (info->ole_inits) + WARN( "Uninitializing apartment while Ole is still initialized\n" ); + apartment_release( info->apt ); + info->apt = NULL; + } +} /****************************************************************************** * CoInitialize [OLE32.@] @@ -1870,8 +1898,7 @@ HRESULT WINAPI CoInitialize(LPVOID lpReserved) HRESULT WINAPI DECLSPEC_HOTPATCH CoInitializeEx(LPVOID lpReserved, DWORD dwCoInit) { struct oletls *info = COM_CurrentInfo(); - HRESULT hr = S_OK; - APARTMENT *apt; + HRESULT hr; TRACE("(%p, %x)\n", lpReserved, (int)dwCoInit); @@ -1900,24 +1927,7 @@ HRESULT WINAPI DECLSPEC_HOTPATCH CoInitializeEx(LPVOID lpReserved, DWORD dwCoIni if (info->spy) IInitializeSpy_PreInitialize(info->spy, dwCoInit, info->inits); - if (!(apt = info->apt)) - { - apt = apartment_get_or_create(dwCoInit); - if (!apt) return E_OUTOFMEMORY; - } - else if (!apartment_is_model(apt, dwCoInit)) - { - /* Changing the threading model after it's been set is illegal. If this warning is triggered by Wine - code then we are probably using the wrong threading model to implement that API. */ - ERR("Attempt to change threading model of this apartment from %s to %s\n", - apt->multi_threaded ? "multi-threaded" : "apartment threaded", - dwCoInit & COINIT_APARTMENTTHREADED ? "apartment threaded" : "multi-threaded"); - return RPC_E_CHANGED_MODE; - } - else - hr = S_FALSE; - - info->inits++; + hr = enter_apartment( info, dwCoInit ); if (info->spy) IInitializeSpy_PostInitialize(info->spy, hr, dwCoInit, info->inits); @@ -1964,13 +1974,7 @@ void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void) return; } - if (!--info->inits) - { - if (info->ole_inits) - WARN("uninitializing apartment while Ole is still initialized\n"); - apartment_release(info->apt); - info->apt = NULL; - } + leave_apartment( info ); /* * Decrease the reference count. diff --git a/dll/win32/ole32/compobj_private.h b/dll/win32/ole32/compobj_private.h index 672b39460b..c1739f57e9 100644 --- a/dll/win32/ole32/compobj_private.h +++ b/dll/win32/ole32/compobj_private.h @@ -233,8 +233,8 @@ static inline HRESULT apartment_getoxid(const struct apartment *apt, OXID *oxid) } HRESULT apartment_createwindowifneeded(struct apartment *apt) DECLSPEC_HIDDEN; HWND apartment_getwindow(const struct apartment *apt) DECLSPEC_HIDDEN; -void apartment_joinmta(void) DECLSPEC_HIDDEN; - +HRESULT enter_apartment(struct oletls *info, DWORD model) DECLSPEC_HIDDEN; +void leave_apartment(struct oletls *info) DECLSPEC_HIDDEN; /* DCOM messages used by the apartment window (not compatible with native) */ #define DM_EXECUTERPC (WM_USER + 0) /* WPARAM = 0, LPARAM = (struct dispatch_params *) */ diff --git a/dll/win32/ole32/datacache.c b/dll/win32/ole32/datacache.c index 8c3fe48e52..e3697761e0 100644 --- a/dll/win32/ole32/datacache.c +++ b/dll/win32/ole32/datacache.c @@ -64,7 +64,8 @@ typedef struct PresentationDataHeader * DWORD length; * CHAR format_name[length]; (null-terminated) */ - DWORD unknown3; /* 4, possibly TYMED_ISTREAM */ + DWORD tdSize; /* This is actually a truncated DVTARGETDEVICE, if tdSize > sizeof(DWORD) + then there are tdSize - sizeof(DWORD) more bytes before dvAspect */ DVASPECT dvAspect; DWORD lindex; DWORD advf; @@ -86,8 +87,6 @@ typedef struct DataCacheEntry struct list entry; /* format of this entry */ FORMATETC fmtetc; - /* the clipboard format of the data */ - CLIPFORMAT data_cf; /* cached data */ STGMEDIUM stgmedium; /* @@ -295,10 +294,10 @@ static DataCacheEntry *DataCache_GetEntryForFormatEtc(DataCache *This, const FOR LIST_FOR_EACH_ENTRY(cache_entry, &This->cache_list, DataCacheEntry, entry) { /* FIXME: also compare DVTARGETDEVICEs */ - if ((!cache_entry->fmtetc.cfFormat || !fmt.cfFormat || (fmt.cfFormat == cache_entry->fmtetc.cfFormat)) && + if ((fmt.cfFormat == cache_entry->fmtetc.cfFormat) && (fmt.dwAspect == cache_entry->fmtetc.dwAspect) && (fmt.lindex == cache_entry->fmtetc.lindex) && - (!cache_entry->fmtetc.tymed || !fmt.tymed || (fmt.tymed == cache_entry->fmtetc.tymed))) + ((fmt.tymed == cache_entry->fmtetc.tymed) || !cache_entry->fmtetc.cfFormat)) /* tymed is ignored for view caching */ return cache_entry; } return NULL; @@ -307,19 +306,23 @@ static DataCacheEntry *DataCache_GetEntryForFormatEtc(DataCache *This, const FOR /* checks that the clipformat and tymed are valid and returns an error if they * aren't and CACHE_S_NOTSUPPORTED if they are valid, but can't be rendered by * DataCache_Draw */ -static HRESULT check_valid_clipformat_and_tymed(CLIPFORMAT cfFormat, DWORD tymed) +static HRESULT check_valid_formatetc( const FORMATETC *fmt ) { - if (!cfFormat || !tymed || - (cfFormat == CF_METAFILEPICT && tymed == TYMED_MFPICT) || - (cfFormat == CF_BITMAP && tymed == TYMED_GDI) || - (cfFormat == CF_DIB && tymed == TYMED_HGLOBAL) || - (cfFormat == CF_ENHMETAFILE && tymed == TYMED_ENHMF)) + /* DVASPECT_ICON must be CF_METAFILEPICT */ + if (fmt->dwAspect == DVASPECT_ICON && fmt->cfFormat != CF_METAFILEPICT) + return DV_E_FORMATETC; + + if (!fmt->cfFormat || + (fmt->cfFormat == CF_METAFILEPICT && fmt->tymed == TYMED_MFPICT) || + (fmt->cfFormat == CF_BITMAP && fmt->tymed == TYMED_GDI) || + (fmt->cfFormat == CF_DIB && fmt->tymed == TYMED_HGLOBAL) || + (fmt->cfFormat == CF_ENHMETAFILE && fmt->tymed == TYMED_ENHMF)) return S_OK; - else if (tymed == TYMED_HGLOBAL) + else if (fmt->tymed == TYMED_HGLOBAL) return CACHE_S_FORMATETC_NOTSUPPORTED; else { - WARN("invalid clipformat/tymed combination: %d/%d\n", cfFormat, tymed); + WARN("invalid clipformat/tymed combination: %d/%d\n", fmt->cfFormat, fmt->tymed); return DV_E_TYMED; } } @@ -332,7 +335,6 @@ static BOOL init_cache_entry(DataCacheEntry *entry, const FORMATETC *fmt, DWORD hr = copy_formatetc(&entry->fmtetc, fmt); if (FAILED(hr)) return FALSE; - entry->data_cf = 0; entry->stgmedium.tymed = TYMED_NULL; entry->stgmedium.pUnkForRelease = NULL; entry->stream = NULL; @@ -353,7 +355,7 @@ static HRESULT DataCache_CreateEntry(DataCache *This, const FORMATETC *formatetc DWORD id = automatic ? 1 : This->last_cache_id; DataCacheEntry *entry; - hr = check_valid_clipformat_and_tymed(formatetc->cfFormat, formatetc->tymed); + hr = check_valid_formatetc( formatetc ); if (FAILED(hr)) return hr; if (hr == CACHE_S_FORMATETC_NOTSUPPORTED) @@ -454,6 +456,10 @@ static HRESULT read_clipformat(IStream *stream, CLIPFORMAT *clipformat) hr = IStream_Read(stream, &length, sizeof(length), &read); if (hr != S_OK || read != sizeof(length)) return DV_E_CLIPFORMAT; + if (!length) { + /* No clipboard format present */ + return S_OK; + } if (length == -1) { DWORD cf; @@ -483,11 +489,16 @@ static HRESULT write_clipformat(IStream *stream, CLIPFORMAT clipformat) { DWORD length; HRESULT hr; + char format_name[256]; if (clipformat < 0xc000) length = -1; else - length = GetClipboardFormatNameA(clipformat, NULL, 0); + { + length = GetClipboardFormatNameA(clipformat, format_name, sizeof(format_name)); + /* If there is a clipboard format name, we need to include its terminating \0 */ + if (length) length++; + } hr = IStream_Write(stream, &length, sizeof(length), NULL); if (FAILED(hr)) return hr; @@ -498,12 +509,7 @@ static HRESULT write_clipformat(IStream *stream, CLIPFORMAT clipformat) } else { - char *format_name = HeapAlloc(GetProcessHeap(), 0, length); - if (!format_name) - return E_OUTOFMEMORY; - GetClipboardFormatNameA(clipformat, format_name, length); hr = IStream_Write(stream, format_name, length, NULL); - HeapFree(GetProcessHeap(), 0, format_name); } return hr; } @@ -618,7 +624,6 @@ static HRESULT load_mf_pict( DataCacheEntry *cache_entry, IStream *stm ) GlobalUnlock( hmfpict ); if (SUCCEEDED( hr )) { - cache_entry->data_cf = cache_entry->fmtetc.cfFormat; cache_entry->stgmedium.tymed = TYMED_MFPICT; cache_entry->stgmedium.u.hMetaFilePict = hmfpict; } @@ -703,7 +708,6 @@ static HRESULT load_dib( DataCacheEntry *cache_entry, IStream *stm ) GlobalUnlock( hglobal ); - cache_entry->data_cf = cache_entry->fmtetc.cfFormat; cache_entry->stgmedium.tymed = TYMED_HGLOBAL; cache_entry->stgmedium.u.hGlobal = hglobal; @@ -756,112 +760,273 @@ static HRESULT DataCacheEntry_LoadData(DataCacheEntry *cache_entry) return hr; } -static HRESULT DataCacheEntry_CreateStream(DataCacheEntry *cache_entry, - IStorage *storage, IStream **stream) +static void init_stream_header(DataCacheEntry *entry, PresentationDataHeader *header) { - WCHAR wszName[] = {2,'O','l','e','P','r','e','s', - '0' + (cache_entry->stream_number / 100) % 10, - '0' + (cache_entry->stream_number / 10) % 10, - '0' + cache_entry->stream_number % 10, 0}; - - /* FIXME: cache the created stream in This? */ - return IStorage_CreateStream(storage, wszName, - STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE, - 0, 0, stream); + if (entry->fmtetc.ptd) + FIXME("ptd not serialized\n"); + header->tdSize = sizeof(header->tdSize); + header->dvAspect = entry->fmtetc.dwAspect; + header->lindex = entry->fmtetc.lindex; + header->advf = entry->advise_flags; + header->unknown7 = 0; + header->dwObjectExtentX = 0; + header->dwObjectExtentY = 0; + header->dwSize = 0; } -static HRESULT DataCacheEntry_Save(DataCacheEntry *cache_entry, IStorage *storage, - BOOL same_as_load) +static HRESULT save_dib(DataCacheEntry *entry, BOOL contents, IStream *stream) { - PresentationDataHeader header; - HRESULT hr; - IStream *pres_stream; - void *data = NULL; - - TRACE("stream_number = %d, fmtetc = %s\n", cache_entry->stream_number, debugstr_formatetc(&cache_entry->fmtetc)); + HRESULT hr = S_OK; + int data_size = 0; + BITMAPINFO *bmi = NULL; - hr = DataCacheEntry_CreateStream(cache_entry, storage, &pres_stream); - if (FAILED(hr)) - return hr; + if (entry->stgmedium.tymed != TYMED_NULL) + { + data_size = GlobalSize(entry->stgmedium.u.hGlobal); + bmi = GlobalLock(entry->stgmedium.u.hGlobal); + } - hr = write_clipformat(pres_stream, cache_entry->data_cf); - if (FAILED(hr)) - return hr; + if (!contents) + { + PresentationDataHeader header; - if (cache_entry->fmtetc.ptd) - FIXME("ptd not serialized\n"); - header.unknown3 = 4; - header.dvAspect = cache_entry->fmtetc.dwAspect; - header.lindex = cache_entry->fmtetc.lindex; - header.advf = cache_entry->advise_flags; - header.unknown7 = 0; - header.dwObjectExtentX = 0; - header.dwObjectExtentY = 0; - header.dwSize = 0; - - /* size the data */ - switch (cache_entry->data_cf) - { - case CF_METAFILEPICT: + init_stream_header(entry, &header); + hr = write_clipformat(stream, entry->fmtetc.cfFormat); + if (FAILED(hr)) goto end; + if (data_size) { - if (cache_entry->stgmedium.tymed != TYMED_NULL) + header.dwSize = data_size; + /* Size in units of 0.01mm (ie. MM_HIMETRIC) */ + if (bmi->bmiHeader.biXPelsPerMeter != 0 && bmi->bmiHeader.biYPelsPerMeter != 0) { - const METAFILEPICT *mfpict = GlobalLock(cache_entry->stgmedium.u.hMetaFilePict); - if (!mfpict) - { - IStream_Release(pres_stream); - return DV_E_STGMEDIUM; - } - header.dwObjectExtentX = mfpict->xExt; - header.dwObjectExtentY = mfpict->yExt; - header.dwSize = GetMetaFileBitsEx(mfpict->hMF, 0, NULL); - GlobalUnlock(cache_entry->stgmedium.u.hMetaFilePict); + header.dwObjectExtentX = MulDiv(bmi->bmiHeader.biWidth, 100000, bmi->bmiHeader.biXPelsPerMeter); + header.dwObjectExtentY = MulDiv(bmi->bmiHeader.biHeight, 100000, bmi->bmiHeader.biYPelsPerMeter); + } + else + { + HDC hdc = GetDC(0); + header.dwObjectExtentX = MulDiv(bmi->bmiHeader.biWidth, 2540, GetDeviceCaps(hdc, LOGPIXELSX)); + header.dwObjectExtentY = MulDiv(bmi->bmiHeader.biHeight, 2540, GetDeviceCaps(hdc, LOGPIXELSY)); + ReleaseDC(0, hdc); } - break; } - default: - break; + hr = IStream_Write(stream, &header, sizeof(PresentationDataHeader), NULL); + if (hr == S_OK && data_size) + hr = IStream_Write(stream, bmi, data_size, NULL); } - - /* - * Write the header. - */ - hr = IStream_Write(pres_stream, &header, sizeof(PresentationDataHeader), - NULL); - if (FAILED(hr)) + else if(data_size) { - IStream_Release(pres_stream); - return hr; + BITMAPFILEHEADER bmp_fhdr; + + bmp_fhdr.bfType = 0x4d42; + bmp_fhdr.bfSize = data_size + sizeof(BITMAPFILEHEADER); + bmp_fhdr.bfReserved1 = bmp_fhdr.bfReserved2 = 0; + bmp_fhdr.bfOffBits = bitmap_info_size(bmi, DIB_RGB_COLORS) + sizeof(BITMAPFILEHEADER); + hr = IStream_Write(stream, &bmp_fhdr, sizeof(BITMAPFILEHEADER), NULL); + if (hr == S_OK) + hr = IStream_Write(stream, bmi, data_size, NULL); } - /* get the data */ - switch (cache_entry->data_cf) +end: + if (bmi) GlobalUnlock(entry->stgmedium.u.hGlobal); + return hr; +} + +#include <pshpack2.h> +struct meta_placeable +{ + DWORD key; + WORD hwmf; + WORD bounding_box[4]; + WORD inch; + DWORD reserved; + WORD checksum; +}; +#include <poppack.h> + +static HRESULT save_mfpict(DataCacheEntry *entry, BOOL contents, IStream *stream) +{ + HRESULT hr = S_OK; + int data_size = 0; + void *data = NULL; + METAFILEPICT *mfpict = NULL; + + if (!contents) { - case CF_METAFILEPICT: + PresentationDataHeader header; + + init_stream_header(entry, &header); + hr = write_clipformat(stream, entry->fmtetc.cfFormat); + if (FAILED(hr)) return hr; + if (entry->stgmedium.tymed != TYMED_NULL) { - if (cache_entry->stgmedium.tymed != TYMED_NULL) + mfpict = GlobalLock(entry->stgmedium.u.hMetaFilePict); + if (!mfpict) + return DV_E_STGMEDIUM; + data_size = GetMetaFileBitsEx(mfpict->hMF, 0, NULL); + header.dwObjectExtentX = mfpict->xExt; + header.dwObjectExtentY = mfpict->yExt; + header.dwSize = data_size; + data = HeapAlloc(GetProcessHeap(), 0, header.dwSize); + if (!data) { - const METAFILEPICT *mfpict = GlobalLock(cache_entry->stgmedium.u.hMetaFilePict); - if (!mfpict) - { - IStream_Release(pres_stream); - return DV_E_STGMEDIUM; - } - data = HeapAlloc(GetProcessHeap(), 0, header.dwSize); - GetMetaFileBitsEx(mfpict->hMF, header.dwSize, data); - GlobalUnlock(cache_entry->stgmedium.u.hMetaFilePict); + GlobalUnlock(entry->stgmedium.u.hMetaFilePict); + return E_OUTOFMEMORY; } - break; + GetMetaFileBitsEx(mfpict->hMF, header.dwSize, data); + GlobalUnlock(entry->stgmedium.u.hMetaFilePict); } - default: - break; + hr = IStream_Write(stream, &header, sizeof(PresentationDataHeader), NULL); + if (hr == S_OK && data_size) + hr = IStream_Write(stream, data, data_size, NULL); + HeapFree(GetProcessHeap(), 0, data); } + else if (entry->stgmedium.tymed != TYMED_NULL) + { + struct meta_placeable meta_place_rec; + WORD *check; - if (data) - hr = IStream_Write(pres_stream, data, header.dwSize, NULL); - HeapFree(GetProcessHeap(), 0, data); + mfpict = GlobalLock(entry->stgmedium.u.hMetaFilePict); + if (!mfpict) + return DV_E_STGMEDIUM; + data_size = GetMetaFileBitsEx(mfpict->hMF, 0, NULL); + data = HeapAlloc(GetProcessHeap(), 0, data_size); + if (!data) + { + GlobalUnlock(entry->stgmedium.u.hMetaFilePict); + return E_OUTOFMEMORY; + } + GetMetaFileBitsEx(mfpict->hMF, data_size, data); + + /* units are in 1/8th of a point (1 point is 1/72th of an inch) */ + meta_place_rec.key = 0x9ac6cdd7; + meta_place_rec.hwmf = 0; + meta_place_rec.inch = 576; + meta_place_rec.bounding_box[0] = 0; + meta_place_rec.bounding_box[1] = 0; + meta_place_rec.bounding_box[2] = 0; + meta_place_rec.bounding_box[3] = 0; + meta_place_rec.checksum = 0; + meta_place_rec.reserved = 0; + + /* These values are rounded down so MulDiv won't do the right thing */ + meta_place_rec.bounding_box[2] = (LONGLONG)mfpict->xExt * meta_place_rec.inch / 2540; + meta_place_rec.bounding_box[3] = (LONGLONG)mfpict->yExt * meta_place_rec.inch / 2540; + GlobalUnlock(entry->stgmedium.u.hMetaFilePict); + + for (check = (WORD *)&meta_place_rec; check != (WORD *)&meta_place_rec.checksum; check++) + meta_place_rec.checksum ^= *check; + hr = IStream_Write(stream, &meta_place_rec, sizeof(struct meta_placeable), NULL); + if (hr == S_OK && data_size) + hr = IStream_Write(stream, data, data_size, NULL); + HeapFree(GetProcessHeap(), 0, data); + } + + return hr; +} + +static HRESULT save_emf(DataCacheEntry *entry, BOOL contents, IStream *stream) +{ + HRESULT hr = S_OK; + int data_size = 0; + BYTE *data; + + if (!contents) + { + PresentationDataHeader header; + METAFILEPICT *mfpict; + HDC hdc = GetDC(0); + + init_stream_header(entry, &header); + hr = write_clipformat(stream, entry->fmtetc.cfFormat); + if (FAILED(hr)) + { + ReleaseDC(0, hdc); + return hr; + } + data_size = GetWinMetaFileBits(entry->stgmedium.u.hEnhMetaFile, 0, NULL, MM_ANISOTROPIC, hdc); + header.dwSize = data_size; + data = HeapAlloc(GetProcessHeap(), 0, header.dwSize); + if (!data) + { + ReleaseDC(0, hdc); + return E_OUTOFMEMORY; + } + GetWinMetaFileBits(entry->stgmedium.u.hEnhMetaFile, header.dwSize, data, MM_ANISOTROPIC, hdc); + ReleaseDC(0, hdc); + mfpict = (METAFILEPICT *)data; + header.dwObjectExtentX = mfpict->xExt; + header.dwObjectExtentY = mfpict->yExt; + hr = IStream_Write(stream, &header, sizeof(PresentationDataHeader), NULL); + if (hr == S_OK && data_size) + hr = IStream_Write(stream, data, data_size, NULL); + HeapFree(GetProcessHeap(), 0, data); + } + else if (entry->stgmedium.tymed != TYMED_NULL) + { + data_size = GetEnhMetaFileBits(entry->stgmedium.u.hEnhMetaFile, 0, NULL); + data = HeapAlloc(GetProcessHeap(), 0, sizeof(DWORD) + sizeof(ENHMETAHEADER) + data_size); + if (!data) return E_OUTOFMEMORY; + *((DWORD *)data) = sizeof(ENHMETAHEADER); + GetEnhMetaFileBits(entry->stgmedium.u.hEnhMetaFile, data_size, data + sizeof(DWORD) + sizeof(ENHMETAHEADER)); + memcpy(data + sizeof(DWORD), data + sizeof(DWORD) + sizeof(ENHMETAHEADER), sizeof(ENHMETAHEADER)); + data_size += sizeof(DWORD) + sizeof(ENHMETAHEADER); + hr = IStream_Write(stream, data, data_size, NULL); + HeapFree(GetProcessHeap(), 0, data); + } - IStream_Release(pres_stream); + return hr; +} + +static const WCHAR CONTENTS[] = {'C','O','N','T','E','N','T','S',0}; +static HRESULT create_stream(DataCacheEntry *cache_entry, IStorage *storage, + BOOL contents, IStream **stream) +{ + WCHAR pres[] = {2,'O','l','e','P','r','e','s', + '0' + (cache_entry->stream_number / 100) % 10, + '0' + (cache_entry->stream_number / 10) % 10, + '0' + cache_entry->stream_number % 10, 0}; + const WCHAR *name; + + if (contents) + name = CONTENTS; + else + name = pres; + + return IStorage_CreateStream(storage, name, + STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE, + 0, 0, stream); +} + +static HRESULT DataCacheEntry_Save(DataCacheEntry *cache_entry, IStorage *storage, + BOOL same_as_load) +{ + HRESULT hr; + IStream *stream; + BOOL contents = (cache_entry->id == 1); + + TRACE("stream_number = %d, fmtetc = %s\n", cache_entry->stream_number, debugstr_formatetc(&cache_entry->fmtetc)); + + hr = create_stream(cache_entry, storage, contents, &stream); + if (FAILED(hr)) + return hr; + + switch (cache_entry->fmtetc.cfFormat) + { + case CF_DIB: + hr = save_dib(cache_entry, contents, stream); + break; + case CF_METAFILEPICT: + hr = save_mfpict(cache_entry, contents, stream); + break; + case CF_ENHMETAFILE: + hr = save_emf(cache_entry, contents, stream); + break; + default: + FIXME("got unsupported clipboard format %x\n", cache_entry->fmtetc.cfFormat); + } + + IStream_Release(stream); return hr; } @@ -904,12 +1069,12 @@ static HRESULT copy_stg_medium(CLIPFORMAT cf, STGMEDIUM *dest_stgm, return S_OK; } -static HGLOBAL synthesize_dib( HBITMAP bm ) +static HRESULT synthesize_dib( HBITMAP bm, STGMEDIUM *med ) { HDC hdc = GetDC( 0 ); BITMAPINFOHEADER header; BITMAPINFO *bmi; - HGLOBAL ret = 0; + HRESULT hr = E_FAIL; DWORD header_size; memset( &header, 0, sizeof(header) ); @@ -917,34 +1082,64 @@ static HGLOBAL synthesize_dib( HBITMAP bm ) if (!GetDIBits( hdc, bm, 0, 0, NULL, (BITMAPINFO *)&header, DIB_RGB_COLORS )) goto done; header_size = bitmap_info_size( (BITMAPINFO *)&header, DIB_RGB_COLORS ); - if (!(ret = GlobalAlloc( GMEM_MOVEABLE, header_size + header.biSizeImage ))) goto done; - bmi = GlobalLock( ret ); + if (!(med->u.hGlobal = GlobalAlloc( GMEM_MOVEABLE, header_size + header.biSizeImage ))) goto done; + bmi = GlobalLock( med->u.hGlobal ); memset( bmi, 0, header_size ); memcpy( bmi, &header, header.biSize ); GetDIBits( hdc, bm, 0, abs(header.biHeight), (char *)bmi + header_size, bmi, DIB_RGB_COLORS ); - GlobalUnlock( ret ); + GlobalUnlock( med->u.hGlobal ); + med->tymed = TYMED_HGLOBAL; + med->pUnkForRelease = NULL; + hr = S_OK; done: ReleaseDC( 0, hdc ); - return ret; + return hr; } -static HBITMAP synthesize_bitmap( HGLOBAL dib ) +static HRESULT synthesize_bitmap( HGLOBAL dib, STGMEDIUM *med ) { - HBITMAP ret = 0; + HRESULT hr = E_FAIL; BITMAPINFO *bmi; HDC hdc = GetDC( 0 ); if ((bmi = GlobalLock( dib ))) { /* FIXME: validate data size */ - ret = CreateDIBitmap( hdc, &bmi->bmiHeader, CBM_INIT, - (char *)bmi + bitmap_info_size( bmi, DIB_RGB_COLORS ), - bmi, DIB_RGB_COLORS ); + med->u.hBitmap = CreateDIBitmap( hdc, &bmi->bmiHeader, CBM_INIT, + (char *)bmi + bitmap_info_size( bmi, DIB_RGB_COLORS ), + bmi, DIB_RGB_COLORS ); GlobalUnlock( dib ); + med->tymed = TYMED_GDI; + med->pUnkForRelease = NULL; + hr = S_OK; } ReleaseDC( 0, hdc ); - return ret; + return hr; +} + +static HRESULT synthesize_emf( HMETAFILEPICT data, STGMEDIUM *med ) +{ + METAFILEPICT *pict; + HRESULT hr = E_FAIL; + UINT size; + void *bits; + + if (!(pict = GlobalLock( data ))) return hr; + + size = GetMetaFileBitsEx( pict->hMF, 0, NULL ); + if ((bits = HeapAlloc( GetProcessHeap(), 0, size ))) + { + GetMetaFileBitsEx( pict->hMF, size, bits ); + med->u.hEnhMetaFile = SetWinMetaFileBits( size, bits, NULL, pict ); + HeapFree( GetProcessHeap(), 0, bits ); + med->tymed = TYMED_ENHMF; + med->pUnkForRelease = NULL; + hr = S_OK; + } + + GlobalUnlock( data ); + return hr; } static HRESULT DataCacheEntry_SetData(DataCacheEntry *cache_entry, @@ -952,7 +1147,8 @@ static HRESULT DataCacheEntry_SetData(DataCacheEntry *cache_entry, STGMEDIUM *stgmedium, BOOL fRelease) { - STGMEDIUM dib_copy; + STGMEDIUM copy; + HRESULT hr; if ((!cache_entry->fmtetc.cfFormat && !formatetc->cfFormat) || (cache_entry->fmtetc.tymed == TYMED_NULL && formatetc->tymed == TYMED_NULL) || @@ -964,15 +1160,21 @@ static HRESULT DataCacheEntry_SetData(DataCacheEntry *cache_entry, cache_entry->dirty = TRUE; ReleaseStgMedium(&cache_entry->stgmedium); - cache_entry->data_cf = cache_entry->fmtetc.cfFormat ? cache_entry->fmtetc.cfFormat : formatetc->cfFormat; if (formatetc->cfFormat == CF_BITMAP) { - dib_copy.tymed = TYMED_HGLOBAL; - dib_copy.u.hGlobal = synthesize_dib( stgmedium->u.hBitmap ); - dib_copy.pUnkForRelease = NULL; + hr = synthesize_dib( stgmedium->u.hBitmap, © ); + if (FAILED(hr)) return hr; if (fRelease) ReleaseStgMedium(stgmedium); - stgmedium = &dib_copy; + stgmedium = © + fRelease = TRUE; + } + else if (formatetc->cfFormat == CF_METAFILEPICT && cache_entry->fmtetc.cfFormat == CF_ENHMETAFILE) + { + hr = synthesize_emf( stgmedium->u.hMetaFilePict, © ); + if (FAILED(hr)) return hr; + if (fRelease) ReleaseStgMedium(stgmedium); + stgmedium = © fRelease = TRUE; } @@ -982,8 +1184,7 @@ static HRESULT DataCacheEntry_SetData(DataCacheEntry *cache_entry, return S_OK; } else - return copy_stg_medium(cache_entry->data_cf, - &cache_entry->stgmedium, stgmedium); + return copy_stg_medium(cache_entry->fmtetc.cfFormat, &cache_entry->stgmedium, stgmedium); } static HRESULT DataCacheEntry_GetData(DataCacheEntry *cache_entry, FORMATETC *fmt, STGMEDIUM *stgmedium) @@ -998,19 +1199,14 @@ static HRESULT DataCacheEntry_GetData(DataCacheEntry *cache_entry, FORMATETC *fm return OLE_E_BLANK; if (fmt->cfFormat == CF_BITMAP) - { - stgmedium->tymed = TYMED_GDI; - stgmedium->u.hBitmap = synthesize_bitmap( cache_entry->stgmedium.u.hGlobal ); - stgmedium->pUnkForRelease = NULL; - return S_OK; - } - return copy_stg_medium(cache_entry->data_cf, stgmedium, &cache_entry->stgmedium); + return synthesize_bitmap( cache_entry->stgmedium.u.hGlobal, stgmedium ); + + return copy_stg_medium(cache_entry->fmtetc.cfFormat, stgmedium, &cache_entry->stgmedium); } static inline HRESULT DataCacheEntry_DiscardData(DataCacheEntry *cache_entry) { ReleaseStgMedium(&cache_entry->stgmedium); - cache_entry->data_cf = cache_entry->fmtetc.cfFormat; return S_OK; } @@ -1108,7 +1304,10 @@ static HRESULT WINAPI DataCache_NDIUnknown_QueryInterface( if (IsEqualIID(&IID_IUnknown, riid)) { - *ppvObject = iface; + if (this->outer_unk == iface) /* non-aggregated, return IUnknown from IOleCache2 */ + *ppvObject = &this->IOleCache2_iface; + else + *ppvObject = iface; } else if (IsEqualIID(&IID_IDataObject, riid)) { @@ -1230,6 +1429,8 @@ static HRESULT WINAPI DataCache_GetData( DataCache *This = impl_from_IDataObject(iface); DataCacheEntry *cache_entry; + TRACE("(%p, %s, %p)\n", iface, debugstr_formatetc(pformatetcIn), pmedium); + memset(pmedium, 0, sizeof(*pmedium)); cache_entry = DataCache_GetEntryForFormatEtc(This, pformatetcIn); @@ -1561,8 +1762,6 @@ static HRESULT parse_contents_stream( DataCache *This, IStorage *stg, IStream *s return add_cache_entry( This, fmt, 0, stm, contents_stream ); } -static const WCHAR CONTENTS[] = {'C','O','N','T','E','N','T','S',0}; - /************************************************************************ * DataCache_Load (IPersistStorage) * @@ -1621,35 +1820,14 @@ static HRESULT WINAPI DataCache_Load( IPersistStorage *iface, IStorage *pStg ) * our responsibility to copy the information when saving to a new * storage. */ -static HRESULT WINAPI DataCache_Save( - IPersistStorage* iface, - IStorage* pStg, - BOOL fSameAsLoad) +static HRESULT WINAPI DataCache_Save(IPersistStorage* iface, IStorage *stg, BOOL same_as_load) { DataCache *This = impl_from_IPersistStorage(iface); DataCacheEntry *cache_entry; - BOOL dirty = FALSE; HRESULT hr = S_OK; unsigned short stream_number = 0; - TRACE("(%p, %p, %d)\n", iface, pStg, fSameAsLoad); - - dirty = This->dirty; - if (!dirty) - { - LIST_FOR_EACH_ENTRY(cache_entry, &This->cache_list, DataCacheEntry, entry) - { - dirty = cache_entry->dirty; - if (dirty) - break; - } - } - - /* this is a shortcut if nothing changed */ - if (!dirty && !fSameAsLoad && This->presentationStorage) - { - return IStorage_CopyTo(This->presentationStorage, 0, NULL, NULL, pStg); - } + TRACE("(%p, %p, %d)\n", iface, stg, same_as_load); /* assign stream numbers to the cache entries */ LIST_FOR_EACH_ENTRY(cache_entry, &This->cache_list, DataCacheEntry, entry) @@ -1665,17 +1843,17 @@ static HRESULT WINAPI DataCache_Save( /* write out the cache entries */ LIST_FOR_EACH_ENTRY(cache_entry, &This->cache_list, DataCacheEntry, entry) { - if (!fSameAsLoad || cache_entry->dirty) + if (!same_as_load || cache_entry->dirty) { - hr = DataCacheEntry_Save(cache_entry, pStg, fSameAsLoad); + hr = DataCacheEntry_Save(cache_entry, stg, same_as_load); if (FAILED(hr)) break; - cache_entry->dirty = FALSE; + if (same_as_load) cache_entry->dirty = FALSE; } } - This->dirty = FALSE; + if (same_as_load) This->dirty = FALSE; return hr; } @@ -1826,7 +2004,7 @@ static HRESULT WINAPI DataCache_Draw( if (pfnContinue && !pfnContinue(dwContinue)) return E_ABORT; - switch (cache_entry->data_cf) + switch (cache_entry->fmtetc.cfFormat) { case CF_METAFILEPICT: { @@ -2085,7 +2263,7 @@ static HRESULT WINAPI DataCache_GetExtent( continue; - switch (cache_entry->data_cf) + switch (cache_entry->fmtetc.cfFormat) { case CF_METAFILEPICT: { @@ -2231,6 +2409,13 @@ static HRESULT WINAPI DataCache_Cache( fmt_cpy.tymed = TYMED_HGLOBAL; } + /* View caching DVASPECT_ICON gets converted to CF_METAFILEPICT */ + if (fmt_cpy.dwAspect == DVASPECT_ICON && fmt_cpy.cfFormat == 0) + { + fmt_cpy.cfFormat = CF_METAFILEPICT; + fmt_cpy.tymed = TYMED_MFPICT; + } + *pdwConnection = 0; cache_entry = DataCache_GetEntryForFormatEtc(This, &fmt_cpy); @@ -2327,12 +2512,10 @@ fail: return hr; } -static HRESULT WINAPI DataCache_InitCache( - IOleCache2* iface, - IDataObject* pDataObject) +static HRESULT WINAPI DataCache_InitCache( IOleCache2 *iface, IDataObject *data ) { - FIXME("stub\n"); - return E_NOTIMPL; + TRACE( "(%p %p)\n", iface, data ); + return IOleCache2_UpdateCache( iface, data, UPDFCACHE_ALLBUTNODATACACHE, NULL ); } static HRESULT WINAPI DataCache_IOleCache2_SetData( @@ -2364,14 +2547,102 @@ static HRESULT WINAPI DataCache_IOleCache2_SetData( return OLE_E_BLANK; } -static HRESULT WINAPI DataCache_UpdateCache( - IOleCache2* iface, - LPDATAOBJECT pDataObject, - DWORD grfUpdf, - LPVOID pReserved) +static BOOL entry_updatable( DataCacheEntry *entry, DWORD mode ) { - FIXME("(%p, 0x%x, %p): stub\n", pDataObject, grfUpdf, pReserved); - return E_NOTIMPL; + BOOL is_blank = entry->stgmedium.tymed == TYMED_NULL; + + if ((mode & UPDFCACHE_ONLYIFBLANK) && !is_blank) return FALSE; + + if ((mode & UPDFCACHE_NODATACACHE) && (entry->advise_flags & ADVF_NODATA)) return TRUE; + if ((mode & UPDFCACHE_ONSAVECACHE) && (entry->advise_flags & ADVFCACHE_ONSAVE)) return TRUE; + if ((mode & UPDFCACHE_ONSTOPCACHE) && (entry->advise_flags & ADVF_DATAONSTOP)) return TRUE; + if ((mode & UPDFCACHE_NORMALCACHE) && (entry->advise_flags == 0)) return TRUE; + if ((mode & UPDFCACHE_IFBLANK) && (is_blank && !(entry->advise_flags & ADVF_NODATA))) return TRUE; + + return FALSE; +} + +static HRESULT WINAPI DataCache_UpdateCache( IOleCache2 *iface, IDataObject *data, + DWORD mode, void *reserved ) +{ + DataCache *This = impl_from_IOleCache2(iface); + DataCacheEntry *cache_entry; + STGMEDIUM med; + HRESULT hr = S_OK; + CLIPFORMAT view_list[] = { CF_METAFILEPICT, CF_ENHMETAFILE, CF_DIB, CF_BITMAP }; + FORMATETC fmt; + int i, slots = 0; + BOOL done_one = FALSE; + + TRACE( "(%p %p %08x %p)\n", iface, data, mode, reserved ); + + LIST_FOR_EACH_ENTRY( cache_entry, &This->cache_list, DataCacheEntry, entry ) + { + slots++; + + if (!entry_updatable( cache_entry, mode )) + { + done_one = TRUE; + continue; + } + + fmt = cache_entry->fmtetc; + + if (fmt.cfFormat) + { + hr = IDataObject_GetData( data, &fmt, &med ); + if (hr != S_OK && fmt.cfFormat == CF_DIB) + { + fmt.cfFormat = CF_BITMAP; + fmt.tymed = TYMED_GDI; + hr = IDataObject_GetData( data, &fmt, &med ); + } + if (hr != S_OK && fmt.cfFormat == CF_ENHMETAFILE) + { + fmt.cfFormat = CF_METAFILEPICT; + fmt.tymed = TYMED_MFPICT; + hr = IDataObject_GetData( data, &fmt, &med ); + } + if (hr == S_OK) + { + hr = DataCacheEntry_SetData( cache_entry, &fmt, &med, TRUE ); + if (hr != S_OK) ReleaseStgMedium( &med ); + else done_one = TRUE; + } + } + else + { + for (i = 0; i < sizeof(view_list) / sizeof(view_list[0]); i++) + { + fmt.cfFormat = view_list[i]; + fmt.tymed = tymed_from_cf( fmt.cfFormat ); + hr = IDataObject_QueryGetData( data, &fmt ); + if (hr == S_OK) + { + hr = IDataObject_GetData( data, &fmt, &med ); + if (hr == S_OK) + { + if (fmt.cfFormat == CF_BITMAP) + { + cache_entry->fmtetc.cfFormat = CF_DIB; + cache_entry->fmtetc.tymed = TYMED_HGLOBAL; + } + else + { + cache_entry->fmtetc.cfFormat = fmt.cfFormat; + cache_entry->fmtetc.tymed = fmt.tymed; + } + hr = DataCacheEntry_SetData( cache_entry, &fmt, &med, TRUE ); + if (hr != S_OK) ReleaseStgMedium( &med ); + else done_one = TRUE; + break; + } + } + } + } + } + + return (!slots || done_one) ? S_OK : CACHE_E_NOCACHE_UPDATED; } static HRESULT WINAPI DataCache_DiscardCache( diff --git a/dll/win32/ole32/enumx.c b/dll/win32/ole32/enumx.c index 3af0cd19ff..7399a0214e 100644 --- a/dll/win32/ole32/enumx.c +++ b/dll/win32/ole32/enumx.c @@ -30,8 +30,6 @@ struct tagEnumSTATPROPSETSTG_impl struct list *current; ULONG elem_size; GUID riid; - IUnknown *parent; - enumx_copy_cb copy_cb; }; /************************************************************************ @@ -82,7 +80,6 @@ ULONG WINAPI enumx_Release(enumx_impl *This) list_remove(x); HeapFree(GetProcessHeap(), 0, x); } - IUnknown_Release(This->parent); HeapFree(GetProcessHeap(), 0, This); } return ref; @@ -104,10 +101,7 @@ HRESULT WINAPI enumx_Next(enumx_impl *This, ULONG celt, p = rgelt; while (count < celt && This->current && This->current != &This->elements) { - if (This->copy_cb) - This->copy_cb(This->parent, &This->current[1], p); - else - memcpy(p, &This->current[1], This->elem_size); + memcpy(p, &This->current[1], This->elem_size); p += This->elem_size; This->current = This->current->next; count++; @@ -164,8 +158,7 @@ HRESULT WINAPI enumx_Clone( * * Allocate a generic enumerator */ -enumx_impl *enumx_allocate(REFIID riid, const void *vtbl, ULONG elem_size, - IUnknown *parent, enumx_copy_cb copy_cb) +enumx_impl *enumx_allocate(REFIID riid, const void *vtbl, ULONG elem_size) { enumx_impl *enumx; @@ -177,11 +170,6 @@ enumx_impl *enumx_allocate(REFIID riid, const void *vtbl, ULONG elem_size, enumx->current = NULL; enumx->elem_size = elem_size; enumx->riid = *riid; - enumx->parent = parent; - enumx->copy_cb = copy_cb; - - IUnknown_AddRef(parent); - list_init(&enumx->elements); } diff --git a/dll/win32/ole32/enumx.h b/dll/win32/ole32/enumx.h index 6f784e140a..d4347d9e33 100644 --- a/dll/win32/ole32/enumx.h +++ b/dll/win32/ole32/enumx.h @@ -21,8 +21,6 @@ typedef struct tagEnumSTATPROPSETSTG_impl enumx_impl; -typedef void (*enumx_copy_cb)(IUnknown *parent, void *orig, void *dest); - extern HRESULT WINAPI enumx_QueryInterface(enumx_impl *, REFIID, void**) DECLSPEC_HIDDEN; extern ULONG WINAPI enumx_AddRef(enumx_impl *) DECLSPEC_HIDDEN; extern ULONG WINAPI enumx_Release(enumx_impl *) DECLSPEC_HIDDEN; @@ -30,8 +28,7 @@ extern HRESULT WINAPI enumx_Next(enumx_impl *, ULONG, void *, ULONG *) DECLSPEC_ extern HRESULT WINAPI enumx_Skip(enumx_impl *, ULONG) DECLSPEC_HIDDEN; extern HRESULT WINAPI enumx_Reset(enumx_impl *) DECLSPEC_HIDDEN; extern HRESULT WINAPI enumx_Clone(enumx_impl *, enumx_impl **) DECLSPEC_HIDDEN; -extern enumx_impl *enumx_allocate(REFIID, const void *, ULONG, - IUnknown *, enumx_copy_cb) DECLSPEC_HIDDEN; +extern enumx_impl *enumx_allocate(REFIID, const void *, ULONG) DECLSPEC_HIDDEN; extern void *enumx_add_element(enumx_impl *, const void *) DECLSPEC_HIDDEN; #endif /* __OLE_ENUM_H__ */ diff --git a/dll/win32/ole32/hglobalstream.c b/dll/win32/ole32/hglobalstream.c index 6a82b716f1..732e6c6c81 100644 --- a/dll/win32/ole32/hglobalstream.c +++ b/dll/win32/ole32/hglobalstream.c @@ -5,7 +5,6 @@ * for streams contained supported by an HGLOBAL pointer. * * Copyright 1999 Francis Beaudet - * Copyright 2016 Dmitry Timoshkov * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -24,158 +23,7 @@ #include "precomp.h" -WINE_DEFAULT_DEBUG_CHANNEL(hglobalstream); - -struct handle_wrapper -{ - LONG ref; - HGLOBAL hglobal; - ULONG size; - BOOL delete_on_release; - CRITICAL_SECTION lock; -}; - -static void handle_addref(struct handle_wrapper *handle) -{ - InterlockedIncrement(&handle->ref); -} - -static void handle_release(struct handle_wrapper *handle) -{ - ULONG ref = InterlockedDecrement(&handle->ref); - - if (!ref) - { - if (handle->delete_on_release) - { - GlobalFree(handle->hglobal); - handle->hglobal = NULL; - } - - handle->lock.DebugInfo->Spare[0] = 0; - DeleteCriticalSection(&handle->lock); - HeapFree(GetProcessHeap(), 0, handle); - } -} - -static ULONG handle_read(struct handle_wrapper *handle, ULONG *pos, void *dest, ULONG len) -{ - void *source; - - EnterCriticalSection(&handle->lock); - - if (*pos < handle->size) - len = min(handle->size - *pos, len); - else - len = 0; - - source = GlobalLock(handle->hglobal); - if (source) - { - memcpy(dest, (char *)source + *pos, len); - *pos += len; - GlobalUnlock(handle->hglobal); - } - else - { - WARN("read from invalid hglobal %p\n", handle->hglobal); - len = 0; - } - - LeaveCriticalSection(&handle->lock); - return len; -} - -static ULONG handle_write(struct handle_wrapper *handle, ULONG *pos, const void *source, ULONG len) -{ - void *dest; - - if (!len) - return 0; - - EnterCriticalSection(&handle->lock); - - if (*pos + len > handle->size) - { - HGLOBAL hglobal = GlobalReAlloc(handle->hglobal, *pos + len, GMEM_MOVEABLE); - if (hglobal) - { - handle->hglobal = hglobal; - handle->size = *pos + len; - } - else - { - len = 0; - goto done; - } - } - - dest = GlobalLock(handle->hglobal); - if (dest) - { - memcpy((char *)dest + *pos, source, len); - *pos += len; - GlobalUnlock(handle->hglobal); - } - else - { - WARN("write to invalid hglobal %p\n", handle->hglobal); - /* len = 0; */ - } - -done: - LeaveCriticalSection(&handle->lock); - return len; -} - -static HGLOBAL handle_gethglobal(struct handle_wrapper *handle) -{ - return handle->hglobal; -} - -static HRESULT handle_setsize(struct handle_wrapper *handle, ULONG size) -{ - HRESULT hr = S_OK; - - EnterCriticalSection(&handle->lock); - - if (handle->size != size) - { - HGLOBAL hglobal = GlobalReAlloc(handle->hglobal, size, GMEM_MOVEABLE); - if (hglobal) - { - handle->hglobal = hglobal; - handle->size = size; - } - else - hr = E_OUTOFMEMORY; - } - - LeaveCriticalSection(&handle->lock); - return hr; -} - -static ULONG handle_getsize(struct handle_wrapper *handle) -{ - return handle->size; -} - -static struct handle_wrapper *handle_create(HGLOBAL hglobal, BOOL delete_on_release) -{ - struct handle_wrapper *handle; - - handle = HeapAlloc(GetProcessHeap(), 0, sizeof(*handle)); - if (handle) - { - handle->ref = 1; - handle->hglobal = hglobal; - handle->size = GlobalSize(hglobal); - handle->delete_on_release = delete_on_release; - InitializeCriticalSection(&handle->lock); - handle->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": handle_wrapper.lock"); - } - return handle; -} +WINE_DEFAULT_DEBUG_CHANNEL(storage); /**************************************************************************** * HGLOBALStreamImpl definition. @@ -188,7 +36,14 @@ typedef struct IStream IStream_iface; LONG ref; - struct handle_wrapper *handle; + /* support for the stream */ + HGLOBAL supportHandle; + + /* if TRUE the HGLOBAL is destroyed when the stream is finally released */ + BOOL deleteOnRelease; + + /* size of the stream */ + ULARGE_INTEGER streamSize; /* current position of the cursor */ ULARGE_INTEGER currentPosition; @@ -240,7 +95,12 @@ static ULONG WINAPI HGLOBALStreamImpl_Release( if (!ref) { - handle_release(This->handle); + if (This->deleteOnRelease) + { + GlobalFree(This->supportHandle); + This->supportHandle = NULL; + } + HeapFree(GetProcessHeap(), 0, This); } @@ -263,12 +123,59 @@ static HRESULT WINAPI HGLOBALStreamImpl_Read( ULONG* pcbRead) /* [out] */ { HGLOBALStreamImpl* This = impl_from_IStream(iface); - ULONG num_bytes; - TRACE("(%p, %p, %d, %p)\n", iface, pv, cb, pcbRead); + void* supportBuffer; + ULONG bytesReadBuffer; + ULONG bytesToReadFromBuffer; + + TRACE("(%p, %p, %d, %p)\n", iface, + pv, cb, pcbRead); + + /* + * If the caller is not interested in the number of bytes read, + * we use another buffer to avoid "if" statements in the code. + */ + if (pcbRead==0) + pcbRead = &bytesReadBuffer; + + /* + * Using the known size of the stream, calculate the number of bytes + * to read from the block chain + */ + bytesToReadFromBuffer = min( This->streamSize.u.LowPart - This->currentPosition.u.LowPart, cb); + + /* + * Lock the buffer in position and copy the data. + */ + supportBuffer = GlobalLock(This->supportHandle); + if (!supportBuffer) + { + WARN("read from invalid hglobal %p\n", This->supportHandle); + *pcbRead = 0; + return S_OK; + } + + memcpy(pv, (char *) supportBuffer+This->currentPosition.u.LowPart, bytesToReadFromBuffer); - num_bytes = handle_read(This->handle, &This->currentPosition.u.LowPart, pv, cb); - if (pcbRead) *pcbRead = num_bytes; + /* + * Move the current position to the new position + */ + This->currentPosition.u.LowPart+=bytesToReadFromBuffer; + + /* + * Return the number of bytes read. + */ + *pcbRead = bytesToReadFromBuffer; + + /* + * Cleanup + */ + GlobalUnlock(This->supportHandle); + + /* + * Always returns S_OK even if the end of the stream is reached before the + * buffer is filled + */ return S_OK; } @@ -290,14 +197,71 @@ static HRESULT WINAPI HGLOBALStreamImpl_Write( ULONG* pcbWritten) /* [out] */ { HGLOBALStreamImpl* This = impl_from_IStream(iface); - ULONG num_bytes; + + void* supportBuffer; + ULARGE_INTEGER newSize; + ULONG bytesWritten = 0; TRACE("(%p, %p, %d, %p)\n", iface, pv, cb, pcbWritten); - num_bytes = handle_write(This->handle, &This->currentPosition.u.LowPart, pv, cb); - if (pcbWritten) *pcbWritten = num_bytes; + /* + * 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); - return (num_bytes < cb) ? E_OUTOFMEMORY : S_OK; + /* + * 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; } /*** @@ -335,7 +299,7 @@ static HRESULT WINAPI HGLOBALStreamImpl_Seek( case STREAM_SEEK_CUR: break; case STREAM_SEEK_END: - newPosition.QuadPart = handle_getsize(This->handle); + newPosition = This->streamSize; break; default: hr = STG_E_SEEKERROR; @@ -380,13 +344,29 @@ static HRESULT WINAPI HGLOBALStreamImpl_SetSize( ULARGE_INTEGER libNewSize) /* [in] */ { HGLOBALStreamImpl* This = impl_from_IStream(iface); + HGLOBAL supportHandle; TRACE("(%p, %d)\n", iface, libNewSize.u.LowPart); /* * HighPart is ignored as shown in tests */ - return handle_setsize(This->handle, libNewSize.u.LowPart); + + if (This->streamSize.u.LowPart == libNewSize.u.LowPart) + return S_OK; + + /* + * Re allocate the HGlobal to fit the new size of the stream. + */ + supportHandle = GlobalReAlloc(This->supportHandle, libNewSize.u.LowPart, 0); + + if (supportHandle == 0) + return E_OUTOFMEMORY; + + This->supportHandle = supportHandle; + This->streamSize.u.LowPart = libNewSize.u.LowPart; + + return S_OK; } /*** @@ -534,49 +514,24 @@ static HRESULT WINAPI HGLOBALStreamImpl_Stat( pstatstg->pwcsName = NULL; pstatstg->type = STGTY_STREAM; - pstatstg->cbSize.QuadPart = handle_getsize(This->handle); + pstatstg->cbSize = This->streamSize; return S_OK; } -static const IStreamVtbl HGLOBALStreamImplVtbl; - -static HGLOBALStreamImpl *HGLOBALStreamImpl_Create(void) -{ - HGLOBALStreamImpl *This; - - This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This)); - if (This) - { - This->IStream_iface.lpVtbl = &HGLOBALStreamImplVtbl; - This->ref = 1; - } - return This; -} - static HRESULT WINAPI HGLOBALStreamImpl_Clone( IStream* iface, IStream** ppstm) /* [out] */ { HGLOBALStreamImpl* This = impl_from_IStream(iface); - HGLOBALStreamImpl* clone; ULARGE_INTEGER dummy; LARGE_INTEGER offset; + HRESULT hr; - if (!ppstm) return E_INVALIDARG; - - *ppstm = NULL; - - TRACE(" Cloning %p (seek position=%d)\n", iface, This->currentPosition.u.LowPart); - - clone = HGLOBALStreamImpl_Create(); - if (!clone) return E_OUTOFMEMORY; - - *ppstm = &clone->IStream_iface; - - handle_addref(This->handle); - clone->handle = This->handle; - + TRACE(" Cloning %p (deleteOnRelease=%d seek position=%ld)\n",iface,This->deleteOnRelease,(long)This->currentPosition.QuadPart); + hr = CreateStreamOnHGlobal(This->supportHandle, FALSE, ppstm); + if(FAILED(hr)) + return hr; offset.QuadPart = (LONGLONG)This->currentPosition.QuadPart; IStream_Seek(*ppstm, offset, STREAM_SEEK_SET, &dummy); return S_OK; @@ -613,19 +568,28 @@ HRESULT WINAPI CreateStreamOnHGlobal( if (!ppstm) return E_INVALIDARG; - This = HGLOBALStreamImpl_Create(); + This = HeapAlloc(GetProcessHeap(), 0, sizeof(HGLOBALStreamImpl)); if (!This) return E_OUTOFMEMORY; - /* allocate a handle if one is not supplied */ - if (!hGlobal) - hGlobal = GlobalAlloc(GMEM_MOVEABLE|GMEM_NODISCARD|GMEM_SHARE, 0); + This->IStream_iface.lpVtbl = &HGLOBALStreamImplVtbl; + This->ref = 1; + + /* initialize the support */ + This->supportHandle = hGlobal; + This->deleteOnRelease = fDeleteOnRelease; - This->handle = handle_create(hGlobal, fDeleteOnRelease); + /* allocate a handle if one is not supplied */ + if (!This->supportHandle) + This->supportHandle = GlobalAlloc(GMEM_MOVEABLE|GMEM_NODISCARD|GMEM_SHARE, 0); /* start at the beginning */ This->currentPosition.u.HighPart = 0; This->currentPosition.u.LowPart = 0; + /* initialize the size of the stream to the size of the handle */ + This->streamSize.u.HighPart = 0; + This->streamSize.u.LowPart = GlobalSize(This->supportHandle); + *ppstm = &This->IStream_iface; return S_OK; @@ -638,16 +602,16 @@ HRESULT WINAPI GetHGlobalFromStream(IStream* pstm, HGLOBAL* phglobal) { HGLOBALStreamImpl* pStream; - if (!pstm || !phglobal) + if (pstm == NULL) return E_INVALIDARG; - pStream = impl_from_IStream(pstm); + pStream = (HGLOBALStreamImpl*) pstm; /* * Verify that the stream object was created with CreateStreamOnHGlobal. */ if (pStream->IStream_iface.lpVtbl == &HGLOBALStreamImplVtbl) - *phglobal = handle_gethglobal(pStream->handle); + *phglobal = pStream->supportHandle; else { *phglobal = 0; diff --git a/dll/win32/ole32/rpc.c b/dll/win32/ole32/rpc.c index 985c622ac6..eb1bf5bb74 100644 --- a/dll/win32/ole32/rpc.c +++ b/dll/win32/ole32/rpc.c @@ -1474,16 +1474,17 @@ static void __RPC_STUB dispatch_rpc(RPC_MESSAGE *msg) else { BOOL joined = FALSE; - if (!COM_CurrentInfo()->apt) + struct oletls *info = COM_CurrentInfo(); + + if (!info->apt) { - apartment_joinmta(); + enter_apartment(info, COINIT_MULTITHREADED); joined = TRUE; } RPC_ExecuteCall(params); if (joined) { - apartment_release(COM_CurrentInfo()->apt); - COM_CurrentInfo()->apt = NULL; + leave_apartment(info); } } diff --git a/dll/win32/ole32/stg_prop.c b/dll/win32/ole32/stg_prop.c index aca47c8cd4..a9308d68da 100644 --- a/dll/win32/ole32/stg_prop.c +++ b/dll/win32/ole32/stg_prop.c @@ -1004,18 +1004,15 @@ static HRESULT PropertyStorage_ReadDictionary(PropertyStorage_impl *This, if (This->codePage != CP_UNICODE) ptr[cbEntry - 1] = '\0'; else - ((LPWSTR)ptr)[cbEntry - 1] = 0; + *((LPWSTR)ptr + cbEntry / sizeof(WCHAR)) = '\0'; hr = PropertyStorage_StoreNameWithId(This, (char*)ptr, This->codePage, propid); if (This->codePage == CP_UNICODE) { - /* cbEntry is the number of characters */ - cbEntry *= 2; - /* Unicode entries are padded to DWORD boundaries */ if (cbEntry % sizeof(DWORD)) ptr += sizeof(DWORD) - (cbEntry % sizeof(DWORD)); } - ptr += cbEntry; + ptr += sizeof(DWORD) + cbEntry; } return hr; } @@ -1056,10 +1053,6 @@ static HRESULT PropertyStorage_ReadProperty(PROPVARIANT *prop, const BYTE *data, prop->u.bVal = *data; TRACE("Read byte 0x%x\n", prop->u.bVal); break; - case VT_BOOL: - StorageUtl_ReadWord(data, 0, (WORD*)&prop->u.boolVal); - TRACE("Read bool %d\n", prop->u.boolVal); - break; case VT_I2: StorageUtl_ReadWord(data, 0, (WORD*)&prop->u.iVal); TRACE("Read short %d\n", prop->u.iVal); @@ -1078,18 +1071,6 @@ static HRESULT PropertyStorage_ReadProperty(PROPVARIANT *prop, const BYTE *data, StorageUtl_ReadDWord(data, 0, &prop->u.ulVal); TRACE("Read ulong %d\n", prop->u.ulVal); break; - case VT_I8: - StorageUtl_ReadULargeInteger(data, 0, (ULARGE_INTEGER *)&prop->u.hVal); - TRACE("Read long long %s\n", wine_dbgstr_longlong(prop->u.hVal.QuadPart)); - break; - case VT_UI8: - StorageUtl_ReadULargeInteger(data, 0, &prop->u.uhVal); - TRACE("Read ulong long %s\n", wine_dbgstr_longlong(prop->u.uhVal.QuadPart)); - break; - case VT_R8: - memcpy(&prop->u.dblVal, data, sizeof(double)); - TRACE("Read double %f\n", prop->u.dblVal); - break; case VT_LPSTR: { DWORD count; @@ -2383,9 +2364,7 @@ static HRESULT create_EnumSTATPROPSETSTG( enumx = enumx_allocate(&IID_IEnumSTATPROPSETSTG, &IEnumSTATPROPSETSTG_Vtbl, - sizeof (STATPROPSETSTG), - (IUnknown*)&This->base.IStorage_iface, - NULL); + sizeof (STATPROPSETSTG)); /* add all the property set elements into a list */ r = IStorage_EnumElements(stg, 0, NULL, 0, &penum); @@ -2478,27 +2457,6 @@ static HRESULT WINAPI IEnumSTATPROPSTG_fnClone( return enumx_Clone((enumx_impl*)iface, (enumx_impl**)ppenum); } -static void prop_enum_copy_cb(IUnknown *parent, void *orig, void *dest) -{ - PropertyStorage_impl *storage = impl_from_IPropertyStorage((IPropertyStorage*)parent); - STATPROPSTG *src_prop = orig; - STATPROPSTG *dest_prop = dest; - LPWSTR name; - - dest_prop->propid = src_prop->propid; - dest_prop->vt = src_prop->vt; - dest_prop->lpwstrName = NULL; - - if (dictionary_find(storage->propid_to_name, UlongToPtr(src_prop->propid), (void**)&name)) - { - DWORD size = (strlenW(name) + 1) * sizeof(WCHAR); - - dest_prop->lpwstrName = CoTaskMemAlloc(size); - if (!dest_prop->lpwstrName) return; - memcpy(dest_prop->lpwstrName, name, size); - } -} - static BOOL prop_enum_stat(const void *k, const void *v, void *extra, void *arg) { enumx_impl *enumx = arg; @@ -2525,9 +2483,7 @@ static HRESULT create_EnumSTATPROPSTG( enumx = enumx_allocate(&IID_IEnumSTATPROPSTG, &IEnumSTATPROPSTG_Vtbl, - sizeof (STATPROPSTG), - (IUnknown*)&This->IPropertyStorage_iface, - prop_enum_copy_cb); + sizeof (STATPROPSTG)); dictionary_enumerate(This->propid_to_prop, prop_enum_stat, enumx); diff --git a/dll/win32/ole32/storage32.c b/dll/win32/ole32/storage32.c index 6443197d93..6adf3c7c19 100644 --- a/dll/win32/ole32/storage32.c +++ b/dll/win32/ole32/storage32.c @@ -2067,7 +2067,7 @@ static HRESULT WINAPI StorageBaseImpl_SetClass( HRESULT hRes; DirEntry currentEntry; - TRACE("(%p, %p)\n", iface, clsid); + TRACE("(%p, %s)\n", iface, wine_dbgstr_guid(clsid)); if (This->reverted) return STG_E_REVERTED; @@ -7249,6 +7249,8 @@ BlockChainStream* BlockChainStream_Construct( BlockChainStream* newStream; newStream = HeapAlloc(GetProcessHeap(), 0, sizeof(BlockChainStream)); + if(!newStream) + return NULL; newStream->parentStorage = parentStorage; newStream->headOfStreamPlaceHolder = headOfStreamPlaceHolder; diff --git a/dll/win32/ole32/storage32.h b/dll/win32/ole32/storage32.h index 51be7d4f86..4f692fe585 100644 --- a/dll/win32/ole32/storage32.h +++ b/dll/win32/ole32/storage32.h @@ -517,20 +517,25 @@ StgStreamImpl* StgStreamImpl_Construct( /****************************************************************************** * Endian conversion macros */ -#undef htole32 -#undef htole16 - #ifdef WORDS_BIGENDIAN +#ifndef htole32 #define htole32(x) RtlUlongByteSwap(x) +#endif +#ifndef htole16 #define htole16(x) RtlUshortByteSwap(x) +#endif #define lendian32toh(x) RtlUlongByteSwap(x) #define lendian16toh(x) RtlUshortByteSwap(x) #else +#ifndef htole32 #define htole32(x) (x) +#endif +#ifndef htole16 #define htole16(x) (x) +#endif #define lendian32toh(x) (x) #define lendian16toh(x) (x) diff --git a/dll/win32/ole32/usrmarshal.c b/dll/win32/ole32/usrmarshal.c index 4de57fd818..9a56bd0933 100644 --- a/dll/win32/ole32/usrmarshal.c +++ b/dll/win32/ole32/usrmarshal.c @@ -80,11 +80,11 @@ static const char* debugstr_user_flags(ULONG *pFlags) * the first parameter is an unsigned long. * This function is only intended to be called by the RPC runtime. */ -ULONG __RPC_USER CLIPFORMAT_UserSize(ULONG *pFlags, ULONG StartingSize, CLIPFORMAT *pCF) +ULONG __RPC_USER CLIPFORMAT_UserSize(ULONG *pFlags, ULONG size, CLIPFORMAT *pCF) { - ULONG size = StartingSize; + TRACE("(%s, %d, %p\n", debugstr_user_flags(pFlags), size, pCF); - TRACE("(%s, %d, %p\n", debugstr_user_flags(pFlags), StartingSize, pCF); + ALIGN_LENGTH(size, 3); size += 8; @@ -129,6 +129,8 @@ unsigned char * __RPC_USER CLIPFORMAT_UserMarshal(ULONG *pFlags, unsigned char * { TRACE("(%s, %p, &0x%04x\n", debugstr_user_flags(pFlags), pBuffer, *pCF); + ALIGN_POINTER(pBuffer, 3); + /* only need to marshal the name if it is not a pre-defined type and * we are going remote */ if ((*pCF >= 0xc000) && (LOWORD(*pFlags) == MSHCTX_DIFFERENTMACHINE)) @@ -191,6 +193,8 @@ unsigned char * __RPC_USER CLIPFORMAT_UserUnmarshal(ULONG *pFlags, unsigned char TRACE("(%s, %p, %p\n", debugstr_user_flags(pFlags), pBuffer, pCF); + ALIGN_POINTER(pBuffer, 3); + fContext = *(DWORD *)pBuffer; pBuffer += 4; @@ -264,18 +268,23 @@ static ULONG handle_UserSize(ULONG *pFlags, ULONG StartingSize, HANDLE *handle) RaiseException(RPC_S_INVALID_TAG, 0, 0, NULL); return StartingSize; } + + ALIGN_LENGTH(StartingSize, 3); return StartingSize + sizeof(RemotableHandle); } static unsigned char * handle_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, HANDLE *handle) { - RemotableHandle *remhandle = (RemotableHandle *)pBuffer; + RemotableHandle *remhandle; if (LOWORD(*pFlags) == MSHCTX_DIFFERENTMACHINE) { ERR("can't remote a local handle\n"); RaiseException(RPC_S_INVALID_TAG, 0, 0, NULL); return pBuffer; } + + ALIGN_POINTER(pBuffer, 3); + remhandle = (RemotableHandle *)pBuffer; remhandle->fContext = WDT_INPROC_CALL; remhandle->u.hInproc = (LONG_PTR)*handle; return pBuffer + sizeof(RemotableHandle); @@ -283,7 +292,10 @@ static unsigned char * handle_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, static unsigned char * handle_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, HANDLE *handle) { - RemotableHandle *remhandle = (RemotableHandle *)pBuffer; + RemotableHandle *remhandle; + + ALIGN_POINTER(pBuffer, 3); + remhandle = (RemotableHandle *)pBuffer; if (remhandle->fContext != WDT_INPROC_CALL) RaiseException(RPC_X_BAD_STUB_DATA, 0, 0, NULL); *handle = (HANDLE)(LONG_PTR)remhandle->u.hInproc; @@ -566,10 +578,28 @@ void __RPC_USER HGLOBAL_UserFree(ULONG *pFlags, HGLOBAL *phGlobal) * the first parameter is a ULONG. * This function is only intended to be called by the RPC runtime. */ -ULONG __RPC_USER HBITMAP_UserSize(ULONG *pFlags, ULONG StartingSize, HBITMAP *phBmp) +ULONG __RPC_USER HBITMAP_UserSize(ULONG *flags, ULONG size, HBITMAP *bmp) { - FIXME(":stub\n"); - return StartingSize; + TRACE("(%s, %d, %p)\n", debugstr_user_flags(flags), size, *bmp); + + ALIGN_LENGTH(size, 3); + + size += sizeof(ULONG); + if (LOWORD(*flags) == MSHCTX_INPROC) + size += sizeof(ULONG); + else + { + size += sizeof(ULONG); + + if (*bmp) + { + size += sizeof(ULONG); + size += FIELD_OFFSET(userBITMAP, cbSize); + size += GetBitmapBits(*bmp, 0, NULL); + } + } + + return size; } /****************************************************************************** @@ -591,10 +621,45 @@ ULONG __RPC_USER HBITMAP_UserSize(ULONG *pFlags, ULONG StartingSize, HBITMAP *ph * the first parameter is a ULONG. * This function is only intended to be called by the RPC runtime. */ -unsigned char * __RPC_USER HBITMAP_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, HBITMAP *phBmp) +unsigned char * __RPC_USER HBITMAP_UserMarshal(ULONG *flags, unsigned char *buffer, HBITMAP *bmp) { - FIXME(":stub\n"); - return pBuffer; + TRACE("(%s, %p, %p)\n", debugstr_user_flags(flags), buffer, *bmp); + + ALIGN_POINTER(buffer, 3); + + if (LOWORD(*flags) == MSHCTX_INPROC) + { + *(ULONG *)buffer = WDT_INPROC_CALL; + buffer += sizeof(ULONG); + *(ULONG *)buffer = (ULONG)(ULONG_PTR)*bmp; + buffer += sizeof(ULONG); + } + else + { + *(ULONG *)buffer = WDT_REMOTE_CALL; + buffer += sizeof(ULONG); + *(ULONG *)buffer = (ULONG)(ULONG_PTR)*bmp; + buffer += sizeof(ULONG); + + if (*bmp) + { + static const ULONG header_size = FIELD_OFFSET(userBITMAP, cbSize); + BITMAP bitmap; + ULONG bitmap_size; + + bitmap_size = GetBitmapBits(*bmp, 0, NULL); + *(ULONG *)buffer = bitmap_size; + buffer += sizeof(ULONG); + + GetObjectW(*bmp, sizeof(BITMAP), &bitmap); + memcpy(buffer, &bitmap, header_size); + buffer += header_size; + + GetBitmapBits(*bmp, bitmap_size, buffer); + buffer += bitmap_size; + } + } + return buffer; } /****************************************************************************** @@ -616,10 +681,56 @@ unsigned char * __RPC_USER HBITMAP_UserMarshal(ULONG *pFlags, unsigned char *pBu * the first parameter is an ULONG. * This function is only intended to be called by the RPC runtime. */ -unsigned char * __RPC_USER HBITMAP_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, HBITMAP *phBmp) +unsigned char * __RPC_USER HBITMAP_UserUnmarshal(ULONG *flags, unsigned char *buffer, HBITMAP *bmp) { - FIXME(":stub\n"); - return pBuffer; + ULONG context; + + TRACE("(%s, %p, %p)\n", debugstr_user_flags(flags), buffer, bmp); + + ALIGN_POINTER(buffer, 3); + + context = *(ULONG *)buffer; + buffer += sizeof(ULONG); + + if (context == WDT_INPROC_CALL) + { + *bmp = *(HBITMAP *)buffer; + buffer += sizeof(*bmp); + } + else if (context == WDT_REMOTE_CALL) + { + ULONG handle = *(ULONG *)buffer; + buffer += sizeof(ULONG); + + if (handle) + { + static const ULONG header_size = FIELD_OFFSET(userBITMAP, cbSize); + BITMAP bitmap; + ULONG bitmap_size; + unsigned char *bits; + + bitmap_size = *(ULONG *)buffer; + buffer += sizeof(ULONG); + bits = HeapAlloc(GetProcessHeap(), 0, bitmap_size); + + memcpy(&bitmap, buffer, header_size); + buffer += header_size; + + memcpy(bits, buffer, bitmap_size); + buffer += bitmap_size; + + bitmap.bmBits = bits; + *bmp = CreateBitmapIndirect(&bitmap); + + HeapFree(GetProcessHeap(), 0, bits); + } + else + *bmp = NULL; + } + else + RaiseException(RPC_S_INVALID_TAG, 0, 0, NULL); + + return buffer; } /****************************************************************************** @@ -640,9 +751,12 @@ unsigned char * __RPC_USER HBITMAP_UserUnmarshal(ULONG *pFlags, unsigned char *p * which the first parameter is a ULONG. * This function is only intended to be called by the RPC runtime. */ -void __RPC_USER HBITMAP_UserFree(ULONG *pFlags, HBITMAP *phBmp) +void __RPC_USER HBITMAP_UserFree(ULONG *flags, HBITMAP *bmp) { - FIXME(":stub\n"); + TRACE("(%s, %p)\n", debugstr_user_flags(flags), *bmp); + + if (LOWORD(*flags) != MSHCTX_INPROC) + DeleteObject(*bmp); } /****************************************************************************** @@ -963,11 +1077,11 @@ void __RPC_USER HMETAFILE_UserFree(ULONG *pFlags, HMETAFILE *phmf) * the first parameter is a ULONG. * This function is only intended to be called by the RPC runtime. */ -ULONG __RPC_USER HENHMETAFILE_UserSize(ULONG *pFlags, ULONG StartingSize, HENHMETAFILE *phEmf) +ULONG __RPC_USER HENHMETAFILE_UserSize(ULONG *pFlags, ULONG size, HENHMETAFILE *phEmf) { - ULONG size = StartingSize; + TRACE("(%s, %d, %p\n", debugstr_user_flags(pFlags), size, *phEmf); - TRACE("(%s, %d, %p\n", debugstr_user_flags(pFlags), StartingSize, *phEmf); + ALIGN_LENGTH(size, 3); size += sizeof(ULONG); if (LOWORD(*pFlags) == MSHCTX_INPROC) @@ -1012,6 +1126,8 @@ unsigned char * __RPC_USER HENHMETAFILE_UserMarshal(ULONG *pFlags, unsigned char { TRACE("(%s, %p, &%p\n", debugstr_user_flags(pFlags), pBuffer, *phEmf); + ALIGN_POINTER(pBuffer, 3); + if (LOWORD(*pFlags) == MSHCTX_INPROC) { if (sizeof(*phEmf) == 8) @@ -1070,6 +1186,8 @@ unsigned char * __RPC_USER HENHMETAFILE_UserUnmarshal(ULONG *pFlags, unsigned ch TRACE("(%s, %p, %p\n", debugstr_user_flags(pFlags), pBuffer, phEmf); + ALIGN_POINTER(pBuffer, 3); + fContext = *(ULONG *)pBuffer; pBuffer += sizeof(ULONG); @@ -1155,11 +1273,11 @@ void __RPC_USER HENHMETAFILE_UserFree(ULONG *pFlags, HENHMETAFILE *phEmf) * the first parameter is a ULONG. * This function is only intended to be called by the RPC runtime. */ -ULONG __RPC_USER HMETAFILEPICT_UserSize(ULONG *pFlags, ULONG StartingSize, HMETAFILEPICT *phMfp) +ULONG __RPC_USER HMETAFILEPICT_UserSize(ULONG *pFlags, ULONG size, HMETAFILEPICT *phMfp) { - ULONG size = StartingSize; + TRACE("(%s, %d, &%p)\n", debugstr_user_flags(pFlags), size, *phMfp); - TRACE("(%s, %d, &%p)\n", debugstr_user_flags(pFlags), StartingSize, *phMfp); + ALIGN_LENGTH(size, 3); size += sizeof(ULONG); @@ -1209,6 +1327,8 @@ unsigned char * __RPC_USER HMETAFILEPICT_UserMarshal(ULONG *pFlags, unsigned cha { TRACE("(%s, %p, &%p)\n", debugstr_user_flags(pFlags), pBuffer, *phMfp); + ALIGN_POINTER(pBuffer, 3); + if (LOWORD(*pFlags) == MSHCTX_INPROC) { if (sizeof(HMETAFILEPICT) == 8) @@ -1272,6 +1392,8 @@ unsigned char * __RPC_USER HMETAFILEPICT_UserUnmarshal(ULONG *pFlags, unsigned c TRACE("(%s, %p, %p)\n", debugstr_user_flags(pFlags), pBuffer, phMfp); + ALIGN_POINTER(pBuffer, 3); + fContext = *(ULONG *)pBuffer; pBuffer += sizeof(ULONG); @@ -1602,9 +1724,7 @@ ULONG __RPC_USER STGMEDIUM_UserSize(ULONG *pFlags, ULONG StartingSize, STGMEDIUM case TYMED_GDI: TRACE("TYMED_GDI\n"); if (pStgMedium->u.hBitmap) - { - FIXME("not implemented for GDI object %p\n", pStgMedium->u.hBitmap); - } + size = HBITMAP_UserSize(pFlags, size, &pStgMedium->u.hBitmap); break; case TYMED_MFPICT: TRACE("TYMED_MFPICT\n"); @@ -1714,9 +1834,7 @@ unsigned char * __RPC_USER STGMEDIUM_UserMarshal(ULONG *pFlags, unsigned char *p case TYMED_GDI: TRACE("TYMED_GDI\n"); if (pStgMedium->u.hBitmap) - { - FIXME("not implemented for GDI object %p\n", pStgMedium->u.hBitmap); - } + pBuffer = HBITMAP_UserMarshal(pFlags, pBuffer, &pStgMedium->u.hBitmap); break; case TYMED_MFPICT: TRACE("TYMED_MFPICT\n"); @@ -1852,9 +1970,7 @@ unsigned char * __RPC_USER STGMEDIUM_UserUnmarshal(ULONG *pFlags, unsigned char case TYMED_GDI: TRACE("TYMED_GDI\n"); if (content) - { - FIXME("not implemented for GDI object\n"); - } + pBuffer = HBITMAP_UserUnmarshal(pFlags, pBuffer, &pStgMedium->u.hBitmap); else pStgMedium->u.hBitmap = NULL; break; diff --git a/media/doc/README.WINE b/media/doc/README.WINE index 5cc918b237..4b324f3b1d 100644 --- a/media/doc/README.WINE +++ b/media/doc/README.WINE @@ -139,7 +139,7 @@ reactos/dll/win32/ntdsapi # Synced to WineStaging-2.9 reactos/dll/win32/objsel # Synced to WineStaging-2.9 reactos/dll/win32/odbc32 # Synced to WineStaging-2.9. Depends on port of Linux ODBC. reactos/dll/win32/odbccp32 # Synced to WineStaging-2.9 -reactos/dll/win32/ole32 # Synced to WineStaging-2.16 +reactos/dll/win32/ole32 # Synced to Wine-3.0 reactos/dll/win32/oleacc # Synced to WineStaging-2.9 reactos/dll/win32/oleaut32 # Synced to WineStaging-2.16 reactos/dll/win32/olecli32 # Synced to WineStaging-2.9
7 years, 4 months
1
0
0
0
01/01: [MSXML3_WINETEST] Sync with Wine 3.0. CORE-14225
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=d4c87f7aa8e680324be41…
commit d4c87f7aa8e680324be4117a431723818feafc04 Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Sat Jan 20 12:36:34 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Sat Jan 20 12:36:34 2018 +0100 [MSXML3_WINETEST] Sync with Wine 3.0. CORE-14225 --- modules/rostests/winetests/msxml3/domdoc.c | 110 ++++++++++++++++++++++++---- modules/rostests/winetests/msxml3/httpreq.c | 91 +++++++++++++++++++++-- modules/rostests/winetests/msxml3/schema.c | 26 +++---- 3 files changed, 195 insertions(+), 32 deletions(-) diff --git a/modules/rostests/winetests/msxml3/domdoc.c b/modules/rostests/winetests/msxml3/domdoc.c index cf0869f263..03ac01675d 100644 --- a/modules/rostests/winetests/msxml3/domdoc.c +++ b/modules/rostests/winetests/msxml3/domdoc.c @@ -29,6 +29,7 @@ #undef CLSID_DOMDocument DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0); +DEFINE_GUID(IID_transformdest_unknown,0xf5078f3a,0xc551,0x11d3,0x89,0xb9,0x00,0x00,0xf8,0x1f,0xe2,0x21); static int g_unexpectedcall, g_expectedcall; @@ -6475,7 +6476,8 @@ static void test_save(void) hr = IXMLDOMDocument_loadXML(doc, _bstr_(win1252xml), &b); EXPECT_HR(hr, S_OK); - CreateStreamOnHGlobal(NULL, TRUE, &stream); + hr = CreateStreamOnHGlobal(NULL, TRUE, &stream); + ok(hr == S_OK, "got 0x%08x\n", hr); V_VT(&dest) = VT_UNKNOWN; V_UNKNOWN(&dest) = (IUnknown*)stream; hr = IXMLDOMDocument_save(doc, dest); @@ -7482,6 +7484,7 @@ static void test_XSLPattern(void) ok(hr == S_OK, "query=%s, failed with 0x%08x\n", ptr->query, hr); len = 0; hr = IXMLDOMNodeList_get_length(list, &len); + ok(hr == S_OK, "Failed to get list length, hr %#x.\n", hr); if (*ptr->list) { ok(len != 0, "query=%s, empty list\n", ptr->query); @@ -10168,16 +10171,20 @@ static void write_to_file(const char *name, const char *data) static void test_load(void) { IXMLDOMDocument *doc, *doc2; + BSTR pathW, bstr1, bstr2; IXMLDOMNodeList *list; IXMLDOMElement *elem; + char path[MAX_PATH]; VARIANT_BOOL b; VARIANT src; HRESULT hr; - BSTR path, bstr1, bstr2; void* ptr; + GetTempPathA(MAX_PATH, path); + strcat(path, "winetest.xml"); + /* prepare a file */ - write_to_file("test.xml", win1252xml); + write_to_file(path, win1252xml); doc = create_document(&IID_IXMLDOMDocument); @@ -10188,11 +10195,11 @@ static void test_load(void) EXPECT_HR(hr, E_INVALIDARG); ok(b == VARIANT_FALSE, "got %d\n", b); - path = _bstr_("test.xml"); + pathW = _bstr_(path); /* load from path: VT_BSTR */ V_VT(&src) = VT_BSTR; - V_BSTR(&src) = path; + V_BSTR(&src) = pathW; hr = IXMLDOMDocument_load(doc, src, &b); EXPECT_HR(hr, S_OK); ok(b == VARIANT_TRUE, "got %d\n", b); @@ -10204,7 +10211,7 @@ static void test_load(void) /* load from a path: VT_BSTR|VT_BYREF */ V_VT(&src) = VT_BSTR | VT_BYREF; - V_BSTRREF(&src) = &path; + V_BSTRREF(&src) = &pathW; hr = IXMLDOMDocument_load(doc, src, &b); EXPECT_HR(hr, S_OK); ok(b == VARIANT_TRUE, "got %d\n", b); @@ -10242,13 +10249,13 @@ static void test_load(void) ok(hr == S_OK, "got 0x%08x\n", hr); SysFreeString(bstr1); - DeleteFileA("test.xml"); + DeleteFileA(path); /* load from existing path, no xml content */ - write_to_file("test.xml", nocontent); + write_to_file(path, nocontent); V_VT(&src) = VT_BSTR; - V_BSTR(&src) = path; + V_BSTR(&src) = pathW; b = VARIANT_TRUE; hr = IXMLDOMDocument_load(doc, src, &b); ok(hr == S_FALSE, "got 0x%08x\n", hr); @@ -10259,7 +10266,7 @@ static void test_load(void) ok(hr == S_FALSE, "got 0x%08x\n", hr); ok(bstr1 == NULL, "got %p\n", bstr1); - DeleteFileA("test.xml"); + DeleteFileA(path); IXMLDOMDocument_Release(doc); doc = create_document(&IID_IXMLDOMDocument); @@ -10964,7 +10971,8 @@ static void test_dispex(void) /* IXMLDOMNodeList */ hr = IXMLDOMDocument_getElementsByTagName(doc, _bstr_("*"), &node_list); EXPECT_HR(hr, S_OK); - IXMLDOMNodeList_QueryInterface(node_list, &IID_IUnknown, (void**)&unk); + hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IUnknown, (void**)&unk); + ok(hr == S_OK, "got 0x%08x\n", hr); test_domobj_dispex(unk); IUnknown_Release(unk); IXMLDOMNodeList_Release(node_list); @@ -12005,7 +12013,7 @@ static void test_get_namespaces(void) free_bstrs(); } -static DOMNodeType put_data_types[] = { +static const DOMNodeType put_data_types[] = { NODE_TEXT, NODE_CDATA_SECTION, NODE_PROCESSING_INSTRUCTION, @@ -12018,7 +12026,7 @@ static void test_put_data(void) static const WCHAR test_data[] = {'t','e','s','t',' ','n','o','d','e',' ','d','a','t','a',0}; WCHAR buff[100], *data; IXMLDOMDocument *doc; - DOMNodeType *type; + const DOMNodeType *type; IXMLDOMText *text; IXMLDOMNode *node; VARIANT v; @@ -12576,6 +12584,81 @@ static void test_merging_text(void) free_bstrs(); } +static HRESULT WINAPI transformdest_QueryInterface(IUnknown *iface, REFIID riid, void **obj) +{ + BOOL known_iid = IsEqualIID(riid, &IID_IHTMLObjectElement) || + IsEqualIID(riid, &IID_transformdest_unknown) || + IsEqualIID(riid, &IID_IServiceProvider) || + IsEqualIID(riid, &IID_IStream) || + IsEqualIID(riid, &IID_ISequentialStream) || + IsEqualIID(riid, &IID_IRequestDictionary); + +todo_wine_if(IsEqualIID(riid, &IID_IXMLDOMDocument)) + ok(known_iid, "Unexpected riid %s\n", wine_dbgstr_guid(riid)); + + return E_NOINTERFACE; +} + +static ULONG WINAPI transformdest_AddRef(IUnknown *iface) +{ + return 2; +} + +static ULONG WINAPI transformdest_Release(IUnknown *iface) +{ + return 1; +} + +static const IUnknownVtbl transformdestvtbl = +{ + transformdest_QueryInterface, + transformdest_AddRef, + transformdest_Release, +}; + +static void test_transformNodeToObject(void) +{ + IUnknown transformdest = { &transformdestvtbl }; + IXMLDOMDocument *doc, *doc2, *doc3; + VARIANT_BOOL b; + HRESULT hr; + VARIANT v; + + doc = create_document(&IID_IXMLDOMDocument); + doc2 = create_document(&IID_IXMLDOMDocument); + doc3 = create_document(&IID_IXMLDOMDocument); + + hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTransformXML), &b); + ok(hr == S_OK, "Failed to load document, hr %#x.\n", hr); + hr = IXMLDOMDocument_loadXML(doc2, _bstr_(szTransformSSXML), &b); + ok(hr == S_OK, "Failed to load document, hr %#x.\n", hr); + + V_VT(&v) = VT_UNKNOWN; + V_UNKNOWN(&v) = &transformdest; + hr = IXMLDOMDocument_transformNodeToObject(doc, (IXMLDOMNode *)doc2, v); + ok(hr == E_INVALIDARG, "Failed to transform node, hr %#x.\n", hr); + + V_VT(&v) = VT_UNKNOWN; + V_UNKNOWN(&v) = NULL; + hr = IXMLDOMDocument_transformNodeToObject(doc, (IXMLDOMNode *)doc2, v); + ok(hr == E_INVALIDARG, "Failed to transform node, hr %#x.\n", hr); + + V_VT(&v) = VT_DISPATCH; + V_DISPATCH(&v) = NULL; + hr = IXMLDOMDocument_transformNodeToObject(doc, (IXMLDOMNode *)doc2, v); + ok(hr == E_INVALIDARG, "Failed to transform node, hr %#x.\n", hr); + + V_VT(&v) = VT_DISPATCH; + V_DISPATCH(&v) = (IDispatch *)doc3; + hr = IXMLDOMDocument_transformNodeToObject(doc, (IXMLDOMNode *)doc2, v); + ok(hr == S_OK, "Failed to transform node, hr %#x.\n", hr); + + IXMLDOMDocument_Release(doc3); + IXMLDOMDocument_Release(doc2); + IXMLDOMDocument_Release(doc); + free_bstrs(); +} + START_TEST(domdoc) { HRESULT hr; @@ -12657,6 +12740,7 @@ START_TEST(domdoc) test_xmlns_attribute(); test_url(); test_merging_text(); + test_transformNodeToObject(); test_xsltemplate(); test_xsltext(); diff --git a/modules/rostests/winetests/msxml3/httpreq.c b/modules/rostests/winetests/msxml3/httpreq.c index 8d97a48cd7..9c4e48864f 100644 --- a/modules/rostests/winetests/msxml3/httpreq.c +++ b/modules/rostests/winetests/msxml3/httpreq.c @@ -1322,6 +1322,16 @@ static IXMLHttpRequest *create_xhr(void) return SUCCEEDED(hr) ? ret : NULL; } +static IServerXMLHTTPRequest *create_server_xhr(void) +{ + IServerXMLHTTPRequest *ret; + HRESULT hr; + + hr = CoCreateInstance(&CLSID_ServerXMLHTTP30, NULL, CLSCTX_INPROC_SERVER, &IID_IServerXMLHTTPRequest, (void **)&ret); + + return SUCCEEDED(hr) ? ret : NULL; +} + static void set_safety_opt(IUnknown *unk, DWORD mask, DWORD opts) { IObjectSafety *obj_safety; @@ -1714,6 +1724,28 @@ static void test_XMLHTTP(void) EXPECT_HR(hr, S_OK); IObjectWithSite_Release(obj_site); + + /* HEAD request */ + hr = IXMLHttpRequest_put_onreadystatechange(xhr, NULL); + ok(hr == S_OK, "Failed to reset state change handler, hr %#x.\n", hr); + + test_open(xhr, "HEAD", xmltestA, S_OK); + + V_VT(&varbody) = VT_EMPTY; + hr = IXMLHttpRequest_send(xhr, varbody); + ok(hr == S_OK, "Failed to send HEAD request, hr %#x.\n", hr); + + str = NULL; + hr = IXMLHttpRequest_get_responseText(xhr, &str); + ok(hr == S_OK, "Failed to get response text, hr %#x.\n", hr); + ok(!*str, "Unexpected text %s.\n", wine_dbgstr_w(str)); + SysFreeString(str); + + hr = IXMLHttpRequest_getAllResponseHeaders(xhr, &str); + ok(hr == S_OK, "Failed to get response headers, hr %#x.\n", hr); + ok(str && *str, "Expected response headers.\n"); + SysFreeString(str); + IXMLHttpRequest_Release(xhr); free_bstrs(); } @@ -1738,20 +1770,67 @@ static void test_safe_httpreq(void) free_bstrs(); } +static void test_supporterrorinfo(void) +{ + HRESULT hr; + IXMLHttpRequest *xhr; + IServerXMLHTTPRequest *server_xhr; + ISupportErrorInfo *errorinfo, *errorinfo2; + + xhr = create_xhr(); + + EXPECT_REF(xhr, 1); + hr = IXMLHttpRequest_QueryInterface(xhr, &IID_ISupportErrorInfo, (void **)&errorinfo); + ok(hr == S_OK, "Failed to get ISupportErrorInfo, hr %#x.\n", hr); + EXPECT_REF(xhr, 2); + + hr = IXMLHttpRequest_QueryInterface(xhr, &IID_ISupportErrorInfo, (void **)&errorinfo2); + ok(hr == S_OK, "Failed to get ISupportErrorInfo, hr %#x.\n", hr); + ok(errorinfo == errorinfo2, "Unexpected error info instance.\n"); + EXPECT_REF(xhr, 3); + + ISupportErrorInfo_Release(errorinfo2); + ISupportErrorInfo_Release(errorinfo); + + IXMLHttpRequest_Release(xhr); + + /* ServerXMLHTTP */ + server_xhr = create_server_xhr(); + + EXPECT_REF(server_xhr, 1); + hr = IServerXMLHTTPRequest_QueryInterface(server_xhr, &IID_ISupportErrorInfo, (void **)&errorinfo); + ok(hr == S_OK, "Failed to get ISupportErrorInfo, hr %#x.\n", hr); + EXPECT_REF(server_xhr, 2); + + hr = IServerXMLHTTPRequest_QueryInterface(server_xhr, &IID_ISupportErrorInfo, (void **)&errorinfo2); + ok(hr == S_OK, "Failed to get ISupportErrorInfo, hr %#x.\n", hr); + ok(errorinfo == errorinfo2, "Unexpected error info instance.\n"); + EXPECT_REF(server_xhr, 3); + + ISupportErrorInfo_Release(errorinfo2); + ISupportErrorInfo_Release(errorinfo); + + IServerXMLHTTPRequest_Release(server_xhr); +} + START_TEST(httpreq) { IXMLHttpRequest *xhr; CoInitialize(NULL); - if((xhr = create_xhr())) { - IXMLHttpRequest_Release(xhr); - - test_XMLHTTP(); - test_safe_httpreq(); - }else { + if (!(xhr = create_xhr())) + { win_skip("IXMLHTTPRequest is not available\n"); + CoUninitialize(); + return; } + IXMLHttpRequest_Release(xhr); + + test_XMLHTTP(); + test_safe_httpreq(); + test_supporterrorinfo(); + CoUninitialize(); } diff --git a/modules/rostests/winetests/msxml3/schema.c b/modules/rostests/winetests/msxml3/schema.c index e082b00f4c..306c65dcf2 100644 --- a/modules/rostests/winetests/msxml3/schema.c +++ b/modules/rostests/winetests/msxml3/schema.c @@ -656,26 +656,26 @@ static void test_collection_refs(void) LONG length; schema1 = create_document(&IID_IXMLDOMDocument2); - schema2 = create_document(&IID_IXMLDOMDocument2); - schema3 = create_document(&IID_IXMLDOMDocument2); + ok(schema1 != NULL, "Failed to create a document.\n"); cache1 = create_cache(&IID_IXMLDOMSchemaCollection); - cache2 = create_cache(&IID_IXMLDOMSchemaCollection); - cache3 = create_cache(&IID_IXMLDOMSchemaCollection); + ok(cache1 != NULL, "Failed to create schema collection.\n"); - if (!schema1 || !schema2 || !schema3 || !cache1 || !cache2 || !cache3) + if (!schema1 || !cache1) { - if (schema1) IXMLDOMDocument2_Release(schema1); - if (schema2) IXMLDOMDocument2_Release(schema2); - if (schema3) IXMLDOMDocument2_Release(schema3); - - if (cache1) IXMLDOMSchemaCollection_Release(cache1); - if (cache2) IXMLDOMSchemaCollection_Release(cache2); - if (cache3) IXMLDOMSchemaCollection_Release(cache2); - + if (schema1) + IXMLDOMDocument2_Release(schema1); + if (cache1) + IXMLDOMSchemaCollection_Release(cache1); return; } + schema2 = create_document(&IID_IXMLDOMDocument2); + schema3 = create_document(&IID_IXMLDOMDocument2); + + cache2 = create_cache(&IID_IXMLDOMSchemaCollection); + cache3 = create_cache(&IID_IXMLDOMSchemaCollection); + ole_check(IXMLDOMDocument2_loadXML(schema1, _bstr_(xdr_schema1_xml), &b)); ok(b == VARIANT_TRUE, "failed to load XML\n");
7 years, 4 months
1
0
0
0
01/01: [MSXML3] Sync with Wine 3.0. CORE-14225
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=0506c9332a4f7c18b4de5…
commit 0506c9332a4f7c18b4de547db823c8e6cd1a6a28 Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Sat Jan 20 12:35:17 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Sat Jan 20 12:35:17 2018 +0100 [MSXML3] Sync with Wine 3.0. CORE-14225 --- dll/win32/msxml3/domdoc.c | 42 ++++++++++++++++++++++++++++-- dll/win32/msxml3/httprequest.c | 58 +++++++++++++++++++++++++++++++++++++++--- dll/win32/msxml3/saxreader.c | 3 ++- dll/win32/msxml3/schema.c | 2 +- media/doc/README.WINE | 2 +- 5 files changed, 99 insertions(+), 8 deletions(-) diff --git a/dll/win32/msxml3/domdoc.c b/dll/win32/msxml3/domdoc.c index b6cdfc760b..bb08f25a13 100644 --- a/dll/win32/msxml3/domdoc.c +++ b/dll/win32/msxml3/domdoc.c @@ -1486,10 +1486,48 @@ static HRESULT WINAPI domdoc_get_baseName( static HRESULT WINAPI domdoc_transformNodeToObject( IXMLDOMDocument3 *iface, IXMLDOMNode* stylesheet, - VARIANT outputObject) + VARIANT output) { domdoc *This = impl_from_IXMLDOMDocument3( iface ); - FIXME("(%p)->(%p %s)\n", This, stylesheet, debugstr_variant(&outputObject)); + + TRACE("(%p)->(%p %s)\n", This, stylesheet, debugstr_variant(&output)); + + switch (V_VT(&output)) + { + case VT_UNKNOWN: + case VT_DISPATCH: + { + IXMLDOMDocument *doc; + HRESULT hr; + + if (!V_UNKNOWN(&output)) + return E_INVALIDARG; + + /* FIXME: we're not supposed to query for document interface, should use IStream + which we don't support currently. */ + if (IUnknown_QueryInterface(V_UNKNOWN(&output), &IID_IXMLDOMDocument, (void **)&doc) == S_OK) + { + VARIANT_BOOL b; + BSTR str; + + if (FAILED(hr = node_transform_node(&This->node, stylesheet, &str))) + return hr; + + hr = IXMLDOMDocument_loadXML(doc, str, &b); + SysFreeString(str); + return hr; + } + else + { + FIXME("Unsupported destination type.\n"); + return E_INVALIDARG; + } + } + default: + FIXME("Output type %d not handled.\n", V_VT(&output)); + return E_NOTIMPL; + } + return E_NOTIMPL; } diff --git a/dll/win32/msxml3/httprequest.c b/dll/win32/msxml3/httprequest.c index 66a47d545e..56bc51a932 100644 --- a/dll/win32/msxml3/httprequest.c +++ b/dll/win32/msxml3/httprequest.c @@ -49,6 +49,7 @@ typedef struct IXMLHTTPRequest IXMLHTTPRequest_iface; IObjectWithSite IObjectWithSite_iface; IObjectSafety IObjectSafety_iface; + ISupportErrorInfo ISupportErrorInfo_iface; LONG ref; READYSTATE state; @@ -107,6 +108,11 @@ static inline httprequest *impl_from_IObjectSafety(IObjectSafety *iface) return CONTAINING_RECORD(iface, httprequest, IObjectSafety_iface); } +static inline httprequest *impl_from_ISupportErrorInfo(ISupportErrorInfo *iface) +{ + return CONTAINING_RECORD(iface, httprequest, ISupportErrorInfo_iface); +} + static inline serverhttp *impl_from_IServerXMLHTTPRequest(IServerXMLHTTPRequest *iface) { return CONTAINING_RECORD(iface, serverhttp, IServerXMLHTTPRequest_iface); @@ -856,6 +862,7 @@ static HRESULT verify_uri(httprequest *This, IUri *uri) static HRESULT httprequest_open(httprequest *This, BSTR method, BSTR url, VARIANT async, VARIANT user, VARIANT password) { + static const WCHAR MethodHeadW[] = {'H','E','A','D',0}; static const WCHAR MethodGetW[] = {'G','E','T',0}; static const WCHAR MethodPutW[] = {'P','U','T',0}; static const WCHAR MethodPostW[] = {'P','O','S','T',0}; @@ -891,6 +898,7 @@ static HRESULT httprequest_open(httprequest *This, BSTR method, BSTR url, This->verb = BINDVERB_POST; } else if (!strcmpiW(method, MethodDeleteW) || + !strcmpiW(method, MethodHeadW) || !strcmpiW(method, MethodPropFindW)) { This->verb = BINDVERB_CUSTOM; @@ -1303,6 +1311,10 @@ static HRESULT WINAPI XMLHTTPRequest_QueryInterface(IXMLHTTPRequest *iface, REFI { *ppvObject = &This->IObjectSafety_iface; } + else if (IsEqualGUID(&IID_ISupportErrorInfo, riid)) + { + *ppvObject = &This->ISupportErrorInfo_iface; + } else { TRACE("Unsupported interface %s\n", debugstr_guid(riid)); @@ -1310,7 +1322,7 @@ static HRESULT WINAPI XMLHTTPRequest_QueryInterface(IXMLHTTPRequest *iface, REFI return E_NOINTERFACE; } - IXMLHTTPRequest_AddRef( iface ); + IUnknown_AddRef((IUnknown *)*ppvObject); return S_OK; } @@ -1683,6 +1695,41 @@ static const IObjectSafetyVtbl ObjectSafetyVtbl = { httprequest_Safety_SetInterfaceSafetyOptions }; +static HRESULT WINAPI SupportErrorInfo_QueryInterface(ISupportErrorInfo *iface, REFIID riid, void **obj) +{ + httprequest *This = impl_from_ISupportErrorInfo(iface); + return IXMLHTTPRequest_QueryInterface(&This->IXMLHTTPRequest_iface, riid, obj); +} + +static ULONG WINAPI SupportErrorInfo_AddRef(ISupportErrorInfo *iface) +{ + httprequest *This = impl_from_ISupportErrorInfo(iface); + return IXMLHTTPRequest_AddRef(&This->IXMLHTTPRequest_iface); +} + +static ULONG WINAPI SupportErrorInfo_Release(ISupportErrorInfo *iface) +{ + httprequest *This = impl_from_ISupportErrorInfo(iface); + return IXMLHTTPRequest_Release(&This->IXMLHTTPRequest_iface); +} + +static HRESULT WINAPI SupportErrorInfo_InterfaceSupportsErrorInfo(ISupportErrorInfo *iface, REFIID riid) +{ + httprequest *This = impl_from_ISupportErrorInfo(iface); + + FIXME("(%p)->(%s)\n", This, debugstr_guid(riid)); + + return E_NOTIMPL; +} + +static const ISupportErrorInfoVtbl SupportErrorInfoVtbl = +{ + SupportErrorInfo_QueryInterface, + SupportErrorInfo_AddRef, + SupportErrorInfo_Release, + SupportErrorInfo_InterfaceSupportsErrorInfo, +}; + /* IServerXMLHTTPRequest */ static HRESULT WINAPI ServerXMLHTTPRequest_QueryInterface(IServerXMLHTTPRequest *iface, REFIID riid, void **obj) { @@ -1697,6 +1744,10 @@ static HRESULT WINAPI ServerXMLHTTPRequest_QueryInterface(IServerXMLHTTPRequest { *obj = iface; } + else if ( IsEqualGUID( riid, &IID_ISupportErrorInfo )) + { + *obj = &This->req.ISupportErrorInfo_iface; + } else { TRACE("Unsupported interface %s\n", debugstr_guid(riid)); @@ -1704,7 +1755,7 @@ static HRESULT WINAPI ServerXMLHTTPRequest_QueryInterface(IServerXMLHTTPRequest return E_NOINTERFACE; } - IServerXMLHTTPRequest_AddRef( iface ); + IUnknown_AddRef( (IUnknown *)*obj ); return S_OK; } @@ -1903,7 +1954,7 @@ static HRESULT WINAPI ServerXMLHTTPRequest_setTimeouts(IServerXMLHTTPRequest *if { serverhttp *This = impl_from_IServerXMLHTTPRequest( iface ); FIXME("(%p)->(%d %d %d %d): stub\n", This, resolveTimeout, connectTimeout, sendTimeout, receiveTimeout); - return E_NOTIMPL; + return S_OK; } static HRESULT WINAPI ServerXMLHTTPRequest_waitForResponse(IServerXMLHTTPRequest *iface, VARIANT timeout, VARIANT_BOOL *isSuccessful) @@ -1961,6 +2012,7 @@ static void init_httprequest(httprequest *req) req->IXMLHTTPRequest_iface.lpVtbl = &XMLHTTPRequestVtbl; req->IObjectWithSite_iface.lpVtbl = &ObjectWithSiteVtbl; req->IObjectSafety_iface.lpVtbl = &ObjectSafetyVtbl; + req->ISupportErrorInfo_iface.lpVtbl = &SupportErrorInfoVtbl; req->ref = 1; req->async = FALSE; diff --git a/dll/win32/msxml3/saxreader.c b/dll/win32/msxml3/saxreader.c index a68a7725d2..5c8923caac 100644 --- a/dll/win32/msxml3/saxreader.c +++ b/dll/win32/msxml3/saxreader.c @@ -1950,6 +1950,7 @@ static BSTR saxreader_get_cdata_chunk(const xmlChar *str, int len) BSTR bstr = bstr_from_xmlCharN(str, len), ret; WCHAR *ptr; + len = SysStringLen(bstr); ptr = bstr + len - 1; while ((*ptr == '\r' || *ptr == '\n') && ptr >= bstr) ptr--; @@ -2016,7 +2017,7 @@ static void libxml_cdatablock(void *ctx, const xmlChar *value, int len) while (i < len) { if (value[i] != '\r' && value[i] != '\n') break; - i++; + i++; } end = &value[i]; diff --git a/dll/win32/msxml3/schema.c b/dll/win32/msxml3/schema.c index 15dfa8d54e..2c761518bd 100644 --- a/dll/win32/msxml3/schema.c +++ b/dll/win32/msxml3/schema.c @@ -789,7 +789,7 @@ static inline schema_cache* impl_from_IXMLDOMSchemaCollection2(IXMLDOMSchemaColl static inline schema_cache* impl_from_IXMLDOMSchemaCollection(IXMLDOMSchemaCollection* iface) { - return CONTAINING_RECORD((IXMLDOMSchemaCollection2 *)iface, schema_cache, IXMLDOMSchemaCollection2_iface); + return CONTAINING_RECORD(iface, schema_cache, IXMLDOMSchemaCollection2_iface); } static inline schema_cache* unsafe_impl_from_IXMLDOMSchemaCollection(IXMLDOMSchemaCollection *iface) diff --git a/media/doc/README.WINE b/media/doc/README.WINE index 50ce55e84b..5cc918b237 100644 --- a/media/doc/README.WINE +++ b/media/doc/README.WINE @@ -129,7 +129,7 @@ reactos/dll/win32/msvfw32 # Synced to Wine-3.0 reactos/dll/win32/msvidc32 # Synced to Wine-3.0 reactos/dll/win32/msxml # Synced to WineStaging-2.9 reactos/dll/win32/msxml2 # Synced to WineStaging-2.9 -reactos/dll/win32/msxml3 # Synced to WineStaging-2.9 +reactos/dll/win32/msxml3 # Synced to Wine-3.0 reactos/dll/win32/msxml4 # Synced to WineStaging-2.9 reactos/dll/win32/msxml6 # Synced to WineStaging-2.9 reactos/dll/win32/nddeapi # Synced to WineStaging-2.9
7 years, 4 months
1
0
0
0
01/01: [MSVIDC32] Sync with Wine 3.0. CORE-14225
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=d023d396ee8de9f362569…
commit d023d396ee8de9f362569caaae65cd53130d71a7 Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Sat Jan 20 12:33:41 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Sat Jan 20 12:33:41 2018 +0100 [MSVIDC32] Sync with Wine 3.0. CORE-14225 --- dll/win32/msvidc32/msvideo1.c | 115 ++++++------------------------------------ media/doc/README.WINE | 2 +- 2 files changed, 17 insertions(+), 100 deletions(-) diff --git a/dll/win32/msvidc32/msvideo1.c b/dll/win32/msvidc32/msvideo1.c index 8d4e0cd90a..6d1248976c 100644 --- a/dll/win32/msvidc32/msvideo1.c +++ b/dll/win32/msvidc32/msvideo1.c @@ -71,14 +71,9 @@ typedef BYTE uint8_t; typedef struct Msvideo1Context { DWORD dwMagic; - int depth; + BOOL mode_8bit; /* if it's not 8-bit, it's 16-bit */ } Msvideo1Context; -static inline int get_stride(int width, int depth) -{ - return ((depth * width + 31) >> 3) & ~3; -} - static void msvideo1_decode_8bit( int width, int height, const unsigned char *buf, int buf_size, unsigned char *pixels, int stride) @@ -336,15 +331,8 @@ CRAM_DecompressQuery( Msvideo1Context *info, LPBITMAPINFO in, LPBITMAPINFO out ) TRACE("out->bpp = %d\n", out->bmiHeader.biBitCount ); TRACE("out->height = %d\n", out->bmiHeader.biHeight ); TRACE("out->width = %d\n", out->bmiHeader.biWidth ); - - if ((in->bmiHeader.biBitCount != out->bmiHeader.biBitCount) && - (in->bmiHeader.biBitCount != 16 || out->bmiHeader.biBitCount != 24)) - { - TRACE("incompatible depth requested\n"); - return ICERR_BADFORMAT; - } - - if(( in->bmiHeader.biPlanes != out->bmiHeader.biPlanes ) || + if(( in->bmiHeader.biBitCount != out->bmiHeader.biBitCount ) || + ( in->bmiHeader.biPlanes != out->bmiHeader.biPlanes ) || ( in->bmiHeader.biHeight != out->bmiHeader.biHeight ) || ( in->bmiHeader.biWidth != out->bmiHeader.biWidth )) { @@ -371,17 +359,12 @@ CRAM_DecompressGetFormat( Msvideo1Context *info, LPBITMAPINFO in, LPBITMAPINFO o if (in->bmiHeader.biBitCount <= 8) size += in->bmiHeader.biClrUsed * sizeof(RGBQUAD); - if (in->bmiHeader.biBitCount != 8 && in->bmiHeader.biBitCount != 16) - return ICERR_BADFORMAT; - if( out ) { memcpy( out, in, size ); - out->bmiHeader.biWidth = in->bmiHeader.biWidth & ~1; - out->bmiHeader.biHeight = in->bmiHeader.biHeight & ~1; out->bmiHeader.biCompression = BI_RGB; - out->bmiHeader.biSizeImage = in->bmiHeader.biHeight * - get_stride(out->bmiHeader.biWidth, out->bmiHeader.biBitCount); + out->bmiHeader.biSizeImage = in->bmiHeader.biHeight + * in->bmiHeader.biWidth *4; return ICERR_OK; } @@ -397,56 +380,21 @@ static LRESULT CRAM_DecompressBegin( Msvideo1Context *info, LPBITMAPINFO in, LPB TRACE("bitmap is %d bpp\n", in->bmiHeader.biBitCount); if( in->bmiHeader.biBitCount == 8 ) - info->depth = 8; + info->mode_8bit = TRUE; else if( in->bmiHeader.biBitCount == 16 ) - info->depth = 16; + info->mode_8bit = FALSE; else { - info->depth = 0; + info->mode_8bit = FALSE; FIXME("Unsupported output format %i\n", in->bmiHeader.biBitCount); } return ICERR_OK; } -static void convert_depth(char *input, int depth_in, char *output, BITMAPINFOHEADER *out_hdr) -{ - int x, y; - int stride_in = get_stride(out_hdr->biWidth, depth_in); - int stride_out = get_stride(out_hdr->biWidth, out_hdr->biBitCount); - - if (depth_in == 16 && out_hdr->biBitCount == 24) - { - static const unsigned char convert_5to8[] = - { - 0x00, 0x08, 0x10, 0x19, 0x21, 0x29, 0x31, 0x3a, - 0x42, 0x4a, 0x52, 0x5a, 0x63, 0x6b, 0x73, 0x7b, - 0x84, 0x8c, 0x94, 0x9c, 0xa5, 0xad, 0xb5, 0xbd, - 0xc5, 0xce, 0xd6, 0xde, 0xe6, 0xef, 0xf7, 0xff, - }; - - for (y = 0; y < out_hdr->biHeight; y++) - { - WORD *src_row = (WORD *)(input + y * stride_in); - char *out_row = output + y * stride_out; - - for (x = 0; x < out_hdr->biWidth; x++) - { - WORD pixel = *src_row++; - *out_row++ = convert_5to8[(pixel & 0x7c00u) >> 10]; - *out_row++ = convert_5to8[(pixel & 0x03e0u) >> 5]; - *out_row++ = convert_5to8[(pixel & 0x001fu)]; - } - } - } - else - FIXME("Conversion from %d to %d bit unimplemented\n", depth_in, out_hdr->biBitCount); -} - static LRESULT CRAM_Decompress( Msvideo1Context *info, ICDECOMPRESS *icd, DWORD size ) { LONG width, height, stride, sz; - void *output; TRACE("ICM_DECOMPRESS %p %p %d\n", info, icd, size); @@ -457,33 +405,18 @@ static LRESULT CRAM_Decompress( Msvideo1Context *info, ICDECOMPRESS *icd, DWORD width = icd->lpbiInput->biWidth; height = icd->lpbiInput->biHeight; + stride = width; /* in bytes or 16bit words */ sz = icd->lpbiInput->biSizeImage; - output = icd->lpOutput; - - if (icd->lpbiOutput->biBitCount != info->depth) + if (info->mode_8bit) { - output = HeapAlloc(GetProcessHeap(), 0, icd->lpbiOutput->biWidth * icd->lpbiOutput->biHeight * info->depth / 8); - if (!output) return ICERR_MEMORY; - } - - if (info->depth == 8) - { - stride = get_stride(width, 8); msvideo1_decode_8bit( width, height, icd->lpInput, sz, - output, stride ); + icd->lpOutput, stride); } else { - stride = get_stride(width, 16) / 2; msvideo1_decode_16bit( width, height, icd->lpInput, sz, - output, stride ); - } - - if (icd->lpbiOutput->biBitCount != info->depth) - { - convert_depth(output, info->depth, icd->lpOutput, icd->lpbiOutput); - HeapFree(GetProcessHeap(), 0, output); + icd->lpOutput, stride); } return ICERR_OK; @@ -492,7 +425,6 @@ static LRESULT CRAM_Decompress( Msvideo1Context *info, ICDECOMPRESS *icd, DWORD static LRESULT CRAM_DecompressEx( Msvideo1Context *info, ICDECOMPRESSEX *icd, DWORD size ) { LONG width, height, stride, sz; - void *output; TRACE("ICM_DECOMPRESSEX %p %p %d\n", info, icd, size); @@ -503,33 +435,18 @@ static LRESULT CRAM_DecompressEx( Msvideo1Context *info, ICDECOMPRESSEX *icd, DW width = icd->lpbiSrc->biWidth; height = icd->lpbiSrc->biHeight; + stride = width; sz = icd->lpbiSrc->biSizeImage; - output = icd->lpDst; - - if (icd->lpbiDst->biBitCount != info->depth) + if (info->mode_8bit) { - output = HeapAlloc(GetProcessHeap(), 0, icd->lpbiDst->biWidth * icd->lpbiDst->biHeight * info->depth / 8); - if (!output) return ICERR_MEMORY; - } - - if (info->depth == 8) - { - stride = get_stride(width, 8); msvideo1_decode_8bit( width, height, icd->lpSrc, sz, - output, stride ); + icd->lpDst, stride); } else { - stride = get_stride(width, 16) / 2; msvideo1_decode_16bit( width, height, icd->lpSrc, sz, - output, stride ); - } - - if (icd->lpbiDst->biBitCount != info->depth) - { - convert_depth(output, info->depth, icd->lpDst, icd->lpbiDst); - HeapFree(GetProcessHeap(), 0, output); + icd->lpDst, stride); } return ICERR_OK; diff --git a/media/doc/README.WINE b/media/doc/README.WINE index dde9cd4aca..50ce55e84b 100644 --- a/media/doc/README.WINE +++ b/media/doc/README.WINE @@ -126,7 +126,7 @@ reactos/dll/win32/mstask # Synced to WineStaging-2.9 reactos/dll/win32/msvcrt20 # Out of sync reactos/dll/win32/msvcrt40 # Out of sync reactos/dll/win32/msvfw32 # Synced to Wine-3.0 -reactos/dll/win32/msvidc32 # Synced to WineStaging-2.9 +reactos/dll/win32/msvidc32 # Synced to Wine-3.0 reactos/dll/win32/msxml # Synced to WineStaging-2.9 reactos/dll/win32/msxml2 # Synced to WineStaging-2.9 reactos/dll/win32/msxml3 # Synced to WineStaging-2.9
7 years, 4 months
1
0
0
0
01/01: [MSVFW32_WINETEST] Sync with Wine 3.0. CORE-14225
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=8e659192608ccced42ccb…
commit 8e659192608ccced42ccb98217327c90a6cd36d6 Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Sat Jan 20 12:32:30 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Sat Jan 20 12:32:30 2018 +0100 [MSVFW32_WINETEST] Sync with Wine 3.0. CORE-14225 --- modules/rostests/winetests/msvfw32/msvfw.c | 374 ----------------------------- 1 file changed, 374 deletions(-) diff --git a/modules/rostests/winetests/msvfw32/msvfw.c b/modules/rostests/winetests/msvfw32/msvfw.c index 9211104777..3fe67026b5 100644 --- a/modules/rostests/winetests/msvfw32/msvfw.c +++ b/modules/rostests/winetests/msvfw32/msvfw.c @@ -25,11 +25,6 @@ #include "wine/test.h" -static inline int get_stride(int width, int depth) -{ - return ((depth * width + 31) >> 3) & ~3; -} - static void test_OpenCase(void) { HIC h; @@ -93,7 +88,6 @@ static void test_Locate(void) { static BITMAPINFOHEADER bi = {sizeof(BITMAPINFOHEADER),32,8, 1,8, BI_RLE8, 0,100000,100000, 0,0}; static BITMAPINFOHEADER bo = {sizeof(BITMAPINFOHEADER),32,8, 1,8, BI_RGB, 0,100000,100000, 0,0}; - BITMAPINFOHEADER tmp = {sizeof(BITMAPINFOHEADER)}; HIC h; DWORD err; @@ -129,45 +123,6 @@ static void test_Locate(void) ok(err == ICERR_OK, "Query cvid->RGB32 height<0: %d\n", err); bo.biHeight = -bo.biHeight; - bi.biWidth = 17; - - bi.biBitCount = 8; - err = ICDecompressGetFormat(h, &bi, &tmp); - ok(err == ICERR_OK, "Query cvid output format: %d\n", err); - ok(tmp.biBitCount == 24, "Expected 24 bit, got %d bit\n", tmp.biBitCount); - ok(tmp.biSizeImage == get_stride(17, 24) * 8, "Expected size %d, got %d\n", - get_stride(17, 24) * 8, tmp.biSizeImage); - - bi.biBitCount = 15; - err = ICDecompressGetFormat(h, &bi, &tmp); - ok(err == ICERR_OK, "Query cvid output format: %d\n", err); - ok(tmp.biBitCount == 24, "Expected 24 bit, got %d bit\n", tmp.biBitCount); - ok(tmp.biSizeImage == get_stride(17, 24) * 8, "Expected size %d, got %d\n", - get_stride(17, 24) * 8, tmp.biSizeImage); - - bi.biBitCount = 16; - err = ICDecompressGetFormat(h, &bi, &tmp); - ok(err == ICERR_OK, "Query cvid output format: %d\n", err); - ok(tmp.biBitCount == 24, "Expected 24 bit, got %d bit\n", tmp.biBitCount); - ok(tmp.biSizeImage == get_stride(17, 24) * 8, "Expected size %d, got %d\n", - get_stride(17, 24) * 8, tmp.biSizeImage); - - bi.biBitCount = 24; - err = ICDecompressGetFormat(h, &bi, &tmp); - ok(err == ICERR_OK, "Query cvid output format: %d\n", err); - ok(tmp.biBitCount == 24, "Expected 24 bit, got %d bit\n", tmp.biBitCount); - ok(tmp.biSizeImage == get_stride(17, 24) * 8, "Expected size %d, got %d\n", - get_stride(17, 24) * 8, tmp.biSizeImage); - - bi.biBitCount = 32; - err = ICDecompressGetFormat(h, &bi, &tmp); - ok(err == ICERR_OK, "Query cvid output format: %d\n", err); - ok(tmp.biBitCount == 24, "Expected 24 bit, got %d bit\n", tmp.biBitCount); - ok(tmp.biSizeImage == get_stride(17, 24) * 8, "Expected size %d, got %d\n", - get_stride(17, 24) * 8, tmp.biSizeImage); - - bi.biWidth = 32; - ok(ICClose(h) == ICERR_OK,"ICClose failed\n"); bo.biBitCount = bi.biBitCount = 8; @@ -247,50 +202,6 @@ static void test_Locate(void) todo_wine ok(err == ICERR_OK, "Query MSVC->RGB16 height<0: %d\n", err); bo.biHeight = -bo.biHeight; - bo.biBitCount = 24; - err = ICDecompressQuery(h, &bi, &bo); - ok(err == ICERR_OK, "Query MSVC 16->24: %d\n", err); - bo.biBitCount = 16; - - bi.biWidth = 553; - - bi.biBitCount = 8; - err = ICDecompressGetFormat(h, &bi, &tmp); - ok(err == ICERR_OK, "Query MSVC output format: %d\n", err); - ok(tmp.biBitCount == 8, "Expected 8 bit, got %d bit\n", tmp.biBitCount); - ok(tmp.biWidth == 552, "Expected width 552, got %d\n", tmp.biWidth); - ok(tmp.biSizeImage == get_stride(552, 8) * 8, "Expected size %d, got %d\n", - get_stride(552, 8) * 8, tmp.biSizeImage); - - bi.biBitCount = 15; - err = ICDecompressGetFormat(h, &bi, &tmp); - ok(err == ICERR_BADFORMAT, "Query MSVC output format: %d\n", err); - - bi.biBitCount = 16; - err = ICDecompressGetFormat(h, &bi, &tmp); - ok(err == ICERR_OK, "Query MSVC output format: %d\n", err); - ok(tmp.biBitCount == 16, "Expected 16 bit, got %d bit\n", tmp.biBitCount); - ok(tmp.biWidth == 552, "Expected width 552, got %d\n", tmp.biWidth); - ok(tmp.biSizeImage == get_stride(552, 16) * 8, "Expected size %d, got %d\n", - get_stride(552, 16) * 8, tmp.biSizeImage); - - bi.biBitCount = 24; - err = ICDecompressGetFormat(h, &bi, &tmp); - ok(err == ICERR_BADFORMAT, "Query MSVC output format: %d\n", err); - - bi.biBitCount = 32; - err = ICDecompressGetFormat(h, &bi, &tmp); - ok(err == ICERR_BADFORMAT, "Query MSVC output format: %d\n", err); - - bi.biHeight = 17; - bi.biBitCount = 8; - err = ICDecompressGetFormat(h, &bi, &tmp); - ok(err == ICERR_OK, "Query MSVC output format: %d\n", err); - ok(tmp.biHeight == 16, "Expected height 16, got %d\n", tmp.biHeight); - bi.biHeight = 8; - - bi.biWidth = 32; - bi.biCompression = mmioFOURCC('m','s','v','c'); err = ICDecompressQuery(h, &bi, &bo); ok(err == ICERR_BADFORMAT, "Query msvc->RGB16: %d\n", err); @@ -374,290 +285,6 @@ static void test_ICSeqCompress(void) ok(err == ICERR_BADHANDLE, "Expected -8, got %d\n", err); } -struct msg_result -{ - int msg_index; - UINT msg; - BOOL output_format; - int width; - int height; - int bits; - int compression; - LRESULT result; - BOOL todo; -}; - -static struct msg_result expected_msgs[] = -{ - /* Wine bug - shouldn't be called */ - { 0, DRV_LOAD, FALSE, 0, 0, 0, 0, TRUE, TRUE}, - { 0, DRV_ENABLE, FALSE, 0, 0, 0, 0, 0, TRUE}, - - { 0, DRV_OPEN, FALSE, 0, 0, 0, 0, 0xdeadbeef, FALSE}, - - /* test 1 */ - { 1, ICM_DECOMPRESS_QUERY, FALSE, 0, 0, 0, 0, ICERR_OK, FALSE}, - { 2, ICM_DECOMPRESS_GET_FORMAT, TRUE, 320, 240, 16, BI_RGB, ICERR_BADFORMAT, FALSE}, - { 3, ICM_DECOMPRESS_QUERY, TRUE, 640, 480, 8, BI_RGB, ICERR_BADFORMAT, FALSE}, - { 4, ICM_DECOMPRESS_QUERY, TRUE, 640, 480, 16, BI_RGB, ICERR_BADFORMAT, FALSE}, - { 5, ICM_DECOMPRESS_QUERY, TRUE, 640, 480, 16, BI_BITFIELDS, ICERR_BADFORMAT, FALSE}, - { 6, ICM_DECOMPRESS_QUERY, TRUE, 640, 480, 24, BI_RGB, ICERR_BADFORMAT, FALSE}, - { 7, ICM_DECOMPRESS_QUERY, TRUE, 640, 480, 32, BI_RGB, ICERR_BADFORMAT, FALSE}, - { 8, ICM_DECOMPRESS_GET_FORMAT, TRUE, 640, 480, 32, BI_RGB, ICERR_OK, FALSE}, - - /* test 2 */ - { 9, ICM_DECOMPRESS_QUERY, FALSE, 0, 0, 0, 0, ICERR_OK, FALSE}, - {10, ICM_DECOMPRESS_GET_FORMAT, TRUE, 320, 240, 16, BI_RGB, ICERR_BADFORMAT, FALSE}, - {11, ICM_DECOMPRESS_QUERY, TRUE, 640, 480, 8, BI_RGB, ICERR_BADFORMAT, FALSE}, - {12, ICM_DECOMPRESS_QUERY, TRUE, 640, 480, 16, BI_RGB, ICERR_OK, FALSE}, - - /* test 3 */ - {13, ICM_DECOMPRESS_QUERY, FALSE, 0, 0, 0, 0, ICERR_OK, FALSE}, - {14, ICM_DECOMPRESS_GET_FORMAT, TRUE, 320, 240, 16, BI_RGB, ICERR_OK, FALSE}, - {15, ICM_DECOMPRESS_QUERY, TRUE, 640, 480, 8, BI_RGB, ICERR_BADFORMAT, FALSE}, - {16, ICM_DECOMPRESS_QUERY, TRUE, 640, 480, 16, BI_RGB, ICERR_OK, FALSE}, - - /* test 4 */ - {17, ICM_DECOMPRESS_QUERY, FALSE, 0, 0, 0, 0, ICERR_OK, FALSE}, - {18, ICM_DECOMPRESS_GET_FORMAT, TRUE, 320, 240, 16, BI_RGB, ICERR_BADFORMAT, FALSE}, - {19, ICM_DECOMPRESS_QUERY, TRUE, 640, 480, 24, BI_RGB, ICERR_BADFORMAT, FALSE}, - {20, ICM_DECOMPRESS_QUERY, TRUE, 640, 480, 32, BI_RGB, ICERR_BADFORMAT, FALSE}, - {21, ICM_DECOMPRESS_GET_FORMAT, TRUE, 640, 480, 32, BI_RGB, ICERR_OK, FALSE}, - - /* test 5 */ - {22, ICM_DECOMPRESS_QUERY, FALSE, 0, 0, 0, 0, ICERR_OK, FALSE}, - {23, ICM_DECOMPRESS_GET_FORMAT, TRUE, 320, 240, 16, BI_RGB, ICERR_OK, FALSE}, - {24, ICM_DECOMPRESS_QUERY, TRUE, 640, 480, 32, BI_RGB, ICERR_OK, FALSE}, - - /* test 6 */ - {25, ICM_DECOMPRESS_QUERY, FALSE, 0, 0, 0, 0, ICERR_OK, FALSE}, - {26, ICM_DECOMPRESS_GET_FORMAT, TRUE, 320, 240, 16, BI_RGB, ICERR_OK, FALSE}, - {27, ICM_DECOMPRESS_QUERY, TRUE, 640, 480, 32, BI_RGB, ICERR_OK, FALSE}, - - /* test 7 */ - {28, ICM_DECOMPRESS_QUERY, FALSE, 0, 0, 0, 0, ICERR_OK, FALSE}, - {29, ICM_DECOMPRESS_GET_FORMAT, TRUE, 320, 240, 16, BI_RGB, ICERR_OK, FALSE}, - {30, ICM_DECOMPRESS_QUERY, TRUE, 640, 480, 9, BI_RGB, ICERR_BADFORMAT, FALSE}, - {31, ICM_DECOMPRESS_QUERY, TRUE, 640, 480, 32, BI_RGB, ICERR_BADFORMAT, FALSE}, - {32, ICM_DECOMPRESS_GET_FORMAT, TRUE, 640, 480, 32, BI_RGB, ICERR_OK, FALSE}, - - /* test 8 */ - {33, ICM_DECOMPRESS_QUERY, FALSE, 0, 0, 0, 0, ICERR_OK, FALSE}, - {34, ICM_DECOMPRESS_GET_FORMAT, TRUE, 320, 240, 16, BI_RGB, ICERR_OK, FALSE}, - {35, ICM_DECOMPRESS_QUERY, TRUE, 800, 600, 32, BI_RGB, ICERR_OK, FALSE}, - - /* test 9 */ - {36, ICM_DECOMPRESS_QUERY, FALSE, 0, 0, 0, 0, ICERR_OK, FALSE}, - {37, ICM_DECOMPRESS_GET_FORMAT, TRUE, 320, 240, 16, BI_RGB, ICERR_OK, FALSE}, - {38, ICM_DECOMPRESS_QUERY, TRUE, 640, 480, 32, BI_RGB, ICERR_OK, FALSE}, - - /* test 10 */ - {39, ICM_DECOMPRESS_QUERY, FALSE, 0, 0, 0, 0, ICERR_OK, FALSE}, - {40, ICM_DECOMPRESS_GET_FORMAT, TRUE, 320, 240, 16, BI_RGB, ICERR_OK, FALSE}, - {41, ICM_DECOMPRESS_QUERY, TRUE, 640, 480, 32, BI_RGB, ICERR_OK, FALSE}, - - /* test 11 */ - {42, ICM_DECOMPRESS_QUERY, FALSE, 0, 0, 0, 0, ICERR_OK, FALSE}, - {43, ICM_DECOMPRESS_GET_FORMAT, TRUE, 320, 240, 16, BI_RGB, ICERR_OK, FALSE}, - {44, ICM_DECOMPRESS_QUERY, TRUE, 270, 270, 8, BI_RGB, ICERR_OK, FALSE}, - {45, ICM_DECOMPRESS_GET_PALETTE, FALSE, 0, 0, 0, 0, ICERR_UNSUPPORTED, FALSE}, - - /* test 12 */ - {46, ICM_DECOMPRESS_QUERY, FALSE, 0, 0, 0, 0, ICERR_OK, FALSE}, - {47, ICM_DECOMPRESS_GET_FORMAT, TRUE, 320, 240, 16, BI_RGB, ICERR_OK, FALSE}, - {48, ICM_DECOMPRESS_QUERY, TRUE, 270, 270, 16, BI_RGB, ICERR_OK, FALSE}, - - /* test 13 */ - {49, ICM_DECOMPRESS_QUERY, FALSE, 0, 0, 0, 0, ICERR_OK, FALSE}, - {50, ICM_DECOMPRESS_GET_FORMAT, TRUE, 320, 240, 16, BI_RGB, ICERR_OK, FALSE}, - {51, ICM_DECOMPRESS_QUERY, TRUE, 270, 270, 24, BI_RGB, ICERR_OK, FALSE}, - - /* test 14 */ - {52, ICM_DECOMPRESS_QUERY, FALSE, 0, 0, 0, 0, ICERR_OK, FALSE}, - {53, ICM_DECOMPRESS_GET_FORMAT, TRUE, 320, 240, 16, BI_RGB, ICERR_OK, FALSE}, - {54, ICM_DECOMPRESS_QUERY, TRUE, 640, 480, 4, BI_RGB, ICERR_OK, FALSE}, - - /* Wine bug - shouldn't be called */ - {55, DRV_DISABLE, FALSE, 0, 0, 0, 0, ICERR_OK, TRUE}, - {55, DRV_FREE, FALSE, 0, 0, 0, 0, ICERR_OK, TRUE}, -}; - -static int msg_index = 0; - -static struct msg_result *get_expected_msg(UINT msg) -{ - int i = 0; - for(; i < sizeof(expected_msgs) / sizeof(expected_msgs[0]); i++) - { - if (expected_msgs[i].msg_index == msg_index && expected_msgs[i].msg == msg) - return &expected_msgs[i]; - } - return NULL; -} - -LRESULT WINAPI driver_proc_test(DWORD_PTR dwDriverId, HDRVR hdrvr, UINT msg, - LPARAM lParam1, LPARAM lParam2) -{ - struct msg_result *expected = get_expected_msg(msg); - LRESULT res = expected ? expected->result : ICERR_UNSUPPORTED; - - if (msg == DRV_CLOSE) - return ICERR_OK; - - if (!expected) - { - ok(0, "unexpected message: %04x %ld %ld at msg index %d\n", - msg, lParam1, lParam2, msg_index); - return ICERR_UNSUPPORTED; - } - else if (expected->todo) - { - todo_wine ok(0, "unexpected message: %04x %ld %ld at msg index %d\n", - msg, lParam1, lParam2, msg_index); - return res; - } - - switch (msg) - { - case ICM_DECOMPRESS_QUERY: - { - BITMAPINFOHEADER *out = (BITMAPINFOHEADER *)lParam2; - - if (!lParam2) - { - trace("query -> without format\n"); - ok(!expected->output_format, "Expected no output format pointer\n"); - break; - } - - ok(expected->output_format, "Expected output format pointer\n"); - ok(out->biWidth == expected->width, - "Expected width %d, got %d\n", expected->width, out->biWidth); - ok(out->biHeight == expected->height, - "Expected height %d, got %d\n", expected->height, out->biHeight); - ok(out->biBitCount == expected->bits, - "Expected biBitCount %d, got %d\n", expected->bits, out->biBitCount); - ok(out->biCompression == expected->compression, - "Expected compression %d, got %d\n", expected->compression, out->biCompression); - ok(out->biSizeImage == get_stride(out->biWidth, out->biBitCount) * out->biHeight, - "Expected biSizeImage %d, got %d\n", get_stride(out->biWidth, out->biBitCount) * out->biHeight, - out->biSizeImage); - - trace("query -> width: %d, height: %d, bit: %d, compression: %d, size: %d\n", - out->biWidth, out->biHeight, out->biBitCount, out->biCompression, out->biSizeImage); - break; - } - - case ICM_DECOMPRESS_GET_FORMAT: - { - BITMAPINFOHEADER *out = (BITMAPINFOHEADER *)lParam2; - - if (!lParam2) - { - trace("format -> without format\n"); - ok(!expected->output_format, "Expected no output format pointer\n"); - break; - } - - ok(expected->output_format, "Expected output format pointer\n"); - ok(out->biWidth == expected->width, - "Expected width %d, got %d\n", expected->width, out->biWidth); - ok(out->biHeight == expected->height, - "Expected height %d, got %d\n", expected->height, out->biHeight); - ok(out->biBitCount == expected->bits, - "Expected biBitCount %d, got %d\n", expected->bits, out->biBitCount); - ok(out->biCompression == expected->compression, - "Expected compression %d, got %d\n", expected->compression, out->biCompression); - - trace("format -> width: %d, height: %d, bit: %d, compression: %d, size: %d\n", - out->biWidth, out->biHeight, out->biBitCount, out->biCompression, out->biSizeImage); - - out->biBitCount = 64; - break; - } - } - - msg_index++; - return res; -} - - -void test_ICGetDisplayFormat(void) -{ - static const struct - { - int bits_wanted; - int bits_expected; - int dx; - int width_expected; - int dy; - int height_expected; - int msg_index; - } - tests[] = - { - { 8, 64, 0, 640, 0, 480, 9}, - { 8, 16, 0, 640, 0, 480, 13}, - { 8, 16, 0, 640, 0, 480, 17}, - {24, 64, 0, 640, 0, 480, 22}, - {32, 32, 0, 640, 0, 480, 25}, - { 0, 32, 0, 640, 0, 480, 28}, - { 9, 64, 0, 640, 0, 480, 33}, - {32, 32, 800, 800, 600, 600, 36}, - {32, 32, -1, 640, -1, 480, 39}, - {32, 32, -90, 640, -60, 480, 42}, - { 8, 8, 270, 270, 270, 270, 46}, - {16, 16, 270, 270, 270, 270, 49}, - {24, 24, 270, 270, 270, 270, 52}, - { 4, 4, 0, 640, 0, 480, 55}, - }; - - HIC ic, ic2; - BITMAPINFOHEADER in; - BITMAPINFOHEADER out; - int real_depth; - int i; - - ic = ICOpenFunction(ICTYPE_VIDEO, 0xdeadbeef, ICMODE_DECOMPRESS, driver_proc_test); - ok(!!ic, "Opening driver failed\n"); - - for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) - { - memset(&in, 0, sizeof(in)); - memset(&out, 0, sizeof(out)); - - in.biSize = sizeof(in); - in.biWidth = 640; - in.biHeight = 480; - in.biPlanes = 1; - in.biBitCount = 32; - in.biCompression = BI_PNG; - in.biSizeImage = 1024; - - out.biBitCount = 16; - out.biWidth = 320; - out.biHeight = 240; - - ic2 = ICGetDisplayFormat(ic, &in, &out, tests[i].bits_wanted, tests[i].dx, tests[i].dy); - ok(!!ic2, "Expected ICGetDisplayFormat to succeeded\n"); - - ok(out.biBitCount == tests[i].bits_expected, - "Expected biBitCount %d, got %d\n", tests[i].bits_expected, out.biBitCount); - ok(out.biWidth == tests[i].width_expected, - "Expected biWidth %d, got %d\n", tests[i].width_expected, out.biWidth); - ok(out.biHeight == tests[i].height_expected, - "Expected biHeight %d, got %d\n", tests[i].height_expected, out.biHeight); - real_depth = (out.biBitCount > 32) ? 32 : out.biBitCount; - ok(out.biSizeImage == get_stride(out.biWidth, real_depth) * out.biHeight, - "Expected biSizeImage %d, got %d\n", get_stride(out.biWidth, real_depth) * out.biHeight, - out.biSizeImage); - ok(msg_index == tests[i].msg_index, - "Expected msg_index %d, got %d\n", tests[i].msg_index, msg_index); - } - - ICClose(ic); -} - static void test_ICInfo(void) { ICINFO info, info2; @@ -697,6 +324,5 @@ START_TEST(msvfw) test_OpenCase(); test_Locate(); test_ICSeqCompress(); - test_ICGetDisplayFormat(); test_ICInfo(); }
7 years, 4 months
1
0
0
0
01/01: [MSVFW32] Sync with Wine 3.0. CORE-14225
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=76e5652fb4ac6b84b6ce7…
commit 76e5652fb4ac6b84b6ce79f5135f23d2d8a10055 Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Sat Jan 20 12:31:50 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Sat Jan 20 12:31:50 2018 +0100 [MSVFW32] Sync with Wine 3.0. CORE-14225 --- dll/win32/msvfw32/msvideo_main.c | 101 +++++++++------------------------------ media/doc/README.WINE | 2 +- 2 files changed, 23 insertions(+), 80 deletions(-) diff --git a/dll/win32/msvfw32/msvideo_main.c b/dll/win32/msvfw32/msvideo_main.c index 931effee64..ebe56ee4a8 100644 --- a/dll/win32/msvfw32/msvideo_main.c +++ b/dll/win32/msvfw32/msvideo_main.c @@ -90,11 +90,6 @@ static const char *wine_dbgstr_icerr( int ret ) return str; } -static inline int get_stride(int width, int depth) -{ - return ((depth * width + 31) >> 3) & ~3; -} - static WINE_HIC* MSVIDEO_FirstHic /* = NULL */; typedef struct _reg_driver reg_driver; @@ -714,86 +709,25 @@ HIC VFWAPI ICGetDisplayFormat( HIC hic,LPBITMAPINFOHEADER lpbiIn,LPBITMAPINFOHEADER lpbiOut, INT depth,INT dx,INT dy) { - static const struct - { - int depth; - int compression; - } - try_depths[] = - { - { 8, BI_RGB}, - {16, BI_RGB}, - {16, BI_BITFIELDS}, - {24, BI_RGB}, - {32, BI_RGB}, - }; + HIC tmphic = hic; - int screen_depth, i; - BOOL found = FALSE; - HIC tmphic; - HDC hdc; + TRACE("(%p,%p,%p,%d,%d,%d)!\n",hic,lpbiIn,lpbiOut,depth,dx,dy); - TRACE("(%p,%p,%p,%d,%d,%d)!\n", hic, lpbiIn, lpbiOut, depth, dx, dy); - - tmphic = hic ? hic : ICLocate(ICTYPE_VIDEO, 0, lpbiIn, NULL, ICMODE_DECOMPRESS); - if (!tmphic) return tmphic; - - hdc = GetDC(0); - screen_depth = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES); - ReleaseDC(0, hdc); - - if (dx <= 0) dx = lpbiIn->biWidth; - if (dy <= 0) dy = lpbiIn->biHeight; - if (!depth) depth = screen_depth; + if (!tmphic) { + tmphic=ICLocate(ICTYPE_VIDEO,0,lpbiIn,NULL,ICMODE_DECOMPRESS); + if (!tmphic) + return tmphic; + } + if ((dy == lpbiIn->biHeight) && (dx == lpbiIn->biWidth)) + dy = dx = 0; /* no resize needed */ /* Can we decompress it ? */ - if (ICDecompressQuery(tmphic, lpbiIn, NULL) != ICERR_OK) + if (ICDecompressQuery(tmphic,lpbiIn,NULL) != 0) goto errout; /* no, sorry */ ICSendMessage(tmphic, ICM_DECOMPRESS_GET_FORMAT, (DWORD_PTR)lpbiIn, (DWORD_PTR)lpbiOut); - lpbiOut->biSize = sizeof(BITMAPINFOHEADER); - lpbiOut->biWidth = dx; - lpbiOut->biHeight = dy; - lpbiOut->biPlanes = 1; - - for (i = 0; i < sizeof(try_depths) / sizeof(try_depths[0]); i++) - { - if (!found && try_depths[i].depth != depth) - continue; - - found = TRUE; - lpbiOut->biBitCount = try_depths[i].depth; - lpbiOut->biCompression = try_depths[i].compression; - lpbiOut->biSizeImage = dx * get_stride(dy, lpbiOut->biBitCount); - - if (ICDecompressQuery(tmphic, lpbiIn, lpbiOut) == ICERR_OK) - { - if (try_depths[i].depth == 8) - ICDecompressGetPalette(tmphic, lpbiIn, lpbiOut); - goto success; - } - } - - if (!found) - { - lpbiOut->biBitCount = depth; - lpbiOut->biCompression = BI_RGB; - lpbiOut->biSizeImage = dx * get_stride(dy, lpbiOut->biBitCount); - if (ICDecompressQuery(tmphic, lpbiIn, lpbiOut) == ICERR_OK) - goto success; - - lpbiOut->biBitCount = screen_depth; - lpbiOut->biCompression = BI_RGB; - lpbiOut->biSizeImage = dx * get_stride(dy, lpbiOut->biBitCount); - if (ICDecompressQuery(tmphic, lpbiIn, lpbiOut) == ICERR_OK) - goto success; - } - - if (ICSendMessage(tmphic, ICM_DECOMPRESS_GET_FORMAT, (DWORD_PTR)lpbiIn, (DWORD_PTR)lpbiOut)) - goto errout; - - if (lpbiOut->biCompression != 0) { + if (lpbiOut->biCompression != 0) { FIXME("Ooch, how come decompressor outputs compressed data (%d)??\n", lpbiOut->biCompression); } @@ -802,11 +736,20 @@ HIC VFWAPI ICGetDisplayFormat( lpbiOut->biSize); lpbiOut->biSize = sizeof(*lpbiOut); } + if (!depth) { + HDC hdc; + + hdc = GetDC(0); + depth = GetDeviceCaps(hdc,BITSPIXEL)*GetDeviceCaps(hdc,PLANES); + ReleaseDC(0,hdc); + if (depth==15) depth = 16; + if (depth<8) depth = 8; + } + if (lpbiIn->biBitCount == 8) + depth = 8; -success: TRACE("=> %p\n", tmphic); return tmphic; - errout: if (hic!=tmphic) ICClose(tmphic); diff --git a/media/doc/README.WINE b/media/doc/README.WINE index 1ed35c46fd..dde9cd4aca 100644 --- a/media/doc/README.WINE +++ b/media/doc/README.WINE @@ -125,7 +125,7 @@ reactos/dll/win32/mssip32 # Synced to WineStaging-2.9 reactos/dll/win32/mstask # Synced to WineStaging-2.9 reactos/dll/win32/msvcrt20 # Out of sync reactos/dll/win32/msvcrt40 # Out of sync -reactos/dll/win32/msvfw32 # Synced to WineStaging-2.9 +reactos/dll/win32/msvfw32 # Synced to Wine-3.0 reactos/dll/win32/msvidc32 # Synced to WineStaging-2.9 reactos/dll/win32/msxml # Synced to WineStaging-2.9 reactos/dll/win32/msxml2 # Synced to WineStaging-2.9
7 years, 4 months
1
0
0
0
01/01: [MSI_WINETEST] Sync with Wine 3.0. CORE-14225
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=f860a7802ce55e530a3d9…
commit f860a7802ce55e530a3d9e4ea0cba7ea30440f1b Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Sat Jan 20 12:30:30 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Sat Jan 20 12:30:30 2018 +0100 [MSI_WINETEST] Sync with Wine 3.0. CORE-14225 --- modules/rostests/winetests/msi/db.c | 173 +- modules/rostests/winetests/msi/format.c | 511 ------ modules/rostests/winetests/msi/install.c | 281 +-- modules/rostests/winetests/msi/package.c | 2883 ++++++++++++++---------------- modules/rostests/winetests/msi/record.c | 10 +- 5 files changed, 1528 insertions(+), 2330 deletions(-) diff --git a/modules/rostests/winetests/msi/db.c b/modules/rostests/winetests/msi/db.c index 5f0738d845..15fb93c82e 100644 --- a/modules/rostests/winetests/msi/db.c +++ b/modules/rostests/winetests/msi/db.c @@ -193,7 +193,7 @@ static UINT run_queryW( MSIHANDLE hdb, MSIHANDLE hrec, const WCHAR *query ) static UINT create_component_table( MSIHANDLE hdb ) { - return run_query( hdb, 0, + UINT r = run_query( hdb, 0, "CREATE TABLE `Component` ( " "`Component` CHAR(72) NOT NULL, " "`ComponentId` CHAR(38), " @@ -202,87 +202,99 @@ static UINT create_component_table( MSIHANDLE hdb ) "`Condition` CHAR(255), " "`KeyPath` CHAR(72) " "PRIMARY KEY `Component`)" ); + ok(r == ERROR_SUCCESS, "Failed to create Component table: %u\n", r); + return r; } static UINT create_custom_action_table( MSIHANDLE hdb ) { - return run_query( hdb, 0, + UINT r = run_query( hdb, 0, "CREATE TABLE `CustomAction` ( " "`Action` CHAR(72) NOT NULL, " "`Type` SHORT NOT NULL, " "`Source` CHAR(72), " "`Target` CHAR(255) " "PRIMARY KEY `Action`)" ); + ok(r == ERROR_SUCCESS, "Failed to create CustomAction table: %u\n", r); + return r; } static UINT create_directory_table( MSIHANDLE hdb ) { - return run_query( hdb, 0, + UINT r = run_query( hdb, 0, "CREATE TABLE `Directory` ( " "`Directory` CHAR(255) NOT NULL, " "`Directory_Parent` CHAR(255), " "`DefaultDir` CHAR(255) NOT NULL " "PRIMARY KEY `Directory`)" ); + ok(r == ERROR_SUCCESS, "Failed to create Directory table: %u\n", r); + return r; } static UINT create_feature_components_table( MSIHANDLE hdb ) { - return run_query( hdb, 0, + UINT r = run_query( hdb, 0, "CREATE TABLE `FeatureComponents` ( " "`Feature_` CHAR(38) NOT NULL, " "`Component_` CHAR(72) NOT NULL " "PRIMARY KEY `Feature_`, `Component_` )" ); + ok(r == ERROR_SUCCESS, "Failed to create FeatureComponents table: %u\n", r); + return r; } static UINT create_std_dlls_table( MSIHANDLE hdb ) { - return run_query( hdb, 0, + UINT r = run_query( hdb, 0, "CREATE TABLE `StdDlls` ( " "`File` CHAR(255) NOT NULL, " "`Binary_` CHAR(72) NOT NULL " "PRIMARY KEY `File` )" ); + ok(r == ERROR_SUCCESS, "Failed to create StdDlls table: %u\n", r); + return r; } static UINT create_binary_table( MSIHANDLE hdb ) { - return run_query( hdb, 0, - "CREATE TABLE `Binary` ( " + UINT r = run_query( hdb, 0, + "CREATE TABLE `Binary` ( " "`Name` CHAR(72) NOT NULL, " "`Data` CHAR(72) NOT NULL " "PRIMARY KEY `Name` )" ); + ok(r == ERROR_SUCCESS, "Failed to create Binary table: %u\n", r); + return r; } -#define make_add_entry(type, qtext) \ - static UINT add##_##type##_##entry( MSIHANDLE hdb, const char *values ) \ - { \ - char insert[] = qtext; \ - char *query; \ - UINT sz, r; \ - sz = strlen(values) + sizeof insert; \ - query = HeapAlloc(GetProcessHeap(),0,sz); \ - sprintf(query,insert,values); \ - r = run_query( hdb, 0, query ); \ - HeapFree(GetProcessHeap(), 0, query); \ - return r; \ - } +static inline UINT add_entry(const char *file, int line, const char *type, MSIHANDLE hdb, const char *values, const char *insert) +{ + char *query; + UINT sz, r; + + sz = strlen(values) + strlen(insert) + 1; + query = HeapAlloc(GetProcessHeap(), 0, sz); + sprintf(query, insert, values); + r = run_query(hdb, 0, query); + HeapFree(GetProcessHeap(), 0, query); + ok_(file, line)(r == ERROR_SUCCESS, "failed to insert into %s table: %u\n", type, r); + return r; +} -make_add_entry(component, - "INSERT INTO `Component` " - "(`Component`, `ComponentId`, `Directory_`, " +#define add_component_entry(hdb, values) add_entry(__FILE__, __LINE__, "Component", hdb, values, \ + "INSERT INTO `Component` " \ + "(`Component`, `ComponentId`, `Directory_`, " \ "`Attributes`, `Condition`, `KeyPath`) VALUES( %s )") -make_add_entry(custom_action, - "INSERT INTO `CustomAction` " +#define add_custom_action_entry(hdb, values) add_entry(__FILE__, __LINE__, "CustomAction", hdb, values, \ + "INSERT INTO `CustomAction` " \ "(`Action`, `Type`, `Source`, `Target`) VALUES( %s )") -make_add_entry(feature_components, - "INSERT INTO `FeatureComponents` " +#define add_feature_components_entry(hdb, values) add_entry(__FILE__, __LINE__, "FeatureComponents", hdb, values, \ + "INSERT INTO `FeatureComponents` " \ "(`Feature_`, `Component_`) VALUES( %s )") -make_add_entry(std_dlls, +#define add_std_dlls_entry(hdb, values) add_entry(__FILE__, __LINE__, "StdDlls", hdb, values, \ "INSERT INTO `StdDlls` (`File`, `Binary_`) VALUES( %s )") -make_add_entry(binary, +#define add_binary_entry(hdb, values) add_entry(__FILE__, __LINE__, "Binary", hdb, values, \ "INSERT INTO `Binary` (`Name`, `Data`) VALUES( %s )") static void test_msiinsert(void) @@ -3117,8 +3129,7 @@ static MSIHANDLE create_package_db(const WCHAR *filename) res = set_summary_info(hdb); ok( res == ERROR_SUCCESS , "Failed to set summary info\n" ); - res = create_directory_table(hdb); - ok( res == ERROR_SUCCESS , "Failed to create directory table\n" ); + create_directory_table(hdb); return hdb; } @@ -3447,62 +3458,28 @@ static void test_join(void) hdb = create_db(); ok( hdb, "failed to create db\n"); - r = create_component_table( hdb ); - ok( r == ERROR_SUCCESS, "cannot create Component table: %d\n", r ); - - r = add_component_entry( hdb, "'zygomatic', 'malar', 'INSTALLDIR', 0, '', ''" ); - ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); - - r = add_component_entry( hdb, "'maxilla', 'alveolar', 'INSTALLDIR', 0, '', ''" ); - ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); - - r = add_component_entry( hdb, "'nasal', 'septum', 'INSTALLDIR', 0, '', ''" ); - ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); - - r = add_component_entry( hdb, "'mandible', 'ramus', 'INSTALLDIR', 0, '', ''" ); - ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); - - r = create_feature_components_table( hdb ); - ok( r == ERROR_SUCCESS, "cannot create FeatureComponents table: %d\n", r ); - - r = add_feature_components_entry( hdb, "'procerus', 'maxilla'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); - - r = add_feature_components_entry( hdb, "'procerus', 'nasal'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); - - r = add_feature_components_entry( hdb, "'nasalis', 'nasal'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); - - r = add_feature_components_entry( hdb, "'nasalis', 'mandible'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); - - r = add_feature_components_entry( hdb, "'nasalis', 'notacomponent'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); - - r = add_feature_components_entry( hdb, "'mentalis', 'zygomatic'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); - - r = create_std_dlls_table( hdb ); - ok( r == ERROR_SUCCESS, "cannot create StdDlls table: %d\n", r ); - - r = add_std_dlls_entry( hdb, "'msvcp.dll', 'msvcp.dll.01234'" ); - ok( r == ERROR_SUCCESS, "cannot add std dlls: %d\n", r ); - - r = add_std_dlls_entry( hdb, "'msvcr.dll', 'msvcr.dll.56789'" ); - ok( r == ERROR_SUCCESS, "cannot add std dlls: %d\n", r ); - - r = create_binary_table( hdb ); - ok( r == ERROR_SUCCESS, "cannot create Binary table: %d\n", r ); - - r = add_binary_entry( hdb, "'msvcp.dll.01234', 'abcdefgh'" ); - ok( r == ERROR_SUCCESS, "cannot add binary: %d\n", r ); - - r = add_binary_entry( hdb, "'msvcr.dll.56789', 'ijklmnop'" ); - ok( r == ERROR_SUCCESS, "cannot add binary: %d\n", r ); - - r = add_binary_entry( hdb, "'single.dll.31415', 'msvcp.dll'" ); - ok( r == ERROR_SUCCESS, "cannot add binary: %d\n", r ); + create_component_table( hdb ); + add_component_entry( hdb, "'zygomatic', 'malar', 'INSTALLDIR', 0, '', ''" ); + add_component_entry( hdb, "'maxilla', 'alveolar', 'INSTALLDIR', 0, '', ''" ); + add_component_entry( hdb, "'nasal', 'septum', 'INSTALLDIR', 0, '', ''" ); + add_component_entry( hdb, "'mandible', 'ramus', 'INSTALLDIR', 0, '', ''" ); + + create_feature_components_table( hdb ); + add_feature_components_entry( hdb, "'procerus', 'maxilla'" ); + add_feature_components_entry( hdb, "'procerus', 'nasal'" ); + add_feature_components_entry( hdb, "'nasalis', 'nasal'" ); + add_feature_components_entry( hdb, "'nasalis', 'mandible'" ); + add_feature_components_entry( hdb, "'nasalis', 'notacomponent'" ); + add_feature_components_entry( hdb, "'mentalis', 'zygomatic'" ); + + create_std_dlls_table( hdb ); + add_std_dlls_entry( hdb, "'msvcp.dll', 'msvcp.dll.01234'" ); + add_std_dlls_entry( hdb, "'msvcr.dll', 'msvcr.dll.56789'" ); + + create_binary_table( hdb ); + add_binary_entry( hdb, "'msvcp.dll.01234', 'abcdefgh'" ); + add_binary_entry( hdb, "'msvcr.dll.56789', 'ijklmnop'" ); + add_binary_entry( hdb, "'single.dll.31415', 'msvcp.dll'" ); query = "CREATE TABLE `One` (`A` SHORT, `B` SHORT PRIMARY KEY `A`)"; r = run_query( hdb, 0, query); @@ -4790,7 +4767,7 @@ static void test_update(void) MsiCloseHandle(rec); r = MsiViewFetch(view, &rec); - ok(r == ERROR_NO_MORE_ITEMS, "Expectd ERROR_NO_MORE_ITEMS, got %d\n", r); + ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r); MsiViewClose(view); MsiCloseHandle(view); @@ -7657,14 +7634,10 @@ static void test_dbtopackage(void) set_summary_info(hdb); - r = create_directory_table(hdb); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + create_directory_table(hdb); - r = create_custom_action_table(hdb); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_custom_action_entry(hdb, "'SetProp', 51, 'MYPROP', 'grape'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + create_custom_action_table(hdb); + add_custom_action_entry(hdb, "'SetProp', 51, 'MYPROP', 'grape'"); sprintf(package, "#%u", hdb); r = MsiOpenPackageA(package, &hpkg); @@ -7721,14 +7694,10 @@ static void test_dbtopackage(void) set_summary_info(hdb); - r = create_directory_table(hdb); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = create_custom_action_table(hdb); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + create_directory_table(hdb); - r = add_custom_action_entry(hdb, "'SetProp', 51, 'MYPROP', 'grape'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + create_custom_action_table(hdb); + add_custom_action_entry(hdb, "'SetProp', 51, 'MYPROP', 'grape'"); sprintf(package, "#%u", hdb); r = MsiOpenPackageA(package, &hpkg); diff --git a/modules/rostests/winetests/msi/format.c b/modules/rostests/winetests/msi/format.c index a8bd290069..cc00af063f 100644 --- a/modules/rostests/winetests/msi/format.c +++ b/modules/rostests/winetests/msi/format.c @@ -22,206 +22,6 @@ #include "precomp.h" static const char msifile[] = "winetest-format.msi"; -static const WCHAR msifileW[] = - {'w','i','n','e','t','e','s','t','-','f','o','r','m','a','t','.','m','s','i',0}; - -static UINT run_query( MSIHANDLE hdb, const char *query ) -{ - MSIHANDLE hview = 0; - UINT r; - - r = MsiDatabaseOpenViewA(hdb, query, &hview); - if( r != ERROR_SUCCESS ) - return r; - - r = MsiViewExecute(hview, 0); - if( r == ERROR_SUCCESS ) - r = MsiViewClose(hview); - MsiCloseHandle(hview); - return r; -} - -static UINT create_feature_table( MSIHANDLE hdb ) -{ - return run_query( hdb, - "CREATE TABLE `Feature` ( " - "`Feature` CHAR(38) NOT NULL, " - "`Feature_Parent` CHAR(38), " - "`Title` CHAR(64), " - "`Description` CHAR(255), " - "`Display` SHORT NOT NULL, " - "`Level` SHORT NOT NULL, " - "`Directory_` CHAR(72), " - "`Attributes` SHORT NOT NULL " - "PRIMARY KEY `Feature`)" ); -} - -static UINT create_component_table( MSIHANDLE hdb ) -{ - return run_query( hdb, - "CREATE TABLE `Component` ( " - "`Component` CHAR(72) NOT NULL, " - "`ComponentId` CHAR(38), " - "`Directory_` CHAR(72) NOT NULL, " - "`Attributes` SHORT NOT NULL, " - "`Condition` CHAR(255), " - "`KeyPath` CHAR(72) " - "PRIMARY KEY `Component`)" ); -} - -static UINT create_feature_components_table( MSIHANDLE hdb ) -{ - return run_query( hdb, - "CREATE TABLE `FeatureComponents` ( " - "`Feature_` CHAR(38) NOT NULL, " - "`Component_` CHAR(72) NOT NULL " - "PRIMARY KEY `Feature_`, `Component_` )" ); -} - -static UINT create_file_table( MSIHANDLE hdb ) -{ - return run_query( hdb, - "CREATE TABLE `File` (" - "`File` CHAR(72) NOT NULL, " - "`Component_` CHAR(72) NOT NULL, " - "`FileName` CHAR(255) NOT NULL, " - "`FileSize` LONG NOT NULL, " - "`Version` CHAR(72), " - "`Language` CHAR(20), " - "`Attributes` SHORT, " - "`Sequence` SHORT NOT NULL " - "PRIMARY KEY `File`)" ); -} - -static UINT create_custom_action_table( MSIHANDLE hdb ) -{ - return run_query( hdb, - "CREATE TABLE `CustomAction` (" - "`Action` CHAR(72) NOT NULL, " - "`Type` SHORT NOT NULL, " - "`Source` CHAR(75), " - "`Target` CHAR(255) " - "PRIMARY KEY `Action`)" ); -} - -#define make_add_entry(type, qtext) \ - static UINT add##_##type##_##entry( MSIHANDLE hdb, const char *values ) \ - { \ - char insert[] = qtext; \ - char *query; \ - UINT sz, r; \ - sz = strlen(values) + sizeof insert; \ - query = HeapAlloc(GetProcessHeap(),0,sz); \ - sprintf(query,insert,values); \ - r = run_query( hdb, query ); \ - HeapFree(GetProcessHeap(), 0, query); \ - return r; \ - } - -make_add_entry(feature, - "INSERT INTO `Feature` " - "(`Feature`, `Feature_Parent`, `Title`, `Description`, " - "`Display`, `Level`, `Directory_`, `Attributes`) VALUES( %s )") - -make_add_entry(component, - "INSERT INTO `Component` " - "(`Component`, `ComponentId`, `Directory_`, " - "`Attributes`, `Condition`, `KeyPath`) VALUES( %s )") - -make_add_entry(feature_components, - "INSERT INTO `FeatureComponents` " - "(`Feature_`, `Component_`) VALUES( %s )") - -make_add_entry(file, - "INSERT INTO `File` " - "(`File`, `Component_`, `FileName`, `FileSize`, " - "`Version`, `Language`, `Attributes`, `Sequence`) VALUES( %s )") - -make_add_entry(directory, - "INSERT INTO `Directory` " - "(`Directory`,`Directory_Parent`,`DefaultDir`) VALUES( %s )") - -make_add_entry(custom_action, - "INSERT INTO `CustomAction` " - "(`Action`, `Type`, `Source`, `Target`) VALUES( %s )") - -static UINT set_summary_info(MSIHANDLE hdb) -{ - UINT res; - MSIHANDLE suminfo; - - /* build summary info */ - res = MsiGetSummaryInformationA(hdb, NULL, 7, &suminfo); - ok( res == ERROR_SUCCESS , "Failed to open summaryinfo\n" ); - - res = MsiSummaryInfoSetPropertyA(suminfo,2, VT_LPSTR, 0,NULL, - "Installation Database"); - ok( res == ERROR_SUCCESS , "Failed to set summary info\n" ); - - res = MsiSummaryInfoSetPropertyA(suminfo,3, VT_LPSTR, 0,NULL, - "Installation Database"); - ok( res == ERROR_SUCCESS , "Failed to set summary info\n" ); - - res = MsiSummaryInfoSetPropertyA(suminfo,4, VT_LPSTR, 0,NULL, - "Wine Hackers"); - ok( res == ERROR_SUCCESS , "Failed to set summary info\n" ); - - res = MsiSummaryInfoSetPropertyA(suminfo,7, VT_LPSTR, 0,NULL, - ";1033"); - ok( res == ERROR_SUCCESS , "Failed to set summary info\n" ); - - res = MsiSummaryInfoSetPropertyA(suminfo,9, VT_LPSTR, 0,NULL, - "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}"); - ok( res == ERROR_SUCCESS , "Failed to set summary info\n" ); - - res = MsiSummaryInfoSetPropertyA(suminfo, 14, VT_I4, 100, NULL, NULL); - ok( res == ERROR_SUCCESS , "Failed to set summary info\n" ); - - res = MsiSummaryInfoSetPropertyA(suminfo, 15, VT_I4, 0, NULL, NULL); - ok( res == ERROR_SUCCESS , "Failed to set summary info\n" ); - - res = MsiSummaryInfoPersist(suminfo); - ok( res == ERROR_SUCCESS , "Failed to make summary info persist\n" ); - - res = MsiCloseHandle( suminfo); - ok( res == ERROR_SUCCESS , "Failed to close suminfo\n" ); - - return res; -} - -static MSIHANDLE create_package_db(void) -{ - MSIHANDLE hdb = 0; - UINT res; - - DeleteFileW(msifileW); - - /* create an empty database */ - res = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATEDIRECT, &hdb ); - ok( res == ERROR_SUCCESS , "Failed to create database %u\n", res ); - if( res != ERROR_SUCCESS ) - return 0; - - res = MsiDatabaseCommit( hdb ); - ok( res == ERROR_SUCCESS , "Failed to commit database\n" ); - if( res != ERROR_SUCCESS ) - return 0; - - res = set_summary_info(hdb); - ok( res == ERROR_SUCCESS , "Failed to set summary info %u\n", res ); - if( res != ERROR_SUCCESS ) - return 0; - - res = run_query( hdb, - "CREATE TABLE `Directory` ( " - "`Directory` CHAR(255) NOT NULL, " - "`Directory_Parent` CHAR(255), " - "`DefaultDir` CHAR(255) NOT NULL " - "PRIMARY KEY `Directory`)" ); - ok( res == ERROR_SUCCESS , "Failed to create directory table %u\n", res ); - - return hdb; -} static UINT package_from_db(MSIHANDLE hdb, MSIHANDLE *handle) { @@ -245,18 +45,6 @@ static UINT package_from_db(MSIHANDLE hdb, MSIHANDLE *handle) return ERROR_SUCCESS; } -static void create_test_file(const CHAR *name) -{ - HANDLE file; - DWORD written; - - file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); - ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n", name); - WriteFile(file, name, strlen(name), &written, NULL); - WriteFile(file, "\n", strlen("\n"), &written, NULL); - CloseHandle(file); -} - static UINT helper_createpackage( const char *szName, MSIHANDLE *handle ) { MSIHANDLE hPackage, suminfo, hdb = 0; @@ -2476,304 +2264,6 @@ static void test_formatrecord_package(void) DeleteFileA( msifile ); } -static void test_formatrecord_tables(void) -{ - MSIHANDLE hdb, hrec, hpkg = 0; - CHAR buf[MAX_PATH]; - CHAR curr_dir[MAX_PATH]; - CHAR expected[MAX_PATH]; - CHAR root[MAX_PATH]; - DWORD size; - UINT r; - - GetCurrentDirectoryA( MAX_PATH, curr_dir ); - - hdb = create_package_db(); - ok ( hdb, "failed to create package database\n"); - - r = add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'" ); - ok( r == ERROR_SUCCESS, "cannot add directory: %d\n", r); - - r = add_directory_entry( hdb, "'ReallyLongDir', 'TARGETDIR', " - "'I am a really long directory'" ); - ok( r == ERROR_SUCCESS, "cannot add directory: %d\n", r); - - r = create_feature_table( hdb ); - ok( r == ERROR_SUCCESS, "cannot create Feature table: %d\n", r); - - r = add_feature_entry( hdb, "'occipitofrontalis', '', '', '', 2, 1, '', 0" ); - ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r ); - - r = create_component_table( hdb ); - ok( r == ERROR_SUCCESS, "cannot create Component table: %d\n", r); - - r = add_component_entry( hdb, "'frontal', '', 'TARGETDIR', 0, '', 'frontal_file'" ); - ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r); - - r = add_component_entry( hdb, "'parietal', '', 'TARGETDIR', 1, '', 'parietal_file'" ); - ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r); - - r = add_component_entry( hdb, "'temporal', '', 'ReallyLongDir', 0, '', 'temporal_file'" ); - ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r); - - r = create_feature_components_table( hdb ); - ok( r == ERROR_SUCCESS, "cannot create FeatureComponents table: %d\n", r); - - r = add_feature_components_entry( hdb, "'occipitofrontalis', 'frontal'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r); - - r = add_feature_components_entry( hdb, "'occipitofrontalis', 'parietal'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r); - - r = add_feature_components_entry( hdb, "'occipitofrontalis', 'temporal'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r); - - r = create_file_table( hdb ); - ok( r == ERROR_SUCCESS, "cannot create File table: %d\n", r); - - r = add_file_entry( hdb, "'frontal_file', 'frontal', 'frontal.txt', 0, '', '1033', 8192, 1" ); - ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r); - - r = add_file_entry( hdb, "'parietal_file', 'parietal', 'parietal.txt', 0, '', '1033', 8192, 1" ); - ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r); - - r = add_file_entry( hdb, "'temporal_file', 'temporal', 'temporal.txt', 0, '', '1033', 8192, 1" ); - ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r); - - r = create_custom_action_table( hdb ); - ok( r == ERROR_SUCCESS, "cannot create CustomAction table: %d\n", r); - - r = add_custom_action_entry( hdb, "'MyCustom', 51, 'prop', '[!temporal_file]'" ); - ok( r == ERROR_SUCCESS, "cannot add custom action: %d\n", r); - - r = add_custom_action_entry( hdb, "'EscapeIt1', 51, 'prop', '[\\[]Bracket Text[\\]]'" ); - ok( r == ERROR_SUCCESS, "cannot add custom action: %d\n", r); - - r = add_custom_action_entry( hdb, "'EscapeIt2', 51, 'prop', '[\\xabcd]'" ); - ok( r == ERROR_SUCCESS, "cannot add custom action: %d\n", r); - - r = add_custom_action_entry( hdb, "'EscapeIt3', 51, 'prop', '[abcd\\xefgh]'" ); - ok( r == ERROR_SUCCESS, "cannot add custom action: %d\n", r); - - r = add_custom_action_entry( hdb, "'EmbedNull', 51, 'prop', '[~]np'" ); - ok( r == ERROR_SUCCESS, "cannot add custom action: %d\n", r); - - r = package_from_db( hdb, &hpkg ); - if (r == ERROR_INSTALL_PACKAGE_REJECTED) - { - skip("Not enough rights to perform tests\n"); - MsiCloseHandle( hdb ); - DeleteFileA( msifile ); - return; - } - ok( r == ERROR_SUCCESS, "failed to create package %u\n", r ); - - MsiCloseHandle( hdb ); - - r = MsiSetPropertyA( hpkg, "imaprop", "ringer" ); - ok( r == ERROR_SUCCESS, "cannot set property: %d\n", r); - - hrec = MsiCreateRecord( 1 ); - - /* property doesn't exist */ - size = MAX_PATH; - /*MsiRecordSetStringA( hrec, 0, "[1]" ); */ - MsiRecordSetStringA( hrec, 1, "[idontexist]" ); - r = MsiFormatRecordA( hpkg, hrec, buf, &size ); - ok( r == ERROR_SUCCESS, "format record failed: %d\n", r); - ok( !lstrcmpA( buf, "1: " ), "Expected '1: ', got %s\n", buf ); - - /* property exists */ - size = MAX_PATH; - MsiRecordSetStringA( hrec, 1, "[imaprop]" ); - r = MsiFormatRecordA( hpkg, hrec, buf, &size ); - ok( r == ERROR_SUCCESS, "format record failed: %d\n", r); - ok( !lstrcmpA( buf, "1: ringer " ), "Expected '1: ringer ', got %s\n", buf ); - - size = MAX_PATH; - MsiRecordSetStringA( hrec, 0, "1: [1] " ); - r = MsiFormatRecordA( hpkg, hrec, buf, &size ); - ok( r == ERROR_SUCCESS, "format record failed: %d\n", r); - ok( !lstrcmpA( buf, "1: ringer " ), "Expected '1: ringer ', got %s\n", buf ); - - /* environment variable doesn't exist */ - size = MAX_PATH; - MsiRecordSetStringA( hrec, 1, "[%idontexist]" ); - r = MsiFormatRecordA( hpkg, hrec, buf, &size ); - ok( r == ERROR_SUCCESS, "format record failed: %d\n", r); - ok( !lstrcmpA( buf, "1: " ), "Expected '1: ', got %s\n", buf ); - - /* environment variable exists */ - size = MAX_PATH; - SetEnvironmentVariableA( "crazyvar", "crazyval" ); - MsiRecordSetStringA( hrec, 1, "[%crazyvar]" ); - r = MsiFormatRecordA( hpkg, hrec, buf, &size ); - ok( r == ERROR_SUCCESS, "format record failed: %d\n", r); - ok( !lstrcmpA( buf, "1: crazyval " ), "Expected '1: crazyval ', got %s\n", buf ); - - /* file key before CostInitialize */ - size = MAX_PATH; - MsiRecordSetStringA( hrec, 1, "[#frontal_file]" ); - r = MsiFormatRecordA( hpkg, hrec, buf, &size ); - ok( r == ERROR_SUCCESS, "format record failed: %d\n", r); - ok( !lstrcmpA( buf, "1: " ), "Expected '1: ', got %s\n", buf ); - - MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); - - r = MsiDoActionA(hpkg, "CostInitialize"); - ok( r == ERROR_SUCCESS, "CostInitialize failed: %d\n", r); - - r = MsiDoActionA(hpkg, "FileCost"); - ok( r == ERROR_SUCCESS, "FileCost failed: %d\n", r); - - r = MsiDoActionA(hpkg, "CostFinalize"); - ok( r == ERROR_SUCCESS, "CostFinalize failed: %d\n", r); - - size = MAX_PATH; - MsiGetPropertyA( hpkg, "ROOTDRIVE", root, &size ); - - sprintf( expected, "1: %sfrontal.txt ", root); - - /* frontal full file key */ - size = MAX_PATH; - MsiRecordSetStringA( hrec, 1, "[#frontal_file]" ); - r = MsiFormatRecordA( hpkg, hrec, buf, &size ); - ok( r == ERROR_SUCCESS, "format record failed: %d\n", r); - ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf); - - /* frontal short file key */ - size = MAX_PATH; - MsiRecordSetStringA( hrec, 1, "[!frontal_file]" ); - r = MsiFormatRecordA( hpkg, hrec, buf, &size ); - ok( r == ERROR_SUCCESS, "format record failed: %d\n", r); - ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf); - - sprintf( expected, "1: %sI am a really long directory\\temporal.txt ", root); - - /* temporal full file key */ - size = MAX_PATH; - MsiRecordSetStringA( hrec, 1, "[#temporal_file]" ); - r = MsiFormatRecordA( hpkg, hrec, buf, &size ); - ok( r == ERROR_SUCCESS, "format record failed: %d\n", r); - ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf); - - /* temporal short file key */ - size = MAX_PATH; - MsiRecordSetStringA( hrec, 1, "[!temporal_file]" ); - r = MsiFormatRecordA( hpkg, hrec, buf, &size ); - ok( r == ERROR_SUCCESS, "format record failed: %d\n", r); - ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf); - - /* custom action 51, files don't exist */ - r = MsiDoActionA( hpkg, "MyCustom" ); - ok( r == ERROR_SUCCESS, "MyCustom failed: %d\n", r); - - sprintf( expected, "%sI am a really long directory\\temporal.txt", root); - - size = MAX_PATH; - r = MsiGetPropertyA( hpkg, "prop", buf, &size ); - ok( r == ERROR_SUCCESS, "get property failed: %d\n", r); - ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf); - - sprintf( buf, "%sI am a really long directory", root ); - CreateDirectoryA( buf, NULL ); - - lstrcatA( buf, "\\temporal.txt" ); - create_test_file( buf ); - - /* custom action 51, files exist */ - r = MsiDoActionA( hpkg, "MyCustom" ); - ok( r == ERROR_SUCCESS, "MyCustom failed: %d\n", r); - - size = MAX_PATH; - r = MsiGetPropertyA( hpkg, "prop", buf, &size ); - ok( r == ERROR_SUCCESS, "get property failed: %d\n", r); - todo_wine - { - ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf); - } - - /* custom action 51, escaped text 1 */ - r = MsiDoActionA( hpkg, "EscapeIt1" ); - ok( r == ERROR_SUCCESS, "EscapeIt1 failed: %d\n", r); - - size = MAX_PATH; - r = MsiGetPropertyA( hpkg, "prop", buf, &size ); - ok( r == ERROR_SUCCESS, "get property failed: %d\n", r); - ok( !lstrcmpA( buf, "[Bracket Text]" ), "Expected '[Bracket Text]', got %s\n", buf); - - /* custom action 51, escaped text 2 */ - r = MsiDoActionA( hpkg, "EscapeIt2" ); - ok( r == ERROR_SUCCESS, "EscapeIt2 failed: %d\n", r); - - size = MAX_PATH; - r = MsiGetPropertyA( hpkg, "prop", buf, &size ); - ok( r == ERROR_SUCCESS, "get property failed: %d\n", r); - ok( !lstrcmpA( buf, "x" ), "Expected 'x', got %s\n", buf); - - /* custom action 51, escaped text 3 */ - r = MsiDoActionA( hpkg, "EscapeIt3" ); - ok( r == ERROR_SUCCESS, "EscapeIt3 failed: %d\n", r); - - size = MAX_PATH; - r = MsiGetPropertyA( hpkg, "prop", buf, &size ); - ok( r == ERROR_SUCCESS, "get property failed: %d\n", r); - ok( !lstrcmpA( buf, "" ), "Expected '', got %s\n", buf); - - /* custom action 51, embedded null */ - r = MsiDoActionA( hpkg, "EmbedNull" ); - ok( r == ERROR_SUCCESS, "EmbedNull failed: %d\n", r); - - size = MAX_PATH; - memset( buf, 'a', sizeof(buf) ); - r = MsiGetPropertyA( hpkg, "prop", buf, &size ); - ok( r == ERROR_SUCCESS, "get property failed: %d\n", r); - ok( !memcmp( buf, "\0np", sizeof("\0np") ), "wrong value\n"); - ok( size == sizeof("\0np") - 1, "got %u\n", size ); - - r = MsiSetPropertyA( hpkg, "prop", "[~]np" ); - ok( r == ERROR_SUCCESS, "cannot set property: %d\n", r); - - size = MAX_PATH; - memset( buf, 'a', sizeof(buf) ); - r = MsiGetPropertyA( hpkg, "prop", buf, &size ); - ok( r == ERROR_SUCCESS, "get property failed: %d\n", r); - ok( !lstrcmpA( buf, "[~]np" ), "Expected '[~]np', got %s\n", buf); - - sprintf( expected, "1: %sI am a really long directory\\ ", root); - - /* component with INSTALLSTATE_LOCAL */ - size = MAX_PATH; - MsiRecordSetStringA( hrec, 1, "[$temporal]" ); - r = MsiFormatRecordA( hpkg, hrec, buf, &size ); - ok( r == ERROR_SUCCESS, "format record failed: %d\n", r); - ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf); - - r = MsiSetComponentStateA( hpkg, "temporal", INSTALLSTATE_SOURCE ); - ok( r == ERROR_SUCCESS, "failed to set install state: %d\n", r); - - /* component with INSTALLSTATE_SOURCE */ - lstrcpyA( expected, "1: " ); - lstrcatA( expected, curr_dir ); - if (strlen(curr_dir) > 3) lstrcatA( expected, "\\" ); - lstrcatA( expected, " " ); - size = MAX_PATH; - MsiRecordSetStringA( hrec, 1, "[$parietal]" ); - r = MsiFormatRecordA( hpkg, hrec, buf, &size ); - ok( r == ERROR_SUCCESS, "format record failed: %d\n", r); - ok( !lstrcmpA( buf, expected ), "Expected '%s', got '%s'\n", expected, buf); - - sprintf( buf, "%sI am a really long directory\\temporal.txt", root ); - DeleteFileA( buf ); - - sprintf( buf, "%sI am a really long directory", root ); - RemoveDirectoryA( buf ); - - MsiCloseHandle( hrec ); - MsiCloseHandle( hpkg ); - DeleteFileA( msifile ); -} - static void test_processmessage(void) { MSIHANDLE hrec, package; @@ -2845,6 +2335,5 @@ START_TEST(format) test_createpackage(); test_formatrecord(); test_formatrecord_package(); - test_formatrecord_tables(); test_processmessage(); } diff --git a/modules/rostests/winetests/msi/install.c b/modules/rostests/winetests/msi/install.c index 21ef1b2e79..2e08918b9e 100644 --- a/modules/rostests/winetests/msi/install.c +++ b/modules/rostests/winetests/msi/install.c @@ -1269,6 +1269,27 @@ static const char ft_install_exec_seq_dat[] = "PublishProduct\t\t1400\n" "InstallFinalize\t\t1500\n"; +static const char da_custom_action_dat[] = + "Action\tType\tSource\tTarget\tISComments\n" + "s72\ti2\tS64\tS0\tS255\n" + "CustomAction\tAction\n" + "deferred\t1074\tCMDEXE\t/c if exist msitest (exit 0) else (exit 1)\t\n" + "immediate\t50\tCMDEXE\t/c mkdir msitest\t\n" + "cleanup\t50\tCMDEXE\t/c rmdir msitest\t\n"; + +static const char da_install_exec_seq_dat[] = + "Action\tCondition\tSequence\n" + "s72\tS255\tI2\n" + "InstallExecuteSequence\tAction\n" + "CostInitialize\t\t200\n" + "FileCost\t\t300\n" + "CostFinalize\t\t400\n" + "InstallInitialize\t\t500\n" + "deferred\t\t600\n" + "immediate\t\t700\n" + "InstallFinalize\t\t1100\n" + "cleanup\t\t1200\n"; + typedef struct _msi_table { const CHAR *filename; @@ -1923,6 +1944,19 @@ static const msi_table ft_tables[] = ADD_TABLE(property) }; +static const msi_table da_tables[] = +{ + ADD_TABLE(media), + ADD_TABLE(directory), + ADD_TABLE(file), + ADD_TABLE(component), + ADD_TABLE(feature), + ADD_TABLE(feature_comp), + ADD_TABLE(property), + ADD_TABLE(da_install_exec_seq), + ADD_TABLE(da_custom_action), +}; + /* cabinet definitions */ /* make the max size large so there is only one cab file */ @@ -2390,6 +2424,22 @@ static void delete_test_files(void) RemoveDirectoryA("msitest"); } +static void delete_pf_files(void) +{ + ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n"); + ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n"); + ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n"); + ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n"); + ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n"); + ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n"); + ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n"); + ok(delete_pf("msitest\\first", FALSE), "Directory not created\n"); + ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n"); + ok(delete_pf("msitest\\filename", TRUE), "File not installed\n"); + ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "Directory not created\n"); +} + static void write_file(const CHAR *filename, const char *data, int data_size) { DWORD size; @@ -2570,18 +2620,7 @@ static void test_MsiInstallProduct(void) } ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\first", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\filename", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "Directory not created\n"); + delete_pf_files(); res = RegOpenKeyExA(HKEY_CURRENT_USER, "SOFTWARE\\Wine\\msitest", 0, access, &hkey); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); @@ -2617,18 +2656,7 @@ static void test_MsiInstallProduct(void) r = MsiInstallProductA(msifile, NULL); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\first", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\filename", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "Directory not created\n"); + delete_pf_files(); res = RegOpenKeyA(HKEY_CURRENT_USER, "SOFTWARE\\Wine\\msitest", &hkey); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); @@ -2640,18 +2668,7 @@ static void test_MsiInstallProduct(void) r = MsiInstallProductA(msifile, NULL); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\first", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\filename", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "Directory not created\n"); + delete_pf_files(); res = RegOpenKeyA(HKEY_CURRENT_USER, "SOFTWARE\\Wine\\msitest", &hkey); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); @@ -2663,18 +2680,7 @@ static void test_MsiInstallProduct(void) r = MsiInstallProductA(msifile, NULL); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\first", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\filename", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "Directory not created\n"); + delete_pf_files(); res = RegOpenKeyA(HKEY_CURRENT_USER, "SOFTWARE\\Wine\\msitest", &hkey); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); @@ -2686,18 +2692,7 @@ static void test_MsiInstallProduct(void) r = MsiInstallProductA(msifile, NULL); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\first", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\filename", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "Directory not created\n"); + delete_pf_files(); res = RegOpenKeyA(HKEY_CURRENT_USER, "SOFTWARE\\Wine\\msitest", &hkey); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); @@ -2709,18 +2704,7 @@ static void test_MsiInstallProduct(void) r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1"); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\first", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\filename", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "Directory not created\n"); + delete_pf_files(); res = RegOpenKeyA(HKEY_CURRENT_USER, "SOFTWARE\\Wine\\msitest", &hkey); ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); @@ -2731,18 +2715,7 @@ static void test_MsiInstallProduct(void) r = MsiInstallProductA(msifile, NULL); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\first", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\filename", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "Directory not created\n"); + delete_pf_files(); res = RegOpenKeyA(HKEY_CURRENT_USER, "SOFTWARE\\Wine\\msitest", &hkey); ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); @@ -2753,18 +2726,7 @@ static void test_MsiInstallProduct(void) r = MsiInstallProductA(msifile, NULL); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\first", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\filename", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "Directory not created\n"); + delete_pf_files(); res = RegOpenKeyA(HKEY_CURRENT_USER, "SOFTWARE\\Wine\\msitest", &hkey); ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); @@ -2775,18 +2737,7 @@ static void test_MsiInstallProduct(void) r = MsiInstallProductA(msifile, NULL); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\first", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\filename", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "Directory not created\n"); + delete_pf_files(); res = RegOpenKeyA(HKEY_CURRENT_USER, "SOFTWARE\\Wine\\msitest", &hkey); ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); @@ -2797,18 +2748,7 @@ static void test_MsiInstallProduct(void) r = MsiInstallProductA(msifile, NULL); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\first", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\filename", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "Directory not created\n"); + delete_pf_files(); res = RegOpenKeyA(HKEY_CURRENT_USER, "SOFTWARE\\Wine\\msitest", &hkey); ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); @@ -3844,6 +3784,7 @@ static void test_admin(void) ok(!RemoveDirectoryA("c:\\msitest"), "File installed\n"); r = MsiInstallProductA(msifile, "ACTION=ADMIN"); + todo_wine ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); ok(!delete_pf("msitest\\augustus", TRUE), "File installed\n"); ok(!delete_pf("msitest", FALSE), "Directory created\n"); @@ -4721,18 +4662,7 @@ static void test_adminimage(void) } ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\first", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\filename", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "Directory not created\n"); + delete_pf_files(); error: DeleteFileA("msifile"); @@ -4900,19 +4830,8 @@ static void test_shortcut(void) CoUninitialize(); - ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\first", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\filename", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n"); while (!delete_pf("msitest\\Shortcut.lnk", TRUE) && GetLastError() == ERROR_SHARING_VIOLATION) Sleep(1000); - ok(delete_pf("msitest", FALSE), "Directory not created\n"); + delete_pf_files(); error: delete_test_files(); @@ -5006,18 +4925,7 @@ static void test_installed_prop(void) r = MsiConfigureProductExA(prodcode, INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT, "FULL=1"); ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r); - ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\first", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\filename", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\one.txt", TRUE), "File installed\n"); - ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "Directory not created\n"); + delete_pf_files(); r = MsiInstallProductA(msifile, "REMOVE=ALL"); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); @@ -5051,18 +4959,7 @@ static void test_allusers_prop(void) } ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\first", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\filename", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\one.txt", TRUE), "File installed\n"); - ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "Directory not created\n"); + delete_pf_files(); r = MsiInstallProductA(msifile, "REMOVE=ALL"); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); @@ -5076,18 +4973,7 @@ static void test_allusers_prop(void) r = MsiInstallProductA(msifile, "FULL=1"); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\first", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\filename", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\one.txt", TRUE), "File installed\n"); - ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "Directory not created\n"); + delete_pf_files(); r = MsiInstallProductA(msifile, "REMOVE=ALL"); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); @@ -5101,18 +4987,7 @@ static void test_allusers_prop(void) r = MsiInstallProductA(msifile, "FULL=1"); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); - ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\first", FALSE), "Directory not created\n"); - ok(delete_pf("msitest\\filename", TRUE), "File not installed\n"); - ok(delete_pf("msitest\\one.txt", TRUE), "File installed\n"); - ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n"); - ok(delete_pf("msitest", FALSE), "Directory not created\n"); + delete_pf_files(); r = MsiInstallProductA(msifile, "REMOVE=ALL"); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); @@ -6029,6 +5904,27 @@ static void test_feature_tree(void) DeleteFileA( msifile ); } +static void test_deferred_action(void) +{ + UINT r; + + create_database(msifile, da_tables, sizeof(da_tables) / sizeof(da_tables[0])); + + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + + r = MsiInstallProductA(msifile, "CMDEXE=\"cmd.exe\""); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + goto error; + } +todo_wine + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + +error: + DeleteFileA(msifile); +} + START_TEST(install) { DWORD len; @@ -6117,6 +6013,7 @@ START_TEST(install) test_shared_component(); test_remove_upgrade_code(); test_feature_tree(); + test_deferred_action(); DeleteFileA(log_file); diff --git a/modules/rostests/winetests/msi/package.c b/modules/rostests/winetests/msi/package.c index 6834bec6af..f29baa9d25 100644 --- a/modules/rostests/winetests/msi/package.c +++ b/modules/rostests/winetests/msi/package.c @@ -437,7 +437,7 @@ static UINT run_query( MSIHANDLE hdb, const char *query ) static UINT create_component_table( MSIHANDLE hdb ) { - return run_query( hdb, + UINT r = run_query( hdb, "CREATE TABLE `Component` ( " "`Component` CHAR(72) NOT NULL, " "`ComponentId` CHAR(38), " @@ -446,11 +446,13 @@ static UINT create_component_table( MSIHANDLE hdb ) "`Condition` CHAR(255), " "`KeyPath` CHAR(72) " "PRIMARY KEY `Component`)" ); + ok(r == ERROR_SUCCESS, "Failed to create Component table: %u\n", r); + return r; } static UINT create_feature_table( MSIHANDLE hdb ) { - return run_query( hdb, + UINT r = run_query( hdb, "CREATE TABLE `Feature` ( " "`Feature` CHAR(38) NOT NULL, " "`Feature_Parent` CHAR(38), " @@ -461,20 +463,24 @@ static UINT create_feature_table( MSIHANDLE hdb ) "`Directory_` CHAR(72), " "`Attributes` SHORT NOT NULL " "PRIMARY KEY `Feature`)" ); + ok(r == ERROR_SUCCESS, "Failed to create Feature table: %u\n", r); + return r; } static UINT create_feature_components_table( MSIHANDLE hdb ) { - return run_query( hdb, + UINT r = run_query( hdb, "CREATE TABLE `FeatureComponents` ( " "`Feature_` CHAR(38) NOT NULL, " "`Component_` CHAR(72) NOT NULL " "PRIMARY KEY `Feature_`, `Component_` )" ); + ok(r == ERROR_SUCCESS, "Failed to create FeatureComponents table: %u\n", r); + return r; } static UINT create_file_table( MSIHANDLE hdb ) { - return run_query( hdb, + UINT r = run_query( hdb, "CREATE TABLE `File` (" "`File` CHAR(72) NOT NULL, " "`Component_` CHAR(72) NOT NULL, " @@ -485,11 +491,13 @@ static UINT create_file_table( MSIHANDLE hdb ) "`Attributes` SHORT, " "`Sequence` SHORT NOT NULL " "PRIMARY KEY `File`)" ); + ok(r == ERROR_SUCCESS, "Failed to create File table: %u\n", r); + return r; } static UINT create_remove_file_table( MSIHANDLE hdb ) { - return run_query( hdb, + UINT r = run_query( hdb, "CREATE TABLE `RemoveFile` (" "`FileKey` CHAR(72) NOT NULL, " "`Component_` CHAR(72) NOT NULL, " @@ -497,20 +505,24 @@ static UINT create_remove_file_table( MSIHANDLE hdb ) "`DirProperty` CHAR(72) NOT NULL, " "`InstallMode` SHORT NOT NULL " "PRIMARY KEY `FileKey`)" ); + ok(r == ERROR_SUCCESS, "Failed to create RemoveFile table: %u\n", r); + return r; } static UINT create_appsearch_table( MSIHANDLE hdb ) { - return run_query( hdb, + UINT r = run_query( hdb, "CREATE TABLE `AppSearch` (" "`Property` CHAR(72) NOT NULL, " "`Signature_` CHAR(72) NOT NULL " "PRIMARY KEY `Property`, `Signature_`)" ); + ok(r == ERROR_SUCCESS, "Failed to create AppSearch table: %u\n", r); + return r; } static UINT create_reglocator_table( MSIHANDLE hdb ) { - return run_query( hdb, + UINT r = run_query( hdb, "CREATE TABLE `RegLocator` (" "`Signature_` CHAR(72) NOT NULL, " "`Root` SHORT NOT NULL, " @@ -518,11 +530,13 @@ static UINT create_reglocator_table( MSIHANDLE hdb ) "`Name` CHAR(255), " "`Type` SHORT " "PRIMARY KEY `Signature_`)" ); + ok(r == ERROR_SUCCESS, "Failed to create RegLocator table: %u\n", r); + return r; } static UINT create_signature_table( MSIHANDLE hdb ) { - return run_query( hdb, + UINT r = run_query( hdb, "CREATE TABLE `Signature` (" "`Signature` CHAR(72) NOT NULL, " "`FileName` CHAR(255) NOT NULL, " @@ -534,39 +548,59 @@ static UINT create_signature_table( MSIHANDLE hdb ) "`MaxDate` LONG, " "`Languages` CHAR(255) " "PRIMARY KEY `Signature`)" ); + ok(r == ERROR_SUCCESS, "Failed to create Signature table: %u\n", r); + return r; } static UINT create_launchcondition_table( MSIHANDLE hdb ) { - return run_query( hdb, + UINT r = run_query( hdb, "CREATE TABLE `LaunchCondition` (" "`Condition` CHAR(255) NOT NULL, " "`Description` CHAR(255) NOT NULL " "PRIMARY KEY `Condition`)" ); + ok(r == ERROR_SUCCESS, "Failed to create LaunchCondition table: %u\n", r); + return r; } static UINT create_property_table( MSIHANDLE hdb ) { - return run_query( hdb, + UINT r = run_query( hdb, "CREATE TABLE `Property` (" "`Property` CHAR(72) NOT NULL, " "`Value` CHAR(0) " "PRIMARY KEY `Property`)" ); + ok(r == ERROR_SUCCESS, "Failed to create Property table: %u\n", r); + return r; } static UINT create_install_execute_sequence_table( MSIHANDLE hdb ) { - return run_query( hdb, + UINT r = run_query( hdb, "CREATE TABLE `InstallExecuteSequence` (" "`Action` CHAR(72) NOT NULL, " "`Condition` CHAR(255), " "`Sequence` SHORT " "PRIMARY KEY `Action`)" ); + ok(r == ERROR_SUCCESS, "Failed to create InstallExecuteSequence table: %u\n", r); + return r; +} + +static UINT create_install_ui_sequence_table( MSIHANDLE hdb ) +{ + UINT r = run_query( hdb, + "CREATE TABLE `InstallUISequence` (" + "`Action` CHAR(72) NOT NULL, " + "`Condition` CHAR(255), " + "`Sequence` SHORT " + "PRIMARY KEY `Action`)" ); + ok(r == ERROR_SUCCESS, "Failed to create InstallUISequence table: %u\n", r); + return r; } static UINT create_media_table( MSIHANDLE hdb ) { - return run_query( hdb, + UINT r = run_query( hdb, "CREATE TABLE `Media` (" "`DiskId` SHORT NOT NULL, " "`LastSequence` SHORT NOT NULL, " @@ -575,40 +609,48 @@ static UINT create_media_table( MSIHANDLE hdb ) "`VolumeLabel` CHAR(32), " "`Source` CHAR(72) " "PRIMARY KEY `DiskId`)" ); + ok(r == ERROR_SUCCESS, "Failed to create Media table: %u\n", r); + return r; } static UINT create_ccpsearch_table( MSIHANDLE hdb ) { - return run_query( hdb, + UINT r = run_query( hdb, "CREATE TABLE `CCPSearch` (" "`Signature_` CHAR(72) NOT NULL " "PRIMARY KEY `Signature_`)" ); + ok(r == ERROR_SUCCESS, "Failed to create CCPSearch table: %u\n", r); + return r; } static UINT create_drlocator_table( MSIHANDLE hdb ) { - return run_query( hdb, + UINT r = run_query( hdb, "CREATE TABLE `DrLocator` (" "`Signature_` CHAR(72) NOT NULL, " "`Parent` CHAR(72), " "`Path` CHAR(255), " "`Depth` SHORT " "PRIMARY KEY `Signature_`, `Parent`, `Path`)" ); + ok(r == ERROR_SUCCESS, "Failed to create DrLocator table: %u\n", r); + return r; } static UINT create_complocator_table( MSIHANDLE hdb ) { - return run_query( hdb, + UINT r = run_query( hdb, "CREATE TABLE `CompLocator` (" "`Signature_` CHAR(72) NOT NULL, " "`ComponentId` CHAR(38) NOT NULL, " "`Type` SHORT " "PRIMARY KEY `Signature_`)" ); + ok(r == ERROR_SUCCESS, "Failed to create CompLocator table: %u\n", r); + return r; } static UINT create_inilocator_table( MSIHANDLE hdb ) { - return run_query( hdb, + UINT r = run_query( hdb, "CREATE TABLE `IniLocator` (" "`Signature_` CHAR(72) NOT NULL, " "`FileName` CHAR(255) NOT NULL, " @@ -617,22 +659,26 @@ static UINT create_inilocator_table( MSIHANDLE hdb ) "`Field` SHORT, " "`Type` SHORT " "PRIMARY KEY `Signature_`)" ); + ok(r == ERROR_SUCCESS, "Failed to create IniLocator table: %u\n", r); + return r; } static UINT create_custom_action_table( MSIHANDLE hdb ) { - return run_query( hdb, + UINT r = run_query( hdb, "CREATE TABLE `CustomAction` (" "`Action` CHAR(72) NOT NULL, " "`Type` SHORT NOT NULL, " "`Source` CHAR(75), " "`Target` CHAR(255) " "PRIMARY KEY `Action`)" ); + ok(r == ERROR_SUCCESS, "Failed to create CustomAction table: %u\n", r); + return r; } static UINT create_dialog_table( MSIHANDLE hdb ) { - return run_query(hdb, + UINT r = run_query(hdb, "CREATE TABLE `Dialog` (" "`Dialog` CHAR(72) NOT NULL, " "`HCentering` SHORT NOT NULL, " @@ -645,11 +691,13 @@ static UINT create_dialog_table( MSIHANDLE hdb ) "`Control_Default` CHAR(50), " "`Control_Cancel` CHAR(50) " "PRIMARY KEY `Dialog`)"); + ok(r == ERROR_SUCCESS, "Failed to create Dialog table: %u\n", r); + return r; } static UINT create_control_table( MSIHANDLE hdb ) { - return run_query(hdb, + UINT r = run_query(hdb, "CREATE TABLE `Control` (" "`Dialog_` CHAR(72) NOT NULL, " "`Control` CHAR(50) NOT NULL, " @@ -664,11 +712,13 @@ static UINT create_control_table( MSIHANDLE hdb ) "`Control_Next` CHAR(50), " "`Help` CHAR(255) LOCALIZABLE " "PRIMARY KEY `Dialog_`, `Control`)"); + ok(r == ERROR_SUCCESS, "Failed to create Control table: %u\n", r); + return r; } static UINT create_controlevent_table( MSIHANDLE hdb ) { - return run_query(hdb, + UINT r = run_query(hdb, "CREATE TABLE `ControlEvent` (" "`Dialog_` CHAR(72) NOT NULL, " "`Control_` CHAR(50) NOT NULL, " @@ -677,115 +727,123 @@ static UINT create_controlevent_table( MSIHANDLE hdb ) "`Condition` CHAR(255), " "`Ordering` SHORT " "PRIMARY KEY `Dialog_`, `Control_`, `Event`, `Argument`, `Condition`)"); + ok(r == ERROR_SUCCESS, "Failed to create ControlEvent table: %u\n", r); + return r; } static UINT create_actiontext_table( MSIHANDLE hdb ) { - return run_query(hdb, + UINT r = run_query(hdb, "CREATE TABLE `ActionText` (" "`Action` CHAR(72) NOT NULL, " "`Description` CHAR(64) LOCALIZABLE, " "`Template` CHAR(128) LOCALIZABLE " "PRIMARY KEY `Action`)"); + ok(r == ERROR_SUCCESS, "Failed to create ActionText table: %u\n", r); + return r; } -#define make_add_entry(type, qtext) \ - static UINT add##_##type##_##entry( MSIHANDLE hdb, const char *values ) \ - { \ - char insert[] = qtext; \ - char *query; \ - UINT sz, r; \ - sz = strlen(values) + sizeof insert; \ - query = HeapAlloc(GetProcessHeap(),0,sz); \ - sprintf(query,insert,values); \ - r = run_query( hdb, query ); \ - HeapFree(GetProcessHeap(), 0, query); \ - return r; \ - } +static inline UINT add_entry(const char *file, int line, const char *type, MSIHANDLE hdb, const char *values, const char *insert) +{ + char *query; + UINT sz, r; + + sz = strlen(values) + strlen(insert) + 1; + query = HeapAlloc(GetProcessHeap(), 0, sz); + sprintf(query, insert, values); + r = run_query(hdb, query); + HeapFree(GetProcessHeap(), 0, query); + ok_(file, line)(r == ERROR_SUCCESS, "failed to insert into %s table: %u\n", type, r); + return r; +} -make_add_entry(component, - "INSERT INTO `Component` " - "(`Component`, `ComponentId`, `Directory_`, " +#define add_component_entry(hdb, values) add_entry(__FILE__, __LINE__, "Component", hdb, values, \ + "INSERT INTO `Component` " \ + "(`Component`, `ComponentId`, `Directory_`, " \ "`Attributes`, `Condition`, `KeyPath`) VALUES( %s )") -make_add_entry(directory, - "INSERT INTO `Directory` " +#define add_directory_entry(hdb, values) add_entry(__FILE__, __LINE__, "Directory", hdb, values, \ + "INSERT INTO `Directory` " \ "(`Directory`,`Directory_Parent`,`DefaultDir`) VALUES( %s )") -make_add_entry(feature, - "INSERT INTO `Feature` " - "(`Feature`, `Feature_Parent`, `Title`, `Description`, " +#define add_feature_entry(hdb, values) add_entry(__FILE__, __LINE__, "Feature", hdb, values, \ + "INSERT INTO `Feature` " \ + "(`Feature`, `Feature_Parent`, `Title`, `Description`, " \ "`Display`, `Level`, `Directory_`, `Attributes`) VALUES( %s )") -make_add_entry(feature_components, - "INSERT INTO `FeatureComponents` " +#define add_feature_components_entry(hdb, values) add_entry(__FILE__, __LINE__, "FeatureComponents", hdb, values, \ + "INSERT INTO `FeatureComponents` " \ "(`Feature_`, `Component_`) VALUES( %s )") -make_add_entry(file, - "INSERT INTO `File` " - "(`File`, `Component_`, `FileName`, `FileSize`, " +#define add_file_entry(hdb, values) add_entry(__FILE__, __LINE__, "File", hdb, values, \ + "INSERT INTO `File` " \ + "(`File`, `Component_`, `FileName`, `FileSize`, " \ "`Version`, `Language`, `Attributes`, `Sequence`) VALUES( %s )") -make_add_entry(appsearch, - "INSERT INTO `AppSearch` " +#define add_appsearch_entry(hdb, values) add_entry(__FILE__, __LINE__, "AppSearch", hdb, values, \ + "INSERT INTO `AppSearch` " \ "(`Property`, `Signature_`) VALUES( %s )") -make_add_entry(signature, - "INSERT INTO `Signature` " - "(`Signature`, `FileName`, `MinVersion`, `MaxVersion`," - " `MinSize`, `MaxSize`, `MinDate`, `MaxDate`, `Languages`) " +#define add_signature_entry(hdb, values) add_entry(__FILE__, __LINE__, "Signature", hdb, values, \ + "INSERT INTO `Signature` " \ + "(`Signature`, `FileName`, `MinVersion`, `MaxVersion`," \ + " `MinSize`, `MaxSize`, `MinDate`, `MaxDate`, `Languages`) " \ "VALUES( %s )") -make_add_entry(launchcondition, - "INSERT INTO `LaunchCondition` " +#define add_launchcondition_entry(hdb, values) add_entry(__FILE__, __LINE__, "LaunchCondition", hdb, values, \ + "INSERT INTO `LaunchCondition` " \ "(`Condition`, `Description`) VALUES( %s )") -make_add_entry(property, +#define add_property_entry(hdb, values) add_entry(__FILE__, __LINE__, "Property", hdb, values, \ "INSERT INTO `Property` (`Property`, `Value`) VALUES( %s )") -make_add_entry(install_execute_sequence, - "INSERT INTO `InstallExecuteSequence` " +#define add_install_execute_sequence_entry(hdb, values) add_entry(__FILE__, __LINE__, "InstallExecuteSequence", hdb, values, \ + "INSERT INTO `InstallExecuteSequence` " \ + "(`Action`, `Condition`, `Sequence`) VALUES( %s )") + +#define add_install_ui_sequence_entry(hdb, values) add_entry(__FILE__, __LINE__, "InstallUISequence", hdb, values, \ + "INSERT INTO `InstallUISequence` " \ "(`Action`, `Condition`, `Sequence`) VALUES( %s )") -make_add_entry(media, - "INSERT INTO `Media` " - "(`DiskId`, `LastSequence`, `DiskPrompt`, " +#define add_media_entry(hdb, values) add_entry(__FILE__, __LINE__, "Media", hdb, values, \ + "INSERT INTO `Media` " \ + "(`DiskId`, `LastSequence`, `DiskPrompt`, " \ "`Cabinet`, `VolumeLabel`, `Source`) VALUES( %s )") -make_add_entry(ccpsearch, +#define add_ccpsearch_entry(hdb, values) add_entry(__FILE__, __LINE__, "CCPSearch", hdb, values, \ "INSERT INTO `CCPSearch` (`Signature_`) VALUES( %s )") -make_add_entry(drlocator, - "INSERT INTO `DrLocator` " +#define add_drlocator_entry(hdb, values) add_entry(__FILE__, __LINE__, "DrLocator", hdb, values, \ + "INSERT INTO `DrLocator` " \ "(`Signature_`, `Parent`, `Path`, `Depth`) VALUES( %s )") -make_add_entry(complocator, - "INSERT INTO `CompLocator` " +#define add_complocator_entry(hdb, values) add_entry(__FILE__, __LINE__, "CompLocator", hdb, values, \ + "INSERT INTO `CompLocator` " \ "(`Signature_`, `ComponentId`, `Type`) VALUES( %s )") -make_add_entry(inilocator, - "INSERT INTO `IniLocator` " - "(`Signature_`, `FileName`, `Section`, `Key`, `Field`, `Type`) " +#define add_inilocator_entry(hdb, values) add_entry(__FILE__, __LINE__, "IniLocator", hdb, values, \ + "INSERT INTO `IniLocator` " \ + "(`Signature_`, `FileName`, `Section`, `Key`, `Field`, `Type`) " \ "VALUES( %s )") -make_add_entry(custom_action, - "INSERT INTO `CustomAction` " +#define add_custom_action_entry(hdb, values) add_entry(__FILE__, __LINE__, "CustomAction", hdb, values, \ + "INSERT INTO `CustomAction` " \ "(`Action`, `Type`, `Source`, `Target`) VALUES( %s )") -make_add_entry(dialog, - "INSERT INTO `Dialog` " +#define add_dialog_entry(hdb, values) add_entry(__FILE__, __LINE__, "Dialog", hdb, values, \ + "INSERT INTO `Dialog` " \ "(`Dialog`, `HCentering`, `VCentering`, `Width`, `Height`, `Attributes`, `Control_First`) VALUES ( %s )") -make_add_entry(control, - "INSERT INTO `Control` " +#define add_control_entry(hdb, values) add_entry(__FILE__, __LINE__, "Control", hdb, values, \ + "INSERT INTO `Control` " \ "(`Dialog_`, `Control`, `Type`, `X`, `Y`, `Width`, `Height`, `Attributes`, `Text`) VALUES( %s )"); -make_add_entry(controlevent, - "INSERT INTO `ControlEvent` " +#define add_controlevent_entry(hdb, values) add_entry(__FILE__, __LINE__, "ControlEvent", hdb, values, \ + "INSERT INTO `ControlEvent` " \ "(`Dialog_`, `Control_`, `Event`, `Argument`, `Condition`, `Ordering`) VALUES( %s )"); -make_add_entry(actiontext, - "INSERT INTO `ActionText` " +#define add_actiontext_entry(hdb, values) add_entry(__FILE__, __LINE__, "ActionText", hdb, values, \ + "INSERT INTO `ActionText` " \ "(`Action`, `Description`, `Template`) VALUES( %s )"); static UINT add_reglocator_entry( MSIHANDLE hdb, const char *sig, UINT root, const char *path, @@ -802,6 +860,7 @@ static UINT add_reglocator_entry( MSIHANDLE hdb, const char *sig, UINT root, con sprintf( query, insert, sig, root, path, name, type ); r = run_query( hdb, query ); HeapFree( GetProcessHeap(), 0, query ); + ok(r == ERROR_SUCCESS, "failed to insert into reglocator table: %u\n", r); \ return r; } @@ -1161,44 +1220,25 @@ static void test_settargetpath(void) hdb = create_package_db(); ok ( hdb, "failed to create package database\n" ); - r = add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'" ); - ok( r == S_OK, "failed to add directory entry: %d\n" , r ); + add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'" ); - r = create_component_table( hdb ); - ok( r == S_OK, "cannot create Component table: %d\n", r ); + create_component_table( hdb ); + add_component_entry( hdb, "'RootComp', '{83e2694d-0864-4124-9323-6d37630912a1}', 'TARGETDIR', 8, '', 'RootFile'" ); + add_component_entry( hdb, "'TestComp', '{A3FB59C8-C293-4F7E-B8C5-F0E1D8EEE4E5}', 'TestDir', 0, '', 'TestFile'" ); - r = add_component_entry( hdb, "'RootComp', '{83e2694d-0864-4124-9323-6d37630912a1}', 'TARGETDIR', 8, '', 'RootFile'" ); - ok( r == S_OK, "cannot add dummy component: %d\n", r ); + create_feature_table( hdb ); + add_feature_entry( hdb, "'TestFeature', '', '', '', 0, 1, '', 0" ); - r = add_component_entry( hdb, "'TestComp', '{A3FB59C8-C293-4F7E-B8C5-F0E1D8EEE4E5}', 'TestDir', 0, '', 'TestFile'" ); - ok( r == S_OK, "cannot add test component: %d\n", r ); - - r = create_feature_table( hdb ); - ok( r == S_OK, "cannot create Feature table: %d\n", r ); - - r = add_feature_entry( hdb, "'TestFeature', '', '', '', 0, 1, '', 0" ); - ok( r == ERROR_SUCCESS, "cannot add TestFeature to Feature table: %d\n", r ); - - r = create_feature_components_table( hdb ); - ok( r == S_OK, "cannot create FeatureComponents table: %d\n", r ); - - r = add_feature_components_entry( hdb, "'TestFeature', 'RootComp'" ); - ok( r == S_OK, "cannot insert component into FeatureComponents table: %d\n", r ); - - r = add_feature_components_entry( hdb, "'TestFeature', 'TestComp'" ); - ok( r == S_OK, "cannot insert component into FeatureComponents table: %d\n", r ); + create_feature_components_table( hdb ); + add_feature_components_entry( hdb, "'TestFeature', 'RootComp'" ); + add_feature_components_entry( hdb, "'TestFeature', 'TestComp'" ); add_directory_entry( hdb, "'TestParent', 'TARGETDIR', 'TestParent'" ); add_directory_entry( hdb, "'TestDir', 'TestParent', 'TestDir'" ); - r = create_file_table( hdb ); - ok( r == S_OK, "cannot create File table: %d\n", r ); - - r = add_file_entry( hdb, "'RootFile', 'RootComp', 'rootfile.txt', 0, '', '1033', 8192, 1" ); - ok( r == S_OK, "cannot add file to the File table: %d\n", r ); - - r = add_file_entry( hdb, "'TestFile', 'TestComp', 'testfile.txt', 0, '', '1033', 8192, 1" ); - ok( r == S_OK, "cannot add file to the File table: %d\n", r ); + create_file_table( hdb ); + add_file_entry( hdb, "'RootFile', 'RootComp', 'rootfile.txt', 0, '', '1033', 8192, 1" ); + add_file_entry( hdb, "'TestFile', 'TestComp', 'testfile.txt', 0, '', '1033', 8192, 1" ); r = package_from_db( hdb, &hpkg ); if (r == ERROR_INSTALL_PACKAGE_REJECTED) @@ -2021,6 +2061,14 @@ static void test_condition(void) /* feature doesn't exist */ r = MsiEvaluateConditionA(hpkg, "&nofeature"); ok( r == MSICONDITION_FALSE, "wrong return val (%d)\n", r); + r = MsiEvaluateConditionA(hpkg, "&nofeature=\"\""); + ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); + r = MsiEvaluateConditionA(hpkg, "!nofeature=\"\""); + ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); + MsiEvaluateConditionA(hpkg, "$nocomponent=\"\""); + ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); + MsiEvaluateConditionA(hpkg, "?nocomponent=\"\""); + ok( r == MSICONDITION_TRUE, "wrong return val (%d)\n", r); MsiSetPropertyA(hpkg, "A", "2"); MsiSetPropertyA(hpkg, "X", "50"); @@ -2102,18 +2150,9 @@ static void test_props(void) char buffer[0x100]; hdb = create_package_db(); - r = run_query( hdb, - "CREATE TABLE `Property` ( " - "`Property` CHAR(255) NOT NULL, " - "`Value` CHAR(255) " - "PRIMARY KEY `Property`)" ); - ok( r == ERROR_SUCCESS , "Failed\n" ); - r = run_query(hdb, - "INSERT INTO `Property` " - "(`Property`, `Value`) " - "VALUES( 'MetadataCompName', 'Photoshop.dll' )"); - ok( r == ERROR_SUCCESS , "Failed\n" ); + create_property_table(hdb); + add_property_entry(hdb, "'MetadataCompName', 'Photoshop.dll'"); r = package_from_db( hdb, &hpkg ); if (r == ERROR_INSTALL_PACKAGE_REJECTED) @@ -2381,17 +2420,11 @@ static void test_property_table(void) hdb = create_package_db(); ok (hdb, "failed to create package database\n"); - r = create_property_table(hdb); - ok(r == ERROR_SUCCESS, "cannot create Property table: %d\n", r); - - r = add_property_entry(hdb, "'prop', 'val'"); - ok(r == ERROR_SUCCESS, "cannot add property: %d\n", r); + create_property_table(hdb); + add_property_entry(hdb, "'prop', 'val'"); - r = create_custom_action_table(hdb); - ok(r == ERROR_SUCCESS, "cannot create CustomAction table: %d\n", r); - - r = add_custom_action_entry( hdb, "'EmbedNull', 51, 'prop2', '[~]np'" ); - ok( r == ERROR_SUCCESS, "cannot add custom action: %d\n", r); + create_custom_action_table(hdb); + add_custom_action_entry( hdb, "'EmbedNull', 51, 'prop2', '[~]np'" ); r = package_from_db(hdb, &hpkg); ok(r == ERROR_SUCCESS, "failed to create package %u\n", r); @@ -2408,8 +2441,7 @@ static void test_property_table(void) found = find_prop_in_property(hdb, "prop", "val", -1); ok(found, "prop should be in the _Property table\n"); - r = add_property_entry(hdb, "'dantes', 'mercedes'"); - ok(r == ERROR_SUCCESS, "cannot add property: %d\n", r); + add_property_entry(hdb, "'dantes', 'mercedes'"); query = "SELECT * FROM `_Property` WHERE `Property` = 'dantes'"; r = do_query(hdb, query, &hrec); @@ -2700,6 +2732,266 @@ static void test_formatrecord2(void) DeleteFileA(msifile); } +static void test_formatrecord_tables(void) +{ + MSIHANDLE hdb, hrec, hpkg = 0; + CHAR buf[MAX_PATH]; + CHAR curr_dir[MAX_PATH]; + CHAR expected[MAX_PATH]; + CHAR root[MAX_PATH]; + DWORD size; + UINT r; + + GetCurrentDirectoryA( MAX_PATH, curr_dir ); + + hdb = create_package_db(); + ok ( hdb, "failed to create package database\n"); + + add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'" ); + add_directory_entry( hdb, "'ReallyLongDir', 'TARGETDIR', " + "'I am a really long directory'" ); + + create_feature_table( hdb ); + add_feature_entry( hdb, "'occipitofrontalis', '', '', '', 2, 1, '', 0" ); + + create_component_table( hdb ); + add_component_entry( hdb, "'frontal', '', 'TARGETDIR', 0, '', 'frontal_file'" ); + add_component_entry( hdb, "'parietal', '', 'TARGETDIR', 1, '', 'parietal_file'" ); + add_component_entry( hdb, "'temporal', '', 'ReallyLongDir', 0, '', 'temporal_file'" ); + + create_feature_components_table( hdb ); + add_feature_components_entry( hdb, "'occipitofrontalis', 'frontal'" ); + add_feature_components_entry( hdb, "'occipitofrontalis', 'parietal'" ); + add_feature_components_entry( hdb, "'occipitofrontalis', 'temporal'" ); + + create_file_table( hdb ); + add_file_entry( hdb, "'frontal_file', 'frontal', 'frontal.txt', 0, '', '1033', 8192, 1" ); + add_file_entry( hdb, "'parietal_file', 'parietal', 'parietal.txt', 0, '', '1033', 8192, 1" ); + add_file_entry( hdb, "'temporal_file', 'temporal', 'temporal.txt', 0, '', '1033', 8192, 1" ); + + create_custom_action_table( hdb ); + add_custom_action_entry( hdb, "'MyCustom', 51, 'prop', '[!temporal_file]'" ); + add_custom_action_entry( hdb, "'EscapeIt1', 51, 'prop', '[\\[]Bracket Text[\\]]'" ); + add_custom_action_entry( hdb, "'EscapeIt2', 51, 'prop', '[\\xabcd]'" ); + add_custom_action_entry( hdb, "'EscapeIt3', 51, 'prop', '[abcd\\xefgh]'" ); + add_custom_action_entry( hdb, "'EmbedNull', 51, 'prop', '[~]np'" ); + + r = package_from_db( hdb, &hpkg ); + if (r == ERROR_INSTALL_PACKAGE_REJECTED) + { + skip("Not enough rights to perform tests\n"); + MsiCloseHandle( hdb ); + DeleteFileA( msifile ); + return; + } + ok( r == ERROR_SUCCESS, "failed to create package %u\n", r ); + + MsiCloseHandle( hdb ); + + r = MsiSetPropertyA( hpkg, "imaprop", "ringer" ); + ok( r == ERROR_SUCCESS, "cannot set property: %d\n", r); + + hrec = MsiCreateRecord( 1 ); + + /* property doesn't exist */ + size = MAX_PATH; + /*MsiRecordSetStringA( hrec, 0, "[1]" ); */ + MsiRecordSetStringA( hrec, 1, "[idontexist]" ); + r = MsiFormatRecordA( hpkg, hrec, buf, &size ); + ok( r == ERROR_SUCCESS, "format record failed: %d\n", r); + ok( !lstrcmpA( buf, "1: " ), "Expected '1: ', got %s\n", buf ); + + /* property exists */ + size = MAX_PATH; + MsiRecordSetStringA( hrec, 1, "[imaprop]" ); + r = MsiFormatRecordA( hpkg, hrec, buf, &size ); + ok( r == ERROR_SUCCESS, "format record failed: %d\n", r); + ok( !lstrcmpA( buf, "1: ringer " ), "Expected '1: ringer ', got %s\n", buf ); + + size = MAX_PATH; + MsiRecordSetStringA( hrec, 0, "1: [1] " ); + r = MsiFormatRecordA( hpkg, hrec, buf, &size ); + ok( r == ERROR_SUCCESS, "format record failed: %d\n", r); + ok( !lstrcmpA( buf, "1: ringer " ), "Expected '1: ringer ', got %s\n", buf ); + + /* environment variable doesn't exist */ + size = MAX_PATH; + MsiRecordSetStringA( hrec, 1, "[%idontexist]" ); + r = MsiFormatRecordA( hpkg, hrec, buf, &size ); + ok( r == ERROR_SUCCESS, "format record failed: %d\n", r); + ok( !lstrcmpA( buf, "1: " ), "Expected '1: ', got %s\n", buf ); + + /* environment variable exists */ + size = MAX_PATH; + SetEnvironmentVariableA( "crazyvar", "crazyval" ); + MsiRecordSetStringA( hrec, 1, "[%crazyvar]" ); + r = MsiFormatRecordA( hpkg, hrec, buf, &size ); + ok( r == ERROR_SUCCESS, "format record failed: %d\n", r); + ok( !lstrcmpA( buf, "1: crazyval " ), "Expected '1: crazyval ', got %s\n", buf ); + + /* file key before CostInitialize */ + size = MAX_PATH; + MsiRecordSetStringA( hrec, 1, "[#frontal_file]" ); + r = MsiFormatRecordA( hpkg, hrec, buf, &size ); + ok( r == ERROR_SUCCESS, "format record failed: %d\n", r); + ok( !lstrcmpA( buf, "1: " ), "Expected '1: ', got %s\n", buf ); + + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + + r = MsiDoActionA(hpkg, "CostInitialize"); + ok( r == ERROR_SUCCESS, "CostInitialize failed: %d\n", r); + + r = MsiDoActionA(hpkg, "FileCost"); + ok( r == ERROR_SUCCESS, "FileCost failed: %d\n", r); + + r = MsiDoActionA(hpkg, "CostFinalize"); + ok( r == ERROR_SUCCESS, "CostFinalize failed: %d\n", r); + + size = MAX_PATH; + MsiGetPropertyA( hpkg, "ROOTDRIVE", root, &size ); + + sprintf( expected, "1: %sfrontal.txt ", root); + + /* frontal full file key */ + size = MAX_PATH; + MsiRecordSetStringA( hrec, 1, "[#frontal_file]" ); + r = MsiFormatRecordA( hpkg, hrec, buf, &size ); + ok( r == ERROR_SUCCESS, "format record failed: %d\n", r); + ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf); + + /* frontal short file key */ + size = MAX_PATH; + MsiRecordSetStringA( hrec, 1, "[!frontal_file]" ); + r = MsiFormatRecordA( hpkg, hrec, buf, &size ); + ok( r == ERROR_SUCCESS, "format record failed: %d\n", r); + ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf); + + sprintf( expected, "1: %sI am a really long directory\\temporal.txt ", root); + + /* temporal full file key */ + size = MAX_PATH; + MsiRecordSetStringA( hrec, 1, "[#temporal_file]" ); + r = MsiFormatRecordA( hpkg, hrec, buf, &size ); + ok( r == ERROR_SUCCESS, "format record failed: %d\n", r); + ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf); + + /* temporal short file key */ + size = MAX_PATH; + MsiRecordSetStringA( hrec, 1, "[!temporal_file]" ); + r = MsiFormatRecordA( hpkg, hrec, buf, &size ); + ok( r == ERROR_SUCCESS, "format record failed: %d\n", r); + ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf); + + /* custom action 51, files don't exist */ + r = MsiDoActionA( hpkg, "MyCustom" ); + ok( r == ERROR_SUCCESS, "MyCustom failed: %d\n", r); + + sprintf( expected, "%sI am a really long directory\\temporal.txt", root); + + size = MAX_PATH; + r = MsiGetPropertyA( hpkg, "prop", buf, &size ); + ok( r == ERROR_SUCCESS, "get property failed: %d\n", r); + ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf); + + sprintf( buf, "%sI am a really long directory", root ); + CreateDirectoryA( buf, NULL ); + + lstrcatA( buf, "\\temporal.txt" ); + create_test_file( buf ); + + /* custom action 51, files exist */ + r = MsiDoActionA( hpkg, "MyCustom" ); + ok( r == ERROR_SUCCESS, "MyCustom failed: %d\n", r); + + size = MAX_PATH; + r = MsiGetPropertyA( hpkg, "prop", buf, &size ); + ok( r == ERROR_SUCCESS, "get property failed: %d\n", r); + todo_wine + { + ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf); + } + + /* custom action 51, escaped text 1 */ + r = MsiDoActionA( hpkg, "EscapeIt1" ); + ok( r == ERROR_SUCCESS, "EscapeIt1 failed: %d\n", r); + + size = MAX_PATH; + r = MsiGetPropertyA( hpkg, "prop", buf, &size ); + ok( r == ERROR_SUCCESS, "get property failed: %d\n", r); + ok( !lstrcmpA( buf, "[Bracket Text]" ), "Expected '[Bracket Text]', got %s\n", buf); + + /* custom action 51, escaped text 2 */ + r = MsiDoActionA( hpkg, "EscapeIt2" ); + ok( r == ERROR_SUCCESS, "EscapeIt2 failed: %d\n", r); + + size = MAX_PATH; + r = MsiGetPropertyA( hpkg, "prop", buf, &size ); + ok( r == ERROR_SUCCESS, "get property failed: %d\n", r); + ok( !lstrcmpA( buf, "x" ), "Expected 'x', got %s\n", buf); + + /* custom action 51, escaped text 3 */ + r = MsiDoActionA( hpkg, "EscapeIt3" ); + ok( r == ERROR_SUCCESS, "EscapeIt3 failed: %d\n", r); + + size = MAX_PATH; + r = MsiGetPropertyA( hpkg, "prop", buf, &size ); + ok( r == ERROR_SUCCESS, "get property failed: %d\n", r); + ok( !lstrcmpA( buf, "" ), "Expected '', got %s\n", buf); + + /* custom action 51, embedded null */ + r = MsiDoActionA( hpkg, "EmbedNull" ); + ok( r == ERROR_SUCCESS, "EmbedNull failed: %d\n", r); + + size = MAX_PATH; + memset( buf, 'a', sizeof(buf) ); + r = MsiGetPropertyA( hpkg, "prop", buf, &size ); + ok( r == ERROR_SUCCESS, "get property failed: %d\n", r); + ok( !memcmp( buf, "\0np", sizeof("\0np") ), "wrong value\n"); + ok( size == sizeof("\0np") - 1, "got %u\n", size ); + + r = MsiSetPropertyA( hpkg, "prop", "[~]np" ); + ok( r == ERROR_SUCCESS, "cannot set property: %d\n", r); + + size = MAX_PATH; + memset( buf, 'a', sizeof(buf) ); + r = MsiGetPropertyA( hpkg, "prop", buf, &size ); + ok( r == ERROR_SUCCESS, "get property failed: %d\n", r); + ok( !lstrcmpA( buf, "[~]np" ), "Expected '[~]np', got %s\n", buf); + + sprintf( expected, "1: %sI am a really long directory\\ ", root); + + /* component with INSTALLSTATE_LOCAL */ + size = MAX_PATH; + MsiRecordSetStringA( hrec, 1, "[$temporal]" ); + r = MsiFormatRecordA( hpkg, hrec, buf, &size ); + ok( r == ERROR_SUCCESS, "format record failed: %d\n", r); + ok( !lstrcmpA( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf); + + r = MsiSetComponentStateA( hpkg, "temporal", INSTALLSTATE_SOURCE ); + ok( r == ERROR_SUCCESS, "failed to set install state: %d\n", r); + + /* component with INSTALLSTATE_SOURCE */ + lstrcpyA( expected, "1: " ); + lstrcatA( expected, curr_dir ); + if (strlen(curr_dir) > 3) lstrcatA( expected, "\\" ); + lstrcatA( expected, " " ); + size = MAX_PATH; + MsiRecordSetStringA( hrec, 1, "[$parietal]" ); + r = MsiFormatRecordA( hpkg, hrec, buf, &size ); + ok( r == ERROR_SUCCESS, "format record failed: %d\n", r); + ok( !lstrcmpA( buf, expected ), "Expected '%s', got '%s'\n", expected, buf); + + sprintf( buf, "%sI am a really long directory\\temporal.txt", root ); + DeleteFileA( buf ); + + sprintf( buf, "%sI am a really long directory", root ); + RemoveDirectoryA( buf ); + + MsiCloseHandle( hrec ); + MsiCloseHandle( hpkg ); + DeleteFileA( msifile ); +} + static void test_feature_states( UINT line, MSIHANDLE package, const char *feature, UINT error, INSTALLSTATE expected_state, INSTALLSTATE expected_action, BOOL todo ) { @@ -2764,10 +3056,13 @@ static void test_states(void) {'w','i','n','e','t','e','s','t','3','-','p','a','c','k','a','g','e','.','m','s','i',0}; static const WCHAR msifile4W[] = {'w','i','n','e','t','e','s','t','4','-','p','a','c','k','a','g','e','.','m','s','i',0}; + char msi_cache_file[MAX_PATH]; + DWORD cache_file_name_len; INSTALLSTATE state; MSIHANDLE hpkg; UINT r; MSIHANDLE hdb; + BOOL is_broken; if (is_process_limited()) { @@ -2778,382 +3073,202 @@ static void test_states(void) hdb = create_package_db(); ok ( hdb, "failed to create package database\n" ); - r = add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'"); - ok( r == ERROR_SUCCESS, "cannot add directory: %d\n", r ); - - r = create_property_table( hdb ); - ok( r == ERROR_SUCCESS, "cannot create Property table: %d\n", r ); - - r = add_property_entry( hdb, "'ProductCode', '{7262AC98-EEBD-4364-8CE3-D654F6A425B9}'" ); - ok( r == ERROR_SUCCESS, "cannot add property entry: %d\n", r ); - - r = add_property_entry( hdb, "'ProductLanguage', '1033'" ); - ok( r == ERROR_SUCCESS, "cannot add property entry: %d\n", r ); - - r = add_property_entry( hdb, "'ProductName', 'MSITEST'" ); - ok( r == ERROR_SUCCESS, "cannot add property entry: %d\n", r ); - - r = add_property_entry( hdb, "'ProductVersion', '1.1.1'" ); - ok( r == ERROR_SUCCESS, "cannot add property entry: %d\n", r ); - - r = add_property_entry( hdb, "'MSIFASTINSTALL', '1'" ); - ok( r == ERROR_SUCCESS, "cannot add property entry: %d\n", r ); - - r = create_install_execute_sequence_table( hdb ); - ok( r == ERROR_SUCCESS, "cannot create InstallExecuteSequence table: %d\n", r ); - - r = add_install_execute_sequence_entry( hdb, "'CostInitialize', '', '800'" ); - ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry: %d\n", r ); - - r = add_install_execute_sequence_entry( hdb, "'FileCost', '', '900'" ); - ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry: %d\n", r ); - - r = add_install_execute_sequence_entry( hdb, "'CostFinalize', '', '1000'" ); - ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry: %d\n", r ); - - r = add_install_execute_sequence_entry( hdb, "'InstallValidate', '', '1400'" ); - ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry: %d\n", r ); - - r = add_install_execute_sequence_entry( hdb, "'InstallInitialize', '', '1500'" ); - ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry: %d\n", r ); - - r = add_install_execute_sequence_entry( hdb, "'ProcessComponents', '', '1600'" ); - ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry: %d\n", r ); + add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'"); - r = add_install_execute_sequence_entry( hdb, "'UnpublishFeatures', '', '1800'" ); - ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry: %d\n", r ); + create_property_table( hdb ); + add_property_entry( hdb, "'ProductCode', '{7262AC98-EEBD-4364-8CE3-D654F6A425B9}'" ); + add_property_entry( hdb, "'ProductLanguage', '1033'" ); + add_property_entry( hdb, "'ProductName', 'MSITEST'" ); + add_property_entry( hdb, "'ProductVersion', '1.1.1'" ); + add_property_entry( hdb, "'MSIFASTINSTALL', '1'" ); - r = add_install_execute_sequence_entry( hdb, "'RegisterProduct', '', '6100'" ); - ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry: %d\n", r ); + create_install_execute_sequence_table( hdb ); + add_install_execute_sequence_entry( hdb, "'CostInitialize', '', '800'" ); + add_install_execute_sequence_entry( hdb, "'FileCost', '', '900'" ); + add_install_execute_sequence_entry( hdb, "'CostFinalize', '', '1000'" ); + add_install_execute_sequence_entry( hdb, "'InstallValidate', '', '1400'" ); + add_install_execute_sequence_entry( hdb, "'InstallInitialize', '', '1500'" ); + add_install_execute_sequence_entry( hdb, "'ProcessComponents', '', '1600'" ); + add_install_execute_sequence_entry( hdb, "'UnpublishFeatures', '', '1800'" ); + add_install_execute_sequence_entry( hdb, "'RegisterProduct', '', '6100'" ); + add_install_execute_sequence_entry( hdb, "'PublishFeatures', '', '6300'" ); + add_install_execute_sequence_entry( hdb, "'PublishProduct', '', '6400'" ); + add_install_execute_sequence_entry( hdb, "'InstallFinalize', '', '6600'" ); - r = add_install_execute_sequence_entry( hdb, "'PublishFeatures', '', '6300'" ); - ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry: %d\n", r ); + create_media_table( hdb ); + add_media_entry( hdb, "'1', '3', '', '', 'DISK1', ''"); - r = add_install_execute_sequence_entry( hdb, "'PublishProduct', '', '6400'" ); - ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry: %d\n", r ); + create_feature_table( hdb ); - r = add_install_execute_sequence_entry( hdb, "'InstallFinalize', '', '6600'" ); - ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry: %d\n", r ); - - r = create_media_table( hdb ); - ok( r == ERROR_SUCCESS, "cannot create media table: %d\n", r ); - - r = add_media_entry( hdb, "'1', '3', '', '', 'DISK1', ''"); - ok( r == ERROR_SUCCESS, "cannot add media entry: %d\n", r ); - - r = create_feature_table( hdb ); - ok( r == ERROR_SUCCESS, "cannot create Feature table: %d\n", r ); - - r = create_component_table( hdb ); - ok( r == ERROR_SUCCESS, "cannot create Component table: %d\n", r ); + create_component_table( hdb ); /* msidbFeatureAttributesFavorLocal */ - r = add_feature_entry( hdb, "'one', '', '', '', 2, 1, '', 0" ); - ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r ); + add_feature_entry( hdb, "'one', '', '', '', 2, 1, '', 0" ); /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesLocalOnly */ - r = add_component_entry( hdb, "'alpha', '{467EC132-739D-4784-A37B-677AA43DBC94}', 'TARGETDIR', 0, '', 'alpha_file'" ); - ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); + add_component_entry( hdb, "'alpha', '{467EC132-739D-4784-A37B-677AA43DBC94}', 'TARGETDIR', 0, '', 'alpha_file'" ); /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesSourceOnly */ - r = add_component_entry( hdb, "'beta', '{2C1F189C-24A6-4C34-B26B-994A6C026506}', 'TARGETDIR', 1, '', 'beta_file'" ); - ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); + add_component_entry( hdb, "'beta', '{2C1F189C-24A6-4C34-B26B-994A6C026506}', 'TARGETDIR', 1, '', 'beta_file'" ); /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesOptional */ - r = add_component_entry( hdb, "'gamma', '{C271E2A4-DE2E-4F70-86D1-6984AF7DE2CA}', 'TARGETDIR', 2, '', 'gamma_file'" ); - ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); + add_component_entry( hdb, "'gamma', '{C271E2A4-DE2E-4F70-86D1-6984AF7DE2CA}', 'TARGETDIR', 2, '', 'gamma_file'" ); /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesSharedDllRefCount */ - r = add_component_entry( hdb, "'theta', '{4EB3129D-81A8-48D5-9801-75600FED3DD9}', 'TARGETDIR', 8, '', 'theta_file'" ); - ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); + add_component_entry( hdb, "'theta', '{4EB3129D-81A8-48D5-9801-75600FED3DD9}', 'TARGETDIR', 8, '', 'theta_file'" ); /* msidbFeatureAttributesFavorSource */ - r = add_feature_entry( hdb, "'two', '', '', '', 2, 1, '', 1" ); - ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r ); + add_feature_entry( hdb, "'two', '', '', '', 2, 1, '', 1" ); /* msidbFeatureAttributesFavorSource:msidbComponentAttributesLocalOnly */ - r = add_component_entry( hdb, "'delta', '{938FD4F2-C648-4259-A03C-7AA3B45643F3}', 'TARGETDIR', 0, '', 'delta_file'" ); - ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); + add_component_entry( hdb, "'delta', '{938FD4F2-C648-4259-A03C-7AA3B45643F3}', 'TARGETDIR', 0, '', 'delta_file'" ); /* msidbFeatureAttributesFavorSource:msidbComponentAttributesSourceOnly */ - r = add_component_entry( hdb, "'epsilon', '{D59713B6-C11D-47F2-A395-1E5321781190}', 'TARGETDIR', 1, '', 'epsilon_file'" ); - ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); + add_component_entry( hdb, "'epsilon', '{D59713B6-C11D-47F2-A395-1E5321781190}', 'TARGETDIR', 1, '', 'epsilon_file'" ); /* msidbFeatureAttributesFavorSource:msidbComponentAttributesOptional */ - r = add_component_entry( hdb, "'zeta', '{377D33AB-2FAA-42B9-A629-0C0DAE9B9C7A}', 'TARGETDIR', 2, '', 'zeta_file'" ); - ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); + add_component_entry( hdb, "'zeta', '{377D33AB-2FAA-42B9-A629-0C0DAE9B9C7A}', 'TARGETDIR', 2, '', 'zeta_file'" ); /* msidbFeatureAttributesFavorSource:msidbComponentAttributesSharedDllRefCount */ - r = add_component_entry( hdb, "'iota', '{5D36F871-B5ED-4801-9E0F-C46B9E5C9669}', 'TARGETDIR', 8, '', 'iota_file'" ); - ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); + add_component_entry( hdb, "'iota', '{5D36F871-B5ED-4801-9E0F-C46B9E5C9669}', 'TARGETDIR', 8, '', 'iota_file'" ); /* msidbFeatureAttributesFavorSource */ - r = add_feature_entry( hdb, "'three', '', '', '', 2, 1, '', 1" ); - ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r ); + add_feature_entry( hdb, "'three', '', '', '', 2, 1, '', 1" ); /* msidbFeatureAttributesFavorLocal */ - r = add_feature_entry( hdb, "'four', '', '', '', 2, 1, '', 0" ); - ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r ); + add_feature_entry( hdb, "'four', '', '', '', 2, 1, '', 0" ); /* disabled */ - r = add_feature_entry( hdb, "'five', '', '', '', 2, 0, '', 1" ); - ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r ); + add_feature_entry( hdb, "'five', '', '', '', 2, 0, '', 1" ); /* msidbFeatureAttributesFavorSource:msidbComponentAttributesSourceOnly */ - r = add_component_entry( hdb, "'eta', '{DD89003F-0DD4-41B8-81C0-3411A7DA2695}', 'TARGETDIR', 1, '', 'eta_file'" ); - ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); + add_component_entry( hdb, "'eta', '{DD89003F-0DD4-41B8-81C0-3411A7DA2695}', 'TARGETDIR', 1, '', 'eta_file'" ); /* no feature parent:msidbComponentAttributesLocalOnly */ - r = add_component_entry( hdb, "'kappa', '{D6B93DC3-8DA5-4769-9888-42BFE156BB8B}', 'TARGETDIR', 1, '', 'kappa_file'" ); - ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); + add_component_entry( hdb, "'kappa', '{D6B93DC3-8DA5-4769-9888-42BFE156BB8B}', 'TARGETDIR', 1, '', 'kappa_file'" ); /* msidbFeatureAttributesFavorLocal:removed */ - r = add_feature_entry( hdb, "'six', '', '', '', 2, 1, '', 0" ); - ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r ); + add_feature_entry( hdb, "'six', '', '', '', 2, 1, '', 0" ); /* msidbFeatureAttributesFavorLocal:removed:msidbComponentAttributesLocalOnly */ - r = add_component_entry( hdb, "'lambda', '{6528C5E4-02A4-4636-A214-7A66A6C35B64}', 'TARGETDIR', 0, '', 'lambda_file'" ); - ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); + add_component_entry( hdb, "'lambda', '{6528C5E4-02A4-4636-A214-7A66A6C35B64}', 'TARGETDIR', 0, '', 'lambda_file'" ); /* msidbFeatureAttributesFavorLocal:removed:msidbComponentAttributesSourceOnly */ - r = add_component_entry( hdb, "'mu', '{97014BAB-6C56-4013-9A63-2BF913B42519}', 'TARGETDIR', 1, '', 'mu_file'" ); - ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); + add_component_entry( hdb, "'mu', '{97014BAB-6C56-4013-9A63-2BF913B42519}', 'TARGETDIR', 1, '', 'mu_file'" ); /* msidbFeatureAttributesFavorLocal:removed:msidbComponentAttributesOptional */ - r = add_component_entry( hdb, "'nu', '{943DD0D8-5808-4954-8526-3B8493FEDDCD}', 'TARGETDIR', 2, '', 'nu_file'" ); - ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); + add_component_entry( hdb, "'nu', '{943DD0D8-5808-4954-8526-3B8493FEDDCD}', 'TARGETDIR', 2, '', 'nu_file'" ); /* msidbFeatureAttributesFavorLocal:removed:msidbComponentAttributesSharedDllRefCount */ - r = add_component_entry( hdb, "'xi', '{D6CF9EF7-6FCF-4930-B34B-F938AEFF9BDB}', 'TARGETDIR', 8, '', 'xi_file'" ); - ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); + add_component_entry( hdb, "'xi', '{D6CF9EF7-6FCF-4930-B34B-F938AEFF9BDB}', 'TARGETDIR', 8, '', 'xi_file'" ); /* msidbFeatureAttributesFavorSource:removed */ - r = add_feature_entry( hdb, "'seven', '', '', '', 2, 1, '', 1" ); - ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r ); + add_feature_entry( hdb, "'seven', '', '', '', 2, 1, '', 1" ); /* msidbFeatureAttributesFavorSource:removed:msidbComponentAttributesLocalOnly */ - r = add_component_entry( hdb, "'omicron', '{7B57521D-15DB-4141-9AA6-01D934A4433F}', 'TARGETDIR', 0, '', 'omicron_file'" ); - ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); + add_component_entry( hdb, "'omicron', '{7B57521D-15DB-4141-9AA6-01D934A4433F}', 'TARGETDIR', 0, '', 'omicron_file'" ); /* msidbFeatureAttributesFavorSource:removed:msidbComponentAttributesSourceOnly */ - r = add_component_entry( hdb, "'pi', '{FB85346B-378E-4492-8769-792305471C81}', 'TARGETDIR', 1, '', 'pi_file'" ); - ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); + add_component_entry( hdb, "'pi', '{FB85346B-378E-4492-8769-792305471C81}', 'TARGETDIR', 1, '', 'pi_file'" ); /* msidbFeatureAttributesFavorSource:removed:msidbComponentAttributesOptional */ - r = add_component_entry( hdb, "'rho', '{798F2047-7B0C-4783-8BB0-D703E554114B}', 'TARGETDIR', 2, '', 'rho_file'" ); - ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); + add_component_entry( hdb, "'rho', '{798F2047-7B0C-4783-8BB0-D703E554114B}', 'TARGETDIR', 2, '', 'rho_file'" ); /* msidbFeatureAttributesFavorSource:removed:msidbComponentAttributesSharedDllRefCount */ - r = add_component_entry( hdb, "'sigma', '{5CE9DDA8-B67B-4736-9D93-99D61C5B93E7}', 'TARGETDIR', 8, '', 'sigma_file'" ); - ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); + add_component_entry( hdb, "'sigma', '{5CE9DDA8-B67B-4736-9D93-99D61C5B93E7}', 'TARGETDIR', 8, '', 'sigma_file'" ); /* msidbFeatureAttributesFavorLocal */ - r = add_feature_entry( hdb, "'eight', '', '', '', 2, 1, '', 0" ); - ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r ); + add_feature_entry( hdb, "'eight', '', '', '', 2, 1, '', 0" ); - r = add_component_entry( hdb, "'tau', '{07DEB510-677C-4A6F-A0A6-7CD8EFEA77ED}', 'TARGETDIR', 1, '', 'tau_file'" ); - ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); + add_component_entry( hdb, "'tau', '{07DEB510-677C-4A6F-A0A6-7CD8EFEA77ED}', 'TARGETDIR', 1, '', 'tau_file'" ); /* msidbFeatureAttributesFavorSource */ - r = add_feature_entry( hdb, "'nine', '', '', '', 2, 1, '', 1" ); - ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r ); + add_feature_entry( hdb, "'nine', '', '', '', 2, 1, '', 1" ); - r = add_component_entry( hdb, "'phi', '{9F0594C5-35AD-43EA-94DD-8DF73FAA664D}', 'TARGETDIR', 1, '', 'phi_file'" ); - ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); + add_component_entry( hdb, "'phi', '{9F0594C5-35AD-43EA-94DD-8DF73FAA664D}', 'TARGETDIR', 1, '', 'phi_file'" ); /* msidbFeatureAttributesFavorAdvertise */ - r = add_feature_entry( hdb, "'ten', '', '', '', 2, 1, '', 4" ); - ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r ); + add_feature_entry( hdb, "'ten', '', '', '', 2, 1, '', 4" ); - r = add_component_entry( hdb, "'chi', '{E6B539AB-5DA9-4236-A2D2-E341A50B4C38}', 'TARGETDIR', 1, '', 'chi_file'" ); - ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); + add_component_entry( hdb, "'chi', '{E6B539AB-5DA9-4236-A2D2-E341A50B4C38}', 'TARGETDIR', 1, '', 'chi_file'" ); /* msidbFeatureAttributesUIDisallowAbsent */ - r = add_feature_entry( hdb, "'eleven', '', '', '', 2, 1, '', 16" ); - ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r ); + add_feature_entry( hdb, "'eleven', '', '', '', 2, 1, '', 16" ); - r = add_component_entry( hdb, "'psi', '{A06B23B5-746B-427A-8A6E-FD6AC8F46A95}', 'TARGETDIR', 1, '', 'psi_file'" ); - ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); + add_component_entry( hdb, "'psi', '{A06B23B5-746B-427A-8A6E-FD6AC8F46A95}', 'TARGETDIR', 1, '', 'psi_file'" ); /* high install level */ - r = add_feature_entry( hdb, "'twelve', '', '', '', 2, 2, '', 0" ); - ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r ); + add_feature_entry( hdb, "'twelve', '', '', '', 2, 2, '', 0" ); - r = add_component_entry( hdb, "'upsilon', '{557e0c04-ceba-4c58-86a9-4a73352e8cf6}', 'TARGETDIR', 1, '', 'upsilon_file'" ); - ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); + add_component_entry( hdb, "'upsilon', '{557e0c04-ceba-4c58-86a9-4a73352e8cf6}', 'TARGETDIR', 1, '', 'upsilon_file'" ); /* msidbFeatureAttributesFollowParent */ - r = add_feature_entry( hdb, "'thirteen', '', '', '', 2, 2, '', 2" ); - ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r ); - - r = create_feature_components_table( hdb ); - ok( r == ERROR_SUCCESS, "cannot create FeatureComponents table: %d\n", r ); - - r = add_feature_components_entry( hdb, "'one', 'alpha'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); - - r = add_feature_components_entry( hdb, "'one', 'beta'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); - - r = add_feature_components_entry( hdb, "'one', 'gamma'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); - - r = add_feature_components_entry( hdb, "'one', 'theta'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); - - r = add_feature_components_entry( hdb, "'two', 'delta'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); - - r = add_feature_components_entry( hdb, "'two', 'epsilon'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); - - r = add_feature_components_entry( hdb, "'two', 'zeta'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); - - r = add_feature_components_entry( hdb, "'two', 'iota'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); - - r = add_feature_components_entry( hdb, "'three', 'eta'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); - - r = add_feature_components_entry( hdb, "'four', 'eta'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); - - r = add_feature_components_entry( hdb, "'five', 'eta'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); - - r = add_feature_components_entry( hdb, "'six', 'lambda'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); - - r = add_feature_components_entry( hdb, "'six', 'mu'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); - - r = add_feature_components_entry( hdb, "'six', 'nu'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); - - r = add_feature_components_entry( hdb, "'six', 'xi'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); - - r = add_feature_components_entry( hdb, "'seven', 'omicron'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); - - r = add_feature_components_entry( hdb, "'seven', 'pi'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); - - r = add_feature_components_entry( hdb, "'seven', 'rho'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); - - r = add_feature_components_entry( hdb, "'seven', 'sigma'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); - - r = add_feature_components_entry( hdb, "'eight', 'tau'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); - - r = add_feature_components_entry( hdb, "'nine', 'phi'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); - - r = add_feature_components_entry( hdb, "'ten', 'chi'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); - - r = add_feature_components_entry( hdb, "'eleven', 'psi'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); - - r = add_feature_components_entry( hdb, "'twelve', 'upsilon'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); - - r = add_feature_components_entry( hdb, "'thirteen', 'upsilon'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); - - r = create_file_table( hdb ); - ok( r == ERROR_SUCCESS, "cannot create File table: %d\n", r ); - - r = add_file_entry( hdb, "'alpha_file', 'alpha', 'alpha.txt', 100, '', '1033', 8192, 1" ); - ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r); - - r = add_file_entry( hdb, "'beta_file', 'beta', 'beta.txt', 0, '', '1033', 8192, 1" ); - ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r); - - r = add_file_entry( hdb, "'gamma_file', 'gamma', 'gamma.txt', 0, '', '1033', 8192, 1" ); - ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r); - - r = add_file_entry( hdb, "'theta_file', 'theta', 'theta.txt', 0, '', '1033', 8192, 1" ); - ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r); - - r = add_file_entry( hdb, "'delta_file', 'delta', 'delta.txt', 0, '', '1033', 8192, 1" ); - ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r); - - r = add_file_entry( hdb, "'epsilon_file', 'epsilon', 'epsilon.txt', 0, '', '1033', 8192, 1" ); - ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r); - - r = add_file_entry( hdb, "'zeta_file', 'zeta', 'zeta.txt', 0, '', '1033', 8192, 1" ); - ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r); - - r = add_file_entry( hdb, "'iota_file', 'iota', 'iota.txt', 0, '', '1033', 8192, 1" ); - ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r); + add_feature_entry( hdb, "'thirteen', '', '', '', 2, 2, '', 2" ); + + create_feature_components_table( hdb ); + add_feature_components_entry( hdb, "'one', 'alpha'" ); + add_feature_components_entry( hdb, "'one', 'beta'" ); + add_feature_components_entry( hdb, "'one', 'gamma'" ); + add_feature_components_entry( hdb, "'one', 'theta'" ); + add_feature_components_entry( hdb, "'two', 'delta'" ); + add_feature_components_entry( hdb, "'two', 'epsilon'" ); + add_feature_components_entry( hdb, "'two', 'zeta'" ); + add_feature_components_entry( hdb, "'two', 'iota'" ); + add_feature_components_entry( hdb, "'three', 'eta'" ); + add_feature_components_entry( hdb, "'four', 'eta'" ); + add_feature_components_entry( hdb, "'five', 'eta'" ); + add_feature_components_entry( hdb, "'six', 'lambda'" ); + add_feature_components_entry( hdb, "'six', 'mu'" ); + add_feature_components_entry( hdb, "'six', 'nu'" ); + add_feature_components_entry( hdb, "'six', 'xi'" ); + add_feature_components_entry( hdb, "'seven', 'omicron'" ); + add_feature_components_entry( hdb, "'seven', 'pi'" ); + add_feature_components_entry( hdb, "'seven', 'rho'" ); + add_feature_components_entry( hdb, "'seven', 'sigma'" ); + add_feature_components_entry( hdb, "'eight', 'tau'" ); + add_feature_components_entry( hdb, "'nine', 'phi'" ); + add_feature_components_entry( hdb, "'ten', 'chi'" ); + add_feature_components_entry( hdb, "'eleven', 'psi'" ); + add_feature_components_entry( hdb, "'twelve', 'upsilon'" ); + add_feature_components_entry( hdb, "'thirteen', 'upsilon'" ); + + create_file_table( hdb ); + add_file_entry( hdb, "'alpha_file', 'alpha', 'alpha.txt', 100, '', '1033', 8192, 1" ); + add_file_entry( hdb, "'beta_file', 'beta', 'beta.txt', 0, '', '1033', 8192, 1" ); + add_file_entry( hdb, "'gamma_file', 'gamma', 'gamma.txt', 0, '', '1033', 8192, 1" ); + add_file_entry( hdb, "'theta_file', 'theta', 'theta.txt', 0, '', '1033', 8192, 1" ); + add_file_entry( hdb, "'delta_file', 'delta', 'delta.txt', 0, '', '1033', 8192, 1" ); + add_file_entry( hdb, "'epsilon_file', 'epsilon', 'epsilon.txt', 0, '', '1033', 8192, 1" ); + add_file_entry( hdb, "'zeta_file', 'zeta', 'zeta.txt', 0, '', '1033', 8192, 1" ); + add_file_entry( hdb, "'iota_file', 'iota', 'iota.txt', 0, '', '1033', 8192, 1" ); /* compressed file */ - r = add_file_entry( hdb, "'eta_file', 'eta', 'eta.txt', 0, '', '1033', 16384, 1" ); - ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r); - - r = add_file_entry( hdb, "'kappa_file', 'kappa', 'kappa.txt', 0, '', '1033', 8192, 1" ); - ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r); - - r = add_file_entry( hdb, "'lambda_file', 'lambda', 'lambda.txt', 100, '', '1033', 8192, 1" ); - ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r); - - r = add_file_entry( hdb, "'mu_file', 'mu', 'mu.txt', 100, '', '1033', 8192, 1" ); - ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r); - - r = add_file_entry( hdb, "'nu_file', 'nu', 'nu.txt', 100, '', '1033', 8192, 1" ); - ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r); - - r = add_file_entry( hdb, "'xi_file', 'xi', 'xi.txt', 100, '', '1033', 8192, 1" ); - ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r); - - r = add_file_entry( hdb, "'omicron_file', 'omicron', 'omicron.txt', 100, '', '1033', 8192, 1" ); - ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r); - - r = add_file_entry( hdb, "'pi_file', 'pi', 'pi.txt', 100, '', '1033', 8192, 1" ); - ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r); - - r = add_file_entry( hdb, "'rho_file', 'rho', 'rho.txt', 100, '', '1033', 8192, 1" ); - ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r); - - r = add_file_entry( hdb, "'sigma_file', 'sigma', 'sigma.txt', 100, '', '1033', 8192, 1" ); - ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r); + add_file_entry( hdb, "'eta_file', 'eta', 'eta.txt', 0, '', '1033', 16384, 1" ); + + add_file_entry( hdb, "'kappa_file', 'kappa', 'kappa.txt', 0, '', '1033', 8192, 1" ); + add_file_entry( hdb, "'lambda_file', 'lambda', 'lambda.txt', 100, '', '1033', 8192, 1" ); + add_file_entry( hdb, "'mu_file', 'mu', 'mu.txt', 100, '', '1033', 8192, 1" ); + add_file_entry( hdb, "'nu_file', 'nu', 'nu.txt', 100, '', '1033', 8192, 1" ); + add_file_entry( hdb, "'xi_file', 'xi', 'xi.txt', 100, '', '1033', 8192, 1" ); + add_file_entry( hdb, "'omicron_file', 'omicron', 'omicron.txt', 100, '', '1033', 8192, 1" ); + add_file_entry( hdb, "'pi_file', 'pi', 'pi.txt', 100, '', '1033', 8192, 1" ); + add_file_entry( hdb, "'rho_file', 'rho', 'rho.txt', 100, '', '1033', 8192, 1" ); + add_file_entry( hdb, "'sigma_file', 'sigma', 'sigma.txt', 100, '', '1033', 8192, 1" ); + add_file_entry( hdb, "'tau_file', 'tau', 'tau.txt', 100, '', '1033', 8192, 1" ); + add_file_entry( hdb, "'phi_file', 'phi', 'phi.txt', 100, '', '1033', 8192, 1" ); + add_file_entry( hdb, "'chi_file', 'chi', 'chi.txt', 100, '', '1033', 8192, 1" ); + add_file_entry( hdb, "'psi_file', 'psi', 'psi.txt', 100, '', '1033', 8192, 1" ); + add_file_entry( hdb, "'upsilon_file', 'upsilon', 'upsilon.txt', 0, '', '1033', 16384, 1" ); - r = add_file_entry( hdb, "'tau_file', 'tau', 'tau.txt', 100, '', '1033', 8192, 1" ); - ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r); - - r = add_file_entry( hdb, "'phi_file', 'phi', 'phi.txt', 100, '', '1033', 8192, 1" ); - ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r); - - r = add_file_entry( hdb, "'chi_file', 'chi', 'chi.txt', 100, '', '1033', 8192, 1" ); - ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r); - - r = add_file_entry( hdb, "'psi_file', 'psi', 'psi.txt', 100, '', '1033', 8192, 1" ); - ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r); - - r = add_file_entry( hdb, "'upsilon_file', 'upsilon', 'upsilon.txt', 0, '', '1033', 16384, 1" ); - ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r); - - MsiDatabaseCommit(hdb); + r = MsiDatabaseCommit(hdb); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r ); /* these properties must not be in the saved msi file */ - r = add_property_entry( hdb, "'ADDLOCAL', 'one,four'"); - ok( r == ERROR_SUCCESS, "cannot add property: %d\n", r ); - - r = add_property_entry( hdb, "'ADDSOURCE', 'two,three'"); - ok( r == ERROR_SUCCESS, "cannot add property: %d\n", r ); - - r = add_property_entry( hdb, "'REMOVE', 'six,seven'"); - ok( r == ERROR_SUCCESS, "cannot add property: %d\n", r ); - - r = add_property_entry( hdb, "'REINSTALL', 'eight,nine,ten'"); - ok( r == ERROR_SUCCESS, "cannot add property: %d\n", r ); - - r = add_property_entry( hdb, "'REINSTALLMODE', 'omus'"); - ok( r == ERROR_SUCCESS, "cannot add property: %d\n", r ); + add_property_entry( hdb, "'ADDLOCAL', 'one,four'"); + add_property_entry( hdb, "'ADDSOURCE', 'two,three'"); + add_property_entry( hdb, "'REMOVE', 'six,seven'"); + add_property_entry( hdb, "'REINSTALL', 'eight,nine,ten'"); + add_property_entry( hdb, "'REINSTALLMODE', 'omus'"); r = package_from_db( hdb, &hpkg ); if (r == ERROR_INSTALL_PACKAGE_REJECTED) @@ -3240,17 +3355,10 @@ static void test_states(void) ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r); /* these properties must not be in the saved msi file */ - r = add_property_entry( hdb, "'ADDLOCAL', 'one,four'"); - ok( r == ERROR_SUCCESS, "cannot add property: %d\n", r ); - - r = add_property_entry( hdb, "'ADDSOURCE', 'two,three'"); - ok( r == ERROR_SUCCESS, "cannot add property: %d\n", r ); - - r = add_property_entry( hdb, "'REMOVE', 'six,seven'"); - ok( r == ERROR_SUCCESS, "cannot add property: %d\n", r ); - - r = add_property_entry( hdb, "'REINSTALL', 'eight,nine,ten'"); - ok( r == ERROR_SUCCESS, "cannot add property: %d\n", r ); + add_property_entry( hdb, "'ADDLOCAL', 'one,four'"); + add_property_entry( hdb, "'ADDSOURCE', 'two,three'"); + add_property_entry( hdb, "'REMOVE', 'six,seven'"); + add_property_entry( hdb, "'REINSTALL', 'eight,nine,ten'"); r = package_from_db( hdb, &hpkg ); ok( r == ERROR_SUCCESS, "failed to create package %u\n", r ); @@ -3337,8 +3445,7 @@ static void test_states(void) ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r); /* these properties must not be in the saved msi file */ - r = add_property_entry( hdb, "'ADDLOCAL', 'one,two,three,four,five,six,seven,eight,nine,ten,twelve'"); - ok( r == ERROR_SUCCESS, "cannot add property: %d\n", r ); + add_property_entry( hdb, "'ADDLOCAL', 'one,two,three,four,five,six,seven,eight,nine,ten,twelve'"); r = package_from_db( hdb, &hpkg ); ok( r == ERROR_SUCCESS, "failed to create package %u\n", r ); @@ -3412,8 +3519,7 @@ static void test_states(void) ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r); /* this property must not be in the saved msi file */ - r = add_property_entry( hdb, "'ADDSOURCE', 'one,two,three,four,five,six,seven,eight,nine,ten'"); - ok( r == ERROR_SUCCESS, "cannot add property: %d\n", r ); + add_property_entry( hdb, "'ADDSOURCE', 'one,two,three,four,five,six,seven,eight,nine,ten'"); r = package_from_db( hdb, &hpkg ); ok( r == ERROR_SUCCESS, "failed to create package %u\n", r ); @@ -3472,13 +3578,14 @@ static void test_states(void) test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); - test_component_states( __LINE__, hpkg, "upsilon", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, TRUE ); + test_component_states( __LINE__, hpkg, "upsilon", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); MsiCloseHandle(hpkg); /* reinstall the product */ r = MsiInstallProductA(msifile3, "REINSTALL=ALL"); - ok(r == ERROR_SUCCESS || broken(r == ERROR_INSTALL_FAILURE) /* win2k3 */, "Expected ERROR_SUCCESS, got %d\n", r); + is_broken = (r == ERROR_INSTALL_FAILURE); + ok(r == ERROR_SUCCESS || broken(is_broken) /* win2k3 */, "Expected ERROR_SUCCESS, got %d\n", r); state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "five"); ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state); @@ -3489,8 +3596,7 @@ static void test_states(void) ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r); /* this property must not be in the saved msi file */ - r = add_property_entry( hdb, "'ADDSOURCE', 'one,two,three,four,five,six,seven,eight,nine,ten'"); - ok( r == ERROR_SUCCESS, "cannot add property: %d\n", r ); + add_property_entry( hdb, "'ADDSOURCE', 'one,two,three,four,five,six,seven,eight,nine,ten'"); r = package_from_db( hdb, &hpkg ); ok( r == ERROR_SUCCESS, "failed to create package %u\n", r ); @@ -3549,25 +3655,127 @@ static void test_states(void) test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); - test_component_states( __LINE__, hpkg, "upsilon", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, TRUE ); + test_component_states( __LINE__, hpkg, "upsilon", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); MsiCloseHandle(hpkg); - /* uninstall the product */ - r = MsiInstallProductA(msifile4, "REMOVE=ALL"); + /* test source only install */ + r = MsiInstallProductA(msifile, "REMOVE=ALL"); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "one"); + ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state); + state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "two"); + ok(state == INSTALLSTATE_UNKNOWN, "state = %d\n", state); - DeleteFileA(msifile); - DeleteFileA(msifile2); - DeleteFileA(msifile3); - DeleteFileA(msifile4); -} + r = MsiInstallProductA(msifile, "ADDSOURCE=one"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "one"); + ok(state == INSTALLSTATE_SOURCE, "state = %d\n", state); + state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "two"); + ok(state == INSTALLSTATE_ABSENT, "state = %d\n", state); -static void test_getproperty(void) -{ - MSIHANDLE hPackage = 0; - char prop[100]; - static CHAR empty[] = ""; + /* no arguments test */ + cache_file_name_len = sizeof(msi_cache_file); + r = MsiGetProductInfoA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", + INSTALLPROPERTY_LOCALPACKAGEA, msi_cache_file, &cache_file_name_len); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + r = MsiOpenDatabaseA(msi_cache_file, (const char*)MSIDBOPEN_DIRECT, &hdb); + ok(r == ERROR_SUCCESS, "failed to open database: %d\n", r); + + create_custom_action_table( hdb ); + add_custom_action_entry( hdb, "'ConditionCheck1', 19, '', 'Condition check failed (1)'" ); + add_custom_action_entry( hdb, "'ConditionCheck2', 19, '', 'Condition check failed (2)'" ); + add_custom_action_entry( hdb, "'ConditionCheck3', 19, '', 'Condition check failed (3)'" ); + add_custom_action_entry( hdb, "'ConditionCheck4', 19, '', 'Condition check failed (4)'" ); + add_custom_action_entry( hdb, "'ConditionCheck5', 19, '', 'Condition check failed (5)'" ); + add_custom_action_entry( hdb, "'ConditionCheck6', 19, '', 'Condition check failed (6)'" ); + add_custom_action_entry( hdb, "'ConditionCheck7', 19, '', 'Condition check failed (7)'" ); + add_custom_action_entry( hdb, "'ConditionCheck8', 19, '', 'Condition check failed (8)'" ); + + add_install_execute_sequence_entry( hdb, "'ConditionCheck1', 'REINSTALL', '798'" ); + add_install_execute_sequence_entry( hdb, "'ConditionCheck2', 'NOT REMOVE AND Preselected', '799'" ); + add_install_execute_sequence_entry( hdb, "'ConditionCheck3', 'REINSTALL', '6598'" ); + add_install_execute_sequence_entry( hdb, "'ConditionCheck4', 'NOT REMOVE AND Preselected', '6599'" ); + add_install_execute_sequence_entry( hdb, "'ConditionCheck5', 'REINSTALL', '6601'" ); + add_install_execute_sequence_entry( hdb, "'ConditionCheck6', 'NOT REMOVE AND Preselected', '6601'" ); + /* Add "one" feature action tests */ + add_install_execute_sequence_entry( hdb, "'ConditionCheck7', 'NOT REMOVE AND NOT(&one=-1)', '1501'" ); + add_install_execute_sequence_entry( hdb, "'ConditionCheck8', 'NOT REMOVE AND NOT(&one=-1)', '6602'" ); + r = MsiDatabaseCommit(hdb); + ok(r == ERROR_SUCCESS, "MsiDatabaseCommit failed: %d\n", r); + r = package_from_db( hdb, &hpkg ); + ok( r == ERROR_SUCCESS, "failed to create package %u\n", r ); + MsiCloseHandle(hdb); + + test_feature_states( __LINE__, hpkg, "one", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE ); + test_feature_states( __LINE__, hpkg, "two", ERROR_UNKNOWN_FEATURE, 0, 0, FALSE ); + r = MsiDoActionA( hpkg, "CostInitialize"); + ok( r == ERROR_SUCCESS, "CostInitialize failed\n"); + test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); + test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); + + r = MsiDoActionA( hpkg, "FileCost"); + ok( r == ERROR_SUCCESS, "FileCost failed\n"); + test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); + test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_UNKNOWN, INSTALLSTATE_UNKNOWN, FALSE ); + + r = MsiDoActionA( hpkg, "CostFinalize"); + ok( r == ERROR_SUCCESS, "CostFinalize failed\n"); + test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); + test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); + test_component_states( __LINE__, hpkg, "alpha", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); + test_component_states( __LINE__, hpkg, "beta", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); + test_component_states( __LINE__, hpkg, "gamma", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); + test_component_states( __LINE__, hpkg, "theta", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE ); + test_component_states( __LINE__, hpkg, "delta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); + test_component_states( __LINE__, hpkg, "epsilon", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); + test_component_states( __LINE__, hpkg, "zeta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); + test_component_states( __LINE__, hpkg, "iota", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); + test_component_states( __LINE__, hpkg, "eta", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); + test_component_states( __LINE__, hpkg, "kappa", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); + test_component_states( __LINE__, hpkg, "lambda", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); + test_component_states( __LINE__, hpkg, "mu", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); + test_component_states( __LINE__, hpkg, "nu", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); + test_component_states( __LINE__, hpkg, "xi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); + test_component_states( __LINE__, hpkg, "omicron", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); + test_component_states( __LINE__, hpkg, "pi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); + test_component_states( __LINE__, hpkg, "rho", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); + test_component_states( __LINE__, hpkg, "sigma", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); + test_component_states( __LINE__, hpkg, "tau", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); + test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); + test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); + test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); + test_component_states( __LINE__, hpkg, "upsilon", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); + + r = MsiDoActionA( hpkg, "InstallValidate"); + ok( r == ERROR_SUCCESS, "InstallValidate failed %d\n", r); + test_feature_states( __LINE__, hpkg, "one", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE ); + test_feature_states( __LINE__, hpkg, "two", ERROR_SUCCESS, INSTALLSTATE_ABSENT, INSTALLSTATE_UNKNOWN, FALSE ); + MsiCloseHandle( hpkg ); + + r = MsiInstallProductA(msifile, ""); + ok(r == ERROR_SUCCESS || (is_broken && r == ERROR_INSTALL_FAILURE) /* win2k3 */, + "Expected ERROR_SUCCESS, got %d\n", r); + state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "one"); + ok(state == INSTALLSTATE_SOURCE, "state = %d\n", state); + state = MsiQueryFeatureStateA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "two"); + ok(state == INSTALLSTATE_ABSENT, "state = %d\n", state); + + /* uninstall the product */ + r = MsiInstallProductA(msifile4, "REMOVE=ALL"); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + + DeleteFileA(msifile); + DeleteFileA(msifile2); + DeleteFileA(msifile3); + DeleteFileA(msifile4); +} + +static void test_getproperty(void) +{ + MSIHANDLE hPackage = 0; + char prop[100]; + static CHAR empty[] = ""; DWORD size; UINT r; @@ -3624,89 +3832,39 @@ static void test_removefiles(void) hdb = create_package_db(); ok ( hdb, "failed to create package database\n" ); - r = add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'"); - ok( r == ERROR_SUCCESS, "cannot add directory: %d\n", r ); - - r = create_feature_table( hdb ); - ok( r == ERROR_SUCCESS, "cannot create Feature table: %d\n", r ); - - r = create_component_table( hdb ); - ok( r == ERROR_SUCCESS, "cannot create Component table: %d\n", r ); - - r = add_feature_entry( hdb, "'one', '', '', '', 2, 1, '', 0" ); - ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r ); - - r = add_component_entry( hdb, "'hydrogen', '', 'TARGETDIR', 0, '', 'hydrogen_file'" ); - ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); - - r = add_component_entry( hdb, "'helium', '', 'TARGETDIR', 0, '', 'helium_file'" ); - ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); - - r = add_component_entry( hdb, "'lithium', '', 'TARGETDIR', 0, '', 'lithium_file'" ); - ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); - - r = add_component_entry( hdb, "'beryllium', '', 'TARGETDIR', 0, '', 'beryllium_file'" ); - ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); - - r = add_component_entry( hdb, "'boron', '', 'TARGETDIR', 0, '', 'boron_file'" ); - ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); - - r = add_component_entry( hdb, "'carbon', '', 'TARGETDIR', 0, '', 'carbon_file'" ); - ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); - - r = add_component_entry( hdb, "'oxygen', '', 'TARGETDIR', 0, '0', 'oxygen_file'" ); - ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); - - r = create_feature_components_table( hdb ); - ok( r == ERROR_SUCCESS, "cannot create FeatureComponents table: %d\n", r ); - - r = add_feature_components_entry( hdb, "'one', 'hydrogen'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); - - r = add_feature_components_entry( hdb, "'one', 'helium'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); - - r = add_feature_components_entry( hdb, "'one', 'lithium'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); - - r = add_feature_components_entry( hdb, "'one', 'beryllium'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); - - r = add_feature_components_entry( hdb, "'one', 'boron'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); - - r = add_feature_components_entry( hdb, "'one', 'carbon'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); - - r = add_feature_components_entry( hdb, "'one', 'oxygen'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); - - r = create_file_table( hdb ); - ok( r == ERROR_SUCCESS, "cannot create File table: %d\n", r ); - - r = add_file_entry( hdb, "'hydrogen_file', 'hydrogen', 'hydrogen.txt', 0, '', '1033', 8192, 1" ); - ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r); - - r = add_file_entry( hdb, "'helium_file', 'helium', 'helium.txt', 0, '', '1033', 8192, 1" ); - ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r); - - r = add_file_entry( hdb, "'lithium_file', 'lithium', 'lithium.txt', 0, '', '1033', 8192, 1" ); - ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r); - - r = add_file_entry( hdb, "'beryllium_file', 'beryllium', 'beryllium.txt', 0, '', '1033', 16384, 1" ); - ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r); - - r = add_file_entry( hdb, "'boron_file', 'boron', 'boron.txt', 0, '', '1033', 16384, 1" ); - ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r); - - r = add_file_entry( hdb, "'carbon_file', 'carbon', 'carbon.txt', 0, '', '1033', 16384, 1" ); - ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r); - - r = add_file_entry( hdb, "'oxygen_file', 'oxygen', 'oxygen.txt', 0, '', '1033', 16384, 1" ); - ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r); - - r = create_remove_file_table( hdb ); - ok( r == ERROR_SUCCESS, "cannot create Remove File table: %d\n", r); + add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'"); + + create_feature_table( hdb ); + add_feature_entry( hdb, "'one', '', '', '', 2, 1, '', 0" ); + + create_component_table( hdb ); + add_component_entry( hdb, "'hydrogen', '', 'TARGETDIR', 0, '', 'hydrogen_file'" ); + add_component_entry( hdb, "'helium', '', 'TARGETDIR', 0, '', 'helium_file'" ); + add_component_entry( hdb, "'lithium', '', 'TARGETDIR', 0, '', 'lithium_file'" ); + add_component_entry( hdb, "'beryllium', '', 'TARGETDIR', 0, '', 'beryllium_file'" ); + add_component_entry( hdb, "'boron', '', 'TARGETDIR', 0, '', 'boron_file'" ); + add_component_entry( hdb, "'carbon', '', 'TARGETDIR', 0, '', 'carbon_file'" ); + add_component_entry( hdb, "'oxygen', '', 'TARGETDIR', 0, '0', 'oxygen_file'" ); + + create_feature_components_table( hdb ); + add_feature_components_entry( hdb, "'one', 'hydrogen'" ); + add_feature_components_entry( hdb, "'one', 'helium'" ); + add_feature_components_entry( hdb, "'one', 'lithium'" ); + add_feature_components_entry( hdb, "'one', 'beryllium'" ); + add_feature_components_entry( hdb, "'one', 'boron'" ); + add_feature_components_entry( hdb, "'one', 'carbon'" ); + add_feature_components_entry( hdb, "'one', 'oxygen'" ); + + create_file_table( hdb ); + add_file_entry( hdb, "'hydrogen_file', 'hydrogen', 'hydrogen.txt', 0, '', '1033', 8192, 1" ); + add_file_entry( hdb, "'helium_file', 'helium', 'helium.txt', 0, '', '1033', 8192, 1" ); + add_file_entry( hdb, "'lithium_file', 'lithium', 'lithium.txt', 0, '', '1033', 8192, 1" ); + add_file_entry( hdb, "'beryllium_file', 'beryllium', 'beryllium.txt', 0, '', '1033', 16384, 1" ); + add_file_entry( hdb, "'boron_file', 'boron', 'boron.txt', 0, '', '1033', 16384, 1" ); + add_file_entry( hdb, "'carbon_file', 'carbon', 'carbon.txt', 0, '', '1033', 16384, 1" ); + add_file_entry( hdb, "'oxygen_file', 'oxygen', 'oxygen.txt', 0, '', '1033', 16384, 1" ); + + create_remove_file_table( hdb ); r = package_from_db( hdb, &hpkg ); if (r == ERROR_INSTALL_PACKAGE_REJECTED) @@ -3826,49 +3984,28 @@ static void test_appsearch(void) hdb = create_package_db(); ok ( hdb, "failed to create package database\n" ); - r = create_appsearch_table( hdb ); - ok( r == ERROR_SUCCESS, "cannot create AppSearch table: %d\n", r ); - - r = add_appsearch_entry( hdb, "'WEBBROWSERPROG', 'NewSignature1'" ); - ok( r == ERROR_SUCCESS, "cannot add entry: %d\n", r ); - - r = add_appsearch_entry( hdb, "'NOTEPAD', 'NewSignature2'" ); - ok( r == ERROR_SUCCESS, "cannot add entry: %d\n", r ); - - r = add_appsearch_entry( hdb, "'REGEXPANDVAL', 'NewSignature3'" ); - ok( r == ERROR_SUCCESS, "cannot add entry: %d\n", r ); - - r = create_reglocator_table( hdb ); - ok( r == ERROR_SUCCESS, "cannot create RegLocator table: %d\n", r ); + create_appsearch_table( hdb ); + add_appsearch_entry( hdb, "'WEBBROWSERPROG', 'NewSignature1'" ); + add_appsearch_entry( hdb, "'NOTEPAD', 'NewSignature2'" ); + add_appsearch_entry( hdb, "'REGEXPANDVAL', 'NewSignature3'" ); - r = add_reglocator_entry( hdb, "NewSignature1", 0, "htmlfile\\shell\\open\\command", "", 1 ); - ok( r == ERROR_SUCCESS, "cannot create RegLocator table: %d\n", r ); + create_reglocator_table( hdb ); + add_reglocator_entry( hdb, "NewSignature1", 0, "htmlfile\\shell\\open\\command", "", 1 ); r = RegCreateKeyExA(HKEY_CURRENT_USER, "Software\\Winetest_msi", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hkey, NULL); ok( r == ERROR_SUCCESS, "Could not create key: %d.\n", r ); r = RegSetValueExA(hkey, NULL, 0, REG_EXPAND_SZ, (const BYTE*)reg_expand_value, strlen(reg_expand_value) + 1); ok( r == ERROR_SUCCESS, "Could not set key value: %d.\n", r); RegCloseKey(hkey); - r = add_reglocator_entry( hdb, "NewSignature3", 1, "Software\\Winetest_msi", "", 1 ); - ok( r == ERROR_SUCCESS, "cannot create RegLocator table: %d\n", r ); + add_reglocator_entry( hdb, "NewSignature3", 1, "Software\\Winetest_msi", "", 1 ); - r = create_drlocator_table( hdb ); - ok( r == ERROR_SUCCESS, "cannot create DrLocator table: %d\n", r ); + create_drlocator_table( hdb ); + add_drlocator_entry( hdb, "'NewSignature2', 0, 'c:\\windows\\system32', 0" ); - r = add_drlocator_entry( hdb, "'NewSignature2', 0, 'c:\\windows\\system32', 0" ); - ok( r == ERROR_SUCCESS, "cannot create RegLocator table: %d\n", r ); - - r = create_signature_table( hdb ); - ok( r == ERROR_SUCCESS, "cannot create Signature table: %d\n", r ); - - r = add_signature_entry( hdb, "'NewSignature1', 'FileName', '', '', '', '', '', '', ''" ); - ok( r == ERROR_SUCCESS, "cannot add signature: %d\n", r ); - - r = add_signature_entry( hdb, "'NewSignature2', 'NOTEPAD.EXE|notepad.exe', '', '', '', '', '', '', ''" ); - ok( r == ERROR_SUCCESS, "cannot add signature: %d\n", r ); - - r = add_signature_entry( hdb, "'NewSignature3', 'NOTEPAD.EXE|notepad.exe', '', '', '', '', '', '', ''" ); - ok( r == ERROR_SUCCESS, "cannot add signature: %d\n", r ); + create_signature_table( hdb ); + add_signature_entry( hdb, "'NewSignature1', 'FileName', '', '', '', '', '', '', ''" ); + add_signature_entry( hdb, "'NewSignature2', 'NOTEPAD.EXE|notepad.exe', '', '', '', '', '', '', ''" ); + add_signature_entry( hdb, "'NewSignature3', 'NOTEPAD.EXE|notepad.exe', '', '', '', '', '', '', ''" ); r = package_from_db( hdb, &hpkg ); if (r == ERROR_INSTALL_PACKAGE_REJECTED) @@ -3968,122 +4105,67 @@ static void test_appsearch_complocator(void) hdb = create_package_db(); ok(hdb, "Expected a valid database handle\n"); - r = create_appsearch_table(hdb); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP1', 'NewSignature1'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP2', 'NewSignature2'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP3', 'NewSignature3'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP4', 'NewSignature4'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP5', 'NewSignature5'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP6', 'NewSignature6'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP7', 'NewSignature7'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP8', 'NewSignature8'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP9', 'NewSignature9'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP10', 'NewSignature10'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP11', 'NewSignature11'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP12', 'NewSignature12'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = create_complocator_table(hdb); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + create_appsearch_table(hdb); + add_appsearch_entry(hdb, "'SIGPROP1', 'NewSignature1'"); + add_appsearch_entry(hdb, "'SIGPROP2', 'NewSignature2'"); + add_appsearch_entry(hdb, "'SIGPROP3', 'NewSignature3'"); + add_appsearch_entry(hdb, "'SIGPROP4', 'NewSignature4'"); + add_appsearch_entry(hdb, "'SIGPROP5', 'NewSignature5'"); + add_appsearch_entry(hdb, "'SIGPROP6', 'NewSignature6'"); + add_appsearch_entry(hdb, "'SIGPROP7', 'NewSignature7'"); + add_appsearch_entry(hdb, "'SIGPROP8', 'NewSignature8'"); + add_appsearch_entry(hdb, "'SIGPROP9', 'NewSignature9'"); + add_appsearch_entry(hdb, "'SIGPROP10', 'NewSignature10'"); + add_appsearch_entry(hdb, "'SIGPROP11', 'NewSignature11'"); + add_appsearch_entry(hdb, "'SIGPROP12', 'NewSignature12'"); + + create_complocator_table(hdb); /* published component, machine, file, signature, misdbLocatorTypeFile */ - r = add_complocator_entry(hdb, "'NewSignature1', '{A8AE6692-96BA-4198-8399-145D7D1D0D0E}', 1"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_complocator_entry(hdb, "'NewSignature1', '{A8AE6692-96BA-4198-8399-145D7D1D0D0E}', 1"); /* published component, user-unmanaged, file, signature, misdbLocatorTypeFile */ - r = add_complocator_entry(hdb, "'NewSignature2', '{1D2CE6F3-E81C-4949-AB81-78D7DAD2AF2E}', 1"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_complocator_entry(hdb, "'NewSignature2', '{1D2CE6F3-E81C-4949-AB81-78D7DAD2AF2E}', 1"); /* published component, user-managed, file, signature, misdbLocatorTypeFile */ - r = add_complocator_entry(hdb, "'NewSignature3', '{19E0B999-85F5-4973-A61B-DBE4D66ECB1D}', 1"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_complocator_entry(hdb, "'NewSignature3', '{19E0B999-85F5-4973-A61B-DBE4D66ECB1D}', 1"); /* published component, machine, file, signature, misdbLocatorTypeDirectory */ - r = add_complocator_entry(hdb, "'NewSignature4', '{A8AE6692-96BA-4198-8399-145D7D1D0D0E}', 0"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_complocator_entry(hdb, "'NewSignature4', '{A8AE6692-96BA-4198-8399-145D7D1D0D0E}', 0"); /* published component, machine, dir, signature, misdbLocatorTypeDirectory */ - r = add_complocator_entry(hdb, "'NewSignature5', '{F0CCA976-27A3-4808-9DDD-1A6FD50A0D5A}', 0"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_complocator_entry(hdb, "'NewSignature5', '{F0CCA976-27A3-4808-9DDD-1A6FD50A0D5A}', 0"); /* published component, machine, dir, no signature, misdbLocatorTypeDirectory */ - r = add_complocator_entry(hdb, "'NewSignature6', '{C0ECD96F-7898-4410-9667-194BD8C1B648}', 0"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_complocator_entry(hdb, "'NewSignature6', '{C0ECD96F-7898-4410-9667-194BD8C1B648}', 0"); /* published component, machine, file, no signature, misdbLocatorTypeFile */ - r = add_complocator_entry(hdb, "'NewSignature7', '{DB20F535-9C26-4127-9C2B-CC45A8B51DA1}', 1"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_complocator_entry(hdb, "'NewSignature7', '{DB20F535-9C26-4127-9C2B-CC45A8B51DA1}', 1"); /* unpublished component, no signature, misdbLocatorTypeDir */ - r = add_complocator_entry(hdb, "'NewSignature8', '{FB671D5B-5083-4048-90E0-481C48D8F3A5}', 0"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_complocator_entry(hdb, "'NewSignature8', '{FB671D5B-5083-4048-90E0-481C48D8F3A5}', 0"); /* published component, no signature, dir does not exist misdbLocatorTypeDir */ - r = add_complocator_entry(hdb, "'NewSignature9', '{91B7359B-07F2-4221-AA8D-DE102BB87A5F}', 0"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_complocator_entry(hdb, "'NewSignature9', '{91B7359B-07F2-4221-AA8D-DE102BB87A5F}', 0"); /* published component, signature w/ ver, misdbLocatorTypeFile */ - r = add_complocator_entry(hdb, "'NewSignature10', '{4A2E1B5B-4034-4177-833B-8CC35F1B3EF1}', 1"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_complocator_entry(hdb, "'NewSignature10', '{4A2E1B5B-4034-4177-833B-8CC35F1B3EF1}', 1"); /* published component, signature w/ ver, ver > max, misdbLocatorTypeFile */ - r = add_complocator_entry(hdb, "'NewSignature11', '{A204DF48-7346-4635-BA2E-66247DBAC9DF}', 1"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_complocator_entry(hdb, "'NewSignature11', '{A204DF48-7346-4635-BA2E-66247DBAC9DF}', 1"); /* published component, signature w/ ver, sig->name ignored, misdbLocatorTypeFile */ - r = add_complocator_entry(hdb, "'NewSignature12', '{EC30CE73-4CF9-4908-BABD-1ED82E1515FD}', 1"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = create_signature_table(hdb); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_signature_entry(hdb, "'NewSignature1', 'FileName1', '', '', '', '', '', '', ''"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_signature_entry(hdb, "'NewSignature2', 'FileName2', '', '', '', '', '', '', ''"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_signature_entry(hdb, "'NewSignature3', 'FileName3', '', '', '', '', '', '', ''"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_signature_entry(hdb, "'NewSignature4', 'FileName4', '', '', '', '', '', '', ''"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_signature_entry(hdb, "'NewSignature5', 'FileName5', '', '', '', '', '', '', ''"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_signature_entry(hdb, "'NewSignature10', 'FileName8.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_signature_entry(hdb, "'NewSignature11', 'FileName9.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_signature_entry(hdb, "'NewSignature12', 'ignored', '1.1.1.1', '2.1.1.1', '', '', '', '', ''"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_complocator_entry(hdb, "'NewSignature12', '{EC30CE73-4CF9-4908-BABD-1ED82E1515FD}', 1"); + + create_signature_table(hdb); + add_signature_entry(hdb, "'NewSignature1', 'FileName1', '', '', '', '', '', '', ''"); + add_signature_entry(hdb, "'NewSignature2', 'FileName2', '', '', '', '', '', '', ''"); + add_signature_entry(hdb, "'NewSignature3', 'FileName3', '', '', '', '', '', '', ''"); + add_signature_entry(hdb, "'NewSignature4', 'FileName4', '', '', '', '', '', '', ''"); + add_signature_entry(hdb, "'NewSignature5', 'FileName5', '', '', '', '', '', '', ''"); + add_signature_entry(hdb, "'NewSignature10', 'FileName8.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''"); + add_signature_entry(hdb, "'NewSignature11', 'FileName9.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''"); + add_signature_entry(hdb, "'NewSignature12', 'ignored', '1.1.1.1', '2.1.1.1', '', '', '', '', ''"); r = package_from_db(hdb, &hpkg); if (r == ERROR_INSTALL_PACKAGE_REJECTED) @@ -4219,7 +4301,6 @@ static void test_appsearch_reglocator(void) BOOL space, version, is_64bit = sizeof(void *) > sizeof(int); HKEY hklm, classes, hkcu, users; LPSTR pathdata, pathvar, ptr; - LPCSTR str; LONG res; UINT r, type = 0; SYSTEM_INFO si; @@ -4359,295 +4440,175 @@ static void test_appsearch_reglocator(void) hdb = create_package_db(); ok(hdb, "Expected a valid database handle\n"); - r = create_appsearch_table(hdb); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP1', 'NewSignature1'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP2', 'NewSignature2'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP3', 'NewSignature3'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP4', 'NewSignature4'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP5', 'NewSignature5'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP6', 'NewSignature6'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP7', 'NewSignature7'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP8', 'NewSignature8'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP9', 'NewSignature9'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP10', 'NewSignature10'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP11', 'NewSignature11'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP12', 'NewSignature12'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP13', 'NewSignature13'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP14', 'NewSignature14'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP15', 'NewSignature15'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP16', 'NewSignature16'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP17', 'NewSignature17'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP18', 'NewSignature18'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP19', 'NewSignature19'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP20', 'NewSignature20'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP21', 'NewSignature21'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP22', 'NewSignature22'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP23', 'NewSignature23'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP24', 'NewSignature24'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP25', 'NewSignature25'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP26', 'NewSignature26'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP27', 'NewSignature27'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP28', 'NewSignature28'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP29', 'NewSignature29'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP30', 'NewSignature30'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = create_reglocator_table(hdb); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + create_appsearch_table(hdb); + add_appsearch_entry(hdb, "'SIGPROP1', 'NewSignature1'"); + add_appsearch_entry(hdb, "'SIGPROP2', 'NewSignature2'"); + add_appsearch_entry(hdb, "'SIGPROP3', 'NewSignature3'"); + add_appsearch_entry(hdb, "'SIGPROP4', 'NewSignature4'"); + add_appsearch_entry(hdb, "'SIGPROP5', 'NewSignature5'"); + add_appsearch_entry(hdb, "'SIGPROP6', 'NewSignature6'"); + add_appsearch_entry(hdb, "'SIGPROP7', 'NewSignature7'"); + add_appsearch_entry(hdb, "'SIGPROP8', 'NewSignature8'"); + add_appsearch_entry(hdb, "'SIGPROP9', 'NewSignature9'"); + add_appsearch_entry(hdb, "'SIGPROP10', 'NewSignature10'"); + add_appsearch_entry(hdb, "'SIGPROP11', 'NewSignature11'"); + add_appsearch_entry(hdb, "'SIGPROP12', 'NewSignature12'"); + add_appsearch_entry(hdb, "'SIGPROP13', 'NewSignature13'"); + add_appsearch_entry(hdb, "'SIGPROP14', 'NewSignature14'"); + add_appsearch_entry(hdb, "'SIGPROP15', 'NewSignature15'"); + add_appsearch_entry(hdb, "'SIGPROP16', 'NewSignature16'"); + add_appsearch_entry(hdb, "'SIGPROP17', 'NewSignature17'"); + add_appsearch_entry(hdb, "'SIGPROP18', 'NewSignature18'"); + add_appsearch_entry(hdb, "'SIGPROP19', 'NewSignature19'"); + add_appsearch_entry(hdb, "'SIGPROP20', 'NewSignature20'"); + add_appsearch_entry(hdb, "'SIGPROP21', 'NewSignature21'"); + add_appsearch_entry(hdb, "'SIGPROP22', 'NewSignature22'"); + add_appsearch_entry(hdb, "'SIGPROP23', 'NewSignature23'"); + add_appsearch_entry(hdb, "'SIGPROP24', 'NewSignature24'"); + add_appsearch_entry(hdb, "'SIGPROP25', 'NewSignature25'"); + add_appsearch_entry(hdb, "'SIGPROP26', 'NewSignature26'"); + add_appsearch_entry(hdb, "'SIGPROP27', 'NewSignature27'"); + add_appsearch_entry(hdb, "'SIGPROP28', 'NewSignature28'"); + add_appsearch_entry(hdb, "'SIGPROP29', 'NewSignature29'"); + add_appsearch_entry(hdb, "'SIGPROP30', 'NewSignature30'"); + + create_reglocator_table(hdb); type = msidbLocatorTypeRawValue; if (is_64bit) type |= msidbLocatorType64bit; /* HKLM, msidbLocatorTypeRawValue, REG_SZ */ - r = add_reglocator_entry(hdb, "NewSignature1", 2, "Software\\Wine", "Value1", type); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_reglocator_entry(hdb, "NewSignature1", 2, "Software\\Wine", "Value1", type); /* HKLM, msidbLocatorTypeRawValue, positive DWORD */ - r = add_reglocator_entry(hdb, "NewSignature2", 2, "Software\\Wine", "Value2", type); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_reglocator_entry(hdb, "NewSignature2", 2, "Software\\Wine", "Value2", type); /* HKLM, msidbLocatorTypeRawValue, negative DWORD */ - r = add_reglocator_entry(hdb, "NewSignature3", 2, "Software\\Wine", "Value3", type); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_reglocator_entry(hdb, "NewSignature3", 2, "Software\\Wine", "Value3", type); /* HKLM, msidbLocatorTypeRawValue, REG_EXPAND_SZ */ - r = add_reglocator_entry(hdb, "NewSignature4", 2, "Software\\Wine", "Value4", type); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_reglocator_entry(hdb, "NewSignature4", 2, "Software\\Wine", "Value4", type); /* HKLM, msidbLocatorTypeRawValue, REG_EXPAND_SZ */ - r = add_reglocator_entry(hdb, "NewSignature5", 2, "Software\\Wine", "Value5", type); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_reglocator_entry(hdb, "NewSignature5", 2, "Software\\Wine", "Value5", type); /* HKLM, msidbLocatorTypeRawValue, REG_MULTI_SZ */ - r = add_reglocator_entry(hdb, "NewSignature6", 2, "Software\\Wine", "Value6", type); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_reglocator_entry(hdb, "NewSignature6", 2, "Software\\Wine", "Value6", type); /* HKLM, msidbLocatorTypeRawValue, REG_BINARY */ - r = add_reglocator_entry(hdb, "NewSignature7", 2, "Software\\Wine", "Value7", type); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_reglocator_entry(hdb, "NewSignature7", 2, "Software\\Wine", "Value7", type); /* HKLM, msidbLocatorTypeRawValue, REG_SZ first char is # */ - r = add_reglocator_entry(hdb, "NewSignature8", 2, "Software\\Wine", "Value8", type); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_reglocator_entry(hdb, "NewSignature8", 2, "Software\\Wine", "Value8", type); type = msidbLocatorTypeFileName; if (is_64bit) type |= msidbLocatorType64bit; /* HKLM, msidbLocatorTypeFileName, signature, file exists */ - r = add_reglocator_entry(hdb, "NewSignature9", 2, "Software\\Wine", "Value9", type); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_reglocator_entry(hdb, "NewSignature9", 2, "Software\\Wine", "Value9", type); /* HKLM, msidbLocatorTypeFileName, signature, file does not exist */ - r = add_reglocator_entry(hdb, "NewSignature10", 2, "Software\\Wine", "Value10", type); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_reglocator_entry(hdb, "NewSignature10", 2, "Software\\Wine", "Value10", type); /* HKLM, msidbLocatorTypeFileName, no signature */ - r = add_reglocator_entry(hdb, "NewSignature11", 2, "Software\\Wine", "Value9", type); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_reglocator_entry(hdb, "NewSignature11", 2, "Software\\Wine", "Value9", type); type = msidbLocatorTypeDirectory; if (is_64bit) type |= msidbLocatorType64bit; /* HKLM, msidbLocatorTypeDirectory, no signature, file exists */ - r = add_reglocator_entry(hdb, "NewSignature12", 2, "Software\\Wine", "Value9", type); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_reglocator_entry(hdb, "NewSignature12", 2, "Software\\Wine", "Value9", type); /* HKLM, msidbLocatorTypeDirectory, no signature, directory exists */ - r = add_reglocator_entry(hdb, "NewSignature13", 2, "Software\\Wine", "Value11", type); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_reglocator_entry(hdb, "NewSignature13", 2, "Software\\Wine", "Value11", type); /* HKLM, msidbLocatorTypeDirectory, signature, file exists */ - r = add_reglocator_entry(hdb, "NewSignature14", 2, "Software\\Wine", "Value9", type); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_reglocator_entry(hdb, "NewSignature14", 2, "Software\\Wine", "Value9", type); type = msidbLocatorTypeRawValue; if (is_64bit) type |= msidbLocatorType64bit; /* HKCR, msidbLocatorTypeRawValue, REG_SZ */ - r = add_reglocator_entry(hdb, "NewSignature15", 0, "Software\\Wine", "Value1", type); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_reglocator_entry(hdb, "NewSignature15", 0, "Software\\Wine", "Value1", type); /* HKCU, msidbLocatorTypeRawValue, REG_SZ */ - r = add_reglocator_entry(hdb, "NewSignature16", 1, "Software\\Wine", "Value1", type); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_reglocator_entry(hdb, "NewSignature16", 1, "Software\\Wine", "Value1", type); /* HKU, msidbLocatorTypeRawValue, REG_SZ */ - r = add_reglocator_entry(hdb, "NewSignature17", 3, "S-1-5-18\\Software\\Wine", "Value1", type); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_reglocator_entry(hdb, "NewSignature17", 3, "S-1-5-18\\Software\\Wine", "Value1", type); /* HKLM, msidbLocatorTypeRawValue, REG_SZ, NULL Name */ - r = add_reglocator_entry(hdb, "NewSignature18", 2, "Software\\Wine", "", type); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_reglocator_entry(hdb, "NewSignature18", 2, "Software\\Wine", "", type); /* HKLM, msidbLocatorTypeRawValue, REG_SZ, key does not exist */ - r = add_reglocator_entry(hdb, "NewSignature19", 2, "Software\\IDontExist", "", type); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_reglocator_entry(hdb, "NewSignature19", 2, "Software\\IDontExist", "", type); /* HKLM, msidbLocatorTypeRawValue, REG_SZ, value is empty */ - r = add_reglocator_entry(hdb, "NewSignature20", 2, "Software\\Wine", "Value12", type); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_reglocator_entry(hdb, "NewSignature20", 2, "Software\\Wine", "Value12", type); type = msidbLocatorTypeFileName; if (is_64bit) type |= msidbLocatorType64bit; /* HKLM, msidbLocatorTypeFileName, signature, file exists w/ version */ - r = add_reglocator_entry(hdb, "NewSignature21", 2, "Software\\Wine", "Value13", type); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_reglocator_entry(hdb, "NewSignature21", 2, "Software\\Wine", "Value13", type); /* HKLM, msidbLocatorTypeFileName, file exists w/ version, version > max */ - r = add_reglocator_entry(hdb, "NewSignature22", 2, "Software\\Wine", "Value14", type); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_reglocator_entry(hdb, "NewSignature22", 2, "Software\\Wine", "Value14", type); /* HKLM, msidbLocatorTypeFileName, file exists w/ version, sig->name ignored */ - r = add_reglocator_entry(hdb, "NewSignature23", 2, "Software\\Wine", "Value15", type); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_reglocator_entry(hdb, "NewSignature23", 2, "Software\\Wine", "Value15", type); /* HKLM, msidbLocatorTypeFileName, no signature, directory exists */ - r = add_reglocator_entry(hdb, "NewSignature24", 2, "Software\\Wine", "Value11", type); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_reglocator_entry(hdb, "NewSignature24", 2, "Software\\Wine", "Value11", type); /* HKLM, msidbLocatorTypeFileName, no signature, file does not exist */ - r = add_reglocator_entry(hdb, "NewSignature25", 2, "Software\\Wine", "Value10", type); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_reglocator_entry(hdb, "NewSignature25", 2, "Software\\Wine", "Value10", type); type = msidbLocatorTypeDirectory; if (is_64bit) type |= msidbLocatorType64bit; /* HKLM, msidbLocatorTypeDirectory, signature, directory exists */ - r = add_reglocator_entry(hdb, "NewSignature26", 2, "Software\\Wine", "Value11", type); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_reglocator_entry(hdb, "NewSignature26", 2, "Software\\Wine", "Value11", type); /* HKLM, msidbLocatorTypeDirectory, signature, file does not exist */ - r = add_reglocator_entry(hdb, "NewSignature27", 2, "Software\\Wine", "Value10", type); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_reglocator_entry(hdb, "NewSignature27", 2, "Software\\Wine", "Value10", type); /* HKLM, msidbLocatorTypeDirectory, no signature, file does not exist */ - r = add_reglocator_entry(hdb, "NewSignature28", 2, "Software\\Wine", "Value10", type); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_reglocator_entry(hdb, "NewSignature28", 2, "Software\\Wine", "Value10", type); type = msidbLocatorTypeFileName; if (is_64bit) type |= msidbLocatorType64bit; /* HKLM, msidbLocatorTypeFile, file exists, in quotes */ - r = add_reglocator_entry(hdb, "NewSignature29", 2, "Software\\Wine", "Value16", type); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_reglocator_entry(hdb, "NewSignature29", 2, "Software\\Wine", "Value16", type); /* HKLM, msidbLocatorTypeFile, file exists, no quotes */ - r = add_reglocator_entry(hdb, "NewSignature30", 2, "Software\\Wine", "Value17", type); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = create_signature_table(hdb); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - str = "'NewSignature9', 'FileName1', '', '', '', '', '', '', ''"; - r = add_signature_entry(hdb, str); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - str = "'NewSignature10', 'FileName2', '', '', '', '', '', '', ''"; - r = add_signature_entry(hdb, str); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - str = "'NewSignature14', 'FileName1', '', '', '', '', '', '', ''"; - r = add_signature_entry(hdb, str); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_reglocator_entry(hdb, "NewSignature30", 2, "Software\\Wine", "Value17", type); - str = "'NewSignature21', 'FileName3.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''"; - r = add_signature_entry(hdb, str); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - str = "'NewSignature22', 'FileName4.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''"; - r = add_signature_entry(hdb, str); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - str = "'NewSignature23', 'ignored', '1.1.1.1', '2.1.1.1', '', '', '', '', ''"; - r = add_signature_entry(hdb, str); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + create_signature_table(hdb); + add_signature_entry(hdb, "'NewSignature9', 'FileName1', '', '', '', '', '', '', ''"); + add_signature_entry(hdb, "'NewSignature10', 'FileName2', '', '', '', '', '', '', ''"); + add_signature_entry(hdb, "'NewSignature14', 'FileName1', '', '', '', '', '', '', ''"); + add_signature_entry(hdb, "'NewSignature21', 'FileName3.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''"); + add_signature_entry(hdb, "'NewSignature22', 'FileName4.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''"); + add_signature_entry(hdb, "'NewSignature23', 'ignored', '1.1.1.1', '2.1.1.1', '', '', '', '', ''"); if (!is_root(CURR_DIR)) { ptr = strrchr(expected, '\\') + 1; sprintf(path, "'NewSignature26', '%s', '', '', '', '', '', '', ''", ptr); - r = add_signature_entry(hdb, path); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_signature_entry(hdb, path); } - str = "'NewSignature27', 'FileName2', '', '', '', '', '', '', ''"; - r = add_signature_entry(hdb, str); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - str = "'NewSignature29', 'FileName1', '', '', '', '', '', '', ''"; - r = add_signature_entry(hdb, str); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - str = "'NewSignature30', 'FileName1', '', '', '', '', '', '', ''"; - r = add_signature_entry(hdb, str); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_signature_entry(hdb, "'NewSignature27', 'FileName2', '', '', '', '', '', '', ''"); + add_signature_entry(hdb, "'NewSignature29', 'FileName1', '', '', '', '', '', '', ''"); + add_signature_entry(hdb, "'NewSignature30', 'FileName1', '', '', '', '', '', '', ''"); r = package_from_db(hdb, &hpkg); ok(r == ERROR_SUCCESS, "Expected a valid package handle %u\n", r); @@ -4919,7 +4880,6 @@ static void test_appsearch_inilocator(void) MSIHANDLE hpkg, hdb; char path[MAX_PATH], expected[MAX_PATH], prop[MAX_PATH]; BOOL version; - LPCSTR str; LPSTR ptr; DWORD size; UINT r; @@ -4959,125 +4919,64 @@ static void test_appsearch_inilocator(void) hdb = create_package_db(); ok(hdb, "Expected a valid database handle\n"); - r = create_appsearch_table(hdb); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP1', 'NewSignature1'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP2', 'NewSignature2'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP3', 'NewSignature3'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP4', 'NewSignature4'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP5', 'NewSignature5'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP6', 'NewSignature6'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP7', 'NewSignature7'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP8', 'NewSignature8'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP9', 'NewSignature9'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP10', 'NewSignature10'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP11', 'NewSignature11'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP12', 'NewSignature12'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = create_inilocator_table(hdb); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + create_appsearch_table(hdb); + add_appsearch_entry(hdb, "'SIGPROP1', 'NewSignature1'"); + add_appsearch_entry(hdb, "'SIGPROP2', 'NewSignature2'"); + add_appsearch_entry(hdb, "'SIGPROP3', 'NewSignature3'"); + add_appsearch_entry(hdb, "'SIGPROP4', 'NewSignature4'"); + add_appsearch_entry(hdb, "'SIGPROP5', 'NewSignature5'"); + add_appsearch_entry(hdb, "'SIGPROP6', 'NewSignature6'"); + add_appsearch_entry(hdb, "'SIGPROP7', 'NewSignature7'"); + add_appsearch_entry(hdb, "'SIGPROP8', 'NewSignature8'"); + add_appsearch_entry(hdb, "'SIGPROP9', 'NewSignature9'"); + add_appsearch_entry(hdb, "'SIGPROP10', 'NewSignature10'"); + add_appsearch_entry(hdb, "'SIGPROP11', 'NewSignature11'"); + add_appsearch_entry(hdb, "'SIGPROP12', 'NewSignature12'"); + + create_inilocator_table(hdb); /* msidbLocatorTypeRawValue, field 1 */ - str = "'NewSignature1', 'IniFile.ini', 'Section', 'Key', 1, 2"; - r = add_inilocator_entry(hdb, str); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_inilocator_entry(hdb, "'NewSignature1', 'IniFile.ini', 'Section', 'Key', 1, 2"); /* msidbLocatorTypeRawValue, field 2 */ - str = "'NewSignature2', 'IniFile.ini', 'Section', 'Key', 2, 2"; - r = add_inilocator_entry(hdb, str); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_inilocator_entry(hdb, "'NewSignature2', 'IniFile.ini', 'Section', 'Key', 2, 2"); /* msidbLocatorTypeRawValue, entire field */ - str = "'NewSignature3', 'IniFile.ini', 'Section', 'Key', 0, 2"; - r = add_inilocator_entry(hdb, str); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_inilocator_entry(hdb, "'NewSignature3', 'IniFile.ini', 'Section', 'Key', 0, 2"); /* msidbLocatorTypeFile */ - str = "'NewSignature4', 'IniFile.ini', 'Section', 'Key2', 1, 1"; - r = add_inilocator_entry(hdb, str); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_inilocator_entry(hdb, "'NewSignature4', 'IniFile.ini', 'Section', 'Key2', 1, 1"); /* msidbLocatorTypeDirectory, file */ - str = "'NewSignature5', 'IniFile.ini', 'Section', 'Key2', 1, 0"; - r = add_inilocator_entry(hdb, str); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_inilocator_entry(hdb, "'NewSignature5', 'IniFile.ini', 'Section', 'Key2', 1, 0"); /* msidbLocatorTypeDirectory, directory */ - str = "'NewSignature6', 'IniFile.ini', 'Section', 'Key3', 1, 0"; - r = add_inilocator_entry(hdb, str); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_inilocator_entry(hdb, "'NewSignature6', 'IniFile.ini', 'Section', 'Key3', 1, 0"); /* msidbLocatorTypeFile, file, no signature */ - str = "'NewSignature7', 'IniFile.ini', 'Section', 'Key2', 1, 1"; - r = add_inilocator_entry(hdb, str); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_inilocator_entry(hdb, "'NewSignature7', 'IniFile.ini', 'Section', 'Key2', 1, 1"); /* msidbLocatorTypeFile, dir, no signature */ - str = "'NewSignature8', 'IniFile.ini', 'Section', 'Key3', 1, 1"; - r = add_inilocator_entry(hdb, str); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_inilocator_entry(hdb, "'NewSignature8', 'IniFile.ini', 'Section', 'Key3', 1, 1"); /* msidbLocatorTypeFile, file does not exist */ - str = "'NewSignature9', 'IniFile.ini', 'Section', 'Key4', 1, 1"; - r = add_inilocator_entry(hdb, str); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_inilocator_entry(hdb, "'NewSignature9', 'IniFile.ini', 'Section', 'Key4', 1, 1"); /* msidbLocatorTypeFile, signature with version */ - str = "'NewSignature10', 'IniFile.ini', 'Section', 'Key5', 1, 1"; - r = add_inilocator_entry(hdb, str); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_inilocator_entry(hdb, "'NewSignature10', 'IniFile.ini', 'Section', 'Key5', 1, 1"); /* msidbLocatorTypeFile, signature with version, ver > max */ - str = "'NewSignature11', 'IniFile.ini', 'Section', 'Key6', 1, 1"; - r = add_inilocator_entry(hdb, str); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_inilocator_entry(hdb, "'NewSignature11', 'IniFile.ini', 'Section', 'Key6', 1, 1"); /* msidbLocatorTypeFile, signature with version, sig->name ignored */ - str = "'NewSignature12', 'IniFile.ini', 'Section', 'Key7', 1, 1"; - r = add_inilocator_entry(hdb, str); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = create_signature_table(hdb); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_signature_entry(hdb, "'NewSignature4', 'FileName1', '', '', '', '', '', '', ''"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_signature_entry(hdb, "'NewSignature9', 'IDontExist', '', '', '', '', '', '', ''"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_signature_entry(hdb, "'NewSignature10', 'FileName2.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_inilocator_entry(hdb, "'NewSignature12', 'IniFile.ini', 'Section', 'Key7', 1, 1"); - r = add_signature_entry(hdb, "'NewSignature11', 'FileName3.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_signature_entry(hdb, "'NewSignature12', 'ignored', '1.1.1.1', '2.1.1.1', '', '', '', '', ''"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + create_signature_table(hdb); + add_signature_entry(hdb, "'NewSignature4', 'FileName1', '', '', '', '', '', '', ''"); + add_signature_entry(hdb, "'NewSignature9', 'IDontExist', '', '', '', '', '', '', ''"); + add_signature_entry(hdb, "'NewSignature10', 'FileName2.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''"); + add_signature_entry(hdb, "'NewSignature11', 'FileName3.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''"); + add_signature_entry(hdb, "'NewSignature12', 'ignored', '1.1.1.1', '2.1.1.1', '', '', '', '', ''"); r = package_from_db(hdb, &hpkg); if (r == ERROR_INSTALL_PACKAGE_REJECTED) @@ -5218,7 +5117,6 @@ static void test_appsearch_drlocator(void) MSIHANDLE hpkg, hdb; char path[MAX_PATH], expected[MAX_PATH], prop[MAX_PATH]; BOOL version; - LPCSTR str; DWORD size; UINT r; @@ -5241,152 +5139,87 @@ static void test_appsearch_drlocator(void) hdb = create_package_db(); ok(hdb, "Expected a valid database handle\n"); - r = create_appsearch_table(hdb); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP1', 'NewSignature1'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP2', 'NewSignature2'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP3', 'NewSignature3'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP4', 'NewSignature4'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP5', 'NewSignature5'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP6', 'NewSignature6'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP7', 'NewSignature7'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP8', 'NewSignature8'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP9', 'NewSignature9'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP10', 'NewSignature10'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP11', 'NewSignature11'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'SIGPROP13', 'NewSignature13'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = create_drlocator_table(hdb); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + create_appsearch_table(hdb); + add_appsearch_entry(hdb, "'SIGPROP1', 'NewSignature1'"); + add_appsearch_entry(hdb, "'SIGPROP2', 'NewSignature2'"); + add_appsearch_entry(hdb, "'SIGPROP3', 'NewSignature3'"); + add_appsearch_entry(hdb, "'SIGPROP4', 'NewSignature4'"); + add_appsearch_entry(hdb, "'SIGPROP5', 'NewSignature5'"); + add_appsearch_entry(hdb, "'SIGPROP6', 'NewSignature6'"); + add_appsearch_entry(hdb, "'SIGPROP7', 'NewSignature7'"); + add_appsearch_entry(hdb, "'SIGPROP8', 'NewSignature8'"); + add_appsearch_entry(hdb, "'SIGPROP9', 'NewSignature9'"); + add_appsearch_entry(hdb, "'SIGPROP10', 'NewSignature10'"); + add_appsearch_entry(hdb, "'SIGPROP11', 'NewSignature11'"); + add_appsearch_entry(hdb, "'SIGPROP13', 'NewSignature13'"); + + create_drlocator_table(hdb); strcpy(expected, CURR_DIR); if (is_root(CURR_DIR)) expected[2] = 0; /* no parent, full path, depth 0, signature */ sprintf(path, "'NewSignature1', '', '%s', 0", expected); - r = add_drlocator_entry(hdb, path); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_drlocator_entry(hdb, path); /* no parent, full path, depth 0, no signature */ sprintf(path, "'NewSignature2', '', '%s', 0", expected); - r = add_drlocator_entry(hdb, path); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_drlocator_entry(hdb, path); /* no parent, relative path, depth 0, no signature */ sprintf(path, "'NewSignature3', '', '%s', 0", expected + 3); - r = add_drlocator_entry(hdb, path); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_drlocator_entry(hdb, path); /* no parent, full path, depth 2, signature */ sprintf(path, "'NewSignature4', '', '%s', 2", expected); - r = add_drlocator_entry(hdb, path); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_drlocator_entry(hdb, path); /* no parent, full path, depth 3, signature */ sprintf(path, "'NewSignature5', '', '%s', 3", expected); - r = add_drlocator_entry(hdb, path); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_drlocator_entry(hdb, path); /* no parent, full path, depth 1, signature is dir */ sprintf(path, "'NewSignature6', '', '%s', 1", expected); - r = add_drlocator_entry(hdb, path); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_drlocator_entry(hdb, path); /* parent is in DrLocator, relative path, depth 0, signature */ sprintf(path, "'NewSignature7', 'NewSignature1', 'one\\two\\three', 1"); - r = add_drlocator_entry(hdb, path); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_drlocator_entry(hdb, path); /* no parent, full path, depth 0, signature w/ version */ sprintf(path, "'NewSignature8', '', '%s', 0", expected); - r = add_drlocator_entry(hdb, path); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_drlocator_entry(hdb, path); /* no parent, full path, depth 0, signature w/ version, ver > max */ sprintf(path, "'NewSignature9', '', '%s', 0", expected); - r = add_drlocator_entry(hdb, path); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_drlocator_entry(hdb, path); /* no parent, full path, depth 0, signature w/ version, sig->name not ignored */ sprintf(path, "'NewSignature10', '', '%s', 0", expected); - r = add_drlocator_entry(hdb, path); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_drlocator_entry(hdb, path); /* no parent, relative empty path, depth 0, no signature */ sprintf(path, "'NewSignature11', '', '', 0"); - r = add_drlocator_entry(hdb, path); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_drlocator_entry(hdb, path); - r = create_reglocator_table(hdb); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + create_reglocator_table(hdb); /* parent */ - r = add_reglocator_entry(hdb, "NewSignature12", 2, "htmlfile\\shell\\open\\nonexistent", "", 1); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_reglocator_entry(hdb, "NewSignature12", 2, "htmlfile\\shell\\open\\nonexistent", "", 1); /* parent is in RegLocator, no path, depth 0, no signature */ sprintf(path, "'NewSignature13', 'NewSignature12', '', 0"); - r = add_drlocator_entry(hdb, path); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = create_signature_table(hdb); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - str = "'NewSignature1', 'FileName1', '', '', '', '', '', '', ''"; - r = add_signature_entry(hdb, str); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - str = "'NewSignature4', 'FileName2', '', '', '', '', '', '', ''"; - r = add_signature_entry(hdb, str); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - str = "'NewSignature5', 'FileName2', '', '', '', '', '', '', ''"; - r = add_signature_entry(hdb, str); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - str = "'NewSignature6', 'another', '', '', '', '', '', '', ''"; - r = add_signature_entry(hdb, str); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - str = "'NewSignature7', 'FileName2', '', '', '', '', '', '', ''"; - r = add_signature_entry(hdb, str); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - str = "'NewSignature8', 'FileName3.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''"; - r = add_signature_entry(hdb, str); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - str = "'NewSignature9', 'FileName4.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''"; - r = add_signature_entry(hdb, str); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - str = "'NewSignature10', 'necessary', '1.1.1.1', '2.1.1.1', '', '', '', '', ''"; - r = add_signature_entry(hdb, str); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + add_drlocator_entry(hdb, path); + + create_signature_table(hdb); + add_signature_entry(hdb, "'NewSignature1', 'FileName1', '', '', '', '', '', '', ''"); + add_signature_entry(hdb, "'NewSignature4', 'FileName2', '', '', '', '', '', '', ''"); + add_signature_entry(hdb, "'NewSignature5', 'FileName2', '', '', '', '', '', '', ''"); + add_signature_entry(hdb, "'NewSignature6', 'another', '', '', '', '', '', '', ''"); + add_signature_entry(hdb, "'NewSignature7', 'FileName2', '', '', '', '', '', '', ''"); + add_signature_entry(hdb, "'NewSignature8', 'FileName3.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''"); + add_signature_entry(hdb, "'NewSignature9', 'FileName4.dll', '1.1.1.1', '2.1.1.1', '', '', '', '', ''"); + add_signature_entry(hdb, "'NewSignature10', 'necessary', '1.1.1.1', '2.1.1.1', '', '', '', '', ''"); r = package_from_db(hdb, &hpkg); if (r == ERROR_INSTALL_PACKAGE_REJECTED) @@ -5496,172 +5329,93 @@ static void test_featureparents(void) hdb = create_package_db(); ok ( hdb, "failed to create package database\n" ); - r = add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'"); - ok( r == ERROR_SUCCESS, "cannot add directory: %d\n", r ); - - r = create_feature_table( hdb ); - ok( r == ERROR_SUCCESS, "cannot create Feature table: %d\n", r ); - - r = create_component_table( hdb ); - ok( r == ERROR_SUCCESS, "cannot create Component table: %d\n", r ); + add_directory_entry(hdb, "'TARGETDIR', '', 'SourceDir'"); - r = create_feature_components_table( hdb ); - ok( r == ERROR_SUCCESS, "cannot create FeatureComponents table: %d\n", r ); - - r = create_file_table( hdb ); - ok( r == ERROR_SUCCESS, "cannot create File table: %d\n", r ); + create_feature_table( hdb ); + create_component_table( hdb ); + create_feature_components_table( hdb ); + create_file_table( hdb ); /* msidbFeatureAttributesFavorLocal */ - r = add_feature_entry( hdb, "'zodiac', '', '', '', 2, 1, '', 0" ); - ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r ); + add_feature_entry( hdb, "'zodiac', '', '', '', 2, 1, '', 0" ); /* msidbFeatureAttributesFavorSource */ - r = add_feature_entry( hdb, "'perseus', '', '', '', 2, 1, '', 1" ); - ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r ); + add_feature_entry( hdb, "'perseus', '', '', '', 2, 1, '', 1" ); /* msidbFeatureAttributesFavorLocal */ - r = add_feature_entry( hdb, "'orion', '', '', '', 2, 1, '', 0" ); - ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r ); + add_feature_entry( hdb, "'orion', '', '', '', 2, 1, '', 0" ); /* msidbFeatureAttributesUIDisallowAbsent */ - r = add_feature_entry( hdb, "'lyra', '', '', '', 2, 1, '', 16" ); - ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r ); + add_feature_entry( hdb, "'lyra', '', '', '', 2, 1, '', 16" ); /* disabled because of install level */ - r = add_feature_entry( hdb, "'waters', '', '', '', 15, 101, '', 9" ); - ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r ); + add_feature_entry( hdb, "'waters', '', '', '', 15, 101, '', 9" ); /* child feature of disabled feature */ - r = add_feature_entry( hdb, "'bayer', 'waters', '', '', 14, 1, '', 9" ); - ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r ); + add_feature_entry( hdb, "'bayer', 'waters', '', '', 14, 1, '', 9" ); /* component of disabled feature (install level) */ - r = add_component_entry( hdb, "'delphinus', '', 'TARGETDIR', 0, '', 'delphinus_file'" ); - ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); + add_component_entry( hdb, "'delphinus', '', 'TARGETDIR', 0, '', 'delphinus_file'" ); /* component of disabled child feature (install level) */ - r = add_component_entry( hdb, "'hydrus', '', 'TARGETDIR', 0, '', 'hydrus_file'" ); - ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); + add_component_entry( hdb, "'hydrus', '', 'TARGETDIR', 0, '', 'hydrus_file'" ); /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesLocalOnly */ - r = add_component_entry( hdb, "'leo', '', 'TARGETDIR', 0, '', 'leo_file'" ); - ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); + add_component_entry( hdb, "'leo', '', 'TARGETDIR', 0, '', 'leo_file'" ); /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesSourceOnly */ - r = add_component_entry( hdb, "'virgo', '', 'TARGETDIR', 1, '', 'virgo_file'" ); - ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); + add_component_entry( hdb, "'virgo', '', 'TARGETDIR', 1, '', 'virgo_file'" ); /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesOptional */ - r = add_component_entry( hdb, "'libra', '', 'TARGETDIR', 2, '', 'libra_file'" ); - ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); + add_component_entry( hdb, "'libra', '', 'TARGETDIR', 2, '', 'libra_file'" ); /* msidbFeatureAttributesFavorSource:msidbComponentAttributesLocalOnly */ - r = add_component_entry( hdb, "'cassiopeia', '', 'TARGETDIR', 0, '', 'cassiopeia_file'" ); - ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); + add_component_entry( hdb, "'cassiopeia', '', 'TARGETDIR', 0, '', 'cassiopeia_file'" ); /* msidbFeatureAttributesFavorSource:msidbComponentAttributesSourceOnly */ - r = add_component_entry( hdb, "'cepheus', '', 'TARGETDIR', 1, '', 'cepheus_file'" ); - ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); + add_component_entry( hdb, "'cepheus', '', 'TARGETDIR', 1, '', 'cepheus_file'" ); /* msidbFeatureAttributesFavorSource:msidbComponentAttributesOptional */ - r = add_component_entry( hdb, "'andromeda', '', 'TARGETDIR', 2, '', 'andromeda_file'" ); - ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); + add_component_entry( hdb, "'andromeda', '', 'TARGETDIR', 2, '', 'andromeda_file'" ); /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesLocalOnly */ - r = add_component_entry( hdb, "'canis', '', 'TARGETDIR', 0, '', 'canis_file'" ); - ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); + add_component_entry( hdb, "'canis', '', 'TARGETDIR', 0, '', 'canis_file'" ); /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesSourceOnly */ - r = add_component_entry( hdb, "'monoceros', '', 'TARGETDIR', 1, '', 'monoceros_file'" ); - ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r ); + add_component_entry( hdb, "'monoceros', '', 'TARGETDIR', 1, '', 'monoceros_file'" ); /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesOptional */ - r = add_component_entry( hdb, "'lepus', '', 'TARGETDIR', 2, '', 'lepus_file'" ); - ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", r); - - r = add_feature_components_entry( hdb, "'zodiac', 'leo'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); - - r = add_feature_components_entry( hdb, "'zodiac', 'virgo'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); - - r = add_feature_components_entry( hdb, "'zodiac', 'libra'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); - - r = add_feature_components_entry( hdb, "'perseus', 'cassiopeia'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); - - r = add_feature_components_entry( hdb, "'perseus', 'cepheus'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); - - r = add_feature_components_entry( hdb, "'perseus', 'andromeda'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); - - r = add_feature_components_entry( hdb, "'orion', 'leo'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); - - r = add_feature_components_entry( hdb, "'orion', 'virgo'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); - - r = add_feature_components_entry( hdb, "'orion', 'libra'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); - - r = add_feature_components_entry( hdb, "'orion', 'cassiopeia'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); - - r = add_feature_components_entry( hdb, "'orion', 'cepheus'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); - - r = add_feature_components_entry( hdb, "'orion', 'andromeda'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); - - r = add_feature_components_entry( hdb, "'orion', 'canis'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); - - r = add_feature_components_entry( hdb, "'orion', 'monoceros'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); - - r = add_feature_components_entry( hdb, "'orion', 'lepus'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); - - r = add_feature_components_entry( hdb, "'waters', 'delphinus'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); - - r = add_feature_components_entry( hdb, "'bayer', 'hydrus'" ); - ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r ); - - r = add_file_entry( hdb, "'leo_file', 'leo', 'leo.txt', 100, '', '1033', 8192, 1" ); - ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r); - - r = add_file_entry( hdb, "'virgo_file', 'virgo', 'virgo.txt', 0, '', '1033', 8192, 1" ); - ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r); - - r = add_file_entry( hdb, "'libra_file', 'libra', 'libra.txt', 0, '', '1033', 8192, 1" ); - ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r); - - r = add_file_entry( hdb, "'cassiopeia_file', 'cassiopeia', 'cassiopeia.txt', 0, '', '1033', 8192, 1" ); - ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r); - - r = add_file_entry( hdb, "'cepheus_file', 'cepheus', 'cepheus.txt', 0, '', '1033', 8192, 1" ); - ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r); - - r = add_file_entry( hdb, "'andromeda_file', 'andromeda', 'andromeda.txt', 0, '', '1033', 8192, 1" ); - ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r); - - r = add_file_entry( hdb, "'canis_file', 'canis', 'canis.txt', 0, '', '1033', 8192, 1" ); - ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r); - - r = add_file_entry( hdb, "'monoceros_file', 'monoceros', 'monoceros.txt', 0, '', '1033', 8192, 1" ); - ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r); - - r = add_file_entry( hdb, "'lepus_file', 'lepus', 'lepus.txt', 0, '', '1033', 8192, 1" ); - ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r); - - r = add_file_entry( hdb, "'delphinus_file', 'delphinus', 'delphinus.txt', 0, '', '1033', 8192, 1" ); - ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r); - - r = add_file_entry( hdb, "'hydrus_file', 'hydrus', 'hydrus.txt', 0, '', '1033', 8192, 1" ); - ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r); + add_component_entry( hdb, "'lepus', '', 'TARGETDIR', 2, '', 'lepus_file'" ); + + add_feature_components_entry( hdb, "'zodiac', 'leo'" ); + add_feature_components_entry( hdb, "'zodiac', 'virgo'" ); + add_feature_components_entry( hdb, "'zodiac', 'libra'" ); + add_feature_components_entry( hdb, "'perseus', 'cassiopeia'" ); + add_feature_components_entry( hdb, "'perseus', 'cepheus'" ); + add_feature_components_entry( hdb, "'perseus', 'andromeda'" ); + add_feature_components_entry( hdb, "'orion', 'leo'" ); + add_feature_components_entry( hdb, "'orion', 'virgo'" ); + add_feature_components_entry( hdb, "'orion', 'libra'" ); + add_feature_components_entry( hdb, "'orion', 'cassiopeia'" ); + add_feature_components_entry( hdb, "'orion', 'cepheus'" ); + add_feature_components_entry( hdb, "'orion', 'andromeda'" ); + add_feature_components_entry( hdb, "'orion', 'canis'" ); + add_feature_components_entry( hdb, "'orion', 'monoceros'" ); + add_feature_components_entry( hdb, "'orion', 'lepus'" ); + add_feature_components_entry( hdb, "'waters', 'delphinus'" ); + add_feature_components_entry( hdb, "'bayer', 'hydrus'" ); + + add_file_entry( hdb, "'leo_file', 'leo', 'leo.txt', 100, '', '1033', 8192, 1" ); + add_file_entry( hdb, "'virgo_file', 'virgo', 'virgo.txt', 0, '', '1033', 8192, 1" ); + add_file_entry( hdb, "'libra_file', 'libra', 'libra.txt', 0, '', '1033', 8192, 1" ); + add_file_entry( hdb, "'cassiopeia_file', 'cassiopeia', 'cassiopeia.txt', 0, '', '1033', 8192, 1" ); + add_file_entry( hdb, "'cepheus_file', 'cepheus', 'cepheus.txt', 0, '', '1033', 8192, 1" ); + add_file_entry( hdb, "'andromeda_file', 'andromeda', 'andromeda.txt', 0, '', '1033', 8192, 1" ); + add_file_entry( hdb, "'canis_file', 'canis', 'canis.txt', 0, '', '1033', 8192, 1" ); + add_file_entry( hdb, "'monoceros_file', 'monoceros', 'monoceros.txt', 0, '', '1033', 8192, 1" ); + add_file_entry( hdb, "'lepus_file', 'lepus', 'lepus.txt', 0, '', '1033', 8192, 1" ); + add_file_entry( hdb, "'delphinus_file', 'delphinus', 'delphinus.txt', 0, '', '1033', 8192, 1" ); + add_file_entry( hdb, "'hydrus_file', 'hydrus', 'hydrus.txt', 0, '', '1033', 8192, 1" ); r = package_from_db( hdb, &hpkg ); if (r == ERROR_INSTALL_PACKAGE_REJECTED) @@ -6128,15 +5882,12 @@ static void test_launchconditions(void) hdb = create_package_db(); ok( hdb, "failed to create package database\n" ); - r = create_launchcondition_table( hdb ); - ok( r == ERROR_SUCCESS, "cannot create LaunchCondition table: %d\n", r ); + create_launchcondition_table( hdb ); - r = add_launchcondition_entry( hdb, "'X = \"1\"', 'one'" ); - ok( r == ERROR_SUCCESS, "cannot add launch condition: %d\n", r ); + add_launchcondition_entry( hdb, "'X = \"1\"', 'one'" ); /* invalid condition */ - r = add_launchcondition_entry( hdb, "'X != \"1\"', 'one'" ); - ok( r == ERROR_SUCCESS, "cannot add launch condition: %d\n", r ); + add_launchcondition_entry( hdb, "'X != \"1\"', 'one'" ); r = package_from_db( hdb, &hpkg ); if (r == ERROR_INSTALL_PACKAGE_REJECTED) @@ -6179,29 +5930,17 @@ static void test_ccpsearch(void) hdb = create_package_db(); ok(hdb, "failed to create package database\n"); - r = create_ccpsearch_table(hdb); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_ccpsearch_entry(hdb, "'CCP_random'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_ccpsearch_entry(hdb, "'RMCCP_random'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = create_reglocator_table(hdb); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_reglocator_entry(hdb, "CCP_random", 0, "htmlfile\\shell\\open\\nonexistent", "", 1); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + create_ccpsearch_table(hdb); + add_ccpsearch_entry(hdb, "'CCP_random'"); + add_ccpsearch_entry(hdb, "'RMCCP_random'"); - r = create_drlocator_table(hdb); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + create_reglocator_table(hdb); + add_reglocator_entry(hdb, "CCP_random", 0, "htmlfile\\shell\\open\\nonexistent", "", 1); - r = add_drlocator_entry(hdb, "'RMCCP_random', '', 'C:\\', '0'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + create_drlocator_table(hdb); + add_drlocator_entry(hdb, "'RMCCP_random', '', 'C:\\', '0'"); - r = create_signature_table(hdb); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + create_signature_table(hdb); r = package_from_db(hdb, &hpkg); if (r == ERROR_INSTALL_PACKAGE_REJECTED) @@ -6238,134 +5977,51 @@ static void test_complocator(void) hdb = create_package_db(); ok(hdb, "failed to create package database\n"); - r = create_appsearch_table(hdb); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'ABELISAURUS', 'abelisaurus'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'BACTROSAURUS', 'bactrosaurus'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'CAMELOTIA', 'camelotia'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'DICLONIUS', 'diclonius'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'ECHINODON', 'echinodon'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'FALCARIUS', 'falcarius'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'GALLIMIMUS', 'gallimimus'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'HAGRYPHUS', 'hagryphus'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'IGUANODON', 'iguanodon'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'JOBARIA', 'jobaria'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'KAKURU', 'kakuru'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'LABOCANIA', 'labocania'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'MEGARAPTOR', 'megaraptor'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'NEOSODON', 'neosodon'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'OLOROTITAN', 'olorotitan'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_appsearch_entry(hdb, "'PANTYDRACO', 'pantydraco'"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = create_complocator_table(hdb); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_complocator_entry(hdb, "'abelisaurus', '{E3619EED-305A-418C-B9C7-F7D7377F0934}', 1"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_complocator_entry(hdb, "'bactrosaurus', '{D56B688D-542F-42Ef-90FD-B6DA76EE8119}', 0"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_complocator_entry(hdb, "'camelotia', '{8211BE36-2466-47E3-AFB7-6AC72E51AED2}', 1"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_complocator_entry(hdb, "'diclonius', '{5C767B20-A33C-45A4-B80B-555E512F01AE}', 0"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_complocator_entry(hdb, "'echinodon', '{A19E16C5-C75D-4699-8111-C4338C40C3CB}', 1"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_complocator_entry(hdb, "'falcarius', '{17762FA1-A7AE-4CC6-8827-62873C35361D}', 0"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_complocator_entry(hdb, "'gallimimus', '{75EBF568-C959-41E0-A99E-9050638CF5FB}', 1"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_complocator_entry(hdb, "'hagrphus', '{D4969B72-17D9-4AB6-BE49-78F2FEE857AC}', 0"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_complocator_entry(hdb, "'iguanodon', '{8E0DA02E-F6A7-4A8F-B25D-6F564C492308}', 1"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_complocator_entry(hdb, "'jobaria', '{243C22B1-8C51-4151-B9D1-1AE5265E079E}', 0"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_complocator_entry(hdb, "'kakuru', '{5D0F03BA-50BC-44F2-ABB1-72C972F4E514}', 1"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_complocator_entry(hdb, "'labocania', '{C7DDB60C-7828-4046-A6F8-699D5E92F1ED}', 0"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_complocator_entry(hdb, "'megaraptor', '{8B1034B7-BD5E-41ac-B52C-0105D3DFD74D}', 1"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_complocator_entry(hdb, "'neosodon', '{0B499649-197A-48EF-93D2-AF1C17ED6E90}', 0"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_complocator_entry(hdb, "'olorotitan', '{54E9E91F-AED2-46D5-A25A-7E50AFA24513}', 1"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_complocator_entry(hdb, "'pantydraco', '{2A989951-5565-4FA7-93A7-E800A3E67D71}', 0"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = create_signature_table(hdb); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_signature_entry(hdb, "'abelisaurus', 'abelisaurus', '', '', '', '', '', '', ''"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_signature_entry(hdb, "'bactrosaurus', 'bactrosaurus', '', '', '', '', '', '', ''"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_signature_entry(hdb, "'camelotia', 'camelotia', '', '', '', '', '', '', ''"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_signature_entry(hdb, "'diclonius', 'diclonius', '', '', '', '', '', '', ''"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_signature_entry(hdb, "'iguanodon', 'iguanodon', '', '', '', '', '', '', ''"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_signature_entry(hdb, "'jobaria', 'jobaria', '', '', '', '', '', '', ''"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_signature_entry(hdb, "'kakuru', 'kakuru', '', '', '', '', '', '', ''"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - r = add_signature_entry(hdb, "'labocania', 'labocania', '', '', '', '', '', '', ''"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + create_appsearch_table(hdb); + add_appsearch_entry(hdb, "'ABELISAURUS', 'abelisaurus'"); + add_appsearch_entry(hdb, "'BACTROSAURUS', 'bactrosaurus'"); + add_appsearch_entry(hdb, "'CAMELOTIA', 'camelotia'"); + add_appsearch_entry(hdb, "'DICLONIUS', 'diclonius'"); + add_appsearch_entry(hdb, "'ECHINODON', 'echinodon'"); + add_appsearch_entry(hdb, "'FALCARIUS', 'falcarius'"); + add_appsearch_entry(hdb, "'GALLIMIMUS', 'gallimimus'"); + add_appsearch_entry(hdb, "'HAGRYPHUS', 'hagryphus'"); + add_appsearch_entry(hdb, "'IGUANODON', 'iguanodon'"); + add_appsearch_entry(hdb, "'JOBARIA', 'jobaria'"); + add_appsearch_entry(hdb, "'KAKURU', 'kakuru'"); + add_appsearch_entry(hdb, "'LABOCANIA', 'labocania'"); + add_appsearch_entry(hdb, "'MEGARAPTOR', 'megaraptor'"); + add_appsearch_entry(hdb, "'NEOSODON', 'neosodon'"); + add_appsearch_entry(hdb, "'OLOROTITAN', 'olorotitan'"); + add_appsearch_entry(hdb, "'PANTYDRACO', 'pantydraco'"); + + create_complocator_table(hdb); + add_complocator_entry(hdb, "'abelisaurus', '{E3619EED-305A-418C-B9C7-F7D7377F0934}', 1"); + add_complocator_entry(hdb, "'bactrosaurus', '{D56B688D-542F-42Ef-90FD-B6DA76EE8119}', 0"); + add_complocator_entry(hdb, "'camelotia', '{8211BE36-2466-47E3-AFB7-6AC72E51AED2}', 1"); + add_complocator_entry(hdb, "'diclonius', '{5C767B20-A33C-45A4-B80B-555E512F01AE}', 0"); + add_complocator_entry(hdb, "'echinodon', '{A19E16C5-C75D-4699-8111-C4338C40C3CB}', 1"); + add_complocator_entry(hdb, "'falcarius', '{17762FA1-A7AE-4CC6-8827-62873C35361D}', 0"); + add_complocator_entry(hdb, "'gallimimus', '{75EBF568-C959-41E0-A99E-9050638CF5FB}', 1"); + add_complocator_entry(hdb, "'hagrphus', '{D4969B72-17D9-4AB6-BE49-78F2FEE857AC}', 0"); + add_complocator_entry(hdb, "'iguanodon', '{8E0DA02E-F6A7-4A8F-B25D-6F564C492308}', 1"); + add_complocator_entry(hdb, "'jobaria', '{243C22B1-8C51-4151-B9D1-1AE5265E079E}', 0"); + add_complocator_entry(hdb, "'kakuru', '{5D0F03BA-50BC-44F2-ABB1-72C972F4E514}', 1"); + add_complocator_entry(hdb, "'labocania', '{C7DDB60C-7828-4046-A6F8-699D5E92F1ED}', 0"); + add_complocator_entry(hdb, "'megaraptor', '{8B1034B7-BD5E-41ac-B52C-0105D3DFD74D}', 1"); + add_complocator_entry(hdb, "'neosodon', '{0B499649-197A-48EF-93D2-AF1C17ED6E90}', 0"); + add_complocator_entry(hdb, "'olorotitan', '{54E9E91F-AED2-46D5-A25A-7E50AFA24513}', 1"); + add_complocator_entry(hdb, "'pantydraco', '{2A989951-5565-4FA7-93A7-E800A3E67D71}', 0"); + + create_signature_table(hdb); + add_signature_entry(hdb, "'abelisaurus', 'abelisaurus', '', '', '', '', '', '', ''"); + add_signature_entry(hdb, "'bactrosaurus', 'bactrosaurus', '', '', '', '', '', '', ''"); + add_signature_entry(hdb, "'camelotia', 'camelotia', '', '', '', '', '', '', ''"); + add_signature_entry(hdb, "'diclonius', 'diclonius', '', '', '', '', '', '', ''"); + add_signature_entry(hdb, "'iguanodon', 'iguanodon', '', '', '', '', '', '', ''"); + add_signature_entry(hdb, "'jobaria', 'jobaria', '', '', '', '', '', '', ''"); + add_signature_entry(hdb, "'kakuru', 'kakuru', '', '', '', '', '', '', ''"); + add_signature_entry(hdb, "'labocania', 'labocania', '', '', '', '', '', '', ''"); r = package_from_db(hdb, &hpkg); if (r == ERROR_INSTALL_PACKAGE_REJECTED) @@ -6596,14 +6252,9 @@ static void test_MsiGetSourcePath(void) set_suminfo_prop(hdb, PID_WORDCOUNT, 0); - r = add_directory_entry(hdb, "'TARGETDIR', '', 'SourceDir'"); - ok(r == S_OK, "failed\n"); - - r = add_directory_entry(hdb, "'SubDir', 'TARGETDIR', 'subtarget:subsource'"); - ok(r == S_OK, "failed\n"); - - r = add_directory_entry(hdb, "'SubDir2', 'SubDir', 'sub2'"); - ok(r == S_OK, "failed\n"); + add_directory_entry(hdb, "'TARGETDIR', '', 'SourceDir'"); + add_directory_entry(hdb, "'SubDir', 'TARGETDIR', 'subtarget:subsource'"); + add_directory_entry(hdb, "'SubDir2', 'SubDir', 'sub2'"); r = MsiDatabaseCommit(hdb); ok(r == ERROR_SUCCESS , "Failed to commit database\n"); @@ -7377,37 +7028,29 @@ static void test_shortlongsource(void) set_suminfo_prop(hdb, PID_WORDCOUNT, 0); - r = add_directory_entry(hdb, "'TARGETDIR', '', 'SourceDir'"); - ok(r == S_OK, "failed\n"); - - r = add_directory_entry(hdb, "'SubDir', 'TARGETDIR', 'short|long'"); - ok(r == S_OK, "failed\n"); + add_directory_entry(hdb, "'TARGETDIR', '', 'SourceDir'"); + add_directory_entry(hdb, "'SubDir', 'TARGETDIR', 'short|long'"); /* CostInitialize:short */ - r = add_directory_entry(hdb, "'SubDir2', 'TARGETDIR', 'one|two'"); - ok(r == S_OK, "failed\n"); + add_directory_entry(hdb, "'SubDir2', 'TARGETDIR', 'one|two'"); /* CostInitialize:long */ - r = add_directory_entry(hdb, "'SubDir3', 'TARGETDIR', 'three|four'"); - ok(r == S_OK, "failed\n"); + add_directory_entry(hdb, "'SubDir3', 'TARGETDIR', 'three|four'"); /* FileCost:short */ - r = add_directory_entry(hdb, "'SubDir4', 'TARGETDIR', 'five|six'"); - ok(r == S_OK, "failed\n"); + add_directory_entry(hdb, "'SubDir4', 'TARGETDIR', 'five|six'"); /* FileCost:long */ - r = add_directory_entry(hdb, "'SubDir5', 'TARGETDIR', 'seven|eight'"); - ok(r == S_OK, "failed\n"); + add_directory_entry(hdb, "'SubDir5', 'TARGETDIR', 'seven|eight'"); /* CostFinalize:short */ - r = add_directory_entry(hdb, "'SubDir6', 'TARGETDIR', 'nine|ten'"); - ok(r == S_OK, "failed\n"); + add_directory_entry(hdb, "'SubDir6', 'TARGETDIR', 'nine|ten'"); /* CostFinalize:long */ - r = add_directory_entry(hdb, "'SubDir7', 'TARGETDIR', 'eleven|twelve'"); - ok(r == S_OK, "failed\n"); + add_directory_entry(hdb, "'SubDir7', 'TARGETDIR', 'eleven|twelve'"); - MsiDatabaseCommit(hdb); + r = MsiDatabaseCommit(hdb); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r ); r = package_from_db(hdb, &hpkg); if (r == ERROR_INSTALL_PACKAGE_REJECTED) @@ -7716,8 +7359,7 @@ static void test_sourcedir(void) hdb = create_package_db(); ok( hdb, "failed to create database\n"); - r = add_directory_entry(hdb, "'TARGETDIR', '', 'SourceDir'"); - ok(r == S_OK, "failed\n"); + add_directory_entry(hdb, "'TARGETDIR', '', 'SourceDir'"); sprintf(package, "#%u", hdb); r = MsiOpenPackageA(package, &hpkg); @@ -8416,18 +8058,10 @@ static void test_MsiGetProductProperty(void) "PRIMARY KEY `Directory`)"); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - r = run_query(hdb, - "CREATE TABLE `Property` ( " - "`Property` CHAR(72) NOT NULL, " - "`Value` CHAR(255) " - "PRIMARY KEY `Property`)"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + create_property_table(hdb); - sprintf(query, "INSERT INTO `Property` " - "(`Property`, `Value`) " - "VALUES( 'ProductCode', '%s' )", prodcode); - r = run_query(hdb, query); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + sprintf(query, "'ProductCode', '%s'", prodcode); + r = add_property_entry(hdb, query); r = MsiDatabaseCommit(hdb); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); @@ -8884,73 +8518,37 @@ static void test_MsiEnumComponentCosts(void) hdb = create_package_db(); ok( hdb, "failed to create database\n" ); - r = create_property_table( hdb ); - ok( r == ERROR_SUCCESS, "cannot create Property table %u\n", r ); - - r = add_property_entry( hdb, "'ProductCode', '{379B1C47-40C1-42FA-A9BB-BEBB6F1B0172}'" ); - ok( r == ERROR_SUCCESS, "cannot add property entry %u\n", r ); - - r = add_property_entry( hdb, "'MSIFASTINSTALL', '1'" ); - ok( r == ERROR_SUCCESS, "cannot add property entry %u\n", r ); - - r = add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'" ); - ok( r == ERROR_SUCCESS, "failed to add directory entry %u\n" , r ); - - r = create_media_table( hdb ); - ok( r == ERROR_SUCCESS, "cannot create Media table %u\n", r ); - - r = add_media_entry( hdb, "'1', '2', 'cabinet', '', '', ''"); - ok( r == ERROR_SUCCESS, "cannot add media entry %u\n", r ); - - r = create_file_table( hdb ); - ok( r == ERROR_SUCCESS, "cannot create File table %u\n", r ); - - r = add_file_entry( hdb, "'one.txt', 'one', 'one.txt', 4096, '', '', 8192, 1" ); - ok( r == ERROR_SUCCESS, "cannot add file %u\n", r ); - - r = create_component_table( hdb ); - ok( r == ERROR_SUCCESS, "cannot create Component table %u\n", r ); - - r = add_component_entry( hdb, "'one', '{B2F86B9D-8447-4BC5-8883-750C45AA31CA}', 'TARGETDIR', 0, '', 'one.txt'" ); - ok( r == ERROR_SUCCESS, "cannot add component %u\n", r ); - - r = add_component_entry( hdb, "'two', '{62A09F6E-0B74-4829-BDB7-CAB66F42CCE8}', 'TARGETDIR', 0, '', ''" ); - ok( r == ERROR_SUCCESS, "cannot add component %u\n", r ); - - r = create_feature_table( hdb ); - ok( r == ERROR_SUCCESS, "cannot create Feature table %u\n", r ); - - r = add_feature_entry( hdb, "'one', '', '', '', 0, 1, '', 0" ); - ok( r == ERROR_SUCCESS, "cannot add feature %u\n", r ); - - r = add_feature_entry( hdb, "'two', '', '', '', 0, 1, '', 0" ); - ok( r == ERROR_SUCCESS, "cannot add feature %u\n", r ); - - r = create_feature_components_table( hdb ); - ok( r == ERROR_SUCCESS, "cannot create FeatureComponents table %u\n", r ); - - r = add_feature_components_entry( hdb, "'one', 'one'" ); - ok( r == ERROR_SUCCESS, "cannot add feature/component pair %u\n", r ); + create_property_table( hdb ); + add_property_entry( hdb, "'ProductCode', '{379B1C47-40C1-42FA-A9BB-BEBB6F1B0172}'" ); + add_property_entry( hdb, "'MSIFASTINSTALL', '1'" ); + add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'" ); - r = add_feature_components_entry( hdb, "'two', 'two'" ); - ok( r == ERROR_SUCCESS, "cannot add feature/component pair %u\n", r ); + create_media_table( hdb ); + add_media_entry( hdb, "'1', '2', 'cabinet', '', '', ''"); - r = create_install_execute_sequence_table( hdb ); - ok( r == ERROR_SUCCESS, "cannot create InstallExecuteSequence table %u\n", r ); + create_file_table( hdb ); + add_file_entry( hdb, "'one.txt', 'one', 'one.txt', 4096, '', '', 8192, 1" ); - r = add_install_execute_sequence_entry( hdb, "'CostInitialize', '', '800'" ); - ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry %u\n", r ); + create_component_table( hdb ); + add_component_entry( hdb, "'one', '{B2F86B9D-8447-4BC5-8883-750C45AA31CA}', 'TARGETDIR', 0, '', 'one.txt'" ); + add_component_entry( hdb, "'two', '{62A09F6E-0B74-4829-BDB7-CAB66F42CCE8}', 'TARGETDIR', 0, '', ''" ); - r = add_install_execute_sequence_entry( hdb, "'FileCost', '', '900'" ); - ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry %u\n", r ); + create_feature_table( hdb ); + add_feature_entry( hdb, "'one', '', '', '', 0, 1, '', 0" ); + add_feature_entry( hdb, "'two', '', '', '', 0, 1, '', 0" ); - r = add_install_execute_sequence_entry( hdb, "'CostFinalize', '', '1000'" ); - ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry %u\n", r ); + create_feature_components_table( hdb ); + add_feature_components_entry( hdb, "'one', 'one'" ); + add_feature_components_entry( hdb, "'two', 'two'" ); - r = add_install_execute_sequence_entry( hdb, "'InstallValidate', '', '1100'" ); - ok( r == ERROR_SUCCESS, "cannot add install execute sequence entry %u\n", r ); + create_install_execute_sequence_table( hdb ); + add_install_execute_sequence_entry( hdb, "'CostInitialize', '', '800'" ); + add_install_execute_sequence_entry( hdb, "'FileCost', '', '900'" ); + add_install_execute_sequence_entry( hdb, "'CostFinalize', '', '1000'" ); + add_install_execute_sequence_entry( hdb, "'InstallValidate', '', '1100'" ); - MsiDatabaseCommit( hdb ); + r = MsiDatabaseCommit( hdb ); + ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r ); sprintf( package, "#%u", hdb ); r = MsiOpenPackageA( package, &hpkg ); @@ -9108,8 +8706,7 @@ static void test_MsiDatabaseCommit(void) hdb = create_package_db(); ok( hdb, "failed to create database\n" ); - r = create_property_table( hdb ); - ok( r == ERROR_SUCCESS, "can't create Property table %u\n", r ); + create_property_table( hdb ); sprintf( package, "#%u", hdb ); r = MsiOpenPackageA( package, &hpkg ); @@ -9293,7 +8890,7 @@ static void ok_sequence_(const struct externalui_message *expected, const char * { if (expected->message == actual->message) { - if (expected->field_count != actual->field_count) + if (expected->field_count < actual->field_count) { todo_wine_if (todo) ok_(file, line) (FALSE, "%s: in msg 0x%08x expecting field count %d got %d\n", @@ -9315,6 +8912,10 @@ static void ok_sequence_(const struct externalui_message *expected, const char * expected++; actual++; } + else if (expected->optional) + { + expected++; + } else { todo_wine_if (todo) @@ -9349,6 +8950,26 @@ done: #define ok_sequence(exp, contx, todo) \ ok_sequence_((exp), (contx), (todo), __FILE__, __LINE__) +/* don't use PROGRESS, which is timing-dependent, + * or SHOWDIALOG, which due to a bug causes a hang on XP */ +static const INSTALLLOGMODE MSITEST_INSTALLLOGMODE = + INSTALLLOGMODE_FATALEXIT | + INSTALLLOGMODE_ERROR | + INSTALLLOGMODE_WARNING | + INSTALLLOGMODE_USER | + INSTALLLOGMODE_INFO | + INSTALLLOGMODE_FILESINUSE | + INSTALLLOGMODE_RESOLVESOURCE | + INSTALLLOGMODE_OUTOFDISKSPACE | + INSTALLLOGMODE_ACTIONSTART | + INSTALLLOGMODE_ACTIONDATA | + INSTALLLOGMODE_COMMONDATA | + INSTALLLOGMODE_INITIALIZE | + INSTALLLOGMODE_TERMINATE | + INSTALLLOGMODE_RMFILESINUSE | + INSTALLLOGMODE_INSTALLSTART | + INSTALLLOGMODE_INSTALLEND; + static const struct externalui_message empty_sequence[] = { {0} }; @@ -9490,8 +9111,9 @@ static INT CALLBACK externalui_message_callback(void *context, UINT message, MSI { INT retval = context ? *((INT *)context) : 0; struct externalui_message msg; - char buffer[100]; - DWORD length = 100; + char buffer[256]; + DWORD length; + UINT r; int i; msg.message = message; @@ -9505,11 +9127,16 @@ static INT CALLBACK externalui_message_callback(void *context, UINT message, MSI msg.field_count = MsiRecordGetFieldCount(hrecord); for (i = 0; i <= msg.field_count; i++) { - length = 100; - MsiRecordGetStringA(hrecord, i, buffer, &length); + length = sizeof(buffer); + r = MsiRecordGetStringA(hrecord, i, buffer, &length); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); memcpy(msg.field[i], buffer, min(100, length+1)); } + /* top-level actions dump a list of all set properties; skip them since they're inconsistent */ + if (message == (INSTALLMESSAGE_INFO|MB_ICONHAND) && msg.field_count > 0 && !strncmp(msg.field[0], "Property", 8)) + return retval; + add_message(&msg); return retval; @@ -9526,9 +9153,8 @@ static void test_externalui_message(void) MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL); - /* processing SHOWDIALOG with a record handler causes a crash on XP */ MsiSetExternalUIA(externalui_message_string_callback, INSTALLLOGMODE_SHOWDIALOG, &retval); - r = MsiSetExternalUIRecord(externalui_message_callback, 0xffffffff ^ INSTALLLOGMODE_PROGRESS ^ INSTALLLOGMODE_SHOWDIALOG, &retval, &prev); + r = MsiSetExternalUIRecord(externalui_message_callback, MSITEST_INSTALLLOGMODE, &retval, &prev); flush_sequence(); @@ -9546,12 +9172,9 @@ static void test_externalui_message(void) r = run_query(hdb, "INSERT INTO `Error` (`Error`, `Message`) VALUES (5, 'internal error')"); ok(r == ERROR_SUCCESS, "Failed to insert into Error table: %u\n", r); - r = create_actiontext_table(hdb); - ok(r == ERROR_SUCCESS, "Failed to create ActionText table: %u\n", r); - r = add_actiontext_entry(hdb, "'custom', 'description', 'template'"); - ok(r == ERROR_SUCCESS, "Failed to insert into ActionText table: %u\n", r); - r = add_actiontext_entry(hdb, "'CostInitialize', 'cost description', 'cost template'"); - ok(r == ERROR_SUCCESS, "Failed to insert into ActionText table: %u\n", r); + create_actiontext_table(hdb); + add_actiontext_entry(hdb, "'custom', 'description', 'template'"); + add_actiontext_entry(hdb, "'CostInitialize', 'cost description', 'cost template'"); r = MsiOpenPackageA(NULL, &hpkg); ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r); @@ -9639,15 +9262,11 @@ static void test_externalui_message(void) r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt"); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - r = create_dialog_table(hdb); - ok(r == ERROR_SUCCESS, "failed to create dialog table %u\n", r); - r = add_dialog_entry(hdb, "'dialog', 50, 50, 100, 100, 0, 'dummy'"); - ok(r == ERROR_SUCCESS, "failed to insert into dialog table %u\n", r); + create_dialog_table(hdb); + add_dialog_entry(hdb, "'dialog', 50, 50, 100, 100, 0, 'dummy'"); - r = create_control_table(hdb); - ok(r == ERROR_SUCCESS, "failed to create control table %u\n", r); - r = add_control_entry(hdb, "'dialog', 'dummy', 'Text', 5, 5, 5, 5, 3, 'dummy'"); - ok(r == ERROR_SUCCESS, "failed to insert into control table %u\n", r); + create_control_table(hdb); + add_control_entry(hdb, "'dialog', 'dummy', 'Text', 5, 5, 5, 5, 3, 'dummy'"); r = package_from_db(hdb, &hpkg); ok(r == ERROR_SUCCESS, "failed to create package %u\n", r); @@ -9751,9 +9370,8 @@ static void test_controlevent(void) MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL); - /* processing SHOWDIALOG with a record handler causes a crash on XP */ MsiSetExternalUIA(externalui_message_string_callback, INSTALLLOGMODE_SHOWDIALOG, NULL); - r = MsiSetExternalUIRecord(externalui_message_callback, 0xffffffff ^ INSTALLLOGMODE_PROGRESS ^ INSTALLLOGMODE_SHOWDIALOG, NULL, &prev); + r = MsiSetExternalUIRecord(externalui_message_callback, MSITEST_INSTALLLOGMODE, NULL, &prev); flush_sequence(); @@ -9766,53 +9384,33 @@ static void test_controlevent(void) r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt"); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - r = create_dialog_table(hdb); - ok(r == ERROR_SUCCESS, "failed to create Dialog table: %u\n", r); - r = add_dialog_entry(hdb, "'spawn', 50, 50, 100, 100, 3, 'button'"); - ok(r == ERROR_SUCCESS, "failed to insert into Dialog table: %u\n", r); - r = add_dialog_entry(hdb, "'spawn2', 50, 50, 100, 100, 3, 'button'"); - ok(r == ERROR_SUCCESS, "failed to insert into Dialog table: %u\n", r); - r = add_dialog_entry(hdb, "'child1', 50, 50, 80, 40, 3, 'exit'"); - ok(r == ERROR_SUCCESS, "failed to insert into Dialog table: %u\n", r); - r = add_dialog_entry(hdb, "'child2', 50, 50, 80, 40, 3, 'exit'"); - ok(r == ERROR_SUCCESS, "failed to insert into Dialog table: %u\n", r); - - r = create_control_table(hdb); - ok(r == ERROR_SUCCESS, "failed to create Control table: %u\n", r); - r = add_control_entry(hdb, "'spawn', 'button', 'PushButton', 10, 10, 66, 17, 3, 'Click me'"); - ok(r == ERROR_SUCCESS, "failed to insert into Control table: %u\n", r); - r = add_control_entry(hdb, "'spawn2', 'button', 'PushButton', 10, 10, 66, 17, 3, 'Click me'"); - ok(r == ERROR_SUCCESS, "failed to insert into Control table: %u\n", r); - r = add_control_entry(hdb, "'child1', 'exit', 'PushButton', 10, 10, 66, 17, 3, 'Click me'"); - ok(r == ERROR_SUCCESS, "failed to insert into Control table: %u\n", r); - r = add_control_entry(hdb, "'child2', 'exit', 'PushButton', 10, 10, 66, 17, 3, 'Click me'"); - ok(r == ERROR_SUCCESS, "failed to insert into Control table: %u\n", r); - - r = create_controlevent_table(hdb); - ok(r == ERROR_SUCCESS, "failed to create ControlEvent table: %u\n", r); - r = add_controlevent_entry(hdb, "'child1', 'exit', 'EndDialog', 'Exit', 1, 1"); - ok(r == ERROR_SUCCESS, "failed to insert into ControlEvent table: %u\n", r); - r = add_controlevent_entry(hdb, "'child2', 'exit', 'EndDialog', 'Exit', 1, 1"); - ok(r == ERROR_SUCCESS, "failed to insert into ControlEvent table: %u\n", r); - - r = create_custom_action_table(hdb); - ok(r == ERROR_SUCCESS, "failed to create CustomAction table: %u\n", r); - r = add_custom_action_entry(hdb, "'custom', 51, 'dummy', 'dummy value'"); - ok(r == ERROR_SUCCESS, "failed to insert into CustomAction table: %u\n", r); + create_dialog_table(hdb); + add_dialog_entry(hdb, "'spawn', 50, 50, 100, 100, 3, 'button'"); + add_dialog_entry(hdb, "'spawn2', 50, 50, 100, 100, 3, 'button'"); + add_dialog_entry(hdb, "'child1', 50, 50, 80, 40, 3, 'exit'"); + add_dialog_entry(hdb, "'child2', 50, 50, 80, 40, 3, 'exit'"); + + create_control_table(hdb); + add_control_entry(hdb, "'spawn', 'button', 'PushButton', 10, 10, 66, 17, 3, 'Click me'"); + add_control_entry(hdb, "'spawn2', 'button', 'PushButton', 10, 10, 66, 17, 3, 'Click me'"); + add_control_entry(hdb, "'child1', 'exit', 'PushButton', 10, 10, 66, 17, 3, 'Click me'"); + add_control_entry(hdb, "'child2', 'exit', 'PushButton', 10, 10, 66, 17, 3, 'Click me'"); + + create_controlevent_table(hdb); + add_controlevent_entry(hdb, "'child1', 'exit', 'EndDialog', 'Exit', 1, 1"); + add_controlevent_entry(hdb, "'child2', 'exit', 'EndDialog', 'Exit', 1, 1"); + + create_custom_action_table(hdb); + add_custom_action_entry(hdb, "'custom', 51, 'dummy', 'dummy value'"); /* SpawnDialog and EndDialog should trigger after all other events */ - r = add_controlevent_entry(hdb, "'spawn', 'button', 'SpawnDialog', 'child1', 1, 1"); - ok(r == ERROR_SUCCESS, "failed to insert into ControlEvent table: %u\n", r); - r = add_controlevent_entry(hdb, "'spawn', 'button', 'DoAction', 'custom', 1, 2"); - ok(r == ERROR_SUCCESS, "failed to insert into ControlEvent table: %u\n", r); + add_controlevent_entry(hdb, "'spawn', 'button', 'SpawnDialog', 'child1', 1, 1"); + add_controlevent_entry(hdb, "'spawn', 'button', 'DoAction', 'custom', 1, 2"); /* Multiple dialog events cause only the last one to be triggered */ - r = add_controlevent_entry(hdb, "'spawn2', 'button', 'SpawnDialog', 'child1', 1, 1"); - ok(r == ERROR_SUCCESS, "failed to insert into ControlEvent table: %u\n", r); - r = add_controlevent_entry(hdb, "'spawn2', 'button', 'SpawnDialog', 'child2', 1, 2"); - ok(r == ERROR_SUCCESS, "failed to insert into ControlEvent table: %u\n", r); - r = add_controlevent_entry(hdb, "'spawn2', 'button', 'DoAction', 'custom', 1, 3"); - ok(r == ERROR_SUCCESS, "failed to insert into ControlEvent table: %u\n", r); + add_controlevent_entry(hdb, "'spawn2', 'button', 'SpawnDialog', 'child1', 1, 1"); + add_controlevent_entry(hdb, "'spawn2', 'button', 'SpawnDialog', 'child2', 1, 2"); + add_controlevent_entry(hdb, "'spawn2', 'button', 'DoAction', 'custom', 1, 3"); r = package_from_db(hdb, &hpkg); ok(r == ERROR_SUCCESS, "failed to create package: %u\n", r); @@ -9834,6 +9432,249 @@ static void test_controlevent(void) DeleteFileA("forcecodepage.idt"); } +static const struct externalui_message toplevel_install_sequence[] = { + {INSTALLMESSAGE_ACTIONSTART, 3, {"", "INSTALL", "", ""}, {0, 1, 1, 1}}, + {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", ""}, {0, 1, 1}}, + + {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}}, + {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}}, + {INSTALLMESSAGE_INFO|MB_ICONHAND, 0, {""}, {0}}, + {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}}, + {INSTALLMESSAGE_COMMONDATA, 3, {"", "1", "", ""}, {0, 1, 0, 0}}, + + {INSTALLMESSAGE_ACTIONSTART, 3, {"", "INSTALL", "", ""}, {0, 1, 1, 1}}, + {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", ""}, {0, 1, 1}}, + {INSTALLMESSAGE_INSTALLSTART, 2, {"", "", "{7262AC98-EEBD-4364-8CE3-D654F6A425B9}"}, {1, 1, 1}, 1}, + + {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CostInitialize", "", ""}, {0, 1, 0, 1}}, + {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", ""}, {0, 1, 1}}, + {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", "1"}, {0, 1, 1}}, + + {INSTALLMESSAGE_ACTIONSTART, 3, {"", "FileCost", "", ""}, {0, 1, 0, 1}}, + {INSTALLMESSAGE_INFO, 2, {"", "FileCost", "1"}, {0, 1, 1}}, + {INSTALLMESSAGE_INFO, 2, {"", "FileCost", "1"}, {0, 1, 1}}, + + {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CostFinalize", "", ""}, {0, 1, 0, 1}}, + {INSTALLMESSAGE_INFO, 2, {"", "CostFinalize", "1"}, {0, 1, 1}}, + {INSTALLMESSAGE_INFO, 2, {"", "CostFinalize", "1"}, {0, 1, 1}}, + + {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", "1"}, {0, 1, 1}}, + {INSTALLMESSAGE_INSTALLEND, 3, {"", "", "{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "1"}, {1, 1, 1, 1}, 1}, + + /* property dump */ + + {INSTALLMESSAGE_COMMONDATA, 2, {"", "2", "0"}, {0, 1, 1}, 1}, + {INSTALLMESSAGE_COMMONDATA, 2, {"", "2", "1"}, {0, 1, 1}, 1}, + {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", "1"}, {0, 1, 1}}, + {0} +}; + +static const struct externalui_message toplevel_install_ui_sequence[] = { + {INSTALLMESSAGE_ACTIONSTART, 3, {"", "INSTALL", "", ""}, {0, 1, 1, 1}}, + {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", ""}, {0, 1, 1}}, + + {INSTALLMESSAGE_ACTIONSTART, 3, {"", "AppSearch", "", ""}, {0, 1, 0, 0}}, + {INSTALLMESSAGE_INFO, 2, {"", "AppSearch", ""}, {0, 1, 1}}, + {INSTALLMESSAGE_INFO, 2, {"", "AppSearch", "0"}, {0, 1, 1}}, + + {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", "1"}, {0, 1, 1}}, + {0} +}; + +static const struct externalui_message toplevel_executeaction_install_sequence[] = { + {INSTALLMESSAGE_ACTIONSTART, 3, {"", "ExecuteAction", "", ""}, {0, 1, 1, 1}}, + {INSTALLMESSAGE_INFO, 2, {"", "ExecuteAction", "1"}, {0, 1, 1}}, + + {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}}, + {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}}, + {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}}, + {INSTALLMESSAGE_COMMONDATA, 3, {"", "1", "", ""}, {0, 1, 0, 0}}, + + {INSTALLMESSAGE_ACTIONSTART, 3, {"", "INSTALL", "", ""}, {0, 1, 1, 1}}, + {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", ""}, {0, 1, 1}}, + {INSTALLMESSAGE_INSTALLSTART, 2, {"", "", "{7262AC98-EEBD-4364-8CE3-D654F6A425B9}"}, {1, 1, 1}, 1}, + + {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CostInitialize", "", ""}, {0, 1, 0, 1}}, + {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize"}, {0, 1}}, + {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", "1"}, {0, 1, 1}}, + + {INSTALLMESSAGE_ACTIONSTART, 3, {"", "FileCost", "", ""}, {0, 1, 0, 1}}, + {INSTALLMESSAGE_INFO, 2, {"", "FileCost", "1"}, {0, 1, 1}}, + {INSTALLMESSAGE_INFO, 2, {"", "FileCost", "1"}, {0, 1, 1}}, + + {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CostFinalize", "", ""}, {0, 1, 0, 1}}, + {INSTALLMESSAGE_INFO, 2, {"", "CostFinalize", "1"}, {0, 1, 1}}, + {INSTALLMESSAGE_INFO, 2, {"", "CostFinalize", "1"}, {0, 1, 1}}, + + {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", "1"}, {0, 1, 1}}, + {INSTALLMESSAGE_INSTALLEND, 3, {"", "", "{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", "1"}, {1, 1, 1, 1}, 1}, + + /* property dump */ + + {INSTALLMESSAGE_COMMONDATA, 2, {"", "2", "0"}, {0, 1, 1}, 1}, + {INSTALLMESSAGE_COMMONDATA, 2, {"", "2", "1"}, {0, 1, 1}, 1}, + {INSTALLMESSAGE_INFO, 2, {"", "ExecuteAction", "1"}, {0, 1, 1}}, + {0} +}; + +static const struct externalui_message toplevel_executeaction_costinitialize_sequence[] = { + {INSTALLMESSAGE_ACTIONSTART, 3, {"", "ExecuteAction", "", ""}, {0, 1, 1, 1}}, + {INSTALLMESSAGE_INFO, 2, {"", "ExecuteAction", "1"}, {0, 1, 1}}, + + {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}}, + {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}}, + {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}}, + {INSTALLMESSAGE_COMMONDATA, 3, {"", "1", "", ""}, {0, 1, 0, 0}}, + + {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CostInitialize", "", ""}, {0, 1, 0, 1}}, + {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", ""}, {0, 1}}, + {INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", "1"}, {0, 1, 1}}, + + /* property dump */ + + {INSTALLMESSAGE_COMMONDATA, 2, {"", "2", "0"}, {0, 1, 1}, 1}, + {INSTALLMESSAGE_COMMONDATA, 2, {"", "2", "1"}, {0, 1, 1}, 1}, + {INSTALLMESSAGE_INFO, 2, {"", "ExecuteAction", "1"}, {0, 1, 1}}, + {0} +}; + +static const struct externalui_message toplevel_msiinstallproduct_sequence[] = { + {INSTALLMESSAGE_INITIALIZE, -1}, + + {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}}, + {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}}, + {INSTALLMESSAGE_INFO|MB_ICONHAND, 0, {""}, {0}}, + {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}}, + {INSTALLMESSAGE_COMMONDATA, 3, {"", "1", "", ""}, {0, 1, 0, 0}}, + + {INSTALLMESSAGE_ACTIONSTART, 3, {"", "INSTALL", "", ""}, {0, 1, 1, 1}}, + {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", ""}, {0, 1, 1}}, + + {INSTALLMESSAGE_ACTIONSTART, 3, {"", "AppSearch", "", ""}, {0, 1, 0, 0}}, + {INSTALLMESSAGE_INFO, 2, {"", "AppSearch", ""}, {0, 1, 1}}, + {INSTALLMESSAGE_INFO, 2, {"", "AppSearch", "0"}, {0, 1, 1}}, + + {INSTALLMESSAGE_INFO, 2, {"", "INSTALL", "1"}, {0, 1, 1}}, + + /* property dump */ + + {INSTALLMESSAGE_INFO|MB_ICONHAND, 0, {""}, {0}}, + {INSTALLMESSAGE_TERMINATE, -1}, + {0} +}; + +static const struct externalui_message toplevel_msiinstallproduct_custom_sequence[] = { + {INSTALLMESSAGE_INITIALIZE, -1}, + + {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}}, + {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {1, 1, 1, 1}}, + {INSTALLMESSAGE_INFO|MB_ICONHAND, 0, {""}, {0}}, + {INSTALLMESSAGE_COMMONDATA, 3, {"", "0", "1033", "1252"}, {0, 1, 1, 1}}, + {INSTALLMESSAGE_COMMONDATA, 3, {"", "1", "", ""}, {0, 1, 0, 0}}, + + {INSTALLMESSAGE_ACTIONSTART, 3, {"", "CUSTOM", "", ""}, {0, 1, 1, 1}}, + {INSTALLMESSAGE_INFO, 2, {"", "CUSTOM", ""}, {0, 1, 1}}, + {INSTALLMESSAGE_INFO, 2, {"", "CUSTOM", "0"}, {0, 1, 1}}, + + /* property dump */ + + {INSTALLMESSAGE_INFO|MB_ICONHAND, 0, {""}, {0}}, + {INSTALLMESSAGE_TERMINATE, -1}, + {0} ... 162 lines suppressed ...
7 years, 4 months
1
0
0
0
← Newer
1
...
19
20
21
22
23
24
25
...
38
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
Results per page:
10
25
50
100
200