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
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
April 2015
----- 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
17 participants
481 discussions
Start a n
N
ew thread
[akhaldi] 67074: [RICHED20] EM_SETSEL should not return 0. By Christoph von Wittich. Already accepted upstream.
by akhaldi@svn.reactos.org
Author: akhaldi Date: Mon Apr 6 17:52:16 2015 New Revision: 67074 URL:
http://svn.reactos.org/svn/reactos?rev=67074&view=rev
Log: [RICHED20] EM_SETSEL should not return 0. By Christoph von Wittich. Already accepted upstream. Modified: trunk/reactos/dll/win32/riched20/editor.c Modified: trunk/reactos/dll/win32/riched20/editor.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/riched20/editor.…
============================================================================== --- trunk/reactos/dll/win32/riched20/editor.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/riched20/editor.c [iso-8859-1] Mon Apr 6 17:52:16 2015 @@ -3304,8 +3304,7 @@ } case EM_SETSEL: { - handle_EM_EXSETSEL( editor, wParam, lParam ); - return 0; + return handle_EM_EXSETSEL( editor, wParam, lParam ); } case EM_SETSCROLLPOS: {
9 years, 8 months
1
0
0
0
[akhaldi] 67073: [RICHED20_WINETEST] Sync with Wine Staging 1.7.37. CORE-9246
by akhaldi@svn.reactos.org
Author: akhaldi Date: Mon Apr 6 17:45:01 2015 New Revision: 67073 URL:
http://svn.reactos.org/svn/reactos?rev=67073&view=rev
Log: [RICHED20_WINETEST] Sync with Wine Staging 1.7.37. CORE-9246 Modified: trunk/rostests/winetests/riched20/editor.c trunk/rostests/winetests/riched20/richole.c trunk/rostests/winetests/riched20/txtsrv.c Modified: trunk/rostests/winetests/riched20/editor.c URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/riched20/editor…
============================================================================== --- trunk/rostests/winetests/riched20/editor.c [iso-8859-1] (original) +++ trunk/rostests/winetests/riched20/editor.c [iso-8859-1] Mon Apr 6 17:45:01 2015 @@ -3735,9 +3735,8 @@ ok (result == 1, "EM_SETTEXTEX returned %d, instead of 1\n",result); - ok(lstrlenW(buf) == 0, - "EM_SETTEXTEX with NULL lParam should clear rich edit.\n"); - + ok(!buf[0], "EM_SETTEXTEX with NULL lParam should clear rich edit.\n"); + /* put some text back: !ST_SELECTION && Unicode && !\rtf */ setText.flags = 0; SendMessageA(hwndRichEdit, EM_SETTEXTEX, (WPARAM)&setText, (LPARAM)TestItem1); @@ -5224,8 +5223,7 @@ result = SendMessageA(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM)buffer); ok (result == 0, "EM_STREAMIN: Test 2 returned %ld, expected 0\n", result); - ok (strlen(buffer) == 0, - "EM_STREAMIN: Test 2 set wrong text: Result: %s\n",buffer); + ok(!buffer[0], "EM_STREAMIN: Test 2 set wrong text: Result: %s\n",buffer); ok(es.dwError == -16, "EM_STREAMIN: Test 2 set error %d, expected %d\n", es.dwError, -16); es.dwCookie = (DWORD_PTR)&streamText3; @@ -5236,8 +5234,7 @@ result = SendMessageA(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM)buffer); ok (result == 0, "EM_STREAMIN: Test 3 returned %ld, expected 0\n", result); - ok (strlen(buffer) == 0, - "EM_STREAMIN: Test 3 set wrong text: Result: %s\n",buffer); + ok(!buffer[0], "EM_STREAMIN: Test 3 set wrong text: Result: %s\n",buffer); ok(es.dwError == -16, "EM_STREAMIN: Test 3 set error %d, expected %d\n", es.dwError, -16); es.dwCookie = (DWORD_PTR)&streamTextUTF8BOM; @@ -7381,7 +7378,7 @@ char buf[2]; buf[0] = delimiter_tests[i].c; buf[1] = 0; - SendMessageW(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)buf); + SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)buf); result = SendMessageA(hwndRichEdit, EM_FINDWORDBREAK, WB_ISDELIMITER, 0); if (buf[0] == 0x20) todo_wine Modified: trunk/rostests/winetests/riched20/richole.c URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/riched20/richol…
============================================================================== --- trunk/rostests/winetests/riched20/richole.c [iso-8859-1] (original) +++ trunk/rostests/winetests/riched20/richole.c [iso-8859-1] Mon Apr 6 17:45:01 2015 @@ -941,6 +941,451 @@ release_interfaces(&w, &reOle, &txtDoc, &txtSel); } +static void test_ITextRange_SetStart(void) +{ + HWND w; + IRichEditOle *reOle = NULL; + ITextDocument *txtDoc = NULL; + ITextRange *txtRge = NULL; + HRESULT hres; + LONG first, lim, start, end; + static const CHAR test_text1[] = "TestSomeText"; + + create_interfaces(&w, &reOle, &txtDoc, NULL); + SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1); + + first = 4, lim = 8; + ITextDocument_Range(txtDoc, first, lim, &txtRge); + hres = ITextRange_SetStart(txtRge, first); + ok(hres == S_FALSE, "ITextRange_SetStart\n"); + +#define TEST_TXTRGE_SETSTART(cp, expected_start, expected_end) \ + hres = ITextRange_SetStart(txtRge, cp); \ + ok(hres == S_OK, "ITextRange_SetStart\n"); \ + ITextRange_GetStart(txtRge, &start); \ + ITextRange_GetEnd(txtRge, &end); \ + ok(start == expected_start, "got wrong start value: %d\n", start); \ + ok(end == expected_end, "got wrong end value: %d\n", end); + + TEST_TXTRGE_SETSTART(2, 2, 8) + TEST_TXTRGE_SETSTART(-1, 0, 8) + TEST_TXTRGE_SETSTART(13, 12, 12) + + release_interfaces(&w, &reOle, &txtDoc, NULL); +} + +static void test_ITextRange_SetEnd(void) +{ + HWND w; + IRichEditOle *reOle = NULL; + ITextDocument *txtDoc = NULL; + ITextRange *txtRge = NULL; + HRESULT hres; + LONG first, lim, start, end; + static const CHAR test_text1[] = "TestSomeText"; + + create_interfaces(&w, &reOle, &txtDoc, NULL); + SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1); + + first = 4, lim = 8; + ITextDocument_Range(txtDoc, first, lim, &txtRge); + hres = ITextRange_SetEnd(txtRge, lim); + ok(hres == S_FALSE, "ITextRange_SetEnd\n"); + +#define TEST_TXTRGE_SETEND(cp, expected_start, expected_end) \ + hres = ITextRange_SetEnd(txtRge, cp); \ + ok(hres == S_OK, "ITextRange_SetEnd\n"); \ + ITextRange_GetStart(txtRge, &start); \ + ITextRange_GetEnd(txtRge, &end); \ + ok(start == expected_start, "got wrong start value: %d\n", start); \ + ok(end == expected_end, "got wrong end value: %d\n", end); + + TEST_TXTRGE_SETEND(6, 4, 6) + TEST_TXTRGE_SETEND(14, 4, 13) + TEST_TXTRGE_SETEND(-1, 0, 0) + + ITextRange_Release(txtRge); + release_interfaces(&w, &reOle, &txtDoc, NULL); +} + +static void test_ITextSelection_SetStart(void) +{ + HWND w; + IRichEditOle *reOle = NULL; + ITextDocument *txtDoc = NULL; + ITextSelection *txtSel = NULL; + HRESULT hres; + LONG first, lim, start, end; + static const CHAR test_text1[] = "TestSomeText"; + + create_interfaces(&w, &reOle, &txtDoc, &txtSel); + SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1); + + first = 4, lim = 8; + SendMessageA(w, EM_SETSEL, first, lim); + hres = ITextSelection_SetStart(txtSel, first); + ok(hres == S_FALSE, "ITextSelection_SetStart\n"); + +#define TEST_TXTSEL_SETSTART(cp, expected_start, expected_end) \ + hres = ITextSelection_SetStart(txtSel, cp); \ + ok(hres == S_OK, "ITextSelection_SetStart\n"); \ + SendMessageA(w, EM_GETSEL, (LPARAM)&start, (WPARAM)&end); \ + ok(start == expected_start, "got wrong start value: %d\n", start); \ + ok(end == expected_end, "got wrong end value: %d\n", end); + + TEST_TXTSEL_SETSTART(2, 2, 8) + TEST_TXTSEL_SETSTART(-1, 0, 8) + TEST_TXTSEL_SETSTART(13, 12, 12) + + release_interfaces(&w, &reOle, &txtDoc, &txtSel); +} + +static void test_ITextSelection_SetEnd(void) +{ + HWND w; + IRichEditOle *reOle = NULL; + ITextDocument *txtDoc = NULL; + ITextSelection *txtSel = NULL; + HRESULT hres; + LONG first, lim, start, end; + static const CHAR test_text1[] = "TestSomeText"; + + create_interfaces(&w, &reOle, &txtDoc, &txtSel); + SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1); + + first = 4, lim = 8; + SendMessageA(w, EM_SETSEL, first, lim); + hres = ITextSelection_SetEnd(txtSel, lim); + ok(hres == S_FALSE, "ITextSelection_SetEnd\n"); + +#define TEST_TXTSEL_SETEND(cp, expected_start, expected_end) \ + hres = ITextSelection_SetEnd(txtSel, cp); \ + ok(hres == S_OK, "ITextSelection_SetEnd\n"); \ + SendMessageA(w, EM_GETSEL, (LPARAM)&start, (WPARAM)&end); \ + ok(start == expected_start, "got wrong start value: %d\n", start); \ + ok(end == expected_end, "got wrong end value: %d\n", end); + + TEST_TXTSEL_SETEND(6, 4, 6) + TEST_TXTSEL_SETEND(14, 4, 13) + TEST_TXTSEL_SETEND(-1, 0, 0) + + release_interfaces(&w, &reOle, &txtDoc, &txtSel); +} + +static void test_ITextRange_GetFont(void) +{ + HWND w; + IRichEditOle *reOle = NULL; + ITextDocument *txtDoc = NULL; + ITextRange *txtRge = NULL; + ITextFont *txtFont = NULL, *txtFont1 = NULL; + HRESULT hres; + int first, lim; + int refcount; + static const CHAR test_text1[] = "TestSomeText"; + LONG value; + + create_interfaces(&w, &reOle, &txtDoc, NULL); + SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1); + + first = 4, lim = 4; + ITextDocument_Range(txtDoc, first, lim, &txtRge); + refcount = get_refcount((IUnknown *)txtRge); + ok(refcount == 1, "got wrong ref count: %d\n", refcount); + + hres = ITextRange_GetFont(txtRge, &txtFont); + ok(hres == S_OK, "ITextRange_GetFont\n"); + refcount = get_refcount((IUnknown *)txtFont); + ok(refcount == 1, "got wrong ref count: %d\n", refcount); + refcount = get_refcount((IUnknown *)txtRge); + ok(refcount == 2, "got wrong ref count: %d\n", refcount); + + hres = ITextRange_GetFont(txtRge, &txtFont1); + ok(hres == S_OK, "ITextRange_GetFont\n"); + ok(txtFont1 != txtFont, "A new pointer should be return\n"); + refcount = get_refcount((IUnknown *)txtFont1); + ok(refcount == 1, "got wrong ref count: %d\n", refcount); + ITextFont_Release(txtFont1); + refcount = get_refcount((IUnknown *)txtRge); + ok(refcount == 2, "got wrong ref count: %d\n", refcount); + + ITextRange_Release(txtRge); + release_interfaces(&w, &reOle, &txtDoc, NULL); + + hres = ITextFont_GetOutline(txtFont, &value); + ok(hres == CO_E_RELEASED, "ITextFont after ITextDocument destroyed\n"); + + ITextFont_Release(txtFont); +} + +static void test_ITextSelection_GetFont(void) +{ + HWND w; + IRichEditOle *reOle = NULL; + ITextDocument *txtDoc = NULL; + ITextSelection *txtSel = NULL; + ITextFont *txtFont = NULL, *txtFont1 = NULL; + HRESULT hres; + int first, lim; + int refcount; + static const CHAR test_text1[] = "TestSomeText"; + LONG value; + + create_interfaces(&w, &reOle, &txtDoc, &txtSel); + SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1); + + first = 4, lim = 4; + SendMessageA(w, EM_SETSEL, first, lim); + refcount = get_refcount((IUnknown *)txtSel); + ok(refcount == 2, "got wrong ref count: %d\n", refcount); + + hres = ITextSelection_GetFont(txtSel, &txtFont); + ok(hres == S_OK, "ITextSelection_GetFont\n"); + refcount = get_refcount((IUnknown *)txtFont); + ok(refcount == 1, "got wrong ref count: %d\n", refcount); + refcount = get_refcount((IUnknown *)txtSel); + ok(refcount == 3, "got wrong ref count: %d\n", refcount); + + hres = ITextSelection_GetFont(txtSel, &txtFont1); + ok(hres == S_OK, "ITextSelection_GetFont\n"); + ok(txtFont1 != txtFont, "A new pointer should be return\n"); + refcount = get_refcount((IUnknown *)txtFont1); + ok(refcount == 1, "got wrong ref count: %d\n", refcount); + ITextFont_Release(txtFont1); + refcount = get_refcount((IUnknown *)txtSel); + ok(refcount == 3, "got wrong ref count: %d\n", refcount); + + release_interfaces(&w, &reOle, &txtDoc, &txtSel); + + hres = ITextFont_GetOutline(txtFont, &value); + ok(hres == CO_E_RELEASED, "ITextFont after ITextDocument destroyed\n"); + + ITextFont_Release(txtFont); +} + +static void test_ITextRange_GetPara(void) +{ + HWND w; + IRichEditOle *reOle = NULL; + ITextDocument *txtDoc = NULL; + ITextRange *txtRge = NULL; + ITextPara *txtPara = NULL, *txtPara1 = NULL; + HRESULT hres; + int first, lim; + int refcount; + static const CHAR test_text1[] = "TestSomeText"; + LONG value; + + create_interfaces(&w, &reOle, &txtDoc, NULL); + SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1); + + first = 4, lim = 4; + ITextDocument_Range(txtDoc, first, lim, &txtRge); + refcount = get_refcount((IUnknown *)txtRge); + ok(refcount == 1, "got wrong ref count: %d\n", refcount); + + hres = ITextRange_GetPara(txtRge, &txtPara); + ok(hres == S_OK, "ITextRange_GetPara\n"); + refcount = get_refcount((IUnknown *)txtPara); + ok(refcount == 1, "got wrong ref count: %d\n", refcount); + refcount = get_refcount((IUnknown *)txtRge); + ok(refcount == 2, "got wrong ref count: %d\n", refcount); + + hres = ITextRange_GetPara(txtRge, &txtPara1); + ok(hres == S_OK, "ITextRange_GetPara\n"); + ok(txtPara1 != txtPara, "A new pointer should be return\n"); + refcount = get_refcount((IUnknown *)txtPara1); + ok(refcount == 1, "got wrong ref count: %d\n", refcount); + ITextPara_Release(txtPara1); + refcount = get_refcount((IUnknown *)txtRge); + ok(refcount == 2, "got wrong ref count: %d\n", refcount); + + ITextRange_Release(txtRge); + release_interfaces(&w, &reOle, &txtDoc, NULL); + + hres = ITextPara_GetStyle(txtPara, &value); + ok(hres == CO_E_RELEASED, "ITextPara after ITextDocument destroyed\n"); + + ITextPara_Release(txtPara); +} + +static void test_ITextRange_GetText(void) +{ + HWND w; + IRichEditOle *reOle = NULL; + ITextDocument *txtDoc = NULL; + ITextRange *txtRge = NULL; + HRESULT hres; + BSTR bstr = NULL; + static const CHAR test_text1[] = "TestSomeText"; + static const WCHAR bufW1[] = {'T', 'e', 's', 't', 0}; + static const WCHAR bufW2[] = {'T', 'e', 'x', 't', '\r', 0}; + static const WCHAR bufW3[] = {'T', 'e', 'x', 't', 0}; + static const WCHAR bufW4[] = {'T', 'e', 's', 't', 'S', 'o', 'm', + 'e', 'T', 'e', 'x', 't', '\r', 0}; + static const WCHAR bufW5[] = {'\r', 0}; + + +#define TEST_TXTRGE_GETTEXT(first, lim, expected_string) \ + create_interfaces(&w, &reOle, &txtDoc, NULL); \ + SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1); \ + ITextDocument_Range(txtDoc, first, lim, &txtRge); \ + hres = ITextRange_GetText(txtRge, &bstr); \ + ok(hres == S_OK, "ITextRange_GetText\n"); \ + ok(!lstrcmpW(bstr, expected_string), "got wrong text: %s\n", wine_dbgstr_w(bstr)); \ + SysFreeString(bstr); \ + ITextRange_Release(txtRge); \ + release_interfaces(&w, &reOle, &txtDoc, NULL); + + TEST_TXTRGE_GETTEXT(0, 4, bufW1) + TEST_TXTRGE_GETTEXT(4, 0, bufW1) + TEST_TXTRGE_GETTEXT(8, 12, bufW3) + TEST_TXTRGE_GETTEXT(8, 13, bufW2) + TEST_TXTRGE_GETTEXT(12, 13, bufW5) + TEST_TXTRGE_GETTEXT(0, 13, bufW4) + TEST_TXTRGE_GETTEXT(1, 1, NULL) +} + +static void test_ITextRange_SetRange(void) +{ + HWND w; + IRichEditOle *reOle = NULL; + ITextDocument *txtDoc = NULL; + ITextRange *txtRge = NULL; + HRESULT hres; + int start, end; + static const CHAR test_text1[] = "TestSomeText"; + + create_interfaces(&w, &reOle, &txtDoc, NULL); + SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1); + ITextDocument_Range(txtDoc, 0, 0, &txtRge); + +#define TEST_TXTRGE_SETRANGE(first, lim, expected_start, expected_end, expected_return) \ + hres = ITextRange_SetRange(txtRge, first, lim); \ + ok(hres == expected_return, "ITextRange_SetRange\n"); \ + ITextRange_GetStart(txtRge, &start); \ + ITextRange_GetEnd(txtRge, &end); \ + ok(start == expected_start, "got wrong start value: %d\n", start); \ + ok(end == expected_end, "got wrong end value: %d\n", end); + + TEST_TXTRGE_SETRANGE(2, 4, 2, 4, S_OK) + TEST_TXTRGE_SETRANGE(2, 4, 2, 4, S_FALSE) + TEST_TXTRGE_SETRANGE(4, 2, 2, 4, S_FALSE) + TEST_TXTRGE_SETRANGE(14, 14, 12, 12, S_OK) + TEST_TXTRGE_SETRANGE(15, 15, 12, 12, S_FALSE) + TEST_TXTRGE_SETRANGE(14, 1, 1, 13, S_OK) + TEST_TXTRGE_SETRANGE(-1, 4, 0, 4, S_OK) + + ITextRange_Release(txtRge); + release_interfaces(&w, &reOle, &txtDoc, NULL); +} + +static void test_ITextRange_IsEqual(void) +{ + HWND w; + IRichEditOle *reOle = NULL; + ITextDocument *txtDoc = NULL; + ITextRange *txtRge1 = NULL, *txtRge2 = NULL; + HRESULT hres; + static const CHAR test_text1[] = "TestSomeText"; + LONG res; + + create_interfaces(&w, &reOle, &txtDoc, NULL); + SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1); + ITextDocument_Range(txtDoc, 2, 4, &txtRge1); + ITextDocument_Range(txtDoc, 2, 4, &txtRge2); + +#define TEST_TXTRGE_ISEQUAL(expected_hres, expected_res) \ + hres = ITextRange_IsEqual(txtRge1, txtRge2, &res); \ + ok(hres == expected_hres, "ITextRange_IsEqual\n"); \ + ok(res == expected_res, "got wrong return value: %d\n", res); + + TEST_TXTRGE_ISEQUAL(S_OK, tomTrue) + ITextRange_SetRange(txtRge2, 1, 2); + TEST_TXTRGE_ISEQUAL(S_FALSE, tomFalse) + + ITextRange_SetRange(txtRge1, 1, 1); + ITextRange_SetRange(txtRge2, 2, 2); + TEST_TXTRGE_ISEQUAL(S_FALSE, tomFalse) + + ITextRange_SetRange(txtRge2, 1, 1); + TEST_TXTRGE_ISEQUAL(S_OK, tomTrue) + + hres = ITextRange_IsEqual(txtRge1, txtRge1, &res); + ok(hres == S_OK, "ITextRange_IsEqual\n"); + ok(res == tomTrue, "got wrong return value: %d\n", res); + + hres = ITextRange_IsEqual(txtRge1, txtRge2, NULL); + ok(hres == S_OK, "ITextRange_IsEqual\n"); + + hres = ITextRange_IsEqual(txtRge1, NULL, NULL); + ok(hres == S_FALSE, "ITextRange_IsEqual\n"); + + ITextRange_Release(txtRge1); + ITextRange_Release(txtRge2); + release_interfaces(&w, &reOle, &txtDoc, NULL); +} + +static void test_ITextRange_GetStoryLength(void) +{ + HWND w; + IRichEditOle *reOle = NULL; + ITextDocument *txtDoc = NULL; + ITextRange *txtRge = NULL; + HRESULT hres; + LONG count; + static const CHAR test_text1[] = "TestSomeText"; + int len = strlen(test_text1) + 1; + + create_interfaces(&w, &reOle, &txtDoc, NULL); + SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1); + ITextDocument_Range(txtDoc, 0, 0, &txtRge); + + hres = ITextRange_GetStoryLength(txtRge, &count); + ok(hres == S_OK, "ITextRange_GetStoryLength\n"); + ok(count == len, "got wrong length: %d\n", count); + + ITextRange_SetRange(txtRge, 1, 2); + hres = ITextRange_GetStoryLength(txtRge, &count); + ok(hres == S_OK, "ITextRange_GetStoryLength\n"); + ok(count == len, "got wrong length: %d\n", count); + + hres = ITextRange_GetStoryLength(txtRge, NULL); + ok(hres == E_INVALIDARG, "ITextRange_GetStoryLength\n"); + + ITextRange_Release(txtRge); + release_interfaces(&w, &reOle, &txtDoc, NULL); +} + +static void test_ITextSelection_GetStoryLength(void) +{ + HWND w; + IRichEditOle *reOle = NULL; + ITextDocument *txtDoc = NULL; + ITextSelection *txtSel = NULL; + HRESULT hres; + LONG count; + static const CHAR test_text1[] = "TestSomeText"; + int len = strlen(test_text1) + 1; + + create_interfaces(&w, &reOle, &txtDoc, &txtSel); + SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1); + + hres = ITextSelection_GetStoryLength(txtSel, &count); + ok(hres == S_OK, "ITextSelection_GetStoryLength\n"); + ok(count == len, "got wrong length: %d\n", count); + + SendMessageA(w, EM_SETSEL, 1, 2); + hres = ITextSelection_GetStoryLength(txtSel, &count); + ok(hres == S_OK, "ITextSelection_GetStoryLength\n"); + ok(count == len, "got wrong length: %d\n", count); + + hres = ITextSelection_GetStoryLength(txtSel, NULL); + ok(hres == E_INVALIDARG, "ITextSelection_GetStoryLength\n"); + + release_interfaces(&w, &reOle, &txtDoc, &txtSel); +} + START_TEST(richole) { /* Must explicitly LoadLibrary(). The test has no references to functions in @@ -953,10 +1398,22 @@ test_ITextSelection_GetText(); test_ITextSelection_GetChar(); test_ITextSelection_GetStart_GetEnd(); + test_ITextSelection_SetStart(); + test_ITextSelection_SetEnd(); test_ITextSelection_Collapse(); + test_ITextSelection_GetFont(); + test_ITextSelection_GetStoryLength(); test_ITextDocument_Range(); test_ITextRange_GetChar(); test_ITextRange_GetStart_GetEnd(); test_ITextRange_GetDuplicate(); test_ITextRange_Collapse(); -} + test_ITextRange_SetStart(); + test_ITextRange_SetEnd(); + test_ITextRange_GetFont(); + test_ITextRange_GetPara(); + test_ITextRange_GetText(); + test_ITextRange_SetRange(); + test_ITextRange_IsEqual(); + test_ITextRange_GetStoryLength(); +} Modified: trunk/rostests/winetests/riched20/txtsrv.c URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/riched20/txtsrv…
============================================================================== --- trunk/rostests/winetests/riched20/txtsrv.c [iso-8859-1] (original) +++ trunk/rostests/winetests/riched20/txtsrv.c [iso-8859-1] Mon Apr 6 17:45:01 2015 @@ -29,6 +29,8 @@ #include <winbase.h> #include <objbase.h> #include <richedit.h> +#include <tom.h> +#include <richole.h> #include <initguid.h> #include <textserv.h> #include <wine/test.h> @@ -861,6 +863,72 @@ IUnknown_Release(unk_obj.inner_unk); } +static ULONG get_refcount(IUnknown *iface) +{ + IUnknown_AddRef(iface); + return IUnknown_Release(iface); +} + +static void test_QueryInterface(void) +{ + HRESULT hres; + IRichEditOle *reole, *txtsrv_reole; + ITextDocument *txtdoc, *txtsrv_txtdoc; + ULONG refcount; + + if(!init_texthost()) + return; + + refcount = get_refcount((IUnknown *)txtserv); + ok(refcount == 1, "got wrong ref count: %d\n", refcount); + + /* IID_IRichEditOle */ + hres = ITextServices_QueryInterface(txtserv, &IID_IRichEditOle, (void **)&txtsrv_reole); + ok(hres == S_OK, "ITextServices_QueryInterface: 0x%08x\n", hres); + refcount = get_refcount((IUnknown *)txtserv); + ok(refcount == 2, "got wrong ref count: %d\n", refcount); + refcount = get_refcount((IUnknown *)txtsrv_reole); + ok(refcount == 2, "got wrong ref count: %d\n", refcount); + + hres = IRichEditOle_QueryInterface(txtsrv_reole, &IID_ITextDocument, (void **)&txtdoc); + ok(hres == S_OK, "IRichEditOle_QueryInterface: 0x%08x\n", hres); + refcount = get_refcount((IUnknown *)txtserv); + ok(refcount == 3, "got wrong ref count: %d\n", refcount); + refcount = get_refcount((IUnknown *)txtsrv_reole); + ok(refcount == 3, "got wrong ref count: %d\n", refcount); + + ITextDocument_Release(txtdoc); + refcount = get_refcount((IUnknown *)txtserv); + ok(refcount == 2, "got wrong ref count: %d\n", refcount); + IRichEditOle_Release(txtsrv_reole); + refcount = get_refcount((IUnknown *)txtserv); + ok(refcount == 1, "got wrong ref count: %d\n", refcount); + + /* IID_ITextDocument */ + hres = ITextServices_QueryInterface(txtserv, &IID_ITextDocument, (void **)&txtsrv_txtdoc); + ok(hres == S_OK, "ITextServices_QueryInterface: 0x%08x\n", hres); + refcount = get_refcount((IUnknown *)txtserv); + ok(refcount == 2, "got wrong ref count: %d\n", refcount); + refcount = get_refcount((IUnknown *)txtsrv_txtdoc); + ok(refcount == 2, "got wrong ref count: %d\n", refcount); + + hres = ITextDocument_QueryInterface(txtsrv_txtdoc, &IID_IRichEditOle, (void **)&reole); + ok(hres == S_OK, "ITextDocument_QueryInterface: 0x%08x\n", hres); + refcount = get_refcount((IUnknown *)txtserv); + ok(refcount == 3, "got wrong ref count: %d\n", refcount); + refcount = get_refcount((IUnknown *)txtsrv_txtdoc); + ok(refcount == 3, "got wrong ref count: %d\n", refcount); + + IRichEditOle_Release(reole); + refcount = get_refcount((IUnknown *)txtserv); + ok(refcount == 2, "got wrong ref count: %d\n", refcount); + ITextDocument_Release(txtsrv_txtdoc); + refcount = get_refcount((IUnknown *)txtserv); + ok(refcount == 1, "got wrong ref count: %d\n", refcount); + + free_texthost(); +} + START_TEST( txtsrv ) { setup_thiscall_wrappers(); @@ -886,6 +954,7 @@ test_TxSetText(); test_TxGetNaturalSize(); test_TxDraw(); + test_QueryInterface(); } if (wrapperCodeMem) VirtualFree(wrapperCodeMem, 0, MEM_RELEASE); }
9 years, 8 months
1
0
0
0
[akhaldi] 67072: [RICHED20] Sync with Wine Staging 1.7.37. CORE-9246
by akhaldi@svn.reactos.org
Author: akhaldi Date: Mon Apr 6 17:44:48 2015 New Revision: 67072 URL:
http://svn.reactos.org/svn/reactos?rev=67072&view=rev
Log: [RICHED20] Sync with Wine Staging 1.7.37. CORE-9246 Modified: trunk/reactos/dll/win32/riched20/editor.c trunk/reactos/dll/win32/riched20/editor.h trunk/reactos/dll/win32/riched20/richole.c trunk/reactos/dll/win32/riched20/run.c trunk/reactos/dll/win32/riched20/txtsrv.c trunk/reactos/media/doc/README.WINE Modified: trunk/reactos/dll/win32/riched20/editor.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/riched20/editor.…
============================================================================== --- trunk/reactos/dll/win32/riched20/editor.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/riched20/editor.c [iso-8859-1] Mon Apr 6 17:44:48 2015 @@ -1192,7 +1192,7 @@ if (!info->lpRichEditOle) { - CreateIRichEditOle(info->editor, (VOID**)&info->lpRichEditOle); + CreateIRichEditOle(NULL, info->editor, (VOID**)&info->lpRichEditOle); } if (OleCreateDefaultHandler(&CLSID_NULL, NULL, &IID_IOleObject, (void**)&lpObject) == S_OK && @@ -2116,7 +2116,7 @@ hr = OleSetClipboard(dataObj); IDataObject_Release(dataObj); } - return SUCCEEDED(hr) != 0; + return SUCCEEDED(hr); } /* helper to send a msg filter notification */ @@ -2861,7 +2861,7 @@ return ed; } -static void ME_DestroyEditor(ME_TextEditor *editor) +void ME_DestroyEditor(ME_TextEditor *editor) { ME_DisplayItem *pFirst = editor->pBuffer->pFirst; ME_DisplayItem *p = pFirst, *pNext = NULL; @@ -4472,7 +4472,7 @@ case EM_GETOLEINTERFACE: { if (!editor->reOle) - if (!CreateIRichEditOle(editor, (LPVOID *)&editor->reOle)) + if (!CreateIRichEditOle(NULL, editor, (LPVOID *)&editor->reOle)) return 0; *(LPVOID *)lParam = editor->reOle; IRichEditOle_AddRef(editor->reOle); @@ -4816,7 +4816,7 @@ wcW.cbWndExtra = sizeof(ME_TextEditor *); wcW.hInstance = NULL; /* hInstance would register DLL-local class */ wcW.hIcon = NULL; - wcW.hCursor = LoadCursorW(NULL, MAKEINTRESOURCEW(IDC_IBEAM)); + wcW.hCursor = LoadCursorW(NULL, (LPWSTR)IDC_IBEAM); wcW.hbrBackground = GetStockObject(NULL_BRUSH); wcW.lpszMenuName = NULL; @@ -4842,7 +4842,7 @@ wcA.cbWndExtra = sizeof(ME_TextEditor *); wcA.hInstance = NULL; /* hInstance would register DLL-local class */ wcA.hIcon = NULL; - wcA.hCursor = LoadCursorW(NULL, MAKEINTRESOURCEW(IDC_IBEAM)); + wcA.hCursor = LoadCursorW(NULL, (LPWSTR)IDC_IBEAM); wcA.hbrBackground = GetStockObject(NULL_BRUSH); wcA.lpszMenuName = NULL; wcA.lpszClassName = RICHEDIT_CLASS20A; Modified: trunk/reactos/dll/win32/riched20/editor.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/riched20/editor.…
============================================================================== --- trunk/reactos/dll/win32/riched20/editor.h [iso-8859-1] (original) +++ trunk/reactos/dll/win32/riched20/editor.h [iso-8859-1] Mon Apr 6 17:44:48 2015 @@ -47,6 +47,7 @@ #include <richole.h> #include <imm.h> #include <textserv.h> +#include <tom.h> #include <usp10.h> #include <wine/debug.h> @@ -274,14 +275,16 @@ int ME_GetParaBorderWidth(const ME_Context *c, int flags) DECLSPEC_HIDDEN; /* richole.c */ -LRESULT CreateIRichEditOle(ME_TextEditor *editor, LPVOID *) DECLSPEC_HIDDEN; +LRESULT CreateIRichEditOle(IUnknown *outer_unk, ME_TextEditor *editor, LPVOID *ppvObj) DECLSPEC_HIDDEN; void ME_DrawOLE(ME_Context *c, int x, int y, ME_Run* run, ME_Paragraph *para, BOOL selected) DECLSPEC_HIDDEN; void ME_GetOLEObjectSize(const ME_Context *c, ME_Run *run, SIZE *pSize) DECLSPEC_HIDDEN; void ME_CopyReObject(REOBJECT* dst, const REOBJECT* src) DECLSPEC_HIDDEN; void ME_DeleteReObject(REOBJECT* reo) DECLSPEC_HIDDEN; +void ME_GetITextDocumentInterface(IRichEditOle *iface, LPVOID *ppvObj) DECLSPEC_HIDDEN; /* editor.c */ ME_TextEditor *ME_MakeEditor(ITextHost *texthost, BOOL bEmulateVersion10) DECLSPEC_HIDDEN; +void ME_DestroyEditor(ME_TextEditor *editor) DECLSPEC_HIDDEN; LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, LPARAM lParam, BOOL unicode, HRESULT* phresult) DECLSPEC_HIDDEN; void ME_SendOldNotify(ME_TextEditor *editor, int nCode) DECLSPEC_HIDDEN; Modified: trunk/reactos/dll/win32/riched20/richole.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/riched20/richole…
============================================================================== --- trunk/reactos/dll/win32/riched20/richole.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/riched20/richole.c [iso-8859-1] Mon Apr 6 17:44:48 2015 @@ -21,8 +21,6 @@ #include "editor.h" -#include <tom.h> - WINE_DEFAULT_DEBUG_CHANNEL(richedit); /* there is no way to be consistent across different sets of headers - mingw, Wine, Win32 SDK*/ @@ -34,21 +32,49 @@ DEFINE_GUID(IID_ITextDocument, 0x8cc497c0, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d); DEFINE_GUID(IID_ITextRange, 0x8cc497c2, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d); DEFINE_GUID(IID_ITextSelection, 0x8cc497c1, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d); +DEFINE_GUID(IID_ITextFont, 0x8cc497c3, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d); +DEFINE_GUID(IID_ITextPara, 0x8cc497c4, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d); typedef struct ITextSelectionImpl ITextSelectionImpl; typedef struct IOleClientSiteImpl IOleClientSiteImpl; typedef struct ITextRangeImpl ITextRangeImpl; +typedef struct ITextFontImpl ITextFontImpl; +typedef struct ITextParaImpl ITextParaImpl; typedef struct IRichEditOleImpl { + IUnknown IUnknown_inner; IRichEditOle IRichEditOle_iface; ITextDocument ITextDocument_iface; + IUnknown *outer_unk; LONG ref; ME_TextEditor *editor; ITextSelectionImpl *txtSel; IOleClientSiteImpl *clientSite; struct list rangelist; + struct list fontlist; + struct list paralist; } IRichEditOleImpl; + +struct ITextParaImpl { + ITextPara ITextPara_iface; + LONG ref; + struct list entry; + + IRichEditOleImpl *reOle; + ITextRangeImpl *txtRge; + ITextSelectionImpl *txtSel; +}; + +struct ITextFontImpl { + ITextFont ITextFont_iface; + LONG ref; + struct list entry; + + IRichEditOleImpl *reOle; + ITextRangeImpl *txtRge; + ITextSelectionImpl *txtSel; +}; struct ITextRangeImpl { ITextRange ITextRange_iface; @@ -83,44 +109,55 @@ return CONTAINING_RECORD(iface, IRichEditOleImpl, ITextDocument_iface); } -static HRESULT WINAPI -IRichEditOle_fnQueryInterface(IRichEditOle *me, REFIID riid, LPVOID *ppvObj) -{ - IRichEditOleImpl *This = impl_from_IRichEditOle(me); - - TRACE("%p %s\n", This, debugstr_guid(riid) ); +static inline IRichEditOleImpl *impl_from_IUnknown(IUnknown *iface) +{ + return CONTAINING_RECORD(iface, IRichEditOleImpl, IUnknown_inner); +} + +static HRESULT WINAPI IRichEditOleImpl_inner_fnQueryInterface(IUnknown *iface, REFIID riid, LPVOID *ppvObj) +{ + IRichEditOleImpl *This = impl_from_IUnknown(iface); + + TRACE("%p %s\n", This, debugstr_guid(riid)); *ppvObj = NULL; - if (IsEqualGUID(riid, &IID_IUnknown) || - IsEqualGUID(riid, &IID_IRichEditOle)) + if (IsEqualGUID(riid, &IID_IUnknown)) + *ppvObj = &This->IUnknown_inner; + else if (IsEqualGUID(riid, &IID_IRichEditOle)) *ppvObj = &This->IRichEditOle_iface; else if (IsEqualGUID(riid, &IID_ITextDocument)) *ppvObj = &This->ITextDocument_iface; if (*ppvObj) { - IRichEditOle_AddRef(me); + IUnknown_AddRef((IUnknown *)*ppvObj); return S_OK; } - FIXME("%p: unhandled interface %s\n", This, debugstr_guid(riid) ); + + if (IsEqualGUID(riid, &IID_ITextServices)) + { + static int once; + if (!once++) FIXME("%p: unhandled interface IID_ITextServices\n", This); + return E_NOINTERFACE; + } + + FIXME("%p: unhandled interface %s\n", This, debugstr_guid(riid)); return E_NOINTERFACE; } -static ULONG WINAPI -IRichEditOle_fnAddRef(IRichEditOle *me) -{ - IRichEditOleImpl *This = impl_from_IRichEditOle(me); - ULONG ref = InterlockedIncrement( &This->ref ); +static ULONG WINAPI IRichEditOleImpl_inner_fnAddRef(IUnknown *iface) +{ + IRichEditOleImpl *This = impl_from_IUnknown(iface); + ULONG ref = InterlockedIncrement(&This->ref); TRACE("%p ref = %u\n", This, ref); return ref; } -static ULONG WINAPI -IRichEditOle_fnRelease(IRichEditOle *me) -{ - IRichEditOleImpl *This = impl_from_IRichEditOle(me); +static ULONG WINAPI IRichEditOleImpl_inner_fnRelease(IUnknown *iface) +{ + IRichEditOleImpl *This = impl_from_IUnknown(iface); ULONG ref = InterlockedDecrement(&This->ref); TRACE ("%p ref=%u\n", This, ref); @@ -128,15 +165,51 @@ if (!ref) { ITextRangeImpl *txtRge; - TRACE ("Destroying %p\n", This); + ITextFontImpl *txtFont; + ITextParaImpl *txtPara; + + TRACE("Destroying %p\n", This); This->txtSel->reOle = NULL; + This->editor->reOle = NULL; ITextSelection_Release(&This->txtSel->ITextSelection_iface); IOleClientSite_Release(&This->clientSite->IOleClientSite_iface); LIST_FOR_EACH_ENTRY(txtRge, &This->rangelist, ITextRangeImpl, entry) txtRge->reOle = NULL; + LIST_FOR_EACH_ENTRY(txtFont, &This->fontlist, ITextFontImpl, entry) + txtFont->reOle = NULL; + LIST_FOR_EACH_ENTRY(txtPara, &This->paralist, ITextParaImpl, entry) + txtPara->reOle = NULL; heap_free(This); } return ref; +} + +static const IUnknownVtbl reo_unk_vtbl = +{ + IRichEditOleImpl_inner_fnQueryInterface, + IRichEditOleImpl_inner_fnAddRef, + IRichEditOleImpl_inner_fnRelease +}; + +static HRESULT WINAPI +IRichEditOle_fnQueryInterface(IRichEditOle *me, REFIID riid, LPVOID *ppvObj) +{ + IRichEditOleImpl *This = impl_from_IRichEditOle(me); + return IUnknown_QueryInterface(This->outer_unk, riid, ppvObj); +} + +static ULONG WINAPI +IRichEditOle_fnAddRef(IRichEditOle *me) +{ + IRichEditOleImpl *This = impl_from_IRichEditOle(me); + return IUnknown_AddRef(This->outer_unk); +} + +static ULONG WINAPI +IRichEditOle_fnRelease(IRichEditOle *me) +{ + IRichEditOleImpl *This = impl_from_IRichEditOle(me); + return IUnknown_Release(This->outer_unk); } static HRESULT WINAPI @@ -445,6 +518,1395 @@ IRichEditOle_fnImportDataObject }; +/* ITextPara interface */ +static inline ITextParaImpl *impl_from_ITextPara(ITextPara *iface) +{ + return CONTAINING_RECORD(iface, ITextParaImpl, ITextPara_iface); +} + +static HRESULT WINAPI ITextPara_fnQueryInterface(ITextPara *me, REFIID riid, void **ppvObj) +{ + *ppvObj = NULL; + if (IsEqualGUID(riid, &IID_IUnknown) + || IsEqualGUID(riid, &IID_ITextPara) + || IsEqualGUID(riid, &IID_IDispatch)) + { + *ppvObj = me; + ITextPara_AddRef(me); + return S_OK; + } + + return E_NOINTERFACE; +} + +static ULONG WINAPI ITextPara_fnAddRef(ITextPara *me) +{ + ITextParaImpl *This = impl_from_ITextPara(me); + return InterlockedIncrement(&This->ref); +} + +static ULONG WINAPI ITextPara_fnRelease(ITextPara *me) +{ + ITextParaImpl *This = impl_from_ITextPara(me); + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE ("%p ref=%u\n", This, ref); + if (ref == 0) + { + if (This->txtRge) + ITextRange_Release(&This->txtRge->ITextRange_iface); + else + ITextSelection_Release(&This->txtSel->ITextSelection_iface); + This->txtRge = NULL; + This->txtSel = NULL; + if (This->reOle) + { + list_remove(&This->entry); + This->reOle = NULL; + } + heap_free(This); + } + return ref; +} + +static HRESULT WINAPI ITextPara_fnGetTypeInfoCount(ITextPara *me, UINT *pctinfo) +{ + ITextParaImpl *This = impl_from_ITextPara(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextPara_fnGetTypeInfo(ITextPara *me, UINT iTInfo, LCID lcid, + ITypeInfo **ppTInfo) +{ + ITextParaImpl *This = impl_from_ITextPara(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextPara_fnGetIDsOfNames(ITextPara *me, REFIID riid, + LPOLESTR *rgszNames, UINT cNames, + LCID lcid, DISPID *rgDispId) +{ + ITextParaImpl *This = impl_from_ITextPara(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextPara_fnInvoke(ITextPara *me, DISPID dispIdMember, REFIID riid, + LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, + VARIANT *pVarResult, EXCEPINFO *pExcepInfo, + UINT *puArgErr) +{ + ITextParaImpl *This = impl_from_ITextPara(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextPara_fnGetDuplicate(ITextPara *me, ITextPara **ppPara) +{ + ITextParaImpl *This = impl_from_ITextPara(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextPara_fnSetDuplicate(ITextPara *me, ITextPara *pPara) +{ + ITextParaImpl *This = impl_from_ITextPara(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextPara_fnCanChange(ITextPara *me, LONG *pB) +{ + ITextParaImpl *This = impl_from_ITextPara(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextPara_fnIsEqual(ITextPara *me, ITextPara *pPara, LONG *pB) +{ + ITextParaImpl *This = impl_from_ITextPara(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextPara_fnReset(ITextPara *me, LONG Value) +{ + ITextParaImpl *This = impl_from_ITextPara(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextPara_fnGetStyle(ITextPara *me, LONG *pValue) +{ + ITextParaImpl *This = impl_from_ITextPara(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextPara_fnSetStyle(ITextPara *me, LONG Value) +{ + ITextParaImpl *This = impl_from_ITextPara(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextPara_fnGetAlignment(ITextPara *me, LONG *pValue) +{ + static int once; + ITextParaImpl *This = impl_from_ITextPara(me); + if (!This->reOle) + return CO_E_RELEASED; + + if (!once++) FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextPara_fnSetAlignment(ITextPara *me, LONG Value) +{ + ITextParaImpl *This = impl_from_ITextPara(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextPara_fnGetHyphenation(ITextPara *me, LONG *pValue) +{ + ITextParaImpl *This = impl_from_ITextPara(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextPara_fnSetHyphenation(ITextPara *me, LONG Value) +{ + ITextParaImpl *This = impl_from_ITextPara(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextPara_fnGetFirstLineIndent(ITextPara *me, float *pValue) +{ + ITextParaImpl *This = impl_from_ITextPara(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextPara_fnGetKeepTogether(ITextPara *me, LONG *pValue) +{ + ITextParaImpl *This = impl_from_ITextPara(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextPara_fnSetKeepTogether(ITextPara *me, LONG Value) +{ + ITextParaImpl *This = impl_from_ITextPara(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextPara_fnGetKeepWithNext(ITextPara *me, LONG *pValue) +{ + ITextParaImpl *This = impl_from_ITextPara(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextPara_fnSetKeepWithNext(ITextPara *me, LONG Value) +{ + ITextParaImpl *This = impl_from_ITextPara(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextPara_fnGetLeftIndent(ITextPara *me, float *pValue) +{ + ITextParaImpl *This = impl_from_ITextPara(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextPara_fnGetLineSpacing(ITextPara *me, float *pValue) +{ + ITextParaImpl *This = impl_from_ITextPara(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextPara_fnGetLineSpacingRule(ITextPara *me, LONG *pValue) +{ + ITextParaImpl *This = impl_from_ITextPara(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextPara_fnGetListAlignment(ITextPara *me, LONG *pValue) +{ + ITextParaImpl *This = impl_from_ITextPara(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextPara_fnSetListAlignment(ITextPara *me, LONG Value) +{ + ITextParaImpl *This = impl_from_ITextPara(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextPara_fnGetListLevelIndex(ITextPara *me, LONG *pValue) +{ + ITextParaImpl *This = impl_from_ITextPara(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextPara_fnSetListLevelIndex(ITextPara *me, LONG Value) +{ + ITextParaImpl *This = impl_from_ITextPara(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextPara_fnGetListStart(ITextPara *me, LONG *pValue) +{ + ITextParaImpl *This = impl_from_ITextPara(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextPara_fnSetListStart(ITextPara *me, LONG Value) +{ + ITextParaImpl *This = impl_from_ITextPara(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextPara_fnGetListTab(ITextPara *me, float *pValue) +{ + ITextParaImpl *This = impl_from_ITextPara(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextPara_fnSetListTab(ITextPara *me, float Value) +{ + ITextParaImpl *This = impl_from_ITextPara(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextPara_fnGetListType(ITextPara *me, LONG *pValue) +{ + ITextParaImpl *This = impl_from_ITextPara(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextPara_fnSetListType(ITextPara *me, LONG Value) +{ + ITextParaImpl *This = impl_from_ITextPara(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextPara_fnGetNoLineNumber(ITextPara *me, LONG *pValue) +{ + ITextParaImpl *This = impl_from_ITextPara(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextPara_fnSetNoLineNumber(ITextPara *me, LONG Value) +{ + ITextParaImpl *This = impl_from_ITextPara(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextPara_fnGetPageBreakBefore(ITextPara *me, LONG *pValue) +{ + ITextParaImpl *This = impl_from_ITextPara(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextPara_fnSetPageBreakBefore(ITextPara *me, LONG Value) +{ + ITextParaImpl *This = impl_from_ITextPara(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextPara_fnGetRightIndent(ITextPara *me, float *pValue) +{ + ITextParaImpl *This = impl_from_ITextPara(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextPara_fnSetRightIndent(ITextPara *me, float Value) +{ + ITextParaImpl *This = impl_from_ITextPara(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextPara_fnSetIndents(ITextPara *me, float StartIndent, float LeftIndent, + float RightIndent) +{ + ITextParaImpl *This = impl_from_ITextPara(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextPara_fnSetLineSpacing(ITextPara *me, LONG LineSpacingRule, float LineSpacing) +{ + ITextParaImpl *This = impl_from_ITextPara(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextPara_fnGetSpaceAfter(ITextPara *me, float *pValue) +{ + ITextParaImpl *This = impl_from_ITextPara(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextPara_fnSetSpaceAfter(ITextPara *me, float Value) +{ + ITextParaImpl *This = impl_from_ITextPara(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextPara_fnGetSpaceBefore(ITextPara *me, float *pValue) +{ + ITextParaImpl *This = impl_from_ITextPara(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextPara_fnSetSpaceBefore(ITextPara *me, float Value) +{ + ITextParaImpl *This = impl_from_ITextPara(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextPara_fnGetWindowControl(ITextPara *me, LONG *pValue) +{ + ITextParaImpl *This = impl_from_ITextPara(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextPara_fnSetWindowControl(ITextPara *me, LONG Value) +{ + ITextParaImpl *This = impl_from_ITextPara(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextPara_fnGetTabCount(ITextPara *me, LONG *pCount) +{ + ITextParaImpl *This = impl_from_ITextPara(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextPara_fnAddTab(ITextPara *me, float tbPos, LONG tbAlign, LONG tbLeader) +{ + ITextParaImpl *This = impl_from_ITextPara(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextPara_fnClearAllTabs(ITextPara *me) +{ + ITextParaImpl *This = impl_from_ITextPara(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextPara_fnDeleteTab(ITextPara *me, float tbPos) +{ + ITextParaImpl *This = impl_from_ITextPara(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextPara_fnGetTab(ITextPara *me, LONG iTab, float *ptbPos, + LONG *ptbAlign, LONG *ptbLeader) +{ + ITextParaImpl *This = impl_from_ITextPara(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static const ITextParaVtbl tpvt = { + ITextPara_fnQueryInterface, + ITextPara_fnAddRef, + ITextPara_fnRelease, + ITextPara_fnGetTypeInfoCount, + ITextPara_fnGetTypeInfo, + ITextPara_fnGetIDsOfNames, + ITextPara_fnInvoke, + ITextPara_fnGetDuplicate, + ITextPara_fnSetDuplicate, + ITextPara_fnCanChange, + ITextPara_fnIsEqual, + ITextPara_fnReset, + ITextPara_fnGetStyle, + ITextPara_fnSetStyle, + ITextPara_fnGetAlignment, + ITextPara_fnSetAlignment, + ITextPara_fnGetHyphenation, + ITextPara_fnSetHyphenation, + ITextPara_fnGetFirstLineIndent, + ITextPara_fnGetKeepTogether, + ITextPara_fnSetKeepTogether, + ITextPara_fnGetKeepWithNext, + ITextPara_fnSetKeepWithNext, + ITextPara_fnGetLeftIndent, + ITextPara_fnGetLineSpacing, + ITextPara_fnGetLineSpacingRule, + ITextPara_fnGetListAlignment, + ITextPara_fnSetListAlignment, + ITextPara_fnGetListLevelIndex, + ITextPara_fnSetListLevelIndex, + ITextPara_fnGetListStart, + ITextPara_fnSetListStart, + ITextPara_fnGetListTab, + ITextPara_fnSetListTab, + ITextPara_fnGetListType, + ITextPara_fnSetListType, + ITextPara_fnGetNoLineNumber, + ITextPara_fnSetNoLineNumber, + ITextPara_fnGetPageBreakBefore, + ITextPara_fnSetPageBreakBefore, + ITextPara_fnGetRightIndent, + ITextPara_fnSetRightIndent, + ITextPara_fnSetIndents, + ITextPara_fnSetLineSpacing, + ITextPara_fnGetSpaceAfter, + ITextPara_fnSetSpaceAfter, + ITextPara_fnGetSpaceBefore, + ITextPara_fnSetSpaceBefore, + ITextPara_fnGetWindowControl, + ITextPara_fnSetWindowControl, + ITextPara_fnGetTabCount, + ITextPara_fnAddTab, + ITextPara_fnClearAllTabs, + ITextPara_fnDeleteTab, + ITextPara_fnGetTab +}; +/* ITextPara interface */ + +/* ITextFont interface */ +static inline ITextFontImpl *impl_from_ITextFont(ITextFont *iface) +{ + return CONTAINING_RECORD(iface, ITextFontImpl, ITextFont_iface); +} + +static HRESULT WINAPI ITextFont_fnQueryInterface(ITextFont *me, REFIID riid, void **ppvObj) +{ + *ppvObj = NULL; + if (IsEqualGUID(riid, &IID_IUnknown) + || IsEqualGUID(riid, &IID_ITextFont) + || IsEqualGUID(riid, &IID_IDispatch)) + { + *ppvObj = me; + ITextFont_AddRef(me); + return S_OK; + } + + return E_NOINTERFACE; +} + +static ULONG WINAPI ITextFont_fnAddRef(ITextFont *me) +{ + ITextFontImpl *This = impl_from_ITextFont(me); + return InterlockedIncrement(&This->ref); +} + +static ULONG WINAPI ITextFont_fnRelease(ITextFont *me) +{ + ITextFontImpl *This = impl_from_ITextFont(me); + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE ("%p ref=%u\n", This, ref); + if (ref == 0) + { + if (This->txtRge) + ITextRange_Release(&This->txtRge->ITextRange_iface); + else + ITextSelection_Release(&This->txtSel->ITextSelection_iface); + This->txtRge = NULL; + This->txtSel = NULL; + if (This->reOle) + { + list_remove(&This->entry); + This->reOle = NULL; + } + heap_free(This); + } + return ref; +} + +static HRESULT WINAPI ITextFont_fnGetTypeInfoCount(ITextFont *me, UINT *pctinfo) +{ + ITextFontImpl *This = impl_from_ITextFont(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextFont_fnGetTypeInfo(ITextFont *me, UINT iTInfo, LCID lcid, + ITypeInfo **ppTInfo) +{ + ITextFontImpl *This = impl_from_ITextFont(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextFont_fnGetIDsOfNames(ITextFont *me, REFIID riid, + LPOLESTR *rgszNames, UINT cNames, + LCID lcid, DISPID *rgDispId) +{ + ITextFontImpl *This = impl_from_ITextFont(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextFont_fnInvoke(ITextFont *me, DISPID dispIdMember, REFIID riid, + LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, + VARIANT *pVarResult, EXCEPINFO *pExcepInfo, + UINT *puArgErr) +{ + ITextFontImpl *This = impl_from_ITextFont(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextFont_fnGetDuplicate(ITextFont *me, ITextFont **ppFont) +{ + ITextFontImpl *This = impl_from_ITextFont(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextFont_fnSetDuplicate(ITextFont *me, ITextFont *pFont) +{ + ITextFontImpl *This = impl_from_ITextFont(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextFont_fnCanChange(ITextFont *me, LONG *pB) +{ + ITextFontImpl *This = impl_from_ITextFont(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextFont_fnIsEqual(ITextFont *me, ITextFont *pFont, LONG *pB) +{ + ITextFontImpl *This = impl_from_ITextFont(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextFont_fnReset(ITextFont *me, LONG Value) +{ + ITextFontImpl *This = impl_from_ITextFont(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextFont_fnGetStyle(ITextFont *me, LONG *pValue) +{ + ITextFontImpl *This = impl_from_ITextFont(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextFont_fnSetStyle(ITextFont *me, LONG Value) +{ + ITextFontImpl *This = impl_from_ITextFont(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextFont_fnGetAllCaps(ITextFont *me, LONG *pValue) +{ + ITextFontImpl *This = impl_from_ITextFont(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextFont_fnSetAllCaps(ITextFont *me, LONG Value) +{ + ITextFontImpl *This = impl_from_ITextFont(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextFont_fnGetAnimation(ITextFont *me, LONG *pValue) +{ + ITextFontImpl *This = impl_from_ITextFont(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextFont_fnSetAnimation(ITextFont *me, LONG Value) +{ + ITextFontImpl *This = impl_from_ITextFont(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextFont_fnGetBackColor(ITextFont *me, LONG *pValue) +{ + ITextFontImpl *This = impl_from_ITextFont(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextFont_fnSetBackColor(ITextFont *me, LONG Value) +{ + ITextFontImpl *This = impl_from_ITextFont(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextFont_fnGetBold(ITextFont *me, LONG *pValue) +{ + static int once; + ITextFontImpl *This = impl_from_ITextFont(me); + if (!pValue) + return E_INVALIDARG; + if (!This->reOle) + return CO_E_RELEASED; + + if (!once++) FIXME("Stub\n"); + *pValue = tomFalse; + return S_OK; +} + +static HRESULT WINAPI ITextFont_fnSetBold(ITextFont *me, LONG Value) +{ + ITextFontImpl *This = impl_from_ITextFont(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextFont_fnGetEmboss(ITextFont *me, LONG *pValue) +{ + ITextFontImpl *This = impl_from_ITextFont(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextFont_fnSetEmboss(ITextFont *me, LONG Value) +{ + ITextFontImpl *This = impl_from_ITextFont(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextFont_fnGetForeColor(ITextFont *me, LONG *pValue) +{ + static int once; + ITextFontImpl *This = impl_from_ITextFont(me); + if (!pValue) + return E_INVALIDARG; + if (!This->reOle) + return CO_E_RELEASED; + + if (!once++) FIXME("Stub\n"); + *pValue = tomAutoColor; + return S_OK; +} + +static HRESULT WINAPI ITextFont_fnSetForeColor(ITextFont *me, LONG Value) +{ + ITextFontImpl *This = impl_from_ITextFont(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextFont_fnGetHidden(ITextFont *me, LONG *pValue) +{ + ITextFontImpl *This = impl_from_ITextFont(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextFont_fnSetHidden(ITextFont *me, LONG Value) +{ + ITextFontImpl *This = impl_from_ITextFont(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextFont_fnGetEngrave(ITextFont *me, LONG *pValue) +{ + ITextFontImpl *This = impl_from_ITextFont(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextFont_fnSetEngrave(ITextFont *me, LONG Value) +{ + ITextFontImpl *This = impl_from_ITextFont(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextFont_fnGetItalic(ITextFont *me, LONG *pValue) +{ + static int once; + ITextFontImpl *This = impl_from_ITextFont(me); + if (!pValue) + return E_INVALIDARG; + if (!This->reOle) + return CO_E_RELEASED; + + if (!once++) FIXME("Stub\n"); + *pValue = tomFalse; + return S_OK; +} + +static HRESULT WINAPI ITextFont_fnSetItalic(ITextFont *me, LONG Value) +{ + ITextFontImpl *This = impl_from_ITextFont(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextFont_fnGetKerning(ITextFont *me, float *pValue) +{ + ITextFontImpl *This = impl_from_ITextFont(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextFont_fnSetKerning(ITextFont *me, float Value) +{ + ITextFontImpl *This = impl_from_ITextFont(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextFont_fnGetLanguageID(ITextFont *me, LONG *pValue) +{ + static int once; + ITextFontImpl *This = impl_from_ITextFont(me); + if (!This->reOle) + return CO_E_RELEASED; + + if (!once++) FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextFont_fnSetLanguageID(ITextFont *me, LONG Value) +{ + ITextFontImpl *This = impl_from_ITextFont(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextFont_fnGetName(ITextFont *me, BSTR *pValue) +{ + ITextFontImpl *This = impl_from_ITextFont(me); + WCHAR font[] = {'S', 'y', 's', 't', 'e', 'm', 0}; + if (!pValue) + return E_INVALIDARG; + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("Stub\n"); + *pValue = SysAllocString(font); + return S_OK; +} + +static HRESULT WINAPI ITextFont_fnSetName(ITextFont *me, BSTR Value) +{ + ITextFontImpl *This = impl_from_ITextFont(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextFont_fnGetOutline(ITextFont *me, LONG *pValue) +{ + ITextFontImpl *This = impl_from_ITextFont(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextFont_fnSetOutline(ITextFont *me, LONG Value) +{ + ITextFontImpl *This = impl_from_ITextFont(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextFont_fnGetPosition(ITextFont *me, float *pValue) +{ + ITextFontImpl *This = impl_from_ITextFont(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextFont_fnSetPosition(ITextFont *me, float Value) +{ + ITextFontImpl *This = impl_from_ITextFont(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextFont_fnGetProtected(ITextFont *me, LONG *pValue) +{ + ITextFontImpl *This = impl_from_ITextFont(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextFont_fnSetProtected(ITextFont *me, LONG Value) +{ + ITextFontImpl *This = impl_from_ITextFont(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextFont_fnGetShadow(ITextFont *me, LONG *pValue) +{ + ITextFontImpl *This = impl_from_ITextFont(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextFont_fnSetShadow(ITextFont *me, LONG Value) +{ + ITextFontImpl *This = impl_from_ITextFont(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextFont_fnGetSize(ITextFont *me, float *pValue) +{ + static int once; + ITextFontImpl *This = impl_from_ITextFont(me); + if (!pValue) + return E_INVALIDARG; + if (!This->reOle) + return CO_E_RELEASED; + + if (!once++) FIXME("Stub\n"); + *pValue = 12.0; + return S_OK; +} + +static HRESULT WINAPI ITextFont_fnSetSize(ITextFont *me, float Value) +{ + ITextFontImpl *This = impl_from_ITextFont(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextFont_fnGetSmallCaps(ITextFont *me, LONG *pValue) +{ + ITextFontImpl *This = impl_from_ITextFont(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextFont_fnSetSmallCaps(ITextFont *me, LONG Value) +{ + ITextFontImpl *This = impl_from_ITextFont(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextFont_fnGetSpacing(ITextFont *me, float *pValue) +{ + ITextFontImpl *This = impl_from_ITextFont(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextFont_fnSetSpacing(ITextFont *me, float Value) +{ + ITextFontImpl *This = impl_from_ITextFont(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextFont_fnGetStrikeThrough(ITextFont *me, LONG *pValue) +{ + static int once; + ITextFontImpl *This = impl_from_ITextFont(me); + if (!pValue) + return E_INVALIDARG; + if (!This->reOle) + return CO_E_RELEASED; + + if (!once++) FIXME("Stub\n"); + *pValue = tomFalse; + return S_OK; +} + +static HRESULT WINAPI ITextFont_fnSetStrikeThrough(ITextFont *me, LONG Value) +{ + ITextFontImpl *This = impl_from_ITextFont(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextFont_fnGetSubscript(ITextFont *me, LONG *pValue) +{ + static int once; + ITextFontImpl *This = impl_from_ITextFont(me); + if (!pValue) + return E_INVALIDARG; + if (!This->reOle) + return CO_E_RELEASED; + + if (!once++) FIXME("Stub\n"); + *pValue = tomFalse; + return S_OK; +} + +static HRESULT WINAPI ITextFont_fnSetSubscript(ITextFont *me, LONG Value) +{ + ITextFontImpl *This = impl_from_ITextFont(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextFont_fnGetSuperscript(ITextFont *me, LONG *pValue) +{ + ITextFontImpl *This = impl_from_ITextFont(me); + if (pValue) + return E_INVALIDARG; + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("Stub\n"); + *pValue = tomFalse; + return S_OK; +} + +static HRESULT WINAPI ITextFont_fnSetSuperscript(ITextFont *me, LONG Value) +{ + ITextFontImpl *This = impl_from_ITextFont(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextFont_fnGetUnderline(ITextFont *me, LONG *pValue) +{ + static int once; + ITextFontImpl *This = impl_from_ITextFont(me); + if (!pValue) + return E_INVALIDARG; + if (!This->reOle) + return CO_E_RELEASED; + + if (!once++) FIXME("Stub\n"); + *pValue = tomNone; + return S_OK; +} + +static HRESULT WINAPI ITextFont_fnSetUnderline(ITextFont *me, LONG Value) +{ + ITextFontImpl *This = impl_from_ITextFont(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextFont_fnGetWeight(ITextFont *me, LONG *pValue) +{ + static int once; + ITextFontImpl *This = impl_from_ITextFont(me); + if (!This->reOle) + return CO_E_RELEASED; + + if (!once++) FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextFont_fnSetWeight(ITextFont *me, LONG Value) +{ + ITextFontImpl *This = impl_from_ITextFont(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented: %p\n", This); + return E_NOTIMPL; +} + +static const ITextFontVtbl tfvt = { + ITextFont_fnQueryInterface, + ITextFont_fnAddRef, + ITextFont_fnRelease, + ITextFont_fnGetTypeInfoCount, + ITextFont_fnGetTypeInfo, + ITextFont_fnGetIDsOfNames, + ITextFont_fnInvoke, + ITextFont_fnGetDuplicate, + ITextFont_fnSetDuplicate, + ITextFont_fnCanChange, + ITextFont_fnIsEqual, + ITextFont_fnReset, + ITextFont_fnGetStyle, + ITextFont_fnSetStyle, + ITextFont_fnGetAllCaps, + ITextFont_fnSetAllCaps, + ITextFont_fnGetAnimation, + ITextFont_fnSetAnimation, + ITextFont_fnGetBackColor, + ITextFont_fnSetBackColor, + ITextFont_fnGetBold, + ITextFont_fnSetBold, + ITextFont_fnGetEmboss, + ITextFont_fnSetEmboss, + ITextFont_fnGetForeColor, + ITextFont_fnSetForeColor, + ITextFont_fnGetHidden, + ITextFont_fnSetHidden, + ITextFont_fnGetEngrave, + ITextFont_fnSetEngrave, + ITextFont_fnGetItalic, + ITextFont_fnSetItalic, + ITextFont_fnGetKerning, + ITextFont_fnSetKerning, + ITextFont_fnGetLanguageID, + ITextFont_fnSetLanguageID, + ITextFont_fnGetName, + ITextFont_fnSetName, + ITextFont_fnGetOutline, + ITextFont_fnSetOutline, + ITextFont_fnGetPosition, + ITextFont_fnSetPosition, + ITextFont_fnGetProtected, + ITextFont_fnSetProtected, + ITextFont_fnGetShadow, + ITextFont_fnSetShadow, + ITextFont_fnGetSize, + ITextFont_fnSetSize, + ITextFont_fnGetSmallCaps, + ITextFont_fnSetSmallCaps, + ITextFont_fnGetSpacing, + ITextFont_fnSetSpacing, + ITextFont_fnGetStrikeThrough, + ITextFont_fnSetStrikeThrough, + ITextFont_fnGetSubscript, + ITextFont_fnSetSubscript, + ITextFont_fnGetSuperscript, + ITextFont_fnSetSuperscript, + ITextFont_fnGetUnderline, + ITextFont_fnSetUnderline, + ITextFont_fnGetWeight, + ITextFont_fnSetWeight +}; +/* ITextFont interface */ + /* ITextRange interface */ static inline ITextRangeImpl *impl_from_ITextRange(ITextRange *iface) { @@ -535,14 +1997,40 @@ return E_NOTIMPL; } +static HRESULT range_GetText(ME_TextEditor *editor, ME_Cursor *start, ME_Cursor *end, BSTR *pbstr) +{ + int nChars, endOfs; + BOOL bEOP; + + endOfs = ME_GetCursorOfs(end); + nChars = endOfs - ME_GetCursorOfs(start); + if (!nChars) + { + *pbstr = NULL; + return S_OK; + } + + *pbstr = SysAllocStringLen(NULL, nChars); + if (!*pbstr) + return E_OUTOFMEMORY; + + bEOP = (end->pRun->next->type == diTextEnd && endOfs > ME_GetTextLength(editor)); + ME_GetTextW(editor, *pbstr, nChars, start, nChars, FALSE, bEOP); + TRACE("%s\n", wine_dbgstr_w(*pbstr)); + + return S_OK; +} + static HRESULT WINAPI ITextRange_fnGetText(ITextRange *me, BSTR *pbstr) { ITextRangeImpl *This = impl_from_ITextRange(me); - if (!This->reOle) - return CO_E_RELEASED; - - FIXME("not implemented %p\n", This); - return E_NOTIMPL; + ME_Cursor start, end; + if (!This->reOle) + return CO_E_RELEASED; + + ME_CursorFromCharOfs(This->reOle->editor, This->start, &start); + ME_CursorFromCharOfs(This->reOle->editor, This->end, &end); + return range_GetText(This->reOle->editor, &start, &end, pbstr); } static HRESULT WINAPI ITextRange_fnSetText(ITextRange *me, BSTR bstr) @@ -638,14 +2126,27 @@ return S_OK; } +static HRESULT range_SetStart(ME_TextEditor *editor, LONG cpFirst, LONG *start, LONG *end) +{ + int len = ME_GetTextLength(editor); + + TRACE("%d\n", cpFirst); + if (cpFirst == *start) + return S_FALSE; + cpFirst = min(cpFirst, len); + cpFirst = max(cpFirst, 0); + *end = max(*end, cpFirst); + *start = cpFirst; + return S_OK; +} + static HRESULT WINAPI ITextRange_fnSetStart(ITextRange *me, LONG cpFirst) { ITextRangeImpl *This = impl_from_ITextRange(me); if (!This->reOle) return CO_E_RELEASED; - FIXME("not implemented %p\n", This); - return E_NOTIMPL; + return range_SetStart(This->reOle->editor, cpFirst, &This->start, &This->end); } static HRESULT WINAPI ITextRange_fnGetEnd(ITextRange *me, LONG *pcpLim) @@ -661,17 +2162,116 @@ return S_OK; } +static HRESULT range_SetEnd(ME_TextEditor *editor, LONG cpLim, LONG *start, LONG *end) +{ + int len = ME_GetTextLength(editor) + 1; + + TRACE("%d\n", cpLim); + if (cpLim == *end) + return S_FALSE; + cpLim = min(cpLim, len); + cpLim = max(cpLim, 0); + *start = min(*start, cpLim); + *end = cpLim; + return S_OK; +} + static HRESULT WINAPI ITextRange_fnSetEnd(ITextRange *me, LONG cpLim) { ITextRangeImpl *This = impl_from_ITextRange(me); if (!This->reOle) return CO_E_RELEASED; + return range_SetEnd(This->reOle->editor, cpLim, &This->start, &This->end); +} + +static HRESULT CreateITextFont(IRichEditOleImpl *reOle, ITextFontImpl **ptxtFont) +{ + ITextFontImpl *txtFont = NULL; + txtFont = heap_alloc(sizeof(ITextFontImpl)); + if (!txtFont) + return E_OUTOFMEMORY; + + txtFont->ITextFont_iface.lpVtbl = &tfvt; + txtFont->ref = 1; + txtFont->reOle = reOle; + list_add_head(&reOle->fontlist, &txtFont->entry); + *ptxtFont = txtFont; + return S_OK; +} + +static HRESULT WINAPI ITextRange_fnGetFont(ITextRange *me, ITextFont **pFont) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + ITextFontImpl *txtFont = NULL; + HRESULT hres; + + if (!This->reOle) + return CO_E_RELEASED; + + TRACE("%p\n", This); + if (!pFont) + return E_INVALIDARG; + hres = CreateITextFont(This->reOle, &txtFont); + if (!hres) + { + txtFont->txtSel = NULL; + txtFont->txtRge = This; + ITextRange_AddRef(me); + *pFont = &txtFont->ITextFont_iface; + } + return hres; +} + +static HRESULT WINAPI ITextRange_fnSetFont(ITextRange *me, ITextFont *pFont) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + FIXME("not implemented %p\n", This); return E_NOTIMPL; } -static HRESULT WINAPI ITextRange_fnGetFont(ITextRange *me, ITextFont **pFont) +static HRESULT CreateITextPara(IRichEditOleImpl *reOle, ITextParaImpl **ptxtPara) +{ + ITextParaImpl *txtPara = NULL; + txtPara = heap_alloc(sizeof(ITextParaImpl)); + if (!txtPara) + return E_OUTOFMEMORY; + + txtPara->ITextPara_iface.lpVtbl = &tpvt; + txtPara->ref = 1; + txtPara->reOle = reOle; + list_add_head(&reOle->paralist, &txtPara->entry); + *ptxtPara = txtPara; + return S_OK; +} + +static HRESULT WINAPI ITextRange_fnGetPara(ITextRange *me, ITextPara **ppPara) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + ITextParaImpl *txtPara = NULL; + HRESULT hres; + + if (!This->reOle) + return CO_E_RELEASED; + + TRACE("%p\n", This); + if (!ppPara) + return E_INVALIDARG; + hres = CreateITextPara(This->reOle, &txtPara); + if (!hres) + { + txtPara->txtSel = NULL; + txtPara->txtRge = This; + ITextRange_AddRef(me); + *ppPara = &txtPara->ITextPara_iface; + } + return hres; +} + +static HRESULT WINAPI ITextRange_fnSetPara(ITextRange *me, ITextPara *pPara) { ITextRangeImpl *This = impl_from_ITextRange(me); if (!This->reOle) @@ -681,44 +2281,16 @@ return E_NOTIMPL; } -static HRESULT WINAPI ITextRange_fnSetFont(ITextRange *me, ITextFont *pFont) -{ - ITextRangeImpl *This = impl_from_ITextRange(me); - if (!This->reOle) - return CO_E_RELEASED; - - FIXME("not implemented %p\n", This); - return E_NOTIMPL; -} - -static HRESULT WINAPI ITextRange_fnGetPara(ITextRange *me, ITextPara **ppPara) -{ - ITextRangeImpl *This = impl_from_ITextRange(me); - if (!This->reOle) - return CO_E_RELEASED; - - FIXME("not implemented %p\n", This); - return E_NOTIMPL; -} - -static HRESULT WINAPI ITextRange_fnSetPara(ITextRange *me, ITextPara *pPara) -{ - ITextRangeImpl *This = impl_from_ITextRange(me); - if (!This->reOle) - return CO_E_RELEASED; - - FIXME("not implemented %p\n", This); - return E_NOTIMPL; -} - static HRESULT WINAPI ITextRange_fnGetStoryLength(ITextRange *me, LONG *pcch) { ITextRangeImpl *This = impl_from_ITextRange(me); if (!This->reOle) return CO_E_RELEASED; - FIXME("not implemented %p\n", This); - return E_NOTIMPL; + if (!pcch) + return E_INVALIDARG; + *pcch = ME_GetTextLength(This->reOle->editor) + 1; + return S_OK; } static HRESULT WINAPI ITextRange_fnGetStoryType(ITextRange *me, LONG *pValue) @@ -783,17 +2355,49 @@ return E_NOTIMPL; } +static void cp2range(ME_TextEditor *editor, LONG *cp1, LONG *cp2) +{ + int len = ME_GetTextLength(editor) + 1; + *cp1 = max(*cp1, 0); + *cp2 = max(*cp2, 0); + *cp1 = min(*cp1, len); + *cp2 = min(*cp2, len); + if (*cp1 > *cp2) + { + int tmp = *cp1; + *cp1 = *cp2; + *cp2 = tmp; + } + if (*cp1 == len) + *cp1 = *cp2 = len - 1; +} + static HRESULT WINAPI ITextRange_fnSetRange(ITextRange *me, LONG cpActive, LONG cpOther) { ITextRangeImpl *This = impl_from_ITextRange(me); if (!This->reOle) return CO_E_RELEASED; + cp2range(This->reOle->editor, &cpActive, &cpOther); + if (cpActive == This->start && cpOther == This->end) + return S_FALSE; + + This->start = cpActive; + This->end = cpOther; + return S_OK; +} + +static HRESULT WINAPI ITextRange_fnInRange(ITextRange *me, ITextRange *pRange, LONG *pb) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + FIXME("not implemented %p\n", This); return E_NOTIMPL; } -static HRESULT WINAPI ITextRange_fnInRange(ITextRange *me, ITextRange *pRange, LONG *pb) +static HRESULT WINAPI ITextRange_fnInStory(ITextRange *me, ITextRange *pRange, LONG *pb) { ITextRangeImpl *This = impl_from_ITextRange(me); if (!This->reOle) @@ -803,14 +2407,18 @@ return E_NOTIMPL; } -static HRESULT WINAPI ITextRange_fnInStory(ITextRange *me, ITextRange *pRange, LONG *pb) -{ - ITextRangeImpl *This = impl_from_ITextRange(me); - if (!This->reOle) - return CO_E_RELEASED; - - FIXME("not implemented %p\n", This); - return E_NOTIMPL; +static HRESULT range_IsEqual(LONG start, LONG end, ITextRange *pRange, LONG *pb) +{ + ITextRangeImpl *pRangeImpl = impl_from_ITextRange(pRange); + if (start == pRangeImpl->start && end == pRangeImpl->end) + { + if (pb) + *pb = tomTrue; + return S_OK; + } + if (pb) + *pb = tomFalse; + return S_FALSE; } static HRESULT WINAPI ITextRange_fnIsEqual(ITextRange *me, ITextRange *pRange, LONG *pb) @@ -819,8 +2427,9 @@ if (!This->reOle) return CO_E_RELEASED; - FIXME("not implemented %p\n", This); - return E_NOTIMPL; + if (!pRange) + return S_FALSE; + return range_IsEqual(This->start, This->end, pRange, pb); } static HRESULT WINAPI ITextRange_fnSelect(ITextRange *me) @@ -1385,26 +2994,12 @@ ITextRange** ppRange) { IRichEditOleImpl *This = impl_from_ITextDocument(me); - const int len = ME_GetTextLength(This->editor) + 1; TRACE("%p %p %d %d\n", This, ppRange, cp1, cp2); if (!ppRange) return E_INVALIDARG; - cp1 = max(cp1, 0); - cp2 = max(cp2, 0); - cp1 = min(cp1, len); - cp2 = min(cp2, len); - if (cp1 > cp2) - { - LONG tmp; - tmp = cp1; - cp1 = cp2; - cp2 = tmp; - } - if (cp1 == len) - cp1 = cp2 = len - 1; - + cp2range(This->editor, &cp1, &cp2); return CreateITextRange(This, cp1, cp2, ppRange); } @@ -1537,8 +3132,6 @@ { ITextSelectionImpl *This = impl_from_ITextSelection(me); ME_Cursor *start = NULL, *end = NULL; - int nChars, endOfs; - BOOL bEOP; if (!This->reOle) return CO_E_RELEASED; @@ -1547,23 +3140,7 @@ return E_INVALIDARG; ME_GetSelection(This->reOle->editor, &start, &end); - endOfs = ME_GetCursorOfs(end); - nChars = endOfs - ME_GetCursorOfs(start); - if (!nChars) - { - *pbstr = NULL; - return S_OK; - } - - *pbstr = SysAllocStringLen(NULL, nChars); - if (!*pbstr) - return E_OUTOFMEMORY; - - bEOP = (end->pRun->next->type == diTextEnd && endOfs > ME_GetTextLength(This->reOle->editor)); - ME_GetTextW(This->reOle->editor, *pbstr, nChars, start, nChars, FALSE, bEOP); - TRACE("%s\n", wine_dbgstr_w(*pbstr)); - - return S_OK; + return range_GetText(This->reOle->editor, start, end, pbstr); } static HRESULT WINAPI ITextSelection_fnSetText(ITextSelection *me, BSTR bstr) @@ -1604,11 +3181,17 @@ static HRESULT WINAPI ITextSelection_fnGetDuplicate(ITextSelection *me, ITextRange **ppRange) { ITextSelectionImpl *This = impl_from_ITextSelection(me); - if (!This->reOle) - return CO_E_RELEASED; - - FIXME("not implemented\n"); - return E_NOTIMPL; + int start, end; + + if (!This->reOle) + return CO_E_RELEASED; + + TRACE("%p %p\n", This, ppRange); + if (!ppRange) + return E_INVALIDARG; + + ME_GetSelectionOfs(This->reOle->editor, &start, &end); + return CreateITextRange(This->reOle, start, end, ppRange); } static HRESULT WINAPI ITextSelection_fnGetFormattedText(ITextSelection *me, ITextRange **ppRange) @@ -1648,11 +3231,16 @@ static HRESULT WINAPI ITextSelection_fnSetStart(ITextSelection *me, LONG cpFirst) { ITextSelectionImpl *This = impl_from_ITextSelection(me); - if (!This->reOle) - return CO_E_RELEASED; - - FIXME("not implemented\n"); - return E_NOTIMPL; + int start, end; + HRESULT hres; + if (!This->reOle) + return CO_E_RELEASED; + + ME_GetSelectionOfs(This->reOle->editor, &start, &end); + hres = range_SetStart(This->reOle->editor, cpFirst, &start, &end); + if (!hres) + ME_SetSelection(This->reOle->editor, start, end); + return hres; } static HRESULT WINAPI ITextSelection_fnGetEnd(ITextSelection *me, LONG *pcpLim) @@ -1672,21 +3260,39 @@ static HRESULT WINAPI ITextSelection_fnSetEnd(ITextSelection *me, LONG cpLim) { ITextSelectionImpl *This = impl_from_ITextSelection(me); - if (!This->reOle) - return CO_E_RELEASED; - - FIXME("not implemented\n"); - return E_NOTIMPL; + int start, end; + HRESULT hres; + if (!This->reOle) + return CO_E_RELEASED; + + ME_GetSelectionOfs(This->reOle->editor, &start, &end); + hres = range_SetEnd(This->reOle->editor, cpLim, &start, &end); + if (!hres) + ME_SetSelection(This->reOle->editor, start, end); + return hres; } static HRESULT WINAPI ITextSelection_fnGetFont(ITextSelection *me, ITextFont **pFont) { ITextSelectionImpl *This = impl_from_ITextSelection(me); - if (!This->reOle) - return CO_E_RELEASED; - - FIXME("not implemented\n"); - return E_NOTIMPL; + ITextFontImpl *txtFont = NULL; + HRESULT hres; + + if (!This->reOle) + return CO_E_RELEASED; + + TRACE("%p\n", This); + if (!pFont) + return E_INVALIDARG; + hres = CreateITextFont(This->reOle, &txtFont); + if (!hres) + { + txtFont->txtSel = This; + txtFont->txtRge = NULL; + ITextSelection_AddRef(me); + *pFont = &txtFont->ITextFont_iface; + } + return hres; } static HRESULT WINAPI ITextSelection_fnSetFont(ITextSelection *me, ITextFont *pFont) @@ -1725,8 +3331,10 @@ if (!This->reOle) return CO_E_RELEASED; - FIXME("not implemented\n"); - return E_NOTIMPL; + if (!pcch) + return E_INVALIDARG; + *pcch = ME_GetTextLength(This->reOle->editor) + 1; + return S_OK; } static HRESULT WINAPI ITextSelection_fnGetStoryType(ITextSelection *me, LONG *pValue) @@ -2292,7 +3900,7 @@ return txtSel; } -LRESULT CreateIRichEditOle(ME_TextEditor *editor, LPVOID *ppObj) +LRESULT CreateIRichEditOle(IUnknown *outer_unk, ME_TextEditor *editor, LPVOID *ppvObj) { IRichEditOleImpl *reo; @@ -2300,6 +3908,7 @@ if (!reo) return 0; + reo->IUnknown_inner.lpVtbl = &reo_unk_vtbl; reo->IRichEditOle_iface.lpVtbl = &revt; reo->ITextDocument_iface.lpVtbl = &tdvt; reo->ref = 1; @@ -2318,8 +3927,14 @@ return 0; } TRACE("Created %p\n",reo); - *ppObj = reo; list_init(&reo->rangelist); + list_init(&reo->fontlist); + list_init(&reo->paralist); + if (outer_unk) + reo->outer_unk = outer_unk; + else + reo->outer_unk = &reo->IUnknown_inner; + *ppvObj = &reo->IRichEditOle_iface; return 1; } @@ -2527,3 +4142,9 @@ if (dst->pstg) IStorage_AddRef(dst->pstg); if (dst->polesite) IOleClientSite_AddRef(dst->polesite); } + +void ME_GetITextDocumentInterface(IRichEditOle *iface, LPVOID *ppvObj) +{ + IRichEditOleImpl *This = impl_from_IRichEditOle(iface); + *ppvObj = &This->ITextDocument_iface; +} Modified: trunk/reactos/dll/win32/riched20/run.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/riched20/run.c?r…
============================================================================== --- trunk/reactos/dll/win32/riched20/run.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/riched20/run.c [iso-8859-1] Mon Apr 6 17:44:48 2015 @@ -181,9 +181,10 @@ int *pOfs) { ME_DisplayItem *item, *next_item; + int endOfs = nCharOfs, len = ME_GetTextLength(editor); nCharOfs = max(nCharOfs, 0); - nCharOfs = min(nCharOfs, ME_GetTextLength(editor)); + nCharOfs = min(nCharOfs, len); /* Find the paragraph at the offset. */ next_item = editor->pBuffer->pFirst->member.para.next_para; @@ -206,7 +207,11 @@ nCharOfs -= item->member.run.nCharOfs; if (ppRun) *ppRun = item; - if (pOfs) *pOfs = nCharOfs; + if (pOfs) { + if (((*ppRun)->member.run.nFlags & MERF_ENDPARA) && endOfs > len) + *pOfs = (*ppRun)->member.run.len; + else *pOfs = nCharOfs; + } } /****************************************************************************** Modified: trunk/reactos/dll/win32/riched20/txtsrv.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/riched20/txtsrv.…
============================================================================== --- trunk/reactos/dll/win32/riched20/txtsrv.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/riched20/txtsrv.c [iso-8859-1] Mon Apr 6 17:44:48 2015 @@ -20,6 +20,7 @@ #include "editor.h" + #ifdef __i386__ /* thiscall functions are i386-specific */ #define THISCALL(func) __thiscall_ ## func @@ -65,7 +66,15 @@ *ppv = &This->IUnknown_inner; else if (IsEqualIID(riid, &IID_ITextServices)) *ppv = &This->ITextServices_iface; - else { + else if (IsEqualIID(riid, &IID_IRichEditOle) || IsEqualIID(riid, &IID_ITextDocument)) { + if (!This->editor->reOle) + if (!CreateIRichEditOle(This->outer_unk, This->editor, (void **)(&This->editor->reOle))) + return E_OUTOFMEMORY; + if (IsEqualIID(riid, &IID_ITextDocument)) + ME_GetITextDocumentInterface(This->editor->reOle, ppv); + else + *ppv = This->editor->reOle; + } else { *ppv = NULL; FIXME("Unknown interface: %s\n", debugstr_guid(riid)); return E_NOINTERFACE; @@ -94,7 +103,7 @@ if (!ref) { - ITextHost_Release(This->pMyHost); + ME_DestroyEditor(This->editor); This->csTxtSrv.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&This->csTxtSrv); CoTaskMemFree(This); Modified: trunk/reactos/media/doc/README.WINE URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/media/doc/README.WINE?rev=…
============================================================================== --- trunk/reactos/media/doc/README.WINE [iso-8859-1] (original) +++ trunk/reactos/media/doc/README.WINE [iso-8859-1] Mon Apr 6 17:44:48 2015 @@ -170,7 +170,7 @@ reactos/dll/win32/query # Synced to Wine-1.7.27 reactos/dll/win32/rasapi32 # Synced to Wine-1.7.27 reactos/dll/win32/resutils # Synced to Wine-1.7.27 -reactos/dll/win32/riched20 # Synced to Wine-1.7.27 +reactos/dll/win32/riched20 # Synced to WineStaging-1.7.37 reactos/dll/win32/riched32 # Synced to Wine-1.7.27 reactos/dll/win32/rpcrt4 # Synced to Wine-1.7.17 reactos/dll/win32/rsabase # Synced to Wine-1.7.27
9 years, 8 months
1
0
0
0
[tfaber] 67071: [RPCRT4] - Avoid double free introduced in r63605. CORE-8200
by tfaber@svn.reactos.org
Author: tfaber Date: Mon Apr 6 08:57:12 2015 New Revision: 67071 URL:
http://svn.reactos.org/svn/reactos?rev=67071&view=rev
Log: [RPCRT4] - Avoid double free introduced in r63605. CORE-8200 Modified: trunk/reactos/dll/win32/rpcrt4/ndr_stubless.c Modified: trunk/reactos/dll/win32/rpcrt4/ndr_stubless.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/rpcrt4/ndr_stubl…
============================================================================== --- trunk/reactos/dll/win32/rpcrt4/ndr_stubless.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/rpcrt4/ndr_stubless.c [iso-8859-1] Mon Apr 6 08:57:12 2015 @@ -1109,7 +1109,9 @@ call_marshaller(pStubMsg, pArg, ¶ms[i]); break; case STUBLESS_FREE: - if (params[i].attr.ServerAllocSize) + if (params[i].attr.MustFree) + break; + else if (params[i].attr.ServerAllocSize) { HeapFree(GetProcessHeap(), 0, *(void **)pArg); }
9 years, 8 months
1
0
0
0
[tfaber] 67070: [USER32_APITEST] - Rename CreateWindowEx test to SetParent since that's what it tests
by tfaber@svn.reactos.org
Author: tfaber Date: Mon Apr 6 06:34:04 2015 New Revision: 67070 URL:
http://svn.reactos.org/svn/reactos?rev=67070&view=rev
Log: [USER32_APITEST] - Rename CreateWindowEx test to SetParent since that's what it tests Added: trunk/rostests/apitests/user32/SetParent.c - copied, changed from r67058, trunk/rostests/apitests/user32/CreateWindowEx.c Removed: trunk/rostests/apitests/user32/CreateWindowEx.c Modified: trunk/rostests/apitests/user32/CMakeLists.txt trunk/rostests/apitests/user32/testlist.c Modified: trunk/rostests/apitests/user32/CMakeLists.txt URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/user32/CMakeList…
============================================================================== --- trunk/rostests/apitests/user32/CMakeLists.txt [iso-8859-1] (original) +++ trunk/rostests/apitests/user32/CMakeLists.txt [iso-8859-1] Mon Apr 6 06:34:04 2015 @@ -3,7 +3,6 @@ AttachThreadInput.c helper.c CreateIconFromResourceEx.c - CreateWindowEx.c DeferWindowPos.c DestroyCursorIcon.c DrawIconEx.c @@ -24,6 +23,7 @@ SendMessageTimeout.c SetActiveWindow.c SetCursorPos.c + SetParent.c SystemParametersInfo.c TrackMouseEvent.c WndProc.c Removed: trunk/rostests/apitests/user32/CreateWindowEx.c URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/user32/CreateWin…
============================================================================== --- trunk/rostests/apitests/user32/CreateWindowEx.c [iso-8859-1] (original) +++ trunk/rostests/apitests/user32/CreateWindowEx.c (removed) @@ -1,189 +0,0 @@ -/* - * PROJECT: ReactOS API tests - * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory - * PURPOSE: Test for CreateWindow stuff - * PROGRAMMERS: Thomas Faber <thomas.faber(a)reactos.org> - */ - -#include <apitest.h> - -#include <winuser.h> -#include "helper.h" - -static HWND hWndList[5 + 1]; -static const int hWndCount = sizeof(hWndList) / sizeof(hWndList[0]) - 1; -static DWORD dwThreadId; - -#define ok_hwnd(val, exp) do \ - { \ - HWND _val = (val), _exp = (exp); \ - int _ival = get_iwnd(_val, FALSE); \ - int _iexp = get_iwnd(_exp, FALSE); \ - ok(_val == _exp, #val " = %p (%d), expected %p (%d)\n", _val, _ival, _exp, _iexp); \ - } while (0) - -static -int -get_iwnd( - _In_ HWND hWnd, - _In_ BOOL set) -{ - int i; - if (!hWnd) - return 0; - for (i = 1; i <= hWndCount; i++) - { - if (hWndList[i] == hWnd) - return i; - } - if (!set) - return 0; - for (i = 1; i <= hWndCount; i++) - { - if (hWndList[i] == NULL) - { - hWndList[i] = hWnd; - return i; - } - } - ok(0, "Too many windows!\n"); - return 0; -} - -static -BOOL -CALLBACK -EnumProc( - _In_ HWND hWnd, - _In_ LPARAM lParam) -{ - HWND hLookingFor = (HWND)lParam; - return hWnd != hLookingFor; -} - -static -LRESULT -CALLBACK -WndProc( - _In_ HWND hWnd, - _In_ UINT message, - _In_ WPARAM wParam, - _In_ LPARAM lParam) -{ - HWND hTest; - int iwnd = get_iwnd(hWnd, TRUE); - - ok(GetCurrentThreadId() == dwThreadId, "Thread 0x%lx instead of 0x%lx\n", GetCurrentThreadId(), dwThreadId); - if (message > WM_USER || IsDWmMsg(message) || IseKeyMsg(message)) - return DefWindowProcW(hWnd, message, wParam, lParam); - - RECOND_MESSAGE(iwnd, message, SENT, wParam, lParam); - - switch(message) - { - case WM_DESTROY: - if (GetParent(hWnd)) - { - /* child window */ - ok(EnumThreadWindows(dwThreadId, EnumProc, (LPARAM)hWnd), "Child window %p (%d) enumerated\n", hWnd, iwnd); - ok(!EnumChildWindows(GetParent(hWnd), EnumProc, (LPARAM)hWnd), "Child window %p (%d) not enumerated\n", hWnd, iwnd); - ok(!EnumThreadWindows(dwThreadId, EnumProc, (LPARAM)GetParent(hWnd)), "Parent window of %p (%d) not enumerated\n", hWnd, iwnd); - } - else - { - /* top-level window */ - ok(!EnumThreadWindows(dwThreadId, EnumProc, (LPARAM)hWnd), "Window %p (%d) not enumerated in WM_DESTROY\n", hWnd, iwnd); - } - if (hWnd == hWndList[3]) - { - hTest = SetParent(hWndList[4], hWndList[2]); - ok_hwnd(hTest, hWndList[1]); - hTest = SetParent(hWndList[5], hWndList[1]); - ok_hwnd(hTest, hWndList[2]); - - ok_hwnd(GetParent(hWndList[1]), NULL); - ok_hwnd(GetParent(hWndList[2]), NULL); - ok_hwnd(GetParent(hWndList[3]), hWndList[1]); - ok_hwnd(GetParent(hWndList[4]), hWndList[2]); - ok_hwnd(GetParent(hWndList[5]), hWndList[1]); - } - break; - } - - return DefWindowProcW(hWnd, message, wParam, lParam); -} - - -START_TEST(CreateWindowEx) -{ - HWND hWnd; - MSG msg; - - SetCursorPos(0,0); - - dwThreadId = GetCurrentThreadId(); - hWndList[0] = INVALID_HANDLE_VALUE; - RegisterSimpleClass(WndProc, L"CreateTest"); - - hWnd = CreateWindowExW(0, L"CreateTest", NULL, 0, 10, 10, 20, 20, NULL, NULL, 0, NULL); - ok(hWnd != NULL, "CreateWindow failed\n"); - ok(hWnd == hWndList[1], "Got %p, expected %p\n", hWnd, hWndList[1]); - - hWnd = CreateWindowExW(0, L"CreateTest", NULL, 0, 40, 10, 20, 20, NULL, NULL, 0, NULL); - ok(hWnd != NULL, "CreateWindow failed\n"); - ok(hWnd == hWndList[2], "Got %p, expected %p\n", hWnd, hWndList[2]); - - hWnd = CreateWindowExW(0, L"CreateTest", NULL, WS_CHILD, 60, 10, 20, 20, hWndList[1], NULL, 0, NULL); - ok(hWnd != NULL, "CreateWindow failed\n"); - ok(hWnd == hWndList[3], "Got %p, expected %p\n", hWnd, hWndList[3]); - - hWnd = CreateWindowExW(0, L"CreateTest", NULL, WS_CHILD, 80, 10, 20, 20, hWndList[1], NULL, 0, NULL); - ok(hWnd != NULL, "CreateWindow failed\n"); - ok(hWnd == hWndList[4], "Got %p, expected %p\n", hWnd, hWndList[4]); - - hWnd = CreateWindowExW(0, L"CreateTest", NULL, WS_CHILD, 60, 10, 20, 20, hWndList[2], NULL, 0, NULL); - ok(hWnd != NULL, "CreateWindow failed\n"); - ok(hWnd == hWndList[5], "Got %p, expected %p\n", hWnd, hWndList[5]); - -trace("\n"); - while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) - { - int iwnd = get_iwnd(msg.hwnd, FALSE); - if(!(msg.message > WM_USER || IsDWmMsg(msg.message) || IseKeyMsg(msg.message))) - RECOND_MESSAGE(iwnd, msg.message, POST, 0, 0); - DispatchMessageA( &msg ); - } -trace("\n"); - TRACE_CACHE(); -trace("\n"); - - ok_hwnd(GetParent(hWndList[1]), NULL); - ok_hwnd(GetParent(hWndList[2]), NULL); - ok_hwnd(GetParent(hWndList[3]), hWndList[1]); - ok_hwnd(GetParent(hWndList[4]), hWndList[1]); - ok_hwnd(GetParent(hWndList[5]), hWndList[2]); - - DestroyWindow(hWndList[1]); - ok(!IsWindow(hWndList[1]), "\n"); - ok( IsWindow(hWndList[2]), "\n"); - ok(!IsWindow(hWndList[3]), "\n"); - ok( IsWindow(hWndList[4]), "\n"); - ok(!IsWindow(hWndList[5]), "\n"); - - ok_hwnd(GetParent(hWndList[1]), NULL); - ok_hwnd(GetParent(hWndList[2]), NULL); - ok_hwnd(GetParent(hWndList[3]), NULL); - ok_hwnd(GetParent(hWndList[4]), hWndList[2]); - ok_hwnd(GetParent(hWndList[5]), NULL); - -trace("\n"); - while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) - { - int iwnd = get_iwnd(msg.hwnd, FALSE); - if(!(msg.message > WM_USER || IsDWmMsg(msg.message) || IseKeyMsg(msg.message))) - RECOND_MESSAGE(iwnd, msg.message, POST, 0, 0); - DispatchMessageA( &msg ); - } -trace("\n"); - TRACE_CACHE(); - } Copied: trunk/rostests/apitests/user32/SetParent.c (from r67058, trunk/rostests/apitests/user32/CreateWindowEx.c) URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/user32/SetParent…
============================================================================== --- trunk/rostests/apitests/user32/CreateWindowEx.c [iso-8859-1] (original) +++ trunk/rostests/apitests/user32/SetParent.c [iso-8859-1] Mon Apr 6 06:34:04 2015 @@ -1,7 +1,7 @@ /* * PROJECT: ReactOS API tests * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory - * PURPOSE: Test for CreateWindow stuff + * PURPOSE: Test for SetParent * PROGRAMMERS: Thomas Faber <thomas.faber(a)reactos.org> */ @@ -114,7 +114,7 @@ } -START_TEST(CreateWindowEx) +START_TEST(SetParent) { HWND hWnd; MSG msg; Modified: trunk/rostests/apitests/user32/testlist.c URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/user32/testlist.…
============================================================================== --- trunk/rostests/apitests/user32/testlist.c [iso-8859-1] (original) +++ trunk/rostests/apitests/user32/testlist.c [iso-8859-1] Mon Apr 6 06:34:04 2015 @@ -5,7 +5,6 @@ extern void func_AttachThreadInput(void); extern void func_CreateIconFromResourceEx(void); -extern void func_CreateWindowEx(void); extern void func_DeferWindowPos(void); extern void func_DestroyCursorIcon(void); extern void func_DrawIconEx(void); @@ -26,6 +25,7 @@ extern void func_SendMessageTimeout(void); extern void func_SetActiveWindow(void); extern void func_SetCursorPos(void); +extern void func_SetParent(void); extern void func_SystemParametersInfo(void); extern void func_TrackMouseEvent(void); extern void func_WndProc(void); @@ -35,7 +35,6 @@ { { "AttachThreadInput", func_AttachThreadInput }, { "CreateIconFromResourceEx", func_CreateIconFromResourceEx }, - { "CreateWindowEx", func_CreateWindowEx }, { "DeferWindowPos", func_DeferWindowPos }, { "DestroyCursorIcon", func_DestroyCursorIcon }, { "DrawIconEx", func_DrawIconEx }, @@ -56,6 +55,7 @@ { "SendMessageTimeout", func_SendMessageTimeout }, { "SetActiveWindow", func_SetActiveWindow }, { "SetCursorPos", func_SetCursorPos }, + { "SetParent", func_SetParent }, { "SystemParametersInfo", func_SystemParametersInfo }, { "TrackMouseEvent", func_TrackMouseEvent }, { "WndProc", func_WndProc },
9 years, 8 months
1
0
0
0
[hbelusca] 67069: [KERNEL32] - Use the correct console critical section when setting console control handlers. - Hold the console critical section in FreeConsole (so that we avoid freeing the conso...
by hbelusca@svn.reactos.org
Author: hbelusca Date: Sun Apr 5 23:42:26 2015 New Revision: 67069 URL:
http://svn.reactos.org/svn/reactos?rev=67069&view=rev
Log: [KERNEL32] - Use the correct console critical section when setting console control handlers. - Hold the console critical section in FreeConsole (so that we avoid freeing the console while also running code in the console control dispatcher...). Modified: trunk/reactos/dll/win32/kernel32/client/console/console.c Modified: trunk/reactos/dll/win32/kernel32/client/console/console.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/client/…
============================================================================== --- trunk/reactos/dll/win32/kernel32/client/console/console.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/kernel32/client/console/console.c [iso-8859-1] Sun Apr 5 23:42:26 2015 @@ -1346,15 +1346,19 @@ DECLSPEC_HOTPATCH FreeConsole(VOID) { + BOOL Success = TRUE; CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_FREECONSOLE FreeConsoleRequest = &ApiMessage.Data.FreeConsoleRequest; HANDLE ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; + RtlEnterCriticalSection(&ConsoleLock); + /* We must have a non-trivial handle to close */ if (ConsoleHandle == NULL) // IsConsoleHandle(ConsoleHandle) { SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; + Success = FALSE; + goto Quit; } /* Set up the data to send to the Console Server */ @@ -1370,7 +1374,8 @@ if (!NT_SUCCESS(ApiMessage.Status)) { BaseSetLastNTError(ApiMessage.Status); - return FALSE; + Success = FALSE; + goto Quit; } /* Reset the console handle */ @@ -1380,7 +1385,9 @@ CloseHandle(InputWaitHandle); InputWaitHandle = INVALID_HANDLE_VALUE; - return TRUE; +Quit: + RtlLeaveCriticalSection(&ConsoleLock); + return Success; } @@ -2007,18 +2014,15 @@ { BOOL Ret; - RtlEnterCriticalSection(&BaseDllDirectoryLock); + RtlEnterCriticalSection(&ConsoleLock); + if (Add) - { Ret = AddConsoleCtrlHandler(HandlerRoutine); - } else - { Ret = RemoveConsoleCtrlHandler(HandlerRoutine); - } - - RtlLeaveCriticalSection(&BaseDllDirectoryLock); - return(Ret); + + RtlLeaveCriticalSection(&ConsoleLock); + return Ret; }
9 years, 8 months
1
0
0
0
[hbelusca] 67068: [CONSRV][CONSOLE.DLL] - Correctly retrieve/set the default console properties. - (for console.dll only): split ApplyConsoleInfo so that it only deals with displaying the confirmat...
by hbelusca@svn.reactos.org
Author: hbelusca Date: Sun Apr 5 23:04:42 2015 New Revision: 67068 URL:
http://svn.reactos.org/svn/reactos?rev=67068&view=rev
Log: [CONSRV][CONSOLE.DLL] - Correctly retrieve/set the default console properties. - (for console.dll only): split ApplyConsoleInfo so that it only deals with displaying the confirmation dialog (and set the correct return value for the PSN_APPLY notification message); the code that really sets console properties and save them in the registry is done in the main CPL function, after the property dialog is destroyed and before the CPL returns. Modified: trunk/reactos/dll/cpl/console/colors.c trunk/reactos/dll/cpl/console/console.c trunk/reactos/dll/cpl/console/console.h trunk/reactos/dll/cpl/console/font.c trunk/reactos/dll/cpl/console/options.c trunk/reactos/win32ss/user/winsrv/concfg/settings.c trunk/reactos/win32ss/user/winsrv/concfg/settings.h trunk/reactos/win32ss/user/winsrv/consrv/console.c Modified: trunk/reactos/dll/cpl/console/colors.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/cpl/console/colors.c?r…
============================================================================== --- trunk/reactos/dll/cpl/console/colors.c [iso-8859-1] (original) +++ trunk/reactos/dll/cpl/console/colors.c [iso-8859-1] Sun Apr 5 23:04:42 2015 @@ -81,17 +81,8 @@ { case PSN_APPLY: { - if (!AppliedConfig) - { - return ApplyConsoleInfo(hwndDlg, ConInfo); - } - else - { - /* Options have already been applied */ - SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR); - return TRUE; - } - break; + ApplyConsoleInfo(hwndDlg); + return TRUE; } case UDN_DELTAPOS: Modified: trunk/reactos/dll/cpl/console/console.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/cpl/console/console.c?…
============================================================================== --- trunk/reactos/dll/cpl/console/console.c [iso-8859-1] (original) +++ trunk/reactos/dll/cpl/console/console.c [iso-8859-1] Sun Apr 5 23:04:42 2015 @@ -18,10 +18,12 @@ INT_PTR CALLBACK ColorsProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); HINSTANCE hApplet = NULL; -BOOLEAN AppliedConfig = FALSE; - -/* Local copy of the console informations */ + +/* Local copy of the console information */ PCONSOLE_STATE_INFO ConInfo = NULL; +/* What to do with the console information */ +static BOOL SetConsoleInfo = FALSE; +static BOOL SaveConsoleInfo = FALSE; static VOID InitPropSheetPage(PROPSHEETPAGEW *psp, @@ -40,8 +42,8 @@ static VOID InitDefaultConsoleInfo(PCONSOLE_STATE_INFO pConInfo) { - /* FIXME: Get also the defaults from the registry */ - ConCfgInitDefaultSettings(pConInfo); + // FIXME: Also retrieve the value of REG_DWORD CurrentPage. + ConCfgGetDefaultSettings(pConInfo); } static INT_PTR @@ -82,41 +84,177 @@ return FALSE; } -BOOL -ApplyConsoleInfo(HWND hwndDlg, - PCONSOLE_STATE_INFO pConInfo) -{ - BOOL SetParams = FALSE; - BOOL SaveParams = FALSE; +VOID +ApplyConsoleInfo(HWND hwndDlg) +{ + static BOOL ConsoleInfoAlreadySaved = FALSE; + + /* + * We alread applied all the console properties (and saved if needed). + * Nothing more needs to be done. + */ + if (ConsoleInfoAlreadySaved) + goto Done; /* * If we are setting the default parameters, just save them, - * otherwise display the save-confirmation dialog. - */ - if (pConInfo->hWnd == NULL) - { - SetParams = FALSE; - SaveParams = TRUE; // FIXME: What happens if one clicks on CANCEL?? + * otherwise display the confirmation & apply dialog. + */ + if (ConInfo->hWnd == NULL) + { + SetConsoleInfo = FALSE; + SaveConsoleInfo = TRUE; } else { INT_PTR res = DialogBoxW(hApplet, MAKEINTRESOURCEW(IDD_APPLYOPTIONS), hwndDlg, ApplyProc); - SetParams = (res != IDCANCEL); - SaveParams = (res == IDC_RADIO_APPLY_ALL); - - if (SetParams == FALSE) - { - /* Don't destroy when user presses cancel */ + SetConsoleInfo = (res != IDCANCEL); + SaveConsoleInfo = (res == IDC_RADIO_APPLY_ALL); + + if (SetConsoleInfo == FALSE) + { + /* Don't destroy when the user presses cancel */ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE); - // return TRUE; - } - } - - if (SetParams) + return; + } + } + + /* + * We applied all the console properties (and saved if needed). + * Set the flag so that if this function is called again, we won't + * need to redo everything again. + */ + ConsoleInfoAlreadySaved = TRUE; + +Done: + /* Options have been applied */ + SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR); + return; +} + +/* First Applet */ +static LONG +APIENTRY +InitApplet(HANDLE hSectionOrWnd) +{ + INT_PTR Result; + PCONSOLE_STATE_INFO pSharedInfo = NULL; + WCHAR szTitle[MAX_PATH + 1]; + PROPSHEETPAGEW psp[4]; + PROPSHEETHEADERW psh; + INT i = 0; + + /* + * Because of Windows compatibility, we need to behave the same concerning + * information sharing with CONSRV. For some obscure reason the designers + * decided to use the CPlApplet hWnd parameter as being either a handle to + * the applet's parent caller's window (in case we ask for displaying + * the global console settings), or a handle to a shared section holding + * a CONSOLE_STATE_INFO structure (they don't use the extra l/wParams). + */ + + /* + * Try to open the shared section via the handle parameter. If we succeed, + * it means we were called by CONSRV for retrieving/setting parameters for + * a given console. If we fail, it means we are retrieving/setting default + * global parameters (and we were either called by CONSRV or directly by + * the user via the Control Panel, etc...) + */ + pSharedInfo = MapViewOfFile(hSectionOrWnd, FILE_MAP_READ, 0, 0, 0); + if (pSharedInfo != NULL) + { + /* + * We succeeded. We were called by CONSRV and are retrieving + * parameters for a given console. + */ + + /* Copy the shared data into our allocated buffer */ + DPRINT1("pSharedInfo->cbSize == %lu ; sizeof(CONSOLE_STATE_INFO) == %u\n", + pSharedInfo->cbSize, sizeof(CONSOLE_STATE_INFO)); + ASSERT(pSharedInfo->cbSize >= sizeof(CONSOLE_STATE_INFO)); + + /* Allocate a local buffer to hold console information */ + ConInfo = HeapAlloc(GetProcessHeap(), + HEAP_ZERO_MEMORY, + pSharedInfo->cbSize); + if (ConInfo) + RtlCopyMemory(ConInfo, pSharedInfo, pSharedInfo->cbSize); + + /* Close the section */ + UnmapViewOfFile(pSharedInfo); + CloseHandle(hSectionOrWnd); + + if (!ConInfo) return 0; + } + else + { + /* + * We failed. We are retrieving the default global parameters. + */ + + /* Allocate a local buffer to hold console information */ + ConInfo = HeapAlloc(GetProcessHeap(), + HEAP_ZERO_MEMORY, + sizeof(CONSOLE_STATE_INFO)); + if (!ConInfo) return 0; + + /* + * Setting the console window handle to NULL indicates we are + * retrieving/setting the default console parameters. + */ + ConInfo->hWnd = NULL; + ConInfo->ConsoleTitle[0] = UNICODE_NULL; + + /* Use defaults */ + InitDefaultConsoleInfo(ConInfo); + } + + /* Initialize the property sheet structure */ + ZeroMemory(&psh, sizeof(psh)); + psh.dwSize = sizeof(psh); + psh.dwFlags = PSH_PROPSHEETPAGE | PSH_PROPTITLE | /* PSH_USEHICON */ PSH_USEICONID | PSH_NOAPPLYNOW; + + if (ConInfo->ConsoleTitle[0] != UNICODE_NULL) + { + wcsncpy(szTitle, L"\"", MAX_PATH); + wcsncat(szTitle, ConInfo->ConsoleTitle, MAX_PATH - wcslen(szTitle)); + wcsncat(szTitle, L"\"", MAX_PATH - wcslen(szTitle)); + } + else + { + wcscpy(szTitle, L"ReactOS Console"); + } + psh.pszCaption = szTitle; + + if (/* pSharedInfo != NULL && */ ConInfo->hWnd != NULL) + { + /* We were started from a console window: this is our parent. */ + psh.hwndParent = ConInfo->hWnd; + } + else + { + /* We were started in another way (--> default parameters). Caller's window is our parent. */ + psh.hwndParent = (HWND)hSectionOrWnd; + } + + psh.hInstance = hApplet; + // psh.hIcon = LoadIcon(hApplet, MAKEINTRESOURCEW(IDC_CPLICON)); + psh.pszIcon = MAKEINTRESOURCEW(IDC_CPLICON); + psh.nPages = ARRAYSIZE(psp); + psh.nStartPage = 0; + psh.ppsp = psp; + + InitPropSheetPage(&psp[i++], IDD_PROPPAGEOPTIONS, OptionsProc); + InitPropSheetPage(&psp[i++], IDD_PROPPAGEFONT , FontProc ); + InitPropSheetPage(&psp[i++], IDD_PROPPAGELAYOUT , LayoutProc ); + InitPropSheetPage(&psp[i++], IDD_PROPPAGECOLORS , ColorsProc ); + + Result = PropertySheetW(&psh); + + if (SetConsoleInfo) { HANDLE hSection; - PCONSOLE_STATE_INFO pSharedInfo; /* * Create a memory section to share with CONSRV, and map it. @@ -125,12 +263,12 @@ NULL, PAGE_READWRITE, 0, - pConInfo->cbSize, + ConInfo->cbSize, NULL); if (!hSection) { DPRINT1("Error when creating file mapping, error = %d\n", GetLastError()); - return FALSE; + goto Quit; } pSharedInfo = MapViewOfFile(hSection, FILE_MAP_ALL_ACCESS, 0, 0, 0); @@ -138,21 +276,17 @@ { DPRINT1("Error when mapping view of file, error = %d\n", GetLastError()); CloseHandle(hSection); - return FALSE; - } - - /* We are applying the chosen configuration */ - AppliedConfig = TRUE; + goto Quit; + } /* Copy the console information into the section */ - RtlCopyMemory(pSharedInfo, pConInfo, pConInfo->cbSize); + RtlCopyMemory(pSharedInfo, ConInfo, ConInfo->cbSize); /* Unmap it */ UnmapViewOfFile(pSharedInfo); /* Signal to CONSRV that it can apply the new configuration */ - SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR); - SendMessage(pConInfo->hWnd, + SendMessage(ConInfo->hWnd, WM_SETCONSOLEINFO, (WPARAM)hSection, 0); @@ -160,133 +294,13 @@ CloseHandle(hSection); } - if (SaveParams) - { - ConCfgWriteUserSettings(pConInfo); - } - - return TRUE; -} - -/* First Applet */ -static LONG -APIENTRY -InitApplet(HANDLE hSectionOrWnd) -{ - INT_PTR Result; - PCONSOLE_STATE_INFO pSharedInfo = NULL; - WCHAR szTitle[MAX_PATH + 1]; - PROPSHEETPAGEW psp[4]; - PROPSHEETHEADERW psh; - INT i = 0; - - /* - * Because of Windows compatibility, we need to behave the same concerning - * information sharing with CONSRV. For some obscure reason the designers - * decided to use the CPlApplet hWnd parameter as being either a handle to - * the applet's parent caller's window (in case we ask for displaying - * the global console settings), or a handle to a shared section holding - * a CONSOLE_STATE_INFO structure (they don't use the extra l/wParams). - */ - - /* - * Try to open the shared section via the handle parameter. If we succeed, - * it means we were called by CONSRV for retrieving/setting parameters for - * a given console. If we fail, it means we are retrieving/setting default - * global parameters (and we were either called by CONSRV or directly by - * the user via the Control Panel, etc...) - */ - pSharedInfo = MapViewOfFile(hSectionOrWnd, FILE_MAP_READ, 0, 0, 0); - if (pSharedInfo != NULL) - { - /* - * We succeeded. We were called by CONSRV and are retrieving - * parameters for a given console. - */ - - /* Copy the shared data into our allocated buffer */ - DPRINT1("pSharedInfo->cbSize == %lu ; sizeof(CONSOLE_STATE_INFO) == %u\n", - pSharedInfo->cbSize, sizeof(CONSOLE_STATE_INFO)); - ASSERT(pSharedInfo->cbSize >= sizeof(CONSOLE_STATE_INFO)); - - /* Allocate a local buffer to hold console information */ - ConInfo = HeapAlloc(GetProcessHeap(), - HEAP_ZERO_MEMORY, - pSharedInfo->cbSize); - if (ConInfo) - RtlCopyMemory(ConInfo, pSharedInfo, pSharedInfo->cbSize); - - /* Close the section */ - UnmapViewOfFile(pSharedInfo); - CloseHandle(hSectionOrWnd); - - if (!ConInfo) return 0; - } - else - { - /* - * We failed. We are retrieving the default global parameters. - */ - - /* Allocate a local buffer to hold console information */ - ConInfo = HeapAlloc(GetProcessHeap(), - HEAP_ZERO_MEMORY, - sizeof(CONSOLE_STATE_INFO)); - if (!ConInfo) return 0; - - /* - * Setting the console window handle to NULL indicates we are - * retrieving/setting the default console parameters. - */ - ConInfo->hWnd = NULL; - ConInfo->ConsoleTitle[0] = UNICODE_NULL; - - /* Use defaults */ - InitDefaultConsoleInfo(ConInfo); - } - - /* Initialize the property sheet structure */ - ZeroMemory(&psh, sizeof(psh)); - psh.dwSize = sizeof(psh); - psh.dwFlags = PSH_PROPSHEETPAGE | PSH_PROPTITLE | /* PSH_USEHICON */ PSH_USEICONID | PSH_NOAPPLYNOW; - - if (ConInfo->ConsoleTitle[0] != UNICODE_NULL) - { - wcsncpy(szTitle, L"\"", MAX_PATH); - wcsncat(szTitle, ConInfo->ConsoleTitle, MAX_PATH - wcslen(szTitle)); - wcsncat(szTitle, L"\"", MAX_PATH - wcslen(szTitle)); - } - else - { - wcscpy(szTitle, L"ReactOS Console"); - } - psh.pszCaption = szTitle; - - if (/* pSharedInfo != NULL && */ ConInfo->hWnd != NULL) - { - /* We were started from a console window: this is our parent. */ - psh.hwndParent = ConInfo->hWnd; - } - else - { - /* We were started in another way (--> default parameters). Caller's window is our parent. */ - psh.hwndParent = (HWND)hSectionOrWnd; - } - - psh.hInstance = hApplet; - // psh.hIcon = LoadIcon(hApplet, MAKEINTRESOURCEW(IDC_CPLICON)); - psh.pszIcon = MAKEINTRESOURCEW(IDC_CPLICON); - psh.nPages = ARRAYSIZE(psp); - psh.nStartPage = 0; - psh.ppsp = psp; - - InitPropSheetPage(&psp[i++], IDD_PROPPAGEOPTIONS, OptionsProc); - InitPropSheetPage(&psp[i++], IDD_PROPPAGEFONT , FontProc ); - InitPropSheetPage(&psp[i++], IDD_PROPPAGELAYOUT , LayoutProc ); - InitPropSheetPage(&psp[i++], IDD_PROPPAGECOLORS , ColorsProc ); - - Result = PropertySheetW(&psh); - + if (SaveConsoleInfo) + { + /* Default settings saved when ConInfo->hWnd == NULL */ + ConCfgWriteUserSettings(ConInfo, ConInfo->hWnd == NULL); + } + +Quit: /* Cleanup */ HeapFree(GetProcessHeap(), 0, ConInfo); ConInfo = NULL; Modified: trunk/reactos/dll/cpl/console/console.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/cpl/console/console.h?…
============================================================================== --- trunk/reactos/dll/cpl/console/console.h [iso-8859-1] (original) +++ trunk/reactos/dll/cpl/console/console.h [iso-8859-1] Sun Apr 5 23:04:42 2015 @@ -29,10 +29,9 @@ } TEXT_TYPE; /* Globals */ -extern BOOLEAN AppliedConfig; extern PCONSOLE_STATE_INFO ConInfo; -BOOL ApplyConsoleInfo(HWND hwndDlg, PCONSOLE_STATE_INFO pConInfo); +VOID ApplyConsoleInfo(HWND hwndDlg); VOID PaintConsole(LPDRAWITEMSTRUCT drawItem, PCONSOLE_STATE_INFO pConInfo); BOOL PaintText(LPDRAWITEMSTRUCT drawItem, PCONSOLE_STATE_INFO pConInfo, TEXT_TYPE TextMode); Modified: trunk/reactos/dll/cpl/console/font.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/cpl/console/font.c?rev…
============================================================================== --- trunk/reactos/dll/cpl/console/font.c [iso-8859-1] (original) +++ trunk/reactos/dll/cpl/console/font.c [iso-8859-1] Sun Apr 5 23:04:42 2015 @@ -421,17 +421,8 @@ { case PSN_APPLY: { - if (!AppliedConfig) - { - return ApplyConsoleInfo(hwndDlg, ConInfo); - } - else - { - /* Options have already been applied */ - SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR); - return TRUE; - } - break; + ApplyConsoleInfo(hwndDlg); + return TRUE; } } Modified: trunk/reactos/dll/cpl/console/options.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/cpl/console/options.c?…
============================================================================== --- trunk/reactos/dll/cpl/console/options.c [iso-8859-1] (original) +++ trunk/reactos/dll/cpl/console/options.c [iso-8859-1] Sun Apr 5 23:04:42 2015 @@ -127,16 +127,8 @@ } else if (lppsn->hdr.code == PSN_APPLY) { - if (!AppliedConfig) - { - return ApplyConsoleInfo(hwndDlg, ConInfo); - } - else - { - /* Options have already been applied */ - SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR); - return TRUE; - } + ApplyConsoleInfo(hwndDlg); + return TRUE; } break; } Modified: trunk/reactos/win32ss/user/winsrv/concfg/settings.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/winsrv/concfg…
============================================================================== --- trunk/reactos/win32ss/user/winsrv/concfg/settings.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/winsrv/concfg/settings.c [iso-8859-1] Sun Apr 5 23:04:42 2015 @@ -115,13 +115,13 @@ while ((DestString = wcschr(DestString, PATH_SEPARATOR))) *DestString = L'_'; } -BOOL +BOOLEAN ConCfgOpenUserSettings(LPCWSTR ConsoleTitle, PHKEY hSubKey, REGSAM samDesired, - BOOL bCreate) -{ - BOOL bRet = TRUE; + BOOLEAN Create) +{ + BOOLEAN RetVal = TRUE; NTSTATUS Status; WCHAR szBuffer[MAX_PATH] = L"Console\\"; WCHAR szBuffer2[MAX_PATH] = L""; @@ -161,37 +161,38 @@ wcsncat(szBuffer, szBuffer2, MAX_PATH - wcslen(szBuffer) - 1); /* Create or open the registry key */ - if (bCreate) + if (Create) { /* Create the key */ - bRet = (RegCreateKeyExW(hKey, + RetVal = (RegCreateKeyExW(hKey, + szBuffer, + 0, NULL, + REG_OPTION_NON_VOLATILE, + samDesired, + NULL, + hSubKey, + NULL) == ERROR_SUCCESS); + } + else + { + /* Open the key */ + RetVal = (RegOpenKeyExW(hKey, szBuffer, - 0, NULL, - REG_OPTION_NON_VOLATILE, + 0, samDesired, - NULL, - hSubKey, - NULL) == ERROR_SUCCESS); - } - else - { - /* Open the key */ - bRet = (RegOpenKeyExW(hKey, - szBuffer, - 0, - samDesired, - hSubKey) == ERROR_SUCCESS); + hSubKey) == ERROR_SUCCESS); } /* Close the parent key and return success or not */ NtClose(hKey); - return bRet; + return RetVal; } -BOOL -ConCfgReadUserSettings(IN OUT PCONSOLE_STATE_INFO ConsoleInfo) -{ - BOOL RetVal = FALSE; +BOOLEAN +ConCfgReadUserSettings(IN OUT PCONSOLE_STATE_INFO ConsoleInfo, + IN BOOLEAN DefaultSettings) +{ + BOOLEAN RetVal = FALSE; HKEY hKey; DWORD dwNumSubKeys = 0; DWORD dwIndex; @@ -203,9 +204,8 @@ DWORD Value; DWORD dwValue; - if (!ConCfgOpenUserSettings(ConsoleInfo->ConsoleTitle, - &hKey, KEY_READ, - FALSE)) + if (!ConCfgOpenUserSettings(DefaultSettings ? L"" : ConsoleInfo->ConsoleTitle, + &hKey, KEY_READ, FALSE)) { DPRINT("ConCfgOpenUserSettings failed\n"); return FALSE; @@ -346,16 +346,16 @@ return RetVal; } -BOOL -ConCfgWriteUserSettings(IN PCONSOLE_STATE_INFO ConsoleInfo) -{ - BOOL GlobalSettings = (ConsoleInfo->ConsoleTitle[0] == L'\0'); // FIXME +BOOLEAN +ConCfgWriteUserSettings(IN PCONSOLE_STATE_INFO ConsoleInfo, + IN BOOLEAN DefaultSettings) +{ HKEY hKey; DWORD Storage = 0; #define SetConsoleSetting(SettingName, SettingType, SettingSize, Setting, DefaultValue) \ do { \ - if (GlobalSettings || (!GlobalSettings && (*(Setting) != (DefaultValue)))) \ + if (DefaultSettings || (!DefaultSettings && (*(Setting) != (DefaultValue)))) \ { \ RegSetValueExW(hKey, (SettingName), 0, (SettingType), (PBYTE)(Setting), (SettingSize)); \ } \ @@ -368,9 +368,8 @@ WCHAR szValueName[15]; UINT i; - if (!ConCfgOpenUserSettings(ConsoleInfo->ConsoleTitle, - &hKey, KEY_WRITE, - TRUE)) + if (!ConCfgOpenUserSettings(DefaultSettings ? L"" : ConsoleInfo->ConsoleTitle, + &hKey, KEY_WRITE, TRUE)) { return FALSE; } @@ -489,9 +488,6 @@ RtlCopyMemory(ConsoleInfo->ColorTable, s_Colors, sizeof(s_Colors)); ConsoleInfo->CodePage = 0; - - /* Default settings --> console title is NULL */ - ConsoleInfo->ConsoleTitle[0] = UNICODE_NULL; } VOID @@ -509,8 +505,8 @@ * If the HKCU\Console key doesn't exist, create it * and store the default values inside. */ - if (!ConCfgReadUserSettings(ConsoleInfo)) - ConCfgWriteUserSettings(ConsoleInfo); + if (!ConCfgReadUserSettings(ConsoleInfo, TRUE)) + ConCfgWriteUserSettings(ConsoleInfo, TRUE); } /* EOF */ Modified: trunk/reactos/win32ss/user/winsrv/concfg/settings.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/winsrv/concfg…
============================================================================== --- trunk/reactos/win32ss/user/winsrv/concfg/settings.h [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/winsrv/concfg/settings.h [iso-8859-1] Sun Apr 5 23:04:42 2015 @@ -75,13 +75,18 @@ /* FUNCTIONS ******************************************************************/ -BOOL ConCfgOpenUserSettings(LPCWSTR ConsoleTitle, - PHKEY hSubKey, - REGSAM samDesired, - BOOL bCreate); +BOOLEAN +ConCfgOpenUserSettings(LPCWSTR ConsoleTitle, + PHKEY hSubKey, + REGSAM samDesired, + BOOLEAN Create); +BOOLEAN +ConCfgReadUserSettings(IN OUT PCONSOLE_STATE_INFO ConsoleInfo, + IN BOOLEAN DefaultSettings); +BOOLEAN +ConCfgWriteUserSettings(IN PCONSOLE_STATE_INFO ConsoleInfo, + IN BOOLEAN DefaultSettings); -BOOL ConCfgReadUserSettings(IN OUT PCONSOLE_STATE_INFO ConsoleInfo); -BOOL ConCfgWriteUserSettings(IN PCONSOLE_STATE_INFO ConsoleInfo); VOID ConCfgInitDefaultSettings(IN OUT PCONSOLE_STATE_INFO ConsoleInfo); VOID ConCfgGetDefaultSettings(IN OUT PCONSOLE_STATE_INFO ConsoleInfo); Modified: trunk/reactos/win32ss/user/winsrv/consrv/console.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/winsrv/consrv…
============================================================================== --- trunk/reactos/win32ss/user/winsrv/consrv/console.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/winsrv/consrv/console.c [iso-8859-1] Sun Apr 5 23:04:42 2015 @@ -535,24 +535,24 @@ /* * Load the console settings */ - - /* Impersonate the caller in order to retrieve settings in its context */ - if (!CsrImpersonateClient(NULL)) - return STATUS_BAD_IMPERSONATION_LEVEL; - - /* 1. Load the default settings */ RtlZeroMemory(ConsoleInfo, sizeof(ConsoleInfoBuffer)); ConsoleInfo->cbSize = sizeof(ConsoleInfoBuffer); - ConCfgGetDefaultSettings(ConsoleInfo); - - /* 2. Get the title of the console (initialize ConsoleInfo->ConsoleTitle) */ + + /* 1. Get the title of the console (initialize ConsoleInfo->ConsoleTitle) */ Length = min(ConsoleInitInfo->TitleLength, (ConsoleInfo->cbSize - FIELD_OFFSET(CONSOLE_STATE_INFO, ConsoleTitle) - sizeof(UNICODE_NULL)) / sizeof(WCHAR)); wcsncpy(ConsoleInfo->ConsoleTitle, ConsoleInitInfo->ConsoleTitle, Length); ConsoleInfo->ConsoleTitle[Length] = UNICODE_NULL; // NULL-terminate it. + /* 2. Impersonate the caller in order to retrieve settings in its context */ + if (!CsrImpersonateClient(NULL)) + return STATUS_BAD_IMPERSONATION_LEVEL; + + /* 3. Load the default settings */ + ConCfgGetDefaultSettings(ConsoleInfo); + /* - * 3. Load per-application terminal settings. + * 4. Load per-application terminal settings. * * Check whether the process creating the console was launched via * a shell-link. ConsoleInfo->ConsoleTitle may be updated with the @@ -567,7 +567,7 @@ } /* - * 4. Load the remaining console settings via the registry. + * 5. Load the remaining console settings via the registry. */ if ((ConsoleInitInfo->ConsoleStartInfo->dwStartupFlags & STARTF_TITLEISLINKNAME) == 0) { @@ -576,7 +576,7 @@ * or we failed to load shell-link console properties. * Therefore, load the console infos for the application from the registry. */ - ConCfgReadUserSettings(ConsoleInfo); + ConCfgReadUserSettings(ConsoleInfo, FALSE); /* * Now, update them with the properties the user might gave to us @@ -617,7 +617,7 @@ #endif } - /* Revert impersonation */ + /* 6. Revert impersonation */ CsrRevertToSelf(); /* Set-up the code page */ @@ -1044,7 +1044,7 @@ PROCESS_BASIC_INFORMATION ProcessInfo; ULONG Length = sizeof(ProcessInfo); - /* Get the real parent's ID */ + /* Get the real parent's PID */ Status = NtQueryInformationProcess(TargetProcess->ProcessHandle, ProcessBasicInformation,
9 years, 8 months
1
0
0
0
[pschweitzer] 67067: [NTOSKRNL] Implement the reparse points loop in IopParseDevice(). Reviewed by Thomas
by pschweitzer@svn.reactos.org
Author: pschweitzer Date: Sun Apr 5 20:02:30 2015 New Revision: 67067 URL:
http://svn.reactos.org/svn/reactos?rev=67067&view=rev
Log: [NTOSKRNL] Implement the reparse points loop in IopParseDevice(). Reviewed by Thomas Modified: trunk/reactos/ntoskrnl/include/internal/io.h trunk/reactos/ntoskrnl/io/iomgr/file.c Modified: trunk/reactos/ntoskrnl/include/internal/io.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
============================================================================== --- trunk/reactos/ntoskrnl/include/internal/io.h [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/include/internal/io.h [iso-8859-1] Sun Apr 5 20:02:30 2015 @@ -79,6 +79,11 @@ // Unable to create symbolic link pointing to the RAM disk device // #define RD_SYMLINK_CREATE_FAILED 5 + +// +// Max traversal of reparse points for a single open in IoParseDevice +// +#define IOP_MAX_REPARSE_TRAVERSAL 0x20 // // We can call the Ob Inlined API, it's the same thing Modified: trunk/reactos/ntoskrnl/io/iomgr/file.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/iomgr/file.c?r…
============================================================================== --- trunk/reactos/ntoskrnl/io/iomgr/file.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/io/iomgr/file.c [iso-8859-1] Sun Apr 5 20:02:30 2015 @@ -300,751 +300,760 @@ BOOLEAN AccessGranted, LockHeld = FALSE; PPRIVILEGE_SET Privileges = NULL; UNICODE_STRING FileString; + USHORT Attempt; IOTRACE(IO_FILE_DEBUG, "ParseObject: %p. RemainingName: %wZ\n", ParseObject, RemainingName); - /* Assume failure */ - *Object = NULL; - - /* Validate the open packet */ - if (!IopValidateOpenPacket(OpenPacket)) return STATUS_OBJECT_TYPE_MISMATCH; - - /* Valide reparse point in case we traversed a mountpoint */ - if (OpenPacket->TraversedMountPoint) - { - /* This is a reparse point we understand */ - ASSERT(OpenPacket->Information == IO_REPARSE_TAG_MOUNT_POINT); - - /* Make sure we're dealing with correct DO */ - if (OriginalDeviceObject->DeviceType != FILE_DEVICE_DISK && - OriginalDeviceObject->DeviceType != FILE_DEVICE_CD_ROM && - OriginalDeviceObject->DeviceType != FILE_DEVICE_VIRTUAL_DISK && - OriginalDeviceObject->DeviceType != FILE_DEVICE_TAPE) - { - OpenPacket->FinalStatus = STATUS_IO_REPARSE_DATA_INVALID; - return STATUS_IO_REPARSE_DATA_INVALID; - } - } - - /* Check if we have a related file object */ - if (OpenPacket->RelatedFileObject) - { - /* Use the related file object's device object */ - OriginalDeviceObject = OpenPacket->RelatedFileObject->DeviceObject; - } - - /* Validate device status */ - Status = IopCheckDeviceAndDriver(OpenPacket, OriginalDeviceObject); - if (!NT_SUCCESS(Status)) - { - /* We failed, return status */ - OpenPacket->FinalStatus = Status; - return Status; - } - - /* Map the generic mask and set the new mapping in the access state */ - RtlMapGenericMask(&AccessState->RemainingDesiredAccess, - &IoFileObjectType->TypeInfo.GenericMapping); - RtlMapGenericMask(&AccessState->OriginalDesiredAccess, - &IoFileObjectType->TypeInfo.GenericMapping); - SeSetAccessStateGenericMapping(AccessState, - &IoFileObjectType->TypeInfo.GenericMapping); - DesiredAccess = AccessState->RemainingDesiredAccess; - - /* Check what kind of access checks to do */ - if ((AccessMode != KernelMode) || - (OpenPacket->Options & IO_FORCE_ACCESS_CHECK)) - { - /* Call is from user-mode or kernel is forcing checks */ - CheckMode = UserMode; - } - else - { - /* Call is from the kernel */ - CheckMode = KernelMode; - } - - /* Check privilege for backup or restore operation */ - IopCheckBackupRestorePrivilege(AccessState, - &OpenPacket->CreateOptions, - CheckMode, - OpenPacket->Disposition); - - /* Check if we are re-parsing */ - if (((OpenPacket->Override) && !(RemainingName->Length)) || - (AccessState->Flags & SE_BACKUP_PRIVILEGES_CHECKED)) - { - /* Get granted access from the last call */ - DesiredAccess |= AccessState->PreviouslyGrantedAccess; - } - - /* Check if this is a volume open */ - if ((OpenPacket->RelatedFileObject) && - (OpenPacket->RelatedFileObject->Flags & FO_VOLUME_OPEN) && - !(RemainingName->Length)) - { - /* It is */ - VolumeOpen = TRUE; - } - - /* Now check if we need access checks */ - if (((AccessMode != KernelMode) || - (OpenPacket->Options & IO_FORCE_ACCESS_CHECK)) && - (!(OpenPacket->RelatedFileObject) || (VolumeOpen)) && - !(OpenPacket->Override)) - { - KeEnterCriticalRegion(); - ExAcquireResourceSharedLite(&IopSecurityResource, TRUE); - - /* Check if a device object is being parsed */ - if (!RemainingName->Length) - { - /* Lock the subject context */ - SeLockSubjectContext(&AccessState->SubjectSecurityContext); - LockHeld = TRUE; - - /* Do access check */ - AccessGranted = SeAccessCheck(OriginalDeviceObject-> - SecurityDescriptor, - &AccessState->SubjectSecurityContext, - LockHeld, - DesiredAccess, - 0, - &Privileges, - &IoFileObjectType-> - TypeInfo.GenericMapping, - UserMode, - &GrantedAccess, - &Status); - if (Privileges) - { - /* Append and free the privileges */ - SeAppendPrivileges(AccessState, Privileges); - SeFreePrivileges(Privileges); - } - - /* Check if we got access */ - if (AccessGranted) - { - /* Update access state */ - AccessState->PreviouslyGrantedAccess |= GrantedAccess; - AccessState->RemainingDesiredAccess &= ~(GrantedAccess & - MAXIMUM_ALLOWED); - OpenPacket->Override= TRUE; - } - - FileString.Length = 8; - FileString.MaximumLength = 8; - FileString.Buffer = L"File"; - - /* Do Audit/Alarm for open operation */ - SeOpenObjectAuditAlarm(&FileString, - OriginalDeviceObject, - CompleteName, - OriginalDeviceObject->SecurityDescriptor, - AccessState, - FALSE, - AccessGranted, - UserMode, - &AccessState->GenerateOnClose); + for (Attempt = 0; Attempt < IOP_MAX_REPARSE_TRAVERSAL; ++Attempt) + { + /* Assume failure */ + *Object = NULL; + + /* Validate the open packet */ + if (!IopValidateOpenPacket(OpenPacket)) return STATUS_OBJECT_TYPE_MISMATCH; + + /* Valide reparse point in case we traversed a mountpoint */ + if (OpenPacket->TraversedMountPoint) + { + /* This is a reparse point we understand */ + ASSERT(OpenPacket->Information == IO_REPARSE_TAG_MOUNT_POINT); + + /* Make sure we're dealing with correct DO */ + if (OriginalDeviceObject->DeviceType != FILE_DEVICE_DISK && + OriginalDeviceObject->DeviceType != FILE_DEVICE_CD_ROM && + OriginalDeviceObject->DeviceType != FILE_DEVICE_VIRTUAL_DISK && + OriginalDeviceObject->DeviceType != FILE_DEVICE_TAPE) + { + OpenPacket->FinalStatus = STATUS_IO_REPARSE_DATA_INVALID; + return STATUS_IO_REPARSE_DATA_INVALID; + } + } + + /* Check if we have a related file object */ + if (OpenPacket->RelatedFileObject) + { + /* Use the related file object's device object */ + OriginalDeviceObject = OpenPacket->RelatedFileObject->DeviceObject; + } + + /* Validate device status */ + Status = IopCheckDeviceAndDriver(OpenPacket, OriginalDeviceObject); + if (!NT_SUCCESS(Status)) + { + /* We failed, return status */ + OpenPacket->FinalStatus = Status; + return Status; + } + + /* Map the generic mask and set the new mapping in the access state */ + RtlMapGenericMask(&AccessState->RemainingDesiredAccess, + &IoFileObjectType->TypeInfo.GenericMapping); + RtlMapGenericMask(&AccessState->OriginalDesiredAccess, + &IoFileObjectType->TypeInfo.GenericMapping); + SeSetAccessStateGenericMapping(AccessState, + &IoFileObjectType->TypeInfo.GenericMapping); + DesiredAccess = AccessState->RemainingDesiredAccess; + + /* Check what kind of access checks to do */ + if ((AccessMode != KernelMode) || + (OpenPacket->Options & IO_FORCE_ACCESS_CHECK)) + { + /* Call is from user-mode or kernel is forcing checks */ + CheckMode = UserMode; } else { - /* Check if we need to do traverse validation */ - if (!(AccessState->Flags & TOKEN_HAS_TRAVERSE_PRIVILEGE) || - ((OriginalDeviceObject->DeviceType == FILE_DEVICE_DISK) || - (OriginalDeviceObject->DeviceType == FILE_DEVICE_CD_ROM))) - { - /* Check if this is a restricted token */ - if (!(AccessState->Flags & TOKEN_IS_RESTRICTED)) + /* Call is from the kernel */ + CheckMode = KernelMode; + } + + /* Check privilege for backup or restore operation */ + IopCheckBackupRestorePrivilege(AccessState, + &OpenPacket->CreateOptions, + CheckMode, + OpenPacket->Disposition); + + /* Check if we are re-parsing */ + if (((OpenPacket->Override) && !(RemainingName->Length)) || + (AccessState->Flags & SE_BACKUP_PRIVILEGES_CHECKED)) + { + /* Get granted access from the last call */ + DesiredAccess |= AccessState->PreviouslyGrantedAccess; + } + + /* Check if this is a volume open */ + if ((OpenPacket->RelatedFileObject) && + (OpenPacket->RelatedFileObject->Flags & FO_VOLUME_OPEN) && + !(RemainingName->Length)) + { + /* It is */ + VolumeOpen = TRUE; + } + + /* Now check if we need access checks */ + if (((AccessMode != KernelMode) || + (OpenPacket->Options & IO_FORCE_ACCESS_CHECK)) && + (!(OpenPacket->RelatedFileObject) || (VolumeOpen)) && + !(OpenPacket->Override)) + { + KeEnterCriticalRegion(); + ExAcquireResourceSharedLite(&IopSecurityResource, TRUE); + + /* Check if a device object is being parsed */ + if (!RemainingName->Length) + { + /* Lock the subject context */ + SeLockSubjectContext(&AccessState->SubjectSecurityContext); + LockHeld = TRUE; + + /* Do access check */ + AccessGranted = SeAccessCheck(OriginalDeviceObject-> + SecurityDescriptor, + &AccessState->SubjectSecurityContext, + LockHeld, + DesiredAccess, + 0, + &Privileges, + &IoFileObjectType-> + TypeInfo.GenericMapping, + UserMode, + &GrantedAccess, + &Status); + if (Privileges) { - /* Do the FAST traverse check */ - AccessGranted = SeFastTraverseCheck(OriginalDeviceObject->SecurityDescriptor, - AccessState, - FILE_TRAVERSE, - UserMode); + /* Append and free the privileges */ + SeAppendPrivileges(AccessState, Privileges); + SeFreePrivileges(Privileges); + } + + /* Check if we got access */ + if (AccessGranted) + { + /* Update access state */ + AccessState->PreviouslyGrantedAccess |= GrantedAccess; + AccessState->RemainingDesiredAccess &= ~(GrantedAccess & + MAXIMUM_ALLOWED); + OpenPacket->Override= TRUE; + } + + FileString.Length = 8; + FileString.MaximumLength = 8; + FileString.Buffer = L"File"; + + /* Do Audit/Alarm for open operation */ + SeOpenObjectAuditAlarm(&FileString, + OriginalDeviceObject, + CompleteName, + OriginalDeviceObject->SecurityDescriptor, + AccessState, + FALSE, + AccessGranted, + UserMode, + &AccessState->GenerateOnClose); + } + else + { + /* Check if we need to do traverse validation */ + if (!(AccessState->Flags & TOKEN_HAS_TRAVERSE_PRIVILEGE) || + ((OriginalDeviceObject->DeviceType == FILE_DEVICE_DISK) || + (OriginalDeviceObject->DeviceType == FILE_DEVICE_CD_ROM))) + { + /* Check if this is a restricted token */ + if (!(AccessState->Flags & TOKEN_IS_RESTRICTED)) + { + /* Do the FAST traverse check */ + AccessGranted = SeFastTraverseCheck(OriginalDeviceObject->SecurityDescriptor, + AccessState, + FILE_TRAVERSE, + UserMode); + } + else + { + /* Fail */ + AccessGranted = FALSE; + } + + /* Check if we failed to get access */ + if (!AccessGranted) + { + /* Lock the subject context */ + SeLockSubjectContext(&AccessState->SubjectSecurityContext); + LockHeld = TRUE; + + /* Do access check */ + AccessGranted = SeAccessCheck(OriginalDeviceObject-> + SecurityDescriptor, + &AccessState->SubjectSecurityContext, + LockHeld, + FILE_TRAVERSE, + 0, + &Privileges, + &IoFileObjectType-> + TypeInfo.GenericMapping, + UserMode, + &GrantedAccess, + &Status); + if (Privileges) + { + /* Append and free the privileges */ + SeAppendPrivileges(AccessState, Privileges); + SeFreePrivileges(Privileges); + } + } + + /* FIXME: Do Audit/Alarm for traverse check */ } else { - /* Fail */ - AccessGranted = FALSE; + /* Access automatically granted */ + AccessGranted = TRUE; } - - /* Check if we failed to get access */ - if (!AccessGranted) - { - /* Lock the subject context */ - SeLockSubjectContext(&AccessState->SubjectSecurityContext); - LockHeld = TRUE; - - /* Do access check */ - AccessGranted = SeAccessCheck(OriginalDeviceObject-> - SecurityDescriptor, - &AccessState->SubjectSecurityContext, - LockHeld, - FILE_TRAVERSE, - 0, - &Privileges, - &IoFileObjectType-> - TypeInfo.GenericMapping, - UserMode, - &GrantedAccess, - &Status); - if (Privileges) - { - /* Append and free the privileges */ - SeAppendPrivileges(AccessState, Privileges); - SeFreePrivileges(Privileges); - } - } - - /* FIXME: Do Audit/Alarm for traverse check */ - } - else - { - /* Access automatically granted */ - AccessGranted = TRUE; - } - } - - ExReleaseResourceLite(&IopSecurityResource); - KeLeaveCriticalRegion(); - - /* Check if we hold the lock */ - if (LockHeld) - { - /* Release it */ - SeUnlockSubjectContext(&AccessState->SubjectSecurityContext); - } - - /* Check if access failed */ - if (!AccessGranted) - { - /* Dereference the device and fail */ - DPRINT1("Traverse access failed!\n"); - IopDereferenceDeviceObject(OriginalDeviceObject, FALSE); - return STATUS_ACCESS_DENIED; - } - } - - /* Check if we can simply use a dummy file */ - UseDummyFile = ((OpenPacket->QueryOnly) || (OpenPacket->DeleteOnly)); + } + + ExReleaseResourceLite(&IopSecurityResource); + KeLeaveCriticalRegion(); + + /* Check if we hold the lock */ + if (LockHeld) + { + /* Release it */ + SeUnlockSubjectContext(&AccessState->SubjectSecurityContext); + } + + /* Check if access failed */ + if (!AccessGranted) + { + /* Dereference the device and fail */ + DPRINT1("Traverse access failed!\n"); + IopDereferenceDeviceObject(OriginalDeviceObject, FALSE); + return STATUS_ACCESS_DENIED; + } + } + + /* Check if we can simply use a dummy file */ + UseDummyFile = ((OpenPacket->QueryOnly) || (OpenPacket->DeleteOnly)); #if 1 - /* FIXME: Small hack still exists, have to check why... - * This is triggered multiple times by usetup and then once per boot. - */ - if (ExpInTextModeSetup && - !(DirectOpen) && - !(RemainingName->Length) && - !(OpenPacket->RelatedFileObject) && - ((wcsstr(CompleteName->Buffer, L"Harddisk")) || - (wcsstr(CompleteName->Buffer, L"Floppy"))) && - !(UseDummyFile)) - { - DPRINT1("Using IopParseDevice() hack. Requested invalid attributes: %lx\n", - DesiredAccess & ~(SYNCHRONIZE | - FILE_READ_ATTRIBUTES | - READ_CONTROL | - ACCESS_SYSTEM_SECURITY | - WRITE_OWNER | - WRITE_DAC)); - DirectOpen = TRUE; - } + /* FIXME: Small hack still exists, have to check why... + * This is triggered multiple times by usetup and then once per boot. + */ + if (ExpInTextModeSetup && + !(DirectOpen) && + !(RemainingName->Length) && + !(OpenPacket->RelatedFileObject) && + ((wcsstr(CompleteName->Buffer, L"Harddisk")) || + (wcsstr(CompleteName->Buffer, L"Floppy"))) && + !(UseDummyFile)) + { + DPRINT1("Using IopParseDevice() hack. Requested invalid attributes: %lx\n", + DesiredAccess & ~(SYNCHRONIZE | + FILE_READ_ATTRIBUTES | + READ_CONTROL | + ACCESS_SYSTEM_SECURITY | + WRITE_OWNER | + WRITE_DAC)); + DirectOpen = TRUE; + } #endif - /* Check if this is a direct open */ - if (!(RemainingName->Length) && - !(OpenPacket->RelatedFileObject) && - ((DesiredAccess & ~(SYNCHRONIZE | - FILE_READ_ATTRIBUTES | - READ_CONTROL | - ACCESS_SYSTEM_SECURITY | - WRITE_OWNER | - WRITE_DAC)) == 0) && - !(UseDummyFile)) - { - /* Remember this for later */ - DirectOpen = TRUE; - } - - /* Check if we have a related FO that wasn't a direct open */ - if ((OpenPacket->RelatedFileObject) && - !(OpenPacket->RelatedFileObject->Flags & FO_DIRECT_DEVICE_OPEN)) - { - /* The device object is the one we were given */ - DeviceObject = ParseObject; - - /* Check if the related FO had a VPB */ - if (OpenPacket->RelatedFileObject->Vpb) - { - /* Yes, remember it */ - Vpb = OpenPacket->RelatedFileObject->Vpb; - - /* Reference it */ - InterlockedIncrement((PLONG)&Vpb->ReferenceCount); - } - } - else - { - /* The device object is the one we were given */ - DeviceObject = OriginalDeviceObject; - - /* Check if it has a VPB */ - if ((OriginalDeviceObject->Vpb) && !(DirectOpen)) - { - /* Check if the VPB is mounted, and mount it */ - Vpb = IopCheckVpbMounted(OpenPacket, - OriginalDeviceObject, - RemainingName, - &Status); - if (!Vpb) return Status; - - /* Get the VPB's device object */ - DeviceObject = Vpb->DeviceObject; - } - - /* Check if there's an attached device */ - if (DeviceObject->AttachedDevice) - { - /* Get the attached device */ - DeviceObject = IoGetAttachedDevice(DeviceObject); - } - } - - /* If we traversed a mount point, reset the information */ - if (OpenPacket->TraversedMountPoint) - { - OpenPacket->TraversedMountPoint = FALSE; - } - - /* Check if this is a secure FSD */ - if ((DeviceObject->Characteristics & FILE_DEVICE_SECURE_OPEN) && - ((OpenPacket->RelatedFileObject) || (RemainingName->Length)) && - (!VolumeOpen)) - { - DPRINT("Fix Secure FSD support!!!\n"); - } - - /* Allocate the IRP */ - Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE); - if (!Irp) - { - /* Dereference the device and VPB, then fail */ - IopDereferenceDeviceObject(OriginalDeviceObject, FALSE); - if (Vpb) IopDereferenceVpbAndFree(Vpb); - return STATUS_INSUFFICIENT_RESOURCES; - } - - /* Now set the IRP data */ - Irp->RequestorMode = AccessMode; - Irp->Flags = IRP_CREATE_OPERATION | IRP_SYNCHRONOUS_API | IRP_DEFER_IO_COMPLETION; - Irp->Tail.Overlay.Thread = PsGetCurrentThread(); - Irp->UserIosb = &IoStatusBlock; - Irp->MdlAddress = NULL; - Irp->PendingReturned = FALSE; - Irp->UserEvent = NULL; - Irp->Cancel = FALSE; - Irp->CancelRoutine = NULL; - Irp->Tail.Overlay.AuxiliaryBuffer = NULL; - - /* Setup the security context */ - SecurityContext.SecurityQos = SecurityQos; - SecurityContext.AccessState = AccessState; - SecurityContext.DesiredAccess = AccessState->RemainingDesiredAccess; - SecurityContext.FullCreateOptions = OpenPacket->CreateOptions; - - /* Get the I/O Stack location */ - StackLoc = (PEXTENDED_IO_STACK_LOCATION)IoGetNextIrpStackLocation(Irp); - StackLoc->Control = 0; - - /* Check what kind of file this is */ - switch (OpenPacket->CreateFileType) - { - /* Normal file */ - case CreateFileTypeNone: - - /* Set the major function and EA Length */ - StackLoc->MajorFunction = IRP_MJ_CREATE; - StackLoc->Parameters.Create.EaLength = OpenPacket->EaLength; - - /* Set the flags */ - StackLoc->Flags = (UCHAR)OpenPacket->Options; - StackLoc->Flags |= !(Attributes & OBJ_CASE_INSENSITIVE) ? SL_CASE_SENSITIVE: 0; - break; - - /* Named pipe */ - case CreateFileTypeNamedPipe: - - /* Set the named pipe MJ and set the parameters */ - StackLoc->MajorFunction = IRP_MJ_CREATE_NAMED_PIPE; - StackLoc->Parameters.CreatePipe.Parameters = OpenPacket->ExtraCreateParameters; - break; - - /* Mailslot */ - case CreateFileTypeMailslot: - - /* Set the mailslot MJ and set the parameters */ - StackLoc->MajorFunction = IRP_MJ_CREATE_MAILSLOT; - StackLoc->Parameters.CreateMailslot.Parameters = OpenPacket->ExtraCreateParameters; - break; - } - - /* Set the common data */ - Irp->Overlay.AllocationSize = OpenPacket->AllocationSize; - Irp->AssociatedIrp.SystemBuffer = OpenPacket->EaBuffer; - StackLoc->Parameters.Create.Options = (OpenPacket->Disposition << 24) | - (OpenPacket->CreateOptions & - 0xFFFFFF); - StackLoc->Parameters.Create.FileAttributes = OpenPacket->FileAttributes; - StackLoc->Parameters.Create.ShareAccess = OpenPacket->ShareAccess; - StackLoc->Parameters.Create.SecurityContext = &SecurityContext; - - /* Check if we really need to create an object */ - if (!UseDummyFile) - { - /* Create the actual file object */ - InitializeObjectAttributes(&ObjectAttributes, - NULL, - Attributes, - NULL, - NULL); - Status = ObCreateObject(KernelMode, - IoFileObjectType, - &ObjectAttributes, - AccessMode, - NULL, - sizeof(FILE_OBJECT), - 0, - 0, - (PVOID*)&FileObject); - if (!NT_SUCCESS(Status)) - { - /* Create failed, free the IRP */ - IoFreeIrp(Irp); - - /* Dereference the device and VPB */ + /* Check if this is a direct open */ + if (!(RemainingName->Length) && + !(OpenPacket->RelatedFileObject) && + ((DesiredAccess & ~(SYNCHRONIZE | + FILE_READ_ATTRIBUTES | + READ_CONTROL | + ACCESS_SYSTEM_SECURITY | + WRITE_OWNER | + WRITE_DAC)) == 0) && + !(UseDummyFile)) + { + /* Remember this for later */ + DirectOpen = TRUE; + } + + /* Check if we have a related FO that wasn't a direct open */ + if ((OpenPacket->RelatedFileObject) && + !(OpenPacket->RelatedFileObject->Flags & FO_DIRECT_DEVICE_OPEN)) + { + /* The device object is the one we were given */ + DeviceObject = ParseObject; + + /* Check if the related FO had a VPB */ + if (OpenPacket->RelatedFileObject->Vpb) + { + /* Yes, remember it */ + Vpb = OpenPacket->RelatedFileObject->Vpb; + + /* Reference it */ + InterlockedIncrement((PLONG)&Vpb->ReferenceCount); + } + } + else + { + /* The device object is the one we were given */ + DeviceObject = OriginalDeviceObject; + + /* Check if it has a VPB */ + if ((OriginalDeviceObject->Vpb) && !(DirectOpen)) + { + /* Check if the VPB is mounted, and mount it */ + Vpb = IopCheckVpbMounted(OpenPacket, + OriginalDeviceObject, + RemainingName, + &Status); + if (!Vpb) return Status; + + /* Get the VPB's device object */ + DeviceObject = Vpb->DeviceObject; + } + + /* Check if there's an attached device */ + if (DeviceObject->AttachedDevice) + { + /* Get the attached device */ + DeviceObject = IoGetAttachedDevice(DeviceObject); + } + } + + /* If we traversed a mount point, reset the information */ + if (OpenPacket->TraversedMountPoint) + { + OpenPacket->TraversedMountPoint = FALSE; + } + + /* Check if this is a secure FSD */ + if ((DeviceObject->Characteristics & FILE_DEVICE_SECURE_OPEN) && + ((OpenPacket->RelatedFileObject) || (RemainingName->Length)) && + (!VolumeOpen)) + { + DPRINT("Fix Secure FSD support!!!\n"); + } + + /* Allocate the IRP */ + Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE); + if (!Irp) + { + /* Dereference the device and VPB, then fail */ IopDereferenceDeviceObject(OriginalDeviceObject, FALSE); if (Vpb) IopDereferenceVpbAndFree(Vpb); - - /* We failed, return status */ + return STATUS_INSUFFICIENT_RESOURCES; + } + + /* Now set the IRP data */ + Irp->RequestorMode = AccessMode; + Irp->Flags = IRP_CREATE_OPERATION | IRP_SYNCHRONOUS_API | IRP_DEFER_IO_COMPLETION; + Irp->Tail.Overlay.Thread = PsGetCurrentThread(); + Irp->UserIosb = &IoStatusBlock; + Irp->MdlAddress = NULL; + Irp->PendingReturned = FALSE; + Irp->UserEvent = NULL; + Irp->Cancel = FALSE; + Irp->CancelRoutine = NULL; + Irp->Tail.Overlay.AuxiliaryBuffer = NULL; + + /* Setup the security context */ + SecurityContext.SecurityQos = SecurityQos; + SecurityContext.AccessState = AccessState; + SecurityContext.DesiredAccess = AccessState->RemainingDesiredAccess; + SecurityContext.FullCreateOptions = OpenPacket->CreateOptions; + + /* Get the I/O Stack location */ + StackLoc = (PEXTENDED_IO_STACK_LOCATION)IoGetNextIrpStackLocation(Irp); + StackLoc->Control = 0; + + /* Check what kind of file this is */ + switch (OpenPacket->CreateFileType) + { + /* Normal file */ + case CreateFileTypeNone: + + /* Set the major function and EA Length */ + StackLoc->MajorFunction = IRP_MJ_CREATE; + StackLoc->Parameters.Create.EaLength = OpenPacket->EaLength; + + /* Set the flags */ + StackLoc->Flags = (UCHAR)OpenPacket->Options; + StackLoc->Flags |= !(Attributes & OBJ_CASE_INSENSITIVE) ? SL_CASE_SENSITIVE: 0; + break; + + /* Named pipe */ + case CreateFileTypeNamedPipe: + + /* Set the named pipe MJ and set the parameters */ + StackLoc->MajorFunction = IRP_MJ_CREATE_NAMED_PIPE; + StackLoc->Parameters.CreatePipe.Parameters = OpenPacket->ExtraCreateParameters; + break; + + /* Mailslot */ + case CreateFileTypeMailslot: + + /* Set the mailslot MJ and set the parameters */ + StackLoc->MajorFunction = IRP_MJ_CREATE_MAILSLOT; + StackLoc->Parameters.CreateMailslot.Parameters = OpenPacket->ExtraCreateParameters; + break; + } + + /* Set the common data */ + Irp->Overlay.AllocationSize = OpenPacket->AllocationSize; + Irp->AssociatedIrp.SystemBuffer = OpenPacket->EaBuffer; + StackLoc->Parameters.Create.Options = (OpenPacket->Disposition << 24) | + (OpenPacket->CreateOptions & + 0xFFFFFF); + StackLoc->Parameters.Create.FileAttributes = OpenPacket->FileAttributes; + StackLoc->Parameters.Create.ShareAccess = OpenPacket->ShareAccess; + StackLoc->Parameters.Create.SecurityContext = &SecurityContext; + + /* Check if we really need to create an object */ + if (!UseDummyFile) + { + /* Create the actual file object */ + InitializeObjectAttributes(&ObjectAttributes, + NULL, + Attributes, + NULL, + NULL); + Status = ObCreateObject(KernelMode, + IoFileObjectType, + &ObjectAttributes, + AccessMode, + NULL, + sizeof(FILE_OBJECT), + 0, + 0, + (PVOID*)&FileObject); + if (!NT_SUCCESS(Status)) + { + /* Create failed, free the IRP */ + IoFreeIrp(Irp); + + /* Dereference the device and VPB */ + IopDereferenceDeviceObject(OriginalDeviceObject, FALSE); + if (Vpb) IopDereferenceVpbAndFree(Vpb); + + /* We failed, return status */ + OpenPacket->FinalStatus = Status; + return Status; + } + + /* Clear the file object */ + RtlZeroMemory(FileObject, sizeof(FILE_OBJECT)); + + /* Check if this is Synch I/O */ + if (OpenPacket->CreateOptions & + (FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT)) + { + /* Set the synch flag */ + FileObject->Flags |= FO_SYNCHRONOUS_IO; + + /* Check if it's also alertable */ + if (OpenPacket->CreateOptions & FILE_SYNCHRONOUS_IO_ALERT) + { + /* It is, set the alertable flag */ + FileObject->Flags |= FO_ALERTABLE_IO; + } + } + + /* Check if this is synch I/O */ + if (FileObject->Flags & FO_SYNCHRONOUS_IO) + { + /* Initialize the event */ + KeInitializeEvent(&FileObject->Lock, SynchronizationEvent, FALSE); + } + + /* Check if the caller requested no intermediate buffering */ + if (OpenPacket->CreateOptions & FILE_NO_INTERMEDIATE_BUFFERING) + { + /* Set the correct flag for the FSD to read */ + FileObject->Flags |= FO_NO_INTERMEDIATE_BUFFERING; + } + + /* Check if the caller requested write through support */ + if (OpenPacket->CreateOptions & FILE_WRITE_THROUGH) + { + /* Set the correct flag for the FSD to read */ + FileObject->Flags |= FO_WRITE_THROUGH; + } + + /* Check if the caller says the file will be only read sequentially */ + if (OpenPacket->CreateOptions & FILE_SEQUENTIAL_ONLY) + { + /* Set the correct flag for the FSD to read */ + FileObject->Flags |= FO_SEQUENTIAL_ONLY; + } + + /* Check if the caller believes the file will be only read randomly */ + if (OpenPacket->CreateOptions & FILE_RANDOM_ACCESS) + { + /* Set the correct flag for the FSD to read */ + FileObject->Flags |= FO_RANDOM_ACCESS; + } + } + else + { + /* Use the dummy object instead */ + LocalFileObject = OpenPacket->LocalFileObject; + RtlZeroMemory(LocalFileObject, sizeof(DUMMY_FILE_OBJECT)); + + /* Set it up */ + FileObject = (PFILE_OBJECT)&LocalFileObject->ObjectHeader.Body; + LocalFileObject->ObjectHeader.Type = IoFileObjectType; + LocalFileObject->ObjectHeader.PointerCount = 1; + } + + /* Setup the file header */ + FileObject->Type = IO_TYPE_FILE; + FileObject->Size = sizeof(FILE_OBJECT); + FileObject->RelatedFileObject = OpenPacket->RelatedFileObject; + FileObject->DeviceObject = OriginalDeviceObject; + + /* Check if this is a direct device open */ + if (DirectOpen) FileObject->Flags |= FO_DIRECT_DEVICE_OPEN; + + /* Check if the caller wants case sensitivity */ + if (!(Attributes & OBJ_CASE_INSENSITIVE)) + { + /* Tell the driver about it */ + FileObject->Flags |= FO_OPENED_CASE_SENSITIVE; + } + + /* Now set the file object */ + Irp->Tail.Overlay.OriginalFileObject = FileObject; + StackLoc->FileObject = FileObject; + + /* Check if the file object has a name */ + if (RemainingName->Length) + { + /* Setup the unicode string */ + FileObject->FileName.MaximumLength = RemainingName->Length + + sizeof(WCHAR); + FileObject->FileName.Buffer = ExAllocatePoolWithTag(PagedPool, + FileObject-> + FileName. + MaximumLength, + TAG_IO_NAME); + if (!FileObject->FileName.Buffer) + { + /* Failed to allocate the name, free the IRP */ + IoFreeIrp(Irp); + + /* Dereference the device object and VPB */ + IopDereferenceDeviceObject(OriginalDeviceObject, FALSE); + if (Vpb) IopDereferenceVpbAndFree(Vpb); + + /* Clear the FO and dereference it */ + FileObject->DeviceObject = NULL; + if (!UseDummyFile) ObDereferenceObject(FileObject); + + /* Fail */ + return STATUS_INSUFFICIENT_RESOURCES; + } + } + + /* Copy the name */ + RtlCopyUnicodeString(&FileObject->FileName, RemainingName); + + /* Initialize the File Object event and set the FO */ + KeInitializeEvent(&FileObject->Event, NotificationEvent, FALSE); + OpenPacket->FileObject = FileObject; + + /* Queue the IRP and call the driver */ + IopQueueIrpToThread(Irp); + Status = IoCallDriver(DeviceObject, Irp); + if (Status == STATUS_PENDING) + { + /* Wait for the driver to complete the create */ + KeWaitForSingleObject(&FileObject->Event, + Executive, + KernelMode, + FALSE, + NULL); + + /* Get the new status */ + Status = IoStatusBlock.Status; + } + else + { + /* We'll have to complete it ourselves */ + ASSERT(!Irp->PendingReturned); + ASSERT(!Irp->MdlAddress); + + /* Handle name change if required */ + if (Status == STATUS_REPARSE) + { + /* Check this is a mount point */ + if (Irp->IoStatus.Information == IO_REPARSE_TAG_MOUNT_POINT) + { + PREPARSE_DATA_BUFFER ReparseData; + + /* Reparse point attributes were passed by the driver in the auxiliary buffer */ + ASSERT(Irp->Tail.Overlay.AuxiliaryBuffer != NULL); + ReparseData = (PREPARSE_DATA_BUFFER)Irp->Tail.Overlay.AuxiliaryBuffer; + + ASSERT(ReparseData->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT); + ASSERT(ReparseData->ReparseDataLength < MAXIMUM_REPARSE_DATA_BUFFER_SIZE); + ASSERT(ReparseData->Reserved < MAXIMUM_REPARSE_DATA_BUFFER_SIZE); + + IopDoNameTransmogrify(Irp, FileObject, ReparseData); + } + } + + /* Completion happens at APC_LEVEL */ + KeRaiseIrql(APC_LEVEL, &OldIrql); + + /* Get the new I/O Status block ourselves */ + IoStatusBlock = Irp->IoStatus; + Status = IoStatusBlock.Status; + + /* Manually signal the even, we can't have any waiters */ + FileObject->Event.Header.SignalState = 1; + + /* Now that we've signaled the events, de-associate the IRP */ + IopUnQueueIrpFromThread(Irp); + + /* Check if the IRP had an input buffer */ + if ((Irp->Flags & IRP_BUFFERED_IO) && + (Irp->Flags & IRP_DEALLOCATE_BUFFER)) + { + /* Free it. A driver might've tacked one on */ + ExFreePool(Irp->AssociatedIrp.SystemBuffer); + } + + /* Free the IRP and bring the IRQL back down */ + IoFreeIrp(Irp); + KeLowerIrql(OldIrql); + } + + /* Copy the I/O Status */ + OpenPacket->Information = IoStatusBlock.Information; + + /* The driver failed to create the file */ + if (!NT_SUCCESS(Status)) + { + /* Check if we have a name */ + if (FileObject->FileName.Length) + { + /* Free it */ + ExFreePoolWithTag(FileObject->FileName.Buffer, TAG_IO_NAME); + FileObject->FileName.Length = 0; + } + + /* Clear its device object */ + FileObject->DeviceObject = NULL; + + /* Save this now because the FO might go away */ + OpenCancelled = FileObject->Flags & FO_FILE_OPEN_CANCELLED ? + TRUE : FALSE; + + /* Clear the file object in the open packet */ + OpenPacket->FileObject = NULL; + + /* Dereference the file object */ + if (!UseDummyFile) ObDereferenceObject(FileObject); + + /* Dereference the device object */ + IopDereferenceDeviceObject(OriginalDeviceObject, FALSE); + + /* Unless the driver cancelled the open, dereference the VPB */ + if (!(OpenCancelled) && (Vpb)) IopDereferenceVpbAndFree(Vpb); + + /* Set the status and return */ OpenPacket->FinalStatus = Status; return Status; } - - /* Clear the file object */ - RtlZeroMemory(FileObject, sizeof(FILE_OBJECT)); - - /* Check if this is Synch I/O */ - if (OpenPacket->CreateOptions & - (FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT)) - { - /* Set the synch flag */ - FileObject->Flags |= FO_SYNCHRONOUS_IO; - - /* Check if it's also alertable */ - if (OpenPacket->CreateOptions & FILE_SYNCHRONOUS_IO_ALERT) - { - /* It is, set the alertable flag */ - FileObject->Flags |= FO_ALERTABLE_IO; - } - } - - /* Check if this is synch I/O */ - if (FileObject->Flags & FO_SYNCHRONOUS_IO) - { - /* Initialize the event */ - KeInitializeEvent(&FileObject->Lock, SynchronizationEvent, FALSE); - } - - /* Check if the caller requested no intermediate buffering */ - if (OpenPacket->CreateOptions & FILE_NO_INTERMEDIATE_BUFFERING) - { - /* Set the correct flag for the FSD to read */ - FileObject->Flags |= FO_NO_INTERMEDIATE_BUFFERING; - } - - /* Check if the caller requested write through support */ - if (OpenPacket->CreateOptions & FILE_WRITE_THROUGH) - { - /* Set the correct flag for the FSD to read */ - FileObject->Flags |= FO_WRITE_THROUGH; - } - - /* Check if the caller says the file will be only read sequentially */ - if (OpenPacket->CreateOptions & FILE_SEQUENTIAL_ONLY) - { - /* Set the correct flag for the FSD to read */ - FileObject->Flags |= FO_SEQUENTIAL_ONLY; - } - - /* Check if the caller believes the file will be only read randomly */ - if (OpenPacket->CreateOptions & FILE_RANDOM_ACCESS) - { - /* Set the correct flag for the FSD to read */ - FileObject->Flags |= FO_RANDOM_ACCESS; - } - } - else - { - /* Use the dummy object instead */ - LocalFileObject = OpenPacket->LocalFileObject; - RtlZeroMemory(LocalFileObject, sizeof(DUMMY_FILE_OBJECT)); - - /* Set it up */ - FileObject = (PFILE_OBJECT)&LocalFileObject->ObjectHeader.Body; - LocalFileObject->ObjectHeader.Type = IoFileObjectType; - LocalFileObject->ObjectHeader.PointerCount = 1; - } - - /* Setup the file header */ - FileObject->Type = IO_TYPE_FILE; - FileObject->Size = sizeof(FILE_OBJECT); - FileObject->RelatedFileObject = OpenPacket->RelatedFileObject; - FileObject->DeviceObject = OriginalDeviceObject; - - /* Check if this is a direct device open */ - if (DirectOpen) FileObject->Flags |= FO_DIRECT_DEVICE_OPEN; - - /* Check if the caller wants case sensitivity */ - if (!(Attributes & OBJ_CASE_INSENSITIVE)) - { - /* Tell the driver about it */ - FileObject->Flags |= FO_OPENED_CASE_SENSITIVE; - } - - /* Now set the file object */ - Irp->Tail.Overlay.OriginalFileObject = FileObject; - StackLoc->FileObject = FileObject; - - /* Check if the file object has a name */ - if (RemainingName->Length) - { - /* Setup the unicode string */ - FileObject->FileName.MaximumLength = RemainingName->Length + - sizeof(WCHAR); - FileObject->FileName.Buffer = ExAllocatePoolWithTag(PagedPool, - FileObject-> - FileName. - MaximumLength, - TAG_IO_NAME); - if (!FileObject->FileName.Buffer) - { - /* Failed to allocate the name, free the IRP */ - IoFreeIrp(Irp); - - /* Dereference the device object and VPB */ + else if (Status == STATUS_REPARSE) + { + if (OpenPacket->Information == IO_REPARSE || + OpenPacket->Information == IO_REPARSE_TAG_MOUNT_POINT) + { + /* Update CompleteName with reparse info which got updated in IopDoNameTransmogrify() */ + if (CompleteName->MaximumLength < FileObject->FileName.Length) + { + PWSTR NewCompleteName; + + /* Allocate a new buffer for the string */ + NewCompleteName = ExAllocatePoolWithTag(PagedPool, FileObject->FileName.Length, TAG_IO_NAME); + if (NewCompleteName == NULL) + { + OpenPacket->FinalStatus = STATUS_INSUFFICIENT_RESOURCES; + return STATUS_INSUFFICIENT_RESOURCES; + } + + /* Release the old one */ + if (CompleteName->Buffer != NULL) + { + ExFreePoolWithTag(CompleteName->Buffer, TAG_IO_NAME); + } + + /* And setup the new one */ + CompleteName->Buffer = NewCompleteName; + CompleteName->MaximumLength = FileObject->FileName.Length; + } + + /* Copy our new complete name */ + RtlCopyUnicodeString(CompleteName, &FileObject->FileName); + + if (OpenPacket->Information == IO_REPARSE_TAG_MOUNT_POINT) + { + OpenPacket->RelatedFileObject = NULL; + } + } + + /* Check if we have a name */ + if (FileObject->FileName.Length) + { + /* Free it */ + ExFreePoolWithTag(FileObject->FileName.Buffer, TAG_IO_NAME); + FileObject->FileName.Length = 0; + } + + /* Clear its device object */ + FileObject->DeviceObject = NULL; + + /* Clear the file object in the open packet */ + OpenPacket->FileObject = NULL; + + /* Dereference the file object */ + if (!UseDummyFile) ObDereferenceObject(FileObject); + + /* Dereference the device object */ IopDereferenceDeviceObject(OriginalDeviceObject, FALSE); - if (Vpb) IopDereferenceVpbAndFree(Vpb); - - /* Clear the FO and dereference it */ - FileObject->DeviceObject = NULL; - if (!UseDummyFile) ObDereferenceObject(FileObject); - - /* Fail */ - return STATUS_INSUFFICIENT_RESOURCES; - } - } - - /* Copy the name */ - RtlCopyUnicodeString(&FileObject->FileName, RemainingName); - - /* Initialize the File Object event and set the FO */ - KeInitializeEvent(&FileObject->Event, NotificationEvent, FALSE); - OpenPacket->FileObject = FileObject; - - /* Queue the IRP and call the driver */ - IopQueueIrpToThread(Irp); - Status = IoCallDriver(DeviceObject, Irp); - if (Status == STATUS_PENDING) - { - /* Wait for the driver to complete the create */ - KeWaitForSingleObject(&FileObject->Event, - Executive, - KernelMode, - FALSE, - NULL); - - /* Get the new status */ - Status = IoStatusBlock.Status; - } - else - { - /* We'll have to complete it ourselves */ - ASSERT(!Irp->PendingReturned); - ASSERT(!Irp->MdlAddress); - - /* Handle name change if required */ - if (Status == STATUS_REPARSE) - { - /* Check this is a mount point */ - if (Irp->IoStatus.Information == IO_REPARSE_TAG_MOUNT_POINT) - { - PREPARSE_DATA_BUFFER ReparseData; - - /* Reparse point attributes were passed by the driver in the auxiliary buffer */ - ASSERT(Irp->Tail.Overlay.AuxiliaryBuffer != NULL); - ReparseData = (PREPARSE_DATA_BUFFER)Irp->Tail.Overlay.AuxiliaryBuffer; - - ASSERT(ReparseData->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT); - ASSERT(ReparseData->ReparseDataLength < MAXIMUM_REPARSE_DATA_BUFFER_SIZE); - ASSERT(ReparseData->Reserved < MAXIMUM_REPARSE_DATA_BUFFER_SIZE); - - IopDoNameTransmogrify(Irp, FileObject, ReparseData); - } - } - - /* Completion happens at APC_LEVEL */ - KeRaiseIrql(APC_LEVEL, &OldIrql); - - /* Get the new I/O Status block ourselves */ - IoStatusBlock = Irp->IoStatus; - Status = IoStatusBlock.Status; - - /* Manually signal the even, we can't have any waiters */ - FileObject->Event.Header.SignalState = 1; - - /* Now that we've signaled the events, de-associate the IRP */ - IopUnQueueIrpFromThread(Irp); - - /* Check if the IRP had an input buffer */ - if ((Irp->Flags & IRP_BUFFERED_IO) && - (Irp->Flags & IRP_DEALLOCATE_BUFFER)) - { - /* Free it. A driver might've tacked one on */ - ExFreePool(Irp->AssociatedIrp.SystemBuffer); - } - - /* Free the IRP and bring the IRQL back down */ - IoFreeIrp(Irp); - KeLowerIrql(OldIrql); - } - - /* Copy the I/O Status */ - OpenPacket->Information = IoStatusBlock.Information; - - /* The driver failed to create the file */ - if (!NT_SUCCESS(Status)) - { - /* Check if we have a name */ - if (FileObject->FileName.Length) - { - /* Free it */ - ExFreePoolWithTag(FileObject->FileName.Buffer, TAG_IO_NAME); - FileObject->FileName.Length = 0; - } - - /* Clear its device object */ - FileObject->DeviceObject = NULL; - - /* Save this now because the FO might go away */ - OpenCancelled = FileObject->Flags & FO_FILE_OPEN_CANCELLED ? - TRUE : FALSE; - - /* Clear the file object in the open packet */ - OpenPacket->FileObject = NULL; - - /* Dereference the file object */ - if (!UseDummyFile) ObDereferenceObject(FileObject); - - /* Dereference the device object */ - IopDereferenceDeviceObject(OriginalDeviceObject, FALSE); - - /* Unless the driver cancelled the open, dereference the VPB */ - if (!(OpenCancelled) && (Vpb)) IopDereferenceVpbAndFree(Vpb); - - /* Set the status and return */ - OpenPacket->FinalStatus = Status; - return Status; - } - else if (Status == STATUS_REPARSE) - { - if (OpenPacket->Information == IO_REPARSE || - OpenPacket->Information == IO_REPARSE_TAG_MOUNT_POINT) - { - /* Update CompleteName with reparse info which got updated in IopDoNameTransmogrify() */ - if (CompleteName->MaximumLength < FileObject->FileName.Length) - { - PWSTR NewCompleteName; - - /* Allocate a new buffer for the string */ - NewCompleteName = ExAllocatePoolWithTag(PagedPool, FileObject->FileName.Length, TAG_IO_NAME); - if (NewCompleteName == NULL) + + /* Unless the driver cancelled the open, dereference the VPB */ + if (Vpb != NULL) IopDereferenceVpbAndFree(Vpb); + + if (OpenPacket->Information != IO_REMOUNT) + { + OpenPacket->RelatedFileObject = NULL; + + /* Inform we traversed a mount point for later attempt */ + if (OpenPacket->Information == IO_REPARSE_TAG_MOUNT_POINT) { - OpenPacket->FinalStatus = STATUS_INSUFFICIENT_RESOURCES; - return STATUS_INSUFFICIENT_RESOURCES; + OpenPacket->TraversedMountPoint = 1; } - /* Release the old one */ - if (CompleteName->Buffer != NULL) + /* In case we override checks, but got this on volume open, fail hard */ + if (OpenPacket->Override) { - ExFreePoolWithTag(CompleteName->Buffer, TAG_IO_NAME); + KeBugCheckEx(DRIVER_RETURNED_STATUS_REPARSE_FOR_VOLUME_OPEN, + (ULONG_PTR)OriginalDeviceObject, + (ULONG_PTR)DeviceObject, + (ULONG_PTR)CompleteName, + OpenPacket->Information); } - /* And setup the new one */ - CompleteName->Buffer = NewCompleteName; - CompleteName->MaximumLength = FileObject->FileName.Length; - } - - /* Copy our new complete name */ - RtlCopyUnicodeString(CompleteName, &FileObject->FileName); - - if (OpenPacket->Information == IO_REPARSE_TAG_MOUNT_POINT) - { - OpenPacket->RelatedFileObject = NULL; - } - } - - /* Check if we have a name */ - if (FileObject->FileName.Length) - { - /* Free it */ - ExFreePoolWithTag(FileObject->FileName.Buffer, TAG_IO_NAME); - FileObject->FileName.Length = 0; - } - - /* Clear its device object */ - FileObject->DeviceObject = NULL; - - /* Clear the file object in the open packet */ - OpenPacket->FileObject = NULL; - - /* Dereference the file object */ - if (!UseDummyFile) ObDereferenceObject(FileObject); - - /* Dereference the device object */ - IopDereferenceDeviceObject(OriginalDeviceObject, FALSE); - - /* Unless the driver cancelled the open, dereference the VPB */ - if (Vpb != NULL) IopDereferenceVpbAndFree(Vpb); - - if (OpenPacket->Information != IO_REMOUNT) - { - OpenPacket->RelatedFileObject = NULL; - - /* Inform we traversed a mount point for later attempt */ - if (OpenPacket->Information == IO_REPARSE_TAG_MOUNT_POINT) - { - OpenPacket->TraversedMountPoint = 1; - } - - /* In case we override checks, but got this on volume open, fail hard */ - if (OpenPacket->Override) - { - KeBugCheckEx(DRIVER_RETURNED_STATUS_REPARSE_FOR_VOLUME_OPEN, - (ULONG_PTR)OriginalDeviceObject, - (ULONG_PTR)DeviceObject, - (ULONG_PTR)CompleteName, - OpenPacket->Information); - } - - /* Return to IO/OB so that information can be upgraded */ - return STATUS_REPARSE; - } - - /* FIXME: At that point, we should loop again and reattempt an opening */ - ASSERT(FALSE); - } + /* Return to IO/OB so that information can be upgraded */ + return STATUS_REPARSE; + } + + /* Loop again and reattempt an opening */ + continue; + } + + break; + } + + if (Attempt == IOP_MAX_REPARSE_TRAVERSAL) + return STATUS_UNSUCCESSFUL; /* Get the owner of the File Object */ OwnerDevice = IoGetRelatedDeviceObject(FileObject);
9 years, 8 months
1
0
0
0
[aandrejevic] 67066: [NTVDM] Fix the shift key. Improve the BIOS keyboard handler. Do not append modifier keys to the buffer. CORE-8231 #resolve #comment Fixed in revision r67066.
by aandrejevic@svn.reactos.org
Author: aandrejevic Date: Sun Apr 5 18:40:18 2015 New Revision: 67066 URL:
http://svn.reactos.org/svn/reactos?rev=67066&view=rev
Log: [NTVDM] Fix the shift key. Improve the BIOS keyboard handler. Do not append modifier keys to the buffer. CORE-8231 #resolve #comment Fixed in revision r67066. Modified: trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/kbdbios32.c Modified: trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/kbdbios32.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/bios…
============================================================================== --- trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/kbdbios32.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/kbdbios32.c [iso-8859-1] Sun Apr 5 18:40:18 2015 @@ -232,33 +232,51 @@ /* Check if this is a key press or release */ if (!(ScanCode & (1 << 7))) { - /* Key press */ - if (VirtualKey == VK_NUMLOCK || - VirtualKey == VK_CAPITAL || - VirtualKey == VK_SCROLL || - VirtualKey == VK_INSERT) - { - /* For toggle keys, toggle the lowest bit in the keyboard map */ - BiosKeyboardMap[VirtualKey] ^= ~(1 << 0); - } - - /* Set the highest bit */ + /* Key press, set the highest bit */ BiosKeyboardMap[VirtualKey] |= (1 << 7); - Character = 0; - - /* If ALT isn't held down, find out which character this is */ - if (!((BiosKeyboardMap[VK_MENU] | BiosKeyboardMap[VK_RMENU] | BiosKeyboardMap[VK_LMENU]) & (1 << 7))) - { - if (ToAscii(VirtualKey, ScanCode, BiosKeyboardMap, &Character, 0) == 0) - { - /* Not ASCII */ + switch (VirtualKey) + { + case VK_NUMLOCK: + case VK_CAPITAL: + case VK_SCROLL: + case VK_INSERT: + { + /* For toggle keys, toggle the lowest bit in the keyboard map */ + BiosKeyboardMap[VirtualKey] ^= ~(1 << 0); + break; + } + + case VK_CONTROL: + case VK_SHIFT: + case VK_LSHIFT: + case VK_RSHIFT: + case VK_MENU: + case VK_LMENU: + case VK_RMENU: + { + /* Modifier keys don't go in the buffer */ + break; + } + + default: + { Character = 0; - } - } - - /* Push it onto the BIOS keyboard queue */ - BiosKbdBufferPush(MAKEWORD(Character, ScanCode)); + + /* If ALT isn't held down, find out which character this is */ + if (!(Bda->KeybdShiftFlags & (BDA_KBDFLAG_ALT | BDA_KBDFLAG_LALT | BDA_KBDFLAG_RALT))) + { + if (ToAscii(VirtualKey, ScanCode, BiosKeyboardMap, &Character, 0) == 0) + { + /* Not ASCII */ + Character = 0; + } + } + + /* Push it onto the BIOS keyboard queue */ + BiosKbdBufferPush(MAKEWORD(Character, ScanCode)); + } + } } else { @@ -270,6 +288,7 @@ Bda->KeybdShiftFlags = 0; /* Set the appropriate flags based on the state */ + if (BiosKeyboardMap[VK_SHIFT] & (1 << 7)) Bda->KeybdShiftFlags |= BDA_KBDFLAG_LSHIFT; if (BiosKeyboardMap[VK_RSHIFT] & (1 << 7)) Bda->KeybdShiftFlags |= BDA_KBDFLAG_RSHIFT; if (BiosKeyboardMap[VK_LSHIFT] & (1 << 7)) Bda->KeybdShiftFlags |= BDA_KBDFLAG_LSHIFT; if (BiosKeyboardMap[VK_CONTROL] & (1 << 7)) Bda->KeybdShiftFlags |= BDA_KBDFLAG_CTRL;
9 years, 8 months
1
0
0
0
[hbelusca] 67065: [CMD]: Check for cmd_realloc returned value. Adapted from patch by Patrick Martin, see CORE-7298.
by hbelusca@svn.reactos.org
Author: hbelusca Date: Sun Apr 5 17:11:29 2015 New Revision: 67065 URL:
http://svn.reactos.org/svn/reactos?rev=67065&view=rev
Log: [CMD]: Check for cmd_realloc returned value. Adapted from patch by Patrick Martin, see CORE-7298. Modified: trunk/reactos/base/shell/cmd/path.c trunk/reactos/base/shell/cmd/where.c Modified: trunk/reactos/base/shell/cmd/path.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/cmd/path.c?rev=…
============================================================================== --- trunk/reactos/base/shell/cmd/path.c [iso-8859-1] (original) +++ trunk/reactos/base/shell/cmd/path.c [iso-8859-1] Sun Apr 5 17:11:29 2015 @@ -59,7 +59,13 @@ } else if (dwBuffer > ENV_BUFFER_SIZE) { + LPTSTR pszOldBuffer = pszBuffer; pszBuffer = (LPTSTR)cmd_realloc (pszBuffer, dwBuffer * sizeof (TCHAR)); + if (pszBuffer == NULL) + { + cmd_free(pszOldBuffer); + return 1; + } GetEnvironmentVariable (_T("PATH"), pszBuffer, dwBuffer); } Modified: trunk/reactos/base/shell/cmd/where.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/cmd/where.c?rev…
============================================================================== --- trunk/reactos/base/shell/cmd/where.c [iso-8859-1] (original) +++ trunk/reactos/base/shell/cmd/where.c [iso-8859-1] Sun Apr 5 17:11:29 2015 @@ -152,7 +152,13 @@ dwBuffer = GetEnvironmentVariable (_T("PATHEXT"), pszPathExt, ENV_BUFFER_SIZE); if (dwBuffer > ENV_BUFFER_SIZE) { + LPTSTR pszOldPathExt = pszPathExt; pszPathExt = (LPTSTR)cmd_realloc (pszPathExt, dwBuffer * sizeof (TCHAR)); + if (pszPathExt == NULL) + { + cmd_free(pszOldPathExt); + return FALSE; + } GetEnvironmentVariable (_T("PATHEXT"), pszPathExt, dwBuffer); _tcslwr(pszPathExt); } @@ -184,7 +190,14 @@ dwBuffer = GetEnvironmentVariable (_T("PATH"), pszPath, ENV_BUFFER_SIZE); if (dwBuffer > ENV_BUFFER_SIZE) { + LPTSTR pszOldPath = pszPath; pszPath = (LPTSTR)cmd_realloc (pszPath, dwBuffer * sizeof (TCHAR)); + if (pszPath == NULL) + { + cmd_free(pszOldPath); + cmd_free(pszPathExt); + return FALSE; + } GetEnvironmentVariable (_T("PATH"), pszPath, dwBuffer); }
9 years, 8 months
1
0
0
0
← Newer
1
...
39
40
41
42
43
44
45
...
49
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
39
40
41
42
43
44
45
46
47
48
49
Results per page:
10
25
50
100
200