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] 67344: [WININET_WINETEST] Sync with Wine Staging 1.7.37. CORE-9246
by akhaldi@svn.reactos.org
Author: akhaldi Date: Wed Apr 22 08:38:32 2015 New Revision: 67344 URL:
http://svn.reactos.org/svn/reactos?rev=67344&view=rev
Log: [WININET_WINETEST] Sync with Wine Staging 1.7.37. CORE-9246 Modified: trunk/rostests/winetests/wininet/ftp.c trunk/rostests/winetests/wininet/http.c trunk/rostests/winetests/wininet/internet.c Modified: trunk/rostests/winetests/wininet/ftp.c URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/wininet/ftp.c?r…
============================================================================== --- trunk/rostests/winetests/wininet/ftp.c [iso-8859-1] (original) +++ trunk/rostests/winetests/wininet/ftp.c [iso-8859-1] Wed Apr 22 08:38:32 2015 @@ -754,6 +754,7 @@ HINTERNET hSearch2; HINTERNET hOpenFile; DWORD error; + BOOL success; /* NULL as the search file ought to return the first file in the directory */ SetLastError(0xdeadbeef); @@ -773,13 +774,13 @@ /* Try a valid filename in a subdirectory search */ SetLastError(0xdeadbeef); hSearch = FtpFindFirstFileA(hFtp, "pub/wine", &findData, 0, 0); - todo_wine ok ( hSearch != NULL, "Expected FtpFindFirstFileA to pass\n" ); + ok( hSearch != NULL, "Expected FtpFindFirstFileA to pass\n" ); InternetCloseHandle(hSearch); /* Try a valid filename in a subdirectory wildcard search */ SetLastError(0xdeadbeef); hSearch = FtpFindFirstFileA(hFtp, "pub/w*", &findData, 0, 0); - todo_wine ok ( hSearch != NULL, "Expected FtpFindFirstFileA to pass\n" ); + ok( hSearch != NULL, "Expected FtpFindFirstFileA to pass\n" ); InternetCloseHandle(hSearch); /* Try an invalid wildcard search */ @@ -787,6 +788,24 @@ hSearch = FtpFindFirstFileA(hFtp, "*/w*", &findData, 0, 0); ok ( hSearch == NULL, "Expected FtpFindFirstFileA to fail\n" ); InternetCloseHandle(hSearch); /* Just in case */ + + /* change current directory, and repeat those tests - this shows + * that the search string is interpreted as relative directory. */ + success = FtpSetCurrentDirectoryA(hFtp, "pub"); + ok( success, "Expected FtpSetCurrentDirectory to succeed\n" ); + + SetLastError(0xdeadbeef); + hSearch = FtpFindFirstFileA(hFtp, "wine", &findData, 0, 0); + ok( hSearch != NULL, "Expected FtpFindFirstFileA to pass\n" ); + InternetCloseHandle(hSearch); + + SetLastError(0xdeadbeef); + hSearch = FtpFindFirstFileA(hFtp, "w*", &findData, 0, 0); + ok( hSearch != NULL, "Expected FtpFindFirstFileA to pass\n" ); + InternetCloseHandle(hSearch); + + success = FtpSetCurrentDirectoryA(hFtp, ".."); + ok( success, "Expected FtpSetCurrentDirectory to succeed\n" ); /* Try FindFirstFile between FtpOpenFile and InternetCloseHandle */ SetLastError(0xdeadbeef); Modified: trunk/rostests/winetests/wininet/http.c URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/wininet/http.c?…
============================================================================== --- trunk/rostests/winetests/wininet/http.c [iso-8859-1] (original) +++ trunk/rostests/winetests/wininet/http.c [iso-8859-1] Wed Apr 22 08:38:32 2015 @@ -2295,9 +2295,37 @@ else if (strstr(buffer, "Cache-Control: no-cache\r\n")) send(c, okmsg, sizeof(okmsg)-1, 0); else send(c, notokmsg, sizeof(notokmsg)-1, 0); } + if (strstr(buffer, "/test_request_content_length")) + { + static char msg[] = "HTTP/1.1 200 OK\r\nConnection: Keep-Alive\r\n\r\n"; + static int seen_content_length; + + if (!seen_content_length) + { + if (strstr(buffer, "Content-Length: 0")) + { + seen_content_length = 1; + send(c, msg, sizeof msg-1, 0); + } + else send(c, notokmsg, sizeof notokmsg-1, 0); + WaitForSingleObject(hCompleteEvent, 5000); + } + else + { + if (strstr(buffer, "Content-Length: 0")) send(c, msg, sizeof msg-1, 0); + else send(c, notokmsg, sizeof notokmsg-1, 0); + WaitForSingleObject(hCompleteEvent, 5000); + } + } if (strstr(buffer, "GET /test_premature_disconnect")) trace("closing connection\n"); - + if (strstr(buffer, "/test_accept_encoding_http10")) + { + if (strstr(buffer, "Accept-Encoding: gzip")) + send(c, okmsg, sizeof okmsg-1, 0); + else + send(c, notokmsg, sizeof notokmsg-1, 0); + } shutdown(c, 2); closesocket(c); c = -1; @@ -4120,6 +4148,79 @@ InternetCloseHandle(session); } +static void test_request_content_length(int port) +{ + char data[] = {'t','e','s','t'}; + HINTERNET ses, con, req; + BOOL ret; + + hCompleteEvent = CreateEventW(NULL, FALSE, FALSE, NULL); + + ses = InternetOpenA("winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0); + ok(ses != NULL, "InternetOpen failed\n"); + + con = InternetConnectA(ses, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0); + ok(con != NULL, "InternetConnect failed\n"); + + req = HttpOpenRequestA(con, "POST", "/test_request_content_length", NULL, NULL, NULL, + INTERNET_FLAG_KEEP_CONNECTION, 0); + ok(req != NULL, "HttpOpenRequest failed\n"); + + ret = HttpSendRequestA(req, NULL, 0, NULL, 0); + ok(ret, "HttpSendRequest failed %u\n", GetLastError()); + test_status_code(req, 200); + + SetEvent(hCompleteEvent); + + ret = HttpSendRequestA(req, NULL, 0, data, sizeof(data)); + ok(ret, "HttpSendRequest failed %u\n", GetLastError()); + test_status_code(req, 200); + + SetEvent(hCompleteEvent); + + InternetCloseHandle(req); + InternetCloseHandle(con); + InternetCloseHandle(ses); + CloseHandle(hCompleteEvent); +} + +static void test_accept_encoding(int port) +{ + HINTERNET ses, con, req; + BOOL ret; + + ses = InternetOpenA("winetest", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); + ok(ses != NULL, "InternetOpen failed\n"); + + con = InternetConnectA(ses, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0); + ok(con != NULL, "InternetConnect failed\n"); + + req = HttpOpenRequestA(con, "GET", "/test_accept_encoding_http10", "HTTP/1.0", NULL, NULL, 0, 0); + ok(req != NULL, "HttpOpenRequest failed\n"); + + ret = HttpAddRequestHeadersA(req, "Accept-Encoding: gzip\r\n", ~0u, HTTP_ADDREQ_FLAG_REPLACE | HTTP_ADDREQ_FLAG_ADD); + ok(ret, "HttpAddRequestHeaders failed\n"); + + ret = HttpSendRequestA(req, NULL, 0, NULL, 0); + ok(ret, "HttpSendRequestA failed\n"); + + test_status_code(req, 200); + + InternetCloseHandle(req); + + req = HttpOpenRequestA(con, "GET", "/test_accept_encoding_http10", "HTTP/1.0", NULL, NULL, 0, 0); + ok(req != NULL, "HttpOpenRequest failed\n"); + + ret = HttpSendRequestA(req, "Accept-Encoding: gzip", ~0u, NULL, 0); + ok(ret, "HttpSendRequestA failed\n"); + + test_status_code(req, 200); + + InternetCloseHandle(req); + InternetCloseHandle(con); + InternetCloseHandle(ses); +} + static void test_http_connection(void) { struct server_info si; @@ -4165,6 +4266,8 @@ test_cache_control_verb(si.port); test_successive_HttpSendRequest(si.port); test_head_request(si.port); + test_request_content_length(si.port); + test_accept_encoding(si.port); /* send the basic request again to shutdown the server thread */ test_basic_request(si.port, "GET", "/quit"); @@ -4232,7 +4335,7 @@ ok(!info.lpszSignatureAlgName, "lpszSignatureAlgName = %s\n", info.lpszSignatureAlgName); ok(!info.lpszEncryptionAlgName, "lpszEncryptionAlgName = %s\n", info.lpszEncryptionAlgName); ok(!info.lpszProtocolName, "lpszProtocolName = %s\n", info.lpszProtocolName); - ok(info.dwKeySize == 128 || info.dwKeySize == 256, "dwKeySize = %u\n", info.dwKeySize); + ok(info.dwKeySize >= 128 && info.dwKeySize <= 256, "dwKeySize = %u\n", info.dwKeySize); release_cert_info(&info); } @@ -5484,6 +5587,55 @@ #undef STATUS_STRING } +static void WINAPI header_cb( HINTERNET handle, DWORD_PTR ctx, DWORD status, LPVOID info, DWORD len ) +{ + if (status == INTERNET_STATUS_REQUEST_COMPLETE) SetEvent( (HANDLE)ctx ); +} + +static void test_concurrent_header_access(void) +{ + HINTERNET ses, con, req; + DWORD index, len, err; + BOOL ret; + char buf[128]; + HANDLE wait = CreateEventW( NULL, FALSE, FALSE, NULL ); + + ses = InternetOpenA( "winetest", 0, NULL, NULL, INTERNET_FLAG_ASYNC ); + ok( ses != NULL, "InternetOpenA failed\n" ); + + con = InternetConnectA( ses, "
test.winehq.org
", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, + INTERNET_SERVICE_HTTP, 0, 0 ); + ok( con != NULL, "InternetConnectA failed %u\n", GetLastError() ); + + req = HttpOpenRequestA( con, NULL, "/", NULL, NULL, NULL, 0, (DWORD_PTR)wait ); + ok( req != NULL, "HttpOpenRequestA failed %u\n", GetLastError() ); + + pInternetSetStatusCallbackA( req, header_cb ); + + SetLastError( 0xdeadbeef ); + ret = HttpSendRequestA( req, NULL, 0, NULL, 0 ); + err = GetLastError(); + ok( !ret, "HttpSendRequestA succeeded\n" ); + ok( err == ERROR_IO_PENDING, "got %u\n", ERROR_IO_PENDING ); + + ret = HttpAddRequestHeadersA( req, "winetest: winetest", ~0u, HTTP_ADDREQ_FLAG_ADD ); + ok( ret, "HttpAddRequestHeadersA failed %u\n", GetLastError() ); + + index = 0; + len = sizeof(buf); + ret = HttpQueryInfoA( req, HTTP_QUERY_RAW_HEADERS_CRLF|HTTP_QUERY_FLAG_REQUEST_HEADERS, + buf, &len, &index ); + ok( ret, "HttpQueryInfoA failed %u\n", GetLastError() ); + ok( strstr( buf, "winetest: winetest" ) != NULL, "header missing\n" ); + + WaitForSingleObject( wait, 5000 ); + + InternetCloseHandle( req ); + InternetCloseHandle( con ); + InternetCloseHandle( ses ); + CloseHandle( wait ); +} + START_TEST(http) { HMODULE hdll; @@ -5526,4 +5678,5 @@ InternetReadFile_test(INTERNET_FLAG_ASYNC, &test_data[3]); test_connection_failure(); test_default_service_port(); -} + test_concurrent_header_access(); +} Modified: trunk/rostests/winetests/wininet/internet.c URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/wininet/interne…
============================================================================== --- trunk/rostests/winetests/wininet/internet.c [iso-8859-1] (original) +++ trunk/rostests/winetests/wininet/internet.c [iso-8859-1] Wed Apr 22 08:38:32 2015 @@ -1526,19 +1526,16 @@ trace("Internet Connection: Flags 0x%02x - Name '%s'\n", flags, buffer); res = pInternetGetConnectedStateExA(NULL, NULL, 0, 0); -todo_wine ok(res == TRUE, "Expected TRUE, got %d\n", res); flags = 0; res = pInternetGetConnectedStateExA(&flags, NULL, 0, 0); -todo_wine ok(res == TRUE, "Expected TRUE, got %d\n", res); ok(flags, "Expected at least one flag set\n"); buffer[0] = 0; flags = 0; res = pInternetGetConnectedStateExA(&flags, buffer, 0, 0); -todo_wine ok(res == TRUE, "Expected TRUE, got %d\n", res); ok(flags, "Expected at least one flag set\n"); ok(!buffer[0], "Buffer must not change, got %02X\n", buffer[0]); @@ -1557,6 +1554,11 @@ sz = strlen(buffer); ok(sz > 0, "Expected a connection name\n"); + flags = 0; + res = pInternetGetConnectedStateExA(&flags, NULL, sizeof(buffer), 0); + ok(res == TRUE, "Expected TRUE, got %d\n", res); + ok(flags, "Expected at least one flag set\n"); + /* no space for complete string this time */ buffer[0] = 0; flags = 0; @@ -1567,11 +1569,31 @@ buffer[0] = 0; flags = 0; + res = pInternetGetConnectedStateExA(&flags, buffer, sz / 2, 0); + ok(res == TRUE, "Expected TRUE, got %d\n", res); + ok(flags, "Expected at least one flag set\n"); + ok(sz / 2 - 1 == strlen(buffer), "Expected %u bytes, got %u\n", sz / 2 - 1, lstrlenA(buffer)); + + buffer[0] = 0; + flags = 0; res = pInternetGetConnectedStateExA(&flags, buffer, 1, 0); -todo_wine ok(res == TRUE, "Expected TRUE, got %d\n", res); ok(flags, "Expected at least one flag set\n"); - ok(strlen(buffer) == 0, "Expected 0 bytes, got %u\n", lstrlenA(buffer)); + ok(!buffer[0], "Expected 0 bytes, got %u\n", lstrlenA(buffer)); + + buffer[0] = 0; + flags = 0; + res = pInternetGetConnectedStateExA(&flags, buffer, 2, 0); + ok(res == TRUE, "Expected TRUE, got %d\n", res); + ok(flags, "Expected at least one flag set\n"); + ok(strlen(buffer) == 1, "Expected 1 byte, got %u\n", lstrlenA(buffer)); + + flags = 0; + buffer[0] = 0xDE; + res = pInternetGetConnectedStateExA(&flags, buffer, 1, 0); + ok(res == TRUE, "Expected TRUE, got %d\n", res); + ok(flags, "Expected at least one flag set\n"); + ok(!buffer[0], "Expected 0 bytes, got %u\n", lstrlenA(buffer)); } static void test_InternetGetConnectedStateExW(void) @@ -1593,12 +1615,10 @@ trace("Internet Connection: Flags 0x%02x - Name '%s'\n", flags, wine_dbgstr_w(buffer)); res = pInternetGetConnectedStateExW(NULL, NULL, 0, 0); -todo_wine ok(res == TRUE, "Expected TRUE, got %d\n", res); flags = 0; res = pInternetGetConnectedStateExW(&flags, NULL, 0, 0); -todo_wine ok(res == TRUE, "Expected TRUE, got %d\n", res); ok(flags, "Expected at least one flag set\n"); @@ -1607,7 +1627,6 @@ res = pInternetGetConnectedStateExW(&flags, buffer, 0, 0); ok(res == TRUE, "Expected TRUE, got %d\n", res); ok(flags, "Expected at least one flag set\n"); -todo_wine ok(!buffer[0], "Buffer must not change, got %02X\n", buffer[0]); buffer[0] = 0; @@ -1624,6 +1643,11 @@ sz = lstrlenW(buffer); ok(sz > 0, "Expected a connection name\n"); + flags = 0; + res = pInternetGetConnectedStateExW(&flags, NULL, sizeof(buffer) / sizeof(buffer[0]), 0); + ok(res == TRUE, "Expected TRUE, got %d\n", res); + ok(flags, "Expected at least one flag set\n"); + /* no space for complete string this time */ buffer[0] = 0; flags = 0; @@ -1634,11 +1658,31 @@ buffer[0] = 0; flags = 0; + res = pInternetGetConnectedStateExW(&flags, buffer, sz / 2, 0); + ok(res == TRUE, "Expected TRUE, got %d\n", res); + ok(flags, "Expected at least one flag set\n"); + ok(sz / 2 - 1 == lstrlenW(buffer), "Expected %u bytes, got %u\n", sz / 2 - 1, lstrlenW(buffer)); + + buffer[0] = 0; + flags = 0; res = pInternetGetConnectedStateExW(&flags, buffer, 1, 0); -todo_wine ok(res == TRUE, "Expected TRUE, got %d\n", res); ok(flags, "Expected at least one flag set\n"); - ok(lstrlenW(buffer) == 0, "Expected 0 bytes, got %u\n", lstrlenW(buffer)); + ok(!buffer[0], "Expected 0 bytes, got %u\n", lstrlenW(buffer)); + + buffer[0] = 0; + flags = 0; + res = pInternetGetConnectedStateExW(&flags, buffer, 2, 0); + ok(res == TRUE, "Expected TRUE, got %d\n", res); + ok(flags, "Expected at least one flag set\n"); + ok(lstrlenW(buffer) == 1, "Expected 1 byte, got %u\n", lstrlenW(buffer)); + + buffer[0] = 0xDEAD; + flags = 0; + res = pInternetGetConnectedStateExW(&flags, buffer, 1, 0); + ok(res == TRUE, "Expected TRUE, got %d\n", res); + ok(flags, "Expected at least one flag set\n"); + ok(!buffer[0], "Expected 0 bytes, got %u\n", lstrlenW(buffer)); } /* ############################### */
9 years, 8 months
1
0
0
0
[akhaldi] 67343: [WININET] Sync with Wine Staging 1.7.37. CORE-9246
by akhaldi@svn.reactos.org
Author: akhaldi Date: Wed Apr 22 08:30:31 2015 New Revision: 67343 URL:
http://svn.reactos.org/svn/reactos?rev=67343&view=rev
Log: [WININET] Sync with Wine Staging 1.7.37. CORE-9246 Modified: trunk/reactos/dll/win32/wininet/CMakeLists.txt trunk/reactos/dll/win32/wininet/cookie.c trunk/reactos/dll/win32/wininet/ftp.c trunk/reactos/dll/win32/wininet/http.c trunk/reactos/dll/win32/wininet/internet.c trunk/reactos/dll/win32/wininet/internet.h trunk/reactos/dll/win32/wininet/netconnection.c trunk/reactos/dll/win32/wininet/urlcache.c trunk/reactos/dll/win32/wininet/utility.c trunk/reactos/media/doc/README.WINE Modified: trunk/reactos/dll/win32/wininet/CMakeLists.txt URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/wininet/CMakeLis…
============================================================================== --- trunk/reactos/dll/win32/wininet/CMakeLists.txt [iso-8859-1] (original) +++ trunk/reactos/dll/win32/wininet/CMakeLists.txt [iso-8859-1] Wed Apr 22 08:30:31 2015 @@ -1,3 +1,6 @@ + +remove_definitions(-DWINVER=0x502) +add_definitions(-DWINVER=0x600) add_definitions( -D__WINESRC__ @@ -30,6 +33,6 @@ set_module_type(wininet win32dll) target_link_libraries(wininet wine ${PSEH_LIB} zlib) add_delay_importlibs(wininet secur32 crypt32 cryptui) -add_importlibs(wininet mpr shlwapi shell32 user32 advapi32 ws2_32 msvcrt kernel32 ntdll) +add_importlibs(wininet mpr shlwapi shell32 user32 advapi32 ws2_32 kernel32_vista msvcrt kernel32 ntdll) add_pch(wininet internet.h SOURCE) add_cd_file(TARGET wininet DESTINATION reactos/system32 FOR all) Modified: trunk/reactos/dll/win32/wininet/cookie.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/wininet/cookie.c…
============================================================================== --- trunk/reactos/dll/win32/wininet/cookie.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/wininet/cookie.c [iso-8859-1] Wed Apr 22 08:30:31 2015 @@ -342,7 +342,6 @@ *pend = 0; data = heap_strdupAtoW(pbeg); - pbeg = pend+1; pbeg = strchr(pend+1, '\n'); if(!pbeg) break; Modified: trunk/reactos/dll/win32/wininet/ftp.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/wininet/ftp.c?re…
============================================================================== --- trunk/reactos/dll/win32/wininet/ftp.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/wininet/ftp.c [iso-8859-1] Wed Apr 22 08:30:31 2015 @@ -28,6 +28,8 @@ */ #include "internet.h" + +#define RESPONSE_TIMEOUT 30 typedef struct _ftp_session_t ftp_session_t; @@ -789,6 +791,7 @@ INT nResCode; appinfo_t *hIC = NULL; HINTERNET hFindNext = NULL; + LPWSTR lpszSearchPath = NULL; TRACE("\n"); @@ -804,7 +807,20 @@ if (!FTP_SendPortOrPasv(lpwfs)) goto lend; - if (!FTP_SendCommand(lpwfs->sndSocket, FTP_CMD_LIST, NULL, + /* split search path into file and path */ + if (lpszSearchFile) + { + LPCWSTR name = lpszSearchFile, p; + if ((p = strrchrW( name, '\\' ))) name = p + 1; + if ((p = strrchrW( name, '/' ))) name = p + 1; + if (name != lpszSearchFile) + { + lpszSearchPath = heap_strndupW(lpszSearchFile, name - lpszSearchFile); + lpszSearchFile = name; + } + } + + if (!FTP_SendCommand(lpwfs->sndSocket, FTP_CMD_LIST, lpszSearchPath, lpwfs->hdr.lpfnStatusCB, &lpwfs->hdr, lpwfs->hdr.dwContext)) goto lend; @@ -830,6 +846,8 @@ } lend: + heap_free(lpszSearchPath); + if (lpwfs->lstnSocket != -1) { closesocket(lpwfs->lstnSocket); @@ -1181,7 +1199,7 @@ res = sock_send(lpwh->nDataSocket, buffer, size, 0); *written = res>0 ? res : 0; - return res >= 0 ? ERROR_SUCCESS : sock_get_error(errno); + return res >= 0 ? ERROR_SUCCESS : sock_get_error(); } static void FTP_ReceiveRequestData(ftp_file_t *file, BOOL first_notif) @@ -1216,17 +1234,14 @@ static DWORD FTPFILE_QueryDataAvailable(object_header_t *hdr, DWORD *available, DWORD flags, DWORD_PTR ctx) { ftp_file_t *file = (ftp_file_t*) hdr; - int retval, unread = 0; + ULONG unread = 0; + int retval; TRACE("(%p %p %x %lx)\n", file, available, flags, ctx); -#ifdef FIONREAD retval = ioctlsocket(file->nDataSocket, FIONREAD, &unread); if (!retval) TRACE("%d bytes of queued, but unread data\n", unread); -#else - FIXME("FIONREAD not available\n"); -#endif *available = unread; @@ -2328,11 +2343,11 @@ if (lpwfs->download_in_progress != NULL) lpwfs->download_in_progress->session_deleted = TRUE; - if (lpwfs->sndSocket != -1) - closesocket(lpwfs->sndSocket); - - if (lpwfs->lstnSocket != -1) - closesocket(lpwfs->lstnSocket); + if (lpwfs->sndSocket != -1) + closesocket(lpwfs->sndSocket); + + if (lpwfs->lstnSocket != -1) + closesocket(lpwfs->lstnSocket); if (lpwfs->pasvSocket != -1) closesocket(lpwfs->pasvSocket); @@ -2409,7 +2424,7 @@ socklen_t sock_namelen; BOOL bSuccess = FALSE; ftp_session_t *lpwfs = NULL; - char szaddr[INET_ADDRSTRLEN]; + char szaddr[INET6_ADDRSTRLEN]; TRACE("%p Server(%s) Port(%d) User(%s) Paswd(%s)\n", hIC, debugstr_w(lpszServerName), @@ -2454,7 +2469,7 @@ if(hIC->proxyBypass) FIXME("Proxy bypass is ignored.\n"); } - if (!lpszUserName || !strlenW(lpszUserName)) { + if (!lpszUserName || !lpszUserName[0]) { HKEY key; WCHAR szPassword[MAX_PATH]; DWORD len = sizeof(szPassword); @@ -2497,7 +2512,7 @@ (LPWSTR) lpszServerName, (strlenW(lpszServerName)+1) * sizeof(WCHAR)); sock_namelen = sizeof(socketAddr); - if (!GetAddress(lpszServerName, lpwfs->serverport, (struct sockaddr *)&socketAddr, &sock_namelen)) + if (!GetAddress(lpszServerName, lpwfs->serverport, (struct sockaddr *)&socketAddr, &sock_namelen, szaddr)) { INTERNET_SetLastError(ERROR_INTERNET_NAME_NOT_RESOLVED); goto lerror; @@ -2510,10 +2525,10 @@ goto lerror; } - inet_ntop(socketAddr.sin_family, &socketAddr.sin_addr, szaddr, sizeof(szaddr)); SendAsyncCallback(&hIC->hdr, dwContext, INTERNET_STATUS_NAME_RESOLVED, szaddr, strlen(szaddr)+1); + init_winsock(); nsocket = socket(AF_INET,SOCK_STREAM,0); if (nsocket == -1) { @@ -2526,7 +2541,7 @@ if (connect(nsocket, (struct sockaddr *)&socketAddr, sock_namelen) < 0) { - ERR("Unable to connect (%s)\n", strerror(errno)); + ERR("Unable to connect (%d)\n", sock_get_error()); INTERNET_SetLastError(ERROR_INTERNET_CANNOT_CONNECT); closesocket(nsocket); } @@ -2601,6 +2616,58 @@ return bSuccess; } +/*********************************************************************** + * FTP_GetNextLine (internal) + * + * Parse next line in directory string listing + * + * RETURNS + * Pointer to beginning of next line + * NULL on failure + * + */ + +static LPSTR FTP_GetNextLine(INT nSocket, LPDWORD dwLen) +{ + struct timeval tv = {RESPONSE_TIMEOUT,0}; + FD_SET set; + INT nRecv = 0; + LPSTR lpszBuffer = INTERNET_GetResponseBuffer(); + + TRACE("\n"); + + FD_ZERO(&set); + FD_SET(nSocket, &set); + + while (nRecv < MAX_REPLY_LEN) + { + if (select(nSocket+1, &set, NULL, NULL, &tv) > 0) + { + if (sock_recv(nSocket, &lpszBuffer[nRecv], 1, 0) <= 0) + { + INTERNET_SetLastError(ERROR_FTP_TRANSFER_IN_PROGRESS); + return NULL; + } + + if (lpszBuffer[nRecv] == '\n') + { + lpszBuffer[nRecv] = '\0'; + *dwLen = nRecv - 1; + TRACE(":%d %s\n", nRecv, lpszBuffer); + return lpszBuffer; + } + if (lpszBuffer[nRecv] != '\r') + nRecv++; + } + else + { + INTERNET_SetLastError(ERROR_INTERNET_TIMEOUT); + return NULL; + } + } + + return NULL; +} /*********************************************************************** * FTP_SendCommandA (internal) @@ -2700,7 +2767,7 @@ while(1) { - if (!INTERNET_GetNextLine(lpwfs->sndSocket, &nRecv)) + if (!FTP_GetNextLine(lpwfs->sndSocket, &nRecv)) goto lerror; if (nRecv >= 3) @@ -2873,7 +2940,8 @@ TRACE("\n"); - lpwfs->lstnSocket = socket(PF_INET, SOCK_STREAM, 0); + init_winsock(); + lpwfs->lstnSocket = socket(AF_INET, SOCK_STREAM, 0); if (lpwfs->lstnSocket == -1) { TRACE("Unable to create listening socket\n"); @@ -3016,10 +3084,10 @@ TRACE("\n"); sprintfW(szIPAddress, szIPFormat, - lpwfs->lstnSocketAddress.sin_addr.s_addr&0x000000FF, - (lpwfs->lstnSocketAddress.sin_addr.s_addr&0x0000FF00)>>8, - (lpwfs->lstnSocketAddress.sin_addr.s_addr&0x00FF0000)>>16, - (lpwfs->lstnSocketAddress.sin_addr.s_addr&0xFF000000)>>24, + lpwfs->lstnSocketAddress.sin_addr.S_un.S_addr&0x000000FF, + (lpwfs->lstnSocketAddress.sin_addr.S_un.S_addr&0x0000FF00)>>8, + (lpwfs->lstnSocketAddress.sin_addr.S_un.S_addr&0x00FF0000)>>16, + (lpwfs->lstnSocketAddress.sin_addr.S_un.S_addr&0xFF000000)>>24, lpwfs->lstnSocketAddress.sin_port & 0xFF, (lpwfs->lstnSocketAddress.sin_port & 0xFF00)>>8); @@ -3092,7 +3160,7 @@ f[i] = f[i] & 0xff; dataSocketAddress = lpwfs->socketAddress; - pAddr = (char *)&(dataSocketAddress.sin_addr.s_addr); + pAddr = (char *)&(dataSocketAddress.sin_addr.S_un.S_addr); pPort = (char *)&(dataSocketAddress.sin_port); pAddr[0] = f[0]; pAddr[1] = f[1]; @@ -3155,7 +3223,7 @@ static BOOL FTP_GetDataSocket(ftp_session_t *lpwfs, LPINT nDataSocket) { struct sockaddr_in saddr; - socklen_t addrlen = sizeof(struct sockaddr); + socklen_t addrlen = sizeof(saddr); TRACE("\n"); if (lpwfs->hdr.dwFlags & INTERNET_FLAG_PASSIVE) @@ -3559,7 +3627,7 @@ lpfp->lpszName = NULL; do { - if(!(pszLine = INTERNET_GetNextLine(nSocket, &nBufLen))) + if(!(pszLine = FTP_GetNextLine(nSocket, &nBufLen))) return FALSE; pszToken = strtok(pszLine, szSpace); Modified: trunk/reactos/dll/win32/wininet/http.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/wininet/http.c?r…
============================================================================== --- trunk/reactos/dll/win32/wininet/http.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/wininet/http.c [iso-8859-1] Wed Apr 22 08:30:31 2015 @@ -37,13 +37,9 @@ #include <wine/exception.h> -// ReactOS -#include "inet_ntop.c" - static const WCHAR g_szHttp1_0[] = {'H','T','T','P','/','1','.','0',0}; static const WCHAR g_szHttp1_1[] = {'H','T','T','P','/','1','.','1',0}; static const WCHAR szOK[] = {'O','K',0}; -static const WCHAR szDefaultHeader[] = {'H','T','T','P','/','1','.','0',' ','2','0','0',' ','O','K',0}; static const WCHAR hostW[] = { 'H','o','s','t',0 }; static const WCHAR szAuthorization[] = { 'A','u','t','h','o','r','i','z','a','t','i','o','n',0 }; static const WCHAR szProxy_Authorization[] = { 'P','r','o','x','y','-','A','u','t','h','o','r','i','z','a','t','i','o','n',0 }; @@ -51,7 +47,6 @@ static const WCHAR szKeepAlive[] = {'K','e','e','p','-','A','l','i','v','e',0}; static const WCHAR szGET[] = { 'G','E','T', 0 }; static const WCHAR szHEAD[] = { 'H','E','A','D', 0 }; -static const WCHAR szCrLf[] = {'\r','\n', 0}; static const WCHAR szAccept[] = { 'A','c','c','e','p','t',0 }; static const WCHAR szAccept_Charset[] = { 'A','c','c','e','p','t','-','C','h','a','r','s','e','t', 0 }; @@ -186,7 +181,6 @@ static DWORD HTTP_HttpQueryInfoW(http_request_t*, DWORD, LPVOID, LPDWORD, LPDWORD); static LPWSTR HTTP_GetRedirectURL(http_request_t *req, LPCWSTR lpszUrl); static UINT HTTP_DecodeBase64(LPCWSTR base64, LPSTR bin); -static BOOL HTTP_VerifyValidHeader(http_request_t *req, LPCWSTR field); static BOOL drain_content(http_request_t*,BOOL); static CRITICAL_SECTION connection_pool_cs; @@ -346,6 +340,11 @@ FreeLibraryAndExitThread(WININET_hModule, 0); } +/*********************************************************************** + * HTTP_GetHeader (internal) + * + * Headers section must be held + */ static LPHTTPHEADERW HTTP_GetHeader(http_request_t *req, LPCWSTR head) { int HeaderIndex = 0; @@ -354,6 +353,17 @@ return NULL; else return &req->custHeaders[HeaderIndex]; +} + +static WCHAR *get_host_header( http_request_t *req ) +{ + HTTPHEADERW *header; + WCHAR *ret = NULL; + + EnterCriticalSection( &req->headers_section ); + if ((header = HTTP_GetHeader( req, hostW ))) ret = heap_strdupW( header->lpszValue ); + LeaveCriticalSection( &req->headers_section ); + return ret; } struct data_stream_vtbl_t { @@ -385,6 +395,15 @@ req->data_stream = &req->netconn_stream.data_stream; req->read_pos = req->read_size = req->netconn_stream.content_read = 0; req->read_chunked = req->read_gzip = FALSE; +} + +static void remove_header( http_request_t *request, const WCHAR *str, BOOL from_request ) +{ + int index; + EnterCriticalSection( &request->headers_section ); + index = HTTP_GetCustomHeaderIndex( request, str, 0, from_request ); + if (index != -1) HTTP_DeleteCustomHeader( request, index ); + LeaveCriticalSection( &request->headers_section ); } #ifdef HAVE_ZLIB @@ -513,7 +532,7 @@ static DWORD init_gzip_stream(http_request_t *req, BOOL is_gzip) { gzip_stream_t *gzip_stream; - int index, zres; + int zres; gzip_stream = heap_alloc_zero(sizeof(gzip_stream_t)); if(!gzip_stream) @@ -530,9 +549,7 @@ return ERROR_OUTOFMEMORY; } - index = HTTP_GetCustomHeaderIndex(req, szContent_Length, 0, FALSE); - if(index != -1) - HTTP_DeleteCustomHeader(req, index); + remove_header(req, szContent_Length, FALSE); if(req->read_size) { memcpy(gzip_stream->buf, req->read_buf+req->read_pos, req->read_size); @@ -606,19 +623,24 @@ static WCHAR* build_request_header(http_request_t *request, const WCHAR *verb, const WCHAR *path, const WCHAR *version, BOOL use_cr) { + static const WCHAR szSpace[] = {' ',0}; + static const WCHAR szColon[] = {':',' ',0}; + static const WCHAR szCr[] = {'\r',0}; + static const WCHAR szLf[] = {'\n',0}; LPWSTR requestString; DWORD len, n; LPCWSTR *req; UINT i; - static const WCHAR szSpace[] = { ' ',0 }; - static const WCHAR szColon[] = { ':',' ',0 }; - static const WCHAR szCr[] = { '\r',0 }; - static const WCHAR szLf[] = { '\n',0 }; + EnterCriticalSection( &request->headers_section ); /* allocate space for an array of all the string pointers to be added */ - len = (request->nCustHeaders)*5 + 10; - req = heap_alloc(len*sizeof(LPCWSTR)); + len = request->nCustHeaders * 5 + 10; + if (!(req = heap_alloc( len * sizeof(const WCHAR *) ))) + { + LeaveCriticalSection( &request->headers_section ); + return NULL; + } /* add the verb, path and HTTP version string */ n = 0; @@ -655,6 +677,7 @@ requestString = HTTP_build_req( req, 4 ); heap_free( req ); + LeaveCriticalSection( &request->headers_section ); return requestString; } @@ -664,14 +687,17 @@ static const WCHAR crW[] = { '\r',0 }; static const WCHAR lfW[] = { '\n',0 }; static const WCHAR status_fmt[] = { ' ','%','u',' ',0 }; - const WCHAR **req; WCHAR *ret, buf[14]; DWORD i, n = 0; - req = heap_alloc((request->nCustHeaders*5+8)*sizeof(WCHAR*)); - if(!req) + EnterCriticalSection( &request->headers_section ); + + if (!(req = heap_alloc( (request->nCustHeaders * 5 + 8) * sizeof(WCHAR *) ))) + { + LeaveCriticalSection( &request->headers_section ); return NULL; + } if (request->status_code) { @@ -708,6 +734,7 @@ ret = HTTP_build_req(req, 0); heap_free(req); + LeaveCriticalSection( &request->headers_section ); return ret; } @@ -720,6 +747,8 @@ if(request->hdr.dwFlags & INTERNET_FLAG_NO_COOKIES) return; + EnterCriticalSection( &request->headers_section ); + while((HeaderIndex = HTTP_GetCustomHeaderIndex(request, szSet_Cookie, numCookies++, FALSE)) != -1) { HTTPHEADERW *host; @@ -747,6 +776,8 @@ set_cookie(host->lpszValue, request->path, name, data, INTERNET_COOKIE_HTTPONLY); heap_free(name); } + + LeaveCriticalSection( &request->headers_section ); } static void strip_spaces(LPWSTR start) @@ -754,7 +785,7 @@ LPWSTR str = start; LPWSTR end; - while (*str == ' ' && *str != '\0') + while (*str == ' ') str++; if (str != start) @@ -786,13 +817,13 @@ if (!token) return TRUE; realm = ptr; - while (*realm == ' ' && *realm != '\0') + while (*realm == ' ') realm++; if(!strncmpiW(realm, szRealm, ARRAYSIZE(szRealm)) && (realm[ARRAYSIZE(szRealm)] == ' ' || realm[ARRAYSIZE(szRealm)] == '=')) { token++; - while (*token == ' ' && *token != '\0') + while (*token == ' ') token++; if (*token == '\0') return TRUE; @@ -1266,10 +1297,8 @@ pFieldAndValue = HTTP_InterpretHttpHeader(lpszStart); if (pFieldAndValue) { - res = HTTP_VerifyValidHeader(request, pFieldAndValue[0]); - if (res == ERROR_SUCCESS) - res = HTTP_ProcessHeader(request, pFieldAndValue[0], - pFieldAndValue[1], dwModifier | HTTP_ADDHDR_FLAG_REQ); + res = HTTP_ProcessHeader(request, pFieldAndValue[0], + pFieldAndValue[1], dwModifier | HTTP_ADDHDR_FLAG_REQ); HTTP_FreeTokens(pFieldAndValue); } @@ -1806,8 +1835,7 @@ static DWORD HTTP_ResolveName(http_request_t *request) { server_t *server = request->proxy ? request->proxy : request->server; - socklen_t addr_len; - void *addr; + int addr_len; if(server->addr_len) return ERROR_SUCCESS; @@ -1818,23 +1846,10 @@ (strlenW(server->name)+1) * sizeof(WCHAR)); addr_len = sizeof(server->addr); - if (!GetAddress(server->name, server->port, (struct sockaddr *)&server->addr, &addr_len)) + if (!GetAddress(server->name, server->port, (SOCKADDR*)&server->addr, &addr_len, server->addr_str)) return ERROR_INTERNET_NAME_NOT_RESOLVED; - switch(server->addr.ss_family) { - case AF_INET: - addr = &((struct sockaddr_in *)&server->addr)->sin_addr; - break; - case AF_INET6: - addr = &((struct sockaddr_in6 *)&server->addr)->sin6_addr; - break; - default: - WARN("unsupported family %d\n", server->addr.ss_family); - return ERROR_INTERNET_NAME_NOT_RESOLVED; - } - server->addr_len = addr_len; - inet_ntop(server->addr.ss_family, addr, server->addr_str, sizeof(server->addr_str)); INTERNET_SendCallback(&request->hdr, request->hdr.dwContext, INTERNET_STATUS_NAME_RESOLVED, server->addr_str, strlen(server->addr_str)+1); @@ -1854,6 +1869,8 @@ host_header = HTTP_GetHeader(req, hostW); if(!host_header) return FALSE; + + EnterCriticalSection( &req->headers_section ); if (req->hdr.dwFlags & INTERNET_FLAG_SECURE) scheme = https; @@ -1864,6 +1881,8 @@ if (req->path[0] != '/') strcatW(buf, slash); strcatW(buf, req->path); + + LeaveCriticalSection( &req->headers_section ); return TRUE; } @@ -1886,6 +1905,8 @@ if(request->req_file) req_file_release(request->req_file); + request->headers_section.DebugInfo->Spare[0] = 0; + DeleteCriticalSection( &request->headers_section ); request->read_section.DebugInfo->Spare[0] = 0; DeleteCriticalSection( &request->read_section ); WININET_Release(&request->session->hdr); @@ -2100,17 +2121,18 @@ return ERROR_SUCCESS; case INTERNET_OPTION_URL: { + static const WCHAR httpW[] = {'h','t','t','p',':','/','/',0}; WCHAR url[INTERNET_MAX_URL_LENGTH]; HTTPHEADERW *host; - static const WCHAR httpW[] = {'h','t','t','p',':','/','/',0}; - TRACE("INTERNET_OPTION_URL\n"); + EnterCriticalSection( &req->headers_section ); host = HTTP_GetHeader(req, hostW); strcpyW(url, httpW); strcatW(url, host->lpszValue); strcatW(url, req->path); + LeaveCriticalSection( &req->headers_section ); TRACE("INTERNET_OPTION_URL: %s\n",debugstr_w(url)); return str_to_buffer(url, buffer, size, unicode); @@ -2386,7 +2408,11 @@ b = FALSE; if(b) { - int header_idx = HTTP_GetCustomHeaderIndex(req, szCache_Control, 0, FALSE); + int header_idx; + + EnterCriticalSection( &req->headers_section ); + + header_idx = HTTP_GetCustomHeaderIndex(req, szCache_Control, 0, FALSE); if(header_idx != -1) { WCHAR *ptr; @@ -2411,6 +2437,8 @@ ptr++; } } + + LeaveCriticalSection( &req->headers_section ); } if(!b) { @@ -2911,17 +2939,23 @@ static const WCHAR deflateW[] = {'d','e','f','l','a','t','e',0}; static const WCHAR gzipW[] = {'g','z','i','p',0}; + EnterCriticalSection( &request->headers_section ); + encoding_idx = HTTP_GetCustomHeaderIndex(request, szContent_Encoding, 0, FALSE); if(encoding_idx != -1) { if(!strcmpiW(request->custHeaders[encoding_idx].lpszValue, gzipW)) { HTTP_DeleteCustomHeader(request, encoding_idx); + LeaveCriticalSection( &request->headers_section ); return init_gzip_stream(request, TRUE); } if(!strcmpiW(request->custHeaders[encoding_idx].lpszValue, deflateW)) { HTTP_DeleteCustomHeader(request, encoding_idx); + LeaveCriticalSection( &request->headers_section ); return init_gzip_stream(request, FALSE); } } + + LeaveCriticalSection( &request->headers_section ); } return ERROR_SUCCESS; @@ -3290,6 +3324,9 @@ request->connect_timeout = session->connect_timeout; request->send_timeout = session->send_timeout; request->receive_timeout = session->receive_timeout; + + InitializeCriticalSection( &request->headers_section ); + request->headers_section.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": http_request_t.headers_section"); InitializeCriticalSection( &request->read_section ); request->read_section.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": http_request_t.read_section"); @@ -3508,11 +3545,17 @@ DWORD level = (dwInfoLevel & ~HTTP_QUERY_MODIFIER_FLAGS_MASK); INT index = -1; + EnterCriticalSection( &request->headers_section ); + /* Find requested header structure */ switch (level) { case HTTP_QUERY_CUSTOM: - if (!lpBuffer) return ERROR_INVALID_PARAMETER; + if (!lpBuffer) + { + LeaveCriticalSection( &request->headers_section ); + return ERROR_INVALID_PARAMETER; + } index = HTTP_GetCustomHeaderIndex(request, lpBuffer, requested_index, request_only); break; case HTTP_QUERY_RAW_HEADERS_CRLF: @@ -3526,7 +3569,10 @@ else headers = build_response_header(request, TRUE); if (!headers) + { + LeaveCriticalSection( &request->headers_section ); return ERROR_OUTOFMEMORY; + } len = strlenW(headers) * sizeof(WCHAR); if (len + sizeof(WCHAR) > *lpdwBufferLength) @@ -3543,6 +3589,7 @@ *lpdwBufferLength = len; heap_free(headers); + LeaveCriticalSection( &request->headers_section ); return res; } case HTTP_QUERY_RAW_HEADERS: @@ -3554,14 +3601,19 @@ headers = build_request_header(request, request->verb, request->path, request->version, FALSE); else headers = build_response_header(request, FALSE); + if (!headers) + { + LeaveCriticalSection( &request->headers_section ); return ERROR_OUTOFMEMORY; + } len = strlenW(headers) * sizeof(WCHAR); if (len > *lpdwBufferLength) { *lpdwBufferLength = len; heap_free(headers); + LeaveCriticalSection( &request->headers_section ); return ERROR_INSUFFICIENT_BUFFER; } @@ -3581,6 +3633,7 @@ *lpdwBufferLength = len - sizeof(WCHAR); heap_free(headers); + LeaveCriticalSection( &request->headers_section ); return ERROR_SUCCESS; } case HTTP_QUERY_STATUS_TEXT: @@ -3590,6 +3643,7 @@ if (len + 1 > *lpdwBufferLength/sizeof(WCHAR)) { *lpdwBufferLength = (len + 1) * sizeof(WCHAR); + LeaveCriticalSection( &request->headers_section ); return ERROR_INSUFFICIENT_BUFFER; } if (lpBuffer) @@ -3598,6 +3652,7 @@ TRACE("returning data: %s\n", debugstr_wn(lpBuffer, len)); } *lpdwBufferLength = len * sizeof(WCHAR); + LeaveCriticalSection( &request->headers_section ); return ERROR_SUCCESS; } break; @@ -3608,6 +3663,7 @@ if (len + 1 > *lpdwBufferLength/sizeof(WCHAR)) { *lpdwBufferLength = (len + 1) * sizeof(WCHAR); + LeaveCriticalSection( &request->headers_section ); return ERROR_INSUFFICIENT_BUFFER; } if (lpBuffer) @@ -3616,6 +3672,7 @@ TRACE("returning data: %s\n", debugstr_wn(lpBuffer, len)); } *lpdwBufferLength = len * sizeof(WCHAR); + LeaveCriticalSection( &request->headers_section ); return ERROR_SUCCESS; } break; @@ -3627,7 +3684,10 @@ DWORD res = ERROR_SUCCESS; if(request_only) + { + LeaveCriticalSection( &request->headers_section ); return ERROR_HTTP_INVALID_QUERY_REQUEST; + } if(requested_index) break; @@ -3654,6 +3714,7 @@ *lpdwBufferLength = size; } + LeaveCriticalSection( &request->headers_section ); return res; } default: @@ -3672,6 +3733,7 @@ ((dwInfoLevel & HTTP_QUERY_FLAG_REQUEST_HEADERS) && (~lphttpHdr->wFlags & HDR_ISREQUEST))) { + LeaveCriticalSection( &request->headers_section ); return ERROR_HTTP_HEADER_NOT_FOUND; } @@ -3711,6 +3773,7 @@ if (len > *lpdwBufferLength) { *lpdwBufferLength = len; + LeaveCriticalSection( &request->headers_section ); return ERROR_INSUFFICIENT_BUFFER; } if (lpBuffer) @@ -3721,6 +3784,8 @@ *lpdwBufferLength = len - sizeof(WCHAR); } if (lpdwIndex) (*lpdwIndex)++; + + LeaveCriticalSection( &request->headers_section ); return ERROR_SUCCESS; } @@ -4009,7 +4074,6 @@ { http_session_t *session = request->session; WCHAR path[INTERNET_MAX_PATH_LENGTH]; - int index; if(lpszUrl[0]=='/') { @@ -4073,19 +4137,8 @@ heap_free(session->hostName); - if(custom_port) { - int len; - static const WCHAR fmt[] = {'%','s',':','%','u',0}; - len = lstrlenW(hostName); - len += 7; /* 5 for strlen("65535") + 1 for ":" + 1 for '\0' */ - session->hostName = heap_alloc(len*sizeof(WCHAR)); - sprintfW(session->hostName, fmt, hostName, urlComponents.nPort); - } - else - session->hostName = heap_strdupW(hostName); + session->hostName = heap_strdupW(hostName); session->hostPort = urlComponents.nPort; - - HTTP_ProcessHeader(request, hostW, session->hostName, HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE | HTTP_ADDHDR_FLAG_REQ); heap_free(session->userName); session->userName = NULL; @@ -4101,6 +4154,11 @@ server_release(request->server); request->server = new_server; } + + if (custom_port) + HTTP_ProcessHeader(request, hostW, request->server->host_port, HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE | HTTP_ADDHDR_FLAG_REQ); + else + HTTP_ProcessHeader(request, hostW, request->server->name, HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE | HTTP_ADDHDR_FLAG_REQ); } heap_free(request->path); request->path=NULL; @@ -4123,12 +4181,8 @@ } /* Remove custom content-type/length headers on redirects. */ - index = HTTP_GetCustomHeaderIndex(request, szContent_Type, 0, TRUE); - if (0 <= index) - HTTP_DeleteCustomHeader(request, index); - index = HTTP_GetCustomHeaderIndex(request, szContent_Length, 0, TRUE); - if (0 <= index) - HTTP_DeleteCustomHeader(request, index); + remove_header(request, szContent_Type, TRUE); + remove_header(request, szContent_Length, TRUE); return ERROR_SUCCESS; } @@ -4585,6 +4639,8 @@ { BOOL expirationFound = FALSE; int headerIndex; + + EnterCriticalSection( &request->headers_section ); /* Look for a Cache-Control header with a max-age directive, as it takes * precedence over the Expires header. @@ -4666,11 +4722,15 @@ request->expires.dwLowDateTime = t.u.LowPart; request->expires.dwHighDateTime = t.u.HighPart; } + + LeaveCriticalSection( &request->headers_section ); } static void HTTP_ProcessLastModified(http_request_t *request) { int headerIndex; + + EnterCriticalSection( &request->headers_section ); headerIndex = HTTP_GetCustomHeaderIndex(request, szLast_Modified, 0, FALSE); if (headerIndex != -1) @@ -4681,11 +4741,15 @@ if (HTTP_ParseDate(expiresHeader->lpszValue, &ft)) request->last_modified = ft; } + + LeaveCriticalSection( &request->headers_section ); } static void http_process_keep_alive(http_request_t *req) { int index; + + EnterCriticalSection( &req->headers_section ); if ((index = HTTP_GetCustomHeaderIndex(req, szConnection, 0, FALSE)) != -1) req->netconn->keep_alive = !strcmpiW(req->custHeaders[index].lpszValue, szKeepAlive); @@ -4693,6 +4757,8 @@ req->netconn->keep_alive = !strcmpiW(req->custHeaders[index].lpszValue, szKeepAlive); else req->netconn->keep_alive = !strcmpiW(req->version, g_szHttp1_1); + + LeaveCriticalSection( &req->headers_section ); } static DWORD open_http_connection(http_request_t *request, BOOL *reusing) @@ -4864,8 +4930,12 @@ if (TRACE_ON(wininet)) { - LPHTTPHEADERW Host = HTTP_GetHeader(request, hostW); - TRACE("Going to url %s %s\n", debugstr_w(Host->lpszValue), debugstr_w(request->path)); + HTTPHEADERW *host; + + EnterCriticalSection( &request->headers_section ); + host = HTTP_GetHeader( request, hostW ); + TRACE("Going to url %s %s\n", debugstr_w(host->lpszValue), debugstr_w(request->path)); + LeaveCriticalSection( &request->headers_section ); } HTTP_FixURL(request); @@ -5019,15 +5089,14 @@ dwBufferSize=2048; if (request->status_code == HTTP_STATUS_DENIED) { - LPHTTPHEADERW Host = HTTP_GetHeader(request, hostW); + WCHAR *host = get_host_header( request ); DWORD dwIndex = 0; while (HTTP_HttpQueryInfoW(request,HTTP_QUERY_WWW_AUTHENTICATE,szAuthValue,&dwBufferSize,&dwIndex) == ERROR_SUCCESS) { if (HTTP_DoAuthorization(request, szAuthValue, &request->authInfo, request->session->userName, - request->session->password, - Host->lpszValue)) + request->session->password, host)) { heap_free(requestString); if(!drain_content(request, TRUE)) { @@ -5038,6 +5107,7 @@ break; } } + heap_free( host ); if(!loop_next) { TRACE("Cleaning wrong authorization data\n"); @@ -5075,8 +5145,6 @@ } if (secure_proxy_connect && request->status_code == HTTP_STATUS_OK) { - int index; - res = NETCON_secure_connect(request->netconn, request->server); if (res != ERROR_SUCCESS) { @@ -5084,8 +5152,7 @@ http_release_netconn( request, FALSE ); break; } - index = HTTP_GetCustomHeaderIndex(request, szProxy_Authorization, 0, TRUE); - if (index != -1) HTTP_DeleteCustomHeader(request, index); + remove_header(request, szProxy_Authorization, TRUE); destroy_authinfo(request->proxyAuthInfo); request->proxyAuthInfo = NULL; @@ -5794,6 +5861,8 @@ { DWORD i; + EnterCriticalSection( &request->headers_section ); + for( i=0; i<request->nCustHeaders; i++) { if( !request->custHeaders[i].lpszField ) @@ -5805,6 +5874,8 @@ HTTP_DeleteCustomHeader( request, i ); i--; } + + LeaveCriticalSection( &request->headers_section ); } /*********************************************************************** @@ -6005,11 +6076,13 @@ static DWORD HTTP_ProcessHeader(http_request_t *request, LPCWSTR field, LPCWSTR value, DWORD dwModifier) { LPHTTPHEADERW lphttpHdr = NULL; - INT index = -1; + INT index; BOOL request_only = dwModifier & HTTP_ADDHDR_FLAG_REQ; DWORD res = ERROR_HTTP_INVALID_HEADER; TRACE("--> %s: %s - 0x%08x\n", debugstr_w(field), debugstr_w(value), dwModifier); + + EnterCriticalSection( &request->headers_section ); /* REPLACE wins out over ADD */ if (dwModifier & HTTP_ADDHDR_FLAG_REPLACE) @@ -6023,7 +6096,10 @@ if (index >= 0) { if (dwModifier & HTTP_ADDHDR_FLAG_ADD_IF_NEW) + { + LeaveCriticalSection( &request->headers_section ); return ERROR_HTTP_INVALID_HEADER; + } lphttpHdr = &request->custHeaders[index]; } else if (value) @@ -6037,10 +6113,16 @@ if (dwModifier & HTTP_ADDHDR_FLAG_REQ) hdr.wFlags |= HDR_ISREQUEST; - return HTTP_InsertCustomHeader(request, &hdr); + res = HTTP_InsertCustomHeader(request, &hdr); + LeaveCriticalSection( &request->headers_section ); + return res; } /* no value to delete */ - else return ERROR_SUCCESS; + else + { + LeaveCriticalSection( &request->headers_section ); + return ERROR_SUCCESS; + } if (dwModifier & HTTP_ADDHDR_FLAG_REQ) lphttpHdr->wFlags |= HDR_ISREQUEST; @@ -6062,9 +6144,12 @@ if (dwModifier & HTTP_ADDHDR_FLAG_REQ) hdr.wFlags |= HDR_ISREQUEST; - return HTTP_InsertCustomHeader(request, &hdr); - } - + res = HTTP_InsertCustomHeader(request, &hdr); + LeaveCriticalSection( &request->headers_section ); + return res; + } + + LeaveCriticalSection( &request->headers_section ); return ERROR_SUCCESS; } else if (dwModifier & COALESCEFLAGS) @@ -6112,6 +6197,7 @@ } } TRACE("<-- %d\n", res); + LeaveCriticalSection( &request->headers_section ); return res; } @@ -6119,7 +6205,7 @@ * HTTP_GetCustomHeaderIndex (internal) * * Return index of custom header from header array - * + * Headers section must be held */ static INT HTTP_GetCustomHeaderIndex(http_request_t *request, LPCWSTR lpszField, int requested_index, BOOL request_only) @@ -6156,7 +6242,7 @@ * HTTP_InsertCustomHeader (internal) * * Insert header into array - * + * Headers section must be held */ static DWORD HTTP_InsertCustomHeader(http_request_t *request, LPHTTPHEADERW lpHdr) { @@ -6188,7 +6274,8 @@ * HTTP_DeleteCustomHeader (internal) * * Delete header from array - * If this function is called, the indexs may change. + * If this function is called, the index may change. + * Headers section must be held */ static BOOL HTTP_DeleteCustomHeader(http_request_t *request, DWORD index) { @@ -6210,21 +6297,6 @@ /*********************************************************************** - * HTTP_VerifyValidHeader (internal) - * - * Verify the given header is not invalid for the given http request - * - */ -static BOOL HTTP_VerifyValidHeader(http_request_t *request, LPCWSTR field) -{ - /* Accept-Encoding is stripped from HTTP/1.0 requests. It is invalid */ - if (!strcmpW(request->version, g_szHttp1_0) && !strcmpiW(field, szAccept_Encoding)) - return ERROR_HTTP_INVALID_HEADER; - - return ERROR_SUCCESS; -} - -/*********************************************************************** * IsHostInProxyBypassList (@) * * Undocumented Modified: trunk/reactos/dll/win32/wininet/internet.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/wininet/internet…
============================================================================== --- trunk/reactos/dll/win32/wininet/internet.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/wininet/internet.c [iso-8859-1] Wed Apr 22 08:30:31 2015 @@ -27,8 +27,6 @@ */ #include "internet.h" - -#define RESPONSE_TIMEOUT 30 typedef struct { @@ -487,11 +485,12 @@ static BOOL parse_proxy_url( proxyinfo_t *info, const WCHAR *url ) { static const WCHAR fmt[] = {'%','s',':','%','u',0}; - WCHAR hostname[INTERNET_MAX_HOST_NAME_LENGTH] = {0}; - WCHAR username[INTERNET_MAX_USER_NAME_LENGTH] = {0}; - WCHAR password[INTERNET_MAX_PASSWORD_LENGTH] = {0}; + WCHAR hostname[INTERNET_MAX_HOST_NAME_LENGTH]; + WCHAR username[INTERNET_MAX_USER_NAME_LENGTH]; + WCHAR password[INTERNET_MAX_PASSWORD_LENGTH]; URL_COMPONENTSW uc; + hostname[0] = username[0] = password[0] = 0; memset( &uc, 0, sizeof(uc) ); uc.dwStructSize = sizeof(uc); uc.lpszHostName = hostname; @@ -801,9 +800,6 @@ heap_free(lpwai->proxyBypass); heap_free(lpwai->proxyUsername); heap_free(lpwai->proxyPassword); -#ifdef __REACTOS__ - WSACleanup(); -#endif } static DWORD APPINFO_QueryOption(object_header_t *hdr, DWORD option, void *buffer, DWORD *size, BOOL unicode) @@ -999,11 +995,6 @@ LPCWSTR lpszProxy, LPCWSTR lpszProxyBypass, DWORD dwFlags) { appinfo_t *lpwai = NULL; -#ifdef __REACTOS__ - WSADATA wsaData; - int error = WSAStartup(MAKEWORD(2, 2), &wsaData); - if (error) ERR("WSAStartup failed: %d\n", error); -#endif if (TRACE_ON(wininet)) { #define FE(x) { x, #x } @@ -1227,13 +1218,21 @@ /* Must be zero */ if(dwReserved) - return FALSE; + return FALSE; if (lpdwStatus) { WARN("always returning LAN connection.\n"); *lpdwStatus = INTERNET_CONNECTION_LAN; } - return LoadStringW(WININET_hModule, IDS_LANCONNECTION, lpszConnectionName, dwNameLen) > 0; + + /* When the buffer size is zero LoadStringW fills the buffer with a pointer to + * the resource, avoid it as we must not change the buffer in this case */ + if(lpszConnectionName && dwNameLen) { + *lpszConnectionName = '\0'; + LoadStringW(WININET_hModule, IDS_LANCONNECTION, lpszConnectionName, dwNameLen); + } + + return TRUE; } @@ -3418,14 +3417,15 @@ socklen_t sa_len = sizeof(saddr); int fd; - if (!GetAddress(hostW, port, (struct sockaddr *)&saddr, &sa_len)) + if (!GetAddress(hostW, port, (struct sockaddr *)&saddr, &sa_len, NULL)) goto End; + init_winsock(); fd = socket(saddr.ss_family, SOCK_STREAM, 0); if (fd != -1) { if (connect(fd, (struct sockaddr *)&saddr, sa_len) == 0) rc = TRUE; - close(fd); + closesocket(fd); } } else @@ -3860,72 +3860,6 @@ return lpwite->response; } -/*********************************************************************** - * INTERNET_GetNextLine (internal) - * - * Parse next line in directory string listing - * - * RETURNS - * Pointer to beginning of next line - * NULL on failure - * - */ - -LPSTR INTERNET_GetNextLine(INT nSocket, LPDWORD dwLen) -{ - /* ReactOS: use select instead of poll */ - fd_set infd; - struct timeval tv; - BOOL bSuccess = FALSE; - INT nRecv = 0; - LPSTR lpszBuffer = INTERNET_GetResponseBuffer(); - - TRACE("\n"); - - FD_ZERO(&infd); - FD_SET(nSocket,&infd); - tv.tv_sec = RESPONSE_TIMEOUT; - tv.tv_usec = 0; - - while (nRecv < MAX_REPLY_LEN) - { - if (select(0, &infd, NULL, NULL, &tv) > 0) - { - if (sock_recv(nSocket, &lpszBuffer[nRecv], 1, 0) <= 0) - { - INTERNET_SetLastError(ERROR_FTP_TRANSFER_IN_PROGRESS); - goto lend; - } - - if (lpszBuffer[nRecv] == '\n') - { - bSuccess = TRUE; - break; - } - if (lpszBuffer[nRecv] != '\r') - nRecv++; - } - else - { - INTERNET_SetLastError(ERROR_INTERNET_TIMEOUT); - goto lend; - } - } - -lend: - if (bSuccess) - { - lpszBuffer[nRecv] = '\0'; - *dwLen = nRecv - 1; - TRACE(":%d %s\n", nRecv, lpszBuffer); - return lpszBuffer; - } - else - { - return NULL; - } -} - /********************************************************** * InternetQueryDataAvailable (WININET.@) * Modified: trunk/reactos/dll/win32/wininet/internet.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/wininet/internet…
============================================================================== --- trunk/reactos/dll/win32/wininet/internet.h [iso-8859-1] (original) +++ trunk/reactos/dll/win32/wininet/internet.h [iso-8859-1] Wed Apr 22 08:30:31 2015 @@ -98,7 +98,7 @@ INTERNET_PORT port; BOOL is_https; struct sockaddr_storage addr; - socklen_t addr_len; + int addr_len; char addr_str[INET6_ADDRSTRLEN]; WCHAR *scheme_host_port; @@ -402,8 +402,11 @@ LPWSTR statusText; DWORD bytesToWrite; DWORD bytesWritten; + + CRITICAL_SECTION headers_section; /* section to protect the headers array */ HTTPHEADERW *custHeaders; DWORD nCustHeaders; + FILETIME last_modified; HANDLE hCacheFile; req_file_t *req_file; @@ -455,8 +458,7 @@ LPCWSTR lpszPassword, DWORD dwFlags, DWORD_PTR dwContext, DWORD dwInternalFlags, HINTERNET*) DECLSPEC_HIDDEN; -BOOL GetAddress(LPCWSTR lpszServerName, INTERNET_PORT nServerPort, - struct sockaddr *psa, socklen_t *sa_len) DECLSPEC_HIDDEN; +BOOL GetAddress(const WCHAR*,INTERNET_PORT,SOCKADDR*,int*,char*) DECLSPEC_HIDDEN; DWORD get_cookie_header(const WCHAR*,const WCHAR*,WCHAR**) DECLSPEC_HIDDEN; DWORD set_cookie(const WCHAR*,const WCHAR*,const WCHAR*,const WCHAR*,DWORD) DECLSPEC_HIDDEN; @@ -465,7 +467,6 @@ DWORD INTERNET_GetLastError(void) DECLSPEC_HIDDEN; DWORD INTERNET_AsyncCall(task_header_t*) DECLSPEC_HIDDEN; LPSTR INTERNET_GetResponseBuffer(void) DECLSPEC_HIDDEN; -LPSTR INTERNET_GetNextLine(INT nSocket, LPDWORD dwLen) DECLSPEC_HIDDEN; VOID SendAsyncCallback(object_header_t *hdr, DWORD_PTR dwContext, DWORD dwInternetStatus, LPVOID lpvStatusInfo, @@ -494,33 +495,7 @@ LPCVOID NETCON_GetCert(netconn_t *connection) DECLSPEC_HIDDEN; int NETCON_GetCipherStrength(netconn_t*) DECLSPEC_HIDDEN; DWORD NETCON_set_timeout(netconn_t *connection, BOOL send, DWORD value) DECLSPEC_HIDDEN; -#ifndef __REACTOS__ -int sock_get_error(int) DECLSPEC_HIDDEN; -#else - -#define sock_get_error(x) WSAGetLastError() -const char *inet_ntop(int, const void *, char *, socklen_t); - -static inline long unix_recv(int socket, void *buffer, size_t length, int flags) -{ - return recv(socket, buffer, length, flags); -} -#define recv unix_recv - -static inline int unix_ioctl(int filedes, long request, void *arg) -{ - return ioctlsocket(filedes, request, arg); -} -#define ioctlsocket unix_ioctl - -static inline int unix_getsockopt(int socket, int level, int option_name, void *option_value, socklen_t *option_len) -{ - return getsockopt(socket, level, option_name, option_value, option_len); -} -#define getsockopt unix_getsockopt - -#endif /* !__REACTOS__ */ - +int sock_get_error(void) DECLSPEC_HIDDEN; int sock_send(int fd, const void *msg, size_t len, int flags) DECLSPEC_HIDDEN; int sock_recv(int fd, void *msg, size_t len, int flags) DECLSPEC_HIDDEN; @@ -538,6 +513,8 @@ BOOL init_urlcache(void) DECLSPEC_HIDDEN; void free_urlcache(void) DECLSPEC_HIDDEN; void free_cookie(void) DECLSPEC_HIDDEN; + +void init_winsock(void) DECLSPEC_HIDDEN; #define MAX_REPLY_LEN 0x5B4 Modified: trunk/reactos/dll/win32/wininet/netconnection.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/wininet/netconne…
============================================================================== --- trunk/reactos/dll/win32/wininet/netconnection.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/wininet/netconnection.c [iso-8859-1] Wed Apr 22 08:30:31 2015 @@ -1,5 +1,5 @@ /* - * Wininet - networking layer. Uses unix sockets. + * Wininet - networking layer * * Copyright 2002 TransGaming Technologies Inc. * Copyright 2013 Jacek Caban for CodeWeavers @@ -36,19 +36,6 @@ #include <errno.h> -#define RESPONSE_TIMEOUT 30 /* FROM internet.c */ - -#ifdef MSG_DONTWAIT -#define WINE_MSG_DONTWAIT MSG_DONTWAIT -#else -#define WINE_MSG_DONTWAIT 0 -#endif - -/* FIXME!!!!!! - * This should use winsock - To use winsock the functions will have to change a bit - * as they are designed for unix sockets. - */ - static DWORD netconn_verify_cert(netconn_t *conn, PCCERT_CONTEXT cert, HCERTSTORE store) { BOOL ret; @@ -62,6 +49,7 @@ CERT_TRUST_IS_NOT_TIME_VALID | CERT_TRUST_IS_UNTRUSTED_ROOT | CERT_TRUST_IS_PARTIAL_CHAIN | + CERT_TRUST_IS_NOT_SIGNATURE_VALID | CERT_TRUST_IS_NOT_VALID_FOR_USAGE; TRACE("verifying %s\n", debugstr_w(conn->server->name)); @@ -126,6 +114,17 @@ conn->security_flags |= _SECURITY_FLAG_CERT_INVALID_CA; } errors &= ~CERT_TRUST_IS_PARTIAL_CHAIN; + } + + if(errors & CERT_TRUST_IS_NOT_SIGNATURE_VALID) { + WARN("CERT_TRUST_IS_NOT_SIGNATURE_VALID\n"); + if(!(conn->security_flags & SECURITY_FLAG_IGNORE_UNKNOWN_CA)) { + err = conn->mask_errors && err ? ERROR_INTERNET_SEC_CERT_ERRORS : ERROR_INTERNET_INVALID_CA; + if(!conn->mask_errors) + break; + conn->security_flags |= _SECURITY_FLAG_CERT_INVALID_CA; + } + errors &= ~CERT_TRUST_IS_NOT_SIGNATURE_VALID; } if(errors & CERT_TRUST_IS_NOT_VALID_FOR_USAGE) { @@ -253,43 +252,65 @@ return TRUE; } +static BOOL winsock_loaded = FALSE; + +static BOOL WINAPI winsock_startup(INIT_ONCE *once, void *param, void **context) +{ + WSADATA wsa_data; + DWORD res; + + res = WSAStartup(MAKEWORD(1,1), &wsa_data); + if(res == ERROR_SUCCESS) + winsock_loaded = TRUE; + else + ERR("WSAStartup failed: %u\n", res); + return TRUE; +} + +void init_winsock(void) +{ + static INIT_ONCE init_once = INIT_ONCE_STATIC_INIT; + InitOnceExecuteOnce(&init_once, winsock_startup, NULL, NULL); +} + +static void set_socket_blocking(int socket, blocking_mode_t mode) +{ + ULONG arg = mode == BLOCKING_DISALLOW; + ioctlsocket(socket, FIONBIO, &arg); +} + static DWORD create_netconn_socket(server_t *server, netconn_t *netconn, DWORD timeout) { int result; ULONG flag; + DWORD res; + + init_winsock(); assert(server->addr_len); result = netconn->socket = socket(server->addr.ss_family, SOCK_STREAM, 0); if(result != -1) { - flag = 1; - ioctlsocket(netconn->socket, FIONBIO, &flag); + set_socket_blocking(netconn->socket, BLOCKING_DISALLOW); result = connect(netconn->socket, (struct sockaddr*)&server->addr, server->addr_len); if(result == -1) { - if (sock_get_error(errno) == WSAEINPROGRESS) { - /* ReactOS: use select instead of poll */ - fd_set outfd; - struct timeval tv; + res = sock_get_error(); + if (res == WSAEINPROGRESS || res == WSAEWOULDBLOCK) { + FD_SET set; int res; - - FD_ZERO(&outfd); - FD_SET(netconn->socket, &outfd); - tv.tv_sec = timeout / 1000; - tv.tv_usec = (timeout % 1000) * 1000; - res = select(0, NULL, &outfd, NULL, &tv); - if (!res) - { + socklen_t len = sizeof(res); + TIMEVAL timeout_timeval = {0, timeout*1000}; + + FD_ZERO(&set); + FD_SET(netconn->socket, &set); + res = select(netconn->socket+1, NULL, &set, NULL, &timeout_timeval); + if(!res || res == SOCKET_ERROR) { closesocket(netconn->socket); netconn->socket = -1; return ERROR_INTERNET_CANNOT_CONNECT; } - else if (res > 0) - { - int err; - socklen_t len = sizeof(err); - if (!getsockopt(netconn->socket, SOL_SOCKET, SO_ERROR, (void *)&err, &len) && !err) - result = 0; - } + if (!getsockopt(netconn->socket, SOL_SOCKET, SO_ERROR, (void *)&res, &len) && !res) + result = 0; } } if(result == -1) @@ -298,19 +319,16 @@ netconn->socket = -1; } else { - flag = 0; - ioctlsocket(netconn->socket, FIONBIO, &flag); + set_socket_blocking(netconn->socket, BLOCKING_ALLOW); } } if(result == -1) return ERROR_INTERNET_CANNOT_CONNECT; -#ifdef TCP_NODELAY flag = 1; result = setsockopt(netconn->socket, IPPROTO_TCP, TCP_NODELAY, (void*)&flag, sizeof(flag)); if(result < 0) WARN("setsockopt(TCP_NODELAY) failed\n"); -#endif return ERROR_SUCCESS; } @@ -381,76 +399,14 @@ if(have_compat_cred_handle) FreeCredentialsHandle(&compat_cred_handle); DeleteCriticalSection(&init_sechandle_cs); -} - -#ifndef __REACTOS__ + WSACleanup(); +} + /* translate a unix error code into a winsock one */ -int sock_get_error( int err ) -{ -#if !defined(__MINGW32__) && !defined (_MSC_VER) - switch (err) - { - case EINTR: return WSAEINTR; - case EBADF: return WSAEBADF; - case EPERM: - case EACCES: return WSAEACCES; - case EFAULT: return WSAEFAULT; - case EINVAL: return WSAEINVAL; - case EMFILE: return WSAEMFILE; - case EWOULDBLOCK: return WSAEWOULDBLOCK; - case EINPROGRESS: return WSAEINPROGRESS; - case EALREADY: return WSAEALREADY; - case ENOTSOCK: return WSAENOTSOCK; - case EDESTADDRREQ: return WSAEDESTADDRREQ; - case EMSGSIZE: return WSAEMSGSIZE; - case EPROTOTYPE: return WSAEPROTOTYPE; - case ENOPROTOOPT: return WSAENOPROTOOPT; - case EPROTONOSUPPORT: return WSAEPROTONOSUPPORT; - case ESOCKTNOSUPPORT: return WSAESOCKTNOSUPPORT; - case EOPNOTSUPP: return WSAEOPNOTSUPP; - case EPFNOSUPPORT: return WSAEPFNOSUPPORT; - case EAFNOSUPPORT: return WSAEAFNOSUPPORT; - case EADDRINUSE: return WSAEADDRINUSE; - case EADDRNOTAVAIL: return WSAEADDRNOTAVAIL; - case ENETDOWN: return WSAENETDOWN; - case ENETUNREACH: return WSAENETUNREACH; - case ENETRESET: return WSAENETRESET; - case ECONNABORTED: return WSAECONNABORTED; - case EPIPE: - case ECONNRESET: return WSAECONNRESET; - case ENOBUFS: return WSAENOBUFS; - case EISCONN: return WSAEISCONN; - case ENOTCONN: return WSAENOTCONN; - case ESHUTDOWN: return WSAESHUTDOWN; - case ETOOMANYREFS: return WSAETOOMANYREFS; - case ETIMEDOUT: return WSAETIMEDOUT; - case ECONNREFUSED: return WSAECONNREFUSED; - case ELOOP: return WSAELOOP; - case ENAMETOOLONG: return WSAENAMETOOLONG; - case EHOSTDOWN: return WSAEHOSTDOWN; - case EHOSTUNREACH: return WSAEHOSTUNREACH; - case ENOTEMPTY: return WSAENOTEMPTY; -#ifdef EPROCLIM - case EPROCLIM: return WSAEPROCLIM; -#endif -#ifdef EUSERS - case EUSERS: return WSAEUSERS; -#endif -#ifdef EDQUOT - case EDQUOT: return WSAEDQUOT; -#endif -#ifdef ESTALE - case ESTALE: return WSAESTALE; -#endif -#ifdef EREMOTE - case EREMOTE: return WSAEREMOTE; -#endif - default: errno=err; perror("sock_set_error"); return WSAEFAULT; - } -#endif - return err; -} -#endif /* !__REACTOS__ */ +int sock_get_error(void) +{ + return WSAGetLastError(); +} int sock_send(int fd, const void *msg, size_t len, int flags) { @@ -459,7 +415,7 @@ { ret = send(fd, msg, len, flags); } - while(ret == -1 && errno == EINTR); + while(ret == -1 && sock_get_error() == WSAEINTR); return ret; } @@ -470,16 +426,8 @@ { ret = recv(fd, msg, len, flags); } - while(ret == -1 && errno == EINTR); + while(ret == -1 && sock_get_error() == WSAEINTR); return ret; -} - -static void set_socket_blocking(int socket, blocking_mode_t mode) -{ -#if defined(__MINGW32__) || defined (_MSC_VER) - ULONG arg = mode == BLOCKING_DISALLOW; - ioctlsocket(socket, FIONBIO, &arg); -#endif } static DWORD netcon_secure_connect_setup(netconn_t *connection, BOOL compat_mode) @@ -715,9 +663,7 @@ if(!connection->secure) { *sent = sock_send(connection->socket, msg, len, flags); - if (*sent == -1) - return sock_get_error(errno); - return ERROR_SUCCESS; + return *sent == -1 ? sock_get_error() : ERROR_SUCCESS; } else { @@ -766,10 +712,10 @@ tmp_mode = buf_len ? BLOCKING_DISALLOW : mode; set_socket_blocking(conn->socket, tmp_mode); - size = sock_recv(conn->socket, conn->ssl_buf+buf_len, ssl_buf_size-buf_len, tmp_mode == BLOCKING_ALLOW ? 0 : WINE_MSG_DONTWAIT); + size = sock_recv(conn->socket, conn->ssl_buf+buf_len, ssl_buf_size-buf_len, 0); if(size < 0) { if(!buf_len) { - if(errno == EAGAIN || errno == EWOULDBLOCK) { + if(sock_get_error() == WSAEWOULDBLOCK) { TRACE("would block\n"); return WSAEWOULDBLOCK; } @@ -807,9 +753,9 @@ assert(buf_len < ssl_buf_size); set_socket_blocking(conn->socket, mode); - size = sock_recv(conn->socket, conn->ssl_buf+buf_len, ssl_buf_size-buf_len, mode == BLOCKING_ALLOW ? 0 : WINE_MSG_DONTWAIT); + size = sock_recv(conn->socket, conn->ssl_buf+buf_len, ssl_buf_size-buf_len, 0); if(size < 1) { - if(size < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) { + if(size < 0 && sock_get_error() == WSAEWOULDBLOCK) { TRACE("would block\n"); /* FIXME: Optimize extra_buf usage. */ @@ -879,20 +825,12 @@ { int flags = 0; - switch(mode) { - case BLOCKING_ALLOW: - break; - case BLOCKING_DISALLOW: - flags = WINE_MSG_DONTWAIT; - break; - case BLOCKING_WAITALL: + if(mode == BLOCKING_WAITALL) flags = MSG_WAITALL; - break; - } set_socket_blocking(connection->socket, mode); *recvd = sock_recv(connection->socket, buf, len, flags); - return *recvd == -1 ? sock_get_error(errno) : ERROR_SUCCESS; + return *recvd == -1 ? sock_get_error() : ERROR_SUCCESS; } else { @@ -956,7 +894,6 @@ if(!connection->secure) { -#ifdef FIONREAD ULONG unread; int retval = ioctlsocket(connection->socket, FIONREAD, &unread); if (!retval) @@ -964,7 +901,6 @@ TRACE("%d bytes of queued, but unread data\n", unread); *available += unread; } -#endif } else { @@ -975,32 +911,14 @@ BOOL NETCON_is_alive(netconn_t *netconn) { -#ifdef MSG_DONTWAIT - ssize_t len; - BYTE b; - - len = sock_recv(netconn->socket, &b, 1, MSG_PEEK|MSG_DONTWAIT); - return len == 1 || (len == -1 && errno == EWOULDBLOCK); -#elif defined(__MINGW32__) || defined(_MSC_VER) - ULONG mode; int len; char b; - mode = 1; - if(!ioctlsocket(netconn->socket, FIONBIO, &mode)) - return FALSE; - + set_socket_blocking(netconn->socket, BLOCKING_DISALLOW); len = sock_recv(netconn->socket, &b, 1, MSG_PEEK); - - mode = 0; - if(!ioctlsocket(netconn->socket, FIONBIO, &mode)) - return FALSE; - - return len == 1 || (len == -1 && errno == WSAEWOULDBLOCK); -#else - FIXME("not supported on this platform\n"); - return TRUE; -#endif + set_socket_blocking(netconn->socket, BLOCKING_ALLOW); + + return len == 1 || (len == -1 && sock_get_error() == WSAEWOULDBLOCK); } LPCVOID NETCON_GetCert(netconn_t *connection) @@ -1047,8 +965,8 @@ sizeof(tv)); if (result == -1) { - WARN("setsockopt failed (%s)\n", strerror(errno)); - return sock_get_error(errno); + WARN("setsockopt failed\n"); + return sock_get_error(); } return ERROR_SUCCESS; } Modified: trunk/reactos/dll/win32/wininet/urlcache.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/wininet/urlcache…
============================================================================== --- trunk/reactos/dll/win32/wininet/urlcache.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/wininet/urlcache.c [iso-8859-1] Wed Apr 22 08:30:31 2015 @@ -1205,7 +1205,6 @@ static int urlcache_decode_url(const char *url, WCHAR *decoded_url, int decoded_len) { -#ifndef __REACTOS__ /* FIXME: Vista+ */ URL_COMPONENTSA uc; DWORD len, part_len; WCHAR *host_name; @@ -1217,10 +1216,8 @@ uc.nScheme = INTERNET_SCHEME_UNKNOWN; if(uc.nScheme!=INTERNET_SCHEME_HTTP && uc.nScheme!=INTERNET_SCHEME_HTTPS) -#endif return MultiByteToWideChar(CP_UTF8, 0, url, -1, decoded_url, decoded_len); -#ifndef __REACTOS__ /* FIXME: Vista+ */ if(!decoded_url) decoded_len = 0; @@ -1257,7 +1254,6 @@ len += part_len; return len; -#endif /* !__REACTOS__ */ } /*********************************************************************** @@ -1873,7 +1869,6 @@ static int urlcache_encode_url(const WCHAR *url, char *encoded_url, int encoded_len) { -#ifndef __REACTOS__ /* FIXME: Vista+ */ URL_COMPONENTSW uc; DWORD len, part_len; WCHAR *punycode; @@ -1887,10 +1882,8 @@ uc.nScheme = INTERNET_SCHEME_UNKNOWN; if(uc.nScheme!=INTERNET_SCHEME_HTTP && uc.nScheme!=INTERNET_SCHEME_HTTPS) -#endif return WideCharToMultiByte(CP_UTF8, 0, url, -1, encoded_url, encoded_len, NULL, NULL); -#ifndef __REACTOS__ /* FIXME: Vista+ */ len = WideCharToMultiByte(CP_UTF8, 0, url, uc.lpszHostName-url, encoded_url, encoded_len, NULL, NULL); if(!len) @@ -1931,7 +1924,6 @@ TRACE("got (%d)%s\n", len, debugstr_a(encoded_url)); return len; -#endif /* !__REACTOS__ */ } static BOOL urlcache_encode_url_alloc(const WCHAR *url, char **encoded_url) Modified: trunk/reactos/dll/win32/wininet/utility.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/wininet/utility.…
============================================================================== --- trunk/reactos/dll/win32/wininet/utility.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/wininet/utility.c [iso-8859-1] Wed Apr 22 08:30:31 2015 @@ -24,19 +24,8 @@ #include "internet.h" -#ifndef HAVE_GETADDRINFO - -/* critical section to protect non-reentrant gethostbyname() */ -static CRITICAL_SECTION cs_gethostbyname; -static CRITICAL_SECTION_DEBUG critsect_debug = -{ - 0, 0, &cs_gethostbyname, - { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList }, - 0, 0, { (DWORD_PTR)(__FILE__ ": cs_gethostbyname") } -}; -static CRITICAL_SECTION cs_gethostbyname = { &critsect_debug, -1, 0, 0, 0, 0 }; - -#endif +// ReactOS +#include "inet_ntop.c" #define TIME_STRING_LEN 30 @@ -124,62 +113,36 @@ } -BOOL GetAddress(LPCWSTR lpszServerName, INTERNET_PORT nServerPort, - struct sockaddr *psa, socklen_t *sa_len) -{ - WCHAR *found; - char *name; - int len, sz; -#ifdef HAVE_GETADDRINFO - struct addrinfo *res, hints; +BOOL GetAddress(const WCHAR *name, INTERNET_PORT port, struct sockaddr *psa, int *sa_len, char *addr_str) +{ + ADDRINFOW *res, hints; + void *addr = NULL; int ret; -#else - struct hostent *phe; - struct sockaddr_in *sin = (struct sockaddr_in *)psa; -#endif - - TRACE("%s\n", debugstr_w(lpszServerName)); - - /* Validate server name first - * Check if there is something like - * pinger.macromedia.com:80 - * if yes, eliminate the :80.... - */ - found = strchrW(lpszServerName, ':'); - if (found) - len = found - lpszServerName; - else - len = strlenW(lpszServerName); - - sz = WideCharToMultiByte( CP_UNIXCP, 0, lpszServerName, len, NULL, 0, NULL, NULL ); - if (!(name = heap_alloc(sz + 1))) return FALSE; - WideCharToMultiByte( CP_UNIXCP, 0, lpszServerName, len, name, sz, NULL, NULL ); - name[sz] = 0; - -#ifdef HAVE_GETADDRINFO - memset( &hints, 0, sizeof(struct addrinfo) ); + + TRACE("%s\n", debugstr_w(name)); + + memset( &hints, 0, sizeof(hints) ); /* Prefer IPv4 to IPv6 addresses, since some servers do not listen on * their IPv6 addresses even though they have IPv6 addresses in the DNS. */ hints.ai_family = AF_INET; - ret = getaddrinfo( name, NULL, &hints, &res ); + ret = GetAddrInfoW(name, NULL, &hints, &res); if (ret != 0) { - TRACE("failed to get IPv4 address of %s (%s), retrying with IPv6\n", debugstr_w(lpszServerName), gai_strerror(ret)); + TRACE("failed to get IPv4 address of %s, retrying with IPv6\n", debugstr_w(name)); hints.ai_family = AF_INET6; - ret = getaddrinfo( name, NULL, &hints, &res ); - } - heap_free( name ); + ret = GetAddrInfoW(name, NULL, &hints, &res); + } if (ret != 0) { - TRACE("failed to get address of %s (%s)\n", debugstr_w(lpszServerName), gai_strerror(ret)); + TRACE("failed to get address of %s\n", debugstr_w(name)); return FALSE; } if (*sa_len < res->ai_addrlen) { WARN("address too small\n"); - freeaddrinfo( res ); + FreeAddrInfoW(res); return FALSE; } *sa_len = res->ai_addrlen; @@ -188,39 +151,18 @@ switch (res->ai_family) { case AF_INET: - ((struct sockaddr_in *)psa)->sin_port = htons(nServerPort); + addr = &((struct sockaddr_in *)psa)->sin_addr; + ((struct sockaddr_in *)psa)->sin_port = htons(port); break; case AF_INET6: - ((struct sockaddr_in6 *)psa)->sin6_port = htons(nServerPort); + addr = &((struct sockaddr_in6 *)psa)->sin6_addr; + ((struct sockaddr_in6 *)psa)->sin6_port = htons(port); break; } - freeaddrinfo( res ); -#else - EnterCriticalSection( &cs_gethostbyname ); - phe = gethostbyname(name); - heap_free( name ); - - if (NULL == phe) - { - TRACE("failed to get address of %s (%d)\n", debugstr_w(lpszServerName), h_errno); - LeaveCriticalSection( &cs_gethostbyname ); - return FALSE; - } - if (*sa_len < sizeof(struct sockaddr_in)) - { - WARN("address too small\n"); - LeaveCriticalSection( &cs_gethostbyname ); - return FALSE; - } - *sa_len = sizeof(struct sockaddr_in); - memset(sin,0,sizeof(struct sockaddr_in)); - memcpy((char *)&sin->sin_addr, phe->h_addr, phe->h_length); - sin->sin_family = phe->h_addrtype; - sin->sin_port = htons(nServerPort); - - LeaveCriticalSection( &cs_gethostbyname ); -#endif + if(addr_str) + inet_ntop(res->ai_family, addr, addr_str, INET6_ADDRSTRLEN); + FreeAddrInfoW(res); return TRUE; } 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] Wed Apr 22 08:30:31 2015 @@ -207,7 +207,7 @@ reactos/dll/win32/winemp3.acm # Synced to Wine-1.7.27 reactos/dll/win32/wing32 # Out of sync reactos/dll/win32/winhttp # Synced to WineStaging-1.7.37 -reactos/dll/win32/wininet # Synced to Wine-1.7.27 +reactos/dll/win32/wininet # Synced to WineStaging-1.7.37 reactos/dll/win32/winmm # Forked at Wine-20050628 reactos/dll/win32/winmm/midimap # Forked at Wine-20050628 reactos/dll/win32/winmm/wavemap # Forked at Wine-20050628
9 years, 8 months
1
0
0
0
[tfaber] 67342: [SHELL32] - Add colon after driver letter in Check Disk dialog title. Patch by Barrett Karish CORE-9583 #resolve
by tfaber@svn.reactos.org
Author: tfaber Date: Wed Apr 22 07:23:49 2015 New Revision: 67342 URL:
http://svn.reactos.org/svn/reactos?rev=67342&view=rev
Log: [SHELL32] - Add colon after driver letter in Check Disk dialog title. Patch by Barrett Karish CORE-9583 #resolve Modified: trunk/reactos/dll/win32/shell32/dialogs/drvdefext.cpp Modified: trunk/reactos/dll/win32/shell32/dialogs/drvdefext.cpp URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/dialogs/…
============================================================================== --- trunk/reactos/dll/win32/shell32/dialogs/drvdefext.cpp [iso-8859-1] (original) +++ trunk/reactos/dll/win32/shell32/dialogs/drvdefext.cpp [iso-8859-1] Wed Apr 22 07:23:49 2015 @@ -58,7 +58,7 @@ } } - StringCchPrintfW(pwszText + cchText, cchTextMax - cchText, L" (%c)", pwszDrive[0]); + StringCchPrintfW(pwszText + cchText, cchTextMax - cchText, L" (%c:)", pwszDrive[0]); } static VOID
9 years, 8 months
1
0
0
0
[aandrejevic] 67341: [FAST486] Fix compilation when FAST486_NO_PREFETCH is set.
by aandrejevic@svn.reactos.org
Author: aandrejevic Date: Wed Apr 22 03:11:03 2015 New Revision: 67341 URL:
http://svn.reactos.org/svn/reactos?rev=67341&view=rev
Log: [FAST486] Fix compilation when FAST486_NO_PREFETCH is set. Modified: trunk/reactos/lib/fast486/fast486.c Modified: trunk/reactos/lib/fast486/fast486.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/fast486/fast486.c?rev=…
============================================================================== --- trunk/reactos/lib/fast486/fast486.c [iso-8859-1] (original) +++ trunk/reactos/lib/fast486/fast486.c [iso-8859-1] Wed Apr 22 03:11:03 2015 @@ -340,7 +340,10 @@ /* This function is used when an instruction has been interrupted remotely */ State->PrefixFlags = 0; State->InstPtr.Long = State->SavedInstPtr.Long; + +#ifndef FAST486_NO_PREFETCH State->PrefetchValid = FALSE; +#endif } /* EOF */
9 years, 8 months
1
0
0
0
[aandrejevic] 67340: [NTVDM] Implement basic XMS functions.
by aandrejevic@svn.reactos.org
Author: aandrejevic Date: Wed Apr 22 03:10:11 2015 New Revision: 67340 URL:
http://svn.reactos.org/svn/reactos?rev=67340&view=rev
Log: [NTVDM] Implement basic XMS functions. Modified: trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/himem.c trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/himem.h Modified: trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/himem.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/dos/…
============================================================================== --- trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/himem.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/himem.c [iso-8859-1] Wed Apr 22 03:10:11 2015 @@ -17,6 +17,7 @@ #include "dos.h" #include "dos/dem.h" #include "device.h" +#include "himem.h" #define XMS_DEVICE_NAME "XMSXXXX0" #define XMS_BOP 0x52 @@ -36,8 +37,116 @@ }; static PDOS_DEVICE_NODE Node = NULL; +static XMS_HANDLE HandleTable[XMS_MAX_HANDLES]; +static WORD FreeBlocks = XMS_BLOCKS; +static RTL_BITMAP AllocBitmap; +static ULONG BitmapBuffer[(XMS_BLOCKS + 31) / 32]; /* PRIVATE FUNCTIONS **********************************************************/ + +static inline PXMS_HANDLE GetHandleRecord(WORD Handle) +{ + PXMS_HANDLE Entry = &HandleTable[Handle - 1]; + if (Handle == 0 || Handle >= XMS_MAX_HANDLES) return NULL; + + return Entry->Size ? Entry : NULL; +} + +static CHAR XmsAlloc(WORD Size, PWORD Handle) +{ + BYTE i; + PXMS_HANDLE HandleEntry; + + if (Size > FreeBlocks) return XMS_STATUS_OUT_OF_MEMORY; + + for (i = 0; i < XMS_MAX_HANDLES; i++) + { + HandleEntry = &HandleTable[i]; + if (HandleEntry->Handle == 0) + { + *Handle = i + 1; + break; + } + } + + if (i == XMS_MAX_HANDLES) return XMS_STATUS_OUT_OF_HANDLES; + + HandleEntry->Handle = i + 1; + HandleEntry->LockCount = 0; + HandleEntry->Size = Size; + FreeBlocks -= Size; + + return XMS_STATUS_SUCCESS; +} + +static CHAR XmsFree(WORD Handle) +{ + PXMS_HANDLE HandleEntry = GetHandleRecord(Handle); + if (HandleEntry == NULL) return XMS_STATUS_INVALID_HANDLE; + if (HandleEntry->LockCount) return XMS_STATUS_LOCKED; + + HandleEntry->Handle = 0; + FreeBlocks += HandleEntry->Size; + + return XMS_STATUS_SUCCESS; +} + +static CHAR XmsLock(WORD Handle, PDWORD Address) +{ + DWORD CurrentIndex = 0; + PXMS_HANDLE HandleEntry = GetHandleRecord(Handle); + + if (HandleEntry == NULL) return XMS_STATUS_INVALID_HANDLE; + if (HandleEntry->LockCount == 0xFF) return XMS_STATUS_LOCK_OVERFLOW; + + if (HandleEntry->LockCount) + { + /* Just increment the lock count */ + HandleEntry->LockCount++; + return XMS_STATUS_SUCCESS; + } + + while (CurrentIndex < XMS_BLOCKS) + { + ULONG RunStart; + ULONG RunSize = RtlFindNextForwardRunClear(&AllocBitmap, CurrentIndex, &RunStart); + if (RunSize == 0) break; + + if (RunSize >= HandleEntry->Size) + { + /* Lock it here */ + HandleEntry->LockCount++; + HandleEntry->Address = XMS_ADDRESS + RunStart * XMS_BLOCK_SIZE; + + RtlSetBits(&AllocBitmap, RunStart, RunSize); + *Address = HandleEntry->Address; + return XMS_STATUS_SUCCESS; + } + + /* Keep searching */ + CurrentIndex = RunStart + RunSize; + } + + /* Can't find any suitable range */ + return XMS_STATUS_CANNOT_LOCK; +} + +static CHAR XmsUnlock(WORD Handle) +{ + DWORD BlockNumber; + PXMS_HANDLE HandleEntry = GetHandleRecord(Handle); + + if (HandleEntry == NULL) return XMS_STATUS_INVALID_HANDLE; + if (!HandleEntry->LockCount) return XMS_STATUS_NOT_LOCKED; + + /* Decrement the lock count and exit early if it's still locked */ + if (--HandleEntry->LockCount) return XMS_STATUS_SUCCESS; + + BlockNumber = (HandleEntry->Address - XMS_ADDRESS) / XMS_BLOCK_SIZE; + RtlClearBits(&AllocBitmap, BlockNumber, HandleEntry->Size); + + return XMS_STATUS_SUCCESS; +} static VOID WINAPI XmsBopProcedure(LPWORD Stack) { @@ -52,9 +161,85 @@ break; } + /* Query Free Extended Memory */ + case 0x08: + { + setAX(FreeBlocks); + setDX(XMS_BLOCKS); + setBL(XMS_STATUS_SUCCESS); + + break; + } + + /* Allocate Extended Memory Block */ + case 0x09: + { + WORD Handle; + CHAR Result = XmsAlloc(getDX(), &Handle); + + if (Result >= 0) + { + setAX(1); + setDX(Handle); + } + else + { + setAX(0); + setBL(Result); + } + + break; + } + + /* Free Extended Memory Block */ + case 0x0A: + { + CHAR Result = XmsFree(getDX()); + + setAX(Result >= 0); + setBL(Result); + + break; + } + + /* Lock Extended Memory Block */ + case 0x0C: + { + DWORD Address; + CHAR Result = XmsLock(getDX(), &Address); + + if (Result >= 0) + { + setAX(1); + + /* Store the LINEAR address in DX:BX */ + setDX(HIWORD(Address)); + setBX(LOWORD(Address)); + } + else + { + setAX(0); + setBL(Result); + } + + break; + } + + /* Unlock Extended Memory Block */ + case 0x0D: + { + CHAR Result = XmsUnlock(getDX()); + + setAX(Result >= 0); + setBL(Result); + + break; + } + default: { DPRINT1("XMS command AH = 0x%02X NOT IMPLEMENTED\n", getAH()); + setBL(XMS_STATUS_NOT_IMPLEMENTED); } } } @@ -70,6 +255,10 @@ VOID XmsInitialize(VOID) { + RtlZeroMemory(HandleTable, sizeof(HandleTable)); + RtlZeroMemory(BitmapBuffer, sizeof(BitmapBuffer)); + RtlInitializeBitMap(&AllocBitmap, BitmapBuffer, XMS_BLOCKS); + Node = DosCreateDeviceEx(DOS_DEVATTR_IOCTL | DOS_DEVATTR_CHARACTER, XMS_DEVICE_NAME, sizeof(EntryProcedure)); Modified: trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/himem.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/dos/…
============================================================================== --- trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/himem.h [iso-8859-1] (original) +++ trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/himem.h [iso-8859-1] Wed Apr 22 03:10:11 2015 @@ -6,6 +6,32 @@ * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org> */ +/* DEFINITIONS ****************************************************************/ + +#define XMS_ADDRESS 0x110000 +#define XMS_BLOCKS 0x37C0 +#define XMS_BLOCK_SIZE 1024 +#define XMS_MAX_HANDLES 16 + +#define XMS_STATUS_SUCCESS 0x00 +#define XMS_STATUS_NOT_IMPLEMENTED 0x80 +#define XMS_STATUS_HMA_IN_USE 0x91 +#define XMS_STATUS_OUT_OF_MEMORY 0xA0 +#define XMS_STATUS_OUT_OF_HANDLES 0xA1 +#define XMS_STATUS_INVALID_HANDLE 0xA2 +#define XMS_STATUS_NOT_LOCKED 0xAA +#define XMS_STATUS_LOCKED 0xAB +#define XMS_STATUS_LOCK_OVERFLOW 0xAC +#define XMS_STATUS_CANNOT_LOCK 0xAD + +typedef struct _XMS_HANDLE +{ + BYTE Handle; + BYTE LockCount; + WORD Size; + DWORD Address; +} XMS_HANDLE, *PXMS_HANDLE; + /* FUNCTIONS ******************************************************************/ BOOLEAN XmsGetDriverEntry(PDWORD Pointer);
9 years, 8 months
1
0
0
0
[aandrejevic] 67339: [NTVDM] - Move the EMS code from the BIOS to the DOS driver where it belongs. - Expand the DOS device API with a new function, DosCreateDeviceEx, which will allow 32-bit DOS dr...
by aandrejevic@svn.reactos.org
Author: aandrejevic Date: Tue Apr 21 22:48:28 2015 New Revision: 67339 URL:
http://svn.reactos.org/svn/reactos?rev=67339&view=rev
Log: [NTVDM] - Move the EMS code from the BIOS to the DOS driver where it belongs. - Expand the DOS device API with a new function, DosCreateDeviceEx, which will allow 32-bit DOS driver to reserve private memory. - For each DOS device, create an entry in guest memory so that 16-bit code can call 32-bit DOS drivers directly. - Implement an XMS driver stub that uses the above. - Arch, that's not how the DOS driver strategy routine works, you need to give it the request in ES:BX which it will store somewhere, and then call the interrupt routine. Added: trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/emsdrv.h (with props) trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/himem.c (with props) trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/himem.h (with props) Removed: trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/ems.c trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/ems.h Modified: trunk/reactos/subsystems/mvdm/ntvdm/CMakeLists.txt trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/bios32.c trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/bios32.h trunk/reactos/subsystems/mvdm/ntvdm/dos/dem.c trunk/reactos/subsystems/mvdm/ntvdm/dos/dem.h trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/device.c trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/device.h trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.c trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.h trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/emsdrv.c Modified: trunk/reactos/subsystems/mvdm/ntvdm/CMakeLists.txt URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/CMak…
============================================================================== --- trunk/reactos/subsystems/mvdm/ntvdm/CMakeLists.txt [iso-8859-1] (original) +++ trunk/reactos/subsystems/mvdm/ntvdm/CMakeLists.txt [iso-8859-1] Tue Apr 21 22:48:28 2015 @@ -10,7 +10,6 @@ bios/bios32/kbdbios32.c bios/bios32/vidbios32.c bios/bios32/moubios32.c - bios/bios32/ems.c bios/bios.c bios/kbdbios.c bios/rom.c @@ -34,6 +33,7 @@ dos/dos32krnl/dos.c dos/dos32krnl/dosfiles.c dos/dos32krnl/emsdrv.c + dos/dos32krnl/himem.c dos/dos32krnl/memory.c dos/mouse32.c dos/dem.c Modified: trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/bios32.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/bios…
============================================================================== --- trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/bios32.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/bios32.c [iso-8859-1] Tue Apr 21 22:48:28 2015 @@ -26,8 +26,6 @@ #include "kbdbios32.h" #include "vidbios32.h" #include "moubios32.h" - -#include "ems.h" #include "io.h" #include "hardware/cmos.h" @@ -665,13 +663,6 @@ SearchAndInitRoms(&BiosContext); - /* Initialize EMS */ - if (!EmsInitialize(EMS_TOTAL_PAGES)) - { - DPRINT1("Could not initialize EMS. EMS will not be available.\n" - "Try reducing the number of EMS pages.\n"); - } - /* * End of the 32-bit POST portion. We then fall back into 16-bit where * the rest of the POST code is executed, typically calling INT 19h @@ -733,7 +724,6 @@ VOID Bios32Cleanup(VOID) { - EmsCleanup(); MouseBios32Cleanup(); VidBios32Cleanup(); KbdBios32Cleanup(); Modified: trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/bios32.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/bios…
============================================================================== --- trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/bios32.h [iso-8859-1] (original) +++ trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/bios32.h [iso-8859-1] Tue Apr 21 22:48:28 2015 @@ -21,9 +21,6 @@ // #define BIOS_TIME_INTERRUPT 0x1A // #define BIOS_SYS_TIMER_INTERRUPT 0x1C -/* 16 MB of EMS memory */ -#define EMS_TOTAL_PAGES 1024 - /* FUNCTIONS ******************************************************************/ BOOLEAN Bios32Initialize(VOID); Removed: trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/ems.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/bios…
============================================================================== --- trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/ems.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/ems.c (removed) @@ -1,422 +0,0 @@ -/* - * COPYRIGHT: GPLv2+ - See COPYING in the top level directory - * PROJECT: ReactOS Virtual DOS Machine - * FILE: ems.c - * PURPOSE: Expanded Memory Support - * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org> - */ - -/* INCLUDES *******************************************************************/ - -#define NDEBUG - -#include "ntvdm.h" -#include "emulator.h" -#include "bios/bios32/bios32p.h" -#include "ems.h" -#include "memory.h" - -/* PRIVATE VARIABLES **********************************************************/ - -static RTL_BITMAP AllocBitmap; -static PULONG BitmapBuffer = NULL; -static PEMS_PAGE PageTable = NULL; -static EMS_HANDLE HandleTable[EMS_MAX_HANDLES]; -static PVOID Mapping[EMS_PHYSICAL_PAGES] = { NULL }; -static ULONG EmsTotalPages = 0; -static PVOID EmsMemory = NULL; - -/* PRIVATE FUNCTIONS **********************************************************/ - -static USHORT EmsFree(USHORT Handle) -{ - PLIST_ENTRY Entry; - PEMS_HANDLE HandleEntry = &HandleTable[Handle]; - - if (Handle >= EMS_MAX_HANDLES || !HandleEntry->Allocated) - { - return EMS_STATUS_INVALID_HANDLE; - } - - for (Entry = HandleEntry->PageList.Flink; - Entry != &HandleEntry->PageList; - Entry = Entry->Flink) - { - PEMS_PAGE PageEntry = (PEMS_PAGE)CONTAINING_RECORD(Entry, EMS_PAGE, Entry); - ULONG PageNumber = ARRAY_INDEX(PageEntry, PageTable); - - /* Free the page */ - RtlClearBits(&AllocBitmap, PageNumber, 1); - } - - HandleEntry->Allocated = FALSE; - HandleEntry->PageCount = 0; - InitializeListHead(&HandleEntry->PageList); - - return EMS_STATUS_OK; -} - -static UCHAR EmsAlloc(USHORT NumPages, PUSHORT Handle) -{ - ULONG i, CurrentIndex = 0; - PEMS_HANDLE HandleEntry; - - if (NumPages == 0) return EMS_STATUS_ZERO_PAGES; - - for (i = 0; i < EMS_MAX_HANDLES; i++) - { - HandleEntry = &HandleTable[i]; - if (!HandleEntry->Allocated) - { - *Handle = i; - break; - } - } - - if (i == EMS_MAX_HANDLES) return EMS_STATUS_NO_MORE_HANDLES; - HandleEntry->Allocated = TRUE; - - while (HandleEntry->PageCount < NumPages) - { - ULONG RunStart; - ULONG RunSize = RtlFindNextForwardRunClear(&AllocBitmap, CurrentIndex, &RunStart); - - if (RunSize == 0) - { - /* Free what's been allocated already and report failure */ - EmsFree(*Handle); - return EMS_STATUS_INSUFFICIENT_PAGES; - } - else if ((HandleEntry->PageCount + RunSize) > NumPages) - { - /* We don't need the entire run */ - RunSize = NumPages - HandleEntry->PageCount; - } - - CurrentIndex = RunStart + RunSize; - HandleEntry->PageCount += RunSize; - RtlSetBits(&AllocBitmap, RunStart, RunSize); - - for (i = 0; i < RunSize; i++) - { - PageTable[RunStart + i].Handle = *Handle; - InsertTailList(&HandleEntry->PageList, &PageTable[RunStart + i].Entry); - } - } - - return EMS_STATUS_OK; -} - -static PEMS_PAGE GetLogicalPage(PEMS_HANDLE Handle, USHORT LogicalPage) -{ - PLIST_ENTRY Entry = Handle->PageList.Flink; - - while (LogicalPage) - { - if (Entry == &Handle->PageList) return NULL; - LogicalPage--; - Entry = Entry->Flink; - } - - return (PEMS_PAGE)CONTAINING_RECORD(Entry, EMS_PAGE, Entry); -} - -static USHORT EmsMap(USHORT Handle, UCHAR PhysicalPage, USHORT LogicalPage) -{ - PEMS_PAGE PageEntry; - PEMS_HANDLE HandleEntry = &HandleTable[Handle]; - - if (PhysicalPage >= EMS_PHYSICAL_PAGES) return EMS_STATUS_INV_PHYSICAL_PAGE; - if (LogicalPage == 0xFFFF) - { - /* Unmap */ - Mapping[PhysicalPage] = NULL; - return EMS_STATUS_OK; - } - - if (Handle >= EMS_MAX_HANDLES || !HandleEntry->Allocated) return EMS_STATUS_INVALID_HANDLE; - - PageEntry = GetLogicalPage(HandleEntry, LogicalPage); - if (!PageEntry) return EMS_STATUS_INV_LOGICAL_PAGE; - - Mapping[PhysicalPage] = (PVOID)((ULONG_PTR)EmsMemory - + ARRAY_INDEX(PageEntry, PageTable) * EMS_PAGE_SIZE); - return EMS_STATUS_OK; -} - -static VOID WINAPI EmsIntHandler(LPWORD Stack) -{ - switch (getAH()) - { - /* Get Manager Status */ - case 0x40: - { - setAH(EMS_STATUS_OK); - break; - } - - /* Get Page Frame Segment */ - case 0x41: - { - setAH(EMS_STATUS_OK); - setBX(EMS_SEGMENT); - break; - } - - /* Get Number Of Pages */ - case 0x42: - { - setAH(EMS_STATUS_OK); - setBX(RtlNumberOfClearBits(&AllocBitmap)); - setDX(EmsTotalPages); - break; - } - - /* Get Handle And Allocate Memory */ - case 0x43: - { - USHORT Handle; - UCHAR Status = EmsAlloc(getBX(), &Handle); - - setAH(Status); - if (Status == EMS_STATUS_OK) setDX(Handle); - break; - } - - /* Map Memory */ - case 0x44: - { - setAH(EmsMap(getDX(), getAL(), getBX())); - break; - } - - /* Release Handle And Memory */ - case 0x45: - { - setAH(EmsFree(getDX())); - break; - } - - /* Get EMM Version */ - case 0x46: - { - setAH(EMS_STATUS_OK); - setAL(EMS_VERSION_NUM); - break; - } - - /* Move/Exchange Memory */ - case 0x57: - { - PUCHAR SourcePtr, DestPtr; - PEMS_HANDLE HandleEntry; - PEMS_PAGE PageEntry; - BOOLEAN Exchange = getAL(); - PEMS_COPY_DATA Data = (PEMS_COPY_DATA)SEG_OFF_TO_PTR(getDS(), getSI()); - - if (Data->SourceType) - { - /* Expanded memory */ - HandleEntry = &HandleTable[Data->SourceHandle]; - - if (Data->SourceHandle >= EMS_MAX_HANDLES || !HandleEntry->Allocated) - { - setAL(EMS_STATUS_INVALID_HANDLE); - break; - } - - PageEntry = GetLogicalPage(HandleEntry, Data->SourceSegment); - - if (!PageEntry) - { - setAL(EMS_STATUS_INV_LOGICAL_PAGE); - break; - } - - SourcePtr = (PUCHAR)((ULONG_PTR)EmsMemory - + ARRAY_INDEX(PageEntry, PageTable) * EMS_PAGE_SIZE - + Data->SourceOffset); - } - else - { - /* Conventional memory */ - SourcePtr = (PUCHAR)SEG_OFF_TO_PTR(Data->SourceSegment, Data->SourceOffset); - } - - if (Data->DestType) - { - /* Expanded memory */ - HandleEntry = &HandleTable[Data->DestHandle]; - - if (Data->SourceHandle >= EMS_MAX_HANDLES || !HandleEntry->Allocated) - { - setAL(EMS_STATUS_INVALID_HANDLE); - break; - } - - PageEntry = GetLogicalPage(HandleEntry, Data->DestSegment); - - if (!PageEntry) - { - setAL(EMS_STATUS_INV_LOGICAL_PAGE); - break; - } - - DestPtr = (PUCHAR)((ULONG_PTR)EmsMemory - + ARRAY_INDEX(PageEntry, PageTable) * EMS_PAGE_SIZE - + Data->DestOffset); - } - else - { - /* Conventional memory */ - DestPtr = (PUCHAR)SEG_OFF_TO_PTR(Data->DestSegment, Data->DestOffset); - } - - if (Exchange) - { - ULONG i; - - /* Exchange */ - for (i = 0; i < Data->RegionLength; i++) - { - UCHAR Temp = DestPtr[i]; - DestPtr[i] = SourcePtr[i]; - SourcePtr[i] = Temp; - } - } - else - { - /* Move */ - RtlMoveMemory(DestPtr, SourcePtr, Data->RegionLength); - } - - setAL(EMS_STATUS_OK); - break; - } - - default: - { - DPRINT1("EMS function AH = %02X NOT IMPLEMENTED\n", getAH()); - setAH(EMS_STATUS_UNKNOWN_FUNCTION); - break; - } - } -} - -static VOID NTAPI EmsReadMemory(ULONG Address, PVOID Buffer, ULONG Size) -{ - ULONG i; - ULONG RelativeAddress = Address - TO_LINEAR(EMS_SEGMENT, 0); - ULONG FirstPage = RelativeAddress / EMS_PAGE_SIZE; - ULONG LastPage = (RelativeAddress + Size - 1) / EMS_PAGE_SIZE; - ULONG Offset, Length; - - for (i = FirstPage; i <= LastPage; i++) - { - Offset = (i == FirstPage) ? RelativeAddress & (EMS_PAGE_SIZE - 1) : 0; - Length = ((i == LastPage) - ? (RelativeAddress + Size - (LastPage << EMS_PAGE_BITS)) - : EMS_PAGE_SIZE) - Offset; - - if (Mapping[i]) RtlCopyMemory(Buffer, (PVOID)((ULONG_PTR)Mapping[i] + Offset), Length); - Buffer = (PVOID)((ULONG_PTR)Buffer + Length); - } -} - -static BOOLEAN NTAPI EmsWriteMemory(ULONG Address, PVOID Buffer, ULONG Size) -{ - ULONG i; - ULONG RelativeAddress = Address - TO_LINEAR(EMS_SEGMENT, 0); - ULONG FirstPage = RelativeAddress / EMS_PAGE_SIZE; - ULONG LastPage = (RelativeAddress + Size - 1) / EMS_PAGE_SIZE; - ULONG Offset, Length; - - for (i = FirstPage; i <= LastPage; i++) - { - Offset = (i == FirstPage) ? RelativeAddress & (EMS_PAGE_SIZE - 1) : 0; - Length = ((i == LastPage) - ? (RelativeAddress + Size - (LastPage << EMS_PAGE_BITS)) - : EMS_PAGE_SIZE) - Offset; - - if (Mapping[i]) RtlCopyMemory((PVOID)((ULONG_PTR)Mapping[i] + Offset), Buffer, Length); - Buffer = (PVOID)((ULONG_PTR)Buffer + Length); - } - - return TRUE; -} - -/* PUBLIC FUNCTIONS ***********************************************************/ - -BOOLEAN EmsInitialize(ULONG TotalPages) -{ - ULONG i; - - for (i = 0; i < EMS_MAX_HANDLES; i++) - { - HandleTable[i].Allocated = FALSE; - HandleTable[i].PageCount = 0; - InitializeListHead(&HandleTable[i].PageList); - } - - EmsTotalPages = TotalPages; - BitmapBuffer = RtlAllocateHeap(RtlGetProcessHeap(), - HEAP_ZERO_MEMORY, - ((TotalPages + 31) / 32) * sizeof(ULONG)); - if (BitmapBuffer == NULL) return FALSE; - - RtlInitializeBitMap(&AllocBitmap, BitmapBuffer, TotalPages); - - PageTable = (PEMS_PAGE)RtlAllocateHeap(RtlGetProcessHeap(), - HEAP_ZERO_MEMORY, - TotalPages * sizeof(EMS_PAGE)); - if (PageTable == NULL) - { - RtlFreeHeap(RtlGetProcessHeap(), 0, BitmapBuffer); - BitmapBuffer = NULL; - - return FALSE; - } - - EmsMemory = (PVOID)RtlAllocateHeap(RtlGetProcessHeap(), 0, TotalPages * EMS_PAGE_SIZE); - if (EmsMemory == NULL) - { - RtlFreeHeap(RtlGetProcessHeap(), 0, PageTable); - PageTable = NULL; - RtlFreeHeap(RtlGetProcessHeap(), 0, BitmapBuffer); - BitmapBuffer = NULL; - - return FALSE; - } - - MemInstallFastMemoryHook((PVOID)TO_LINEAR(EMS_SEGMENT, 0), - EMS_PHYSICAL_PAGES * EMS_PAGE_SIZE, - EmsReadMemory, - EmsWriteMemory); - - RegisterBiosInt32(EMS_INTERRUPT_NUM, EmsIntHandler); - return TRUE; -} - -VOID EmsCleanup(VOID) -{ - MemRemoveFastMemoryHook((PVOID)TO_LINEAR(EMS_SEGMENT, 0), - EMS_PHYSICAL_PAGES * EMS_PAGE_SIZE); - - if (EmsMemory) - { - RtlFreeHeap(RtlGetProcessHeap(), 0, EmsMemory); - EmsMemory = NULL; - } - - if (PageTable) - { - RtlFreeHeap(RtlGetProcessHeap(), 0, PageTable); - PageTable = NULL; - } - - if (BitmapBuffer) - { - RtlFreeHeap(RtlGetProcessHeap(), 0, BitmapBuffer); - BitmapBuffer = NULL; - } -} Removed: trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/ems.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/bios…
============================================================================== --- trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/ems.h [iso-8859-1] (original) +++ trunk/reactos/subsystems/mvdm/ntvdm/bios/bios32/ems.h (removed) @@ -1,69 +0,0 @@ -/* - * COPYRIGHT: GPLv2+ - See COPYING in the top level directory - * PROJECT: ReactOS Virtual DOS Machine - * FILE: ems.h - * PURPOSE: Expanded Memory Support - * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org> - */ - -#ifndef _EMS_H_ -#define _EMS_H_ - -/* DEFINITIONS ****************************************************************/ - -#define EMS_VERSION_NUM 0x04 -#define EMS_INTERRUPT_NUM 0x67 -#define EMS_SEGMENT 0xD000 -#define EMS_MAX_HANDLES 16 -#define EMS_PAGE_BITS 14 -#define EMS_PAGE_SIZE (1 << EMS_PAGE_BITS) -#define EMS_PHYSICAL_PAGES 4 - -#define EMS_STATUS_OK 0x00 -#define EMS_STATUS_INTERNAL_ERROR 0x80 -#define EMS_STATUS_INVALID_HANDLE 0x83 -#define EMS_STATUS_NO_MORE_HANDLES 0x85 -#define EMS_STATUS_INSUFFICIENT_PAGES 0x88 -#define EMS_STATUS_ZERO_PAGES 0x89 -#define EMS_STATUS_INV_LOGICAL_PAGE 0x8A -#define EMS_STATUS_INV_PHYSICAL_PAGE 0x8B -#define EMS_STATUS_UNKNOWN_FUNCTION 0x8F - -typedef struct _EMS_HANDLE -{ - BOOLEAN Allocated; - USHORT PageCount; - LIST_ENTRY PageList; -} EMS_HANDLE, *PEMS_HANDLE; - -typedef struct _EMS_PAGE -{ - LIST_ENTRY Entry; - USHORT Handle; -} EMS_PAGE, *PEMS_PAGE; - -#pragma pack(push, 1) - -typedef struct _EMS_COPY_DATA -{ - ULONG RegionLength; - UCHAR SourceType; - USHORT SourceHandle; - USHORT SourceOffset; - USHORT SourceSegment; - UCHAR DestType; - USHORT DestHandle; - USHORT DestOffset; - USHORT DestSegment; -} EMS_COPY_DATA, *PEMS_COPY_DATA; - -#pragma pack(pop) - -/* FUNCTIONS ******************************************************************/ - -BOOLEAN EmsInitialize(ULONG TotalPages); -VOID EmsCleanup(VOID); - -#endif // _EMS_H_ - -/* EOF */ Modified: trunk/reactos/subsystems/mvdm/ntvdm/dos/dem.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/dos/…
============================================================================== --- trunk/reactos/subsystems/mvdm/ntvdm/dos/dem.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/mvdm/ntvdm/dos/dem.c [iso-8859-1] Tue Apr 21 22:48:28 2015 @@ -19,6 +19,7 @@ #include "utils.h" #include "dem.h" +#include "dos/dos32krnl/device.h" #include "cpu/bop.h" #include "bios/bios.h" @@ -27,14 +28,6 @@ /* PRIVATE VARIABLES **********************************************************/ /**/extern BYTE CurrentDrive;/**/ - -/* DEFINES ********************************************************************/ - -/* BOP Identifiers */ -#define BOP_LOAD_DOS 0x2B // DOS Loading and Initializing BOP. In parameter (following bytes) we take a NULL-terminated string indicating the name of the DOS kernel file. -#define BOP_START_DOS 0x2C // DOS Starting BOP. In parameter (following bytes) we take a NULL-terminated string indicating the name of the DOS kernel file. -#define BOP_DOS 0x50 // DOS System BOP (for NTIO.SYS and NTDOS.SYS) -#define BOP_CMD 0x54 // DOS Command Interpreter BOP (for
COMMAND.COM
) /* PRIVATE FUNCTIONS **********************************************************/ @@ -86,6 +79,20 @@ EmulatorTerminate(); } + break; + } + + /* Call 32-bit Driver Strategy Routine */ + case BOP_DRV_STRATEGY: + { + DeviceStrategyBop(); + break; + } + + /* Call 32-bit Driver Interrupt Routine */ + case BOP_DRV_INTERRUPT: + { + DeviceInterruptBop(); break; } Modified: trunk/reactos/subsystems/mvdm/ntvdm/dos/dem.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/dos/…
============================================================================== --- trunk/reactos/subsystems/mvdm/ntvdm/dos/dem.h [iso-8859-1] (original) +++ trunk/reactos/subsystems/mvdm/ntvdm/dos/dem.h [iso-8859-1] Tue Apr 21 22:48:28 2015 @@ -16,6 +16,14 @@ /* INCLUDES *******************************************************************/ #include "dos32krnl/dos.h" + +/* DEFINES ********************************************************************/ + +/* BOP Identifiers */ +#define BOP_LOAD_DOS 0x2B // DOS Loading and Initializing BOP. In parameter (following bytes) we take a NULL-terminated string indicating the name of the DOS kernel file. +#define BOP_START_DOS 0x2C // DOS Starting BOP. In parameter (following bytes) we take a NULL-terminated string indicating the name of the DOS kernel file. +#define BOP_DOS 0x50 // DOS System BOP (for NTIO.SYS and NTDOS.SYS) +#define BOP_CMD 0x54 // DOS Command Interpreter BOP (for
COMMAND.COM
) /* FUNCTIONS ******************************************************************/ Modified: trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/device.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/dos/…
============================================================================== --- trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/device.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/device.c [iso-8859-1] Tue Apr 21 22:48:28 2015 @@ -12,6 +12,7 @@ #include "ntvdm.h" #include "emulator.h" +#include "cpu/bop.h" #include "device.h" #include "dos.h" @@ -20,27 +21,54 @@ /* PRIVATE VARIABLES **********************************************************/ +static const BYTE StrategyRoutine[] = { + LOBYTE(EMULATOR_BOP), + HIBYTE(EMULATOR_BOP), + BOP_DOS, + BOP_DRV_STRATEGY, + 0xCB // retf +}; + +static const BYTE InterruptRoutine[] = { + LOBYTE(EMULATOR_BOP), + HIBYTE(EMULATOR_BOP), + BOP_DOS, + BOP_DRV_INTERRUPT, + 0xCB // retf +}; + +C_ASSERT((sizeof(StrategyRoutine) + sizeof(InterruptRoutine)) == DEVICE_CODE_SIZE); + static LIST_ENTRY DeviceList = { &DeviceList, &DeviceList }; +static DWORD FirstDriver = 0xFFFFFFFF; +static PDOS_REQUEST_HEADER DeviceRequest; /* PRIVATE FUNCTIONS **********************************************************/ static VOID DosCallDriver(DWORD Driver, PDOS_REQUEST_HEADER Request) { PDOS_DRIVER DriverBlock = (PDOS_DRIVER)FAR_POINTER(Driver); - PDOS_REQUEST_HEADER RemoteRequest; - - /* Call the strategy routine first */ - Call16(HIWORD(Driver), DriverBlock->StrategyRoutine); - RemoteRequest = (PDOS_REQUEST_HEADER)SEG_OFF_TO_PTR(getES(), getBX()); + PDOS_REQUEST_HEADER RemoteRequest = FAR_POINTER(REQUEST_LOCATION); + WORD ES = getES(); + WORD BX = getBX(); + + /* Set ES:BX to the location of the request */ + setES(HIWORD(REQUEST_LOCATION)); + setBX(LOWORD(REQUEST_LOCATION)); /* Copy the request structure to ES:BX */ RtlMoveMemory(RemoteRequest, Request, Request->RequestLength); - /* Call the interrupt routine */ + /* Call the strategy routine, and then the interrupt routine */ + Call16(HIWORD(Driver), DriverBlock->StrategyRoutine); Call16(HIWORD(Driver), DriverBlock->InterruptRoutine); /* Get the request structure from ES:BX */ - RtlMoveMemory(Request, RemoteRequest, RemoteRequest->RequestLength); + RtlMoveMemory(Request, RemoteRequest, Request->RequestLength); + + /* Restore ES:BX */ + setES(ES); + setBX(BX); } static inline WORD NTAPI DosDriverReadInternal(PDOS_DEVICE_NODE DeviceNode, @@ -183,41 +211,65 @@ return Request.Header.Status; } -/* PUBLIC FUNCTIONS ***********************************************************/ - -PDOS_DEVICE_NODE DosGetDevice(LPCSTR DeviceName) -{ - PLIST_ENTRY i; - PDOS_DEVICE_NODE Node; - ANSI_STRING DeviceNameString; - - RtlInitAnsiString(&DeviceNameString, DeviceName); - - for (i = DeviceList.Flink; i != &DeviceList; i = i->Flink) - { - Node = CONTAINING_RECORD(i, DOS_DEVICE_NODE, Entry); - if (RtlEqualString(&Node->Name, &DeviceNameString, TRUE)) return Node; - } - - return NULL; -} - -PDOS_DEVICE_NODE DosCreateDevice(WORD Attributes, PCHAR DeviceName) +static VOID DosAddDriver(DWORD Driver) +{ + PDOS_DRIVER LastDriver; + + if (LOWORD(FirstDriver) == 0xFFFF) + { + /* This is the first driver */ + FirstDriver = Driver; + return; + } + + /* The list isn't empty, so find the last driver in it */ + LastDriver = (PDOS_DRIVER)FAR_POINTER(FirstDriver); + while (LOWORD(LastDriver->Link) != 0xFFFF) + { + LastDriver = (PDOS_DRIVER)FAR_POINTER(LastDriver->Link); + } + + /* Add the new driver to the list */ + LastDriver->Link = Driver; +} + +static VOID DosRemoveDriver(DWORD Driver) +{ + DWORD CurrentDriver = FirstDriver; + + if (FirstDriver == Driver) + { + /* Update the first driver */ + FirstDriver = ((PDOS_DRIVER)FAR_POINTER(FirstDriver))->Link; + return; + } + + while (LOWORD(CurrentDriver) != 0xFFFF) + { + PDOS_DRIVER DriverHeader = (PDOS_DRIVER)FAR_POINTER(CurrentDriver); + + if (DriverHeader->Link == Driver) + { + /* Remove it from the list */ + DriverHeader->Link = ((PDOS_DRIVER)FAR_POINTER(DriverHeader->Link))->Link; + return; + } + + CurrentDriver = DriverHeader->Link; + } +} + +static PDOS_DEVICE_NODE DosCreateDeviceNode(DWORD Driver) { BYTE i; - PDOS_DEVICE_NODE Node; - - /* Make sure this is a character device */ - if (!(Attributes & DOS_DEVATTR_CHARACTER)) - { - DPRINT1("ERROR: Block devices are not supported.\n"); - return FALSE; - } - - Node = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*Node)); + PDOS_DRIVER DriverHeader = (PDOS_DRIVER)FAR_POINTER(Driver); + PDOS_DEVICE_NODE Node = RtlAllocateHeap(RtlGetProcessHeap(), + HEAP_ZERO_MEMORY, + sizeof(*Node)); if (Node == NULL) return NULL; - Node->DeviceAttributes = Attributes; + Node->Driver = Driver; + Node->DeviceAttributes = DriverHeader->DeviceAttributes; /* Initialize the name string */ Node->Name.Buffer = Node->NameBuffer; @@ -225,8 +277,8 @@ for (i = 0; i < MAX_DEVICE_NAME; i++) { - if (DeviceName[i] == '\0' || DeviceName[i] == ' ') break; - Node->Name.Buffer[i] = DeviceName[i]; + if (DriverHeader->DeviceName[i] == ' ') break; + Node->Name.Buffer[i] = DriverHeader->DeviceName[i]; } Node->Name.Length = i; @@ -235,10 +287,266 @@ return Node; } +/* PUBLIC FUNCTIONS ***********************************************************/ + +PDOS_DEVICE_NODE DosGetDevice(LPCSTR DeviceName) +{ + PLIST_ENTRY i; + DWORD CurrentDriver = FirstDriver; + ANSI_STRING DeviceNameString; + + RtlInitAnsiString(&DeviceNameString, DeviceName); + + while (LOWORD(CurrentDriver) != 0xFFFF) + { + PDOS_DEVICE_NODE Node; + PDOS_DRIVER DriverHeader = (PDOS_DRIVER)FAR_POINTER(CurrentDriver); + + /* Get the device node for this driver */ + for (i = DeviceList.Flink; i != &DeviceList; i = i->Flink) + { + Node = CONTAINING_RECORD(i, DOS_DEVICE_NODE, Entry); + if (Node->Driver == CurrentDriver) break; + } + + if (i == &DeviceList) + { + DPRINT1("The driver at %04X:%04X has no associated device node. " + "Installing automagically.\n", + HIWORD(CurrentDriver), + LOWORD(CurrentDriver)); + + /* Create the device node */ + Node = DosCreateDeviceNode(CurrentDriver); + Node->IoctlReadRoutine = DosDriverDispatchIoctlRead; + Node->ReadRoutine = DosDriverDispatchRead; + Node->PeekRoutine = DosDriverDispatchPeek; + Node->InputStatusRoutine = DosDriverDispatchInputStatus; + Node->FlushInputRoutine = DosDriverDispatchFlushInput; + Node->IoctlWriteRoutine = DosDriverDispatchIoctlWrite; + Node->WriteRoutine = DosDriverDispatchWrite; + Node->OutputStatusRoutine = DosDriverDispatchOutputStatus; + Node->FlushOutputRoutine = DosDriverDispatchFlushOutput; + Node->OpenRoutine = DosDriverDispatchOpen; + Node->CloseRoutine = DosDriverDispatchClose; + Node->OutputUntilBusyRoutine = DosDriverDispatchOutputUntilBusy; + } + + if (RtlEqualString(&Node->Name, &DeviceNameString, TRUE)) return Node; + CurrentDriver = DriverHeader->Link; + } + + return NULL; +} + +PDOS_DEVICE_NODE DosCreateDeviceEx(WORD Attributes, PCHAR DeviceName, WORD PrivateDataSize) +{ + BYTE i; + WORD Segment; + PDOS_DRIVER DriverHeader; + PDOS_DEVICE_NODE Node; + + /* Make sure this is a character device */ + if (!(Attributes & DOS_DEVATTR_CHARACTER)) + { + DPRINT1("ERROR: Block devices are not supported.\n"); + return NULL; + } + + /* Create a driver header for this device */ + Segment = DosAllocateMemory(sizeof(DOS_DRIVER) + 10 + PrivateDataSize, NULL); + if (Segment == 0) return NULL; + + /* Fill the header with data */ + DriverHeader = SEG_OFF_TO_PTR(Segment, 0); + DriverHeader->Link = 0xFFFFFFFF; + DriverHeader->DeviceAttributes = Attributes; + DriverHeader->StrategyRoutine = sizeof(DOS_DRIVER); + DriverHeader->InterruptRoutine = sizeof(DOS_DRIVER) + sizeof(StrategyRoutine); + + RtlFillMemory(DriverHeader->DeviceName, MAX_DEVICE_NAME, ' '); + for (i = 0; i < MAX_DEVICE_NAME; i++) + { + if (DeviceName[i] == '\0' || DeviceName[i] == ' ') break; + DriverHeader->DeviceName[i] = DeviceName[i]; + } + + /* Write the routines */ + RtlMoveMemory(SEG_OFF_TO_PTR(Segment, DriverHeader->StrategyRoutine), + StrategyRoutine, + sizeof(StrategyRoutine)); + RtlMoveMemory(SEG_OFF_TO_PTR(Segment, DriverHeader->StrategyRoutine), + InterruptRoutine, + sizeof(InterruptRoutine)); + + /* Create the node */ + Node = DosCreateDeviceNode(MAKELONG(0, Segment)); + if (Node == NULL) + { + DosFreeMemory(Segment); + return NULL; + } + + DosAddDriver(Node->Driver); + return Node; +} + +PDOS_DEVICE_NODE DosCreateDevice(WORD Attributes, PCHAR DeviceName) +{ + /* Call the extended API */ + return DosCreateDeviceEx(Attributes, DeviceName, 0); +} + VOID DosDeleteDevice(PDOS_DEVICE_NODE DeviceNode) { + DosRemoveDriver(DeviceNode->Driver); + + ASSERT(LOWORD(DeviceNode->Driver) == 0); + DosFreeMemory(HIWORD(DeviceNode->Driver)); + RemoveEntryList(&DeviceNode->Entry); RtlFreeHeap(RtlGetProcessHeap(), 0, DeviceNode); +} + +VOID DeviceStrategyBop(VOID) +{ + /* Save ES:BX */ + DeviceRequest = (PDOS_REQUEST_HEADER)SEG_OFF_TO_PTR(getES(), getBX()); +} + +VOID DeviceInterruptBop(VOID) +{ + PLIST_ENTRY i; + PDOS_DEVICE_NODE Node; + DWORD DriverAddress = (getCS() << 4) + getIP() - sizeof(DOS_DRIVER) - 9; + + /* Get the device node for this driver */ + for (i = DeviceList.Flink; i != &DeviceList; i = i->Flink) + { + Node = CONTAINING_RECORD(i, DOS_DEVICE_NODE, Entry); + if (TO_LINEAR(HIWORD(Node->Driver), LOWORD(Node->Driver)) == DriverAddress) break; + } + + if (i == &DeviceList) + { + DPRINT1("Device interrupt BOP from an unknown location.\n"); + return; + } + + switch (DeviceRequest->CommandCode) + { + case DOS_DEVCMD_IOCTL_READ: + { + PDOS_IOCTL_RW_REQUEST Request = (PDOS_IOCTL_RW_REQUEST)DeviceRequest; + + DeviceRequest->Status = Node->IoctlReadRoutine( + Node, + Request->BufferPointer, + &Request->Length + ); + + break; + } + + case DOS_DEVCMD_READ: + { + PDOS_RW_REQUEST Request = (PDOS_RW_REQUEST)DeviceRequest; + + DeviceRequest->Status = Node->ReadRoutine( + Node, + Request->BufferPointer, + &Request->Length + ); + + break; + } + + case DOS_DEVCMD_PEEK: + { + PDOS_PEEK_REQUEST Request = (PDOS_PEEK_REQUEST)DeviceRequest; + DeviceRequest->Status = Node->PeekRoutine(Node, &Request->Character); + break; + } + + case DOS_DEVCMD_INSTAT: + { + DeviceRequest->Status = Node->InputStatusRoutine(Node); + break; + } + + case DOS_DEVCMD_FLUSH_INPUT: + { + DeviceRequest->Status = Node->FlushInputRoutine(Node); + break; + } + + case DOS_DEVCMD_IOCTL_WRITE: + { + PDOS_IOCTL_RW_REQUEST Request = (PDOS_IOCTL_RW_REQUEST)DeviceRequest; + + DeviceRequest->Status = Node->IoctlWriteRoutine( + Node, + Request->BufferPointer, + &Request->Length + ); + + break; + } + + case DOS_DEVCMD_WRITE: + { + PDOS_RW_REQUEST Request = (PDOS_RW_REQUEST)DeviceRequest; + + DeviceRequest->Status = Node->WriteRoutine(Node, + Request->BufferPointer, + &Request->Length + ); + + break; + } + + case DOS_DEVCMD_OUTSTAT: + { + DeviceRequest->Status = Node->OutputStatusRoutine(Node); + break; + } + + case DOS_DEVCMD_FLUSH_OUTPUT: + { + DeviceRequest->Status = Node->FlushOutputRoutine(Node); + break; + } + + case DOS_DEVCMD_OPEN: + { + DeviceRequest->Status = Node->OpenRoutine(Node); + break; + } + + case DOS_DEVCMD_CLOSE: + { + DeviceRequest->Status = Node->CloseRoutine(Node); + break; + } + + case DOS_DEVCMD_OUTPUT_BUSY: + { + PDOS_OUTPUT_BUSY_REQUEST Request = (PDOS_OUTPUT_BUSY_REQUEST)DeviceRequest; + + DeviceRequest->Status = Node->OutputUntilBusyRoutine( + Node, + Request->BufferPointer, + &Request->Length + ); + + break; + } + + default: + { + DPRINT1("Unknown device command code: %u\n", DeviceRequest->CommandCode); + } + } } DWORD DosLoadDriver(LPCSTR DriverFile) @@ -334,10 +642,8 @@ goto Next; } - /* Create the device */ - DeviceNode = DosCreateDevice(DriverHeader->DeviceAttributes, - DriverHeader->DeviceName); - DeviceNode->Driver = Driver; + /* Create the device node */ + DeviceNode = DosCreateDeviceNode(Driver); DeviceNode->IoctlReadRoutine = DosDriverDispatchIoctlRead; DeviceNode->ReadRoutine = DosDriverDispatchRead; DeviceNode->PeekRoutine = DosDriverDispatchPeek; @@ -351,6 +657,7 @@ DeviceNode->CloseRoutine = DosDriverDispatchClose; DeviceNode->OutputUntilBusyRoutine = DosDriverDispatchOutputUntilBusy; + DosAddDriver(Driver); DriversLoaded++; Next: Modified: trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/device.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/dos/…
============================================================================== --- trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/device.h [iso-8859-1] (original) +++ trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/device.h [iso-8859-1] Tue Apr 21 22:48:28 2015 @@ -12,6 +12,12 @@ /* DEFINITIONS ****************************************************************/ #define MAX_DEVICE_NAME 8 +#define REQUEST_LOCATION 0x00700100 // 0070:0100 +#define DEVICE_CODE_SIZE 10 +#define DEVICE_PRIVATE_AREA(Driver) (Driver + sizeof(DOS_DRIVER) + DEVICE_CODE_SIZE) + +#define BOP_DRV_STRATEGY 0x42 +#define BOP_DRV_INTERRUPT 0x43 #define DOS_DEVATTR_STDIN (1 << 0) #define DOS_DEVATTR_STDOUT (1 << 1) @@ -80,6 +86,7 @@ struct _DOS_DEVICE_NODE { LIST_ENTRY Entry; + DWORD Driver; WORD DeviceAttributes; ANSI_STRING Name; CHAR NameBuffer[MAX_DEVICE_NAME]; @@ -95,7 +102,6 @@ PDOS_DEVICE_GENERIC_ROUTINE OpenRoutine; PDOS_DEVICE_GENERIC_ROUTINE CloseRoutine; PDOS_DEVICE_IO_ROUTINE OutputUntilBusyRoutine; - DWORD Driver; }; #pragma pack(push, 1) @@ -190,7 +196,16 @@ PDOS_DEVICE_NODE DosGetDevice(LPCSTR DeviceName); PDOS_DEVICE_NODE DosCreateDevice(WORD Attributes, PCHAR DeviceName); +PDOS_DEVICE_NODE DosCreateDeviceEx +( + WORD Attributes, + PCHAR DeviceName, + WORD PrivateDataSize +); VOID DosDeleteDevice(PDOS_DEVICE_NODE DeviceNode); +VOID DeviceStrategyBop(VOID); +VOID DeviceInterruptBop(VOID); +DWORD DosLoadDriver(LPCSTR DriverFile); #endif // _DEVICE_H_ Modified: trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/dos/…
============================================================================== --- trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.c [iso-8859-1] Tue Apr 21 22:48:28 2015 @@ -20,11 +20,14 @@ #include "dos/dem.h" #include "device.h" #include "memory.h" +#include "himem.h" #include "bios/bios.h" #include "io.h" #include "hardware/ps2.h" + +#include "emsdrv.h" /* PRIVATE VARIABLES **********************************************************/ @@ -2934,9 +2937,39 @@ VOID WINAPI DosInt2Fh(LPWORD Stack) { - DPRINT1("DOS Internal System Function INT 0x2F, AH = %xh, AL = %xh NOT IMPLEMENTED!\n", - getAH(), getAL()); - Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF; + switch (getAH()) + { + /* Extended Memory Specification */ + case 0x43: + { + DWORD DriverEntry; + if (!XmsGetDriverEntry(&DriverEntry)) break; + + if (getAL() == 0x00) + { + /* The driver is loaded */ + setAL(0x80); + } + else if (getAL() == 0x10) + { + setES(HIWORD(DriverEntry)); + setBX(LOWORD(DriverEntry)); + } + else + { + DPRINT1("Unknown DOS XMS Function: INT 0x2F, AH = 43h, AL = %xh\n", getAL()); + } + + break; + } + + default: + { + DPRINT1("DOS Internal System Function INT 0x2F, AH = %xh, AL = %xh NOT IMPLEMENTED!\n", + getAH(), getAL()); + Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF; + } + } } BOOLEAN DosKRNLInitialize(VOID) @@ -3003,12 +3036,6 @@ DosSystemFileTable[i].Type = DOS_SFT_ENTRY_NONE; DosSystemFileTable[i].RefCount = 0; } - - /* Load the EMS driver */ - EmsDrvInitialize(); - - /* Load the CON driver */ - ConDrvInitialize(); #endif @@ -3024,6 +3051,19 @@ RegisterDosInt32(0x29, DosFastConOut ); // DOS 2+ Fast Console Output RegisterDosInt32(0x2F, DosInt2Fh ); + /* Load the EMS driver */ + if (!EmsDrvInitialize(EMS_TOTAL_PAGES)) + { + DPRINT1("Could not initialize EMS. EMS will not be available.\n" + "Try reducing the number of EMS pages.\n"); + } + + /* Load the XMS driver (HIMEM) */ + XmsInitialize(); + + /* Load the CON driver */ + ConDrvInitialize(); + return TRUE; } Modified: trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/dos/…
============================================================================== --- trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.h [iso-8859-1] (original) +++ trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.h [iso-8859-1] Tue Apr 21 22:48:28 2015 @@ -49,6 +49,9 @@ #define DOS_CHAR_ATTRIBUTE 0x07 #define DOS_PROGRAM_NAME_TAG 0x0001 #define DEFAULT_JFT_SIZE 20 + +/* 16 MB of EMS memory */ +#define EMS_TOTAL_PAGES 1024 typedef enum { @@ -198,8 +201,6 @@ VOID DosPrintCharacter(WORD FileHandle, CHAR Character); BOOLEAN DosBIOSInitialize(VOID); -VOID EmsDrvInitialize(VOID); -VOID EmsDrvCleanup(VOID); VOID ConDrvInitialize(VOID); VOID ConDrvCleanup(VOID); Modified: trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/emsdrv.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/dos/…
============================================================================== --- trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/emsdrv.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/emsdrv.c [iso-8859-1] Tue Apr 21 22:48:28 2015 @@ -11,18 +11,347 @@ #define NDEBUG #include "ntvdm.h" +#include "emulator.h" #include "dos.h" #include "dos/dem.h" #include "device.h" +#include "../../memory.h" +#include "emsdrv.h" + #define EMS_DEVICE_NAME "EMMXXXX0" /* PRIVATE VARIABLES **********************************************************/ static PDOS_DEVICE_NODE Node; +static RTL_BITMAP AllocBitmap; +static PULONG BitmapBuffer = NULL; +static PEMS_PAGE PageTable = NULL; +static EMS_HANDLE HandleTable[EMS_MAX_HANDLES]; +static PVOID Mapping[EMS_PHYSICAL_PAGES] = { NULL }; +static ULONG EmsTotalPages = 0; +static PVOID EmsMemory = NULL; /* PRIVATE FUNCTIONS **********************************************************/ + +static USHORT EmsFree(USHORT Handle) +{ + PLIST_ENTRY Entry; + PEMS_HANDLE HandleEntry = &HandleTable[Handle]; + + if (Handle >= EMS_MAX_HANDLES || !HandleEntry->Allocated) + { + return EMS_STATUS_INVALID_HANDLE; + } + + for (Entry = HandleEntry->PageList.Flink; + Entry != &HandleEntry->PageList; + Entry = Entry->Flink) + { + PEMS_PAGE PageEntry = (PEMS_PAGE)CONTAINING_RECORD(Entry, EMS_PAGE, Entry); + ULONG PageNumber = ARRAY_INDEX(PageEntry, PageTable); + + /* Free the page */ + RtlClearBits(&AllocBitmap, PageNumber, 1); + } + + HandleEntry->Allocated = FALSE; + HandleEntry->PageCount = 0; + InitializeListHead(&HandleEntry->PageList); + + return EMS_STATUS_OK; +} + +static UCHAR EmsAlloc(USHORT NumPages, PUSHORT Handle) +{ + ULONG i, CurrentIndex = 0; + PEMS_HANDLE HandleEntry; + + if (NumPages == 0) return EMS_STATUS_ZERO_PAGES; + + for (i = 0; i < EMS_MAX_HANDLES; i++) + { + HandleEntry = &HandleTable[i]; + if (!HandleEntry->Allocated) + { + *Handle = i; + break; + } + } + + if (i == EMS_MAX_HANDLES) return EMS_STATUS_NO_MORE_HANDLES; + HandleEntry->Allocated = TRUE; + + while (HandleEntry->PageCount < NumPages) + { + ULONG RunStart; + ULONG RunSize = RtlFindNextForwardRunClear(&AllocBitmap, CurrentIndex, &RunStart); + + if (RunSize == 0) + { + /* Free what's been allocated already and report failure */ + EmsFree(*Handle); + return EMS_STATUS_INSUFFICIENT_PAGES; + } + else if ((HandleEntry->PageCount + RunSize) > NumPages) + { + /* We don't need the entire run */ + RunSize = NumPages - HandleEntry->PageCount; + } + + CurrentIndex = RunStart + RunSize; + HandleEntry->PageCount += RunSize; + RtlSetBits(&AllocBitmap, RunStart, RunSize); + + for (i = 0; i < RunSize; i++) + { + PageTable[RunStart + i].Handle = *Handle; + InsertTailList(&HandleEntry->PageList, &PageTable[RunStart + i].Entry); + } + } + + return EMS_STATUS_OK; +} + +static PEMS_PAGE GetLogicalPage(PEMS_HANDLE Handle, USHORT LogicalPage) +{ + PLIST_ENTRY Entry = Handle->PageList.Flink; + + while (LogicalPage) + { + if (Entry == &Handle->PageList) return NULL; + LogicalPage--; + Entry = Entry->Flink; + } + + return (PEMS_PAGE)CONTAINING_RECORD(Entry, EMS_PAGE, Entry); +} + +static USHORT EmsMap(USHORT Handle, UCHAR PhysicalPage, USHORT LogicalPage) +{ + PEMS_PAGE PageEntry; + PEMS_HANDLE HandleEntry = &HandleTable[Handle]; + + if (PhysicalPage >= EMS_PHYSICAL_PAGES) return EMS_STATUS_INV_PHYSICAL_PAGE; + if (LogicalPage == 0xFFFF) + { + /* Unmap */ + Mapping[PhysicalPage] = NULL; + return EMS_STATUS_OK; + } + + if (Handle >= EMS_MAX_HANDLES || !HandleEntry->Allocated) return EMS_STATUS_INVALID_HANDLE; + + PageEntry = GetLogicalPage(HandleEntry, LogicalPage); + if (!PageEntry) return EMS_STATUS_INV_LOGICAL_PAGE; + + Mapping[PhysicalPage] = (PVOID)((ULONG_PTR)EmsMemory + + ARRAY_INDEX(PageEntry, PageTable) * EMS_PAGE_SIZE); + return EMS_STATUS_OK; +} + +static VOID WINAPI EmsIntHandler(LPWORD Stack) +{ + switch (getAH()) + { + /* Get Manager Status */ + case 0x40: + { + setAH(EMS_STATUS_OK); + break; + } + + /* Get Page Frame Segment */ + case 0x41: + { + setAH(EMS_STATUS_OK); + setBX(EMS_SEGMENT); + break; + } + + /* Get Number Of Pages */ + case 0x42: + { + setAH(EMS_STATUS_OK); + setBX(RtlNumberOfClearBits(&AllocBitmap)); + setDX(EmsTotalPages); + break; + } + + /* Get Handle And Allocate Memory */ + case 0x43: + { + USHORT Handle; + UCHAR Status = EmsAlloc(getBX(), &Handle); + + setAH(Status); + if (Status == EMS_STATUS_OK) setDX(Handle); + break; + } + + /* Map Memory */ + case 0x44: + { + setAH(EmsMap(getDX(), getAL(), getBX())); + break; + } + + /* Release Handle And Memory */ + case 0x45: + { + setAH(EmsFree(getDX())); + break; + } + + /* Get EMM Version */ + case 0x46: + { + setAH(EMS_STATUS_OK); + setAL(EMS_VERSION_NUM); + break; + } + + /* Move/Exchange Memory */ + case 0x57: + { + PUCHAR SourcePtr, DestPtr; + PEMS_HANDLE HandleEntry; + PEMS_PAGE PageEntry; + BOOLEAN Exchange = getAL(); + PEMS_COPY_DATA Data = (PEMS_COPY_DATA)SEG_OFF_TO_PTR(getDS(), getSI()); + + if (Data->SourceType) + { + /* Expanded memory */ + HandleEntry = &HandleTable[Data->SourceHandle]; + + if (Data->SourceHandle >= EMS_MAX_HANDLES || !HandleEntry->Allocated) + { + setAL(EMS_STATUS_INVALID_HANDLE); + break; + } + + PageEntry = GetLogicalPage(HandleEntry, Data->SourceSegment); + + if (!PageEntry) + { + setAL(EMS_STATUS_INV_LOGICAL_PAGE); + break; + } + + SourcePtr = (PUCHAR)((ULONG_PTR)EmsMemory + + ARRAY_INDEX(PageEntry, PageTable) * EMS_PAGE_SIZE + + Data->SourceOffset); + } + else + { + /* Conventional memory */ + SourcePtr = (PUCHAR)SEG_OFF_TO_PTR(Data->SourceSegment, Data->SourceOffset); + } + + if (Data->DestType) + { + /* Expanded memory */ + HandleEntry = &HandleTable[Data->DestHandle]; + + if (Data->SourceHandle >= EMS_MAX_HANDLES || !HandleEntry->Allocated) + { + setAL(EMS_STATUS_INVALID_HANDLE); + break; + } + + PageEntry = GetLogicalPage(HandleEntry, Data->DestSegment); + + if (!PageEntry) + { + setAL(EMS_STATUS_INV_LOGICAL_PAGE); + break; + } + + DestPtr = (PUCHAR)((ULONG_PTR)EmsMemory + + ARRAY_INDEX(PageEntry, PageTable) * EMS_PAGE_SIZE + + Data->DestOffset); + } + else + { + /* Conventional memory */ + DestPtr = (PUCHAR)SEG_OFF_TO_PTR(Data->DestSegment, Data->DestOffset); + } + + if (Exchange) + { + ULONG i; + + /* Exchange */ + for (i = 0; i < Data->RegionLength; i++) + { + UCHAR Temp = DestPtr[i]; + DestPtr[i] = SourcePtr[i]; + SourcePtr[i] = Temp; + } + } + else + { + /* Move */ + RtlMoveMemory(DestPtr, SourcePtr, Data->RegionLength); + } + + setAL(EMS_STATUS_OK); + break; + } + + default: + { + DPRINT1("EMS function AH = %02X NOT IMPLEMENTED\n", getAH()); + setAH(EMS_STATUS_UNKNOWN_FUNCTION); + break; + } + } +} + +static VOID NTAPI EmsReadMemory(ULONG Address, PVOID Buffer, ULONG Size) +{ + ULONG i; + ULONG RelativeAddress = Address - TO_LINEAR(EMS_SEGMENT, 0); + ULONG FirstPage = RelativeAddress / EMS_PAGE_SIZE; + ULONG LastPage = (RelativeAddress + Size - 1) / EMS_PAGE_SIZE; + ULONG Offset, Length; + + for (i = FirstPage; i <= LastPage; i++) + { + Offset = (i == FirstPage) ? RelativeAddress & (EMS_PAGE_SIZE - 1) : 0; + Length = ((i == LastPage) + ? (RelativeAddress + Size - (LastPage << EMS_PAGE_BITS)) + : EMS_PAGE_SIZE) - Offset; + + if (Mapping[i]) RtlCopyMemory(Buffer, (PVOID)((ULONG_PTR)Mapping[i] + Offset), Length); + Buffer = (PVOID)((ULONG_PTR)Buffer + Length); + } +} + +static BOOLEAN NTAPI EmsWriteMemory(ULONG Address, PVOID Buffer, ULONG Size) +{ + ULONG i; + ULONG RelativeAddress = Address - TO_LINEAR(EMS_SEGMENT, 0); + ULONG FirstPage = RelativeAddress / EMS_PAGE_SIZE; + ULONG LastPage = (RelativeAddress + Size - 1) / EMS_PAGE_SIZE; + ULONG Offset, Length; + + for (i = FirstPage; i <= LastPage; i++) + { + Offset = (i == FirstPage) ? RelativeAddress & (EMS_PAGE_SIZE - 1) : 0; + Length = ((i == LastPage) + ? (RelativeAddress + Size - (LastPage << EMS_PAGE_BITS)) + : EMS_PAGE_SIZE) - Offset; + + if (Mapping[i]) RtlCopyMemory((PVOID)((ULONG_PTR)Mapping[i] + Offset), Buffer, Length); + Buffer = (PVOID)((ULONG_PTR)Buffer + Length); + } + + return TRUE; +} + WORD NTAPI EmsDrvDispatchIoctlRead(PDOS_DEVICE_NODE Device, DWORD Buffer, PWORD Length) { @@ -34,17 +363,85 @@ /* PUBLIC FUNCTIONS ***********************************************************/ -VOID EmsDrvInitialize(VOID) -{ +BOOLEAN EmsDrvInitialize(ULONG TotalPages) +{ + ULONG i; + + for (i = 0; i < EMS_MAX_HANDLES; i++) + { + HandleTable[i].Allocated = FALSE; + HandleTable[i].PageCount = 0; + InitializeListHead(&HandleTable[i].PageList); + } + + EmsTotalPages = TotalPages; + BitmapBuffer = RtlAllocateHeap(RtlGetProcessHeap(), + HEAP_ZERO_MEMORY, + ((TotalPages + 31) / 32) * sizeof(ULONG)); + if (BitmapBuffer == NULL) return FALSE; + + RtlInitializeBitMap(&AllocBitmap, BitmapBuffer, TotalPages); + + PageTable = (PEMS_PAGE)RtlAllocateHeap(RtlGetProcessHeap(), + HEAP_ZERO_MEMORY, + TotalPages * sizeof(EMS_PAGE)); + if (PageTable == NULL) + { + RtlFreeHeap(RtlGetProcessHeap(), 0, BitmapBuffer); + BitmapBuffer = NULL; + + return FALSE; + } + + EmsMemory = (PVOID)RtlAllocateHeap(RtlGetProcessHeap(), 0, TotalPages * EMS_PAGE_SIZE); + if (EmsMemory == NULL) + { + RtlFreeHeap(RtlGetProcessHeap(), 0, PageTable); + PageTable = NULL; + RtlFreeHeap(RtlGetProcessHeap(), 0, BitmapBuffer); + BitmapBuffer = NULL; + + return FALSE; + } + + MemInstallFastMemoryHook((PVOID)TO_LINEAR(EMS_SEGMENT, 0), + EMS_PHYSICAL_PAGES * EMS_PAGE_SIZE, + EmsReadMemory, + EmsWriteMemory); + + RegisterDosInt32(EMS_INTERRUPT_NUM, EmsIntHandler); + /* Create the device */ - Node = DosCreateDevice(DOS_DEVATTR_IOCTL - | DOS_DEVATTR_CHARACTER, + Node = DosCreateDevice(DOS_DEVATTR_IOCTL | DOS_DEVATTR_CHARACTER, EMS_DEVICE_NAME); Node->IoctlReadRoutine = EmsDrvDispatchIoctlRead; + + return TRUE; } VOID EmsDrvCleanup(VOID) { /* Delete the device */ DosDeleteDevice(Node); -} + + MemRemoveFastMemoryHook((PVOID)TO_LINEAR(EMS_SEGMENT, 0), + EMS_PHYSICAL_PAGES * EMS_PAGE_SIZE); + + if (EmsMemory) + { + RtlFreeHeap(RtlGetProcessHeap(), 0, EmsMemory); + EmsMemory = NULL; + } + + if (PageTable) + { + RtlFreeHeap(RtlGetProcessHeap(), 0, PageTable); + PageTable = NULL; + } + + if (BitmapBuffer) + { + RtlFreeHeap(RtlGetProcessHeap(), 0, BitmapBuffer); + BitmapBuffer = NULL; + } +} Added: trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/emsdrv.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/dos/…
============================================================================== --- trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/emsdrv.h (added) +++ trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/emsdrv.h [iso-8859-1] Tue Apr 21 22:48:28 2015 @@ -0,0 +1,67 @@ +/* + * COPYRIGHT: GPLv2+ - See COPYING in the top level directory + * PROJECT: ReactOS Virtual DOS Machine + * FILE: emsdrv.h + * PURPOSE: DOS EMS Driver + * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org> + */ + +#ifndef _EMSDRV_H_ +#define _EMSDRV_H_ + +/* DEFINITIONS ****************************************************************/ + +#define EMS_VERSION_NUM 0x04 +#define EMS_INTERRUPT_NUM 0x67 +#define EMS_SEGMENT 0xD000 +#define EMS_MAX_HANDLES 16 +#define EMS_PAGE_BITS 14 +#define EMS_PAGE_SIZE (1 << EMS_PAGE_BITS) +#define EMS_PHYSICAL_PAGES 4 + +#define EMS_STATUS_OK 0x00 +#define EMS_STATUS_INTERNAL_ERROR 0x80 +#define EMS_STATUS_INVALID_HANDLE 0x83 +#define EMS_STATUS_NO_MORE_HANDLES 0x85 +#define EMS_STATUS_INSUFFICIENT_PAGES 0x88 +#define EMS_STATUS_ZERO_PAGES 0x89 +#define EMS_STATUS_INV_LOGICAL_PAGE 0x8A +#define EMS_STATUS_INV_PHYSICAL_PAGE 0x8B +#define EMS_STATUS_UNKNOWN_FUNCTION 0x8F + +typedef struct _EMS_HANDLE +{ + BOOLEAN Allocated; + USHORT PageCount; + LIST_ENTRY PageList; +} EMS_HANDLE, *PEMS_HANDLE; + +typedef struct _EMS_PAGE +{ + LIST_ENTRY Entry; + USHORT Handle; +} EMS_PAGE, *PEMS_PAGE; + +#pragma pack(push, 1) + +typedef struct _EMS_COPY_DATA +{ + ULONG RegionLength; + UCHAR SourceType; + USHORT SourceHandle; + USHORT SourceOffset; + USHORT SourceSegment; + UCHAR DestType; + USHORT DestHandle; + USHORT DestOffset; + USHORT DestSegment; +} EMS_COPY_DATA, *PEMS_COPY_DATA; + +#pragma pack(pop) + +#endif + +/* FUNCTIONS ******************************************************************/ + +BOOLEAN EmsDrvInitialize(ULONG TotalPages); +VOID EmsDrvCleanup(VOID); Propchange: trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/emsdrv.h ------------------------------------------------------------------------------ svn:eol-style = native Added: trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/himem.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/dos/…
============================================================================== --- trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/himem.c (added) +++ trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/himem.c [iso-8859-1] Tue Apr 21 22:48:28 2015 @@ -0,0 +1,89 @@ +/* + * COPYRIGHT: GPLv2+ - See COPYING in the top level directory + * PROJECT: ReactOS Virtual DOS Machine + * FILE: himem.c + * PURPOSE: DOS XMS Driver + * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org> + */ + +/* INCLUDES *******************************************************************/ + +#define NDEBUG + +#include "ntvdm.h" +#include "emulator.h" +#include "cpu/bop.h" + +#include "dos.h" +#include "dos/dem.h" +#include "device.h" + +#define XMS_DEVICE_NAME "XMSXXXX0" +#define XMS_BOP 0x52 + +/* PRIVATE VARIABLES **********************************************************/ + +static const BYTE EntryProcedure[] = { + 0xEB, // jmp short +0x03 + 0x03, + 0x90, // nop + 0x90, // nop + 0x90, // nop + LOBYTE(EMULATOR_BOP), + HIBYTE(EMULATOR_BOP), + XMS_BOP, + 0xCB // retf +}; + +static PDOS_DEVICE_NODE Node = NULL; + +/* PRIVATE FUNCTIONS **********************************************************/ + +static VOID WINAPI XmsBopProcedure(LPWORD Stack) +{ + switch (getAH()) + { + /* Get XMS Version */ + case 0x00: + { + setAX(0x0300); /* XMS version 3.0 */ + setDX(0x0001); /* HMA present */ + + break; + } + + default: + { + DPRINT1("XMS command AH = 0x%02X NOT IMPLEMENTED\n", getAH()); + } + } +} + +/* PUBLIC FUNCTIONS ***********************************************************/ + +BOOLEAN XmsGetDriverEntry(PDWORD Pointer) +{ + if (Node == NULL) return FALSE; + *Pointer = DEVICE_PRIVATE_AREA(Node->Driver); + return TRUE; +} + +VOID XmsInitialize(VOID) +{ + Node = DosCreateDeviceEx(DOS_DEVATTR_IOCTL | DOS_DEVATTR_CHARACTER, + XMS_DEVICE_NAME, + sizeof(EntryProcedure)); + + RegisterBop(XMS_BOP, XmsBopProcedure); + + /* Copy the entry routine to the device private area */ + RtlMoveMemory(FAR_POINTER(DEVICE_PRIVATE_AREA(Node->Driver)), + EntryProcedure, + sizeof(EntryProcedure)); +} + +VOID XmsCleanup(VOID) +{ + RegisterBop(XMS_BOP, NULL); + DosDeleteDevice(Node); +} Propchange: trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/himem.c ------------------------------------------------------------------------------ svn:eol-style = native Added: trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/himem.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/dos/…
============================================================================== --- trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/himem.h (added) +++ trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/himem.h [iso-8859-1] Tue Apr 21 22:48:28 2015 @@ -0,0 +1,13 @@ +/* + * COPYRIGHT: GPLv2+ - See COPYING in the top level directory + * PROJECT: ReactOS Virtual DOS Machine + * FILE: himem.h + * PURPOSE: DOS XMS Driver + * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org> + */ + +/* FUNCTIONS ******************************************************************/ + +BOOLEAN XmsGetDriverEntry(PDWORD Pointer); +VOID XmsInitialize(VOID); +VOID XmsCleanup(VOID); Propchange: trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/himem.h ------------------------------------------------------------------------------ svn:eol-style = native
9 years, 8 months
1
0
0
0
[pschweitzer] 67338: [NDK] Add definition for FILE_TRACKING_INFORMATION [XDK] Add definition for FILE_TRACKING_INFORMATION
by pschweitzer@svn.reactos.org
Author: pschweitzer Date: Tue Apr 21 19:47:49 2015 New Revision: 67338 URL:
http://svn.reactos.org/svn/reactos?rev=67338&view=rev
Log: [NDK] Add definition for FILE_TRACKING_INFORMATION [XDK] Add definition for FILE_TRACKING_INFORMATION Modified: trunk/reactos/include/ndk/iotypes.h trunk/reactos/include/xdk/iotypes.h Modified: trunk/reactos/include/ndk/iotypes.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/ndk/iotypes.h?rev=…
============================================================================== --- trunk/reactos/include/ndk/iotypes.h [iso-8859-1] (original) +++ trunk/reactos/include/ndk/iotypes.h [iso-8859-1] Tue Apr 21 19:47:49 2015 @@ -620,6 +620,13 @@ ULONG FileAttributes; ULONG ReparseTag; } FILE_ATTRIBUTE_TAG_INFORMATION, *PFILE_ATTRIBUTE_TAG_INFORMATION; + +typedef struct _FILE_TRACKING_INFORMATION +{ + HANDLE DestinationFile; + ULONG ObjectInformationLength; + CHAR ObjectInformation[1]; +} FILE_TRACKING_INFORMATION, *PFILE_TRACKING_INFORMATION; // // File System Information structures for NtQueryInformationFile Modified: trunk/reactos/include/xdk/iotypes.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/xdk/iotypes.h?rev=…
============================================================================== --- trunk/reactos/include/xdk/iotypes.h [iso-8859-1] (original) +++ trunk/reactos/include/xdk/iotypes.h [iso-8859-1] Tue Apr 21 19:47:49 2015 @@ -4972,6 +4972,12 @@ ULONG ReparseTag; } FILE_ATTRIBUTE_TAG_INFORMATION, *PFILE_ATTRIBUTE_TAG_INFORMATION; +typedef struct _FILE_TRACKING_INFORMATION { + HANDLE DestinationFile; + ULONG ObjectInformationLength; + CHAR ObjectInformation[1]; +} FILE_TRACKING_INFORMATION, *PFILE_TRACKING_INFORMATION; + typedef struct _FILE_DISPOSITION_INFORMATION { BOOLEAN DeleteFile; } FILE_DISPOSITION_INFORMATION, *PFILE_DISPOSITION_INFORMATION;
9 years, 8 months
1
0
0
0
[pschweitzer] 67337: [KERNEL32] Move BasepOpenFileForMove() in the Basep functions block. No code change!
by pschweitzer@svn.reactos.org
Author: pschweitzer Date: Tue Apr 21 19:44:16 2015 New Revision: 67337 URL:
http://svn.reactos.org/svn/reactos?rev=67337&view=rev
Log: [KERNEL32] Move BasepOpenFileForMove() in the Basep functions block. No code change! Modified: trunk/reactos/dll/win32/kernel32/client/file/move.c Modified: trunk/reactos/dll/win32/kernel32/client/file/move.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/client/…
============================================================================== --- trunk/reactos/dll/win32/kernel32/client/file/move.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/kernel32/client/file/move.c [iso-8859-1] Tue Apr 21 19:44:16 2015 @@ -188,6 +188,132 @@ IN PUNICODE_STRING NewPath) { return STATUS_NOT_IMPLEMENTED; +} + + +/* + * @implemented + */ +NTSTATUS +WINAPI +BasepOpenFileForMove(IN LPCWSTR File, + OUT PUNICODE_STRING RelativeNtName, + OUT LPWSTR * NtName, + OUT PHANDLE FileHandle, + OUT POBJECT_ATTRIBUTES ObjectAttributes, + IN ACCESS_MASK DesiredAccess, + IN ULONG ShareAccess, + IN ULONG OpenOptions) +{ + RTL_RELATIVE_NAME_U RelativeName; + NTSTATUS Status; + IO_STATUS_BLOCK IoStatusBlock; + FILE_ATTRIBUTE_TAG_INFORMATION TagInfo; + ULONG IntShareAccess; + BOOLEAN HasRelative = FALSE; + + _SEH2_TRY + { + /* Zero output */ + RelativeNtName->Length = + RelativeNtName->MaximumLength = 0; + RelativeNtName->Buffer = NULL; + *NtName = NULL; + + if (!RtlDosPathNameToRelativeNtPathName_U(File, RelativeNtName, NULL, &RelativeName)) + { + Status = STATUS_OBJECT_PATH_NOT_FOUND; + _SEH2_LEAVE; + } + + HasRelative = TRUE; + *NtName = RelativeNtName->Buffer; + + if (RelativeName.RelativeName.Length) + { + RelativeNtName->Length = RelativeName.RelativeName.Length; + RelativeNtName->MaximumLength = RelativeName.RelativeName.MaximumLength; + RelativeNtName->Buffer = RelativeName.RelativeName.Buffer; + } + else + { + RelativeName.ContainingDirectory = 0; + } + + InitializeObjectAttributes(ObjectAttributes, + RelativeNtName, + OBJ_CASE_INSENSITIVE, + RelativeName.ContainingDirectory, + NULL); + /* Force certain flags here, given ops we'll do */ + IntShareAccess = ShareAccess | FILE_SHARE_READ | FILE_SHARE_WRITE; + OpenOptions |= FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT; + + /* We'll try to read reparse tag */ + Status = NtOpenFile(FileHandle, + DesiredAccess | FILE_READ_ATTRIBUTES | SYNCHRONIZE, + ObjectAttributes, + &IoStatusBlock, + IntShareAccess, + OpenOptions | FILE_OPEN_REPARSE_POINT); + if (NT_SUCCESS(Status)) + { + /* Attempt the read */ + Status = NtQueryInformationFile(*FileHandle, + &IoStatusBlock, + &TagInfo, + sizeof(FILE_ATTRIBUTE_TAG_INFORMATION), + FileAttributeTagInformation); + + /* Return if failure with a status that wouldn't mean the FSD cannot support reparse points */ + if (!NT_SUCCESS(Status) && + (Status != STATUS_NOT_IMPLEMENTED && Status != STATUS_INVALID_PARAMETER)) + { + _SEH2_LEAVE; + } + + if (NT_SUCCESS(Status)) + { + /* This cannot happen on mount points */ + if (TagInfo.FileAttributes & FILE_ATTRIBUTE_DEVICE || + TagInfo.ReparseTag == IO_REPARSE_TAG_MOUNT_POINT) + { + _SEH2_LEAVE; + } + } + + NtClose(*FileHandle); + *FileHandle = INVALID_HANDLE_VALUE; + + IntShareAccess = ShareAccess | FILE_SHARE_READ | FILE_SHARE_DELETE; + } + else if (Status == STATUS_INVALID_PARAMETER) + { + IntShareAccess = ShareAccess | FILE_SHARE_READ | FILE_SHARE_WRITE; + } + else + { + _SEH2_LEAVE; + } + + /* Reattempt to open normally, following reparse point if needed */ + Status = NtOpenFile(FileHandle, + DesiredAccess | SYNCHRONIZE, + ObjectAttributes, + &IoStatusBlock, + IntShareAccess, + OpenOptions); + } + _SEH2_FINALLY + { + if (HasRelative) + { + RtlReleaseRelativeName(&RelativeName); + } + } + _SEH2_END; + + return Status; } @@ -885,130 +1011,6 @@ return Ret; } -/* - * @implemented - */ -NTSTATUS -WINAPI -BasepOpenFileForMove(IN LPCWSTR File, - OUT PUNICODE_STRING RelativeNtName, - OUT LPWSTR * NtName, - OUT PHANDLE FileHandle, - OUT POBJECT_ATTRIBUTES ObjectAttributes, - IN ACCESS_MASK DesiredAccess, - IN ULONG ShareAccess, - IN ULONG OpenOptions) -{ - RTL_RELATIVE_NAME_U RelativeName; - NTSTATUS Status; - IO_STATUS_BLOCK IoStatusBlock; - FILE_ATTRIBUTE_TAG_INFORMATION TagInfo; - ULONG IntShareAccess; - BOOLEAN HasRelative = FALSE; - - _SEH2_TRY - { - /* Zero output */ - RelativeNtName->Length = - RelativeNtName->MaximumLength = 0; - RelativeNtName->Buffer = NULL; - *NtName = NULL; - - if (!RtlDosPathNameToRelativeNtPathName_U(File, RelativeNtName, NULL, &RelativeName)) - { - Status = STATUS_OBJECT_PATH_NOT_FOUND; - _SEH2_LEAVE; - } - - HasRelative = TRUE; - *NtName = RelativeNtName->Buffer; - - if (RelativeName.RelativeName.Length) - { - RelativeNtName->Length = RelativeName.RelativeName.Length; - RelativeNtName->MaximumLength = RelativeName.RelativeName.MaximumLength; - RelativeNtName->Buffer = RelativeName.RelativeName.Buffer; - } - else - { - RelativeName.ContainingDirectory = 0; - } - - InitializeObjectAttributes(ObjectAttributes, - RelativeNtName, - OBJ_CASE_INSENSITIVE, - RelativeName.ContainingDirectory, - NULL); - /* Force certain flags here, given ops we'll do */ - IntShareAccess = ShareAccess | FILE_SHARE_READ | FILE_SHARE_WRITE; - OpenOptions |= FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT; - - /* We'll try to read reparse tag */ - Status = NtOpenFile(FileHandle, - DesiredAccess | FILE_READ_ATTRIBUTES | SYNCHRONIZE, - ObjectAttributes, - &IoStatusBlock, - IntShareAccess, - OpenOptions | FILE_OPEN_REPARSE_POINT); - if (NT_SUCCESS(Status)) - { - /* Attempt the read */ - Status = NtQueryInformationFile(*FileHandle, - &IoStatusBlock, - &TagInfo, - sizeof(FILE_ATTRIBUTE_TAG_INFORMATION), - FileAttributeTagInformation); - - /* Return if failure with a status that wouldn't mean the FSD cannot support reparse points */ - if (!NT_SUCCESS(Status) && - (Status != STATUS_NOT_IMPLEMENTED && Status != STATUS_INVALID_PARAMETER)) - { - _SEH2_LEAVE; - } - - if (NT_SUCCESS(Status)) - { - /* This cannot happen on mount points */ - if (TagInfo.FileAttributes & FILE_ATTRIBUTE_DEVICE || - TagInfo.ReparseTag == IO_REPARSE_TAG_MOUNT_POINT) - { - _SEH2_LEAVE; - } - } - - NtClose(*FileHandle); - *FileHandle = INVALID_HANDLE_VALUE; - - IntShareAccess = ShareAccess | FILE_SHARE_READ | FILE_SHARE_DELETE; - } - else if (Status == STATUS_INVALID_PARAMETER) - { - IntShareAccess = ShareAccess | FILE_SHARE_READ | FILE_SHARE_WRITE; - } - else - { - _SEH2_LEAVE; - } - - /* Reattempt to open normally, following reparse point if needed */ - Status = NtOpenFile(FileHandle, - DesiredAccess | SYNCHRONIZE, - ObjectAttributes, - &IoStatusBlock, - IntShareAccess, - OpenOptions); - } - _SEH2_FINALLY - { - if (HasRelative) - { - RtlReleaseRelativeName(&RelativeName); - } - } - _SEH2_END; - - return Status; -} /* * @implemented
9 years, 8 months
1
0
0
0
[akhaldi] 67336: [SHELL32] Add missing colon in window title bar when formatting a disk. By Radek Liska. CORE-9531
by akhaldi@svn.reactos.org
Author: akhaldi Date: Tue Apr 21 11:43:15 2015 New Revision: 67336 URL:
http://svn.reactos.org/svn/reactos?rev=67336&view=rev
Log: [SHELL32] Add missing colon in window title bar when formatting a disk. By Radek Liska. CORE-9531 Modified: trunk/reactos/dll/win32/shell32/dialogs/drive.cpp Modified: trunk/reactos/dll/win32/shell32/dialogs/drive.cpp URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/dialogs/…
============================================================================== --- trunk/reactos/dll/win32/shell32/dialogs/drive.cpp [iso-8859-1] (original) +++ trunk/reactos/dll/win32/shell32/dialogs/drive.cpp [iso-8859-1] Tue Apr 21 11:43:15 2015 @@ -316,7 +316,7 @@ } } - StringCchPrintfW(szText + cchText, _countof(szText) - cchText, L" (%c)", szDrive[0]); + StringCchPrintfW(szText + cchText, _countof(szText) - cchText, L" (%c:)", szDrive[0]); /* set window text */ SetWindowTextW(hwndDlg, szText);
9 years, 8 months
1
0
0
0
[pschweitzer] 67335: [KERNEL32] - Implement BasepOpenFileForMove() used by PrivMoveFileIdentityW(), with its Windows bugs - Implement PrivMoveFileIdentityW() Not sure yet why Windows implementation...
by pschweitzer@svn.reactos.org
Author: pschweitzer Date: Tue Apr 21 10:55:26 2015 New Revision: 67335 URL:
http://svn.reactos.org/svn/reactos?rev=67335&view=rev
Log: [KERNEL32] - Implement BasepOpenFileForMove() used by PrivMoveFileIdentityW(), with its Windows bugs - Implement PrivMoveFileIdentityW() Not sure yet why Windows implementation exposes a sharing violation during our API test. Our absence of sharing violation looks more legit... To be investigated. Modified: trunk/reactos/dll/win32/kernel32/client/file/move.c trunk/reactos/dll/win32/kernel32/include/kernel32.h Modified: trunk/reactos/dll/win32/kernel32/client/file/move.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/client/…
============================================================================== --- trunk/reactos/dll/win32/kernel32/client/file/move.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/kernel32/client/file/move.c [iso-8859-1] Tue Apr 21 10:55:26 2015 @@ -886,14 +886,379 @@ } /* - * @unimplemented + * @implemented + */ +NTSTATUS +WINAPI +BasepOpenFileForMove(IN LPCWSTR File, + OUT PUNICODE_STRING RelativeNtName, + OUT LPWSTR * NtName, + OUT PHANDLE FileHandle, + OUT POBJECT_ATTRIBUTES ObjectAttributes, + IN ACCESS_MASK DesiredAccess, + IN ULONG ShareAccess, + IN ULONG OpenOptions) +{ + RTL_RELATIVE_NAME_U RelativeName; + NTSTATUS Status; + IO_STATUS_BLOCK IoStatusBlock; + FILE_ATTRIBUTE_TAG_INFORMATION TagInfo; + ULONG IntShareAccess; + BOOLEAN HasRelative = FALSE; + + _SEH2_TRY + { + /* Zero output */ + RelativeNtName->Length = + RelativeNtName->MaximumLength = 0; + RelativeNtName->Buffer = NULL; + *NtName = NULL; + + if (!RtlDosPathNameToRelativeNtPathName_U(File, RelativeNtName, NULL, &RelativeName)) + { + Status = STATUS_OBJECT_PATH_NOT_FOUND; + _SEH2_LEAVE; + } + + HasRelative = TRUE; + *NtName = RelativeNtName->Buffer; + + if (RelativeName.RelativeName.Length) + { + RelativeNtName->Length = RelativeName.RelativeName.Length; + RelativeNtName->MaximumLength = RelativeName.RelativeName.MaximumLength; + RelativeNtName->Buffer = RelativeName.RelativeName.Buffer; + } + else + { + RelativeName.ContainingDirectory = 0; + } + + InitializeObjectAttributes(ObjectAttributes, + RelativeNtName, + OBJ_CASE_INSENSITIVE, + RelativeName.ContainingDirectory, + NULL); + /* Force certain flags here, given ops we'll do */ + IntShareAccess = ShareAccess | FILE_SHARE_READ | FILE_SHARE_WRITE; + OpenOptions |= FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT; + + /* We'll try to read reparse tag */ + Status = NtOpenFile(FileHandle, + DesiredAccess | FILE_READ_ATTRIBUTES | SYNCHRONIZE, + ObjectAttributes, + &IoStatusBlock, + IntShareAccess, + OpenOptions | FILE_OPEN_REPARSE_POINT); + if (NT_SUCCESS(Status)) + { + /* Attempt the read */ + Status = NtQueryInformationFile(*FileHandle, + &IoStatusBlock, + &TagInfo, + sizeof(FILE_ATTRIBUTE_TAG_INFORMATION), + FileAttributeTagInformation); + + /* Return if failure with a status that wouldn't mean the FSD cannot support reparse points */ + if (!NT_SUCCESS(Status) && + (Status != STATUS_NOT_IMPLEMENTED && Status != STATUS_INVALID_PARAMETER)) + { + _SEH2_LEAVE; + } + + if (NT_SUCCESS(Status)) + { + /* This cannot happen on mount points */ + if (TagInfo.FileAttributes & FILE_ATTRIBUTE_DEVICE || + TagInfo.ReparseTag == IO_REPARSE_TAG_MOUNT_POINT) + { + _SEH2_LEAVE; + } + } + + NtClose(*FileHandle); + *FileHandle = INVALID_HANDLE_VALUE; + + IntShareAccess = ShareAccess | FILE_SHARE_READ | FILE_SHARE_DELETE; + } + else if (Status == STATUS_INVALID_PARAMETER) + { + IntShareAccess = ShareAccess | FILE_SHARE_READ | FILE_SHARE_WRITE; + } + else + { + _SEH2_LEAVE; + } + + /* Reattempt to open normally, following reparse point if needed */ + Status = NtOpenFile(FileHandle, + DesiredAccess | SYNCHRONIZE, + ObjectAttributes, + &IoStatusBlock, + IntShareAccess, + OpenOptions); + } + _SEH2_FINALLY + { + if (HasRelative) + { + RtlReleaseRelativeName(&RelativeName); + } + } + _SEH2_END; + + return Status; +} + +/* + * @implemented */ BOOL WINAPI -PrivMoveFileIdentityW(DWORD Unknown1, DWORD Unknown2, DWORD Unknown3) -{ - STUB; - return FALSE; +PrivMoveFileIdentityW(IN LPCWSTR lpSource, IN LPCWSTR lpDestination, IN DWORD dwFlags) +{ + ACCESS_MASK SourceAccess; + UNICODE_STRING NtSource, NtDestination; + LPWSTR RelativeSource, RelativeDestination; + HANDLE SourceHandle, DestinationHandle; + OBJECT_ATTRIBUTES ObjectAttributesSource, ObjectAttributesDestination; + NTSTATUS Status, OldStatus = STATUS_SUCCESS; + ACCESS_MASK DestAccess; + IO_STATUS_BLOCK IoStatusBlock; + FILE_BASIC_INFORMATION SourceInformation, DestinationInformation; + FILE_DISPOSITION_INFORMATION FileDispositionInfo; + + DPRINT("PrivMoveFileIdentityW(%S, %S, %x)\n", lpSource, lpDestination, dwFlags); + + SourceHandle = INVALID_HANDLE_VALUE; + NtSource.Length = + NtSource.MaximumLength = 0; + NtSource.Buffer = NULL; + RelativeSource = NULL; + DestinationHandle = INVALID_HANDLE_VALUE; + NtDestination.Length = + NtDestination.MaximumLength = 0; + NtDestination.Buffer = NULL; + RelativeDestination = NULL; + + /* FILE_WRITE_DATA is required for later on notification */ + SourceAccess = FILE_READ_ATTRIBUTES | FILE_WRITE_DATA; + if (dwFlags & PRIV_DELETE_ON_SUCCESS) + { + SourceAccess |= DELETE; + } + + _SEH2_TRY + { + /* We will loop twice: + * First we attempt to open with FILE_WRITE_DATA for notification + * If it fails and we have flag for non-trackable files, we retry + * without FILE_WRITE_DATA. + * If that one fails, then, we quit for real + */ + while (TRUE) + { + Status = BasepOpenFileForMove(lpSource, + &NtSource, + &RelativeSource, + &SourceHandle, + &ObjectAttributesSource, + SourceAccess, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + FILE_OPEN_NO_RECALL); + if (NT_SUCCESS(Status)) + { + break; + } + + /* If we already attempted the opening without FILE_WRITE_DATA + * or if we cannot move on non-trackable files, fail. + */ + if (!(SourceAccess & FILE_WRITE_DATA) || !(dwFlags & PRIV_ALLOW_NON_TRACKABLE)) + { + _SEH2_LEAVE; + } + + if (RelativeSource) + { + RtlFreeHeap(RtlGetProcessHeap(), 0, RelativeSource); + RelativeSource = NULL; + } + + if (SourceHandle != INVALID_HANDLE_VALUE) + { + NtClose(SourceHandle); + SourceHandle = INVALID_HANDLE_VALUE; + } + + SourceAccess &= ~FILE_WRITE_DATA; + + /* Remember fist failure in the path */ + if (NT_SUCCESS(OldStatus)) + { + OldStatus = Status; + } + } + + DestAccess = FILE_WRITE_ATTRIBUTES; + /* If we could preserve FILE_WRITE_DATA for source, attempt to get it for destination + * Still for notification purposes + */ + if (SourceAccess & FILE_WRITE_DATA) + { + DestAccess |= FILE_WRITE_DATA; + } + + /* cf comment for first loop */ + while (TRUE) + { + Status = BasepOpenFileForMove(lpDestination, + &NtDestination, + &RelativeDestination, + &DestinationHandle, + &ObjectAttributesDestination, + DestAccess, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + FILE_OPEN_NO_RECALL); + if (NT_SUCCESS(Status)) + { + break; + } + + /* If we already attempted the opening without FILE_WRITE_DATA + * or if we cannot move on non-trackable files, fail. + */ + if (!(DestAccess & FILE_WRITE_DATA) || !(dwFlags & PRIV_ALLOW_NON_TRACKABLE)) + { + _SEH2_LEAVE; + } + + if (RelativeDestination) + { + RtlFreeHeap(RtlGetProcessHeap(), 0, RelativeDestination); + RelativeDestination = NULL; + } + + if (DestinationHandle != INVALID_HANDLE_VALUE) + { + NtClose(DestinationHandle); + DestinationHandle = INVALID_HANDLE_VALUE; + } + + DestAccess &= ~FILE_WRITE_DATA; + + /* Remember fist failure in the path */ + if (NT_SUCCESS(OldStatus)) + { + OldStatus = Status; + } + } + + /* Get the creation time from source */ + Status = NtQueryInformationFile(SourceHandle, + &IoStatusBlock, + &SourceInformation, + sizeof(SourceInformation), + FileBasicInformation); + if (NT_SUCCESS(Status)) + { + /* Then, prepare to set it for destination */ + RtlZeroMemory(&DestinationInformation, sizeof(DestinationInformation)); + DestinationInformation.CreationTime.QuadPart = SourceInformation.CreationTime.QuadPart; + + /* And set it, that's all folks! */ + Status = NtSetInformationFile(DestinationHandle, + &IoStatusBlock, + &DestinationInformation, + sizeof(DestinationInformation), + FileBasicInformation); + } + + if (!NT_SUCCESS(Status)) + { + if (!(dwFlags & PRIV_ALLOW_NON_TRACKABLE)) + { + _SEH2_LEAVE; + } + + /* Remember the failure for later notification */ + if (NT_SUCCESS(OldStatus)) + { + OldStatus = Status; + } + } + + /* If we could open with FILE_WRITE_DATA both source and destination, + * then, notify + */ + if (DestAccess & FILE_WRITE_DATA && SourceAccess & FILE_WRITE_DATA) + { + Status = BasepNotifyTrackingService(&SourceHandle, + &ObjectAttributesSource, + DestinationHandle, + &NtDestination); +#if 1 // ReactOS HACK + /* FIXME: To be removed once BasepNotifyTrackingService is implemented */ + if (Status == STATUS_NOT_IMPLEMENTED) + Status = STATUS_SUCCESS; +#endif + if (!NT_SUCCESS(Status)) + { + if (dwFlags & PRIV_ALLOW_NON_TRACKABLE) + { + if (NT_SUCCESS(OldStatus)) + OldStatus = Status; + } + } + } + } + _SEH2_FINALLY + { + if (RelativeSource) + RtlFreeHeap(RtlGetProcessHeap(), 0, RelativeSource); + + if (RelativeDestination) + RtlFreeHeap(RtlGetProcessHeap(), 0, RelativeDestination); + } + _SEH2_END; + + /* If caller asked for source deletion, if everything succeed, proceed */ + if (NT_SUCCESS(Status) && dwFlags & PRIV_DELETE_ON_SUCCESS) + { + FileDispositionInfo.DeleteFile = TRUE; + + Status = NtSetInformationFile(SourceHandle, + &IoStatusBlock, + &FileDispositionInfo, + sizeof(FileDispositionInfo), + FileDispositionInformation); + } + + /* Cleanup/close portion */ + if (DestinationHandle != INVALID_HANDLE_VALUE) + { + NtClose(DestinationHandle); + } + + if (SourceHandle != INVALID_HANDLE_VALUE) + { + NtClose(SourceHandle); + } + + /* Set last error if any, and quit */ + if (NT_SUCCESS(Status)) + { + if (!NT_SUCCESS(OldStatus)) + { + BaseSetLastNTError(OldStatus); + } + } + else + { + BaseSetLastNTError(Status); + } + + return NT_SUCCESS(Status); } /* EOF */ Modified: trunk/reactos/dll/win32/kernel32/include/kernel32.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/include…
============================================================================== --- trunk/reactos/dll/win32/kernel32/include/kernel32.h [iso-8859-1] (original) +++ trunk/reactos/dll/win32/kernel32/include/kernel32.h [iso-8859-1] Tue Apr 21 10:55:26 2015 @@ -142,6 +142,10 @@ #define BASEP_COPY_PUBLIC_MASK 0xF #define BASEP_COPY_BASEP_MASK 0xFFFFFFF0 +/* Flags for PrivMoveFileIdentityW */ +#define PRIV_DELETE_ON_SUCCESS 0x1 +#define PRIV_ALLOW_NON_TRACKABLE 0x2 + /* GLOBAL VARIABLES **********************************************************/ extern BOOL bIsFileApiAnsi;
9 years, 8 months
1
0
0
0
← Newer
1
...
12
13
14
15
16
17
18
...
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