ReactOS.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2025
January
2024
December
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
February
January
2012
December
November
October
September
August
July
June
May
April
March
February
January
2011
December
November
October
September
August
July
June
May
April
March
February
January
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008
December
November
October
September
August
July
June
May
April
March
February
January
2007
December
November
October
September
August
July
June
May
April
March
February
January
2006
December
November
October
September
August
July
June
May
April
March
February
January
2005
December
November
October
September
August
July
June
May
April
March
February
January
2004
December
November
October
September
August
July
June
May
April
March
February
List overview
Download
Ros-diffs
June 2016
----- 2025 -----
January 2025
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
----- 2010 -----
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
June 2010
May 2010
April 2010
March 2010
February 2010
January 2010
----- 2009 -----
December 2009
November 2009
October 2009
September 2009
August 2009
July 2009
June 2009
May 2009
April 2009
March 2009
February 2009
January 2009
----- 2008 -----
December 2008
November 2008
October 2008
September 2008
August 2008
July 2008
June 2008
May 2008
April 2008
March 2008
February 2008
January 2008
----- 2007 -----
December 2007
November 2007
October 2007
September 2007
August 2007
July 2007
June 2007
May 2007
April 2007
March 2007
February 2007
January 2007
----- 2006 -----
December 2006
November 2006
October 2006
September 2006
August 2006
July 2006
June 2006
May 2006
April 2006
March 2006
February 2006
January 2006
----- 2005 -----
December 2005
November 2005
October 2005
September 2005
August 2005
July 2005
June 2005
May 2005
April 2005
March 2005
February 2005
January 2005
----- 2004 -----
December 2004
November 2004
October 2004
September 2004
August 2004
July 2004
June 2004
May 2004
April 2004
March 2004
February 2004
ros-diffs@reactos.org
17 participants
228 discussions
Start a n
N
ew thread
[akhaldi] 71668: [MSI_WINETEST] Sync with Wine Staging 1.9.12. CORE-11266
by akhaldi@svn.reactos.org
Author: akhaldi Date: Sat Jun 25 11:28:00 2016 New Revision: 71668 URL:
http://svn.reactos.org/svn/reactos?rev=71668&view=rev
Log: [MSI_WINETEST] Sync with Wine Staging 1.9.12. CORE-11266 Modified: trunk/rostests/winetests/msi/action.c trunk/rostests/winetests/msi/automation.c trunk/rostests/winetests/msi/db.c trunk/rostests/winetests/msi/package.c Modified: trunk/rostests/winetests/msi/action.c URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/msi/action.c?re…
============================================================================== --- trunk/rostests/winetests/msi/action.c [iso-8859-1] (original) +++ trunk/rostests/winetests/msi/action.c [iso-8859-1] Sat Jun 25 11:28:00 2016 @@ -21,6 +21,7 @@ #define _WIN32_MSI 300 #include <stdio.h> +#include <stdlib.h> #include <windows.h> #include <msiquery.h> @@ -28,6 +29,9 @@ #include <msi.h> #include <fci.h> #include <srrestoreptapi.h> +#include <wtypes.h> +#include <shellapi.h> +#include <winsvc.h> #include "wine/test.h" @@ -230,7 +234,7 @@ "LoadOrderGroup\tDependencies\tStartName\tPassword\tArguments\tComponent_\tDescription\n" "s72\ts255\tL255\ti4\ti4\ti4\tS255\tS255\tS255\tS255\tS255\ts72\tL255\n" "ServiceInstall\tServiceInstall\n" - "TestService\tTestService\tTestService\t2\t3\t0\t\t\tTestService\t\t\tservice_comp\t\n" + "TestService\tTestService\tTestService\t2\t3\t32768\t\t\tTestService\t\t\tservice_comp\t\n" "TestService4\tTestService4\tTestService4\t2\t3\t0\t\t\tTestService4\t\t\tservice_comp3\t\n"; static const char service_control_dat[] = @@ -5423,6 +5427,30 @@ DeleteFileA(msifile); } +static void delete_TestService(void) +{ + BOOL ret; + SC_HANDLE manager, service; + + manager = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS); + ok(manager != NULL, "can't open service manager\n"); + if (!manager) + return; + + service = OpenServiceA(manager, "TestService", GENERIC_ALL); + ok(service != NULL, "TestService doesn't exist\n"); + + if (service) + { + ret = DeleteService( service ); + ok( ret, "failed to delete service %u\n", GetLastError() ); + + CloseServiceHandle(service); + } + CloseServiceHandle(manager); + +} + static void test_delete_services(void) { UINT r; @@ -5488,6 +5516,7 @@ ok(delete_pf("msitest", FALSE), "Directory not created\n"); error: + delete_TestService(); delete_test_files(); DeleteFileA(msifile); } @@ -5496,7 +5525,9 @@ { UINT r; SC_HANDLE manager, service; - BOOL ret; + LONG res; + HKEY hKey; + DWORD err_control, err_controlsize, err_controltype; if (is_process_limited()) { @@ -5528,6 +5559,19 @@ service = OpenServiceA(manager, "TestService4", GENERIC_ALL); ok(service == NULL, "TestService4 installed\n"); CloseServiceHandle(manager); + + res = RegOpenKeyA(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\TestService", &hKey); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + + if (res == ERROR_SUCCESS) + { + err_control = 0xBEEF; + err_controltype = REG_DWORD; + err_controlsize = sizeof(err_control); + res = RegQueryValueExA(hKey, "ErrorControl", NULL, &err_controltype, (LPBYTE)&err_control, &err_controlsize); + ok(err_control == 0, "TestService.ErrorControl wrong, expected 0, got %u\n", err_control); + RegCloseKey(hKey); + } r = MsiInstallProductA(msifile, "REMOVE=ALL"); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); @@ -5546,20 +5590,8 @@ ok(delete_pf("msitest\\service2.exe", TRUE), "File not installed\n"); ok(delete_pf("msitest", FALSE), "Directory not created\n"); - manager = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS); - ok(manager != NULL, "can't open service manager\n"); - if (!manager) goto error; - - service = OpenServiceA(manager, "TestService", GENERIC_ALL); - ok(service != NULL, "TestService doesn't exist\n"); - - ret = DeleteService( service ); - ok( ret, "failed to delete service %u\n", GetLastError() ); - - CloseServiceHandle(service); - CloseServiceHandle(manager); - error: + delete_TestService(); delete_test_files(); DeleteFileA(msifile); } @@ -5882,7 +5914,7 @@ size = 0; r = MsiProvideQualifiedComponentA("{92AFCBC0-9CA6-4270-8454-47C5EE2B8FAA}", "english.txt", INSTALLMODE_DEFAULT, NULL, &size); - ok(r == ERROR_SUCCESS, "MsiProvideQualifiedCompontent returned %d\n", r); + ok(r == ERROR_SUCCESS, "MsiProvideQualifiedComponent returned %d\n", r); res = RegOpenKeyA(HKEY_CURRENT_USER, keypath, &key); ok(res == ERROR_SUCCESS, "components key not created %d\n", res); @@ -5908,7 +5940,7 @@ size = 0; r = MsiProvideQualifiedComponentA("{92AFCBC0-9CA6-4270-8454-47C5EE2B8FAA}", "english.txt", INSTALLMODE_DEFAULT, NULL, &size); - ok(r == ERROR_SUCCESS, "MsiProvideQualifiedCompontent returned %d\n", r); + ok(r == ERROR_SUCCESS, "MsiProvideQualifiedComponent returned %d\n", r); if (pRegDeleteKeyExA) res = pRegDeleteKeyExA(HKEY_LOCAL_MACHINE, keypath2, KEY_WOW64_64KEY, 0); Modified: trunk/rostests/winetests/msi/automation.c URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/msi/automation.…
============================================================================== --- trunk/rostests/winetests/msi/automation.c [iso-8859-1] (original) +++ trunk/rostests/winetests/msi/automation.c [iso-8859-1] Sat Jun 25 11:28:00 2016 @@ -29,6 +29,7 @@ #include <msidefs.h> #include <msi.h> #include <fci.h> +#include <oaidl.h> #include "wine/test.h" @@ -600,10 +601,7 @@ while (ptr->name) { dispid = get_dispid(pInstaller, ptr->name); - if (ptr->todo) - todo_wine - ok(dispid == ptr->did, "%s: expected %d, got %d\n", ptr->name, ptr->did, dispid); - else + todo_wine_if (ptr->todo) ok(dispid == ptr->did, "%s: expected %d, got %d\n", ptr->name, ptr->did, dispid); ptr++; } @@ -884,9 +882,7 @@ if (hr == S_OK) { - if (_invoke_todo_vtResult) todo_wine - ok(V_VT(pVarResult) == vtResult, "Variant result type is %d, expected %d\n", V_VT(pVarResult), vtResult); - else + todo_wine_if (_invoke_todo_vtResult) ok(V_VT(pVarResult) == vtResult, "Variant result type is %d, expected %d\n", V_VT(pVarResult), vtResult); if (vtResult != VT_EMPTY) { Modified: trunk/rostests/winetests/msi/db.c URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/msi/db.c?rev=71…
============================================================================== --- trunk/rostests/winetests/msi/db.c [iso-8859-1] (original) +++ trunk/rostests/winetests/msi/db.c [iso-8859-1] Sat Jun 25 11:28:00 2016 @@ -23,11 +23,10 @@ #include <stdio.h> #include <windows.h> +#include <objidl.h> #include <msi.h> #include <msidefs.h> #include <msiquery.h> - -#include <objidl.h> #include "wine/test.h" @@ -8069,7 +8068,7 @@ r = run_query(href, 0, query); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - /* column sting types don't match exactly */ + /* column string types don't match exactly */ r = MsiDatabaseMergeA(hdb, href, "MergeErrors"); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); Modified: trunk/rostests/winetests/msi/package.c URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/msi/package.c?r…
============================================================================== --- trunk/rostests/winetests/msi/package.c [iso-8859-1] (original) +++ trunk/rostests/winetests/msi/package.c [iso-8859-1] Sat Jun 25 11:28:00 2016 @@ -2482,7 +2482,7 @@ r = MsiOpenDatabaseW(msifileW, MSIDBOPEN_CREATE, &hdb); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - /* database exists, but is emtpy */ + /* database exists, but is empty */ sprintf(name, "#%d", hdb); r = MsiOpenPackageA(name, &hpack); ok(r == ERROR_INSTALL_PACKAGE_INVALID, @@ -2638,19 +2638,14 @@ { ok( state == expected_state, "%u: expected state %d got %d\n", line, expected_state, state ); - if (todo) todo_wine + todo_wine_if (todo) ok( action == expected_action, "%u: expected action %d got %d\n", line, expected_action, action ); - else - ok( action == expected_action, "%u: expected action %d got %d\n", - line, expected_action, action ); } else { ok( state == 0xdeadbee, "%u: expected state 0xdeadbee got %d\n", line, state ); - if (todo) todo_wine - ok( action == 0xdeadbee, "%u: expected action 0xdeadbee got %d\n", line, action ); - else + todo_wine_if (todo) ok( action == 0xdeadbee, "%u: expected action 0xdeadbee got %d\n", line, action ); } @@ -2669,21 +2664,15 @@ { ok( state == expected_state, "%u: expected state %d got %d\n", line, expected_state, state ); - if (todo) todo_wine + todo_wine_if (todo) ok( action == expected_action, "%u: expected action %d got %d\n", line, expected_action, action ); - else - ok( action == expected_action, "%u: expected action %d got %d\n", - line, expected_action, action ); } else { ok( state == 0xdeadbee, "%u: expected state 0xdeadbee got %d\n", line, state ); - if (todo) todo_wine - ok( action == 0xdeadbee, "%u: expected action 0xdeadbee got %d\n", - line, action ); - else + todo_wine_if (todo) ok( action == 0xdeadbee, "%u: expected action 0xdeadbee got %d\n", line, action ); }
8 years, 7 months
1
0
0
0
[akhaldi] 71667: [MSI] Sync with Wine Staging 1.9.12. CORE-11266
by akhaldi@svn.reactos.org
Author: akhaldi Date: Sat Jun 25 11:27:22 2016 New Revision: 71667 URL:
http://svn.reactos.org/svn/reactos?rev=71667&view=rev
Log: [MSI] Sync with Wine Staging 1.9.12. CORE-11266 Modified: trunk/reactos/dll/win32/msi/action.c trunk/reactos/dll/win32/msi/custom.c trunk/reactos/dll/win32/msi/dialog.c trunk/reactos/dll/win32/msi/msvchelper.h trunk/reactos/dll/win32/msi/where.c trunk/reactos/media/doc/README.WINE Modified: trunk/reactos/dll/win32/msi/action.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/action.c?rev…
============================================================================== --- trunk/reactos/dll/win32/msi/action.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msi/action.c [iso-8859-1] Sat Jun 25 11:27:22 2016 @@ -2987,11 +2987,7 @@ { *p = 0; if (!p[1]) continue; /* trailing backslash */ -#ifdef __REACTOS__ /* CORE-10587 */ hkey = open_key( comp, root, subkey, FALSE, access | READ_CONTROL ); -#else - hkey = open_key( comp, root, subkey, FALSE, access ); -#endif if (!hkey) break; res = RegDeleteKeyExW( hkey, p + 1, access, 0 ); RegCloseKey( hkey ); @@ -5806,6 +5802,7 @@ LPWSTR name = NULL, disp = NULL, load_order = NULL, serv_name = NULL; LPWSTR depends = NULL, pass = NULL, args = NULL, image_path = NULL; DWORD serv_type, start_type, err_control; + BOOL is_vital; SERVICE_DESCRIPTIONW sd = {NULL}; UINT ret = ERROR_SUCCESS; @@ -5844,6 +5841,13 @@ deformat_string(package, MSI_RecordGetString(rec, 11), &args); deformat_string(package, MSI_RecordGetString(rec, 13), &sd.lpDescription); + /* Should the complete install fail if CreateService fails? */ + is_vital = (err_control & msidbServiceInstallErrorControlVital); + + /* Remove the msidbServiceInstallErrorControlVital-flag from err_control. + CreateService (under Windows) would fail if not. */ + err_control &= ~msidbServiceInstallErrorControlVital; + /* fetch the service path */ row = MSI_QueryGetRecord(package->db, query, comp); if (!row) @@ -5885,7 +5889,12 @@ if (!service) { if (GetLastError() != ERROR_SERVICE_EXISTS) - ERR("Failed to create service %s: %d\n", debugstr_w(name), GetLastError()); + { + WARN("Failed to create service %s: %d\n", debugstr_w(name), GetLastError()); + if (is_vital) + ret = ERROR_INSTALL_FAILURE; + + } } else if (sd.lpDescription) { Modified: trunk/reactos/dll/win32/msi/custom.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/custom.c?rev…
============================================================================== --- trunk/reactos/dll/win32/msi/custom.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msi/custom.c [iso-8859-1] Sat Jun 25 11:27:22 2016 @@ -527,6 +527,7 @@ __ASM_CFI(".cfi_rel_offset %ebp,0\n\t") "movl %esp,%ebp\n\t" __ASM_CFI(".cfi_def_cfa_register %ebp\n\t") + "subl $4,%esp\n\t" "pushl 12(%ebp)\n\t" "movl 8(%ebp),%eax\n\t" "call *%eax\n\t" Modified: trunk/reactos/dll/win32/msi/dialog.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/dialog.c?rev…
============================================================================== --- trunk/reactos/dll/win32/msi/dialog.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msi/dialog.c [iso-8859-1] Sat Jun 25 11:27:22 2016 @@ -3590,7 +3590,7 @@ dialog->size.cx = sz.cx; dialog->size.cy = sz.cy; - TRACE("%u %u %u %u\n", pos->left, pos->top, pos->right, pos->bottom); + TRACE("%s\n", wine_dbgstr_rect(pos)); style = GetWindowLongPtrW( dialog->hwnd, GWL_STYLE ); AdjustWindowRect( pos, style, FALSE ); Modified: trunk/reactos/dll/win32/msi/msvchelper.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/msvchelper.h…
============================================================================== --- trunk/reactos/dll/win32/msi/msvchelper.h [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msi/msvchelper.h [iso-8859-1] Sat Jun 25 11:27:22 2016 @@ -14,6 +14,7 @@ { push ebp mov ebp, esp + sub esp, 4 push dword ptr [ebp + 12] mov eax, dword ptr [ebp + 8] call eax Modified: trunk/reactos/dll/win32/msi/where.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/where.c?rev=…
============================================================================== --- trunk/reactos/dll/win32/msi/where.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msi/where.c [iso-8859-1] Sat Jun 25 11:27:22 2016 @@ -578,7 +578,7 @@ default: ERR("Invalid expression type\n"); - break; + return ERROR_FUNCTION_FAILED; } return ERROR_SUCCESS; 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] Sat Jun 25 11:27:22 2016 @@ -114,7 +114,7 @@ reactos/dll/win32/msgsm32.acm # Synced to WineStaging-1.9.4 reactos/dll/win32/mshtml # Synced to WineStaging-1.7.55 reactos/dll/win32/mshtml.tlb # Synced to WineStaging-1.7.55 -reactos/dll/win32/msi # Synced to WineStaging-1.9.4 +reactos/dll/win32/msi # Synced to WineStaging-1.9.12 reactos/dll/win32/msimg32 # Synced to WineStaging-1.9.4 reactos/dll/win32/msimtf # Synced to WineStaging-1.9.4 reactos/dll/win32/msisip # Synced to WineStaging-1.9.4
8 years, 7 months
1
0
0
0
[akhaldi] 71666: [PSDK] Add missing msidbServiceInstallErrorControl enum.
by akhaldi@svn.reactos.org
Author: akhaldi Date: Sat Jun 25 11:26:38 2016 New Revision: 71666 URL:
http://svn.reactos.org/svn/reactos?rev=71666&view=rev
Log: [PSDK] Add missing msidbServiceInstallErrorControl enum. Modified: trunk/reactos/sdk/include/psdk/msidefs.h Modified: trunk/reactos/sdk/include/psdk/msidefs.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/sdk/include/psdk/msidefs.h…
============================================================================== --- trunk/reactos/sdk/include/psdk/msidefs.h [iso-8859-1] (original) +++ trunk/reactos/sdk/include/psdk/msidefs.h [iso-8859-1] Sat Jun 25 11:26:38 2016 @@ -198,6 +198,11 @@ msidbServiceControlEventUninstallStart = 0x00000010, msidbServiceControlEventUninstallStop = 0x00000020, msidbServiceControlEventUninstallDelete = 0x00000080, +}; + +enum msidbServiceInstallErrorControl +{ + msidbServiceInstallErrorControlVital = 0x00008000 }; enum msidbMoveFileOptions
8 years, 7 months
1
0
0
0
[zhu] 71665: Server now handles multiple connections without crashing, as long as each connection terminates before the next one is established. Removed misuse of the datagram request lock. Added t...
by zhu@svn.reactos.org
Author: zhu Date: Fri Jun 24 16:11:18 2016 New Revision: 71665 URL:
http://svn.reactos.org/svn/reactos?rev=71665&view=rev
Log: Server now handles multiple connections without crashing, as long as each connection terminates before the next one is established. Removed misuse of the datagram request lock. Added two more memory allocation tags, one for connection contexts and one for TCP requests. Added state variable to ADDRESS_FILE struct to make socket state management cleaner. Modified: branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/address.c branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/address.h branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/main.c Modified: branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/address.c URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/lwIP-tcpip/drivers/ne…
============================================================================== --- branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/address.c [iso-8859-1] (original) +++ branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/address.c [iso-8859-1] Fri Jun 24 16:11:18 2016 @@ -22,13 +22,15 @@ /* The pool tags we will use for all of our allocation */ #define TAG_ADDRESS_FILE 'FrdA' +#define TAG_TCP_CONTEXT 'TCPx' +#define TAG_TCP_REQUEST 'TCPr' /* The list of shared addresses */ static KSPIN_LOCK AddressListLock; static LIST_ENTRY AddressListHead; /* implementation in testing */ -NTSTATUS +PTCP_REQUEST PrepareIrpForCancel( PIRP Irp, PDRIVER_CANCEL CancelRoutine, @@ -46,10 +48,10 @@ if (!Irp->Cancel) { - Request = ExAllocatePoolWithTag(NonPagedPool, sizeof(*Request), TAG_ADDRESS_FILE); + Request = ExAllocatePoolWithTag(NonPagedPool, sizeof(*Request), TAG_TCP_REQUEST); if (!Request) { - return STATUS_NO_MEMORY; + return NULL; } Request->PendingIrp = Irp; Request->CancelMode = CancelMode; @@ -63,7 +65,7 @@ DPRINT1("Prepared for cancel\n"); - return STATUS_SUCCESS; + return Request; } DPRINT1("Already cancelled\n"); @@ -73,10 +75,11 @@ Irp->IoStatus.Status = STATUS_CANCELLED; Irp->IoStatus.Information = 0; - return Irp->IoStatus.Status; + return NULL; } /* implementation in testing */ +/* Does not dequeue the request, simply marks it as cancelled */ VOID NTAPI CancelRequestRoutine( @@ -115,11 +118,12 @@ Irp->IoStatus.Information = 0; switch(MinorFunction) { + case TDI_LISTEN: + DPRINT1("TDI_LISTEN Cancel\n"); + Context->AddressFile->ConnectionContext->lwip_tcp_pcb = NULL; + break; case TDI_SEND: DPRINT1("TDI_SEND Cancel\n"); - break; - case TDI_LISTEN: - DPRINT1("TDI_LISTEN Cancel\n"); break; case TDI_CONNECT: DPRINT1("TDI_CONNECT Cancel\n"); @@ -142,7 +146,7 @@ Request = CONTAINING_RECORD(Entry, TCP_REQUEST, ListEntry); if (Request->PendingIrp == Irp) { - RemoveEntryList(Entry); + DPRINT1("Found matching request\n"); switch (Request->CancelMode) { case TCP_REQUEST_CANCEL_MODE_ABORT: @@ -261,7 +265,7 @@ Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp, IO_NETWORK_INCREMENT); - ExFreePoolWithTag(Request, TAG_ADDRESS_FILE); + ExFreePoolWithTag(Request, TAG_TCP_REQUEST); /* Start again from the beginning */ IoAcquireCancelSpinLock(&OldIrql); @@ -306,14 +310,13 @@ PLIST_ENTRY Head; PLIST_ENTRY Entry; - PLIST_ENTRY Temp; DPRINT1("lwIP TCP Accept Callback\n"); AddressFile = (PADDRESS_FILE)arg; - if (AddressFile->ContextCount == 0) - { - DPRINT1("\n Callback on address file with no contexts\n"); + if (AddressFile->TcpState != TCP_STATE_LISTENING) + { + DPRINT1("Accept callback on an address file that's not listening\n"); return ERR_ABRT; } Head = &AddressFile->ConnectionContext->ListEntry; @@ -334,12 +337,10 @@ Irp = Request->PendingIrp; if (!Irp) { - DPRINT1("Found cancelled IRP\n"); - Temp = Entry->Blink; - RemoveEntryList(Entry); - ExFreePoolWithTag(Request, TAG_ADDRESS_FILE); - Entry = Temp; - continue; + DPRINT1("Request has been cancelled\n"); + RemoveEntryList(&Request->ListEntry); + ExFreePoolWithTag(Request, TAG_TCP_REQUEST); + return ERR_ABRT; } break; } @@ -363,7 +364,7 @@ Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp, IO_NETWORK_INCREMENT); - ExFreePoolWithTag(Request, TAG_ADDRESS_FILE); + ExFreePoolWithTag(Request, TAG_TCP_REQUEST); return ERR_OK; } @@ -388,7 +389,8 @@ if (!Irp) { DPRINT1("Callback on cancelled IRP\n"); - ExFreePoolWithTag(Request, TAG_ADDRESS_FILE); + RemoveEntryList(&Request->ListEntry); + ExFreePoolWithTag(Request, TAG_TCP_REQUEST); return ERR_ABRT; } @@ -402,7 +404,7 @@ IoCompleteRequest(Irp, IO_NETWORK_INCREMENT); RemoveEntryList(&Request->ListEntry); - ExFreePoolWithTag(Request, TAG_ADDRESS_FILE); + ExFreePoolWithTag(Request, TAG_TCP_REQUEST); return ERR_OK; } @@ -444,16 +446,12 @@ if (!Irp) { DPRINT1("Callback on cancelled IRP\n"); - ExFreePoolWithTag(Request, TAG_ADDRESS_FILE); + RemoveEntryList(&Request->ListEntry); + ExFreePoolWithTag(Request, TAG_TCP_REQUEST); return ERR_ABRT; } IrpSp = IoGetCurrentIrpStackLocation(Irp); Context = (PTCP_CONTEXT)IrpSp->FileObject->FsContext; - if (!Context->lwip_tcp_pcb) - { - DPRINT1("Context pcb is NULL\n"); - return ERR_ABRT; - } if (Context->lwip_tcp_pcb != tpcb) { DPRINT1("Receive tcp_pcb mismatch\n"); @@ -462,7 +460,12 @@ Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NETWORK_INCREMENT); RemoveEntryList(&Request->ListEntry); - ExFreePoolWithTag(Request, TAG_ADDRESS_FILE); + ExFreePoolWithTag(Request, TAG_TCP_REQUEST); + return ERR_ABRT; + } + if (!(Context->AddressFile->TcpState & (TCP_STATE_LISTENING|TCP_STATE_CONNECTED))) + { + DPRINT1("Invalid TCP state\n"); return ERR_ABRT; } @@ -538,7 +541,7 @@ IoCompleteRequest(Irp, IO_NETWORK_INCREMENT); RemoveEntryList(&Request->ListEntry); - ExFreePoolWithTag(Request, TAG_ADDRESS_FILE); + ExFreePoolWithTag(Request, TAG_TCP_REQUEST); return ERR_OK; } @@ -591,13 +594,14 @@ /* implementation in testing */ static err_t -lwip_tcp_Connected_callback( +lwip_tcp_connected_callback( void *arg, struct tcp_pcb *tpcb, err_t err) { PTCP_REQUEST Request; PTCP_CONTEXT Context; + PADDRESS_FILE AddressFile; PIO_STACK_LOCATION IrpSp; PIRP Irp; KIRQL OldIrql; @@ -609,33 +613,31 @@ if (!Irp) { DPRINT1("Callback on cancelled IRP\n"); - ExFreePoolWithTag(Request, TAG_ADDRESS_FILE); + RemoveEntryList(&Request->ListEntry); + ExFreePoolWithTag(Request, TAG_TCP_REQUEST); return ERR_ABRT; } IrpSp = IoGetCurrentIrpStackLocation(Irp); Context = (PTCP_CONTEXT)IrpSp->FileObject->FsContext; - if (Context->AddressFile->ConnectionContext->lwip_tcp_pcb == tpcb) - { - DPRINT1("Same as old pcb\n"); - } - else - { - DPRINT1("Connected callback assigns new pcb\n"); - } - Context->lwip_tcp_pcb = tpcb; - Context->AddressFile->ConnectionContext->lwip_tcp_pcb = NULL; + AddressFile = Context->AddressFile; + if (AddressFile->TcpState != TCP_STATE_CONNECTING) + { + DPRINT1("Invalid TCP state\n"); + } IoAcquireCancelSpinLock(&OldIrql); IoSetCancelRoutine(Irp, NULL); Irp->Cancel = FALSE; IoReleaseCancelSpinLock(OldIrql); + AddressFile->TcpState = TCP_STATE_CONNECTED; + Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp, IO_NETWORK_INCREMENT); RemoveEntryList(&Request->ListEntry); - ExFreePoolWithTag(Request, TAG_ADDRESS_FILE); + ExFreePoolWithTag(Request, TAG_TCP_REQUEST); return ERR_OK; } @@ -764,9 +766,9 @@ ip_addr_t IpAddr; ip4_addr_set_u32(&IpAddr, AddressFile->Address.in_addr); InsertEntityInstance(CO_TL_ENTITY, &AddressFile->Instance); - + AddressFile->TcpState = TCP_STATE_CREATED; TcpContext - = ExAllocatePoolWithTag(NonPagedPool, sizeof(TCP_CONTEXT), TAG_ADDRESS_FILE); + = ExAllocatePoolWithTag(NonPagedPool, sizeof(TCP_CONTEXT), TAG_TCP_CONTEXT); InitializeListHead(&TcpContext->ListEntry); TcpContext->AddressFile = AddressFile; TcpContext->Protocol = IPPROTO_TCP; @@ -832,26 +834,10 @@ { PIO_STACK_LOCATION IrpSp; PTCP_CONTEXT Context; - -// ULONG *temp; IrpSp = IoGetCurrentIrpStackLocation(Irp); -/* temp = (ULONG*)Address; - DPRINT1("\n TcpIpCreateAddress Input Dump\n %08x %08x %08x %08x\n", - temp[3], temp[2], - temp[1], temp[0]); - if (IrpSp->FileObject && IrpSp->FileObject->FsContext) - { - temp = IrpSp->FileObject->FsContext; - if (temp) { - DPRINT1("\n IrpSp Dump\n %08x %08x %08x %08x\n %08x %08x %08x %08x\n", - temp[7], temp[6], temp[5], temp[4], - temp[3], temp[2], temp[1], temp[0]); - } - }*/ - - Context = ExAllocatePoolWithTag(NonPagedPool, sizeof(*Context), TAG_ADDRESS_FILE); + Context = ExAllocatePoolWithTag(NonPagedPool, sizeof(*Context), TAG_TCP_CONTEXT); if (!Context) { return STATUS_NO_MEMORY; @@ -879,12 +865,9 @@ _Inout_ ADDRESS_FILE* AddressFile ) { - LIST_ENTRY *Entry; - LIST_ENTRY *Temp; - LIST_ENTRY *Head; - PTCP_CONTEXT CurrentContext; - KIRQL OldIrql; + + err_t lwip_err; /* Lock the global address list */ KeAcquireSpinLock(&AddressListLock, &OldIrql); @@ -898,51 +881,36 @@ } /* remove the lwip pcb */ - if (AddressFile->Protocol == IPPROTO_UDP) - udp_remove(AddressFile->lwip_udp_pcb); - else if (AddressFile->Protocol == IPPROTO_TCP) - { - DPRINT1("Closing TCP address\n"); - if (AddressFile->ContextCount != 0) - { - DPRINT1("Closing open contexts\n"); - Head = &AddressFile->ConnectionContext->ListEntry; - Entry = Head->Flink; - while (Entry != Head) - { - Temp = Entry->Flink; - - CurrentContext = CONTAINING_RECORD(Entry, TCP_CONTEXT, ListEntry); - RemoveEntryList(Entry); - if (!IsListEmpty(&CurrentContext->RequestListHead)) - { - DPRINT1("Address has non-empty request queue\n"); - return STATUS_NOT_IMPLEMENTED; - } - if (CurrentContext->lwip_tcp_pcb != AddressFile->ConnectionContext->lwip_tcp_pcb - && CurrentContext->lwip_tcp_pcb) - { - DPRINT1("Freeing connected tcp_pcb\n"); - tcp_abort(CurrentContext->lwip_tcp_pcb); - } - ExFreePoolWithTag(CurrentContext, TAG_ADDRESS_FILE); - AddressFile->ContextCount--; - Entry = Temp; - } + switch (AddressFile->Protocol) + { + case IPPROTO_UDP : + udp_remove(AddressFile->lwip_udp_pcb); + break; + case IPPROTO_TCP : if (AddressFile->ContextCount != 0) { - DPRINT1("Still contexts remaining after deallocation\n"); - return STATUS_UNSUCCESSFUL; + DPRINT1("Calling close on TCP address with open contexts\n"); + return STATUS_INVALID_PARAMETER; } - } - if (AddressFile->ConnectionContext->lwip_tcp_pcb) - { - tcp_close(AddressFile->ConnectionContext->lwip_tcp_pcb); - } - ExFreePoolWithTag(AddressFile->ConnectionContext, TAG_ADDRESS_FILE); - } - else if (AddressFile->Protocol == IPPROTO_RAW) - raw_remove(AddressFile->lwip_raw_pcb); + if (AddressFile->ConnectionContext->lwip_tcp_pcb) + { + lwip_err = tcp_close(AddressFile->ConnectionContext->lwip_tcp_pcb); + if (lwip_err != ERR_OK) + { + DPRINT1("lwIP tcp_close error: %d", lwip_err); + return STATUS_UNSUCCESSFUL; + } + AddressFile->ConnectionContext->lwip_tcp_pcb = NULL; + } + ExFreePoolWithTag(AddressFile->ConnectionContext, TAG_TCP_CONTEXT); + break; + case IPPROTO_RAW : + raw_remove(AddressFile->lwip_raw_pcb); + break; + default : + DPRINT1("Unknown protocol\n"); + return STATUS_INVALID_ADDRESS; + } /* Remove from the list and free the structure */ RemoveEntryList(&AddressFile->ListEntry); @@ -953,6 +921,66 @@ ExFreePoolWithTag(AddressFile, TAG_ADDRESS_FILE); return STATUS_SUCCESS; +} + +/* implementation in testing */ +NTSTATUS +TcpIpCloseContext( + _In_ PTCP_CONTEXT Context) +{ + err_t lwip_err; + PLIST_ENTRY Head; + PLIST_ENTRY Entry; + PTCP_REQUEST Request; + PIRP Irp; + PIO_STACK_LOCATION IrpSp; + + if (Context->Protocol != IPPROTO_TCP) + { + DPRINT1("Invalid protocol\n"); + return STATUS_INVALID_PARAMETER; + } + if (Context->AddressFile) + { + DPRINT1("Context retains association\n"); + return STATUS_UNSUCCESSFUL; + } + + if (Context->lwip_tcp_pcb) + { + lwip_err = tcp_close(Context->lwip_tcp_pcb); + if (lwip_err != ERR_OK) + { + DPRINT1("lwIP tcp_close error: %d", lwip_err); + return STATUS_UNSUCCESSFUL; + } + } + + Head = &Context->RequestListHead; + Entry = Head->Flink; + while (Entry != Head) + { + Request = CONTAINING_RECORD(Entry, TCP_REQUEST, ListEntry); + Irp = Request->PendingIrp; + if (Irp) + { + IrpSp = IoGetCurrentIrpStackLocation(Irp); + if (IrpSp->FileObject->FsContext != Context) + { + DPRINT1("IRP context mismatch\n"); + return STATUS_UNSUCCESSFUL; + } + + DPRINT1("Closing outstanding request on context\n"); + Irp->IoStatus.Status = STATUS_CANCELLED; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NETWORK_INCREMENT); + } + Entry = Entry->Flink; + ExFreePoolWithTag(Request, TAG_TCP_REQUEST); + } + + return STATUS_SUCCESS; } static @@ -1023,7 +1051,7 @@ IoCompleteRequest(Irp, IO_NETWORK_INCREMENT); - ExFreePoolWithTag(Request, TAG_ADDRESS_FILE); + ExFreePoolWithTag(Request, TAG_TCP_REQUEST); } /* implementation in testing */ @@ -1055,6 +1083,11 @@ if (Context->AddressFile->Protocol != IPPROTO_TCP) { DPRINT1("Received TDI_CONNECT for a non-TCP protocol\n"); + return STATUS_INVALID_ADDRESS; + } + if (Context->AddressFile->TcpState != TCP_STATE_BOUND) + { + DPRINT1("Connecting on address that's not bound\n"); return STATUS_INVALID_ADDRESS; } @@ -1075,7 +1108,7 @@ lwip_err = tcp_connect(Context->lwip_tcp_pcb, (ip_addr_t *)&SocketAddressInRemote->sin_addr.s_addr, SocketAddressInRemote->sin_port, - lwip_tcp_Connected_callback); + lwip_tcp_connected_callback); // DPRINT1("lwip error %d\n", lwip_err); switch (lwip_err) { @@ -1115,12 +1148,12 @@ } case (ERR_OK) : { - PrepareIrpForCancel(Irp, CancelRequestRoutine, TCP_REQUEST_CANCEL_MODE_ABORT); - Request = CONTAINING_RECORD( - Context->RequestListHead.Blink, - TCP_REQUEST, - ListEntry); + Request = PrepareIrpForCancel( + Irp, + CancelRequestRoutine, + TCP_REQUEST_CANCEL_MODE_ABORT); tcp_arg(Context->lwip_tcp_pcb, Request); + Context->AddressFile->TcpState = TCP_STATE_CONNECTING; break; } default : @@ -1144,7 +1177,6 @@ PADDRESS_FILE AddressFile; PTDI_REQUEST_KERNEL_ASSOCIATE RequestInfo; PFILE_OBJECT FileObject; - KIRQL OldIrql; err_t lwip_err; NTSTATUS Status; @@ -1195,18 +1227,12 @@ ObDereferenceObject(FileObject); return STATUS_INVALID_PARAMETER; } - - KeAcquireSpinLock(&AddressFile->RequestLock, &OldIrql); if (AddressFile->Address.in_addr == 0) { // should really look through address file list for an interface AddressFile->Address.in_addr = 0x0100007f; } - -/* DPRINT1("\n TDI Address\n Port: %04x\n Address: %08x\n", - AddressFile->Address.sin_port, - AddressFile->Address.in_addr);*/ Context->AddressFile = AddressFile; Context->lwip_tcp_pcb = AddressFile->ConnectionContext->lwip_tcp_pcb; @@ -1214,61 +1240,66 @@ &Context->ListEntry); AddressFile->ContextCount++; - if (AddressFile->ContextCount <= 1) - { - /* Finally calling into lwip to perform socket bind */ - lwip_err = tcp_bind( - Context->lwip_tcp_pcb, - (ip_addr_t *)&AddressFile->Address.in_addr, - AddressFile->Address.sin_port); - ip_set_option(Context->lwip_tcp_pcb, SOF_BROADCAST); - DPRINT1("lwip error %d\n TCP PCB:\n Local Address: %08x\n Local Port: %04x\n Remote Address: %08x\n Remote Port: %04x\n", - lwip_err, - Context->lwip_tcp_pcb->local_ip, - Context->lwip_tcp_pcb->local_port, - Context->lwip_tcp_pcb->remote_ip, - Context->lwip_tcp_pcb->remote_port); - - if (lwip_err != ERR_OK) - { - switch (lwip_err) + switch (AddressFile->TcpState) + { + case TCP_STATE_CREATED : + /* Finally calling into lwip to perform socket bind */ + lwip_err = tcp_bind( + Context->lwip_tcp_pcb, + (ip_addr_t *)&AddressFile->Address.in_addr, + AddressFile->Address.sin_port); + ip_set_option(Context->lwip_tcp_pcb, SOF_BROADCAST); + DPRINT1("lwip error %d\n TCP PCB:\n Local Address: %08x\n Local Port: %04x\n Remote Address: %08x\n Remote Port: %04x\n", + lwip_err, + Context->lwip_tcp_pcb->local_ip, + Context->lwip_tcp_pcb->local_port, + Context->lwip_tcp_pcb->remote_ip, + Context->lwip_tcp_pcb->remote_port); + if (lwip_err != ERR_OK) { - case (ERR_BUF) : + switch (lwip_err) { - DPRINT1("lwIP ERR_BUFF\n"); - Status = STATUS_NO_MEMORY; - goto LEAVE; - } - case (ERR_VAL) : - { - DPRINT1("lwIP ERR_VAL\n"); - Status = STATUS_INVALID_PARAMETER; - goto LEAVE; - } - case (ERR_USE) : - { - DPRINT1("lwIP ERR_USE\n"); - Status = STATUS_ADDRESS_ALREADY_EXISTS; - goto LEAVE; - } - case (ERR_OK) : - { - DPRINT1("lwIP ERR_OK\n"); - break; - } - default : - { - DPRINT1("lwIP unexpected error\n"); - Status = STATUS_NOT_IMPLEMENTED; - goto LEAVE; + case (ERR_BUF) : + { + DPRINT1("lwIP ERR_BUFF\n"); + Status = STATUS_NO_MEMORY; + goto LEAVE; + } + case (ERR_VAL) : + { + DPRINT1("lwIP ERR_VAL\n"); + Status = STATUS_INVALID_PARAMETER; + goto LEAVE; + } + case (ERR_USE) : + { + DPRINT1("lwIP ERR_USE\n"); + Status = STATUS_ADDRESS_ALREADY_EXISTS; + goto LEAVE; + } + case (ERR_OK) : + { + DPRINT1("lwIP ERR_OK\n"); + break; + } + default : + { + DPRINT1("lwIP unexpected error\n"); + Status = STATUS_NOT_IMPLEMENTED; + goto LEAVE; + } } } - } - } - - KeReleaseSpinLock(&AddressFile->RequestLock, OldIrql); - - Status = STATUS_SUCCESS; + AddressFile->TcpState = TCP_STATE_BOUND; + case TCP_STATE_BOUND : + case TCP_STATE_LISTENING : + Status = STATUS_SUCCESS; + break; + default : + DPRINT1("Invalid TCP state: %d\n", AddressFile->TcpState); + Status = STATUS_UNSUCCESSFUL; + } + LEAVE: return Status; } @@ -1282,7 +1313,6 @@ PIO_STACK_LOCATION IrpSp; PTCP_CONTEXT Context; PADDRESS_FILE AddressFile; - KIRQL OldIrql; IrpSp = IoGetCurrentIrpStackLocation(Irp); if ((ULONG)IrpSp->FileObject->FsContext2 != TDI_CONNECTION_FILE) @@ -1304,21 +1334,27 @@ return STATUS_INVALID_ADDRESS; } - KeAcquireSpinLock(&AddressFile->RequestLock, &OldIrql); - RemoveEntryList(&Context->ListEntry); - if (!IsListEmpty(&Context->RequestListHead)) - { - DPRINT1("Disassociating context with pending requests\n"); - } - if (Context->lwip_tcp_pcb != AddressFile->ConnectionContext->lwip_tcp_pcb) - { - tcp_abort(Context->lwip_tcp_pcb); - } - ExFreePoolWithTag(Context, TAG_ADDRESS_FILE); - AddressFile->ContextCount--; - KeReleaseSpinLock(&AddressFile->RequestLock, OldIrql); - - return STATUS_SUCCESS; + switch (AddressFile->TcpState) + { + case TCP_STATE_BOUND : + tcp_close(Context->lwip_tcp_pcb); + case TCP_STATE_CONNECTED : + AddressFile->ConnectionContext->lwip_tcp_pcb = NULL; + Context->lwip_tcp_pcb = NULL; + case TCP_STATE_LISTENING : + RemoveEntryList(&Context->ListEntry); + Context->AddressFile = NULL; + AddressFile->ContextCount--; + if (AddressFile->ContextCount == 0) + { + return TcpIpCloseAddress(AddressFile); + } + return STATUS_SUCCESS; + default : + DPRINT1("Invalid TCP state: %d\n", AddressFile->TcpState); + // TODO: more case statements for better error reporting + return STATUS_UNSUCCESSFUL; + } } /* Implementation in testing */ @@ -1330,8 +1366,6 @@ PADDRESS_FILE AddressFile; PTCP_CONTEXT ConnectionContext; - KIRQL OldIrql; - struct tcp_pcb *lpcb; IrpSp = IoGetCurrentIrpStackLocation(Irp); @@ -1352,31 +1386,36 @@ return STATUS_INVALID_ADDRESS; } - if (AddressFile->ContextCount == 1) - { - KeAcquireSpinLock(&AddressFile->RequestLock, &OldIrql); - /* Call down into lwip to initiate a listen */ - lpcb = tcp_listen(ConnectionContext->lwip_tcp_pcb); - DPRINT1("lwip tcp_listen returned\n"); - if (lpcb == NULL) - { - /* tcp_listen returning NULL can mean - either INVALID_ADDRESS or NO_MEMORY - if SO_REUSE is enabled in lwip options */ - DPRINT1("lwip tcp_listen error\n"); - return STATUS_INVALID_ADDRESS; - } - AddressFile->ConnectionContext->lwip_tcp_pcb = lpcb; - ConnectionContext->lwip_tcp_pcb = lpcb; - tcp_arg(ConnectionContext->lwip_tcp_pcb, AddressFile); - tcp_accept(ConnectionContext->lwip_tcp_pcb, lwip_tcp_accept_callback); - - KeReleaseSpinLock(&AddressFile->RequestLock, OldIrql); - } - - PrepareIrpForCancel(Irp, CancelRequestRoutine, TCP_REQUEST_CANCEL_MODE_CLOSE); - - return STATUS_PENDING; + switch (AddressFile->TcpState) + { + case TCP_STATE_BOUND : + /* Call down into lwip to initiate a listen */ + lpcb = tcp_listen(AddressFile->ConnectionContext->lwip_tcp_pcb); + DPRINT1("lwip tcp_listen returned\n"); + if (lpcb == NULL) + { + /* tcp_listen returning NULL can mean + either INVALID_ADDRESS or NO_MEMORY + if SO_REUSE is enabled in lwip options */ + DPRINT1("lwip tcp_listen error\n"); + return STATUS_INVALID_ADDRESS; + } + AddressFile->ConnectionContext->lwip_tcp_pcb = lpcb; + tcp_arg(lpcb, AddressFile); + tcp_accept(lpcb, lwip_tcp_accept_callback); + AddressFile->TcpState = TCP_STATE_LISTENING; + case TCP_STATE_LISTENING : + ConnectionContext->lwip_tcp_pcb + = AddressFile->ConnectionContext->lwip_tcp_pcb; + PrepareIrpForCancel( + Irp, + CancelRequestRoutine, + TCP_REQUEST_CANCEL_MODE_CLOSE); + return STATUS_PENDING; + default : + DPRINT1("Invalid TCP sate\n"); + return STATUS_UNSUCCESSFUL; + } } NTSTATUS @@ -1401,6 +1440,23 @@ return STATUS_INVALID_PARAMETER; } Context = IrpSp->FileObject->FsContext; + + switch (Context->AddressFile->TcpState) + { + case TCP_STATE_LISTENING : + if (Context->lwip_tcp_pcb == Context->AddressFile->ConnectionContext->lwip_tcp_pcb) + { + DPRINT1("Has the PCB been assigned by an lwIP callback?\n"); + // TODO: change to better error + return STATUS_UNSUCCESSFUL; + } + case TCP_STATE_CONNECTED : + break; + default : + DPRINT1("Invalid TCP state: %d\n", Context->AddressFile->TcpState); + // TODO: more cases for better error reporting + return STATUS_UNSUCCESSFUL; + } if (!Irp->MdlAddress) { @@ -1439,9 +1495,10 @@ return STATUS_NOT_IMPLEMENTED; } - PrepareIrpForCancel(Irp, CancelRequestRoutine, TCP_REQUEST_CANCEL_MODE_ABORT); - TcpRequest = CONTAINING_RECORD(Context->RequestListHead.Blink, - TCP_REQUEST, ListEntry); + TcpRequest = PrepareIrpForCancel( + Irp, + CancelRequestRoutine, + TCP_REQUEST_CANCEL_MODE_ABORT); tcp_arg(Context->lwip_tcp_pcb, TcpRequest); tcp_sent(Context->lwip_tcp_pcb, lwip_tcp_sent_callback); @@ -1454,6 +1511,7 @@ { PIO_STACK_LOCATION IrpSp; PTCP_CONTEXT Context; + PADDRESS_FILE AddressFile; PTCP_REQUEST Request; PTDI_REQUEST_KERNEL_RECEIVE RequestInfo; @@ -1462,32 +1520,35 @@ if (IrpSp->FileObject->FsContext2 != (PVOID)TDI_CONNECTION_FILE) { - DPRINT1("TcpIpReceive on something that is not an address file\n"); + DPRINT1("TcpIpReceive on something that is not a connection context\n"); return STATUS_INVALID_PARAMETER; } Context = IrpSp->FileObject->FsContext; - - if (!Context->lwip_tcp_pcb) - { - DPRINT1("Connection context does not contain a lwIP tcp_pcb\n"); - return STATUS_INVALID_ADDRESS; - } - if (Context->lwip_tcp_pcb == Context->AddressFile->ConnectionContext->lwip_tcp_pcb) - { - DPRINT1("Has the pcb been assigned by a lwIP callback?\n"); - return STATUS_INVALID_ADDRESS; - } - - RequestInfo = (PTDI_REQUEST_KERNEL_RECEIVE)&IrpSp->Parameters; - DPRINT1("\n Request Length = %d\n", RequestInfo->ReceiveLength); - - PrepareIrpForCancel(Irp, CancelRequestRoutine, TCP_REQUEST_CANCEL_MODE_CLOSE); - Request = CONTAINING_RECORD(Context->RequestListHead.Blink, - TCP_REQUEST, ListEntry); - tcp_arg(Context->lwip_tcp_pcb, Request); - tcp_recv(Context->lwip_tcp_pcb, lwip_tcp_receive_callback); - - return STATUS_PENDING; + AddressFile = Context->AddressFile; + switch (AddressFile->TcpState) + { + case TCP_STATE_LISTENING : + if (Context->lwip_tcp_pcb == AddressFile->ConnectionContext->lwip_tcp_pcb) + { + DPRINT1("Has the PCB been assigned by an lwIP callback?\n"); + return STATUS_INVALID_ADDRESS; + } + case TCP_STATE_CONNECTED : + RequestInfo = (PTDI_REQUEST_KERNEL_RECEIVE)&IrpSp->Parameters; + DPRINT1("\n Request Length = %d\n", RequestInfo->ReceiveLength); + + Request = PrepareIrpForCancel( + Irp, + CancelRequestRoutine, + TCP_REQUEST_CANCEL_MODE_CLOSE); + tcp_arg(Context->lwip_tcp_pcb, Request); + tcp_recv(Context->lwip_tcp_pcb, lwip_tcp_receive_callback); + + return STATUS_PENDING; + default : + DPRINT1("Invalid TCP state: %d\n", AddressFile->TcpState); + return STATUS_INVALID_PARAMETER; + } } NTSTATUS @@ -1520,7 +1581,7 @@ } /* Queue the request */ - Request = ExAllocatePoolWithTag(NonPagedPool, sizeof(*Request), TAG_ADDRESS_FILE); + Request = ExAllocatePoolWithTag(NonPagedPool, sizeof(*Request), TAG_TCP_REQUEST); if (!Request) { Status = STATUS_INSUFFICIENT_RESOURCES; @@ -1570,7 +1631,7 @@ Failure: if (Request) - ExFreePoolWithTag(Request, TAG_ADDRESS_FILE); + ExFreePoolWithTag(Request, TAG_TCP_REQUEST); Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NETWORK_INCREMENT); return Status; Modified: branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/address.h URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/lwIP-tcpip/drivers/ne…
============================================================================== --- branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/address.h [iso-8859-1] (original) +++ branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/address.h [iso-8859-1] Fri Jun 24 16:11:18 2016 @@ -3,6 +3,12 @@ #define TCP_REQUEST_CANCEL_MODE_ABORT 1 #define TCP_REQUEST_CANCEL_MODE_CLOSE 2 + +#define TCP_STATE_CREATED 1 // created, unbound +#define TCP_STATE_BOUND 2 // bound, not listening or trying to connect +#define TCP_STATE_LISTENING 4 // listening, may or may not have connected clients +#define TCP_STATE_CONNECTING 8 // trying to connect as a client +#define TCP_STATE_CONNECTED 16 // connected as client typedef struct _ADDRESS_FILE { LIST_ENTRY ListEntry; @@ -13,6 +19,7 @@ TCPIP_INSTANCE Instance; KSPIN_LOCK RequestLock; LIST_ENTRY RequestListHead; + UCHAR TcpState; union { struct raw_pcb* lwip_raw_pcb; @@ -26,6 +33,7 @@ PADDRESS_FILE AddressFile; IPPROTO Protocol; TDI_ADDRESS_IP RequestAddress; + KSPIN_LOCK RequestListLock; // TODO: implement LIST_ENTRY RequestListHead; struct tcp_pcb* lwip_tcp_pcb; } TCP_CONTEXT, *PTCP_CONTEXT; @@ -56,6 +64,11 @@ NTSTATUS TcpIpCloseAddress( _Inout_ ADDRESS_FILE* AddressFile +); + +NTSTATUS +TcpIpCloseContext( + _In_ PTCP_CONTEXT Context ); NTSTATUS Modified: branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/main.c URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/lwIP-tcpip/drivers/ne…
============================================================================== --- branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/main.c [iso-8859-1] (original) +++ branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/main.c [iso-8859-1] Fri Jun 24 16:11:18 2016 @@ -370,7 +370,7 @@ case TDI_CONNECTION_FILE: DPRINT1("TCPIP Close Connection Context\n"); Context = IrpSp->FileObject->FsContext; - Status = TcpIpCloseAddress(Context->AddressFile); + Status = TcpIpCloseContext(Context); break; case TDI_CONTROL_CHANNEL_FILE: /* We didn't allocate anything for this. */
8 years, 7 months
1
0
0
0
[tthompson] 71664: [NTFS] Update a file's size in the relevant $FILE_NAME attribute of the index entry in the parent directory. +UpdateFileNameRecord() - Searches a parent directory for the proper ...
by tthompson@svn.reactos.org
Author: tthompson Date: Thu Jun 23 18:02:03 2016 New Revision: 71664 URL:
http://svn.reactos.org/svn/reactos?rev=71664&view=rev
Log: [NTFS] Update a file's size in the relevant $FILE_NAME attribute of the index entry in the parent directory. +UpdateFileNameRecord() - Searches a parent directory for the proper index entry, then updates the file sizes in that entry. +UpdateIndexEntryFileNameSize() - Recursively searches directory index and applies the size update. Modified: branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/mft.c branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/ntfs.h branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/rw.c Modified: branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/mft.c URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/NTFS/drivers/filesyst…
============================================================================== --- branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/mft.c [iso-8859-1] (original) +++ branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/mft.c [iso-8859-1] Thu Jun 23 18:02:03 2016 @@ -685,6 +685,212 @@ return FixupUpdateSequenceArray(Vcb, &file->Ntfs); } + +/** +* Searches a file's parent directory (given the parent's index in the mft) +* for the given file. Upon finding an index entry for that file, updates +* Data Size and Allocated Size values in the $FILE_NAME attribute of that entry. +* +* (Most of this code was copied from NtfsFindMftRecord) +*/ +NTSTATUS +UpdateFileNameRecord(PDEVICE_EXTENSION Vcb, + ULONGLONG ParentMFTIndex, + PUNICODE_STRING FileName, + BOOLEAN DirSearch, + ULONGLONG NewDataSize, + ULONGLONG NewAllocationSize) +{ + PFILE_RECORD_HEADER MftRecord; + PNTFS_ATTR_CONTEXT IndexRootCtx; + PINDEX_ROOT_ATTRIBUTE IndexRoot; + PCHAR IndexRecord; + PINDEX_ENTRY_ATTRIBUTE IndexEntry, IndexEntryEnd; + NTSTATUS Status; + ULONG CurrentEntry = 0; + + DPRINT("UpdateFileNameRecord(%p, %I64d, %wZ, %u, %I64u, %I64u)\n", Vcb, ParentMFTIndex, FileName, DirSearch, NewDataSize, NewAllocationSize); + + MftRecord = ExAllocatePoolWithTag(NonPagedPool, + Vcb->NtfsInfo.BytesPerFileRecord, + TAG_NTFS); + if (MftRecord == NULL) + { + return STATUS_INSUFFICIENT_RESOURCES; + } + + Status = ReadFileRecord(Vcb, ParentMFTIndex, MftRecord); + if (!NT_SUCCESS(Status)) + { + ExFreePoolWithTag(MftRecord, TAG_NTFS); + return Status; + } + + ASSERT(MftRecord->Ntfs.Type == NRH_FILE_TYPE); + Status = FindAttribute(Vcb, MftRecord, AttributeIndexRoot, L"$I30", 4, &IndexRootCtx, NULL); + if (!NT_SUCCESS(Status)) + { + ExFreePoolWithTag(MftRecord, TAG_NTFS); + return Status; + } + + IndexRecord = ExAllocatePoolWithTag(NonPagedPool, Vcb->NtfsInfo.BytesPerIndexRecord, TAG_NTFS); + if (IndexRecord == NULL) + { + ReleaseAttributeContext(IndexRootCtx); + ExFreePoolWithTag(MftRecord, TAG_NTFS); + return STATUS_INSUFFICIENT_RESOURCES; + } + + ReadAttribute(Vcb, IndexRootCtx, 0, IndexRecord, Vcb->NtfsInfo.BytesPerIndexRecord); + IndexRoot = (PINDEX_ROOT_ATTRIBUTE)IndexRecord; + IndexEntry = (PINDEX_ENTRY_ATTRIBUTE)((PCHAR)&IndexRoot->Header + IndexRoot->Header.FirstEntryOffset); + // Index root is always resident. + IndexEntryEnd = (PINDEX_ENTRY_ATTRIBUTE)(IndexRecord + IndexRoot->Header.TotalSizeOfEntries); + + DPRINT("IndexRecordSize: %x IndexBlockSize: %x\n", Vcb->NtfsInfo.BytesPerIndexRecord, IndexRoot->SizeOfEntry); + + Status = UpdateIndexEntryFileNameSize(Vcb, + MftRecord, + IndexRecord, + IndexRoot->SizeOfEntry, + IndexEntry, + IndexEntryEnd, + FileName, + &CurrentEntry, + &CurrentEntry, + DirSearch, + NewDataSize, + NewAllocationSize); + + ReleaseAttributeContext(IndexRootCtx); + ExFreePoolWithTag(IndexRecord, TAG_NTFS); + ExFreePoolWithTag(MftRecord, TAG_NTFS); + + return Status; +} + +/** +* Recursively searches directory index and applies the size update to the $FILE_NAME attribute of the +* proper index entry. +* (Heavily based on BrowseIndexEntries) +*/ +NTSTATUS +UpdateIndexEntryFileNameSize(PDEVICE_EXTENSION Vcb, + PFILE_RECORD_HEADER MftRecord, + PCHAR IndexRecord, + ULONG IndexBlockSize, + PINDEX_ENTRY_ATTRIBUTE FirstEntry, + PINDEX_ENTRY_ATTRIBUTE LastEntry, + PUNICODE_STRING FileName, + PULONG StartEntry, + PULONG CurrentEntry, + BOOLEAN DirSearch, + ULONGLONG NewDataSize, + ULONGLONG NewAllocatedSize) +{ + NTSTATUS Status; + ULONG RecordOffset; + PINDEX_ENTRY_ATTRIBUTE IndexEntry; + PNTFS_ATTR_CONTEXT IndexAllocationCtx; + ULONGLONG IndexAllocationSize; + PINDEX_BUFFER IndexBuffer; + + DPRINT("UpdateIndexEntrySize(%p, %p, %p, %u, %p, %p, %wZ, %u, %u, %u, %I64u, %I64u)\n", Vcb, MftRecord, IndexRecord, IndexBlockSize, FirstEntry, LastEntry, FileName, *StartEntry, *CurrentEntry, DirSearch, NewDataSize, NewAllocatedSize); + + // find the index entry responsible for the file we're trying to update + IndexEntry = FirstEntry; + while (IndexEntry < LastEntry && + !(IndexEntry->Flags & NTFS_INDEX_ENTRY_END)) + { + if ((IndexEntry->Data.Directory.IndexedFile & NTFS_MFT_MASK) > 0x10 && + *CurrentEntry >= *StartEntry && + IndexEntry->FileName.NameType != NTFS_FILE_NAME_DOS && + CompareFileName(FileName, IndexEntry, DirSearch)) + { + *StartEntry = *CurrentEntry; + IndexEntry->FileName.DataSize = NewDataSize; + IndexEntry->FileName.AllocatedSize = NewAllocatedSize; + // indicate that the caller will still need to write the structure to the disk + return STATUS_PENDING; + } + + (*CurrentEntry) += 1; + ASSERT(IndexEntry->Length >= sizeof(INDEX_ENTRY_ATTRIBUTE)); + IndexEntry = (PINDEX_ENTRY_ATTRIBUTE)((PCHAR)IndexEntry + IndexEntry->Length); + } + + /* If we're already browsing a subnode */ + if (IndexRecord == NULL) + { + return STATUS_OBJECT_PATH_NOT_FOUND; + } + + /* If there's no subnode */ + if (!(IndexEntry->Flags & NTFS_INDEX_ENTRY_NODE)) + { + return STATUS_OBJECT_PATH_NOT_FOUND; + } + + Status = FindAttribute(Vcb, MftRecord, AttributeIndexAllocation, L"$I30", 4, &IndexAllocationCtx, NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT("Corrupted filesystem!\n"); + return Status; + } + + IndexAllocationSize = AttributeDataLength(&IndexAllocationCtx->Record); + Status = STATUS_OBJECT_PATH_NOT_FOUND; + for (RecordOffset = 0; RecordOffset < IndexAllocationSize; RecordOffset += IndexBlockSize) + { + ReadAttribute(Vcb, IndexAllocationCtx, RecordOffset, IndexRecord, IndexBlockSize); + Status = FixupUpdateSequenceArray(Vcb, &((PFILE_RECORD_HEADER)IndexRecord)->Ntfs); + if (!NT_SUCCESS(Status)) + { + break; + } + + IndexBuffer = (PINDEX_BUFFER)IndexRecord; + ASSERT(IndexBuffer->Ntfs.Type == NRH_INDX_TYPE); + ASSERT(IndexBuffer->Header.AllocatedSize + FIELD_OFFSET(INDEX_BUFFER, Header) == IndexBlockSize); + FirstEntry = (PINDEX_ENTRY_ATTRIBUTE)((ULONG_PTR)&IndexBuffer->Header + IndexBuffer->Header.FirstEntryOffset); + LastEntry = (PINDEX_ENTRY_ATTRIBUTE)((ULONG_PTR)&IndexBuffer->Header + IndexBuffer->Header.TotalSizeOfEntries); + ASSERT(LastEntry <= (PINDEX_ENTRY_ATTRIBUTE)((ULONG_PTR)IndexBuffer + IndexBlockSize)); + + Status = UpdateIndexEntryFileNameSize(NULL, NULL, NULL, 0, FirstEntry, LastEntry, FileName, StartEntry, CurrentEntry, DirSearch, NewDataSize, NewAllocatedSize); + if (Status == STATUS_PENDING) + { + // write the index record back to disk + ULONG Written; + + // first we need to update the fixup values for the index block + Status = AddFixupArray(Vcb, &((PFILE_RECORD_HEADER)IndexRecord)->Ntfs); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Error: Failed to update fixup sequence array!\n"); + break; + } + + Status = WriteAttribute(Vcb, IndexAllocationCtx, RecordOffset, (const PUCHAR)IndexRecord, IndexBlockSize, &Written); + if (!NT_SUCCESS(Status)) + { + DPRINT1("ERROR Performing write!\n"); + break; + } + + Status = STATUS_SUCCESS; + break; + } + if (NT_SUCCESS(Status)) + { + break; + } + } + + ReleaseAttributeContext(IndexAllocationCtx); + return Status; +} + /** * UpdateFileRecord * @implemented Modified: branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/ntfs.h URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/NTFS/drivers/filesyst…
============================================================================== --- branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/ntfs.h [iso-8859-1] (original) +++ branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/ntfs.h [iso-8859-1] Thu Jun 23 18:02:03 2016 @@ -778,10 +778,37 @@ ULONG AttributeAllocatedLength(PNTFS_ATTR_RECORD AttrRecord); +BOOLEAN +CompareFileName(PUNICODE_STRING FileName, + PINDEX_ENTRY_ATTRIBUTE IndexEntry, + BOOLEAN DirSearch); + NTSTATUS ReadFileRecord(PDEVICE_EXTENSION Vcb, ULONGLONG index, PFILE_RECORD_HEADER file); + +NTSTATUS +UpdateIndexEntryFileNameSize(PDEVICE_EXTENSION Vcb, + PFILE_RECORD_HEADER MftRecord, + PCHAR IndexRecord, + ULONG IndexBlockSize, + PINDEX_ENTRY_ATTRIBUTE FirstEntry, + PINDEX_ENTRY_ATTRIBUTE LastEntry, + PUNICODE_STRING FileName, + PULONG StartEntry, + PULONG CurrentEntry, + BOOLEAN DirSearch, + ULONGLONG NewDataSize, + ULONGLONG NewAllocatedSize); + +NTSTATUS +UpdateFileNameRecord(PDEVICE_EXTENSION Vcb, + ULONGLONG ParentMFTIndex, + PUNICODE_STRING FileName, + BOOLEAN DirSearch, + ULONGLONG NewDataSize, + ULONGLONG NewAllocationSize); NTSTATUS UpdateFileRecord(PDEVICE_EXTENSION Vcb, Modified: branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/rw.c URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/NTFS/drivers/filesyst…
============================================================================== --- branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/rw.c [iso-8859-1] (original) +++ branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/rw.c [iso-8859-1] Thu Jun 23 18:02:03 2016 @@ -410,6 +410,9 @@ { LARGE_INTEGER DataSize; ULONGLONG AllocationSize; + PFILENAME_ATTRIBUTE fileNameAttribute; + ULONGLONG ParentMFTId; + UNICODE_STRING filename; DataSize.QuadPart = WriteOffset + Length; @@ -427,7 +430,19 @@ } // now we need to update this file's size in every directory index entry that references it - // (saved for a later commit) + // TODO: put this code in its own function and adapt it to work with every filename / hardlink + // stored in the file record. + fileNameAttribute = GetBestFileNameFromRecord(Fcb->Vcb, FileRecord); + ASSERT(fileNameAttribute); + + ParentMFTId = fileNameAttribute->DirectoryFileReferenceNumber & NTFS_MFT_MASK; + + filename.Buffer = fileNameAttribute->Name; + filename.Length = fileNameAttribute->NameLength * sizeof(WCHAR); + filename.MaximumLength = filename.Length; + + Status = UpdateFileNameRecord(Fcb->Vcb, ParentMFTId, &filename, FALSE, DataSize.QuadPart, AllocationSize); + } else {
8 years, 7 months
1
0
0
0
[zhu] 71663: Added my user-mode test programs
by zhu@svn.reactos.org
Author: zhu Date: Thu Jun 23 16:03:13 2016 New Revision: 71663 URL:
http://svn.reactos.org/svn/reactos?rev=71663&view=rev
Log: Added my user-mode test programs Added: branches/GSoC_2016/lwIP-tcpip/base/applications/network/tcpclient/ branches/GSoC_2016/lwIP-tcpip/base/applications/network/tcpclient/CMakeLists.txt (with props) branches/GSoC_2016/lwIP-tcpip/base/applications/network/tcpclient/main.c (with props) branches/GSoC_2016/lwIP-tcpip/base/applications/network/tcpserver/ branches/GSoC_2016/lwIP-tcpip/base/applications/network/tcpserver/CMakeLists.txt (with props) branches/GSoC_2016/lwIP-tcpip/base/applications/network/tcpserver/main.c (with props) Added: branches/GSoC_2016/lwIP-tcpip/base/applications/network/tcpclient/CMakeLists.txt URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/lwIP-tcpip/base/appli…
============================================================================== --- branches/GSoC_2016/lwIP-tcpip/base/applications/network/tcpclient/CMakeLists.txt (added) +++ branches/GSoC_2016/lwIP-tcpip/base/applications/network/tcpclient/CMakeLists.txt [iso-8859-1] Thu Jun 23 16:03:13 2016 @@ -0,0 +1,11 @@ + +add_definitions(-D__USE_W32_SOCKETS) +add_executable(client main.c) +set_module_type(client win32cui UNICODE) +add_importlibs(client user32 ws2_32 msvcrt kernel32) + +if(MSVC) + add_importlibs(client ntdll) +endif() + +add_cd_file(TARGET client DESTINATION reactos/system32 FOR all) Propchange: branches/GSoC_2016/lwIP-tcpip/base/applications/network/tcpclient/CMakeLists.txt ------------------------------------------------------------------------------ svn:eol-style = native Added: branches/GSoC_2016/lwIP-tcpip/base/applications/network/tcpclient/main.c URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/lwIP-tcpip/base/appli…
============================================================================== --- branches/GSoC_2016/lwIP-tcpip/base/applications/network/tcpclient/main.c (added) +++ branches/GSoC_2016/lwIP-tcpip/base/applications/network/tcpclient/main.c [iso-8859-1] Thu Jun 23 16:03:13 2016 @@ -0,0 +1,49 @@ +#include <stdlib.h> +#include <stdio.h> +#include <winsock2.h> + +int wmain(int argc, LPWSTR argv[]) { + WSADATA wsa; + SOCKET sock; + struct sockaddr_in server; + + int ret; + + char buff[256]; + + ret = WSAStartup(MAKEWORD(2, 2), &wsa); + if (ret != 0) { + printf("Windows Socket API Startup Failed: %d", WSAGetLastError()); + return 1; + } + + printf("Attempt socket creation\n"); + fgets(&buff[0], 255, stdin); + sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (sock == INVALID_SOCKET) { + printf("Socket Creation Failed: %d", WSAGetLastError()); + return 1; + } + + server.sin_addr.s_addr = inet_addr("127.0.0.1"); + server.sin_family = AF_INET; + server.sin_port = htons(10000); + + printf("Attempt connect\n"); + fgets(&buff[0], 255, stdin); + ret = connect(sock, (struct sockaddr *)&server, sizeof(server)); + if (ret < 0) { + printf("Socket Connection Failed: %d", WSAGetLastError()); + return 1; + } + + printf("Connected\n"); + + fgets(&buff[0], 255, stdin); + ret = send(sock, &buff[0], 256, MSG_OOB); + printf("Sent %d bytes", ret); + + fgets(&buff[0], 255, stdin); + + return 0; +} Propchange: branches/GSoC_2016/lwIP-tcpip/base/applications/network/tcpclient/main.c ------------------------------------------------------------------------------ svn:eol-style = native Added: branches/GSoC_2016/lwIP-tcpip/base/applications/network/tcpserver/CMakeLists.txt URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/lwIP-tcpip/base/appli…
============================================================================== --- branches/GSoC_2016/lwIP-tcpip/base/applications/network/tcpserver/CMakeLists.txt (added) +++ branches/GSoC_2016/lwIP-tcpip/base/applications/network/tcpserver/CMakeLists.txt [iso-8859-1] Thu Jun 23 16:03:13 2016 @@ -0,0 +1,11 @@ + +add_definitions(-D__USE_W32_SOCKETS) +add_executable(server main.c) +set_module_type(server win32cui UNICODE) +add_importlibs(server user32 ws2_32 msvcrt kernel32) + +if(MSVC) + add_importlibs(server ntdll) +endif() + +add_cd_file(TARGET server DESTINATION reactos/system32 FOR all) Propchange: branches/GSoC_2016/lwIP-tcpip/base/applications/network/tcpserver/CMakeLists.txt ------------------------------------------------------------------------------ svn:eol-style = native Added: branches/GSoC_2016/lwIP-tcpip/base/applications/network/tcpserver/main.c URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/lwIP-tcpip/base/appli…
============================================================================== --- branches/GSoC_2016/lwIP-tcpip/base/applications/network/tcpserver/main.c (added) +++ branches/GSoC_2016/lwIP-tcpip/base/applications/network/tcpserver/main.c [iso-8859-1] Thu Jun 23 16:03:13 2016 @@ -0,0 +1,73 @@ +#include <stdio.h> +#include <WinSock2.h> + +int wmain(int argc, LPWSTR argv[]) { + WSADATA wsa; + SOCKET sock; + SOCKET accepted; + struct sockaddr_in server; + struct sockaddr_in client; + + int c; + int ret; + + char buff[256]; + + memset(&server, 0, sizeof(struct sockaddr_in)); + memset(&client, 0, sizeof(struct sockaddr_in)); + + ret = WSAStartup(MAKEWORD(2, 2), &wsa); + if (ret != 0) { + printf("Windows Socket API Startup Failed: %d", WSAGetLastError()); + exit(1); + } + + printf("Attempt socket creation\n"); + fgets(&buff[0], 255, stdin); + sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (sock == INVALID_SOCKET) { + printf("Socket Creation Failed: %d", WSAGetLastError()); + exit(1); + } + + server.sin_family = AF_INET; + server.sin_addr.s_addr = inet_addr("127.0.0.1"); + server.sin_port = htons(10000); + + printf("Attempt bind\n"); + fgets(&buff[0], 255, stdin); + ret = bind(sock, (struct sockaddr *)&server, sizeof(server)); + if (ret == SOCKET_ERROR) { + printf("Socket Bind Failed: %d", WSAGetLastError()); + exit(1); + } + + printf("Attempt listen\n"); + fgets(&buff[0], 255, stdin); + ret = listen(sock, 3); + if (ret != 0) { + printf("Socket Listen Failed: %d", WSAGetLastError()); + exit(1); + } + + printf("Listening for connections on LOOPBACK port 10000\n"); + + c = sizeof(struct sockaddr_in); + + printf("Enter accept loop\n"); + fgets(&buff[0], 255, stdin); + while(1) { + accepted = accept(sock, (struct sockaddr *)&client, &c); + if (accepted == INVALID_SOCKET) { + printf("Socket Connection Acceptance Failed: %d", WSAGetLastError()); + exit(1); + } else { + printf("Socket connection accepted\n"); + ret = recv(accepted, &buff[0], 256, MSG_OOB); + printf("Received %d bytes\n", ret); + printf("Message: %s", &buff[0]); + } + } + + exit(1); +} Propchange: branches/GSoC_2016/lwIP-tcpip/base/applications/network/tcpserver/main.c ------------------------------------------------------------------------------ svn:eol-style = native
8 years, 7 months
1
0
0
0
[tthompson] 71662: [NTFS] Fix Up AddFixupArray - It needs to accept a PNTFS_RECORD_HEADER for parameter 2, not a PFILE_RECORD_HEADER.
by tthompson@svn.reactos.org
Author: tthompson Date: Thu Jun 23 15:37:19 2016 New Revision: 71662 URL:
http://svn.reactos.org/svn/reactos?rev=71662&view=rev
Log: [NTFS] Fix Up AddFixupArray - It needs to accept a PNTFS_RECORD_HEADER for parameter 2, not a PFILE_RECORD_HEADER. Modified: branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/mft.c branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/ntfs.h Modified: branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/mft.c URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/NTFS/drivers/filesyst…
============================================================================== --- branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/mft.c [iso-8859-1] (original) +++ branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/mft.c [iso-8859-1] Thu Jun 23 15:37:19 2016 @@ -701,7 +701,7 @@ DPRINT("UpdateFileRecord(%p, %I64x, %p)\n", Vcb, index, file); // Add the fixup array to prepare the data for writing to disk - AddFixupArray(Vcb, file); + AddFixupArray(Vcb, &file->Ntfs); // write the file record to the master file table Status = WriteAttribute(Vcb, Vcb->MFTContext, index * Vcb->NtfsInfo.BytesPerFileRecord, (const PUCHAR)file, Vcb->NtfsInfo.BytesPerFileRecord, &BytesWritten); @@ -750,27 +750,24 @@ NTSTATUS AddFixupArray(PDEVICE_EXTENSION Vcb, - PFILE_RECORD_HEADER Record) + PNTFS_RECORD_HEADER Record) { USHORT *pShortToFixUp; - unsigned int ArrayEntryCount = Record->BytesAllocated / Vcb->NtfsInfo.BytesPerSector; + unsigned int ArrayEntryCount = Record->UsaCount - 1; unsigned int Offset = Vcb->NtfsInfo.BytesPerSector - 2; int i; - PFIXUP_ARRAY fixupArray = (PFIXUP_ARRAY)((UCHAR*)Record + Record->Ntfs.UsaOffset); + PFIXUP_ARRAY fixupArray = (PFIXUP_ARRAY)((UCHAR*)Record + Record->UsaOffset); DPRINT("AddFixupArray(%p, %p)\n fixupArray->USN: %u, ArrayEntryCount: %u\n", Vcb, Record, fixupArray->USN, ArrayEntryCount); - if (Record->BytesAllocated % Vcb->NtfsInfo.BytesPerSector != 0) - ArrayEntryCount++; - fixupArray->USN++; for (i = 0; i < ArrayEntryCount; i++) { DPRINT("USN: %u\tOffset: %u\n", fixupArray->USN, Offset); - pShortToFixUp = (USHORT*)((UCHAR*)Record + Offset); + pShortToFixUp = (USHORT*)((PCHAR)Record + Offset); fixupArray->Array[i] = *pShortToFixUp; *pShortToFixUp = fixupArray->USN; Offset += Vcb->NtfsInfo.BytesPerSector; Modified: branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/ntfs.h URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/NTFS/drivers/filesyst…
============================================================================== --- branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/ntfs.h [iso-8859-1] (original) +++ branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/ntfs.h [iso-8859-1] Thu Jun 23 15:37:19 2016 @@ -811,7 +811,7 @@ NTSTATUS AddFixupArray(PDEVICE_EXTENSION Vcb, - PFILE_RECORD_HEADER Record); + PNTFS_RECORD_HEADER Record); NTSTATUS ReadLCN(PDEVICE_EXTENSION Vcb,
8 years, 7 months
1
0
0
0
[zhu] 71661: Backlogging successful. Server is able to simultaneously receive messages from two different clients. Crashes on client exit due to referencing deallocated memory.
by zhu@svn.reactos.org
Author: zhu Date: Thu Jun 23 15:28:39 2016 New Revision: 71661 URL:
http://svn.reactos.org/svn/reactos?rev=71661&view=rev
Log: Backlogging successful. Server is able to simultaneously receive messages from two different clients. Crashes on client exit due to referencing deallocated memory. Modified: branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/address.c branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/address.h branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/main.c branches/GSoC_2016/lwIP-tcpip/sdk/lib/drivers/lwip/src/include/lwip/opt.h Modified: branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/address.c URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/lwIP-tcpip/drivers/ne…
============================================================================== --- branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/address.c [iso-8859-1] (original) +++ branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/address.c [iso-8859-1] Thu Jun 23 15:28:39 2016 @@ -31,11 +31,13 @@ NTSTATUS PrepareIrpForCancel( PIRP Irp, - PDRIVER_CANCEL CancelRoutine + PDRIVER_CANCEL CancelRoutine, + UCHAR CancelMode ) { PIO_STACK_LOCATION IrpSp; - PADDRESS_FILE AddressFile; + PTCP_CONTEXT Context; + PTCP_REQUEST Request; KIRQL OldIrql; DPRINT1("Prepare for cancel\n"); @@ -44,14 +46,27 @@ if (!Irp->Cancel) { + Request = ExAllocatePoolWithTag(NonPagedPool, sizeof(*Request), TAG_ADDRESS_FILE); + if (!Request) + { + return STATUS_NO_MEMORY; + } + Request->PendingIrp = Irp; + Request->CancelMode = CancelMode; + IrpSp = IoGetCurrentIrpStackLocation(Irp); - AddressFile = (PADDRESS_FILE)IrpSp->FileObject->FsContext; - AddressFile->ConnectionContext->PendingIrp = Irp; + Context = (PTCP_CONTEXT)IrpSp->FileObject->FsContext; + InsertTailList(&Context->RequestListHead, &Request->ListEntry); IoSetCancelRoutine(Irp, CancelRoutine); IoReleaseCancelSpinLock(OldIrql); + + DPRINT1("Prepared for cancel\n"); + return STATUS_SUCCESS; } + + DPRINT1("Already cancelled\n"); IoReleaseCancelSpinLock(OldIrql); @@ -70,7 +85,10 @@ ) { PIO_STACK_LOCATION IrpSp; - PADDRESS_FILE AddressFile; + PTCP_CONTEXT Context; + PLIST_ENTRY Head; + PLIST_ENTRY Entry; + PTCP_REQUEST Request; UCHAR MinorFunction; KIRQL OldIrql; @@ -79,51 +97,68 @@ IoReleaseCancelSpinLock(Irp->CancelIrql); IrpSp = IoGetCurrentIrpStackLocation(Irp); - AddressFile = (PADDRESS_FILE)IrpSp->FileObject->FsContext; + switch ((ULONG)IrpSp->FileObject->FsContext2) + { + case TDI_TRANSPORT_ADDRESS_FILE : + goto DGRAM_CANCEL; + case TDI_CONNECTION_FILE : + Context = (PTCP_CONTEXT)IrpSp->FileObject->FsContext; + goto TCP_CANCEL; + default : + DPRINT1("Cancellation error\n"); + goto FINISH; + } + +TCP_CANCEL: MinorFunction = IrpSp->MinorFunction; - Irp->IoStatus.Status = STATUS_CANCELLED; Irp->IoStatus.Information = 0; - switch(MinorFunction) { + case TDI_SEND: + DPRINT1("TDI_SEND Cancel\n"); + break; + case TDI_LISTEN: + DPRINT1("TDI_LISTEN Cancel\n"); + break; + case TDI_CONNECT: + DPRINT1("TDI_CONNECT Cancel\n"); + break; case TDI_RECEIVE: DPRINT1("TDI_RECEIVE Cancel\n"); - goto TCP_CANCEL; - case TDI_RECEIVE_DATAGRAM: - DPRINT1("TDI_RECEIVE_DATAGRAM cancelling is handled within TcpIpReceiveDatagram()\n"); - goto DGRAM_CANCEL; - case TDI_SEND: - DPRINT1("TDI_SEND Cancel\n"); - goto TCP_CANCEL; - case TDI_SEND_DATAGRAM: - DPRINT1("TDI_SEND_DATAGRAM Cancel\n"); - goto DGRAM_CANCEL; - case TDI_LISTEN: - DPRINT1("TDI_LISTEN Cancel\n"); - goto TCP_CANCEL; - case TDI_CONNECT: - DPRINT1("TDI_CONNECT Cancel\n"); - goto TCP_CANCEL; + break; case TDI_DISCONNECT: DPRINT1("TDI_DISCONNECT Cancel\n"); - goto TCP_CANCEL; + break; default: - DPRINT1("Invalid MinorFunction for cancelling IRP\n"); - return; - } - -TCP_CANCEL: - if (AddressFile->ConnectionContext) - { - if (AddressFile->ConnectionContext->lwip_tcp_pcb) + DPRINT1("Invalid MinorFunction for TCP_CANCEL\n"); + goto FINISH; + } + + Head = &Context->RequestListHead; + Entry = Head->Flink; + while (Entry != Head) + { + Request = CONTAINING_RECORD(Entry, TCP_REQUEST, ListEntry); + if (Request->PendingIrp == Irp) { - tcp_abort(AddressFile->ConnectionContext->lwip_tcp_pcb); - AddressFile->ConnectionContext->PendingIrp = NULL; - AddressFile->ConnectionContext->lwip_tcp_pcb = NULL; - DPRINT1("TCP_CANCEL\n"); + RemoveEntryList(Entry); + switch (Request->CancelMode) + { + case TCP_REQUEST_CANCEL_MODE_ABORT: + tcp_abort(Context->lwip_tcp_pcb); + break; + case TCP_REQUEST_CANCEL_MODE_CLOSE: + tcp_close(Context->lwip_tcp_pcb); + break; + } + Context->lwip_tcp_pcb = NULL; + Request->PendingIrp = NULL; + goto FINISH; } - } + Entry = Entry->Flink; + } + DPRINT1("No matching TCP_REQUEST found\n"); goto FINISH; DGRAM_CANCEL: @@ -136,7 +171,8 @@ IoCompleteRequest(Irp, IO_NETWORK_INCREMENT); - DPRINT1("\n CancelRequestRoutine\n Exiting\n"); + DPRINT1("\n CancelRequestRoutine Exiting\n"); + return; } @@ -263,26 +299,55 @@ err_t err) { PIRP Irp; - PIO_STACK_LOCATION IrpSp; KIRQL OldIrql; + PTCP_REQUEST Request; PADDRESS_FILE AddressFile; + PTCP_CONTEXT Context; + + PLIST_ENTRY Head; + PLIST_ENTRY Entry; + PLIST_ENTRY Temp; DPRINT1("lwIP TCP Accept Callback\n"); AddressFile = (PADDRESS_FILE)arg; - Irp = AddressFile->ConnectionContext->PendingIrp; + if (AddressFile->ContextCount == 0) + { + DPRINT1("\n Callback on address file with no contexts\n"); + return ERR_ABRT; + } + Head = &AddressFile->ConnectionContext->ListEntry; + Entry = Head->Blink; + Irp = NULL; + while (Entry != Head) + { + Context = CONTAINING_RECORD(Entry, TCP_CONTEXT, ListEntry); + if (Context->lwip_tcp_pcb == AddressFile->ConnectionContext->lwip_tcp_pcb) + { + if (IsListEmpty(&Context->RequestListHead)) + { + DPRINT1("Context has empty request list\n"); + return ERR_ABRT; + } + Request = CONTAINING_RECORD(Context->RequestListHead.Flink, + TCP_REQUEST, ListEntry); + Irp = Request->PendingIrp; + if (!Irp) + { + DPRINT1("Found cancelled IRP\n"); + Temp = Entry->Blink; + RemoveEntryList(Entry); + ExFreePoolWithTag(Request, TAG_ADDRESS_FILE); + Entry = Temp; + continue; + } + break; + } + Entry = Entry->Blink; + } if (!Irp) { - DPRINT1("Callback on canceled IRP\n"); - return ERR_ABRT; - } - IrpSp = IoGetCurrentIrpStackLocation(Irp); - - if (AddressFile != IrpSp->FileObject->FsContext) - { - DPRINT1("AddressFile Mismatch\n"); - tcp_abort(AddressFile->ConnectionContext->lwip_tcp_pcb); - AddressFile->ConnectionContext->lwip_tcp_pcb = NULL; + DPRINT1("Could not find a listening tcp_pcb\n"); return ERR_ABRT; } @@ -291,10 +356,14 @@ Irp->Cancel = FALSE; IoReleaseCancelSpinLock(OldIrql); - AddressFile->ConnectionContext->lwip_tcp_pcb = newpcb; + Context->lwip_tcp_pcb = newpcb; + tcp_accepted(AddressFile->ConnectionContext->lwip_tcp_pcb); + RemoveEntryList(&Request->ListEntry); Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp, IO_NETWORK_INCREMENT); + + ExFreePoolWithTag(Request, TAG_ADDRESS_FILE); return ERR_OK; } @@ -308,17 +377,18 @@ u16_t len ) { - PADDRESS_FILE AddressFile; + PTCP_REQUEST Request; PIRP Irp; KIRQL OldIrql; DPRINT1("lwIP TCP Sent Callback\n"); - AddressFile = (PADDRESS_FILE)arg; - Irp = AddressFile->ConnectionContext->PendingIrp; + Request = (PTCP_REQUEST)arg; + Irp = Request->PendingIrp; if (!Irp) { - DPRINT1("Callback on canceled IRP\n"); + DPRINT1("Callback on cancelled IRP\n"); + ExFreePoolWithTag(Request, TAG_ADDRESS_FILE); return ERR_ABRT; } @@ -330,6 +400,9 @@ Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = len; IoCompleteRequest(Irp, IO_NETWORK_INCREMENT); + + RemoveEntryList(&Request->ListEntry); + ExFreePoolWithTag(Request, TAG_ADDRESS_FILE); return ERR_OK; } @@ -346,7 +419,8 @@ { PIRP Irp; PNDIS_BUFFER Buffer; - PADDRESS_FILE AddressFile; + PTCP_CONTEXT Context; + PTCP_REQUEST Request; PIO_STACK_LOCATION IrpSp; PTDI_REQUEST_KERNEL_RECEIVE ReceiveInfo; KIRQL OldIrql; @@ -359,11 +433,36 @@ DPRINT1("lwIP TCP Receive Callback\n"); - AddressFile = (PADDRESS_FILE)arg; - Irp = AddressFile->ConnectionContext->PendingIrp; + if (err != ERR_OK) + { + DPRINT1("lwIP Error %d\n", err); + return ERR_ABRT; + } + + Request = (PTCP_REQUEST)arg; + Irp = Request->PendingIrp; if (!Irp) { - DPRINT1("Callback on canceled IRP\n"); + DPRINT1("Callback on cancelled IRP\n"); + ExFreePoolWithTag(Request, TAG_ADDRESS_FILE); + return ERR_ABRT; + } + IrpSp = IoGetCurrentIrpStackLocation(Irp); + Context = (PTCP_CONTEXT)IrpSp->FileObject->FsContext; + if (!Context->lwip_tcp_pcb) + { + DPRINT1("Context pcb is NULL\n"); + return ERR_ABRT; + } + if (Context->lwip_tcp_pcb != tpcb) + { + DPRINT1("Receive tcp_pcb mismatch\n"); + tcp_abort(tpcb); + Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NETWORK_INCREMENT); + RemoveEntryList(&Request->ListEntry); + ExFreePoolWithTag(Request, TAG_ADDRESS_FILE); return ERR_ABRT; } @@ -373,7 +472,6 @@ IoReleaseCancelSpinLock(OldIrql); Buffer = (PNDIS_BUFFER)Irp->MdlAddress; - IrpSp = IoGetCurrentIrpStackLocation(Irp); ReceiveInfo = (PTDI_REQUEST_KERNEL_RECEIVE)&IrpSp->Parameters; NdisQueryBuffer(Buffer, &CurrentDestLocation, &RemainingDestBytes); @@ -432,10 +530,15 @@ RETURN: DPRINT1("Receive CopiedLength = %d\n", CopiedLength); + + tcp_recved(tpcb, CopiedLength); Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = CopiedLength; IoCompleteRequest(Irp, IO_NETWORK_INCREMENT); + + RemoveEntryList(&Request->ListEntry); + ExFreePoolWithTag(Request, TAG_ADDRESS_FILE); return ERR_OK; } @@ -493,19 +596,35 @@ struct tcp_pcb *tpcb, err_t err) { - PADDRESS_FILE AddressFile; + PTCP_REQUEST Request; + PTCP_CONTEXT Context; + PIO_STACK_LOCATION IrpSp; PIRP Irp; KIRQL OldIrql; DPRINT1("lwIP TCP Connected Callback\n"); - AddressFile = (PADDRESS_FILE)arg; - Irp = AddressFile->ConnectionContext->PendingIrp; + Request = (PTCP_REQUEST)arg; + Irp = Request->PendingIrp; if (!Irp) { - DPRINT1("Callback on canceled IRP\n"); + DPRINT1("Callback on cancelled IRP\n"); + ExFreePoolWithTag(Request, TAG_ADDRESS_FILE); return ERR_ABRT; } + + IrpSp = IoGetCurrentIrpStackLocation(Irp); + Context = (PTCP_CONTEXT)IrpSp->FileObject->FsContext; + if (Context->AddressFile->ConnectionContext->lwip_tcp_pcb == tpcb) + { + DPRINT1("Same as old pcb\n"); + } + else + { + DPRINT1("Connected callback assigns new pcb\n"); + } + Context->lwip_tcp_pcb = tpcb; + Context->AddressFile->ConnectionContext->lwip_tcp_pcb = NULL; IoAcquireCancelSpinLock(&OldIrql); IoSetCancelRoutine(Irp, NULL); @@ -514,6 +633,9 @@ Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp, IO_NETWORK_INCREMENT); + + RemoveEntryList(&Request->ListEntry); + ExFreePoolWithTag(Request, TAG_ADDRESS_FILE); return ERR_OK; } @@ -648,7 +770,7 @@ InitializeListHead(&TcpContext->ListEntry); TcpContext->AddressFile = AddressFile; TcpContext->Protocol = IPPROTO_TCP; - TcpContext->PendingIrp = NULL; + InitializeListHead(&TcpContext->RequestListHead); TcpContext->lwip_tcp_pcb = tcp_new(); AddressFile->ConnectionContext = TcpContext; AddressFile->ContextCount = 0; @@ -696,6 +818,7 @@ Success: IrpSp->FileObject->FsContext = AddressFile; IrpSp->FileObject->FsContext2 = (PVOID)TDI_TRANSPORT_ADDRESS_FILE; + return STATUS_SUCCESS; } @@ -741,6 +864,7 @@ } Context->Protocol = Protocol; RtlCopyMemory(&Context->RequestAddress, Address, sizeof(*Address)); + InitializeListHead(&Context->RequestListHead); Context->lwip_tcp_pcb = NULL; IrpSp->FileObject->FsContext = (PVOID)Context; @@ -776,10 +900,12 @@ /* remove the lwip pcb */ if (AddressFile->Protocol == IPPROTO_UDP) udp_remove(AddressFile->lwip_udp_pcb); - else if (AddressFile->Protocol == IPPROTO_TCP && AddressFile->ConnectionContext) - { + else if (AddressFile->Protocol == IPPROTO_TCP) + { + DPRINT1("Closing TCP address\n"); if (AddressFile->ContextCount != 0) { + DPRINT1("Closing open contexts\n"); Head = &AddressFile->ConnectionContext->ListEntry; Entry = Head->Flink; while (Entry != Head) @@ -788,6 +914,17 @@ CurrentContext = CONTAINING_RECORD(Entry, TCP_CONTEXT, ListEntry); RemoveEntryList(Entry); + if (!IsListEmpty(&CurrentContext->RequestListHead)) + { + DPRINT1("Address has non-empty request queue\n"); + return STATUS_NOT_IMPLEMENTED; + } + if (CurrentContext->lwip_tcp_pcb != AddressFile->ConnectionContext->lwip_tcp_pcb + && CurrentContext->lwip_tcp_pcb) + { + DPRINT1("Freeing connected tcp_pcb\n"); + tcp_abort(CurrentContext->lwip_tcp_pcb); + } ExFreePoolWithTag(CurrentContext, TAG_ADDRESS_FILE); AddressFile->ContextCount--; Entry = Temp; @@ -801,7 +938,6 @@ if (AddressFile->ConnectionContext->lwip_tcp_pcb) { tcp_close(AddressFile->ConnectionContext->lwip_tcp_pcb); - AddressFile->ConnectionContext->lwip_tcp_pcb = NULL; } ExFreePoolWithTag(AddressFile->ConnectionContext, TAG_ADDRESS_FILE); } @@ -896,7 +1032,8 @@ _Inout_ PIRP Irp) { PIO_STACK_LOCATION IrpSp; - ADDRESS_FILE *AddressFile; + PTCP_CONTEXT Context; + PTCP_REQUEST Request; PTDI_REQUEST_KERNEL_CONNECT Parameters; PTRANSPORT_ADDRESS RemoteTransportAddress; @@ -908,14 +1045,14 @@ IrpSp = IoGetCurrentIrpStackLocation(Irp); /* Check this is really a connection file */ - if ((ULONG_PTR)IrpSp->FileObject->FsContext2 != TDI_TRANSPORT_ADDRESS_FILE) - { - DPRINT1("File object not an address file\n"); + if ((ULONG_PTR)IrpSp->FileObject->FsContext2 != TDI_CONNECTION_FILE) + { + DPRINT1("File object not a connection context\n"); return STATUS_FILE_INVALID; } - AddressFile = IrpSp->FileObject->FsContext; - if (AddressFile->Protocol != IPPROTO_TCP) + Context = IrpSp->FileObject->FsContext; + if (Context->AddressFile->Protocol != IPPROTO_TCP) { DPRINT1("Received TDI_CONNECT for a non-TCP protocol\n"); return STATUS_INVALID_ADDRESS; @@ -932,10 +1069,10 @@ SocketAddressInRemote->sin_addr.s_addr, SocketAddressInRemote->sin_port); DPRINT1("\n Local Address\n Address: %08x\n Port: %04x\n", - AddressFile->ConnectionContext->lwip_tcp_pcb->local_ip, - AddressFile->ConnectionContext->lwip_tcp_pcb->local_port); - - lwip_err = tcp_connect(AddressFile->ConnectionContext->lwip_tcp_pcb, + Context->lwip_tcp_pcb->local_ip, + Context->lwip_tcp_pcb->local_port); + + lwip_err = tcp_connect(Context->lwip_tcp_pcb, (ip_addr_t *)&SocketAddressInRemote->sin_addr.s_addr, SocketAddressInRemote->sin_port, lwip_tcp_Connected_callback); @@ -978,9 +1115,12 @@ } case (ERR_OK) : { -// DPRINT1("lwip ERR_OK\n"); - PrepareIrpForCancel(Irp, CancelRequestRoutine); - tcp_arg(AddressFile->ConnectionContext->lwip_tcp_pcb, AddressFile); + PrepareIrpForCancel(Irp, CancelRequestRoutine, TCP_REQUEST_CANCEL_MODE_ABORT); + Request = CONTAINING_RECORD( + Context->RequestListHead.Blink, + TCP_REQUEST, + ListEntry); + tcp_arg(Context->lwip_tcp_pcb, Request); break; } default : @@ -1127,9 +1267,6 @@ } KeReleaseSpinLock(&AddressFile->RequestLock, OldIrql); - - IrpSp->FileObject->FsContext = AddressFile; - IrpSp->FileObject->FsContext2 = (PVOID)TDI_TRANSPORT_ADDRESS_FILE; Status = STATUS_SUCCESS; LEAVE: @@ -1144,32 +1281,23 @@ { PIO_STACK_LOCATION IrpSp; PTCP_CONTEXT Context; - PTCP_CONTEXT CurrentContext; PADDRESS_FILE AddressFile; KIRQL OldIrql; - LIST_ENTRY *Head; - LIST_ENTRY *Entry; IrpSp = IoGetCurrentIrpStackLocation(Irp); - if ((ULONG)IrpSp->FileObject->FsContext2 != TDI_TRANSPORT_ADDRESS_FILE) - { + if ((ULONG)IrpSp->FileObject->FsContext2 != TDI_CONNECTION_FILE) + { + DPRINT1("Disassociating something that is not a connection context\n"); return STATUS_FILE_INVALID; } - AddressFile = IrpSp->FileObject->FsContext; + Context = IrpSp->FileObject->FsContext; + AddressFile = Context->AddressFile; if (AddressFile->Protocol != IPPROTO_TCP) { DPRINT1("Received TDI_DISASSOCIATE_ADDRESS for non-TCP protocol\n"); return STATUS_INVALID_ADDRESS; } - - Context = AddressFile->ConnectionContext; - if (!Context) - { - DPRINT1("No connection context\n"); - return STATUS_INVALID_PARAMETER; - } - if (Context->Protocol != IPPROTO_TCP) { DPRINT1("Address File and Context have mismatching protocols\n"); @@ -1177,26 +1305,17 @@ } KeAcquireSpinLock(&AddressFile->RequestLock, &OldIrql); - - Head = &AddressFile->ConnectionContext->ListEntry; - Entry = Head->Flink; - if (Entry == Head) - { - DPRINT1("Disassociating from empty context list\n"); - KeReleaseSpinLock(&AddressFile->RequestLock, OldIrql); - return STATUS_INVALID_ADDRESS; - } - if (AddressFile->ContextCount < 1) - { - DPRINT1("Invalid ContextCount\n"); - KeReleaseSpinLock(&AddressFile->RequestLock, OldIrql); - return STATUS_INVALID_ADDRESS; - } - CurrentContext = CONTAINING_RECORD(Entry, TCP_CONTEXT, ListEntry); - RemoveEntryList(Entry); - ExFreePoolWithTag(CurrentContext, TAG_ADDRESS_FILE); + RemoveEntryList(&Context->ListEntry); + if (!IsListEmpty(&Context->RequestListHead)) + { + DPRINT1("Disassociating context with pending requests\n"); + } + if (Context->lwip_tcp_pcb != AddressFile->ConnectionContext->lwip_tcp_pcb) + { + tcp_abort(Context->lwip_tcp_pcb); + } + ExFreePoolWithTag(Context, TAG_ADDRESS_FILE); AddressFile->ContextCount--; - KeReleaseSpinLock(&AddressFile->RequestLock, OldIrql); return STATUS_SUCCESS; @@ -1211,29 +1330,31 @@ PADDRESS_FILE AddressFile; PTCP_CONTEXT ConnectionContext; + KIRQL OldIrql; + struct tcp_pcb *lpcb; IrpSp = IoGetCurrentIrpStackLocation(Irp); - /* Check this is really an address file */ - if ((ULONG_PTR)IrpSp->FileObject->FsContext2 != TDI_TRANSPORT_ADDRESS_FILE) - { - DPRINT1("Not an address file\n"); + /* Check this is really a context file */ + if ((ULONG_PTR)IrpSp->FileObject->FsContext2 != TDI_CONNECTION_FILE) + { + DPRINT1("Not a connection context\n"); return STATUS_FILE_INVALID; } - /* Get address file */ - AddressFile = IrpSp->FileObject->FsContext; - ConnectionContext = AddressFile->ConnectionContext; + /* Get context file */ + ConnectionContext = IrpSp->FileObject->FsContext; + AddressFile = ConnectionContext->AddressFile; if (ConnectionContext->Protocol != IPPROTO_TCP) { DPRINT1("Received TDI_LISTEN for a non-TCP protocol\n"); return STATUS_INVALID_ADDRESS; } - PrepareIrpForCancel(Irp, CancelRequestRoutine); - if (AddressFile->ContextCount <= 1) - { + if (AddressFile->ContextCount == 1) + { + KeAcquireSpinLock(&AddressFile->RequestLock, &OldIrql); /* Call down into lwip to initiate a listen */ lpcb = tcp_listen(ConnectionContext->lwip_tcp_pcb); DPRINT1("lwip tcp_listen returned\n"); @@ -1245,13 +1366,15 @@ DPRINT1("lwip tcp_listen error\n"); return STATUS_INVALID_ADDRESS; } - else - { - ConnectionContext->lwip_tcp_pcb = lpcb; - } + AddressFile->ConnectionContext->lwip_tcp_pcb = lpcb; + ConnectionContext->lwip_tcp_pcb = lpcb; + tcp_arg(ConnectionContext->lwip_tcp_pcb, AddressFile); tcp_accept(ConnectionContext->lwip_tcp_pcb, lwip_tcp_accept_callback); - tcp_arg(ConnectionContext->lwip_tcp_pcb, AddressFile); - } + + KeReleaseSpinLock(&AddressFile->RequestLock, OldIrql); + } + + PrepareIrpForCancel(Irp, CancelRequestRoutine, TCP_REQUEST_CANCEL_MODE_CLOSE); return STATUS_PENDING; } @@ -1262,8 +1385,8 @@ { PIO_STACK_LOCATION IrpSp; PTDI_REQUEST_KERNEL_SEND Request; - PADDRESS_FILE AddressFile; PTCP_CONTEXT Context; + PTCP_REQUEST TcpRequest; PVOID Buffer; UINT Len; @@ -1272,19 +1395,12 @@ IrpSp = IoGetCurrentIrpStackLocation(Irp); Request = (PTDI_REQUEST_KERNEL_SEND)&IrpSp->Parameters; - if (IrpSp->FileObject->FsContext2 != (PVOID)TDI_TRANSPORT_ADDRESS_FILE) - { - DPRINT1("TcpIpSend without a TDI_TRANSPORT_ADDRESS_FILE\n"); + if (IrpSp->FileObject->FsContext2 != (PVOID)TDI_CONNECTION_FILE) + { + DPRINT1("TcpIpSend without a TDI_CONNECTION_FILE\n"); return STATUS_INVALID_PARAMETER; } - AddressFile = IrpSp->FileObject->FsContext; - - if (!AddressFile->ConnectionContext) - { - DPRINT1("TcpIpSend with no TCP_CONTEXT\n"); - return STATUS_INVALID_PARAMETER; - } - Context = AddressFile->ConnectionContext; + Context = IrpSp->FileObject->FsContext; if (!Irp->MdlAddress) { @@ -1323,8 +1439,10 @@ return STATUS_NOT_IMPLEMENTED; } - PrepareIrpForCancel(Irp, CancelRequestRoutine); - tcp_arg(Context->lwip_tcp_pcb, AddressFile); + PrepareIrpForCancel(Irp, CancelRequestRoutine, TCP_REQUEST_CANCEL_MODE_ABORT); + TcpRequest = CONTAINING_RECORD(Context->RequestListHead.Blink, + TCP_REQUEST, ListEntry); + tcp_arg(Context->lwip_tcp_pcb, TcpRequest); tcp_sent(Context->lwip_tcp_pcb, lwip_tcp_sent_callback); return STATUS_PENDING; @@ -1335,39 +1453,39 @@ _Inout_ PIRP Irp) { PIO_STACK_LOCATION IrpSp; - PADDRESS_FILE AddressFile; PTCP_CONTEXT Context; + PTCP_REQUEST Request; PTDI_REQUEST_KERNEL_RECEIVE RequestInfo; IrpSp = IoGetCurrentIrpStackLocation(Irp); - if (IrpSp->FileObject->FsContext2 != (PVOID)TDI_TRANSPORT_ADDRESS_FILE) + if (IrpSp->FileObject->FsContext2 != (PVOID)TDI_CONNECTION_FILE) { DPRINT1("TcpIpReceive on something that is not an address file\n"); return STATUS_INVALID_PARAMETER; } - AddressFile = IrpSp->FileObject->FsContext; - - if (!AddressFile->ConnectionContext) - { - DPRINT1("Receiving on TCP address file with no connection context\n"); - return STATUS_INVALID_ADDRESS; - } - Context = AddressFile->ConnectionContext; + Context = IrpSp->FileObject->FsContext; if (!Context->lwip_tcp_pcb) { DPRINT1("Connection context does not contain a lwIP tcp_pcb\n"); return STATUS_INVALID_ADDRESS; } + if (Context->lwip_tcp_pcb == Context->AddressFile->ConnectionContext->lwip_tcp_pcb) + { + DPRINT1("Has the pcb been assigned by a lwIP callback?\n"); + return STATUS_INVALID_ADDRESS; + } RequestInfo = (PTDI_REQUEST_KERNEL_RECEIVE)&IrpSp->Parameters; DPRINT1("\n Request Length = %d\n", RequestInfo->ReceiveLength); - PrepareIrpForCancel(Irp, CancelRequestRoutine); + PrepareIrpForCancel(Irp, CancelRequestRoutine, TCP_REQUEST_CANCEL_MODE_CLOSE); + Request = CONTAINING_RECORD(Context->RequestListHead.Blink, + TCP_REQUEST, ListEntry); + tcp_arg(Context->lwip_tcp_pcb, Request); tcp_recv(Context->lwip_tcp_pcb, lwip_tcp_receive_callback); - tcp_arg(Context->lwip_tcp_pcb, AddressFile); return STATUS_PENDING; } Modified: branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/address.h URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/lwIP-tcpip/drivers/ne…
============================================================================== --- branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/address.h [iso-8859-1] (original) +++ branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/address.h [iso-8859-1] Thu Jun 23 15:28:39 2016 @@ -1,5 +1,8 @@ #pragma once + +#define TCP_REQUEST_CANCEL_MODE_ABORT 1 +#define TCP_REQUEST_CANCEL_MODE_CLOSE 2 typedef struct _ADDRESS_FILE { LIST_ENTRY ListEntry; @@ -23,9 +26,15 @@ PADDRESS_FILE AddressFile; IPPROTO Protocol; TDI_ADDRESS_IP RequestAddress; - PIRP PendingIrp; + LIST_ENTRY RequestListHead; struct tcp_pcb* lwip_tcp_pcb; } TCP_CONTEXT, *PTCP_CONTEXT; + +typedef struct _TCP_REQUEST { + LIST_ENTRY ListEntry; + PIRP PendingIrp; + UCHAR CancelMode; +} TCP_REQUEST, *PTCP_REQUEST; void TcpIpInitializeAddresses(void); Modified: branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/main.c URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/lwIP-tcpip/drivers/ne…
============================================================================== --- branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/main.c [iso-8859-1] (original) +++ branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/main.c [iso-8859-1] Thu Jun 23 15:28:39 2016 @@ -346,6 +346,7 @@ ) { PIO_STACK_LOCATION IrpSp; + PTCP_CONTEXT Context; NTSTATUS Status; ULONG_PTR FileType; @@ -366,6 +367,11 @@ } Status = TcpIpCloseAddress(IrpSp->FileObject->FsContext); break; + case TDI_CONNECTION_FILE: + DPRINT1("TCPIP Close Connection Context\n"); + Context = IrpSp->FileObject->FsContext; + Status = TcpIpCloseAddress(Context->AddressFile); + break; case TDI_CONTROL_CHANNEL_FILE: /* We didn't allocate anything for this. */ Status = STATUS_SUCCESS; @@ -394,13 +400,26 @@ { NTSTATUS Status; PIO_STACK_LOCATION IrpSp; + PTCP_CONTEXT Context; PADDRESS_FILE AddressFile; DPRINT1("TcpIpDispatchInternal\n"); IrpSp = IoGetCurrentIrpStackLocation(Irp); - AddressFile = IrpSp->FileObject->FsContext; + switch ((ULONG)IrpSp->FileObject->FsContext2) + { + case TDI_TRANSPORT_ADDRESS_FILE : + AddressFile = IrpSp->FileObject->FsContext; + break; + case TDI_CONNECTION_FILE : + Context = IrpSp->FileObject->FsContext; + AddressFile = Context->AddressFile; + break; + default : + DPRINT1("Unknown FileObject type\n"); + break; + } switch (IrpSp->MinorFunction) { @@ -423,7 +442,6 @@ if (Status == STATUS_NOT_IMPLEMENTED) { DPRINT1("Received TDI_RECEIVE for non-TCP protocol\n"); - } break; case TDI_RECEIVE_DATAGRAM: Modified: branches/GSoC_2016/lwIP-tcpip/sdk/lib/drivers/lwip/src/include/lwip/opt.h URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/lwIP-tcpip/sdk/lib/dr…
============================================================================== --- branches/GSoC_2016/lwIP-tcpip/sdk/lib/drivers/lwip/src/include/lwip/opt.h [iso-8859-1] (original) +++ branches/GSoC_2016/lwIP-tcpip/sdk/lib/drivers/lwip/src/include/lwip/opt.h [iso-8859-1] Thu Jun 23 15:28:39 2016 @@ -1023,7 +1023,7 @@ * TCP_LISTEN_BACKLOG: Enable the backlog option for tcp listen pcb. */ #ifndef TCP_LISTEN_BACKLOG -#define TCP_LISTEN_BACKLOG 0 +#define TCP_LISTEN_BACKLOG 1 #endif /**
8 years, 7 months
1
0
0
0
[tthompson] 71660: [NTFS] When writing to a file, increase the file size if trying to write past the end. *FindAttribute() has been given an optional pointer to a ULONG that will receive the offset...
by tthompson@svn.reactos.org
Author: tthompson Date: Wed Jun 22 21:20:50 2016 New Revision: 71660 URL:
http://svn.reactos.org/svn/reactos?rev=71660&view=rev
Log: [NTFS] When writing to a file, increase the file size if trying to write past the end. *FindAttribute() has been given an optional pointer to a ULONG that will receive the offset of the found attribute from the beginning of the record. This is to allow for found attributes to be written back into their file records. +SetAttributeDataLength() +UpdateFileRecord() - Updates a file record in the master file table at a given index. +AddFixupArray() - Prepares a file record or directory index for writing to the disk. Modified: branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/attrib.c branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/dirctl.c branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/fcb.c branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/fsctl.c branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/mft.c branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/ntfs.h branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/rw.c branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/volinfo.c Modified: branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/attrib.c URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/NTFS/drivers/filesyst…
============================================================================== --- branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/attrib.c [iso-8859-1] (original) +++ branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/attrib.c [iso-8859-1] Wed Jun 22 21:20:50 2016 @@ -150,6 +150,8 @@ PNTFS_ATTR_RECORD InternalGetNextAttribute(PFIND_ATTR_CONTXT Context) { + PNTFS_ATTR_RECORD NextAttribute; + if (Context->CurrAttr == (PVOID)-1) { return NULL; @@ -165,7 +167,10 @@ return NULL; } - Context->CurrAttr = (PNTFS_ATTR_RECORD)((ULONG_PTR)Context->CurrAttr + Context->CurrAttr->Length); + NextAttribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)Context->CurrAttr + Context->CurrAttr->Length); + Context->Offset += ((ULONG_PTR)NextAttribute - (ULONG_PTR)Context->CurrAttr); + Context->CurrAttr = NextAttribute; + if (Context->CurrAttr < Context->LastAttr && Context->CurrAttr->Type != AttributeEnd) { @@ -186,7 +191,9 @@ } else if (Context->CurrAttr->Length != 0) { - Context->CurrAttr = (PNTFS_ATTR_RECORD)((ULONG_PTR)Context->CurrAttr + Context->CurrAttr->Length); + NextAttribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)Context->CurrAttr + Context->CurrAttr->Length); + Context->Offset += ((ULONG_PTR)NextAttribute - (ULONG_PTR)Context->CurrAttr); + Context->CurrAttr = NextAttribute; } else { @@ -223,6 +230,7 @@ Context->LastAttr = (PNTFS_ATTR_RECORD)((ULONG_PTR)FileRecord + FileRecord->BytesInUse); Context->NonResidentStart = NULL; Context->NonResidentEnd = NULL; + Context->Offset = FileRecord->AttributeOffset; if (Context->FirstAttr->Type == AttributeEnd) { @@ -246,6 +254,7 @@ else { *Attribute = Context->CurrAttr; + Context->Offset = (UCHAR*)Context->CurrAttr - (UCHAR*)FileRecord; } return STATUS_SUCCESS; @@ -307,7 +316,8 @@ FileNameAttr = (PFILENAME_ATTRIBUTE)((ULONG_PTR)Attribute + Attribute->Resident.ValueOffset); DbgPrint(" (%x) '%.*S' ", FileNameAttr->NameType, FileNameAttr->NameLength, FileNameAttr->Name); - DbgPrint(" '%x' ", FileNameAttr->FileAttributes); + DbgPrint(" '%x' \n", FileNameAttr->FileAttributes); + DbgPrint(" AllocatedSize: %I64u\nDataSize: %I64u\n", FileNameAttr->AllocatedSize, FileNameAttr->DataSize); } @@ -481,8 +491,8 @@ { FindRun(Attribute,0,&lcn, &runcount); - DbgPrint(" AllocatedSize %I64u DataSize %I64u\n", - Attribute->NonResident.AllocatedSize, Attribute->NonResident.DataSize); + DbgPrint(" AllocatedSize %I64u DataSize %I64u InitilizedSize %I64u\n", + Attribute->NonResident.AllocatedSize, Attribute->NonResident.DataSize, Attribute->NonResident.InitializedSize); DbgPrint(" logical clusters: %I64u - %I64u\n", lcn, lcn + runcount - 1); } Modified: branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/dirctl.c URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/NTFS/drivers/filesyst…
============================================================================== --- branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/dirctl.c [iso-8859-1] (original) +++ branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/dirctl.c [iso-8859-1] Wed Jun 22 21:20:50 2016 @@ -47,7 +47,7 @@ NTSTATUS Status; PNTFS_ATTR_CONTEXT DataContext; - Status = FindAttribute(DeviceExt, FileRecord, AttributeData, Stream, StreamLength, &DataContext); + Status = FindAttribute(DeviceExt, FileRecord, AttributeData, Stream, StreamLength, &DataContext, NULL); if (NT_SUCCESS(Status)) { Size = AttributeDataLength(&DataContext->Record); Modified: branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/fcb.c URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/NTFS/drivers/filesyst…
============================================================================== --- branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/fcb.c [iso-8859-1] (original) +++ branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/fcb.c [iso-8859-1] Wed Jun 22 21:20:50 2016 @@ -568,7 +568,7 @@ } else if (Colon != 0) { - Status = FindAttribute(Vcb, FileRecord, AttributeData, Colon, wcslen(Colon), &DataContext); + Status = FindAttribute(Vcb, FileRecord, AttributeData, Colon, wcslen(Colon), &DataContext, NULL); if (!NT_SUCCESS(Status)) { return STATUS_OBJECT_NAME_NOT_FOUND; @@ -741,7 +741,7 @@ return Status; } - Status = FindAttribute(Vcb, FileRecord, Type, Name, NameLength, &AttrCtxt); + Status = FindAttribute(Vcb, FileRecord, Type, Name, NameLength, &AttrCtxt, NULL); if (!NT_SUCCESS(Status)) { ExFreePoolWithTag(FileRecord, TAG_NTFS); Modified: branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/fsctl.c URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/NTFS/drivers/filesyst…
============================================================================== --- branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/fsctl.c [iso-8859-1] (original) +++ branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/fsctl.c [iso-8859-1] Wed Jun 22 21:20:50 2016 @@ -295,7 +295,7 @@ return Status; } - Status = FindAttribute(DeviceExt, DeviceExt->MasterFileTable, AttributeData, L"", 0, &DeviceExt->MFTContext); + Status = FindAttribute(DeviceExt, DeviceExt->MasterFileTable, AttributeData, L"", 0, &DeviceExt->MFTContext, NULL); if (!NT_SUCCESS(Status)) { DPRINT1("Can't find data attribute for Master File Table.\n"); @@ -333,7 +333,7 @@ NtfsDumpFileAttributes(DeviceExt, VolumeRecord); /* Get volume name */ - Status = FindAttribute(DeviceExt, VolumeRecord, AttributeVolumeName, L"", 0, &AttrCtxt); + Status = FindAttribute(DeviceExt, VolumeRecord, AttributeVolumeName, L"", 0, &AttrCtxt, NULL); if (NT_SUCCESS(Status) && AttrCtxt->Record.Resident.ValueLength != 0) { @@ -374,7 +374,7 @@ DeviceExt->VolumeFcb = VolumeFcb; /* Get volume information */ - Status = FindAttribute(DeviceExt, VolumeRecord, AttributeVolumeInformation, L"", 0, &AttrCtxt); + Status = FindAttribute(DeviceExt, VolumeRecord, AttributeVolumeInformation, L"", 0, &AttrCtxt, NULL); if (NT_SUCCESS(Status) && AttrCtxt->Record.Resident.ValueLength != 0) { @@ -804,7 +804,7 @@ return Status; } - Status = FindAttribute(DeviceExt, BitmapRecord, AttributeData, L"", 0, &DataContext); + Status = FindAttribute(DeviceExt, BitmapRecord, AttributeData, L"", 0, &DataContext, NULL); if (!NT_SUCCESS(Status)) { DPRINT1("Failed find $DATA for bitmap: %lx\n", Status); Modified: branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/mft.c URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/NTFS/drivers/filesyst…
============================================================================== --- branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/mft.c [iso-8859-1] (original) +++ branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/mft.c [iso-8859-1] Wed Jun 22 21:20:50 2016 @@ -81,13 +81,24 @@ } +/** +* @name FindAttribute +* @implemented +* +* Searches a file record for an attribute matching the given type and name. +* +* @param Offset +* Optional pointer to a ULONG that will receive the offset of the found attribute +* from the beginning of the record. Can be set to NULL. +*/ NTSTATUS FindAttribute(PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER MftRecord, ULONG Type, PCWSTR Name, ULONG NameLength, - PNTFS_ATTR_CONTEXT * AttrCtx) + PNTFS_ATTR_CONTEXT * AttrCtx, + PULONG Offset) { BOOLEAN Found; NTSTATUS Status; @@ -123,6 +134,10 @@ /* Found it, fill up the context and return. */ DPRINT("Found context\n"); *AttrCtx = PrepareAttributeContext(Attribute); + + if (Offset != NULL) + *Offset = Context.Offset; + FindCloseAttribute(&Context); return STATUS_SUCCESS; } @@ -155,6 +170,61 @@ return AttrRecord->Resident.ValueLength; } + +NTSTATUS +SetAttributeDataLength(PFILE_OBJECT FileObject, + PNTFS_FCB Fcb, + PNTFS_ATTR_CONTEXT AttrContext, + ULONG AttrOffset, + PFILE_RECORD_HEADER FileRecord, + PDEVICE_EXTENSION DeviceExt, + PLARGE_INTEGER DataSize) +{ + if (AttrContext->Record.IsNonResident) + { + // do we need to increase the allocation size? + if (AttrContext->Record.NonResident.AllocatedSize < DataSize->QuadPart) + { + DPRINT1("FixMe: Increasing allocation size is unimplemented!\n"); + return STATUS_NOT_IMPLEMENTED; + } + + // TODO: is the file compressed, encrypted, or sparse? + + // NOTE: we need to have acquired the main resource exclusively, as well as(?) the PagingIoResource + + // TODO: update the allocated size on-disk + DPRINT("Allocated Size: %I64u\n", AttrContext->Record.NonResident.AllocatedSize); + + AttrContext->Record.NonResident.DataSize = DataSize->QuadPart; + AttrContext->Record.NonResident.InitializedSize = DataSize->QuadPart; + + Fcb->RFCB.FileSize = *DataSize; + Fcb->RFCB.ValidDataLength = *DataSize; + + DPRINT("Data Size: %I64u\n", Fcb->RFCB.FileSize.QuadPart); + + //NtfsDumpFileAttributes(Fcb->Vcb, FileRecord); + + // copy the attribute back into the FileRecord + RtlCopyMemory((PCHAR)FileRecord + AttrOffset, &AttrContext->Record, AttrContext->Record.Length); + + //NtfsDumpFileAttributes(Fcb->Vcb, FileRecord); + + // write the updated file record back to disk + UpdateFileRecord(Fcb->Vcb, Fcb->MFTIndex, FileRecord); + + CcSetFileSizes(FileObject, (PCC_FILE_SIZES)&Fcb->RFCB.AllocationSize); + } + else + { + // we can't yet handle resident attributes + DPRINT1("FixMe: Can't handle increasing length of resident attribute\n"); + return STATUS_NOT_IMPLEMENTED; + } + + return STATUS_SUCCESS; +} ULONG ReadAttribute(PDEVICE_EXTENSION Vcb, @@ -615,8 +685,39 @@ return FixupUpdateSequenceArray(Vcb, &file->Ntfs); } - -NTSTATUS +/** +* UpdateFileRecord +* @implemented +* Writes a file record to the master file table, at a given index. +*/ +NTSTATUS +UpdateFileRecord(PDEVICE_EXTENSION Vcb, + ULONGLONG index, + PFILE_RECORD_HEADER file) +{ + ULONG BytesWritten; + NTSTATUS Status = STATUS_SUCCESS; + + DPRINT("UpdateFileRecord(%p, %I64x, %p)\n", Vcb, index, file); + + // Add the fixup array to prepare the data for writing to disk + AddFixupArray(Vcb, file); + + // write the file record to the master file table + Status = WriteAttribute(Vcb, Vcb->MFTContext, index * Vcb->NtfsInfo.BytesPerFileRecord, (const PUCHAR)file, Vcb->NtfsInfo.BytesPerFileRecord, &BytesWritten); + + // TODO: Update MFT mirror + + if (!NT_SUCCESS(Status)) + { + DPRINT1("UpdateFileRecord failed: %I64u written, %u expected\n", BytesWritten, Vcb->NtfsInfo.BytesPerFileRecord); + } + + return Status; +} + + +NTSTATUS FixupUpdateSequenceArray(PDEVICE_EXTENSION Vcb, PNTFS_RECORD_HEADER Record) { @@ -630,6 +731,8 @@ USACount = Record->UsaCount - 1; /* Exclude the USA Number. */ Block = (USHORT*)((PCHAR)Record + Vcb->NtfsInfo.BytesPerSector - 2); + DPRINT("FixupUpdateSequenceArray(%p, %p)\nUSANumber: %u\tUSACount: %u\n", Vcb, Record, USANumber, USACount); + while (USACount) { if (*Block != USANumber) @@ -645,6 +748,36 @@ return STATUS_SUCCESS; } +NTSTATUS +AddFixupArray(PDEVICE_EXTENSION Vcb, + PFILE_RECORD_HEADER Record) +{ + USHORT *pShortToFixUp; + unsigned int ArrayEntryCount = Record->BytesAllocated / Vcb->NtfsInfo.BytesPerSector; + unsigned int Offset = Vcb->NtfsInfo.BytesPerSector - 2; + int i; + + PFIXUP_ARRAY fixupArray = (PFIXUP_ARRAY)((UCHAR*)Record + Record->Ntfs.UsaOffset); + + DPRINT("AddFixupArray(%p, %p)\n fixupArray->USN: %u, ArrayEntryCount: %u\n", Vcb, Record, fixupArray->USN, ArrayEntryCount); + + if (Record->BytesAllocated % Vcb->NtfsInfo.BytesPerSector != 0) + ArrayEntryCount++; + + fixupArray->USN++; + + for (i = 0; i < ArrayEntryCount; i++) + { + DPRINT("USN: %u\tOffset: %u\n", fixupArray->USN, Offset); + + pShortToFixUp = (USHORT*)((UCHAR*)Record + Offset); + fixupArray->Array[i] = *pShortToFixUp; + *pShortToFixUp = fixupArray->USN; + Offset += Vcb->NtfsInfo.BytesPerSector; + } + + return STATUS_SUCCESS; +} NTSTATUS ReadLCN(PDEVICE_EXTENSION Vcb, @@ -783,7 +916,7 @@ return STATUS_OBJECT_PATH_NOT_FOUND; } - Status = FindAttribute(Vcb, MftRecord, AttributeIndexAllocation, L"$I30", 4, &IndexAllocationCtx); + Status = FindAttribute(Vcb, MftRecord, AttributeIndexAllocation, L"$I30", 4, &IndexAllocationCtx, NULL); if (!NT_SUCCESS(Status)) { DPRINT("Corrupted filesystem!\n"); @@ -853,7 +986,7 @@ } ASSERT(MftRecord->Ntfs.Type == NRH_FILE_TYPE); - Status = FindAttribute(Vcb, MftRecord, AttributeIndexRoot, L"$I30", 4, &IndexRootCtx); + Status = FindAttribute(Vcb, MftRecord, AttributeIndexRoot, L"$I30", 4, &IndexRootCtx, NULL); if (!NT_SUCCESS(Status)) { ExFreePoolWithTag(MftRecord, TAG_NTFS); Modified: branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/ntfs.h URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/NTFS/drivers/filesyst…
============================================================================== --- branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/ntfs.h [iso-8859-1] (original) +++ branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/ntfs.h [iso-8859-1] Wed Jun 22 21:20:50 2016 @@ -483,7 +483,14 @@ PNTFS_ATTR_RECORD LastAttr; PNTFS_ATTR_RECORD NonResidentStart; PNTFS_ATTR_RECORD NonResidentEnd; + ULONG Offset; } FIND_ATTR_CONTXT, *PFIND_ATTR_CONTXT; + +typedef struct +{ + USHORT USN; + USHORT Array[]; +} FIXUP_ARRAY, *PFIXUP_ARRAY; extern PNTFS_GLOBAL_DATA NtfsGlobalData; @@ -555,7 +562,7 @@ IN LONGLONG StartingOffset, IN ULONG Length, IN ULONG SectorSize, - IN PUCHAR Buffer); + IN const PUCHAR Buffer); NTSTATUS NtfsReadSectors(IN PDEVICE_OBJECT DeviceObject, @@ -759,6 +766,15 @@ ULONGLONG AttributeDataLength(PNTFS_ATTR_RECORD AttrRecord); +NTSTATUS +SetAttributeDataLength(PFILE_OBJECT FileObject, + PNTFS_FCB Fcb, + PNTFS_ATTR_CONTEXT AttrContext, + ULONG AttrOffset, + PFILE_RECORD_HEADER FileRecord, + PDEVICE_EXTENSION DeviceExt, + PLARGE_INTEGER DataSize); + ULONG AttributeAllocatedLength(PNTFS_ATTR_RECORD AttrRecord); @@ -766,6 +782,11 @@ ReadFileRecord(PDEVICE_EXTENSION Vcb, ULONGLONG index, PFILE_RECORD_HEADER file); + +NTSTATUS +UpdateFileRecord(PDEVICE_EXTENSION Vcb, + ULONGLONG index, + PFILE_RECORD_HEADER file); NTSTATUS FindAttribute(PDEVICE_EXTENSION Vcb, @@ -773,7 +794,8 @@ ULONG Type, PCWSTR Name, ULONG NameLength, - PNTFS_ATTR_CONTEXT * AttrCtx); + PNTFS_ATTR_CONTEXT * AttrCtx, + PULONG Offset); VOID ReadVCN(PDEVICE_EXTENSION Vcb, @@ -788,6 +810,10 @@ PNTFS_RECORD_HEADER Record); NTSTATUS +AddFixupArray(PDEVICE_EXTENSION Vcb, + PFILE_RECORD_HEADER Record); + +NTSTATUS ReadLCN(PDEVICE_EXTENSION Vcb, ULONGLONG lcn, ULONG count, Modified: branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/rw.c URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/NTFS/drivers/filesyst…
============================================================================== --- branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/rw.c [iso-8859-1] (original) +++ branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/rw.c [iso-8859-1] Wed Jun 22 21:20:50 2016 @@ -95,7 +95,7 @@ } - Status = FindAttribute(DeviceExt, FileRecord, AttributeData, Fcb->Stream, wcslen(Fcb->Stream), &DataContext); + Status = FindAttribute(DeviceExt, FileRecord, AttributeData, Fcb->Stream, wcslen(Fcb->Stream), &DataContext, NULL); if (!NT_SUCCESS(Status)) { NTSTATUS BrowseStatus; @@ -306,6 +306,7 @@ PNTFS_FCB Fcb; PFILE_RECORD_HEADER FileRecord; PNTFS_ATTR_CONTEXT DataContext; + ULONG AttributeOffset; ULONGLONG StreamSize; DPRINT("NtfsWriteFile(%p, %p, %p, %u, %u, %x, %p)\n", DeviceExt, FileObject, Buffer, Length, WriteOffset, IrpFlags, LengthWritten); @@ -358,9 +359,10 @@ DPRINT("Found record for %wS\n", Fcb->ObjectName); - // Find the attribute (in the NTFS sense of the word) with the data stream for our file + // Find the attribute with the data stream for our file DPRINT("Finding Data Attribute...\n"); - Status = FindAttribute(DeviceExt, FileRecord, AttributeData, Fcb->Stream, wcslen(Fcb->Stream), &DataContext); + Status = FindAttribute(DeviceExt, FileRecord, AttributeData, Fcb->Stream, wcslen(Fcb->Stream), &DataContext, + &AttributeOffset); // Did we fail to find the attribute? if (!NT_SUCCESS(Status)) @@ -402,13 +404,39 @@ // Are we trying to write beyond the end of the stream? if (WriteOffset + Length > StreamSize) { - // TODO: allocate additional clusters as needed and expand stream - DPRINT1("WriteOffset: %lu\tLength: %lu\tStreamSize: %I64u\n", WriteOffset, Length, StreamSize); - DPRINT1("TODO: Stream embiggening (appending files) is not yet supported!\n"); - ReleaseAttributeContext(DataContext); - ExFreePoolWithTag(FileRecord, TAG_NTFS); - *LengthWritten = 0; // We didn't write anything - return STATUS_ACCESS_DENIED; // temporarily; we don't change file sizes yet + // is increasing the stream size allowed? + if (!(Fcb->Flags & FCB_IS_VOLUME) && + !(IrpFlags & IRP_PAGING_IO)) + { + LARGE_INTEGER DataSize; + ULONGLONG AllocationSize; + + DataSize.QuadPart = WriteOffset + Length; + + AllocationSize = ROUND_UP(DataSize.QuadPart, Fcb->Vcb->NtfsInfo.BytesPerCluster); + + // set the attribute data length + Status = SetAttributeDataLength(FileObject, Fcb, DataContext, AttributeOffset, FileRecord, DeviceExt, &DataSize); + + if (!NT_SUCCESS(Status)) + { + ReleaseAttributeContext(DataContext); + ExFreePoolWithTag(FileRecord, TAG_NTFS); + *LengthWritten = 0; + return Status; + } + + // now we need to update this file's size in every directory index entry that references it + // (saved for a later commit) + } + else + { + // TODO - just fail for now + ReleaseAttributeContext(DataContext); + ExFreePoolWithTag(FileRecord, TAG_NTFS); + *LengthWritten = 0; + return STATUS_ACCESS_DENIED; + } } DPRINT("Length: %lu\tWriteOffset: %lu\tStreamSize: %I64u\n", Length, WriteOffset, StreamSize); Modified: branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/volinfo.c URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/NTFS/drivers/filesyst…
============================================================================== --- branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/volinfo.c [iso-8859-1] (original) +++ branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/volinfo.c [iso-8859-1] Wed Jun 22 21:20:50 2016 @@ -62,7 +62,7 @@ return 0; } - Status = FindAttribute(DeviceExt, BitmapRecord, AttributeData, L"", 0, &DataContext); + Status = FindAttribute(DeviceExt, BitmapRecord, AttributeData, L"", 0, &DataContext, NULL); if (!NT_SUCCESS(Status)) { ExFreePoolWithTag(BitmapRecord, TAG_NTFS);
8 years, 7 months
1
0
0
0
[apriyadarshi] 71659: Implemented AhciBuild_PRDT
by apriyadarshi@svn.reactos.org
Author: apriyadarshi Date: Wed Jun 22 16:08:45 2016 New Revision: 71659 URL:
http://svn.reactos.org/svn/reactos?rev=71659&view=rev
Log: Implemented AhciBuild_PRDT Modified: branches/GSoC_2016/AHCI/drivers/storage/storahci/Notes.txt branches/GSoC_2016/AHCI/drivers/storage/storahci/storahci.c branches/GSoC_2016/AHCI/drivers/storage/storahci/storahci.h Modified: branches/GSoC_2016/AHCI/drivers/storage/storahci/Notes.txt URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/AHCI/drivers/storage/…
============================================================================== --- branches/GSoC_2016/AHCI/drivers/storage/storahci/Notes.txt [iso-8859-1] (original) +++ branches/GSoC_2016/AHCI/drivers/storage/storahci/Notes.txt [iso-8859-1] Wed Jun 22 16:08:45 2016 @@ -82,9 +82,9 @@ AhciBuild_PRDT Flags - NOT_IMPLEMENTED + IMPLEMENTED Comment - Need to configure command table according to Srb function + NONE AhciProcessSrb Flags Modified: branches/GSoC_2016/AHCI/drivers/storage/storahci/storahci.c URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/AHCI/drivers/storage/…
============================================================================== --- branches/GSoC_2016/AHCI/drivers/storage/storahci/storahci.c [iso-8859-1] (original) +++ branches/GSoC_2016/AHCI/drivers/storage/storahci/storahci.c [iso-8859-1] Wed Jun 22 16:08:45 2016 @@ -259,7 +259,7 @@ // software should perform the appropriate error recovery actions based on whether // non-queued commands were being issued or native command queuing commands were being issued. - DebugPrint("\tFata Error: %x\n", PxIS.Status); + DebugPrint("\tFatal Error: %x\n", PxIS.Status); } // Normal Command Completion @@ -781,7 +781,7 @@ /** * @name AhciBuild_PRDT - * @not_implemented + * @implemented * * Build PRDT for data transfer * @@ -797,9 +797,32 @@ __in PAHCI_SRB_EXTENSION SrbExtension ) { + ULONG index; + PAHCI_COMMAND_TABLE cmdTable; + PLOCAL_SCATTER_GATHER_LIST sgl; + PAHCI_ADAPTER_EXTENSION AdapterExtension; + DebugPrint("AhciBuild_PRDT()\n"); - return -1; + sgl = &SrbExtension->Sgl; + cmdTable = (PAHCI_COMMAND_TABLE)SrbExtension; + AdapterExtension = PortExtension->AdapterExtension; + + NT_ASSERT(sgl != NULL); + NT_ASSERT(sgl->NumberOfElements < MAXIMUM_AHCI_PRDT_ENTRIES); + + for (index = 0; index < sgl->NumberOfElements; index++) + { + NT_ASSERT(sgl->List[index].Length <= MAXIMUM_TRANSFER_LENGTH); + + cmdTable->PRDT[index].DBA = sgl->List[index].PhysicalAddress.LowPart; + if (IsAdapterCAPS64(AdapterExtension->CAP)) + { + cmdTable->PRDT[index].DBAU = sgl->List[index].PhysicalAddress.HighPart; + } + } + + return sgl->NumberOfElements; }// -- AhciBuild_PRDT(); /** @@ -830,24 +853,24 @@ NT_ASSERT(Srb->PathId == PortExtension->PortNumber); - SrbExtension = Srb->SrbExtension; + SrbExtension = GetSrbExtension(Srb); AdapterExtension = PortExtension->AdapterExtension; NT_ASSERT(SrbExtension != NULL); NT_ASSERT(SrbExtension->AtaFunction != 0); if ((SrbExtension->AtaFunction == ATA_FUNCTION_ATA_IDENTIFY) && - (SrbExtension->Task.CommandReg == IDE_COMMAND_NOT_VALID)) + (SrbExtension->CommandReg == IDE_COMMAND_NOT_VALID)) { // Here we are safe to check SIG register sig = StorPortReadRegisterUlong(AdapterExtension, &PortExtension->Port->SIG); if (sig == 0x101) { - SrbExtension->Task.CommandReg = IDE_COMMAND_IDENTIFY; + SrbExtension->CommandReg = IDE_COMMAND_IDENTIFY; } else { - SrbExtension->Task.CommandReg = IDE_COMMAND_ATAPI_IDENTIFY; + SrbExtension->CommandReg = IDE_COMMAND_ATAPI_IDENTIFY; } } @@ -992,7 +1015,7 @@ tmpSrb = RemoveQueue(&PortExtension->SrbQueue); if (tmpSrb != NULL) { - NT_ASSERT(Srb->PathId == PathId); + NT_ASSERT(tmpSrb->PathId == PathId); AhciProcessSrb(PortExtension, tmpSrb, slotIndex); } else @@ -1045,7 +1068,7 @@ DebugPrint("DeviceInquiryRequest()\n"); - SrbExtension = Srb->SrbExtension; + SrbExtension = GetSrbExtension(Srb); // 3.6.1 // If the EVPD bit is set to zero, the device server shall return the standard INQUIRY data @@ -1055,7 +1078,7 @@ NT_ASSERT(SrbExtension != NULL); SrbExtension->AtaFunction = ATA_FUNCTION_ATA_IDENTIFY; - SrbExtension->Task.CommandReg = IDE_COMMAND_NOT_VALID; + SrbExtension->CommandReg = IDE_COMMAND_NOT_VALID; } else { @@ -1211,7 +1234,7 @@ NT_ASSERT(Queue->Head < MAXIMUM_QUEUE_BUFFER_SIZE); NT_ASSERT(Queue->Tail < MAXIMUM_QUEUE_BUFFER_SIZE); - if (Queue->Head == ((Queue->Tail + 1) % MAXIMUM_QUEUE_BUFFER_SIZE)) + if (Queue->Tail == ((Queue->Head + 1) % MAXIMUM_QUEUE_BUFFER_SIZE)) return FALSE; Queue->Buffer[Queue->Head++] = Srb; @@ -1251,3 +1274,34 @@ return Srb; }// -- RemoveQueue(); + +/** + * @name GetSrbExtension + * @implemented + * + * GetSrbExtension from Srb make sure It is properly aligned + * + * @param Srb + * + * @return + * return SrbExtension + * + */ +__inline +PAHCI_SRB_EXTENSION +GetSrbExtension ( + __in PSCSI_REQUEST_BLOCK Srb + ) +{ + ULONG Offset; + ULONG_PTR SrbExtension; + + SrbExtension = Srb->SrbExtension; + Offset = SrbExtension % 128; + + // CommandTable should be 128 byte aligned + if (Offset != 0) + Offset = 128 - Offset; + + return (PAHCI_SRB_EXTENSION)(SrbExtension + Offset); +}// -- PAHCI_SRB_EXTENSION(); Modified: branches/GSoC_2016/AHCI/drivers/storage/storahci/storahci.h URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/AHCI/drivers/storage/…
============================================================================== --- branches/GSoC_2016/AHCI/drivers/storage/storahci/storahci.h [iso-8859-1] (original) +++ branches/GSoC_2016/AHCI/drivers/storage/storahci/storahci.h [iso-8859-1] Wed Jun 22 16:08:45 2016 @@ -12,6 +12,7 @@ #define DEBUG 1 #define MAXIMUM_AHCI_PORT_COUNT 25 +#define MAXIMUM_AHCI_PRDT_ENTRIES 32 #define MAXIMUM_QUEUE_BUFFER_SIZE 255 #define MAXIMUM_TRANSFER_LENGTH (128*1024) // 128 KB @@ -202,6 +203,28 @@ ULONG Status; } AHCI_COMMAND_HEADER_DESCRIPTION; +typedef struct _AHCI_PRDT +{ + ULONG DBA; + ULONG DBAU; + ULONG RSV0; + + ULONG DBC : 22; + ULONG RSV1 : 9; + ULONG I : 1; +} AHCI_PRDT, *PAHCI_PRDT; + +// 4.2.3 Command Table +typedef struct _AHCI_COMMAND_TABLE +{ + // (16 * 32) + 64 + 16 + 48 = 648 + // 128 byte aligned :D + UCHAR CFIS[64]; + UCHAR ACMD[16]; + UCHAR RSV0[48]; + AHCI_PRDT PRDT[MAXIMUM_AHCI_PRDT_ENTRIES]; +} AHCI_COMMAND_TABLE, *PAHCI_COMMAND_TABLE; + // 4.2.2 Command Header typedef struct _AHCI_COMMAND_HEADER { @@ -318,19 +341,21 @@ AHCI_PORT_EXTENSION PortExtension[MAXIMUM_AHCI_PORT_COUNT]; } AHCI_ADAPTER_EXTENSION, *PAHCI_ADAPTER_EXTENSION; -typedef struct _ATA_REGISTER -{ - UCHAR CommandReg; - ULONG Reserved; -} ATA_REGISTER; +typedef struct _LOCAL_SCATTER_GATHER_LIST +{ + ULONG NumberOfElements; + ULONG_PTR Reserved; + STOR_SCATTER_GATHER_ELEMENT List[MAXIMUM_AHCI_PRDT_ENTRIES]; +} LOCAL_SCATTER_GATHER_LIST, *PLOCAL_SCATTER_GATHER_LIST; typedef struct _AHCI_SRB_EXTENSION { + AHCI_COMMAND_TABLE CommandTable; ULONG AtaFunction; ULONG Flags; - ATA_REGISTER Task; + ULONG CommandReg; ULONG SlotIndex; - ULONG Reserved[4]; + LOCAL_SCATTER_GATHER_LIST Sgl; } AHCI_SRB_EXTENSION, *PAHCI_SRB_EXTENSION; ////////////////////////////////////////////////////////////// @@ -375,3 +400,9 @@ RemoveQueue ( __inout PAHCI_QUEUE Queue ); + +__inline +PAHCI_SRB_EXTENSION +GetSrbExtension( + __in PSCSI_REQUEST_BLOCK Srb + );
8 years, 7 months
1
0
0
0
← Newer
1
2
3
4
5
6
7
8
...
23
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
Results per page:
10
25
50
100
200