winehq.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2025
February
January
2024
December
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
February
January
2012
December
November
October
September
August
July
June
May
April
March
February
January
2011
December
November
October
September
August
July
June
May
April
March
February
January
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008
December
November
October
September
August
July
June
May
April
March
February
January
2007
December
November
October
September
August
July
June
May
April
March
February
January
2006
December
November
October
September
August
July
June
May
April
March
February
January
2005
December
November
October
September
August
July
June
May
April
March
February
January
2004
December
November
October
September
August
July
June
May
April
March
February
January
2003
December
November
October
September
August
July
June
May
April
March
February
January
2002
December
November
October
September
August
July
June
May
April
March
February
January
2001
December
November
October
September
August
July
June
May
April
March
February
List overview
wine-commits
June 2015
----- 2025 -----
February 2025
January 2025
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
----- 2010 -----
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
June 2010
May 2010
April 2010
March 2010
February 2010
January 2010
----- 2009 -----
December 2009
November 2009
October 2009
September 2009
August 2009
July 2009
June 2009
May 2009
April 2009
March 2009
February 2009
January 2009
----- 2008 -----
December 2008
November 2008
October 2008
September 2008
August 2008
July 2008
June 2008
May 2008
April 2008
March 2008
February 2008
January 2008
----- 2007 -----
December 2007
November 2007
October 2007
September 2007
August 2007
July 2007
June 2007
May 2007
April 2007
March 2007
February 2007
January 2007
----- 2006 -----
December 2006
November 2006
October 2006
September 2006
August 2006
July 2006
June 2006
May 2006
April 2006
March 2006
February 2006
January 2006
----- 2005 -----
December 2005
November 2005
October 2005
September 2005
August 2005
July 2005
June 2005
May 2005
April 2005
March 2005
February 2005
January 2005
----- 2004 -----
December 2004
November 2004
October 2004
September 2004
August 2004
July 2004
June 2004
May 2004
April 2004
March 2004
February 2004
January 2004
----- 2003 -----
December 2003
November 2003
October 2003
September 2003
August 2003
July 2003
June 2003
May 2003
April 2003
March 2003
February 2003
January 2003
----- 2002 -----
December 2002
November 2002
October 2002
September 2002
August 2002
July 2002
June 2002
May 2002
April 2002
March 2002
February 2002
January 2002
----- 2001 -----
December 2001
November 2001
October 2001
September 2001
August 2001
July 2001
June 2001
May 2001
April 2001
March 2001
February 2001
wine-commits@winehq.org
2 participants
610 discussions
Start a n
N
ew thread
Erich E. Hoover : kernel32/tests: Convert GetVolumePathName tests into a list.
by Alexandre Julliard
23 Jun '15
23 Jun '15
Module: wine Branch: master Commit: b29b0d2cff2bff0b148fc2d63499f4f97ee947ce URL:
http://source.winehq.org/git/wine.git/?a=commit;h=b29b0d2cff2bff0b148fc2d63…
Author: Erich E. Hoover <erich.e.hoover(a)wine-staging.com> Date: Wed Jun 17 19:28:54 2015 -0600 kernel32/tests: Convert GetVolumePathName tests into a list. --- dlls/kernel32/tests/volume.c | 137 +++++++++++++++++++++++-------------------- 1 file changed, 74 insertions(+), 63 deletions(-) diff --git a/dlls/kernel32/tests/volume.c b/dlls/kernel32/tests/volume.c index 2243da9..2bb2603 100644 --- a/dlls/kernel32/tests/volume.c +++ b/dlls/kernel32/tests/volume.c @@ -591,79 +591,90 @@ static void test_disk_extents(void) static void test_GetVolumePathNameA(void) { - BOOL ret; - char volume[MAX_PATH]; - char expected[] = "C:\\", pathC1[] = "C:\\", pathC2[] = "C::"; + char volume_path[MAX_PATH]; + struct { + const char *file_name; + const char *path_name; + DWORD path_len; + DWORD error; + DWORD broken_error; + } test_paths[] = { + { /* test 0: NULL parameters, 0 output length */ + NULL, NULL, 0, + ERROR_INVALID_PARAMETER, 0xdeadbeef /* winxp */ + }, + { /* test 1: empty input, NULL output, 0 output length */ + "", NULL, 0, + ERROR_INVALID_PARAMETER, 0xdeadbeef /* winxp */ + }, + { /* test 2: valid input, NULL output, 0 output length */ + "C:\\", NULL, 0, + ERROR_INVALID_PARAMETER, ERROR_FILENAME_EXCED_RANGE /* winxp */ + }, + { /* test 3: valid input, valid output, 0 output length */ + "C:\\", "C:\\", 0, + ERROR_INVALID_PARAMETER, ERROR_FILENAME_EXCED_RANGE /* winxp */ + }, + { /* test 4: valid input, valid output, 1 output length */ + "C:\\", "C:\\", 1, + ERROR_FILENAME_EXCED_RANGE, NO_ERROR + }, + { /* test 5: valid input, valid output, valid output length */ + "C:\\", "C:\\", sizeof(volume_path), + NO_ERROR, NO_ERROR + }, + { /* test 6: lowercase input, uppercase output, valid output length */ + "c:\\", "C:\\", sizeof(volume_path), + NO_ERROR, NO_ERROR + }, + { /* test 7: poor quality input, valid output, valid output length */ + "C::", "C:\\", sizeof(volume_path), + NO_ERROR, NO_ERROR + }, + { /* test 8: really bogus input, valid output, 1 output length */ + "\\\\$$$", "C:\\", 1, + ERROR_INVALID_NAME, ERROR_FILENAME_EXCED_RANGE + }, + }; + BOOL ret, success; DWORD error; + UINT i; + /* GetVolumePathNameA is not present before w2k */ if (!pGetVolumePathNameA) { win_skip("required functions not found\n"); return; } - SetLastError( 0xdeadbeef ); - ret = pGetVolumePathNameA(NULL, NULL, 0); - error = GetLastError(); - ok(!ret, "expected failure\n"); - ok(error == ERROR_INVALID_PARAMETER - || broken( error == 0xdeadbeef) /* <=XP */, - "expected ERROR_INVALID_PARAMETER got %u\n", error); - - SetLastError( 0xdeadbeef ); - ret = pGetVolumePathNameA("", NULL, 0); - error = GetLastError(); - ok(!ret, "expected failure\n"); - ok(error == ERROR_INVALID_PARAMETER - || broken( error == 0xdeadbeef) /* <=XP */, - "expected ERROR_INVALID_PARAMETER got %u\n", error); + for (i=0; i<sizeof(test_paths)/sizeof(test_paths[0]); i++) + { + char *output = (test_paths[i].path_name != NULL ? volume_path : NULL); + BOOL expected_ret = test_paths[i].error == NO_ERROR ? TRUE : FALSE; - SetLastError( 0xdeadbeef ); - ret = pGetVolumePathNameA(pathC1, NULL, 0); - error = GetLastError(); - ok(!ret, "expected failure\n"); - ok(error == ERROR_INVALID_PARAMETER - || broken(error == ERROR_FILENAME_EXCED_RANGE) /* <=XP */, - "expected ERROR_INVALID_PARAMETER got %u\n", error); + volume_path[0] = 0; + SetLastError( 0xdeadbeef ); + ret = pGetVolumePathNameA( test_paths[i].file_name, output, test_paths[i].path_len ); + error = GetLastError(); + ok(ret == expected_ret, "GetVolumePathName test %d %s unexpectedly.\n", + i, test_paths[i].error == NO_ERROR ? "failed" : "succeeded"); - SetLastError( 0xdeadbeef ); - ret = pGetVolumePathNameA(pathC1, volume, 0); - error = GetLastError(); - ok(!ret, "expected failure\n"); - ok(error == ERROR_INVALID_PARAMETER - || broken(error == ERROR_FILENAME_EXCED_RANGE ) /* <=XP */, - "expected ERROR_INVALID_PARAMETER got %u\n", error); - - SetLastError( 0xdeadbeef ); - ret = pGetVolumePathNameA(pathC1, volume, 1); - error = GetLastError(); - ok(!ret, "expected failure\n"); - ok(error == ERROR_FILENAME_EXCED_RANGE, "expected ERROR_FILENAME_EXCED_RANGE got %u\n", error); - - volume[0] = '\0'; - ret = pGetVolumePathNameA(pathC1, volume, sizeof(volume)); - ok(ret, "expected success\n"); - ok(!strcmp(expected, volume), "expected name '%s', returned '%s'\n", pathC1, volume); - - pathC1[0] = tolower(pathC1[0]); - volume[0] = '\0'; - ret = pGetVolumePathNameA(pathC1, volume, sizeof(volume)); - ok(ret, "expected success\n"); - ok(!strcmp(expected, volume) || broken(!strcasecmp(expected, volume)) /* <=XP */, - "expected name '%s', returned '%s'\n", expected, volume); - - volume[0] = '\0'; - ret = pGetVolumePathNameA(pathC2, volume, sizeof(volume)); - ok(ret, "expected success\n"); - ok(!strcmp(expected, volume), "expected name '%s', returned '%s'\n", expected, volume); - - /* test an invalid path */ - SetLastError( 0xdeadbeef ); - ret = pGetVolumePathNameA("\\\\$$$", volume, 1); - error = GetLastError(); - ok(!ret, "expected failure\n"); - ok(error == ERROR_INVALID_NAME || broken(ERROR_FILENAME_EXCED_RANGE) /* <=2000 */, - "expected ERROR_INVALID_NAME got %u\n", error); + if (ret) + { + /* If we succeeded then make sure the path is correct */ + success = (strcmp( volume_path, test_paths[i].path_name ) == 0) + || broken(strcasecmp( volume_path, test_paths[i].path_name ) == 0) /* XP */; + ok(success, "GetVolumePathName test %d unexpectedly returned path %s (expected %s).\n", + i, volume_path, test_paths[i].path_name); + } + else + { + /* On success Windows always returns ERROR_MORE_DATA, so only worry about failure */ + success = (error == test_paths[i].error || broken(error == test_paths[i].broken_error)); + ok(success, "GetVolumePathName test %d unexpectedly returned error 0x%x (expected 0x%x).\n", + i, error, test_paths[i].error); + } + } } static void test_GetVolumePathNamesForVolumeNameA(void)
1
0
0
0
Erich E. Hoover : kernel32: Implement GetVolumePathName.
by Alexandre Julliard
23 Jun '15
23 Jun '15
Module: wine Branch: master Commit: f6c7e247add306e757c6b75e99dd23eba087f9f8 URL:
http://source.winehq.org/git/wine.git/?a=commit;h=f6c7e247add306e757c6b75e9…
Author: Erich E. Hoover <erich.e.hoover(a)wine-staging.com> Date: Wed Jun 17 19:28:39 2015 -0600 kernel32: Implement GetVolumePathName. The purpose of this function is to return the most fundamental path without leaving a filesystem. Steam uses this so that it can use inode searches, without this functionality some installations/validations will fail if the Steam Library is not on the same drive as Steam itself (symlink'd to another location). --- dlls/kernel32/tests/volume.c | 3 -- dlls/kernel32/volume.c | 121 ++++++++++++++++++++++++++++++++++++++----- 2 files changed, 107 insertions(+), 17 deletions(-) diff --git a/dlls/kernel32/tests/volume.c b/dlls/kernel32/tests/volume.c index e934dee..2243da9 100644 --- a/dlls/kernel32/tests/volume.c +++ b/dlls/kernel32/tests/volume.c @@ -649,15 +649,12 @@ static void test_GetVolumePathNameA(void) volume[0] = '\0'; ret = pGetVolumePathNameA(pathC1, volume, sizeof(volume)); ok(ret, "expected success\n"); -todo_wine ok(!strcmp(expected, volume) || broken(!strcasecmp(expected, volume)) /* <=XP */, "expected name '%s', returned '%s'\n", expected, volume); volume[0] = '\0'; ret = pGetVolumePathNameA(pathC2, volume, sizeof(volume)); -todo_wine ok(ret, "expected success\n"); -todo_wine ok(!strcmp(expected, volume), "expected name '%s', returned '%s'\n", expected, volume); /* test an invalid path */ diff --git a/dlls/kernel32/volume.c b/dlls/kernel32/volume.c index d06dd05..a6b2b3d 100644 --- a/dlls/kernel32/volume.c +++ b/dlls/kernel32/volume.c @@ -1792,7 +1792,7 @@ BOOL WINAPI GetVolumePathNameA(LPCSTR filename, LPSTR volumepathname, DWORD bufl BOOL ret; WCHAR *filenameW = NULL, *volumeW = NULL; - FIXME("(%s, %p, %d), stub!\n", debugstr_a(filename), volumepathname, buflen); + TRACE("(%s, %p, %d)\n", debugstr_a(filename), volumepathname, buflen); if (filename && !(filenameW = FILE_name_AtoW( filename, FALSE ))) return FALSE; @@ -1808,12 +1808,27 @@ BOOL WINAPI GetVolumePathNameA(LPCSTR filename, LPSTR volumepathname, DWORD bufl /*********************************************************************** * GetVolumePathNameW (KERNEL32.@) + * + * This routine is intended to find the most basic path on the same filesystem + * for any particular path name. Since we can have very complicated drive/path + * relationships on Unix systems, due to symbolic links, the safest way to + * handle this is to start with the full path and work our way back folder by + * folder unil we find a folder on a different drive (or run out of folders). */ BOOL WINAPI GetVolumePathNameW(LPCWSTR filename, LPWSTR volumepathname, DWORD buflen) { - const WCHAR *p = filename; + static const WCHAR ntprefixW[] = { '\\','\\','?','\\',0 }; + static const WCHAR fallbackpathW[] = { 'C',':','\\',0 }; + NTSTATUS status = STATUS_SUCCESS; + WCHAR *volumenameW = NULL, *c; + int pos, last_pos, stop_pos; + UNICODE_STRING nt_name; + ANSI_STRING unix_name; + BOOL first_run = TRUE; + dev_t search_dev = 0; + struct stat st; - FIXME("(%s, %p, %d), stub!\n", debugstr_w(filename), volumepathname, buflen); + TRACE("(%s, %p, %d)\n", debugstr_w(filename), volumepathname, buflen); if (!filename || !volumepathname || !buflen) { @@ -1821,24 +1836,102 @@ BOOL WINAPI GetVolumePathNameW(LPCWSTR filename, LPWSTR volumepathname, DWORD bu return FALSE; } - if (p && tolowerW(p[0]) >= 'a' && tolowerW(p[0]) <= 'z' && p[1] ==':' && p[2] == '\\') + last_pos = pos = strlenW( filename ); + /* allocate enough memory for searching the path (need room for a slash and a NULL terminator) */ + if (!(volumenameW = HeapAlloc( GetProcessHeap(), 0, (pos + 2) * sizeof(WCHAR) ))) { - if (buflen < 4) + SetLastError( ERROR_NOT_ENOUGH_MEMORY ); + return FALSE; + } + strcpyW( volumenameW, filename ); + stop_pos = 0; + /* stop searching slashes early for NT-type and nearly NT-type paths */ + if (strncmpW(ntprefixW, filename, strlenW(ntprefixW)) == 0) + stop_pos = strlenW(ntprefixW)-1; + else if (strncmpW(ntprefixW, filename, 2) == 0) + stop_pos = 2; + + do + { + volumenameW[pos+0] = '\\'; + volumenameW[pos+1] = '\0'; + if (!RtlDosPathNameToNtPathName_U( volumenameW, &nt_name, NULL, NULL )) + goto cleanup; + volumenameW[pos] = '\0'; + status = wine_nt_to_unix_file_name( &nt_name, &unix_name, FILE_OPEN, FALSE ); + RtlFreeUnicodeString( &nt_name ); + if (status == STATUS_SUCCESS) { - SetLastError(ERROR_FILENAME_EXCED_RANGE); - return FALSE; + if (stat( unix_name.Buffer, &st ) != 0) + { + RtlFreeAnsiString( &unix_name ); + status = STATUS_OBJECT_NAME_INVALID; + goto cleanup; + } + if (first_run) + { + first_run = FALSE; + search_dev = st.st_dev; + } + else if (st.st_dev != search_dev) + { + /* folder is on a new filesystem, return the last folder */ + RtlFreeAnsiString( &unix_name ); + break; + } } - volumepathname[0] = p[0]; - volumepathname[1] = ':'; - volumepathname[2] = '\\'; - volumepathname[3] = 0; - return TRUE; + RtlFreeAnsiString( &unix_name ); + last_pos = pos; + c = strrchrW( volumenameW, '\\' ); + if (c != NULL) + pos = c-volumenameW; + } while (c != NULL && pos > stop_pos); + + if (status != STATUS_SUCCESS) + { + /* the path was completely invalid */ + if (filename[0] == '\\') + { + /* NT-style paths fail */ + status = STATUS_OBJECT_NAME_INVALID; + goto cleanup; + } + + /* DOS-style paths revert to C:\ (anything not beginning with a slash) */ + last_pos = strlenW(fallbackpathW) - 1; /* points to \\ */ + filename = fallbackpathW; + status = STATUS_SUCCESS; } - SetLastError(ERROR_INVALID_NAME); - return FALSE; + if (last_pos + 1 <= buflen) + { + WCHAR *p; + memcpy(volumepathname, filename, last_pos * sizeof(WCHAR)); + if (last_pos + 2 <= buflen) volumepathname[last_pos++] = '\\'; + volumepathname[last_pos] = '\0'; + + /* Normalize path */ + for (p = volumepathname; *p; p++) if (*p == '/') *p = '\\'; + + /* DOS-style paths always return upper-case drive letters */ + if (volumepathname[1] == ':') + volumepathname[0] = toupperW(volumepathname[0]); + + TRACE("Successfully translated path %s to mount-point %s\n", + debugstr_w(filename), debugstr_w(volumepathname)); + } + else + status = STATUS_NAME_TOO_LONG; + +cleanup: + HeapFree( GetProcessHeap(), 0, volumenameW ); + + if (status != STATUS_SUCCESS) + SetLastError( RtlNtStatusToDosError(status) ); + return (status == STATUS_SUCCESS); } + /*********************************************************************** * GetVolumePathNamesForVolumeNameA (KERNEL32.@) */
1
0
0
0
Iván Matellanes : msvcirt: Add implementation of streambuf::sgetn/sputn.
by Alexandre Julliard
23 Jun '15
23 Jun '15
Module: wine Branch: master Commit: 7b877fbce8dab7d60faa29a1e97d0d73ee39a532 URL:
http://source.winehq.org/git/wine.git/?a=commit;h=7b877fbce8dab7d60faa29a1e…
Author: Iván Matellanes <matellanesivan(a)gmail.com> Date: Sat Jun 20 16:40:21 2015 +0200 msvcirt: Add implementation of streambuf::sgetn/sputn. --- dlls/msvcirt/msvcirt.c | 18 ++++++++++++++++++ dlls/msvcirt/msvcirt.spec | 8 ++++---- dlls/msvcrt20/msvcrt20.spec | 8 ++++---- dlls/msvcrt40/msvcrt40.spec | 8 ++++---- 4 files changed, 30 insertions(+), 12 deletions(-) diff --git a/dlls/msvcirt/msvcirt.c b/dlls/msvcirt/msvcirt.c index e8faa54..35777e3 100644 --- a/dlls/msvcirt/msvcirt.c +++ b/dlls/msvcirt/msvcirt.c @@ -502,6 +502,7 @@ void __thiscall streambuf_unlock(streambuf *this) /* ?xsgetn@streambuf@@UAEHPADH@Z */ /* ?xsgetn@streambuf@@UEAAHPEADH@Z */ DEFINE_THISCALL_WRAPPER(streambuf_xsgetn, 12) +#define call_streambuf_xsgetn(this, buffer, count) CALL_VTBL_FUNC(this, 24, int, (streambuf*, char*, int), (this, buffer, count)) int __thiscall streambuf_xsgetn(streambuf *this, char *buffer, int count) { int copied = 0, chunk; @@ -533,6 +534,7 @@ int __thiscall streambuf_xsgetn(streambuf *this, char *buffer, int count) /* ?xsputn@streambuf@@UAEHPBDH@Z */ /* ?xsputn@streambuf@@UEAAHPEBDH@Z */ DEFINE_THISCALL_WRAPPER(streambuf_xsputn, 12) +#define call_streambuf_xsputn(this, data, length) CALL_VTBL_FUNC(this, 20, int, (streambuf*, const char*, int), (this, data, length)) int __thiscall streambuf_xsputn(streambuf *this, const char *data, int length) { int copied = 0, chunk; @@ -579,6 +581,22 @@ int __thiscall streambuf_sputc(streambuf *this, int ch) return (this->pptr < this->epptr) ? *this->pptr++ = ch : call_streambuf_overflow(this, ch); } +/* ?sgetn@streambuf@@QAEHPADH@Z */ +/* ?sgetn@streambuf@@QEAAHPEADH@Z */ +DEFINE_THISCALL_WRAPPER(streambuf_sgetn, 12) +int __thiscall streambuf_sgetn(streambuf *this, char *buffer, int count) +{ + return call_streambuf_xsgetn(this, buffer, count); +} + +/* ?sputn@streambuf@@QAEHPBDH@Z */ +/* ?sputn@streambuf@@QEAAHPEBDH@Z */ +DEFINE_THISCALL_WRAPPER(streambuf_sputn, 12) +int __thiscall streambuf_sputn(streambuf *this, const char *data, int length) +{ + return call_streambuf_xsputn(this, data, length); +} + /****************************************************************** * ??1ios@@UAE@XZ (MSVCRTI.@) * class ios & __thiscall ios::-ios<<(void) diff --git a/dlls/msvcirt/msvcirt.spec b/dlls/msvcirt/msvcirt.spec index 7d6df5f..2a65e2f 100644 --- a/dlls/msvcirt/msvcirt.spec +++ b/dlls/msvcirt/msvcirt.spec @@ -695,8 +695,8 @@ @ stub -arch=win64 ?setrwbuf@stdiobuf@@QEAAHHH@Z @ thiscall -arch=win32 ?sgetc@streambuf@@QAEHXZ(ptr) streambuf_sgetc @ cdecl -arch=win64 ?sgetc@streambuf@@QEAAHXZ(ptr) streambuf_sgetc -@ stub -arch=win32 ?sgetn@streambuf@@QAEHPADH@Z # int __thiscall streambuf::sgetn(char *,int) -@ stub -arch=win64 ?sgetn@streambuf@@QEAAHPEADH@Z +@ thiscall -arch=win32 ?sgetn@streambuf@@QAEHPADH@Z(ptr ptr long) streambuf_sgetn +@ cdecl -arch=win64 ?sgetn@streambuf@@QEAAHPEADH@Z(ptr ptr long) streambuf_sgetn # @ extern ?sh_none@filebuf@@2HB # static int const filebuf::sh_none # @ extern ?sh_read@filebuf@@2HB # static int const filebuf::sh_read # @ extern ?sh_write@filebuf@@2HB # static int const filebuf::sh_write @@ -706,8 +706,8 @@ @ stub -arch=win64 ?sputbackc@streambuf@@QEAAHD@Z @ thiscall -arch=win32 ?sputc@streambuf@@QAEHH@Z(ptr long) streambuf_sputc @ cdecl -arch=win64 ?sputc@streambuf@@QEAAHH@Z(ptr long) streambuf_sputc -@ stub -arch=win32 ?sputn@streambuf@@QAEHPBDH@Z # int __thiscall streambuf::sputn(char const *,int) -@ stub -arch=win64 ?sputn@streambuf@@QEAAHPEBDH@Z +@ thiscall -arch=win32 ?sputn@streambuf@@QAEHPBDH@Z(ptr str long) streambuf_sputn +@ cdecl -arch=win64 ?sputn@streambuf@@QEAAHPEBDH@Z(ptr str long) streambuf_sputn @ stub -arch=win32 ?stdiofile@stdiobuf@@QAEPAU_iobuf@@XZ # struct _iobuf * __thiscall stdiobuf::stdiofile(void) @ stub -arch=win64 ?stdiofile@stdiobuf@@QEAAPEAU_iobuf@@XZ @ stub -arch=win32 ?stossc@streambuf@@QAEXXZ # void __thiscall streambuf::stossc(void) diff --git a/dlls/msvcrt20/msvcrt20.spec b/dlls/msvcrt20/msvcrt20.spec index 79f5902..1be499b 100644 --- a/dlls/msvcrt20/msvcrt20.spec +++ b/dlls/msvcrt20/msvcrt20.spec @@ -683,8 +683,8 @@ @ stub -arch=win64 ?setrwbuf@stdiobuf@@QEAAHHH@Z @ thiscall -arch=win32 ?sgetc@streambuf@@QAEHXZ(ptr) msvcirt.?sgetc@streambuf@@QAEHXZ @ cdecl -arch=win64 ?sgetc@streambuf@@QEAAHXZ(ptr) msvcirt.?sgetc@streambuf@@QEAAHXZ -@ stub -arch=win32 ?sgetn@streambuf@@QAEHPADH@Z -@ stub -arch=win64 ?sgetn@streambuf@@QEAAHPEADH@Z +@ thiscall -arch=win32 ?sgetn@streambuf@@QAEHPADH@Z(ptr ptr long) msvcirt.?sgetn@streambuf@@QAEHPADH@Z +@ cdecl -arch=win64 ?sgetn@streambuf@@QEAAHPEADH@Z(ptr ptr long) msvcirt.?sgetn@streambuf@@QEAAHPEADH@Z # @ extern ?sh_none@filebuf@@2HB # @ extern ?sh_read@filebuf@@2HB # @ extern ?sh_write@filebuf@@2HB @@ -694,8 +694,8 @@ @ stub -arch=win64 ?sputbackc@streambuf@@QEAAHD@Z @ thiscall -arch=win32 ?sputc@streambuf@@QAEHH@Z(ptr long) msvcirt.?sputc@streambuf@@QAEHH@Z @ cdecl -arch=win64 ?sputc@streambuf@@QEAAHH@Z(ptr long) msvcirt.?sputc@streambuf@@QEAAHH@Z -@ stub -arch=win32 ?sputn@streambuf@@QAEHPBDH@Z -@ stub -arch=win64 ?sputn@streambuf@@QEAAHPEBDH@Z +@ thiscall -arch=win32 ?sputn@streambuf@@QAEHPBDH@Z(ptr str long) msvcirt.?sputn@streambuf@@QAEHPBDH@Z +@ cdecl -arch=win64 ?sputn@streambuf@@QEAAHPEBDH@Z(ptr str long) msvcirt.?sputn@streambuf@@QEAAHPEBDH@Z @ stub -arch=win32 ?stdiofile@stdiobuf@@QAEPAU_iobuf@@XZ @ stub -arch=win64 ?stdiofile@stdiobuf@@QEAAPEAU_iobuf@@XZ @ stub -arch=win32 ?stossc@streambuf@@QAEXXZ diff --git a/dlls/msvcrt40/msvcrt40.spec b/dlls/msvcrt40/msvcrt40.spec index 86d3985..94d9035 100644 --- a/dlls/msvcrt40/msvcrt40.spec +++ b/dlls/msvcrt40/msvcrt40.spec @@ -755,8 +755,8 @@ @ stub -arch=win64 ?setrwbuf@stdiobuf@@QEAAHHH@Z @ thiscall -arch=win32 ?sgetc@streambuf@@QAEHXZ(ptr) msvcirt.?sgetc@streambuf@@QAEHXZ @ cdecl -arch=win64 ?sgetc@streambuf@@QEAAHXZ(ptr) msvcirt.?sgetc@streambuf@@QEAAHXZ -@ stub -arch=win32 ?sgetn@streambuf@@QAEHPADH@Z -@ stub -arch=win64 ?sgetn@streambuf@@QEAAHPEADH@Z +@ thiscall -arch=win32 ?sgetn@streambuf@@QAEHPADH@Z(ptr ptr long) msvcirt.?sgetn@streambuf@@QAEHPADH@Z +@ cdecl -arch=win64 ?sgetn@streambuf@@QEAAHPEADH@Z(ptr ptr long) msvcirt.?sgetn@streambuf@@QEAAHPEADH@Z # @ extern ?sh_none@filebuf@@2HB # @ extern ?sh_read@filebuf@@2HB # @ extern ?sh_write@filebuf@@2HB @@ -766,8 +766,8 @@ @ stub -arch=win64 ?sputbackc@streambuf@@QEAAHD@Z @ thiscall -arch=win32 ?sputc@streambuf@@QAEHH@Z(ptr long) msvcirt.?sputc@streambuf@@QAEHH@Z @ cdecl -arch=win64 ?sputc@streambuf@@QEAAHH@Z(ptr long) msvcirt.?sputc@streambuf@@QEAAHH@Z -@ stub -arch=win32 ?sputn@streambuf@@QAEHPBDH@Z -@ stub -arch=win64 ?sputn@streambuf@@QEAAHPEBDH@Z +@ thiscall -arch=win32 ?sputn@streambuf@@QAEHPBDH@Z(ptr str long) msvcirt.?sputn@streambuf@@QAEHPBDH@Z +@ cdecl -arch=win64 ?sputn@streambuf@@QEAAHPEBDH@Z(ptr str long) msvcirt.?sputn@streambuf@@QEAAHPEBDH@Z @ stub -arch=win32 ?stdiofile@stdiobuf@@QAEPAU_iobuf@@XZ @ stub -arch=win64 ?stdiofile@stdiobuf@@QEAAPEAU_iobuf@@XZ @ stub -arch=win32 ?stossc@streambuf@@QAEXXZ
1
0
0
0
Iván Matellanes : msvcirt: Add implementation of streambuf::xsputn.
by Alexandre Julliard
23 Jun '15
23 Jun '15
Module: wine Branch: master Commit: f71186b6450b0f5a345d4ec660667a4189ec905d URL:
http://source.winehq.org/git/wine.git/?a=commit;h=f71186b6450b0f5a345d4ec66…
Author: Iván Matellanes <matellanesivan(a)gmail.com> Date: Sat Jun 20 16:40:15 2015 +0200 msvcirt: Add implementation of streambuf::xsputn. --- dlls/msvcirt/msvcirt.c | 21 +++++++++++++++++++-- dlls/msvcirt/tests/msvcirt.c | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 2 deletions(-) diff --git a/dlls/msvcirt/msvcirt.c b/dlls/msvcirt/msvcirt.c index 6b440fd..e8faa54 100644 --- a/dlls/msvcirt/msvcirt.c +++ b/dlls/msvcirt/msvcirt.c @@ -535,8 +535,25 @@ int __thiscall streambuf_xsgetn(streambuf *this, char *buffer, int count) DEFINE_THISCALL_WRAPPER(streambuf_xsputn, 12) int __thiscall streambuf_xsputn(streambuf *this, const char *data, int length) { - FIXME("(%p %p %d): stub\n", this, data, length); - return 0; + int copied = 0, chunk; + + TRACE("(%p %p %d)\n", this, data, length); + + while (copied < length) { + if (this->unbuffered || this->pptr == this->epptr) { + if (call_streambuf_overflow(this, data[copied]) == EOF) + break; + copied++; + } else { + chunk = this->epptr - this->pptr; + if (chunk > length - copied) + chunk = length - copied; + memcpy(this->pptr, data+copied, chunk); + this->pptr += chunk; + copied += chunk; + } + } + return copied; } /* ?sgetc@streambuf@@QAEHXZ */ diff --git a/dlls/msvcirt/tests/msvcirt.c b/dlls/msvcirt/tests/msvcirt.c index c4777a2..a175531 100644 --- a/dlls/msvcirt/tests/msvcirt.c +++ b/dlls/msvcirt/tests/msvcirt.c @@ -66,6 +66,7 @@ static int (*__thiscall p_streambuf_sputc)(streambuf*, int); static int (*__thiscall p_streambuf_sync)(streambuf*); static void (*__thiscall p_streambuf_unlock)(streambuf*); static int (*__thiscall p_streambuf_xsgetn)(streambuf*, char*, int); +static int (*__thiscall p_streambuf_xsputn)(streambuf*, const char*, int); /* Emulate a __thiscall */ #ifdef __i386__ @@ -153,6 +154,7 @@ static BOOL init(void) SET(p_streambuf_sync, "?sync@streambuf@@UEAAHXZ"); SET(p_streambuf_unlock, "?unlock@streambuf@@QEAAXXZ"); SET(p_streambuf_xsgetn, "?xsgetn@streambuf@@UEAAHPEADH@Z"); + SET(p_streambuf_xsputn, "?xsputn@streambuf@@UEAAHPEBDH@Z"); } else { SET(p_streambuf_reserve_ctor, "??0streambuf@@IAE@PADH@Z"); SET(p_streambuf_ctor, "??0streambuf@@IAE@XZ"); @@ -171,6 +173,7 @@ static BOOL init(void) SET(p_streambuf_sync, "?sync@streambuf@@UAEHXZ"); SET(p_streambuf_unlock, "?unlock@streambuf@@QAEXXZ"); SET(p_streambuf_xsgetn, "?xsgetn@streambuf@@UAEHPADH@Z"); + SET(p_streambuf_xsputn, "?xsputn@streambuf@@UAEHPBDH@Z"); } init_thiscall_thunk(); @@ -189,6 +192,8 @@ static int __thiscall test_streambuf_overflow(streambuf *this, int ch) #endif { overflow_count++; + if (ch == 'L') /* simulate a failure */ + return EOF; if (!test_this->unbuffered) test_this->pptr = test_this->pbase + 5; return ch; @@ -527,6 +532,38 @@ static void test_streambuf(void) ok(sb3.stored_char == 'G', "wrong stored character, expected 'G' got %c\n", sb3.stored_char); ok(underflow_count == 37, "expected 6 calls to underflow, got %d\n", underflow_count - 31); + /* xsputn */ + ret = (int) call_func3(p_streambuf_xsputn, &sb, "Test\0ing", 8); + ok(ret == 8, "wrong return value, expected 8 got %d\n", ret); + ok(sb.pptr == sb.pbase + 9, "wrong put pointer, expected %p got %p\n", sb.pbase + 9, sb.pptr); + test_this = &sb2; + sb2.pptr = sb2.epptr - 7; + ret = (int) call_func3(p_streambuf_xsputn, &sb2, "Testing", 7); + ok(ret == 7, "wrong return value, expected 7 got %d\n", ret); + ok(sb2.pptr == sb2.epptr, "wrong put pointer, expected %p got %p\n", sb2.epptr, sb2.pptr); + ok(overflow_count == 2, "no call to overflow expected\n"); + sb2.pptr = sb2.epptr - 5; + sb2.pbase[5] = 'a'; + ret = (int) call_func3(p_streambuf_xsputn, &sb2, "Testing", 7); + ok(ret == 7, "wrong return value, expected 7 got %d\n", ret); + ok(sb2.pbase[5] == 'g', "expected 'g' got %c\n", sb2.pbase[5]); + ok(sb2.pptr == sb2.pbase + 6, "wrong put pointer, expected %p got %p\n", sb2.pbase + 6, sb2.pptr); + ok(overflow_count == 3, "expected call to overflow\n"); + sb2.pptr = sb2.epptr - 4; + ret = (int) call_func3(p_streambuf_xsputn, &sb2, "TestLing", 8); + ok(ret == 4, "wrong return value, expected 4 got %d\n", ret); + ok(sb2.pptr == sb2.epptr, "wrong put pointer, expected %p got %p\n", sb2.epptr, sb2.pptr); + ok(overflow_count == 4, "expected call to overflow\n"); + test_this = &sb3; + ret = (int) call_func3(p_streambuf_xsputn, &sb3, "Testing", 7); + ok(ret == 7, "wrong return value, expected 7 got %d\n", ret); + ok(sb3.stored_char == 'G', "wrong stored character, expected 'G' got %c\n", sb3.stored_char); + ok(overflow_count == 11, "expected 7 calls to overflow, got %d\n", overflow_count - 4); + ret = (int) call_func3(p_streambuf_xsputn, &sb3, "TeLephone", 9); + ok(ret == 2, "wrong return value, expected 2 got %d\n", ret); + ok(sb3.stored_char == 'G', "wrong stored character, expected 'G' got %c\n", sb3.stored_char); + ok(overflow_count == 14, "expected 3 calls to overflow, got %d\n", overflow_count - 11); + SetEvent(lock_arg.test[3]); WaitForSingleObject(thread, INFINITE);
1
0
0
0
Iván Matellanes : msvcirt: Add implementation of streambuf::xsgetn.
by Alexandre Julliard
23 Jun '15
23 Jun '15
Module: wine Branch: master Commit: a507132cdc11c44efc7702e9bac14b7dfd6884d6 URL:
http://source.winehq.org/git/wine.git/?a=commit;h=a507132cdc11c44efc7702e9b…
Author: Iván Matellanes <matellanesivan(a)gmail.com> Date: Sat Jun 20 16:40:06 2015 +0200 msvcirt: Add implementation of streambuf::xsgetn. --- dlls/msvcirt/msvcirt.c | 26 ++++++++++++-- dlls/msvcirt/tests/msvcirt.c | 80 +++++++++++++++++++++++++++++++++++++------- 2 files changed, 92 insertions(+), 14 deletions(-) diff --git a/dlls/msvcirt/msvcirt.c b/dlls/msvcirt/msvcirt.c index 47a7f28..6b440fd 100644 --- a/dlls/msvcirt/msvcirt.c +++ b/dlls/msvcirt/msvcirt.c @@ -504,8 +504,30 @@ void __thiscall streambuf_unlock(streambuf *this) DEFINE_THISCALL_WRAPPER(streambuf_xsgetn, 12) int __thiscall streambuf_xsgetn(streambuf *this, char *buffer, int count) { - FIXME("(%p %p %d): stub\n", this, buffer, count); - return 0; + int copied = 0, chunk; + + TRACE("(%p %p %d)\n", this, buffer, count); + + if (this->unbuffered) { + if (this->stored_char == EOF) + this->stored_char = call_streambuf_underflow(this); + while (copied < count && this->stored_char != EOF) { + buffer[copied++] = this->stored_char; + this->stored_char = call_streambuf_underflow(this); + } + } else { + while (copied < count) { + if (call_streambuf_underflow(this) == EOF) + break; + chunk = this->egptr - this->gptr; + if (chunk > count - copied) + chunk = count - copied; + memcpy(buffer+copied, this->gptr, chunk); + this->gptr += chunk; + copied += chunk; + } + } + return copied; } /* ?xsputn@streambuf@@UAEHPBDH@Z */ diff --git a/dlls/msvcirt/tests/msvcirt.c b/dlls/msvcirt/tests/msvcirt.c index 6c60dd0..c4777a2 100644 --- a/dlls/msvcirt/tests/msvcirt.c +++ b/dlls/msvcirt/tests/msvcirt.c @@ -65,6 +65,7 @@ static int (*__thiscall p_streambuf_sgetc)(streambuf*); static int (*__thiscall p_streambuf_sputc)(streambuf*, int); static int (*__thiscall p_streambuf_sync)(streambuf*); static void (*__thiscall p_streambuf_unlock)(streambuf*); +static int (*__thiscall p_streambuf_xsgetn)(streambuf*, char*, int); /* Emulate a __thiscall */ #ifdef __i386__ @@ -151,6 +152,7 @@ static BOOL init(void) SET(p_streambuf_sputc, "?sputc@streambuf@@QEAAHH@Z"); SET(p_streambuf_sync, "?sync@streambuf@@UEAAHXZ"); SET(p_streambuf_unlock, "?unlock@streambuf@@QEAAXXZ"); + SET(p_streambuf_xsgetn, "?xsgetn@streambuf@@UEAAHPEADH@Z"); } else { SET(p_streambuf_reserve_ctor, "??0streambuf@@IAE@PADH@Z"); SET(p_streambuf_ctor, "??0streambuf@@IAE@XZ"); @@ -168,6 +170,7 @@ static BOOL init(void) SET(p_streambuf_sputc, "?sputc@streambuf@@QAEHH@Z"); SET(p_streambuf_sync, "?sync@streambuf@@UAEHXZ"); SET(p_streambuf_unlock, "?unlock@streambuf@@QAEXXZ"); + SET(p_streambuf_xsgetn, "?xsgetn@streambuf@@UAEHPADH@Z"); } init_thiscall_thunk(); @@ -175,7 +178,9 @@ static BOOL init(void) } static int overflow_count, underflow_count; -static streambuf *test_overflow_this; +static streambuf *test_this; +static char test_get_buffer[24]; +static int buffer_pos, get_end; #ifdef __i386__ static int __thiscall test_streambuf_overflow(int ch) @@ -184,8 +189,8 @@ static int __thiscall test_streambuf_overflow(streambuf *this, int ch) #endif { overflow_count++; - if (!test_overflow_this->unbuffered) - test_overflow_this->pptr = test_overflow_this->pbase + 5; + if (!test_this->unbuffered) + test_this->pptr = test_this->pbase + 5; return ch; } @@ -196,7 +201,13 @@ static int __thiscall test_streambuf_underflow(streambuf *this) #endif { underflow_count++; - return 'u'; + if (test_this->unbuffered) { + return (buffer_pos < 23) ? test_get_buffer[buffer_pos++] : EOF; + } else if (test_this->gptr < test_this->egptr) { + return *test_this->gptr; + } else { + return get_end ? EOF : *(test_this->gptr = test_this->eback); + } } struct streambuf_lock_arg @@ -264,6 +275,8 @@ static void test_streambuf(void) sb2.vtable = test_streambuf_vtbl; sb3.vtable = test_streambuf_vtbl; overflow_count = underflow_count = 0; + strcpy(test_get_buffer, "CompuGlobalHyperMegaNet"); + buffer_pos = get_end = 0; /* setlock */ ok(sb.do_lock == -1, "expected do_lock value -1, got %d\n", sb.do_lock); @@ -426,21 +439,23 @@ static void test_streambuf(void) ok(ret == 0, "sync failed, expected 0 got %d\n", ret); /* sgetc */ + strcpy(sb2.eback, "WorstTestEver"); + test_this = &sb2; ret = (int) call_func1(p_streambuf_sgetc, &sb2); - ok(ret == 'u', "expected 'u' got '%c'\n", ret); + ok(ret == 'W', "expected 'W' got '%c'\n", ret); ok(underflow_count == 1, "expected call to underflow\n"); ok(sb2.stored_char == EOF, "wrong stored character, expected EOF got %c\n", sb2.stored_char); - sb2.gptr = sb2.eback; - *sb2.gptr = 'a'; + sb2.gptr++; ret = (int) call_func1(p_streambuf_sgetc, &sb2); - ok(ret == 'u', "expected 'u' got '%c'\n", ret); + ok(ret == 'o', "expected 'o' got '%c'\n", ret); ok(underflow_count == 2, "expected call to underflow\n"); ok(sb2.stored_char == EOF, "wrong stored character, expected EOF got %c\n", sb2.stored_char); sb2.gptr = sb2.egptr; + test_this = &sb3; ret = (int) call_func1(p_streambuf_sgetc, &sb3); - ok(ret == 'u', "expected 'u' got '%c'\n", ret); + ok(ret == 'C', "expected 'C' got '%c'\n", ret); ok(underflow_count == 3, "expected call to underflow\n"); - ok(sb3.stored_char == 'u', "wrong stored character, expected 'u' got %c\n", sb3.stored_char); + ok(sb3.stored_char == 'C', "wrong stored character, expected 'C' got %c\n", sb3.stored_char); sb3.stored_char = 'b'; ret = (int) call_func1(p_streambuf_sgetc, &sb3); ok(ret == 'b', "expected 'b' got '%c'\n", ret); @@ -454,12 +469,12 @@ static void test_streambuf(void) ok(overflow_count == 0, "no call to overflow expected\n"); ok(*sb.pbase == 'c', "expected 'c' in the put area, got %c\n", *sb.pbase); ok(sb.pptr == sb.pbase + 1, "wrong put pointer, expected %p got %p\n", sb.pbase + 1, sb.pptr); - test_overflow_this = &sb2; + test_this = &sb2; ret = (int) call_func2(p_streambuf_sputc, &sb2, 'c'); ok(ret == 'c', "wrong return value, expected 'c' got %d\n", ret); ok(overflow_count == 1, "expected call to overflow\n"); ok(sb2.pptr == sb2.pbase + 5, "wrong put pointer, expected %p got %p\n", sb2.pbase + 5, sb2.pptr); - test_overflow_this = &sb3; + test_this = &sb3; ret = (int) call_func2(p_streambuf_sputc, &sb3, 'c'); ok(ret == 'c', "wrong return value, expected 'c' got %d\n", ret); ok(overflow_count == 2, "expected call to overflow\n"); @@ -471,6 +486,47 @@ static void test_streambuf(void) ok(*sb3.pbase == 'c', "expected 'c' in the put area, got %c\n", *sb3.pbase); sb3.pbase = sb3.pptr = sb3.epptr = NULL; + /* xsgetn */ + sb2.gptr = sb2.egptr = sb2.eback + 13; + test_this = &sb2; + ret = (int) call_func3(p_streambuf_xsgetn, &sb2, reserve, 5); + ok(ret == 5, "wrong return value, expected 5 got %d\n", ret); + ok(!strncmp(reserve, "Worst", 5), "expected 'Worst' got %s\n", reserve); + ok(sb2.gptr == sb2.eback + 5, "wrong get pointer, expected %p got %p\n", sb2.eback + 5, sb2.gptr); + ok(underflow_count == 4, "expected call to underflow\n"); + ret = (int) call_func3(p_streambuf_xsgetn, &sb2, reserve, 4); + ok(ret == 4, "wrong return value, expected 4 got %d\n", ret); + ok(!strncmp(reserve, "Test", 4), "expected 'Test' got %s\n", reserve); + ok(sb2.gptr == sb2.eback + 9, "wrong get pointer, expected %p got %p\n", sb2.eback + 9, sb2.gptr); + ok(underflow_count == 5, "expected call to underflow\n"); + get_end = 1; + ret = (int) call_func3(p_streambuf_xsgetn, &sb2, reserve, 16); + ok(ret == 4, "wrong return value, expected 4 got %d\n", ret); + ok(!strncmp(reserve, "Ever", 4), "expected 'Ever' got %s\n", reserve); + ok(sb2.gptr == sb2.egptr, "wrong get pointer, expected %p got %p\n", sb2.egptr, sb2.gptr); + ok(underflow_count == 7, "expected 2 calls to underflow, got %d\n", underflow_count - 5); + test_this = &sb3; + ret = (int) call_func3(p_streambuf_xsgetn, &sb3, reserve, 11); + ok(ret == 11, "wrong return value, expected 11 got %d\n", ret); + ok(!strncmp(reserve, "bompuGlobal", 11), "expected 'bompuGlobal' got %s\n", reserve); + ok(sb3.stored_char == 'H', "wrong stored character, expected 'H' got %c\n", sb3.stored_char); + ok(underflow_count == 18, "expected 11 calls to underflow, got %d\n", underflow_count - 7); + ret = (int) call_func3(p_streambuf_xsgetn, &sb3, reserve, 16); + ok(ret == 12, "wrong return value, expected 12 got %d\n", ret); + ok(!strncmp(reserve, "HyperMegaNet", 12), "expected 'HyperMegaNet' got %s\n", reserve); + ok(sb3.stored_char == EOF, "wrong stored character, expected EOF got %c\n", sb3.stored_char); + ok(underflow_count == 30, "expected 12 calls to underflow, got %d\n", underflow_count - 18); + ret = (int) call_func3(p_streambuf_xsgetn, &sb3, reserve, 3); + ok(ret == 0, "wrong return value, expected 0 got %d\n", ret); + ok(sb3.stored_char == EOF, "wrong stored character, expected EOF got %c\n", sb3.stored_char); + ok(underflow_count == 31, "expected call to underflow\n"); + buffer_pos = 0; + ret = (int) call_func3(p_streambuf_xsgetn, &sb3, reserve, 5); + ok(ret == 5, "wrong return value, expected 5 got %d\n", ret); + ok(!strncmp(reserve, "Compu", 5), "expected 'Compu' got %s\n", reserve); + ok(sb3.stored_char == 'G', "wrong stored character, expected 'G' got %c\n", sb3.stored_char); + ok(underflow_count == 37, "expected 6 calls to underflow, got %d\n", underflow_count - 31); + SetEvent(lock_arg.test[3]); WaitForSingleObject(thread, INFINITE);
1
0
0
0
Alistair Leslie-Hughes : dpnet: Correct adding components in Duplicate.
by Alexandre Julliard
23 Jun '15
23 Jun '15
Module: wine Branch: master Commit: 275364d919e35da8261644eece44412faf6f2ef7 URL:
http://source.winehq.org/git/wine.git/?a=commit;h=275364d919e35da8261644eec…
Author: Alistair Leslie-Hughes <leslie_alistair(a)hotmail.com> Date: Thu Jun 11 08:55:48 2015 +1000 dpnet: Correct adding components in Duplicate. --- dlls/dpnet/address.c | 23 ++++++++++++++++++++++- dlls/dpnet/tests/address.c | 16 ++++++++++++++-- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/dlls/dpnet/address.c b/dlls/dpnet/address.c index 7a33f8a..d2a05f6 100644 --- a/dlls/dpnet/address.c +++ b/dlls/dpnet/address.c @@ -232,9 +232,30 @@ static HRESULT WINAPI IDirectPlay8AddressImpl_Duplicate(IDirectPlay8Address *ifa { struct component *entry = This->components[i]; - hr = IDirectPlay8Address_AddComponent(dup, entry->name, &entry->data, entry->size, entry->type); + switch (entry->type) + { + case DPNA_DATATYPE_DWORD: + hr = IDirectPlay8Address_AddComponent(dup, entry->name, &entry->data.value, entry->size, entry->type); + break; + case DPNA_DATATYPE_GUID: + hr = IDirectPlay8Address_AddComponent(dup, entry->name, &entry->data.guid, entry->size, entry->type); + break; + case DPNA_DATATYPE_STRING: + hr = IDirectPlay8Address_AddComponent(dup, entry->name, entry->data.string, entry->size, entry->type); + break; + case DPNA_DATATYPE_STRING_ANSI: + hr = IDirectPlay8Address_AddComponent(dup, entry->name, entry->data.ansi, entry->size, entry->type); + break; + case DPNA_DATATYPE_BINARY: + hr = IDirectPlay8Address_AddComponent(dup, entry->name, entry->data.binary, entry->size, entry->type); + break; + } + if(hr != S_OK) + { ERR("Failed to copy component: %s - 0x%08x\n", debugstr_w(entry->name), hr); + break; + } } *ppdpaNewAddress = dup; diff --git a/dlls/dpnet/tests/address.c b/dlls/dpnet/tests/address.c index ee589f5..cb226f9 100644 --- a/dlls/dpnet/tests/address.c +++ b/dlls/dpnet/tests/address.c @@ -24,6 +24,7 @@ /* {6733C6E8-A0D6-450E-8C18-CEACF331DC27} */ static const GUID IID_Random = {0x6733c6e8, 0xa0d6, 0x450e, { 0x8c, 0x18, 0xce, 0xac, 0xf3, 0x31, 0xdc, 0x27 } }; +static const WCHAR localhost[] = {'l','o','c','a','l','h','o','s','t',0}; static void create_directplay_address(void) { @@ -70,7 +71,6 @@ static void create_directplay_address(void) static void address_addcomponents(void) { static const WCHAR UNKNOWN[] = { 'u','n','k','n','o','w','n',0 }; - static const WCHAR localhost[] = {'l','o','c','a','l','h','o','s','t',0}; static const char testing[] = "testing"; HRESULT hr; IDirectPlay8Address *localaddr = NULL; @@ -309,14 +309,20 @@ static void address_duplicate(void) hr = IDirectPlay8Address_SetSP(localaddr, &CLSID_DP8SP_TCPIP); ok(hr == S_OK, "got 0x%08x\n", hr); + hr = IDirectPlay8Address_AddComponent(localaddr, DPNA_KEY_HOSTNAME, &localhost, sizeof(localhost), DPNA_DATATYPE_STRING); + ok(hr == S_OK, "got 0x%08x\n", hr); + hr = IDirectPlay8Address_GetNumComponents(localaddr, &components); ok(hr == S_OK, "got 0x%08x\n", hr); - ok(components == 1, "components=%d\n", components); + ok(components == 2, "components=%d\n", components); hr = IDirectPlay8Address_Duplicate(localaddr, &duplicate); ok(hr == S_OK, "got 0x%08x\n", hr); if(SUCCEEDED(hr)) { + DWORD size, type; + WCHAR buffer[256]; + hr = IDirectPlay8Address_GetSP(duplicate, &guid); ok(hr == S_OK, "got 0x%08x\n", hr); ok(IsEqualGUID(&guid, &CLSID_DP8SP_TCPIP), "wrong guid\n"); @@ -325,6 +331,12 @@ static void address_duplicate(void) ok(hr == S_OK, "got 0x%08x\n", hr); ok(components == dupcomps, "expected %d got %d\n", components, dupcomps); + size = sizeof(buffer); + hr = IDirectPlay8Address_GetComponentByName(duplicate, DPNA_KEY_HOSTNAME, buffer, &size, &type); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(type == DPNA_DATATYPE_STRING, "incorrect type %d\n", type); + ok(!lstrcmpW(buffer, localhost), "Invalid string: %s\n", wine_dbgstr_w(buffer)); + IDirectPlay8Address_Release(duplicate); }
1
0
0
0
Nikolay Sivov : amstream: Forward IUnknown methods to IAMMediaStream for streams.
by Alexandre Julliard
23 Jun '15
23 Jun '15
Module: wine Branch: master Commit: 147068453983bd1211e51251eaf885796fbc0e6d URL:
http://source.winehq.org/git/wine.git/?a=commit;h=147068453983bd1211e51251e…
Author: Nikolay Sivov <nsivov(a)codeweavers.com> Date: Tue Jun 23 10:09:08 2015 +0300 amstream: Forward IUnknown methods to IAMMediaStream for streams. --- dlls/amstream/mediastream.c | 72 +++++---------------------------------------- 1 file changed, 8 insertions(+), 64 deletions(-) diff --git a/dlls/amstream/mediastream.c b/dlls/amstream/mediastream.c index 1a31706..ca4f0ce 100644 --- a/dlls/amstream/mediastream.c +++ b/dlls/amstream/mediastream.c @@ -247,48 +247,22 @@ static HRESULT WINAPI DirectDrawMediaStreamImpl_IDirectDrawMediaStream_QueryInte REFIID riid, void **ret_iface) { DirectDrawMediaStreamImpl *This = impl_from_IDirectDrawMediaStream(iface); - TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ret_iface); - - if (IsEqualGUID(riid, &IID_IUnknown) || - IsEqualGUID(riid, &IID_IMediaStream) || - IsEqualGUID(riid, &IID_IDirectDrawMediaStream)) - { - IDirectDrawMediaStream_AddRef(iface); - *ret_iface = iface; - return S_OK; - } - else if (IsEqualGUID(riid, &IID_IAMMediaStream)) - { - IDirectDrawMediaStream_AddRef(iface); - *ret_iface = &This->IAMMediaStream_iface; - return S_OK; - } - - ERR("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ret_iface); - return E_NOINTERFACE; + return IAMMediaStream_QueryInterface(&This->IAMMediaStream_iface, riid, ret_iface); } static ULONG WINAPI DirectDrawMediaStreamImpl_IDirectDrawMediaStream_AddRef(IDirectDrawMediaStream *iface) { DirectDrawMediaStreamImpl *This = impl_from_IDirectDrawMediaStream(iface); - TRACE("(%p/%p)\n", iface, This); - - return InterlockedIncrement(&This->ref); + return IAMMediaStream_AddRef(&This->IAMMediaStream_iface); } static ULONG WINAPI DirectDrawMediaStreamImpl_IDirectDrawMediaStream_Release(IDirectDrawMediaStream *iface) { DirectDrawMediaStreamImpl *This = impl_from_IDirectDrawMediaStream(iface); - ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p/%p)\n", iface, This); - - if (!ref) - HeapFree(GetProcessHeap(), 0, This); - - return ref; + return IAMMediaStream_Release(&This->IAMMediaStream_iface); } /*** IMediaStream methods ***/ @@ -673,52 +647,22 @@ static HRESULT WINAPI AudioMediaStreamImpl_IAudioMediaStream_QueryInterface(IAud REFIID riid, void **ret_iface) { AudioMediaStreamImpl *This = impl_from_IAudioMediaStream(iface); - TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ret_iface); - - if (IsEqualGUID(riid, &IID_IUnknown) || - IsEqualGUID(riid, &IID_IMediaStream) || - IsEqualGUID(riid, &IID_IAudioMediaStream)) - { - IAudioMediaStream_AddRef(iface); - *ret_iface = iface; - return S_OK; - } - else if (IsEqualGUID(riid, &IID_IAMMediaStream)) - { - IAudioMediaStream_AddRef(iface); - *ret_iface = &This->IAMMediaStream_iface; - return S_OK; - } - - - *ret_iface = NULL; - - ERR("(%p/%p)->(%s,%p),not found\n", iface, This, debugstr_guid(riid), ret_iface); - return E_NOINTERFACE; + return IAMMediaStream_QueryInterface(&This->IAMMediaStream_iface, riid, ret_iface); } static ULONG WINAPI AudioMediaStreamImpl_IAudioMediaStream_AddRef(IAudioMediaStream *iface) { AudioMediaStreamImpl *This = impl_from_IAudioMediaStream(iface); - ULONG ref = InterlockedIncrement(&This->ref); - - TRACE("(%p/%p): new ref = %u\n", iface, This, ref); - - return ref; + TRACE("(%p/%p)\n", iface, This); + return IAMMediaStream_AddRef(&This->IAMMediaStream_iface); } static ULONG WINAPI AudioMediaStreamImpl_IAudioMediaStream_Release(IAudioMediaStream *iface) { AudioMediaStreamImpl *This = impl_from_IAudioMediaStream(iface); - ULONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p/%p): new ref = %u\n", iface, This, ref); - - if (!ref) - HeapFree(GetProcessHeap(), 0, This); - - return ref; + TRACE("(%p/%p)\n", iface, This); + return IAMMediaStream_Release(&This->IAMMediaStream_iface); } /*** IMediaStream methods ***/
1
0
0
0
Nikolay Sivov : amstream: Implement GetDirectDraw().
by Alexandre Julliard
23 Jun '15
23 Jun '15
Module: wine Branch: master Commit: eb0b1d55e41f24f0159ed0582b182bb415e0c23a URL:
http://source.winehq.org/git/wine.git/?a=commit;h=eb0b1d55e41f24f0159ed0582…
Author: Nikolay Sivov <nsivov(a)codeweavers.com> Date: Mon Jun 22 23:52:08 2015 +0300 amstream: Implement GetDirectDraw(). --- dlls/amstream/Makefile.in | 2 +- dlls/amstream/mediastream.c | 21 ++++++++++++++++++--- dlls/amstream/tests/amstream.c | 16 ++++++++++++++++ 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/dlls/amstream/Makefile.in b/dlls/amstream/Makefile.in index 1107223..c00822b 100644 --- a/dlls/amstream/Makefile.in +++ b/dlls/amstream/Makefile.in @@ -1,5 +1,5 @@ MODULE = amstream.dll -IMPORTS = strmiids strmbase uuid ole32 advapi32 +IMPORTS = strmiids strmbase uuid ole32 advapi32 ddraw C_SRCS = \ amstream.c \ diff --git a/dlls/amstream/mediastream.c b/dlls/amstream/mediastream.c index 4a8c19b..1a31706 100644 --- a/dlls/amstream/mediastream.c +++ b/dlls/amstream/mediastream.c @@ -42,6 +42,7 @@ typedef struct { IMultiMediaStream* parent; MSPID purpose_id; STREAM_TYPE stream_type; + IDirectDraw7 *ddraw; } DirectDrawMediaStreamImpl; static inline DirectDrawMediaStreamImpl *impl_from_DirectDrawMediaStream_IAMMediaStream(IAMMediaStream *iface) @@ -94,7 +95,11 @@ static ULONG WINAPI DirectDrawMediaStreamImpl_IAMMediaStream_Release(IAMMediaStr TRACE("(%p/%p)->(): new ref = %u\n", iface, This, ref); if (!ref) + { + if (This->ddraw) + IDirectDraw7_Release(This->ddraw); HeapFree(GetProcessHeap(), 0, This); + } return ref; } @@ -373,11 +378,21 @@ static HRESULT WINAPI DirectDrawMediaStreamImpl_IDirectDrawMediaStream_SetFormat } static HRESULT WINAPI DirectDrawMediaStreamImpl_IDirectDrawMediaStream_GetDirectDraw(IDirectDrawMediaStream *iface, - IDirectDraw **ppDirectDraw) + IDirectDraw **ddraw) { - FIXME("(%p)->(%p) stub!\n", iface, ppDirectDraw); + DirectDrawMediaStreamImpl *This = impl_from_IDirectDrawMediaStream(iface); - return E_NOTIMPL; + TRACE("(%p)->(%p)\n", iface, ddraw); + + *ddraw = NULL; + if (!This->ddraw) + { + HRESULT hr = DirectDrawCreateEx(NULL, (void**)&This->ddraw, &IID_IDirectDraw7, NULL); + if (FAILED(hr)) + return hr; + } + + return IDirectDraw7_QueryInterface(This->ddraw, &IID_IDirectDraw, (void**)ddraw); } static HRESULT WINAPI DirectDrawMediaStreamImpl_IDirectDrawMediaStream_SetDirectDraw(IDirectDrawMediaStream *iface, diff --git a/dlls/amstream/tests/amstream.c b/dlls/amstream/tests/amstream.c index a8986a6..b961084 100644 --- a/dlls/amstream/tests/amstream.c +++ b/dlls/amstream/tests/amstream.c @@ -458,6 +458,8 @@ static void test_IDirectDrawStreamSample(void) IDirectDrawMediaStream *pddstream = NULL; IDirectDrawStreamSample *pddsample = NULL; IDirectDrawSurface *surface, *surface2; + IDirectDraw *ddraw, *ddraw2; + IDirectDraw7 *ddraw7; RECT rect; if (!(pams = create_ammultimediastream())) @@ -482,6 +484,20 @@ static void test_IDirectDrawStreamSample(void) ok(hr == S_OK, "got 0x%08x\n", hr); if (FAILED(hr)) goto error; + hr = IDirectDrawMediaStream_GetDirectDraw(pddstream, &ddraw); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IDirectDrawMediaStream_GetDirectDraw(pddstream, &ddraw2); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(ddraw == ddraw2, "got %p, %p\n", ddraw, ddraw2); + + hr = IDirectDraw_QueryInterface(ddraw, &IID_IDirectDraw7, (void**)&ddraw7); + ok(hr == S_OK, "got 0x%08x\n", hr); + IDirectDraw7_Release(ddraw7); + + IDirectDraw_Release(ddraw2); + IDirectDraw_Release(ddraw); + hr = IDirectDrawMediaStream_CreateSample(pddstream, NULL, NULL, 0, &pddsample); ok(hr == S_OK, "got 0x%08x\n", hr);
1
0
0
0
Nikolay Sivov : amstream: Keep stream reference when creating sample.
by Alexandre Julliard
23 Jun '15
23 Jun '15
Module: wine Branch: master Commit: 17283f9be50050fb0024635fd2701e8599d97ab7 URL:
http://source.winehq.org/git/wine.git/?a=commit;h=17283f9be50050fb0024635fd…
Author: Nikolay Sivov <nsivov(a)codeweavers.com> Date: Mon Jun 22 22:56:10 2015 +0300 amstream: Keep stream reference when creating sample. --- dlls/amstream/mediastream.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dlls/amstream/mediastream.c b/dlls/amstream/mediastream.c index f51d4dd..4a8c19b 100644 --- a/dlls/amstream/mediastream.c +++ b/dlls/amstream/mediastream.c @@ -906,6 +906,7 @@ static ULONG WINAPI IDirectDrawStreamSampleImpl_Release(IDirectDrawStreamSample { if (This->surface) IDirectDrawSurface_Release(This->surface); + IMediaStream_Release(This->parent); HeapFree(GetProcessHeap(), 0, This); } @@ -1011,6 +1012,8 @@ static HRESULT ddrawstreamsample_create(IDirectDrawMediaStream *parent, IDirectD object->IDirectDrawStreamSample_iface.lpVtbl = &DirectDrawStreamSample_Vtbl; object->ref = 1; object->parent = (IMediaStream*)parent; + IMediaStream_AddRef(object->parent); + if (surface) { object->surface = surface;
1
0
0
0
Nikolay Sivov : amstream: Implement IDirectDrawStreamSample_GetSurface().
by Alexandre Julliard
23 Jun '15
23 Jun '15
Module: wine Branch: master Commit: 139445eb49c3f3500a1105fa7803b8f35b2bf5a2 URL:
http://source.winehq.org/git/wine.git/?a=commit;h=139445eb49c3f3500a1105fa7…
Author: Nikolay Sivov <nsivov(a)codeweavers.com> Date: Mon Jun 22 22:39:41 2015 +0300 amstream: Implement IDirectDrawStreamSample_GetSurface(). --- dlls/amstream/mediastream.c | 58 ++++++++++++++++++---- dlls/amstream/tests/amstream.c | 106 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 154 insertions(+), 10 deletions(-) diff --git a/dlls/amstream/mediastream.c b/dlls/amstream/mediastream.c index b457d1f..f51d4dd 100644 --- a/dlls/amstream/mediastream.c +++ b/dlls/amstream/mediastream.c @@ -31,7 +31,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(amstream); -static HRESULT ddrawstreamsample_create(IDirectDrawMediaStream *parent, IDirectDrawStreamSample **ddraw_stream_sample); +static HRESULT ddrawstreamsample_create(IDirectDrawMediaStream *parent, IDirectDrawSurface *surface, + const RECT *rect, IDirectDrawStreamSample **ddraw_stream_sample); static HRESULT audiostreamsample_create(IAudioMediaStream *parent, IAudioData *audio_data, IAudioStreamSample **audio_stream_sample); typedef struct { @@ -388,12 +389,12 @@ static HRESULT WINAPI DirectDrawMediaStreamImpl_IDirectDrawMediaStream_SetDirect } static HRESULT WINAPI DirectDrawMediaStreamImpl_IDirectDrawMediaStream_CreateSample(IDirectDrawMediaStream *iface, - IDirectDrawSurface *pSurface, const RECT *pRect, DWORD dwFlags, + IDirectDrawSurface *surface, const RECT *rect, DWORD dwFlags, IDirectDrawStreamSample **ppSample) { - TRACE("(%p)->(%p,%p,%x,%p)\n", iface, pSurface, pRect, dwFlags, ppSample); + TRACE("(%p)->(%p,%s,%x,%p)\n", iface, surface, wine_dbgstr_rect(rect), dwFlags, ppSample); - return ddrawstreamsample_create(iface, ppSample); + return ddrawstreamsample_create(iface, surface, rect, ppSample); } static HRESULT WINAPI DirectDrawMediaStreamImpl_IDirectDrawMediaStream_GetTimePerFrame(IDirectDrawMediaStream *iface, @@ -854,6 +855,8 @@ typedef struct { IDirectDrawStreamSample IDirectDrawStreamSample_iface; LONG ref; IMediaStream *parent; + IDirectDrawSurface *surface; + RECT rect; } IDirectDrawStreamSampleImpl; static inline IDirectDrawStreamSampleImpl *impl_from_IDirectDrawStreamSample(IDirectDrawStreamSample *iface) @@ -900,7 +903,11 @@ static ULONG WINAPI IDirectDrawStreamSampleImpl_Release(IDirectDrawStreamSample TRACE("(%p)->(): new ref = %u\n", iface, ref); if (!ref) + { + if (This->surface) + IDirectDrawSurface_Release(This->surface); HeapFree(GetProcessHeap(), 0, This); + } return ref; } @@ -948,9 +955,21 @@ static HRESULT WINAPI IDirectDrawStreamSampleImpl_CompletionStatus(IDirectDrawSt static HRESULT WINAPI IDirectDrawStreamSampleImpl_GetSurface(IDirectDrawStreamSample *iface, IDirectDrawSurface **ddraw_surface, RECT *rect) { - FIXME("(%p)->(%p,%p): stub\n", iface, ddraw_surface, rect); + IDirectDrawStreamSampleImpl *This = impl_from_IDirectDrawStreamSample(iface); - return E_NOTIMPL; + TRACE("(%p)->(%p,%p)\n", iface, ddraw_surface, rect); + + if (ddraw_surface) + { + *ddraw_surface = This->surface; + if (*ddraw_surface) + IDirectDrawSurface_AddRef(*ddraw_surface); + } + + if (rect) + *rect = This->rect; + + return S_OK; } static HRESULT WINAPI IDirectDrawStreamSampleImpl_SetRect(IDirectDrawStreamSample *iface, const RECT *rect) @@ -977,19 +996,42 @@ static const struct IDirectDrawStreamSampleVtbl DirectDrawStreamSample_Vtbl = IDirectDrawStreamSampleImpl_SetRect }; -static HRESULT ddrawstreamsample_create(IDirectDrawMediaStream *parent, IDirectDrawStreamSample **ddraw_stream_sample) +static HRESULT ddrawstreamsample_create(IDirectDrawMediaStream *parent, IDirectDrawSurface *surface, + const RECT *rect, IDirectDrawStreamSample **ddraw_stream_sample) { IDirectDrawStreamSampleImpl *object; + HRESULT hr; TRACE("(%p)\n", ddraw_stream_sample); - object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectDrawStreamSampleImpl)); + object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); if (!object) return E_OUTOFMEMORY; object->IDirectDrawStreamSample_iface.lpVtbl = &DirectDrawStreamSample_Vtbl; object->ref = 1; object->parent = (IMediaStream*)parent; + if (surface) + { + object->surface = surface; + IDirectDrawSurface_AddRef(surface); + } + else + FIXME("create ddraw surface\n"); + + if (rect) + object->rect = *rect; + else if (object->surface) + { + DDSURFACEDESC desc = { sizeof(desc) }; + hr = IDirectDrawSurface_GetSurfaceDesc(object->surface, &desc); + if (hr == S_OK) + { + object->rect.left = object->rect.top = 0; + object->rect.right = desc.dwWidth; + object->rect.bottom = desc.dwHeight; + } + } *ddraw_stream_sample = (IDirectDrawStreamSample*)&object->IDirectDrawStreamSample_iface; diff --git a/dlls/amstream/tests/amstream.c b/dlls/amstream/tests/amstream.c index f2f5723..a8986a6 100644 --- a/dlls/amstream/tests/amstream.c +++ b/dlls/amstream/tests/amstream.c @@ -26,6 +26,14 @@ #include "amstream.h" #include "vfwmsgs.h" +#define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__) +static void _expect_ref(IUnknown* obj, ULONG ref, int line) +{ + ULONG rc = IUnknown_AddRef(obj); + IUnknown_Release(obj); + ok_(__FILE__,line)(rc-1 == ref, "expected refcount %d, got %d\n", ref, rc-1); +} + static const WCHAR filenameW[] = {'t','e','s','t','.','a','v','i',0}; static IDirectDraw7* pdd7; @@ -119,6 +127,8 @@ static void test_renderfile(void) IMediaStream *pvidstream = NULL; IDirectDrawMediaStream *pddstream = NULL; IDirectDrawStreamSample *pddsample = NULL; + IDirectDrawSurface *surface; + RECT rect; if (!(pams = create_ammultimediastream())) return; @@ -151,9 +161,23 @@ static void test_renderfile(void) hr = IDirectDrawMediaStream_CreateSample(pddstream, NULL, NULL, 0, &pddsample); ok(hr == S_OK, "IDirectDrawMediaStream_CreateSample returned: %x\n", hr); + surface = NULL; + hr = IDirectDrawStreamSample_GetSurface(pddsample, &surface, &rect); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(surface == NULL, "got %p\n", surface); + IDirectDrawStreamSample_Release(pddsample); + + hr = IDirectDrawSurface7_QueryInterface(pdds7, &IID_IDirectDrawSurface, (void**)&surface); + ok(hr == S_OK, "got 0x%08x\n", hr); + + EXPECT_REF(surface, 1); + hr = IDirectDrawMediaStream_CreateSample(pddstream, surface, NULL, 0, &pddsample); + ok(hr == S_OK, "IDirectDrawMediaStream_CreateSample returned: %x\n", hr); + EXPECT_REF(surface, 2); + IDirectDrawStreamSample_Release(pddsample); + IDirectDrawSurface_Release(surface); + error: - if (pddsample) - IDirectDrawStreamSample_Release(pddsample); if (pddstream) IDirectDrawMediaStream_Release(pddstream); if (pvidstream) @@ -426,6 +450,83 @@ static void test_media_streams(void) IAMMultiMediaStream_Release(pams); } +static void test_IDirectDrawStreamSample(void) +{ + IAMMultiMediaStream *pams; + HRESULT hr; + IMediaStream *pvidstream = NULL; + IDirectDrawMediaStream *pddstream = NULL; + IDirectDrawStreamSample *pddsample = NULL; + IDirectDrawSurface *surface, *surface2; + RECT rect; + + if (!(pams = create_ammultimediastream())) + return; + if (!create_directdraw()) + { + IAMMultiMediaStream_Release(pams); + return; + } + + hr = IAMMultiMediaStream_Initialize(pams, STREAMTYPE_READ, 0, NULL); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IAMMultiMediaStream_AddMediaStream(pams, (IUnknown*)pdd7, &MSPID_PrimaryVideo, 0, NULL); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IAMMultiMediaStream_GetMediaStream(pams, &MSPID_PrimaryVideo, &pvidstream); + ok(hr == S_OK, "got 0x%08x\n", hr); + if (FAILED(hr)) goto error; + + hr = IMediaStream_QueryInterface(pvidstream, &IID_IDirectDrawMediaStream, (LPVOID*)&pddstream); + ok(hr == S_OK, "got 0x%08x\n", hr); + if (FAILED(hr)) goto error; + + hr = IDirectDrawMediaStream_CreateSample(pddstream, NULL, NULL, 0, &pddsample); + ok(hr == S_OK, "got 0x%08x\n", hr); + + surface = NULL; + hr = IDirectDrawStreamSample_GetSurface(pddsample, &surface, &rect); + ok(hr == S_OK, "got 0x%08x\n", hr); +todo_wine + ok(surface != NULL, "got %p\n", surface); +if (surface) + IDirectDrawSurface_Release(surface); + IDirectDrawStreamSample_Release(pddsample); + + hr = IDirectDrawSurface7_QueryInterface(pdds7, &IID_IDirectDrawSurface, (void**)&surface); + ok(hr == S_OK, "got 0x%08x\n", hr); + + EXPECT_REF(surface, 1); + hr = IDirectDrawMediaStream_CreateSample(pddstream, surface, NULL, 0, &pddsample); + ok(hr == S_OK, "got 0x%08x\n", hr); + EXPECT_REF(surface, 2); + + surface2 = NULL; + memset(&rect, 0, sizeof(rect)); + hr = IDirectDrawStreamSample_GetSurface(pddsample, &surface2, &rect); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(surface == surface2, "got %p\n", surface2); + ok(rect.right > 0 && rect.bottom > 0, "got %d, %d\n", rect.right, rect.bottom); + EXPECT_REF(surface, 3); + IDirectDrawSurface_Release(surface2); + + hr = IDirectDrawStreamSample_GetSurface(pddsample, NULL, NULL); + ok(hr == S_OK, "got 0x%08x\n", hr); + + IDirectDrawStreamSample_Release(pddsample); + IDirectDrawSurface_Release(surface); + +error: + if (pddstream) + IDirectDrawMediaStream_Release(pddstream); + if (pvidstream) + IMediaStream_Release(pvidstream); + + release_directdraw(); + IAMMultiMediaStream_Release(pams); +} + START_TEST(amstream) { HANDLE file; @@ -433,6 +534,7 @@ START_TEST(amstream) CoInitializeEx(NULL, COINIT_MULTITHREADED); test_media_streams(); + test_IDirectDrawStreamSample(); file = CreateFileW(filenameW, 0, 0, NULL, OPEN_EXISTING, 0, NULL); if (file != INVALID_HANDLE_VALUE)
1
0
0
0
← Newer
1
...
14
15
16
17
18
19
20
...
61
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
50
51
52
53
54
55
56
57
58
59
60
61
Results per page:
10
25
50
100
200