ReactOS.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2024
December
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
February
January
2012
December
November
October
September
August
July
June
May
April
March
February
January
2011
December
November
October
September
August
July
June
May
April
March
February
January
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008
December
November
October
September
August
July
June
May
April
March
February
January
2007
December
November
October
September
August
July
June
May
April
March
February
January
2006
December
November
October
September
August
July
June
May
April
March
February
January
2005
December
November
October
September
August
July
June
May
April
March
February
January
2004
December
November
October
September
August
July
June
May
April
March
February
List overview
Download
Ros-diffs
January 2018
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
----- 2010 -----
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
June 2010
May 2010
April 2010
March 2010
February 2010
January 2010
----- 2009 -----
December 2009
November 2009
October 2009
September 2009
August 2009
July 2009
June 2009
May 2009
April 2009
March 2009
February 2009
January 2009
----- 2008 -----
December 2008
November 2008
October 2008
September 2008
August 2008
July 2008
June 2008
May 2008
April 2008
March 2008
February 2008
January 2008
----- 2007 -----
December 2007
November 2007
October 2007
September 2007
August 2007
July 2007
June 2007
May 2007
April 2007
March 2007
February 2007
January 2007
----- 2006 -----
December 2006
November 2006
October 2006
September 2006
August 2006
July 2006
June 2006
May 2006
April 2006
March 2006
February 2006
January 2006
----- 2005 -----
December 2005
November 2005
October 2005
September 2005
August 2005
July 2005
June 2005
May 2005
April 2005
March 2005
February 2005
January 2005
----- 2004 -----
December 2004
November 2004
October 2004
September 2004
August 2004
July 2004
June 2004
May 2004
April 2004
March 2004
February 2004
ros-diffs@reactos.org
37 participants
372 discussions
Start a n
N
ew thread
03/06: [APPSHIM_APITEST] Add test for shims in AcGenral
by Mark Jansen
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=fc503b7c083751d43c07b…
commit fc503b7c083751d43c07b317f70729be438e0f45 Author: Mark Jansen <mark.jansen(a)reactos.org> AuthorDate: Wed Jun 14 18:38:41 2017 +0200 Commit: Mark Jansen <mark.jansen(a)reactos.org> CommitDate: Sun Jan 21 21:13:08 2018 +0100 [APPSHIM_APITEST] Add test for shims in AcGenral --- modules/rostests/apitests/appshim/CMakeLists.txt | 4 +- .../rostests/apitests/appshim/appshim_apitest.h | 35 ++++++ modules/rostests/apitests/appshim/dispmode.c | 62 ++++----- modules/rostests/apitests/appshim/genral_hooks.c | 138 +++++++++++++++++++++ modules/rostests/apitests/appshim/testlist.c | 2 + modules/rostests/apitests/appshim/versionlie.c | 100 ++++++++++----- 6 files changed, 270 insertions(+), 71 deletions(-) diff --git a/modules/rostests/apitests/appshim/CMakeLists.txt b/modules/rostests/apitests/appshim/CMakeLists.txt index 48a4db166c..fa7a76527b 100644 --- a/modules/rostests/apitests/appshim/CMakeLists.txt +++ b/modules/rostests/apitests/appshim/CMakeLists.txt @@ -3,8 +3,10 @@ add_definitions(-D__ROS_LONG64__) list(APPEND SOURCE dispmode.c + genral_hooks.c versionlie.c - testlist.c) + testlist.c + appshim_apitest.h) add_executable(appshim_apitest ${SOURCE}) set_module_type(appshim_apitest win32cui) diff --git a/modules/rostests/apitests/appshim/appshim_apitest.h b/modules/rostests/apitests/appshim/appshim_apitest.h new file mode 100644 index 0000000000..1f3a0f6bb2 --- /dev/null +++ b/modules/rostests/apitests/appshim/appshim_apitest.h @@ -0,0 +1,35 @@ +#ifndef APPSHIM_APITEST_H +#define APPSHIM_APITEST_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct tagHOOKAPI { + PCSTR LibraryName; + PCSTR FunctionName; + PVOID ReplacementFunction; + PVOID OriginalFunction; + PVOID Unk1; + PVOID Unk2; +} HOOKAPI, *PHOOKAPI; + +typedef BOOL (WINAPI* tSDBGETAPPPATCHDIR)(PVOID hsdb, LPWSTR path, DWORD size); +typedef PHOOKAPI (WINAPI* tGETHOOKAPIS)(LPCSTR szCommandLine, LPCWSTR wszShimName, PDWORD pdwHookCount); + + +/* versionlie.c */ +void expect_shim_imp(PHOOKAPI hook, PCSTR library, PCSTR function, PCSTR shim, int* same); +#define expect_shim (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : expect_shim_imp + + +BOOL LoadShimDLL(PCWSTR ShimDll, HMODULE* module, tGETHOOKAPIS* ppGetHookAPIs); +tGETHOOKAPIS LoadShimDLL2(PCWSTR ShimDll); + + + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // APPHELP_APITEST_H diff --git a/modules/rostests/apitests/appshim/dispmode.c b/modules/rostests/apitests/appshim/dispmode.c index 0f8b3aaaea..68c3b2f190 100644 --- a/modules/rostests/apitests/appshim/dispmode.c +++ b/modules/rostests/apitests/appshim/dispmode.c @@ -2,7 +2,7 @@ * PROJECT: appshim_apitest * LICENSE: GPL-2.0+ (
https://spdx.org/licenses/GPL-2.0+
) * PURPOSE: Tests for display mode shims - * COPYRIGHT: Copyright 2016 Mark Jansen (mark.jansen(a)reactos.org) + * COPYRIGHT: Copyright 2016-2018 Mark Jansen (mark.jansen(a)reactos.org) */ #include <ntstatus.h> @@ -17,18 +17,16 @@ #include <strsafe.h> #include "wine/test.h" #include "apitest_iathook.h" +#include "appshim_apitest.h" static DWORD g_Version; #define WINVER_ANY 0 - -/* apphelp.dll */ -static BOOL(WINAPI* pSdbGetAppPatchDir)(PVOID, LPWSTR, DWORD); - /* aclayers.dll / acgenral.dll */ -static PVOID(WINAPI* pGetHookAPIs)(LPCSTR, LPCWSTR, PDWORD); +static tGETHOOKAPIS pGetHookAPIs; static BOOL(WINAPI* pNotifyShims)(DWORD fdwReason, PVOID ptr); + DWORD get_module_version(HMODULE mod) { DWORD dwVersion = 0; @@ -123,14 +121,6 @@ void WINAPI mSetThemeAppProperties(DWORD dwFlags) } -static const WCHAR* shim_dll(const WCHAR* name) -{ - static WCHAR buf[MAX_PATH]; - pSdbGetAppPatchDir(NULL, buf, MAX_PATH); - StringCchCatW(buf, _countof(buf), name); - return buf; -} - static void pre_8bit(void) { g_ChangeCount = 0; @@ -379,18 +369,18 @@ static struct test_info } tests[] = { /* Success */ - { "Force8BitColor", L"\\aclayers.dll", WINVER_ANY, 1, hook_disp, unhook_disp, pre_8bit, post_8bit, post_8bit_no }, - { "Force8BitColor", L"\\aclayers.dll", _WIN32_WINNT_VISTA, 100, hook_disp, unhook_disp,pre_8bit, post_8bit, post_8bit_no }, - { "Force640x480", L"\\aclayers.dll", WINVER_ANY, 1, hook_disp, unhook_disp, pre_640, post_640, post_640_no }, - { "Force640x480", L"\\aclayers.dll", _WIN32_WINNT_VISTA, 100, hook_disp, unhook_disp, pre_640, post_640, post_640_no }, - { "DisableThemes", L"\\acgenral.dll", WINVER_ANY, 1, hook_theme, unhook_theme, pre_theme, post_theme, post_theme_no }, - { "DisableThemes", L"\\acgenral.dll", _WIN32_WINNT_VISTA, 100, hook_theme, unhook_theme, pre_theme, post_theme, post_theme_no }, + { "Force8BitColor", L"aclayers.dll", WINVER_ANY, 1, hook_disp, unhook_disp, pre_8bit, post_8bit, post_8bit_no }, + { "Force8BitColor", L"aclayers.dll", _WIN32_WINNT_VISTA, 100, hook_disp, unhook_disp,pre_8bit, post_8bit, post_8bit_no }, + { "Force640x480", L"aclayers.dll", WINVER_ANY, 1, hook_disp, unhook_disp, pre_640, post_640, post_640_no }, + { "Force640x480", L"aclayers.dll", _WIN32_WINNT_VISTA, 100, hook_disp, unhook_disp, pre_640, post_640, post_640_no }, + { "DisableThemes", L"acgenral.dll", WINVER_ANY, 1, hook_theme, unhook_theme, pre_theme, post_theme, post_theme_no }, + { "DisableThemes", L"acgenral.dll", _WIN32_WINNT_VISTA, 100, hook_theme, unhook_theme, pre_theme, post_theme, post_theme_no }, /* No need to change anything */ - { "Force8BitColor", L"\\aclayers.dll", WINVER_ANY, 1, hook_disp, unhook_disp, pre_8bit_2, post_8bit_2, post_8bit_2_no }, - { "Force8BitColor", L"\\aclayers.dll", _WIN32_WINNT_VISTA, 100, hook_disp, unhook_disp, pre_8bit_2, post_8bit_2, post_8bit_2_no }, - { "Force640x480", L"\\aclayers.dll", WINVER_ANY, 1, hook_disp, unhook_disp, pre_640_2, post_640_2, post_640_2_no }, - { "Force640x480", L"\\aclayers.dll", _WIN32_WINNT_VISTA, 100, hook_disp, unhook_disp, pre_640_2, post_640_2, post_640_2_no }, + { "Force8BitColor", L"aclayers.dll", WINVER_ANY, 1, hook_disp, unhook_disp, pre_8bit_2, post_8bit_2, post_8bit_2_no }, + { "Force8BitColor", L"aclayers.dll", _WIN32_WINNT_VISTA, 100, hook_disp, unhook_disp, pre_8bit_2, post_8bit_2, post_8bit_2_no }, + { "Force640x480", L"aclayers.dll", WINVER_ANY, 1, hook_disp, unhook_disp, pre_640_2, post_640_2, post_640_2_no }, + { "Force640x480", L"aclayers.dll", _WIN32_WINNT_VISTA, 100, hook_disp, unhook_disp, pre_640_2, post_640_2, post_640_2_no }, }; @@ -398,16 +388,15 @@ static void run_test(size_t n, BOOL unload) { BOOL ret; HMODULE dll; - const WCHAR* buf = shim_dll(tests[n].dll); - dll = LoadLibraryW(shim_dll(tests[n].dll)); - pGetHookAPIs = (void*)GetProcAddress(dll, "GetHookAPIs"); + if (!LoadShimDLL(tests[n].dll, &dll, &pGetHookAPIs)) + pGetHookAPIs = NULL; pNotifyShims = (void*)GetProcAddress(dll, "NotifyShims"); if (!pGetHookAPIs || !pNotifyShims) { - skip("aclayers.dll not loaded, or does not export GetHookAPIs or pNotifyShims (%s, %p, %p)\n", - tests[n].name, pGetHookAPIs, pNotifyShims); + skip("%s not loaded, or does not export GetHookAPIs or pNotifyShims (%s, %p, %p)\n", + wine_dbgstr_w(tests[n].dll), tests[n].name, pGetHookAPIs, pNotifyShims); return; } @@ -435,8 +424,8 @@ static void run_test(size_t n, BOOL unload) FreeLibrary(dll); if (unload) { - dll = GetModuleHandleW(buf); - ok(dll == NULL, "Unable to unload %s\n", wine_dbgstr_w(buf)); + dll = GetModuleHandleW(tests[n].dll); + ok(dll == NULL, "Unable to unload %s\n", wine_dbgstr_w(tests[n].dll)); } } @@ -448,21 +437,14 @@ START_TEST(dispmode) int argc; char **argv; - pSdbGetAppPatchDir = (void*)GetProcAddress(dll, "SdbGetAppPatchDir"); - if (!pSdbGetAppPatchDir) - { - skip("apphelp.dll not loaded, or does not export SdbGetAppPatchDir\n"); - return; - } - argc = winetest_get_mainargs(&argv); if (argc < 3) { WCHAR path[MAX_PATH]; GetModuleFileNameW(NULL, path, _countof(path)); - dll = GetModuleHandleW(shim_dll(L"\\aclayers.dll")); + dll = GetModuleHandleW(L"aclayers.dll"); if (!dll) - dll = GetModuleHandleW(shim_dll(L"\\acgenral.dll")); + dll = GetModuleHandleW(L"acgenral.dll"); if (dll != NULL) trace("Loaded under a shim, running each test in it's own process\n"); diff --git a/modules/rostests/apitests/appshim/genral_hooks.c b/modules/rostests/apitests/appshim/genral_hooks.c new file mode 100644 index 0000000000..72680c75a8 --- /dev/null +++ b/modules/rostests/apitests/appshim/genral_hooks.c @@ -0,0 +1,138 @@ +/* + * PROJECT: appshim_apitest + * LICENSE: GPL-2.0+ (
https://spdx.org/licenses/GPL-2.0+
) + * PURPOSE: Test to document the hooks used by various shims in AcGenral + * COPYRIGHT: Copyright 2017-2018 Mark Jansen (mark.jansen(a)reactos.org) + */ + +#include <ntstatus.h> +#define WIN32_NO_STATUS +#include <windows.h> +#include <ndk/rtlfuncs.h> +#include <strsafe.h> +#include "wine/test.h" + +#include "appshim_apitest.h" + +static DWORD g_WinVersion; +#define WINVER_WIN8 0x0602 + + +typedef struct expect_shim_hook +{ + const char* Library; + const char* Function; +} expect_shim_hook; + +typedef struct expect_shim_data +{ + const WCHAR* ShimName; + DWORD MinVersion; + expect_shim_hook hooks[4]; +} expect_shim_data; + + +static expect_shim_data data[] = +{ + { + L"IgnoreChromeSandbox", + WINVER_WIN8, + { + { "KERNEL32.DLL", "CreateProcessW" }, + } + }, + { + L"AddProcessParametersFlags", + 0, + /* No hooks */ + }, + { + L"DisableThemes", + 0, + /* No hooks */ + }, +}; + +static DWORD count_shims(expect_shim_data* data) +{ + DWORD num; + for (num = 0; num < _countof(data->hooks) && data->hooks[num].Library;) + { + ++num; + } + return num; +} + +static const char* safe_str(const char* ptr) +{ + static char buffer[2][30]; + static int index = 0; + if (HIWORD(ptr)) + return ptr; + + index ^= 1; + StringCchPrintfA(buffer[index], _countof(buffer[index]), "#%d", (int)ptr); + return buffer[index]; +} + +START_TEST(genral_hooks) +{ + RTL_OSVERSIONINFOEXW rtlinfo = {0}; + size_t n, h; + + tGETHOOKAPIS pGetHookAPIs = LoadShimDLL2(L"AcGenral.dll"); + if (!pGetHookAPIs) + return; + + rtlinfo.dwOSVersionInfoSize = sizeof(rtlinfo); + RtlGetVersion((PRTL_OSVERSIONINFOW)&rtlinfo); + g_WinVersion = (rtlinfo.dwMajorVersion << 8) | rtlinfo.dwMinorVersion; + + + + for (n = 0; n < _countof(data); ++n) + { + expect_shim_data* current = data + n; + DWORD num_shims = 0, expected_shims = count_shims(current); + + PHOOKAPI hook = pGetHookAPIs("", current->ShimName, &num_shims); + + if (current->MinVersion > g_WinVersion && !hook) + continue; + + ok(!!hook, "Expected a valid pointer, got nothing for %s\n", wine_dbgstr_w(current->ShimName)); + ok(num_shims == expected_shims, "Expected %u shims, got %u for %s\n", + expected_shims, num_shims, wine_dbgstr_w(current->ShimName)); + for (h = 0; h < min(num_shims, expected_shims); ++h) + { + expect_shim_hook* expect_hk = current->hooks + h; + PHOOKAPI got_hk = hook+h; + int lib = lstrcmpA(expect_hk->Library, got_hk->LibraryName); + int fn = lstrcmpA(safe_str(expect_hk->Function), safe_str(got_hk->FunctionName)); + ok(lib == 0, "Expected LibraryName to be %s, was: %s for %s\n", + expect_hk->Library, got_hk->LibraryName, wine_dbgstr_w(current->ShimName)); + ok(fn == 0, "Expected FunctionName to be %s, was: %s for %s\n", + safe_str(expect_hk->Function), safe_str(got_hk->FunctionName), wine_dbgstr_w(current->ShimName)); + } + if (num_shims > expected_shims) + { + for (h = expected_shims; h < num_shims; ++h) + { + PHOOKAPI got_hk = hook+h; + + ok(0, "Extra shim: %s!%s for %s\n", + got_hk->LibraryName, safe_str(got_hk->FunctionName), wine_dbgstr_w(current->ShimName)); + } + } + else + { + for (h = num_shims; h < expected_shims; ++h) + { + expect_shim_hook* expect_hk = current->hooks + h; + + ok(0, "Missing shim: %s!%s for %s\n", + expect_hk->Library, safe_str(expect_hk->Function), wine_dbgstr_w(current->ShimName)); + } + } + } +} diff --git a/modules/rostests/apitests/appshim/testlist.c b/modules/rostests/apitests/appshim/testlist.c index b3b8a216db..2b2e692a3d 100644 --- a/modules/rostests/apitests/appshim/testlist.c +++ b/modules/rostests/apitests/appshim/testlist.c @@ -4,11 +4,13 @@ #include <wine/test.h> extern void func_dispmode(void); +extern void func_genral_hooks(void); extern void func_versionlie(void); const struct test winetest_testlist[] = { { "dispmode", func_dispmode }, + { "genral_hooks", func_genral_hooks }, { "versionlie", func_versionlie }, { 0, 0 } }; diff --git a/modules/rostests/apitests/appshim/versionlie.c b/modules/rostests/apitests/appshim/versionlie.c index ad38731796..5322b8a03e 100644 --- a/modules/rostests/apitests/appshim/versionlie.c +++ b/modules/rostests/apitests/appshim/versionlie.c @@ -2,7 +2,7 @@ * PROJECT: appshim_apitest * LICENSE: GPL-2.0+ (
https://spdx.org/licenses/GPL-2.0+
) * PURPOSE: Tests for versionlie shims - * COPYRIGHT: Copyright 2015 Mark Jansen (mark.jansen(a)reactos.org) + * COPYRIGHT: Copyright 2015-2018 Mark Jansen (mark.jansen(a)reactos.org) */ #include <ntstatus.h> @@ -13,20 +13,12 @@ #else #include <winternl.h> #endif -#include <stdio.h> #include "wine/test.h" +#include <strsafe.h> -typedef struct tagHOOKAPI { - PCSTR LibraryName; - PCSTR FunctionName; - PVOID ReplacementFunction; - PVOID OriginalFunction; - PVOID Unk1; - PVOID Unk2; -} HOOKAPI, *PHOOKAPI; +#include "appshim_apitest.h" -static BOOL (WINAPI* pSdbGetAppPatchDir)(PVOID,LPWSTR,DWORD); -static PHOOKAPI (WINAPI* pGetHookAPIs)(LPCSTR,LPCWSTR,PDWORD); +static tGETHOOKAPIS pGetHookAPIs; static DWORD g_WinVersion; @@ -48,7 +40,7 @@ typedef BOOL(WINAPI* GETVERSIONEXAPROC)(LPOSVERSIONINFOEXA); typedef BOOL(WINAPI* GETVERSIONEXWPROC)(LPOSVERSIONINFOEXW); typedef DWORD(WINAPI* GETVERSIONPROC)(void); -static void expect_shim_imp(PHOOKAPI hook, PCSTR library, PCSTR function, PCSTR shim, int* same) +void expect_shim_imp(PHOOKAPI hook, PCSTR library, PCSTR function, PCSTR shim, int* same) { int lib = lstrcmpA(library, hook->LibraryName); int fn = lstrcmpA(function, hook->FunctionName); @@ -86,7 +78,7 @@ static void verify_shima_imp(PHOOKAPI hook, const VersionLieInfo* info, PCSTR sh winetest_ok(info->dwPlatformId == v2.dwPlatformId, "Expected dwPlatformId to be equal, was: %u, %u for %s\n", info->dwPlatformId, v2.dwPlatformId, shim); if (info->wServicePackMajor) - sprintf(szCSDVersion, "Service Pack %u", info->wServicePackMajor); + StringCchPrintfA(szCSDVersion, _countof(szCSDVersion), "Service Pack %u", info->wServicePackMajor); winetest_ok(lstrcmpA(szCSDVersion, v2.szCSDVersion) == 0, "Expected szCSDVersion to be equal, was: %s, %s for %s\n", szCSDVersion, v2.szCSDVersion, shim); if (v1.dwOSVersionInfoSize == sizeof(OSVERSIONINFOEXA)) @@ -150,7 +142,6 @@ static void verify_shimw_imp(PHOOKAPI hook, const VersionLieInfo* info, PCSTR sh } if (ok1 && ok2) { - static const WCHAR szCSDFMT[] = {'S','e','r','v','i','c','e',' ','P','a','c','k',' ','%','u',0}; WCHAR szCSDVersion[128] = { 0 }; winetest_ok(v1.dwOSVersionInfoSize == v2.dwOSVersionInfoSize, "Expected dwOSVersionInfoSize to be equal, was: %u, %u for %s\n", v1.dwOSVersionInfoSize, v2.dwOSVersionInfoSize, shim); winetest_ok(info->dwMajorVersion == v2.dwMajorVersion, "Expected dwMajorVersion to be equal, was: %u, %u for %s\n", info->dwMajorVersion, v2.dwMajorVersion, shim); @@ -159,7 +150,7 @@ static void verify_shimw_imp(PHOOKAPI hook, const VersionLieInfo* info, PCSTR sh winetest_ok(info->dwPlatformId == v2.dwPlatformId, "Expected dwPlatformId to be equal, was: %u, %u for %s\n", info->dwPlatformId, v2.dwPlatformId, shim); if (info->wServicePackMajor) - swprintf(szCSDVersion, szCSDFMT, info->wServicePackMajor); + StringCchPrintfW(szCSDVersion, _countof(szCSDVersion), L"Service Pack %u", info->wServicePackMajor); winetest_ok(lstrcmpW(szCSDVersion, v2.szCSDVersion) == 0, "Expected szCSDVersion to be equal, was: %s, %s for %s\n", wine_dbgstr_w(szCSDVersion), wine_dbgstr_w(v2.szCSDVersion), shim); if (v1.dwOSVersionInfoSize == sizeof(OSVERSIONINFOEXW)) @@ -209,7 +200,6 @@ static void verify_shim_imp(PHOOKAPI hook, const VersionLieInfo* info, PCSTR shi } -#define expect_shim (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : expect_shim_imp #define verify_shima (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : verify_shima_imp #define verify_shimw (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : verify_shimw_imp #define verify_shim (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : verify_shim_imp @@ -303,28 +293,78 @@ DWORD get_host_winver(void) return (rtlinfo.dwMajorVersion << 8) | rtlinfo.dwMinorVersion; } -START_TEST(versionlie) +BOOL LoadShimDLL(PCWSTR ShimDll, HMODULE* module, tGETHOOKAPIS* ppGetHookAPIs) { - HMODULE dll = LoadLibraryA("apphelp.dll"); - WCHAR buf[MAX_PATH]; - WCHAR aclayers[] = {'\\','a','c','l','a','y','e','r','s','.','d','l','l',0}; - pSdbGetAppPatchDir = (void*)GetProcAddress(dll, "SdbGetAppPatchDir"); + static tSDBGETAPPPATCHDIR pSdbGetAppPatchDir = NULL; + HMODULE dll; + WCHAR buf[MAX_PATH] = {0}; if (!pSdbGetAppPatchDir) { - skip("apphelp.dll not loaded, or does not export SdbGetAppPatchDir\n"); - return; + dll = LoadLibraryA("apphelp.dll"); + pSdbGetAppPatchDir = (tSDBGETAPPPATCHDIR)GetProcAddress(dll, "SdbGetAppPatchDir"); + + if (!pSdbGetAppPatchDir) + { + skip("Unable to retrieve SdbGetAppPatchDir (%p, %p)\n", dll, pSdbGetAppPatchDir); + } + } + + if (!pSdbGetAppPatchDir || !pSdbGetAppPatchDir(NULL, buf, MAX_PATH)) + { + skip("Unable to retrieve AppPatch dir, building manually\n"); + if (!GetSystemWindowsDirectoryW(buf, MAX_PATH)) + { + skip("Unable to build AppPatch name(1)\n"); + return FALSE; + } + if (!SUCCEEDED(StringCchCatW(buf, _countof(buf), L"\\AppPatch"))) + { + skip("Unable to build AppPatch name(2)\n"); + return FALSE; + } + } + if (!SUCCEEDED(StringCchCatW(buf, _countof(buf), L"\\")) || + !SUCCEEDED(StringCchCatW(buf, _countof(buf), ShimDll))) + { + skip("Unable to append dll name\n"); + return FALSE; } - pSdbGetAppPatchDir(NULL, buf, MAX_PATH); - lstrcatW(buf, aclayers); dll = LoadLibraryW(buf); - pGetHookAPIs = (void*)GetProcAddress(dll, "GetHookAPIs"); + if (!dll) + { + skip("Unable to load shim dll\n"); + return FALSE; + } + *module = dll; + *ppGetHookAPIs = (tGETHOOKAPIS)GetProcAddress(dll, "GetHookAPIs"); - if (!pGetHookAPIs) + return *ppGetHookAPIs != NULL; +} + + +tGETHOOKAPIS LoadShimDLL2(PCWSTR ShimDll) +{ + HMODULE module; + tGETHOOKAPIS pGetHookAPIs; + + if (LoadShimDLL(ShimDll, &module, &pGetHookAPIs)) { - skip("aclayers.dll not loaded, or does not export GetHookAPIs\n"); - return; + if (!pGetHookAPIs) + skip("No GetHookAPIs found\n"); + return pGetHookAPIs; } + return NULL; +} + + +START_TEST(versionlie) +{ + pGetHookAPIs = LoadShimDLL2(L"aclayers.dll"); + + if (!pGetHookAPIs) + return; + g_WinVersion = get_host_winver(); run_test("Win95VersionLie", &g_Win95);
6 years, 11 months
1
0
0
0
02/06: [APPHELP] Use GetSystemWindowsDirectory instead of GetWindowsDirectory
by Mark Jansen
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=3fd6fcf6eb4ad30b29af4…
commit 3fd6fcf6eb4ad30b29af4059d74534a53f8dd510 Author: Mark Jansen <mark.jansen(a)reactos.org> AuthorDate: Sat Jan 20 22:52:53 2018 +0100 Commit: Mark Jansen <mark.jansen(a)reactos.org> CommitDate: Sun Jan 21 21:13:08 2018 +0100 [APPHELP] Use GetSystemWindowsDirectory instead of GetWindowsDirectory --- dll/appcompat/apphelp/hsdb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dll/appcompat/apphelp/hsdb.c b/dll/appcompat/apphelp/hsdb.c index 9fb9ad5564..ea61555539 100644 --- a/dll/appcompat/apphelp/hsdb.c +++ b/dll/appcompat/apphelp/hsdb.c @@ -692,7 +692,7 @@ BOOL WINAPI SdbPackAppCompatData(HSDB hsdb, PSDBQUERYRESULT pQueryResult, PVOID* return FALSE; } - GetWindowsDirectoryW(pData->szModule, _countof(pData->szModule)); + GetSystemWindowsDirectoryW(pData->szModule, _countof(pData->szModule)); hr = StringCchCatW(pData->szModule, _countof(pData->szModule), L"\\system32\\apphelp.dll"); if (!SUCCEEDED(hr)) {
6 years, 11 months
1
0
0
0
01/06: [SHIMENG] Change the default loglevel + mute GetProcAddress logging
by Mark Jansen
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=abeaf2e9dbc3b0891e790…
commit abeaf2e9dbc3b0891e790f868c521bc1c4d64722 Author: Mark Jansen <mark.jansen(a)reactos.org> AuthorDate: Mon Jan 15 22:36:07 2018 +0100 Commit: Mark Jansen <mark.jansen(a)reactos.org> CommitDate: Sun Jan 21 21:13:08 2018 +0100 [SHIMENG] Change the default loglevel + mute GetProcAddress logging --- dll/appcompat/apphelp/shimeng.c | 4 ++-- dll/appcompat/shims/shimlib/shimlib.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dll/appcompat/apphelp/shimeng.c b/dll/appcompat/apphelp/shimeng.c index 0d95d61183..20f125a456 100644 --- a/dll/appcompat/apphelp/shimeng.c +++ b/dll/appcompat/apphelp/shimeng.c @@ -2,7 +2,7 @@ * PROJECT: ReactOS Application compatibility module * LICENSE: GPL-2.0+ (
https://spdx.org/licenses/GPL-2.0+
) * PURPOSE: Shim engine core - * COPYRIGHT: Copyright 2015-2017 Mark Jansen (mark.jansen(a)reactos.org) + * COPYRIGHT: Copyright 2015-2018 Mark Jansen (mark.jansen(a)reactos.org) */ #define WIN32_NO_STATUS @@ -569,7 +569,7 @@ FARPROC WINAPI StubGetProcAddress(HINSTANCE hModule, LPCSTR lpProcName) return proc; } - SHIMENG_MSG("(GetProcAddress(%p!%s) => %p\n", hModule, lpPrintName, proc); + SHIMENG_INFO("(GetProcAddress(%p!%s) => %p\n", hModule, lpPrintName, proc); HookModuleInfo = SeiFindHookModuleInfo(NULL, hModule); diff --git a/dll/appcompat/shims/shimlib/shimlib.c b/dll/appcompat/shims/shimlib/shimlib.c index ec528d2ead..54d64799d1 100644 --- a/dll/appcompat/shims/shimlib/shimlib.c +++ b/dll/appcompat/shims/shimlib/shimlib.c @@ -2,7 +2,7 @@ * PROJECT: ReactOS Shim helper library * LICENSE: GPL-2.0+ (
https://spdx.org/licenses/GPL-2.0+
) * PURPOSE: Shim helper functions - * COPYRIGHT: Copyright 2016,2017 Mark Jansen (mark.jansen(a)reactos.org) + * COPYRIGHT: Copyright 2016-2018 Mark Jansen (mark.jansen(a)reactos.org) */ #define WIN32_NO_STATUS @@ -155,7 +155,7 @@ VOID SeiInitDebugSupport(VOID) static const UNICODE_STRING DebugKey = RTL_CONSTANT_STRING(L"SHIM_DEBUG_LEVEL"); UNICODE_STRING DebugValue; NTSTATUS Status; - ULONG NewLevel = 0; + ULONG NewLevel = SEI_MSG; WCHAR Buffer[40]; RtlInitEmptyUnicodeString(&DebugValue, Buffer, sizeof(Buffer));
6 years, 11 months
1
0
0
0
01/01: [SHELL32] Fix typo in Polish translation pl-PL.rc
by Kamil Smoliński
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=00ed9fc88b6ded2228749…
commit 00ed9fc88b6ded2228749ad100a3d6b17b9304f0 Author: Kamil Smoliński <blackdragondev85(a)gmail.com> AuthorDate: Sat Jan 20 17:09:20 2018 +0100 Commit: Mark Jansen <mark.jansen(a)reactos.org> CommitDate: Sun Jan 21 19:13:57 2018 +0100 [SHELL32] Fix typo in Polish translation pl-PL.rc --- dll/win32/shell32/lang/pl-PL.rc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dll/win32/shell32/lang/pl-PL.rc b/dll/win32/shell32/lang/pl-PL.rc index 192b706f7f..53103de96e 100644 --- a/dll/win32/shell32/lang/pl-PL.rc +++ b/dll/win32/shell32/lang/pl-PL.rc @@ -1,5 +1,6 @@ /* * Updated by Saibamen (July, 2015) + * Updated by BlackDragonDv (January, 2018) */ LANGUAGE LANG_POLISH, SUBLANG_DEFAULT @@ -841,8 +842,8 @@ BEGIN IDS_EXE_DESCRIPTION "Opis:" IDS_MENU_EMPTY "(Puste)" - IDS_OBJECTS "%d Objekty" - IDS_OBJECTS_SELECTED "%d Wybrane objekty" + IDS_OBJECTS "%d Obiekty" + IDS_OBJECTS_SELECTED "%d Wybrane obiekty" IDS_ADVANCED_FOLDER "Pliki i Foldery" IDS_ADVANCED_NET_CRAWLER "Automatycznie wyszukuj foldery sieciowe i drukarki"
6 years, 11 months
1
0
0
0
01/01: [CMAKE] My eyes!
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=bb888f9b11aa1e5b42917…
commit bb888f9b11aa1e5b42917bde182e25d4844c8bc5 Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Sun Jan 21 13:54:18 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Sun Jan 21 13:54:18 2018 +0100 [CMAKE] My eyes! --- drivers/usb/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/CMakeLists.txt b/drivers/usb/CMakeLists.txt index 17fc45d14e..51edb17b0c 100644 --- a/drivers/usb/CMakeLists.txt +++ b/drivers/usb/CMakeLists.txt @@ -6,6 +6,6 @@ add_subdirectory(usbhub) add_subdirectory(usbohci) #add_subdirectory(usbohci_new) add_subdirectory(usbport) -#add_subdirectory(usbport_new) add_subdirectory(usbstor) +#add_subdirectory(usbstor_new) add_subdirectory(usbuhci)
6 years, 11 months
1
0
0
0
01/01: [USBSTOR_NEW] Create usbstor_new based on usbstor in order to contain Vadim Galyant's work.
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=94e0942644cc8f7c2f923…
commit 94e0942644cc8f7c2f923bc19299068cded76662 Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Sun Jan 21 13:51:07 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Sun Jan 21 13:51:07 2018 +0100 [USBSTOR_NEW] Create usbstor_new based on usbstor in order to contain Vadim Galyant's work. --- drivers/usb/CMakeLists.txt | 1 + drivers/usb/usbstor_new/CMakeLists.txt | 25 + drivers/usb/usbstor_new/descriptor.c | 549 ++++++++++++ drivers/usb/usbstor_new/disk.c | 691 +++++++++++++++ drivers/usb/usbstor_new/error.c | 410 +++++++++ drivers/usb/usbstor_new/fdo.c | 461 +++++++++++ drivers/usb/usbstor_new/guid.c | 9 + drivers/usb/usbstor_new/misc.c | 520 ++++++++++++ drivers/usb/usbstor_new/pdo.c | 1376 ++++++++++++++++++++++++++++++ drivers/usb/usbstor_new/queue.c | 670 +++++++++++++++ drivers/usb/usbstor_new/scsi.c | 1429 ++++++++++++++++++++++++++++++++ drivers/usb/usbstor_new/usbstor.c | 295 +++++++ drivers/usb/usbstor_new/usbstor.h | 550 ++++++++++++ drivers/usb/usbstor_new/usbstor.rc | 5 + 14 files changed, 6991 insertions(+) diff --git a/drivers/usb/CMakeLists.txt b/drivers/usb/CMakeLists.txt index 05817b0f82..17fc45d14e 100644 --- a/drivers/usb/CMakeLists.txt +++ b/drivers/usb/CMakeLists.txt @@ -6,5 +6,6 @@ add_subdirectory(usbhub) add_subdirectory(usbohci) #add_subdirectory(usbohci_new) add_subdirectory(usbport) +#add_subdirectory(usbport_new) add_subdirectory(usbstor) add_subdirectory(usbuhci) diff --git a/drivers/usb/usbstor_new/CMakeLists.txt b/drivers/usb/usbstor_new/CMakeLists.txt new file mode 100644 index 0000000000..3bb2eed0f2 --- /dev/null +++ b/drivers/usb/usbstor_new/CMakeLists.txt @@ -0,0 +1,25 @@ + +add_definitions(-DDEBUG_MODE) +include_directories(${REACTOS_SOURCE_DIR}/ntoskrnl/include) + +list(APPEND SOURCE + descriptor.c + disk.c + fdo.c + misc.c + pdo.c + queue.c + error.c + scsi.c + usbstor.c + usbstor.h) + +add_library(usbstor SHARED + ${SOURCE} + guid.c + usbstor.rc) + +set_module_type(usbstor kernelmodedriver) +add_importlibs(usbstor ntoskrnl hal usbd) +add_pch(usbstor usbstor.h SOURCE) +add_cd_file(TARGET usbstor DESTINATION reactos/system32/drivers NO_CAB FOR all) diff --git a/drivers/usb/usbstor_new/descriptor.c b/drivers/usb/usbstor_new/descriptor.c new file mode 100644 index 0000000000..3df36a671c --- /dev/null +++ b/drivers/usb/usbstor_new/descriptor.c @@ -0,0 +1,549 @@ +/* + * PROJECT: ReactOS Universal Serial Bus Bulk Storage Driver + * LICENSE: GPL - See COPYING in the top level directory + * FILE: drivers/usb/usbstor/descriptor.c + * PURPOSE: USB block storage device driver. + * PROGRAMMERS: + * James Tabor + * Michael Martin (michael.martin(a)reactos.org) + * Johannes Anderwald (johannes.anderwald(a)reactos.org) + */ + +#include "usbstor.h" + +#define NDEBUG +#include <debug.h> + +NTSTATUS +NTAPI +USBSTOR_GetDescriptor( + IN PDEVICE_OBJECT DeviceObject, + IN UCHAR DescriptorType, + IN ULONG DescriptorLength, + IN UCHAR DescriptorIndex, + IN LANGID LanguageId, + OUT PVOID *OutDescriptor) +{ + PURB Urb; + NTSTATUS Status; + PVOID Descriptor; + + // + // sanity checks + // + ASSERT(DeviceObject); + ASSERT(OutDescriptor); + ASSERT(DescriptorLength); + + // + // first allocate descriptor buffer + // + Descriptor = AllocateItem(NonPagedPool, DescriptorLength); + if (!Descriptor) + { + // + // no memory + // + return STATUS_INSUFFICIENT_RESOURCES; + } + + // + // allocate urb + // + Urb = (PURB) AllocateItem(NonPagedPool, sizeof(URB)); + if (!Urb) + { + // + // no memory + // + FreeItem(Descriptor); + return STATUS_INSUFFICIENT_RESOURCES; + } + + // + // initialize urb + // + UsbBuildGetDescriptorRequest(Urb, + sizeof(Urb->UrbControlDescriptorRequest), + DescriptorType, + DescriptorIndex, + LanguageId, + Descriptor, + NULL, + DescriptorLength, + NULL); + + // + // submit urb + // + Status = USBSTOR_SyncUrbRequest(DeviceObject, Urb); + + // + // free urb + // + FreeItem(Urb); + + if (NT_SUCCESS(Status)) + { + // + // store result + // + *OutDescriptor = Descriptor; + } + + // + // done + // + return Status; +} + + +NTSTATUS +USBSTOR_GetDescriptors( + IN PDEVICE_OBJECT DeviceObject) +{ + NTSTATUS Status; + PFDO_DEVICE_EXTENSION DeviceExtension; + USHORT DescriptorLength; + + // + // get device extension + // + DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + // + // first get device descriptor + // + Status = USBSTOR_GetDescriptor(DeviceExtension->LowerDeviceObject, USB_DEVICE_DESCRIPTOR_TYPE, sizeof(USB_DEVICE_DESCRIPTOR), 0, 0, (PVOID*)&DeviceExtension->DeviceDescriptor); + if (!NT_SUCCESS(Status)) + { + // + // failed to get device descriptor + // + DeviceExtension->DeviceDescriptor = NULL; + return Status; + } + + // + // now get basic configuration descriptor + // + Status = USBSTOR_GetDescriptor(DeviceExtension->LowerDeviceObject, USB_CONFIGURATION_DESCRIPTOR_TYPE, sizeof(USB_CONFIGURATION_DESCRIPTOR), 0, 0, (PVOID*)&DeviceExtension->ConfigurationDescriptor); + if (!NT_SUCCESS(Status)) + { + // + // failed to get configuration descriptor + // + FreeItem(DeviceExtension->DeviceDescriptor); + DeviceExtension->DeviceDescriptor = NULL; + return Status; + } + + // + // backup length + // + DescriptorLength = DeviceExtension->ConfigurationDescriptor->wTotalLength; + + // + // release basic descriptor + // + FreeItem(DeviceExtension->ConfigurationDescriptor); + DeviceExtension->ConfigurationDescriptor = NULL; + + // + // allocate full descriptor + // + Status = USBSTOR_GetDescriptor(DeviceExtension->LowerDeviceObject, USB_CONFIGURATION_DESCRIPTOR_TYPE, DescriptorLength, 0, 0, (PVOID*)&DeviceExtension->ConfigurationDescriptor); + if (!NT_SUCCESS(Status)) + { + // + // failed to get configuration descriptor + // + FreeItem(DeviceExtension->DeviceDescriptor); + DeviceExtension->DeviceDescriptor = NULL; + return Status; + } + + // + // check if there is a serial number provided + // + if (DeviceExtension->DeviceDescriptor->iSerialNumber) + { + // + // get serial number + // + Status = USBSTOR_GetDescriptor(DeviceExtension->LowerDeviceObject, USB_STRING_DESCRIPTOR_TYPE, 100 * sizeof(WCHAR), DeviceExtension->DeviceDescriptor->iSerialNumber, 0x0409, (PVOID*)&DeviceExtension->SerialNumber); + if (!NT_SUCCESS(Status)) + { + // + // failed to get serial number descriptor, free device descriptor + // + FreeItem(DeviceExtension->DeviceDescriptor); + DeviceExtension->DeviceDescriptor = NULL; + + // + // free configuration descriptor + // + FreeItem(DeviceExtension->ConfigurationDescriptor); + DeviceExtension->ConfigurationDescriptor = NULL; + + // + // set serial number to zero + // + DeviceExtension->SerialNumber = NULL; + return Status; + } + } + + return Status; +} + +NTSTATUS +NTAPI +USBSTOR_ScanConfigurationDescriptor( + IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, + OUT PUSB_INTERFACE_DESCRIPTOR * OutInterfaceDescriptor, + OUT PUSB_ENDPOINT_DESCRIPTOR * InEndpointDescriptor, + OUT PUSB_ENDPOINT_DESCRIPTOR * OutEndpointDescriptor) +{ + PUSB_CONFIGURATION_DESCRIPTOR CurrentDescriptor; + PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor; + + // + // sanity checks + // + ASSERT(ConfigurationDescriptor); + ASSERT(OutInterfaceDescriptor); + ASSERT(InEndpointDescriptor); + ASSERT(OutEndpointDescriptor); + + // + // nullify pointers + // + *OutInterfaceDescriptor = NULL; + *InEndpointDescriptor = NULL; + *OutEndpointDescriptor = NULL; + + // + // start scanning + // + CurrentDescriptor = ConfigurationDescriptor; + + do + { + // + // check current descriptor type + // + if (CurrentDescriptor->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE) + { + // + // found interface descriptor + // + if (*OutInterfaceDescriptor) + { + // + // we only process the first interface descriptor as ms does -> see documentation + // + break; + } + + // + // store interface descriptor + // + *OutInterfaceDescriptor = (PUSB_INTERFACE_DESCRIPTOR)CurrentDescriptor; + } + else if (CurrentDescriptor->bDescriptorType == USB_ENDPOINT_DESCRIPTOR_TYPE) + { + // + // convert to endpoint descriptor + // + EndpointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR)CurrentDescriptor; + + // + // sanity check + // + ASSERT(*OutInterfaceDescriptor); + + // + // get endpoint type + // + if ((EndpointDescriptor->bmAttributes & USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_BULK) + { + // + // bulk endpoint type + // + if (USB_ENDPOINT_DIRECTION_IN(EndpointDescriptor->bEndpointAddress)) + { + // + // bulk in + // + *InEndpointDescriptor = EndpointDescriptor; + } + else + { + // + // bulk out + // + *OutEndpointDescriptor = EndpointDescriptor; + } + } + else if ((EndpointDescriptor->bmAttributes & USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_INTERRUPT) + { + // + // interrupt endpoint type + // + UNIMPLEMENTED; + } + } + + // + // move to next descriptor + // + CurrentDescriptor = (PUSB_CONFIGURATION_DESCRIPTOR)((ULONG_PTR)CurrentDescriptor + CurrentDescriptor->bLength); + + // + // was it the last descriptor + // + if ((ULONG_PTR)CurrentDescriptor >= ((ULONG_PTR)ConfigurationDescriptor + ConfigurationDescriptor->wTotalLength)) + { + // + // reached last descriptor + // + break; + } + + }while(TRUE); + + // + // check if everything has been found + // + if (*OutInterfaceDescriptor == NULL || *InEndpointDescriptor == NULL || *OutEndpointDescriptor == NULL) + { + // + // failed to find interface / endpoint descriptor + // + DPRINT1("USBSTOR_ScanConfigurationDescriptor: Failed to find InterfaceDescriptor %p InEndpointDescriptor %p OutEndpointDescriptor %p\n", *OutInterfaceDescriptor, *InEndpointDescriptor, *OutEndpointDescriptor); + return STATUS_UNSUCCESSFUL; + } + + // + // completed successfully + // + return STATUS_SUCCESS; +} + +VOID +DumpConfigurationDescriptor(PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor) +{ + DPRINT1("Dumping ConfigurationDescriptor %p\n", ConfigurationDescriptor); + DPRINT1("bLength %x\n", ConfigurationDescriptor->bLength); + DPRINT1("bDescriptorType %x\n", ConfigurationDescriptor->bDescriptorType); + DPRINT1("wTotalLength %x\n", ConfigurationDescriptor->wTotalLength); + DPRINT1("bNumInterfaces %x\n", ConfigurationDescriptor->bNumInterfaces); + DPRINT1("bConfigurationValue %x\n", ConfigurationDescriptor->bConfigurationValue); + DPRINT1("iConfiguration %x\n", ConfigurationDescriptor->iConfiguration); + DPRINT1("bmAttributes %x\n", ConfigurationDescriptor->bmAttributes); + DPRINT1("MaxPower %x\n", ConfigurationDescriptor->MaxPower); +} + +NTSTATUS +USBSTOR_SelectConfigurationAndInterface( + IN PDEVICE_OBJECT DeviceObject, + IN PFDO_DEVICE_EXTENSION DeviceExtension) +{ + PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor; + PUSB_ENDPOINT_DESCRIPTOR InEndpointDescriptor, OutEndpointDescriptor; + NTSTATUS Status; + PURB Urb; + PUSBD_INTERFACE_LIST_ENTRY InterfaceList; + + // + // now scan configuration descriptors + // + Status = USBSTOR_ScanConfigurationDescriptor(DeviceExtension->ConfigurationDescriptor, &InterfaceDescriptor, &InEndpointDescriptor, &OutEndpointDescriptor); + if (!NT_SUCCESS(Status)) + { + // + // failed to scan + // + return Status; + } + + // + // now allocate one interface entry and terminating null entry + // + InterfaceList = (PUSBD_INTERFACE_LIST_ENTRY)AllocateItem(PagedPool, sizeof(USBD_INTERFACE_LIST_ENTRY) * 2); + if (!InterfaceList) + { + // + // no memory + // + return STATUS_INSUFFICIENT_RESOURCES; + } + + // + // initialize interface list entry + // + InterfaceList[0].InterfaceDescriptor = InterfaceDescriptor; + + // + // now allocate the urb + // + Urb = USBD_CreateConfigurationRequestEx(DeviceExtension->ConfigurationDescriptor, InterfaceList); + if (!Urb) + { + // + // no memory + // + FreeItem(InterfaceList); + return STATUS_INSUFFICIENT_RESOURCES; + } + + // + // sanity check + // + ASSERT(InterfaceList[0].Interface); + + // + // submit urb + // + Status = USBSTOR_SyncUrbRequest(DeviceExtension->LowerDeviceObject, Urb); + if (!NT_SUCCESS(Status)) + { + // + // failed to set configuration + // + DPRINT1("USBSTOR_SelectConfiguration failed to set interface %x\n", Status); + FreeItem(InterfaceList); + ExFreePoolWithTag(Urb, 0); + return Status; + } + + // + // backup interface information + // + DeviceExtension->InterfaceInformation = (PUSBD_INTERFACE_INFORMATION)AllocateItem(NonPagedPool, Urb->UrbSelectConfiguration.Interface.Length); + if (!DeviceExtension->InterfaceInformation) + { + // + // failed to allocate interface information structure + // + FreeItem(InterfaceList); + ExFreePoolWithTag(Urb, 0); + return STATUS_INSUFFICIENT_RESOURCES; + } + + // + // copy interface information + // + RtlCopyMemory(DeviceExtension->InterfaceInformation, &Urb->UrbSelectConfiguration.Interface, Urb->UrbSelectConfiguration.Interface.Length); + + // + // store pipe handle + // + DeviceExtension->ConfigurationHandle = Urb->UrbSelectConfiguration.ConfigurationHandle; + + // + // now prepare interface urb + // + UsbBuildSelectInterfaceRequest(Urb, GET_SELECT_INTERFACE_REQUEST_SIZE(InterfaceDescriptor->bNumEndpoints), DeviceExtension->ConfigurationHandle, InterfaceDescriptor->bInterfaceNumber, InterfaceDescriptor->bAlternateSetting); + + // + // copy interface information structure back - as offset for SelectConfiguration / SelectInterface request do differ + // + RtlCopyMemory(&Urb->UrbSelectInterface.Interface, DeviceExtension->InterfaceInformation, DeviceExtension->InterfaceInformation->Length); + + // + // now select the interface + // + Status = USBSTOR_SyncUrbRequest(DeviceExtension->LowerDeviceObject, Urb); + + // + // did it succeed + // + if (NT_SUCCESS(Status)) + { + // + // update configuration info + // + ASSERT(Urb->UrbSelectInterface.Interface.Length == DeviceExtension->InterfaceInformation->Length); + RtlCopyMemory(DeviceExtension->InterfaceInformation, &Urb->UrbSelectInterface.Interface, Urb->UrbSelectInterface.Interface.Length); + } + + // + // free interface list & urb + // + FreeItem(InterfaceList); + ExFreePoolWithTag(Urb, 0); + + // + // done + // + return Status; +} + +NTSTATUS +USBSTOR_GetPipeHandles( + IN PFDO_DEVICE_EXTENSION DeviceExtension) +{ + ULONG Index; + BOOLEAN BulkInFound = FALSE, BulkOutFound = FALSE; + + // + // no enumerate all pipes and extract bulk-in / bulk-out pipe handle + // + for(Index = 0; Index < DeviceExtension->InterfaceInformation->NumberOfPipes; Index++) + { + // + // check pipe type + // + if (DeviceExtension->InterfaceInformation->Pipes[Index].PipeType == UsbdPipeTypeBulk) + { + // + // check direction + // + if (USB_ENDPOINT_DIRECTION_IN(DeviceExtension->InterfaceInformation->Pipes[Index].EndpointAddress)) + { + // + // bulk in pipe + // + DeviceExtension->BulkInPipeIndex = Index; + + // + // there should not be another bulk in pipe + // + ASSERT(BulkInFound == FALSE); + BulkInFound = TRUE; + } + else + { + // + // bulk out pipe + // + DeviceExtension->BulkOutPipeIndex = Index; + + // + // there should not be another bulk out pipe + // + ASSERT(BulkOutFound == FALSE); + BulkOutFound = TRUE; + } + } + } + + // + // check if both bulk pipes have been found + // + if (!BulkInFound || !BulkOutFound) + { + // + // WTF? usb port driver does not give us bulk pipe access + // + DPRINT1("USBSTOR_GetPipeHandles> BulkInFound %c BulkOutFound %c missing!!!\n", BulkInFound, BulkOutFound); + return STATUS_DEVICE_CONFIGURATION_ERROR; + } + + // + // device is configured + // + return STATUS_SUCCESS; +} diff --git a/drivers/usb/usbstor_new/disk.c b/drivers/usb/usbstor_new/disk.c new file mode 100644 index 0000000000..604f621c91 --- /dev/null +++ b/drivers/usb/usbstor_new/disk.c @@ -0,0 +1,691 @@ +/* + * PROJECT: ReactOS Universal Serial Bus Bulk Storage Driver + * LICENSE: GPL - See COPYING in the top level directory + * FILE: drivers/usb/usbstor/disk.c + * PURPOSE: USB block storage device driver. + * PROGRAMMERS: + * James Tabor + * Michael Martin (michael.martin(a)reactos.org) + * Johannes Anderwald (johannes.anderwald(a)reactos.org) + */ + +#include "usbstor.h" + +#define NDEBUG +#include <debug.h> + +NTSTATUS +USBSTOR_HandleInternalDeviceControl( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PIO_STACK_LOCATION IoStack; + PSCSI_REQUEST_BLOCK Request; + PPDO_DEVICE_EXTENSION PDODeviceExtension; + NTSTATUS Status; + + // + // get current stack location + // + IoStack = IoGetCurrentIrpStackLocation(Irp); + + // + // get request block + // + Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1; + + // + // sanity check + // + ASSERT(Request); + + // + // get device extension + // + PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + // + // sanity check + // + ASSERT(PDODeviceExtension->Common.IsFDO == FALSE); + + switch(Request->Function) + { + case SRB_FUNCTION_EXECUTE_SCSI: + { + DPRINT("SRB_FUNCTION_EXECUTE_SCSI\n"); + + // + // check if request is valid + // + if (Request->SrbFlags & (SRB_FLAGS_DATA_IN | SRB_FLAGS_DATA_OUT)) + { + // + // data is transferred with this irp + // + if ((Request->SrbFlags & (SRB_FLAGS_DATA_IN | SRB_FLAGS_DATA_OUT)) == (SRB_FLAGS_DATA_IN | SRB_FLAGS_DATA_OUT) || + Request->DataTransferLength == 0 || + Irp->MdlAddress == NULL) + { + // + // invalid parameter + // + Status = STATUS_INVALID_PARAMETER; + break; + } + } + else + { + // + // sense buffer request + // + if (Request->DataTransferLength || + Request->DataBuffer || + Irp->MdlAddress) + { + // + // invalid parameter + // + Status = STATUS_INVALID_PARAMETER; + break; + } + } + + // + // add the request + // + if (!USBSTOR_QueueAddIrp(PDODeviceExtension->LowerDeviceObject, Irp)) + { + // + // irp was not added to the queue + // + IoStartPacket(PDODeviceExtension->LowerDeviceObject, Irp, &Request->QueueSortKey, USBSTOR_CancelIo); + } + + // + // irp pending + // + return STATUS_PENDING; + } + case SRB_FUNCTION_RELEASE_DEVICE: + { + DPRINT1("SRB_FUNCTION_RELEASE_DEVICE\n"); + // + // sanity check + // + ASSERT(PDODeviceExtension->Claimed == TRUE); + + // + // release claim + // + PDODeviceExtension->Claimed = FALSE; + Status = STATUS_SUCCESS; + break; + } + case SRB_FUNCTION_CLAIM_DEVICE: + { + DPRINT1("SRB_FUNCTION_CLAIM_DEVICE\n"); + // + // check if the device has been claimed + // + if (PDODeviceExtension->Claimed) + { + // + // device has already been claimed + // + Status = STATUS_DEVICE_BUSY; + Request->SrbStatus = SRB_STATUS_BUSY; + break; + } + + // + // claim device + // + PDODeviceExtension->Claimed = TRUE; + + // + // output device object + // + Request->DataBuffer = DeviceObject; + + // + // completed successfully + // + Status = STATUS_SUCCESS; + break; + } + case SRB_FUNCTION_RELEASE_QUEUE: + { + DPRINT1("SRB_FUNCTION_RELEASE_QUEUE\n"); + + // + // release queue + // + USBSTOR_QueueRelease(PDODeviceExtension->LowerDeviceObject); + + // + // set status success + // + Request->SrbStatus = SRB_STATUS_SUCCESS; + Status = STATUS_SUCCESS; + break; + } + + case SRB_FUNCTION_SHUTDOWN: + case SRB_FUNCTION_FLUSH: + case SRB_FUNCTION_FLUSH_QUEUE: + { + DPRINT1("SRB_FUNCTION_FLUSH / SRB_FUNCTION_FLUSH_QUEUE / SRB_FUNCTION_SHUTDOWN\n"); + + // HACK: don't flush pending requests +#if 0 // we really need a proper storage stack + // + // wait for pending requests to finish + // + USBSTOR_QueueWaitForPendingRequests(PDODeviceExtension->LowerDeviceObject); +#endif + // + // set status success + // + Request->SrbStatus = SRB_STATUS_SUCCESS; + Status = STATUS_SUCCESS; + break; + } + default: + { + // + // not supported + // + Status = STATUS_NOT_SUPPORTED; + Request->SrbStatus = SRB_STATUS_ERROR; + } + } + + // + // complete request + // + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; +} + +ULONG +USBSTOR_GetFieldLength( + IN PUCHAR Name, + IN ULONG MaxLength) +{ + ULONG Index; + ULONG LastCharacterPosition = 0; + + // + // scan the field and return last position which contains a valid character + // + for(Index = 0; Index < MaxLength; Index++) + { + if (Name[Index] != ' ') + { + // + // trim white spaces from field + // + LastCharacterPosition = Index; + } + } + + // + // convert from zero based index to length + // + return LastCharacterPosition + 1; +} + +NTSTATUS +USBSTOR_HandleQueryProperty( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PIO_STACK_LOCATION IoStack; + PSTORAGE_PROPERTY_QUERY PropertyQuery; + PSTORAGE_DESCRIPTOR_HEADER DescriptorHeader; + PSTORAGE_ADAPTER_DESCRIPTOR AdapterDescriptor; + ULONG FieldLengthVendor, FieldLengthProduct, FieldLengthRevision, TotalLength, FieldLengthSerialNumber; + PPDO_DEVICE_EXTENSION PDODeviceExtension; + PUFI_INQUIRY_RESPONSE InquiryData; + PSTORAGE_DEVICE_DESCRIPTOR DeviceDescriptor; + PUCHAR Buffer; + PFDO_DEVICE_EXTENSION FDODeviceExtension; + UNICODE_STRING SerialNumber; + ANSI_STRING AnsiString; + NTSTATUS Status; + + DPRINT("USBSTOR_HandleQueryProperty\n"); + + // + // get current stack location + // + IoStack = IoGetCurrentIrpStackLocation(Irp); + + // + // sanity check + // + ASSERT(IoStack->Parameters.DeviceIoControl.InputBufferLength >= sizeof(STORAGE_PROPERTY_QUERY)); + ASSERT(Irp->AssociatedIrp.SystemBuffer); + + // + // get property query + // + PropertyQuery = (PSTORAGE_PROPERTY_QUERY)Irp->AssociatedIrp.SystemBuffer; + + // + // check property type + // + if (PropertyQuery->PropertyId != StorageDeviceProperty && + PropertyQuery->PropertyId != StorageAdapterProperty) + { + // + // only device property / adapter property are supported + // + return STATUS_INVALID_PARAMETER_1; + } + + // + // check query type + // + if (PropertyQuery->QueryType == PropertyExistsQuery) + { + // + // device property / adapter property is supported + // + return STATUS_SUCCESS; + } + + if (PropertyQuery->QueryType != PropertyStandardQuery) + { + // + // only standard query and exists query are supported + // + return STATUS_INVALID_PARAMETER_2; + } + + // + // check if it is a device property + // + if (PropertyQuery->PropertyId == StorageDeviceProperty) + { + DPRINT("USBSTOR_HandleQueryProperty StorageDeviceProperty OutputBufferLength %lu\n", IoStack->Parameters.DeviceIoControl.OutputBufferLength); + + // + // get device extension + // + PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + ASSERT(PDODeviceExtension); + ASSERT(PDODeviceExtension->Common.IsFDO == FALSE); + + // + // get device extension + // + FDODeviceExtension = (PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension; + ASSERT(FDODeviceExtension); + ASSERT(FDODeviceExtension->Common.IsFDO); + + // + // get inquiry data + // + InquiryData = (PUFI_INQUIRY_RESPONSE)PDODeviceExtension->InquiryData; + ASSERT(InquiryData); + + // + // compute extra parameters length + // + FieldLengthVendor = USBSTOR_GetFieldLength(InquiryData->Vendor, 8); + FieldLengthProduct = USBSTOR_GetFieldLength(InquiryData->Product, 16); + FieldLengthRevision = USBSTOR_GetFieldLength(InquiryData->Revision, 4); + + // + // is there a serial number + // + if (FDODeviceExtension->SerialNumber) + { + // + // get length + // + FieldLengthSerialNumber = wcslen(FDODeviceExtension->SerialNumber->bString); + } + else + { + // + // no serial number + // + FieldLengthSerialNumber = 0; + } + + // + // total length required is sizeof(STORAGE_DEVICE_DESCRIPTOR) + FieldLength + 4 extra null bytes - 1 + // -1 due STORAGE_DEVICE_DESCRIPTOR contains one byte length of parameter data + // + TotalLength = sizeof(STORAGE_DEVICE_DESCRIPTOR) + FieldLengthVendor + FieldLengthProduct + FieldLengthRevision + FieldLengthSerialNumber + 3; + + // + // check if output buffer is long enough + // + if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < TotalLength) + { + // + // buffer too small + // + DescriptorHeader = (PSTORAGE_DESCRIPTOR_HEADER)Irp->AssociatedIrp.SystemBuffer; + ASSERT(IoStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(STORAGE_DESCRIPTOR_HEADER)); + + // + // return required size + // + DescriptorHeader->Version = TotalLength; + DescriptorHeader->Size = TotalLength; + + Irp->IoStatus.Information = sizeof(STORAGE_DESCRIPTOR_HEADER); + return STATUS_SUCCESS; + } + + // + // get device descriptor + // + DeviceDescriptor = (PSTORAGE_DEVICE_DESCRIPTOR)Irp->AssociatedIrp.SystemBuffer; + + // + // initialize device descriptor + // + DeviceDescriptor->Version = TotalLength; + DeviceDescriptor->Size = TotalLength; + DeviceDescriptor->DeviceType = InquiryData->DeviceType; + DeviceDescriptor->DeviceTypeModifier = (InquiryData->RMB & 0x7F); + DeviceDescriptor->RemovableMedia = (InquiryData->RMB & 0x80) ? TRUE : FALSE; + DeviceDescriptor->CommandQueueing = FALSE; + DeviceDescriptor->BusType = BusTypeUsb; + DeviceDescriptor->VendorIdOffset = sizeof(STORAGE_DEVICE_DESCRIPTOR) - sizeof(UCHAR); + DeviceDescriptor->ProductIdOffset = DeviceDescriptor->VendorIdOffset + FieldLengthVendor + 1; + DeviceDescriptor->ProductRevisionOffset = DeviceDescriptor->ProductIdOffset + FieldLengthProduct + 1; + DeviceDescriptor->SerialNumberOffset = (FieldLengthSerialNumber > 0 ? DeviceDescriptor->ProductRevisionOffset + FieldLengthRevision + 1 : 0); + DeviceDescriptor->RawPropertiesLength = FieldLengthVendor + FieldLengthProduct + FieldLengthRevision + FieldLengthSerialNumber + 3 + (FieldLengthSerialNumber > 0 ? + 1 : 0); + + // + // copy descriptors + // + Buffer = (PUCHAR)((ULONG_PTR)DeviceDescriptor + sizeof(STORAGE_DEVICE_DESCRIPTOR) - sizeof(UCHAR)); + + // + // copy vendor + // + RtlCopyMemory(Buffer, InquiryData->Vendor, FieldLengthVendor); + Buffer[FieldLengthVendor] = '\0'; + Buffer += FieldLengthVendor + 1; + + // + // copy product + // + RtlCopyMemory(Buffer, InquiryData->Product, FieldLengthProduct); + Buffer[FieldLengthProduct] = '\0'; + Buffer += FieldLengthProduct + 1; + + // + // copy revision + // + RtlCopyMemory(Buffer, InquiryData->Revision, FieldLengthRevision); + Buffer[FieldLengthRevision] = '\0'; + Buffer += FieldLengthRevision + 1; + + // + // copy serial number + // + if (FieldLengthSerialNumber) + { + // + // init unicode string + // + RtlInitUnicodeString(&SerialNumber, FDODeviceExtension->SerialNumber->bString); + + // + // init ansi string + // + AnsiString.Buffer = (PCHAR)Buffer; + AnsiString.Length = 0; + AnsiString.MaximumLength = FieldLengthSerialNumber * sizeof(WCHAR); + + // + // convert to ansi code + // + Status = RtlUnicodeStringToAnsiString(&AnsiString, &SerialNumber, FALSE); + ASSERT(Status == STATUS_SUCCESS); + } + + + DPRINT("Vendor %s\n", (LPCSTR)((ULONG_PTR)DeviceDescriptor + DeviceDescriptor->VendorIdOffset)); + DPRINT("Product %s\n", (LPCSTR)((ULONG_PTR)DeviceDescriptor + DeviceDescriptor->ProductIdOffset)); + DPRINT("Revision %s\n", (LPCSTR)((ULONG_PTR)DeviceDescriptor + DeviceDescriptor->ProductRevisionOffset)); + DPRINT("Serial %s\n", (LPCSTR)((ULONG_PTR)DeviceDescriptor + DeviceDescriptor->SerialNumberOffset)); + + // + // done + // + Irp->IoStatus.Information = TotalLength; + return STATUS_SUCCESS; + } + else + { + // + // adapter property query request + // + DPRINT("USBSTOR_HandleQueryProperty StorageAdapterProperty OutputBufferLength %lu\n", IoStack->Parameters.DeviceIoControl.OutputBufferLength); + + if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(STORAGE_ADAPTER_DESCRIPTOR)) + { + // + // buffer too small + // + DescriptorHeader = (PSTORAGE_DESCRIPTOR_HEADER)Irp->AssociatedIrp.SystemBuffer; + ASSERT(IoStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(STORAGE_DESCRIPTOR_HEADER)); + + // + // return required size + // + DescriptorHeader->Version = sizeof(STORAGE_ADAPTER_DESCRIPTOR); + DescriptorHeader->Size = sizeof(STORAGE_ADAPTER_DESCRIPTOR); + + Irp->IoStatus.Information = sizeof(STORAGE_DESCRIPTOR_HEADER); + return STATUS_SUCCESS; + } + + // + // get adapter descriptor, information is returned in the same buffer + // + AdapterDescriptor = (PSTORAGE_ADAPTER_DESCRIPTOR)Irp->AssociatedIrp.SystemBuffer; + + // + // fill out descriptor + // + AdapterDescriptor->Version = sizeof(STORAGE_ADAPTER_DESCRIPTOR); + AdapterDescriptor->Size = sizeof(STORAGE_ADAPTER_DESCRIPTOR); + AdapterDescriptor->MaximumTransferLength = MAXULONG; //FIXME compute some sane value + AdapterDescriptor->MaximumPhysicalPages = 25; //FIXME compute some sane value + AdapterDescriptor->AlignmentMask = 0; + AdapterDescriptor->AdapterUsesPio = FALSE; + AdapterDescriptor->AdapterScansDown = FALSE; + AdapterDescriptor->CommandQueueing = FALSE; + AdapterDescriptor->AcceleratedTransfer = FALSE; + AdapterDescriptor->BusType = BusTypeUsb; + AdapterDescriptor->BusMajorVersion = 0x2; //FIXME verify + AdapterDescriptor->BusMinorVersion = 0x00; //FIXME + + // + // store returned length + // + Irp->IoStatus.Information = sizeof(STORAGE_ADAPTER_DESCRIPTOR); + + // + // done + // + return STATUS_SUCCESS; + } +} + +NTSTATUS +USBSTOR_HandleDeviceControl( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PIO_STACK_LOCATION IoStack; + NTSTATUS Status; + PPDO_DEVICE_EXTENSION PDODeviceExtension; + PSCSI_ADAPTER_BUS_INFO BusInfo; + PSCSI_INQUIRY_DATA InquiryData; + PINQUIRYDATA ScsiInquiryData; + PUFI_INQUIRY_RESPONSE UFIInquiryResponse; + + // + // get current stack location + // + IoStack = IoGetCurrentIrpStackLocation(Irp); + + if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_STORAGE_QUERY_PROPERTY) + { + // + // query property + // + Status = USBSTOR_HandleQueryProperty(DeviceObject, Irp); + } + else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SCSI_PASS_THROUGH) + { + // + // query scsi pass through + // + DPRINT1("USBSTOR_HandleDeviceControl IOCTL_SCSI_PASS_THROUGH NOT implemented\n"); + Status = STATUS_NOT_SUPPORTED; + } + else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SCSI_PASS_THROUGH_DIRECT) + { + // + // query scsi pass through direct + // + DPRINT1("USBSTOR_HandleDeviceControl IOCTL_SCSI_PASS_THROUGH_DIRECT NOT implemented\n"); + Status = STATUS_NOT_SUPPORTED; + } + else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER) + { + // + // query serial number + // + DPRINT1("USBSTOR_HandleDeviceControl IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER NOT implemented\n"); + Status = STATUS_NOT_SUPPORTED; + } + else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SCSI_GET_CAPABILITIES) + { + PIO_SCSI_CAPABILITIES Capabilities; + + /* Legacy port capability query */ + if (IoStack->Parameters.DeviceIoControl.OutputBufferLength == sizeof(PVOID)) + { + Capabilities = *((PVOID *)Irp->AssociatedIrp.SystemBuffer) = ExAllocatePoolWithTag(NonPagedPool, + sizeof(IO_SCSI_CAPABILITIES), + USB_STOR_TAG); + Irp->IoStatus.Information = sizeof(PVOID); + } + else + { + Capabilities = Irp->AssociatedIrp.SystemBuffer; + Irp->IoStatus.Information = sizeof(IO_SCSI_CAPABILITIES); + } + + if (Capabilities) + { + Capabilities->MaximumTransferLength = MAXULONG; + Capabilities->MaximumPhysicalPages = 25; + Capabilities->SupportedAsynchronousEvents = 0; + Capabilities->AlignmentMask = 0; + Capabilities->TaggedQueuing = FALSE; + Capabilities->AdapterScansDown = FALSE; + Capabilities->AdapterUsesPio = FALSE; + Status = STATUS_SUCCESS; + } + else + { + Status = STATUS_INSUFFICIENT_RESOURCES; + } + } + else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SCSI_GET_INQUIRY_DATA) + { + // + // get device extension + // + PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + ASSERT(PDODeviceExtension); + ASSERT(PDODeviceExtension->Common.IsFDO == FALSE); + + // + // get parameters + // + BusInfo = Irp->AssociatedIrp.SystemBuffer; + InquiryData = (PSCSI_INQUIRY_DATA)(BusInfo + 1); + ScsiInquiryData = (PINQUIRYDATA)InquiryData->InquiryData; + + + // + // get inquiry data + // + UFIInquiryResponse = (PUFI_INQUIRY_RESPONSE)PDODeviceExtension->InquiryData; + ASSERT(UFIInquiryResponse); + + + BusInfo->NumberOfBuses = 1; + BusInfo->BusData[0].NumberOfLogicalUnits = 1; //FIXME + BusInfo->BusData[0].InitiatorBusId = 0; + BusInfo->BusData[0].InquiryDataOffset = sizeof(SCSI_ADAPTER_BUS_INFO); + + InquiryData->PathId = 0; + InquiryData->TargetId = 0; + InquiryData->Lun = PDODeviceExtension->LUN & MAX_LUN; + InquiryData->DeviceClaimed = PDODeviceExtension->Claimed; + InquiryData->InquiryDataLength = sizeof(INQUIRYDATA); + InquiryData->NextInquiryDataOffset = 0; + + RtlZeroMemory(ScsiInquiryData, sizeof(INQUIRYDATA)); + ScsiInquiryData->DeviceType = UFIInquiryResponse->DeviceType; + ScsiInquiryData->DeviceTypeQualifier = (UFIInquiryResponse->RMB & 0x7F); + + /* Hack for IoReadPartitionTable call in disk.sys */ + ScsiInquiryData->RemovableMedia = ((ScsiInquiryData->DeviceType != DIRECT_ACCESS_DEVICE) ? ((UFIInquiryResponse->RMB & 0x80) ? 1 : 0) : 0); + + ScsiInquiryData->Versions = 0x04; + ScsiInquiryData->ResponseDataFormat = 0x02; + ScsiInquiryData->AdditionalLength = 31; + ScsiInquiryData->SoftReset = 0; + ScsiInquiryData->CommandQueue = 0; + ScsiInquiryData->LinkedCommands = 0; + ScsiInquiryData->RelativeAddressing = 0; + + RtlCopyMemory(&ScsiInquiryData->VendorId, UFIInquiryResponse->Vendor, USBSTOR_GetFieldLength(UFIInquiryResponse->Vendor, 8)); + RtlCopyMemory(&ScsiInquiryData->ProductId, UFIInquiryResponse->Product, USBSTOR_GetFieldLength(UFIInquiryResponse->Product, 16)); + + Irp->IoStatus.Information = sizeof(SCSI_ADAPTER_BUS_INFO) + sizeof(SCSI_INQUIRY_DATA) + sizeof(INQUIRYDATA) - 1; + Status = STATUS_SUCCESS; + } + else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SCSI_GET_ADDRESS) + { + PSCSI_ADDRESS Address = Irp->AssociatedIrp.SystemBuffer; + + Address->Length = sizeof(SCSI_ADDRESS); + Address->PortNumber = 0; + Address->PathId = 0; + Address->TargetId = 0; + Address->Lun = (((PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LUN & MAX_LUN); + Irp->IoStatus.Information = sizeof(SCSI_ADDRESS); + + Status = STATUS_SUCCESS; + } + else + { + // + // unsupported + // + DPRINT("USBSTOR_HandleDeviceControl IoControl %x not supported\n", IoStack->Parameters.DeviceIoControl.IoControlCode); + Status = STATUS_NOT_SUPPORTED; + } + + return Status; +} diff --git a/drivers/usb/usbstor_new/error.c b/drivers/usb/usbstor_new/error.c new file mode 100644 index 0000000000..e920d353d1 --- /dev/null +++ b/drivers/usb/usbstor_new/error.c @@ -0,0 +1,410 @@ +/* + * PROJECT: ReactOS Universal Serial Bus Bulk Storage Driver + * LICENSE: GPL - See COPYING in the top level directory + * FILE: drivers/usb/usbstor/error.c + * PURPOSE: USB block storage device driver. + * PROGRAMMERS: + * James Tabor + * Michael Martin (michael.martin(a)reactos.org) + * Johannes Anderwald (johannes.anderwald(a)reactos.org) + */ + +#include "usbstor.h" + +#define NDEBUG +#include <debug.h> + +NTSTATUS +USBSTOR_GetEndpointStatus( + IN PDEVICE_OBJECT DeviceObject, + IN UCHAR bEndpointAddress, + OUT PUSHORT Value) +{ + PURB Urb; + NTSTATUS Status; + + // + // allocate urb + // + DPRINT("Allocating URB\n"); + Urb = (PURB)AllocateItem(NonPagedPool, sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST)); + if (!Urb) + { + // + // out of memory + // + DPRINT1("OutofMemory!\n"); + return STATUS_INSUFFICIENT_RESOURCES; + } + + // + // build status + // + UsbBuildGetStatusRequest(Urb, URB_FUNCTION_GET_STATUS_FROM_ENDPOINT, bEndpointAddress & 0x0F, Value, NULL, NULL); + + // + // send the request + // + DPRINT1("Sending Request DeviceObject %p, Urb %p\n", DeviceObject, Urb); + Status = USBSTOR_SyncUrbRequest(DeviceObject, Urb); + + // + // free urb + // + FreeItem(Urb); + + // + // done + // + return Status; +} + + + +NTSTATUS +USBSTOR_ResetPipeWithHandle( + IN PDEVICE_OBJECT DeviceObject, + IN USBD_PIPE_HANDLE PipeHandle) +{ + PURB Urb; + NTSTATUS Status; + + // + // allocate urb + // + DPRINT("Allocating URB\n"); + Urb = (PURB)AllocateItem(NonPagedPool, sizeof(struct _URB_PIPE_REQUEST)); + if (!Urb) + { + // + // out of memory + // + DPRINT1("OutofMemory!\n"); + return STATUS_INSUFFICIENT_RESOURCES; + } + + // + // initialize the urb + // + Urb->UrbPipeRequest.Hdr.Length = sizeof(struct _URB_PIPE_REQUEST); + Urb->UrbPipeRequest.Hdr.Function = URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL; + Urb->UrbPipeRequest.PipeHandle = PipeHandle; + + // + // send the request + // + DPRINT1("Sending Request DeviceObject %p, Urb %p\n", DeviceObject, Urb); + Status = USBSTOR_SyncUrbRequest(DeviceObject, Urb); + + // + // free urb + // + FreeItem(Urb); + + // + // done + // + return Status; +} + + +NTSTATUS +USBSTOR_HandleTransferError( + PDEVICE_OBJECT DeviceObject, + PIRP_CONTEXT Context) +{ + NTSTATUS Status = STATUS_SUCCESS; + PIO_STACK_LOCATION Stack; + PSCSI_REQUEST_BLOCK Request; + PCDB pCDB; + + // + // sanity checks + // + ASSERT(Context); + ASSERT(Context->PDODeviceExtension); + ASSERT(Context->PDODeviceExtension->Self); + ASSERT(Context->Irp); + + // + // first perform a mass storage reset step 1 in 5.3.4 USB Mass Storage Bulk Only Specification + // + Status = USBSTOR_ResetDevice(Context->FDODeviceExtension->LowerDeviceObject, Context->FDODeviceExtension); + if (NT_SUCCESS(Status)) + { + // + // step 2 reset bulk in pipe section 5.3.4 + // + Status = USBSTOR_ResetPipeWithHandle(Context->FDODeviceExtension->LowerDeviceObject, Context->FDODeviceExtension->InterfaceInformation->Pipes[Context->FDODeviceExtension->BulkInPipeIndex].PipeHandle); + if (NT_SUCCESS(Status)) + { + // + // finally reset bulk out pipe + // + Status = USBSTOR_ResetPipeWithHandle(Context->FDODeviceExtension->LowerDeviceObject, Context->FDODeviceExtension->InterfaceInformation->Pipes[Context->FDODeviceExtension->BulkOutPipeIndex].PipeHandle); + } + } + + // + // get next stack location + // + Stack = IoGetCurrentIrpStackLocation(Context->Irp); + + // + // get request block + // + Request = (PSCSI_REQUEST_BLOCK)Stack->Parameters.Others.Argument1; + ASSERT(Request); + + // + // obtain request type + // + pCDB = (PCDB)Request->Cdb; + ASSERT(pCDB); + + if (Status != STATUS_SUCCESS || Context->RetryCount >= 1) + { + // + // Complete the master IRP + // + Context->Irp->IoStatus.Status = Status; + Context->Irp->IoStatus.Information = 0; + USBSTOR_QueueTerminateRequest(Context->PDODeviceExtension->LowerDeviceObject, Context->Irp); + IoCompleteRequest(Context->Irp, IO_NO_INCREMENT); + + // + // Start the next request + // + USBSTOR_QueueNextRequest(Context->PDODeviceExtension->LowerDeviceObject); + + // + // srb handling finished + // + Context->FDODeviceExtension->SrbErrorHandlingActive = FALSE; + + // + // clear timer srb + // + Context->FDODeviceExtension->LastTimerActiveSrb = NULL; + } + else + { + DPRINT1("Retrying Count %lu %p\n", Context->RetryCount, Context->PDODeviceExtension->Self); + + // + // re-schedule request + // + USBSTOR_HandleExecuteSCSI(Context->PDODeviceExtension->Self, Context->Irp, Context->RetryCount + 1); + + // + // srb error handling finished + // + Context->FDODeviceExtension->SrbErrorHandlingActive = FALSE; + + // + // srb error handling finished + // + Context->FDODeviceExtension->TimerWorkQueueEnabled = TRUE; + + // + // clear timer srb + // + Context->FDODeviceExtension->LastTimerActiveSrb = NULL; + } + + // + // cleanup irp context + // + FreeItem(Context->cbw); + FreeItem(Context); + + + DPRINT1("USBSTOR_HandleTransferError returning with Status %x\n", Status); + return Status; +} + +VOID +NTAPI +USBSTOR_ResetHandlerWorkItemRoutine( + PVOID Context) +{ + NTSTATUS Status; + PERRORHANDLER_WORKITEM_DATA WorkItemData = (PERRORHANDLER_WORKITEM_DATA)Context; + + // + // clear stall on BulkIn pipe + // + Status = USBSTOR_ResetPipeWithHandle(WorkItemData->Context->FDODeviceExtension->LowerDeviceObject, WorkItemData->Context->FDODeviceExtension->InterfaceInformation->Pipes[WorkItemData->Context->FDODeviceExtension->BulkInPipeIndex].PipeHandle); + DPRINT1("USBSTOR_ResetPipeWithHandle Status %x\n", Status); + + // + // now resend the csw as the stall got cleared + // + USBSTOR_SendCSW(WorkItemData->Context, WorkItemData->Irp); +} + +VOID +NTAPI +ErrorHandlerWorkItemRoutine( + PVOID Context) +{ + PERRORHANDLER_WORKITEM_DATA WorkItemData = (PERRORHANDLER_WORKITEM_DATA)Context; + + if (WorkItemData->Context->ErrorIndex == 2) + { + // + // reset device + // + USBSTOR_HandleTransferError(WorkItemData->DeviceObject, WorkItemData->Context); + } + else + { + // + // clear stall + // + USBSTOR_ResetHandlerWorkItemRoutine(WorkItemData); + } + + // + // Free Work Item Data + // + ExFreePoolWithTag(WorkItemData, USB_STOR_TAG); +} + +VOID +NTAPI +USBSTOR_TimerWorkerRoutine( + IN PVOID Context) +{ + PFDO_DEVICE_EXTENSION FDODeviceExtension; + NTSTATUS Status; + PERRORHANDLER_WORKITEM_DATA WorkItemData = (PERRORHANDLER_WORKITEM_DATA)Context; + + // + // get device extension + // + FDODeviceExtension = (PFDO_DEVICE_EXTENSION)WorkItemData->DeviceObject->DeviceExtension; + ASSERT(FDODeviceExtension->Common.IsFDO); + + // + // first perform a mass storage reset step 1 in 5.3.4 USB Mass Storage Bulk Only Specification + // + Status = USBSTOR_ResetDevice(FDODeviceExtension->LowerDeviceObject, FDODeviceExtension); + if (NT_SUCCESS(Status)) + { + // + // step 2 reset bulk in pipe section 5.3.4 + // + Status = USBSTOR_ResetPipeWithHandle(FDODeviceExtension->LowerDeviceObject, FDODeviceExtension->InterfaceInformation->Pipes[FDODeviceExtension->BulkInPipeIndex].PipeHandle); + if (NT_SUCCESS(Status)) + { + // + // finally reset bulk out pipe + // + Status = USBSTOR_ResetPipeWithHandle(FDODeviceExtension->LowerDeviceObject, FDODeviceExtension->InterfaceInformation->Pipes[FDODeviceExtension->BulkOutPipeIndex].PipeHandle); + } + } + DPRINT1("Status %x\n", Status); + + // + // clear timer srb + // + FDODeviceExtension->LastTimerActiveSrb = NULL; + + // + // re-schedule request + // + //USBSTOR_HandleExecuteSCSI(WorkItemData->Context->PDODeviceExtension->Self, WorkItemData->Context->Irp, Context->RetryCount + 1); + + + + // + // do not retry for the same packet again + // + FDODeviceExtension->TimerWorkQueueEnabled = FALSE; + + // + // Free Work Item Data + // + ExFreePoolWithTag(WorkItemData, USB_STOR_TAG); +} + + +VOID +NTAPI +USBSTOR_TimerRoutine( + PDEVICE_OBJECT DeviceObject, + PVOID Context) +{ + PFDO_DEVICE_EXTENSION FDODeviceExtension; + BOOLEAN ResetDevice = FALSE; + PERRORHANDLER_WORKITEM_DATA WorkItemData; + + // + // get device extension + // + FDODeviceExtension = (PFDO_DEVICE_EXTENSION)Context; + DPRINT1("[USBSTOR] TimerRoutine entered\n"); + DPRINT1("[USBSTOR] ActiveSrb %p ResetInProgress %x LastTimerActiveSrb %p\n", FDODeviceExtension->ActiveSrb, FDODeviceExtension->ResetInProgress, FDODeviceExtension->LastTimerActiveSrb); + + // + // acquire spinlock + // + KeAcquireSpinLockAtDpcLevel(&FDODeviceExtension->IrpListLock); + + // + // is there an active srb and no global reset is in progress + // + if (FDODeviceExtension->ActiveSrb && FDODeviceExtension->ResetInProgress == FALSE && FDODeviceExtension->TimerWorkQueueEnabled) + { + if (FDODeviceExtension->LastTimerActiveSrb != NULL && FDODeviceExtension->LastTimerActiveSrb == FDODeviceExtension->ActiveSrb) + { + // + // check if empty + // + DPRINT1("[USBSTOR] ActiveSrb %p hang detected\n", FDODeviceExtension->ActiveSrb); + ResetDevice = TRUE; + } + else + { + // + // update pointer + // + FDODeviceExtension->LastTimerActiveSrb = FDODeviceExtension->ActiveSrb; + } + } + else + { + // + // reset srb + // + FDODeviceExtension->LastTimerActiveSrb = NULL; + } + + // + // release lock + // + KeReleaseSpinLockFromDpcLevel(&FDODeviceExtension->IrpListLock); + + + if (ResetDevice && FDODeviceExtension->TimerWorkQueueEnabled && FDODeviceExtension->SrbErrorHandlingActive == FALSE) + { + WorkItemData = ExAllocatePoolWithTag(NonPagedPool, + sizeof(ERRORHANDLER_WORKITEM_DATA), + USB_STOR_TAG); + if (WorkItemData) + { + // + // Initialize and queue the work item to handle the error + // + ExInitializeWorkItem(&WorkItemData->WorkQueueItem, + USBSTOR_TimerWorkerRoutine, + WorkItemData); + + WorkItemData->DeviceObject = FDODeviceExtension->FunctionalDeviceObject; + + DPRINT1("[USBSTOR] Queing Timer WorkItem\n"); + ExQueueWorkItem(&WorkItemData->WorkQueueItem, DelayedWorkQueue); + } + } +} diff --git a/drivers/usb/usbstor_new/fdo.c b/drivers/usb/usbstor_new/fdo.c new file mode 100644 index 0000000000..e3707041f5 --- /dev/null +++ b/drivers/usb/usbstor_new/fdo.c @@ -0,0 +1,461 @@ +/* + * PROJECT: ReactOS Universal Serial Bus Bulk Storage Driver + * LICENSE: GPL - See COPYING in the top level directory + * FILE: drivers/usb/usbstor/fdo.c + * PURPOSE: USB block storage device driver. + * PROGRAMMERS: + * James Tabor + * Michael Martin (michael.martin(a)reactos.org) + * Johannes Anderwald (johannes.anderwald(a)reactos.org) + */ + +#include "usbstor.h" + +#define NDEBUG +#include <debug.h> + +VOID +USBSTOR_DumpDeviceDescriptor(PUSB_DEVICE_DESCRIPTOR DeviceDescriptor) +{ + DPRINT1("Dumping Device Descriptor %p\n", DeviceDescriptor); + DPRINT1("bLength %x\n", DeviceDescriptor->bLength); + DPRINT1("bDescriptorType %x\n", DeviceDescriptor->bDescriptorType); + DPRINT1("bcdUSB %x\n", DeviceDescriptor->bcdUSB); + DPRINT1("bDeviceClass %x\n", DeviceDescriptor->bDeviceClass); + DPRINT1("bDeviceSubClass %x\n", DeviceDescriptor->bDeviceSubClass); + DPRINT1("bDeviceProtocol %x\n", DeviceDescriptor->bDeviceProtocol); + DPRINT1("bMaxPacketSize0 %x\n", DeviceDescriptor->bMaxPacketSize0); + DPRINT1("idVendor %x\n", DeviceDescriptor->idVendor); + DPRINT1("idProduct %x\n", DeviceDescriptor->idProduct); + DPRINT1("bcdDevice %x\n", DeviceDescriptor->bcdDevice); + DPRINT1("iManufacturer %x\n", DeviceDescriptor->iManufacturer); + DPRINT1("iProduct %x\n", DeviceDescriptor->iProduct); + DPRINT1("iSerialNumber %x\n", DeviceDescriptor->iSerialNumber); + DPRINT1("bNumConfigurations %x\n", DeviceDescriptor->bNumConfigurations); +} + +NTSTATUS +USBSTOR_FdoHandleDeviceRelations( + IN PFDO_DEVICE_EXTENSION DeviceExtension, + IN OUT PIRP Irp) +{ + ULONG DeviceCount = 0; + LONG Index; + PDEVICE_RELATIONS DeviceRelations; + PIO_STACK_LOCATION IoStack; + + // + // get current irp stack location + // + IoStack = IoGetCurrentIrpStackLocation(Irp); + + // + // check if relation type is BusRelations + // + if (IoStack->Parameters.QueryDeviceRelations.Type != BusRelations) + { + // + // FDO always only handles bus relations + // + return USBSTOR_SyncForwardIrp(DeviceExtension->LowerDeviceObject, Irp); + } + + // + // go through array and count device objects + // + for (Index = 0; Index < max(DeviceExtension->MaxLUN, 1); Index++) + { + if (DeviceExtension->ChildPDO[Index]) + { + // + // child pdo + // + DeviceCount++; + } + } + + // + // allocate device relations + // + DeviceRelations = (PDEVICE_RELATIONS)AllocateItem(PagedPool, sizeof(DEVICE_RELATIONS) + (DeviceCount > 1 ? (DeviceCount-1) * sizeof(PDEVICE_OBJECT) : 0)); + if (!DeviceRelations) + { + // + // no memory + // + return STATUS_INSUFFICIENT_RESOURCES; + } + + // + // add device objects + // + for(Index = 0; Index < max(DeviceExtension->MaxLUN, 1); Index++) + { + if (DeviceExtension->ChildPDO[Index]) + { + // + // store child pdo + // + DeviceRelations->Objects[DeviceRelations->Count] = DeviceExtension->ChildPDO[Index]; + + // + // add reference + // + ObReferenceObject(DeviceExtension->ChildPDO[Index]); + + // + // increment count + // + DeviceRelations->Count++; + } + } + + // + // store result + // + Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations; + + // + // request completed successfully + // + return STATUS_SUCCESS; +} + +NTSTATUS +USBSTOR_FdoHandleRemoveDevice( + IN PDEVICE_OBJECT DeviceObject, + IN PFDO_DEVICE_EXTENSION DeviceExtension, + IN OUT PIRP Irp) +{ + NTSTATUS Status; + ULONG Index; + + DPRINT("Handling FDO removal %p\n", DeviceObject); + + /* FIXME: wait for devices finished processing */ + for(Index = 0; Index < 16; Index++) + { + if (DeviceExtension->ChildPDO[Index] != NULL) + { + DPRINT("Deleting PDO %p RefCount %x AttachedDevice %p \n", DeviceExtension->ChildPDO[Index], DeviceExtension->ChildPDO[Index]->ReferenceCount, DeviceExtension->ChildPDO[Index]->AttachedDevice); + IoDeleteDevice(DeviceExtension->ChildPDO[Index]); + } + } + + /* Send the IRP down the stack */ + IoSkipCurrentIrpStackLocation(Irp); + Status = IoCallDriver(DeviceExtension->LowerDeviceObject, Irp); + + /* Detach from the device stack */ + IoDetachDevice(DeviceExtension->LowerDeviceObject); + + /* Delete the device object */ + IoDeleteDevice(DeviceObject); + + return Status; +} + +NTSTATUS +USBSTOR_FdoHandleStartDevice( + IN PDEVICE_OBJECT DeviceObject, + IN PFDO_DEVICE_EXTENSION DeviceExtension, + IN OUT PIRP Irp) +{ + PUSB_INTERFACE_DESCRIPTOR InterfaceDesc; + NTSTATUS Status; + UCHAR Index = 0; + + // + // forward irp to lower device + // + Status = USBSTOR_SyncForwardIrp(DeviceExtension->LowerDeviceObject, Irp); + if (!NT_SUCCESS(Status)) + { + // + // failed to start + // + DPRINT1("USBSTOR_FdoHandleStartDevice Lower device failed to start %x\n", Status); + return Status; + } + + // + // initialize irp queue + // + USBSTOR_QueueInitialize(DeviceExtension); + + // + // first get device & configuration & string descriptor + // + Status = USBSTOR_GetDescriptors(DeviceObject); + if (!NT_SUCCESS(Status)) + { + // + // failed to get device descriptor + // + DPRINT1("USBSTOR_FdoHandleStartDevice failed to get device descriptor with %x\n", Status); + return Status; + } + + // + // dump device descriptor + // + USBSTOR_DumpDeviceDescriptor(DeviceExtension->DeviceDescriptor); + + // + // Check that this device uses bulk transfers and is SCSI + // + InterfaceDesc = (PUSB_INTERFACE_DESCRIPTOR)((ULONG_PTR)DeviceExtension->ConfigurationDescriptor + sizeof(USB_CONFIGURATION_DESCRIPTOR)); + + // + // sanity check + // + ASSERT(InterfaceDesc->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE); + ASSERT(InterfaceDesc->bLength == sizeof(USB_INTERFACE_DESCRIPTOR)); + + DPRINT("bInterfaceSubClass %x\n", InterfaceDesc->bInterfaceSubClass); + if (InterfaceDesc->bInterfaceProtocol != 0x50) + { + DPRINT1("USB Device is not a bulk only device and is not currently supported\n"); + return STATUS_NOT_SUPPORTED; + } + + if (InterfaceDesc->bInterfaceSubClass != 0x06) + { + // + // FIXME: need to pad CDBs to 12 byte + // mode select commands must be translated from 1AH / 15h to 5AH / 55h + // + DPRINT1("[USBSTOR] Error: need to pad CDBs\n"); + return STATUS_NOT_IMPLEMENTED; + } + + // + // now select an interface + // + Status = USBSTOR_SelectConfigurationAndInterface(DeviceObject, DeviceExtension); + if (!NT_SUCCESS(Status)) + { + // + // failed to get device descriptor + // + DPRINT1("USBSTOR_FdoHandleStartDevice failed to select configuration / interface with %x\n", Status); + return Status; + } + + // + // check if we got a bulk in + bulk out endpoint + // + Status = USBSTOR_GetPipeHandles(DeviceExtension); + if (!NT_SUCCESS(Status)) + { + // + // failed to get pipe handles descriptor + // + DPRINT1("USBSTOR_FdoHandleStartDevice no pipe handles %x\n", Status); + return Status; + } + + // + // get num of lun which are supported + // + Status = USBSTOR_GetMaxLUN(DeviceExtension->LowerDeviceObject, DeviceExtension); + if (!NT_SUCCESS(Status)) + { + // + // failed to get max LUN + // + DPRINT1("USBSTOR_FdoHandleStartDevice failed to get max lun %x\n", Status); + return Status; + } + + // + // now create for each LUN a device object, 1 minimum + // + do + { + // + // create pdo + // + Status = USBSTOR_CreatePDO(DeviceObject, Index); + + // + // check for failure + // + if (!NT_SUCCESS(Status)) + { + // + // failed to create child pdo + // + DPRINT1("USBSTOR_FdoHandleStartDevice USBSTOR_CreatePDO failed for Index %lu with Status %x\n", Index, Status); + return Status; + } + + // + // increment pdo index + // + Index++; + DeviceExtension->InstanceCount++; + + }while(Index < DeviceExtension->MaxLUN); + +#if 0 + // + // finally get usb device interface + // + Status = USBSTOR_GetBusInterface(DeviceExtension->LowerDeviceObject, &DeviceExtension->BusInterface); + if (!NT_SUCCESS(Status)) + { + // + // failed to device interface + // + DPRINT1("USBSTOR_FdoHandleStartDevice failed to get device interface %x\n", Status); + return Status; + } +#endif + + + // + // start the timer + // + //IoStartTimer(DeviceObject); + + + // + // fdo is now initialized + // + DPRINT("USBSTOR_FdoHandleStartDevice FDO is initialized\n"); + return STATUS_SUCCESS; +} + +NTSTATUS +USBSTOR_FdoHandlePnp( + IN PDEVICE_OBJECT DeviceObject, + IN OUT PIRP Irp) +{ + PIO_STACK_LOCATION IoStack; + PFDO_DEVICE_EXTENSION DeviceExtension; + NTSTATUS Status; + + // + // get current stack location + // + IoStack = IoGetCurrentIrpStackLocation(Irp); + + // + // get device extension + // + DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + // + // sanity check + // + ASSERT(DeviceExtension->Common.IsFDO); + + switch(IoStack->MinorFunction) + { + case IRP_MN_SURPRISE_REMOVAL: + { + DPRINT("IRP_MN_SURPRISE_REMOVAL %p\n", DeviceObject); + Irp->IoStatus.Status = STATUS_SUCCESS; + + // + // forward irp to next device object + // + IoSkipCurrentIrpStackLocation(Irp); + return IoCallDriver(DeviceExtension->LowerDeviceObject, Irp); + } + case IRP_MN_QUERY_DEVICE_RELATIONS: + { + DPRINT("IRP_MN_QUERY_DEVICE_RELATIONS %p\n", DeviceObject); + Status = USBSTOR_FdoHandleDeviceRelations(DeviceExtension, Irp); + break; + } + case IRP_MN_STOP_DEVICE: + { + DPRINT1("USBSTOR_FdoHandlePnp: IRP_MN_STOP_DEVICE unimplemented\n"); + IoStopTimer(DeviceObject); + Irp->IoStatus.Status = STATUS_SUCCESS; + + // + // forward irp to next device object + // + IoSkipCurrentIrpStackLocation(Irp); + return IoCallDriver(DeviceExtension->LowerDeviceObject, Irp); + } + case IRP_MN_REMOVE_DEVICE: + { + DPRINT("IRP_MN_REMOVE_DEVICE\n"); + + return USBSTOR_FdoHandleRemoveDevice(DeviceObject, DeviceExtension, Irp); + } + case IRP_MN_QUERY_CAPABILITIES: + { + // + // FIXME: set custom capabilities + // + IoSkipCurrentIrpStackLocation(Irp); + return IoCallDriver(DeviceExtension->LowerDeviceObject, Irp); + } + case IRP_MN_QUERY_STOP_DEVICE: + case IRP_MN_QUERY_REMOVE_DEVICE: + { +#if 0 + // + // we can if nothing is pending + // + if (DeviceExtension->IrpPendingCount != 0 || + DeviceExtension->ActiveSrb != NULL) +#else + if (TRUE) +#endif + { + /* We have pending requests */ + DPRINT1("Failing removal/stop request due to pending requests present\n"); + Status = STATUS_UNSUCCESSFUL; + } + else + { + /* We're all clear */ + Irp->IoStatus.Status = STATUS_SUCCESS; + + IoSkipCurrentIrpStackLocation(Irp); + return IoCallDriver(DeviceExtension->LowerDeviceObject, Irp); + } + break; + } + case IRP_MN_START_DEVICE: + { + Status = USBSTOR_FdoHandleStartDevice(DeviceObject, DeviceExtension, Irp); + break; + } + default: + { + // + // forward irp to next device object + // + IoSkipCurrentIrpStackLocation(Irp); + return IoCallDriver(DeviceExtension->LowerDeviceObject, Irp); + } + } + + // + // complete request + // + if (Status != STATUS_PENDING) + { + // + // store result + // + Irp->IoStatus.Status = Status; + + // + // complete request + // + IoCompleteRequest(Irp, IO_NO_INCREMENT); + } + + // + // done processing + // + return Status; +} diff --git a/drivers/usb/usbstor_new/guid.c b/drivers/usb/usbstor_new/guid.c new file mode 100644 index 0000000000..2fd41c6e0b --- /dev/null +++ b/drivers/usb/usbstor_new/guid.c @@ -0,0 +1,9 @@ +/* DO NOT USE THE PRECOMPILED HEADER FOR THIS FILE! */ + +#include <ntdef.h> +#include <miniport.h> +#include <usb.h> +#include <initguid.h> +#include <usbbusif.h> + +/* NO CODE HERE, THIS IS JUST REQUIRED FOR THE GUID DEFINITIONS */ diff --git a/drivers/usb/usbstor_new/misc.c b/drivers/usb/usbstor_new/misc.c new file mode 100644 index 0000000000..6b60cf828e --- /dev/null +++ b/drivers/usb/usbstor_new/misc.c @@ -0,0 +1,520 @@ +/* + * PROJECT: ReactOS Universal Serial Bus Bulk Storage Driver + * LICENSE: GPL - See COPYING in the top level directory + * FILE: drivers/usb/usbstor/misc.c + * PURPOSE: USB block storage device driver. + * PROGRAMMERS: + * James Tabor + * Michael Martin (michael.martin(a)reactos.org) + * Johannes Anderwald (johannes.anderwald(a)reactos.org) + */ + +#include "usbstor.h" + +#define NDEBUG +#include <debug.h> + +// +// driver verifier +// +IO_COMPLETION_ROUTINE SyncForwardIrpCompletionRoutine; + +NTSTATUS +NTAPI +USBSTOR_SyncForwardIrpCompletionRoutine( + PDEVICE_OBJECT DeviceObject, + PIRP Irp, + PVOID Context) +{ + if (Irp->PendingReturned) + { + KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE); + } + return STATUS_MORE_PROCESSING_REQUIRED; +} + +NTSTATUS +NTAPI +USBSTOR_SyncForwardIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp) +{ + KEVENT Event; + NTSTATUS Status; + + // + // initialize event + // + KeInitializeEvent(&Event, NotificationEvent, FALSE); + + // + // copy irp stack location + // + IoCopyCurrentIrpStackLocationToNext(Irp); + + // + // set completion routine + // + IoSetCompletionRoutine(Irp, USBSTOR_SyncForwardIrpCompletionRoutine, &Event, TRUE, TRUE, TRUE); + + + // + // call driver + // + Status = IoCallDriver(DeviceObject, Irp); + + // + // check if pending + // + if (Status == STATUS_PENDING) + { + // + // wait for the request to finish + // + KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); + + // + // copy status code + // + Status = Irp->IoStatus.Status; + } + + // + // done + // + return Status; +} + +NTSTATUS +NTAPI +USBSTOR_GetBusInterface( + IN PDEVICE_OBJECT DeviceObject, + OUT PUSB_BUS_INTERFACE_USBDI_V2 BusInterface) +{ + KEVENT Event; + NTSTATUS Status; + PIRP Irp; + IO_STATUS_BLOCK IoStatus; + PIO_STACK_LOCATION Stack; + + // + // sanity checks + // + ASSERT(DeviceObject); + ASSERT(BusInterface); + + + // + // initialize event + // + KeInitializeEvent(&Event, NotificationEvent, FALSE); + + + // + // create irp + // + Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP, + DeviceObject, + NULL, + 0, + NULL, + &Event, + &IoStatus); + + // + // was irp built + // + if (Irp == NULL) + { + // + // no memory + // + return STATUS_INSUFFICIENT_RESOURCES; + } + + // + // initialize request + // + Stack=IoGetNextIrpStackLocation(Irp); + Stack->MajorFunction = IRP_MJ_PNP; + Stack->MinorFunction = IRP_MN_QUERY_INTERFACE; + Stack->Parameters.QueryInterface.Size = sizeof(BUS_INTERFACE_STANDARD); + Stack->Parameters.QueryInterface.InterfaceType = (LPGUID)&USB_BUS_INTERFACE_USBDI_GUID; + Stack->Parameters.QueryInterface.Version = 2; + Stack->Parameters.QueryInterface.Interface = (PINTERFACE)BusInterface; + Stack->Parameters.QueryInterface.InterfaceSpecificData = NULL; + Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; + + // + // call driver + // + Status= IoCallDriver(DeviceObject, Irp); + + // + // did operation complete + // + if (Status == STATUS_PENDING) + { + // + // wait for completion + // + KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); + + // + // collect status + // + Status=IoStatus.Status; + } + + return Status; +} + +NTSTATUS +USBSTOR_SyncUrbRequest( + IN PDEVICE_OBJECT DeviceObject, + OUT PURB UrbRequest) +{ + PIRP Irp; + PIO_STACK_LOCATION IoStack; + KEVENT Event; + NTSTATUS Status; + + // + // allocate irp + // + Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE); + if (!Irp) + { + // + // no memory + // + return STATUS_INSUFFICIENT_RESOURCES; + } + + // + // initialize event + // + KeInitializeEvent(&Event, NotificationEvent, FALSE); + + + // + // get next stack location + // + IoStack = IoGetNextIrpStackLocation(Irp); + + // + // initialize stack location + // + IoStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; + IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB; + IoStack->Parameters.Others.Argument1 = (PVOID)UrbRequest; + IoStack->Parameters.DeviceIoControl.InputBufferLength = UrbRequest->UrbHeader.Length; + Irp->IoStatus.Status = STATUS_SUCCESS; + + // + // setup completion routine + // + IoSetCompletionRoutine(Irp, USBSTOR_SyncForwardIrpCompletionRoutine, &Event, TRUE, TRUE, TRUE); + + // + // call driver + // + Status = IoCallDriver(DeviceObject, Irp); + + // + // check if request is pending + // + if (Status == STATUS_PENDING) + { + // + // wait for completion + // + KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); + + // + // update status + // + Status = Irp->IoStatus.Status; + } + + // + // free irp + // + IoFreeIrp(Irp); + + // + // done + // + return Status; +} + +PVOID +AllocateItem( + IN POOL_TYPE PoolType, + IN ULONG ItemSize) +{ + // + // allocate item + // + PVOID Item = ExAllocatePoolWithTag(PoolType, ItemSize, USB_STOR_TAG); + + if (Item) + { + // + // zero item + // + RtlZeroMemory(Item, ItemSize); + } + + // + // return element + // + return Item; +} + +VOID +FreeItem( + IN PVOID Item) +{ + // + // free item + // + ExFreePoolWithTag(Item, USB_STOR_TAG); +} + +NTSTATUS +USBSTOR_ClassRequest( + IN PDEVICE_OBJECT DeviceObject, + IN PFDO_DEVICE_EXTENSION DeviceExtension, + IN UCHAR RequestType, + IN USHORT Index, + IN ULONG TransferFlags, + IN ULONG TransferBufferLength, + IN PVOID TransferBuffer) + +{ + PURB Urb; + NTSTATUS Status; + + // + // first allocate urb + // + Urb = (PURB)AllocateItem(NonPagedPool, sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST)); + if (!Urb) + { + // + // no memory + // + return STATUS_INSUFFICIENT_RESOURCES; + } + + // + // initialize vendor request + // + Urb->UrbControlVendorClassRequest.Hdr.Length = sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST); + Urb->UrbControlVendorClassRequest.Hdr.Function = URB_FUNCTION_CLASS_INTERFACE; + Urb->UrbControlVendorClassRequest.TransferFlags = TransferFlags; + Urb->UrbControlVendorClassRequest.TransferBufferLength = TransferBufferLength; + Urb->UrbControlVendorClassRequest.TransferBuffer = TransferBuffer; + Urb->UrbControlVendorClassRequest.Request = RequestType; + Urb->UrbControlVendorClassRequest.Index = Index; + + // + // submit request + // + Status = USBSTOR_SyncUrbRequest(DeviceObject, Urb); + + // + // free urb + // + FreeItem(Urb); + + // + // done + // + return Status; +} + + +NTSTATUS +USBSTOR_GetMaxLUN( + IN PDEVICE_OBJECT DeviceObject, + IN PFDO_DEVICE_EXTENSION DeviceExtension) +{ + PUCHAR Buffer; + NTSTATUS Status; + + // + // allocate 1-byte buffer + // + Buffer = (PUCHAR)AllocateItem(NonPagedPool, sizeof(UCHAR)); + if (!Buffer) + { + // + // no memory + // + FreeItem(Buffer); + return STATUS_INSUFFICIENT_RESOURCES; + } + + // + // execute request + // + Status = USBSTOR_ClassRequest(DeviceObject, DeviceExtension, USB_BULK_GET_MAX_LUN, DeviceExtension->InterfaceInformation->InterfaceNumber, USBD_TRANSFER_DIRECTION_IN, sizeof(UCHAR), Buffer); + + DPRINT("MaxLUN: %x\n", *Buffer); + + if (NT_SUCCESS(Status)) + { + if (*Buffer > 0xF) + { + // + // invalid response documented in usb mass storage specification + // + Status = STATUS_DEVICE_DATA_ERROR; + } + else + { + // + // store maxlun + // + DeviceExtension->MaxLUN = *Buffer; + } + } + else + { + // + // "USB Mass Storage Class. Bulk-Only Transport. Revision 1.0" + // 3.2 Get Max LUN (class-specific request) : + // Devices that do not support multiple LUNs may STALL this command. + // + USBSTOR_ResetDevice(DeviceExtension->LowerDeviceObject, DeviceExtension); + + DeviceExtension->MaxLUN = 0; + Status = STATUS_SUCCESS; + } + + // + // free buffer + // + FreeItem(Buffer); + + // + // done + // + return Status; + +} + +NTSTATUS +USBSTOR_ResetDevice( + IN PDEVICE_OBJECT DeviceObject, + IN PFDO_DEVICE_EXTENSION DeviceExtension) +{ + NTSTATUS Status; + + // + // execute request + // + Status = USBSTOR_ClassRequest(DeviceObject, DeviceExtension, USB_BULK_RESET_DEVICE, DeviceExtension->InterfaceInformation->InterfaceNumber, USBD_TRANSFER_DIRECTION_OUT, 0, NULL); + + // + // done + // + return Status; + +} + +BOOLEAN +USBSTOR_IsFloppy( + IN PUCHAR Buffer, + IN ULONG BufferLength, + OUT PUCHAR MediumTypeCode) +{ + PUFI_CAPACITY_FORMAT_HEADER FormatHeader; + PUFI_CAPACITY_DESCRIPTOR Descriptor; + ULONG Length, Index, BlockCount, BlockLength; + + // + // get format header + // + FormatHeader = (PUFI_CAPACITY_FORMAT_HEADER)Buffer; + + // + // sanity checks + // + ASSERT(FormatHeader->Reserved1 == 0x00); + ASSERT(FormatHeader->Reserved2 == 0x00); + ASSERT(FormatHeader->Reserved3 == 0x00); + + // + // is there capacity data + // + if (!FormatHeader->CapacityLength) + { + // + // no data provided + // + DPRINT1("[USBSTOR] No capacity length\n"); + return FALSE; + } + + // + // the format header are always 8 bytes in length + // + ASSERT((FormatHeader->CapacityLength & 0x7) == 0); + DPRINT1("CapacityLength %x\n", FormatHeader->CapacityLength); + + // + // grab length and locate first descriptor + // + Length = FormatHeader->CapacityLength; + Descriptor = (PUFI_CAPACITY_DESCRIPTOR)(FormatHeader + 1); + for(Index = 0; Index < Length / sizeof(UFI_CAPACITY_DESCRIPTOR); Index++) + { + // + // blocks are little endian format + // + BlockCount = NTOHL(Descriptor->BlockCount); + + // + // get block length + // + BlockLength = NTOHL((Descriptor->BlockLengthByte0 << 24 | Descriptor->BlockLengthByte1 << 16 | Descriptor->BlockLengthByte2 << 8)); + + DPRINT1("BlockCount %x BlockLength %x Code %x\n", BlockCount, BlockLength, Descriptor->Code); + + if (BlockLength == 512 && BlockCount == 1440) + { + // + // 720 KB DD + // + *MediumTypeCode = 0x1E; + return TRUE; + } + else if (BlockLength == 1024 && BlockCount == 1232) + { + // + // 1,25 MB + // + *MediumTypeCode = 0x93; + return TRUE; + } + else if (BlockLength == 512 && BlockCount == 2880) + { + // + // 1,44MB KB DD + // + *MediumTypeCode = 0x94; + return TRUE; + } + + // + // move to next descriptor + // + Descriptor = (Descriptor + 1); + } + + // + // no floppy detected + // + return FALSE; +} diff --git a/drivers/usb/usbstor_new/pdo.c b/drivers/usb/usbstor_new/pdo.c new file mode 100644 index 0000000000..6ce5d8f746 --- /dev/null +++ b/drivers/usb/usbstor_new/pdo.c @@ -0,0 +1,1376 @@ +/* + * PROJECT: ReactOS Universal Serial Bus Bulk Storage Driver + * LICENSE: GPL - See COPYING in the top level directory + * FILE: drivers/usb/usbstor/pdo.c + * PURPOSE: USB block storage device driver. + * PROGRAMMERS: + * James Tabor + * Michael Martin (michael.martin(a)reactos.org) + * Johannes Anderwald (johannes.anderwald(a)reactos.org) + */ + +#include "usbstor.h" + +#define NDEBUG +#include <debug.h> + +LPCSTR +USBSTOR_GetDeviceType( + IN PUFI_INQUIRY_RESPONSE InquiryData, + IN UCHAR IsFloppy) +{ + // + // check if device type is zero + // + if (InquiryData->DeviceType == 0) + { + if (IsFloppy) + { + // + // floppy device + // + return "SFloppy"; + } + + // + // direct access device + // + return "Disk"; + } + + // + // FIXME: use constant - derived from
http://en.wikipedia.org/wiki/SCSI_Peripheral_Device_Type
+ // + switch (InquiryData->DeviceType) + { + case 1: + { + // + // sequential device, i.e magnetic tape + // + return "Sequential"; + } + case 4: + { + // + // write once device + // + return "Worm"; + } + case 5: + { + // + // CDROM device + // + return "CdRom"; + } + case 7: + { + // + // optical memory device + // + return "Optical"; + } + case 8: + { + // + // medium change device + // + return "Changer"; + } + default: + { + // + // other device + // + return "Other"; + } + } +} + +LPCSTR +USBSTOR_GetGenericType( + IN PUFI_INQUIRY_RESPONSE InquiryData, + IN UCHAR IsFloppy) +{ + // + // check if device type is zero + // + if (InquiryData->DeviceType == 0) + { + if (IsFloppy) + { + // + // floppy device + // + return "GenSFloppy"; + } + + // + // direct access device + // + return "GenDisk"; + } + + // + // FIXME: use constant - derived from
http://en.wikipedia.org/wiki/SCSI_Peripheral_Device_Type
+ // + switch (InquiryData->DeviceType) + { + case 1: + { + // + // sequential device, i.e magnetic tape + // + return "GenSequential"; + } + case 4: + { + // + // write once device + // + return "GenWorm"; + } + case 5: + { + // + // CDROM device + // + return "GenCdRom"; + } + case 7: + { + // + // optical memory device + // + return "GenOptical"; + } + case 8: + { + // + // medium change device + // + return "GenChanger"; + } + default: + { + // + // other device + // + return "UsbstorOther"; + } + } +} + + +ULONG +CopyField( + IN PUCHAR Name, + IN PCHAR Buffer, + IN ULONG MaxLength) +{ + ULONG Index; + + for(Index = 0; Index < MaxLength; Index++) + { + if (Name[Index] <= ' ' || Name[Index] >= 0x7F /* last printable ascii character */ || Name[Index] == ',') + { + // + // convert to underscore + // + Buffer[Index] = '_'; + } + else + { + // + // just copy character + // + Buffer[Index] = Name[Index]; + } + } + + return MaxLength; +} + +NTSTATUS +USBSTOR_PdoHandleQueryDeviceText( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + //PPDO_DEVICE_EXTENSION DeviceExtension; + PIO_STACK_LOCATION IoStack; + LPWSTR Buffer; + static WCHAR DeviceText[] = L"USB Mass Storage Device"; + + // + // get current stack location + // + IoStack = IoGetCurrentIrpStackLocation(Irp); + + if (IoStack->Parameters.QueryDeviceText.DeviceTextType == DeviceTextDescription) + { + DPRINT("USBSTOR_PdoHandleQueryDeviceText DeviceTextDescription\n"); + + // + // allocate item + // + Buffer = (LPWSTR)AllocateItem(PagedPool, sizeof(DeviceText)); + if (!Buffer) + { + // + // no memory + // + Irp->IoStatus.Information = 0; + return STATUS_INSUFFICIENT_RESOURCES; + } + + // + // copy buffer + // + wcscpy(Buffer, DeviceText); + + // + // save result + // + Irp->IoStatus.Information = (ULONG_PTR)Buffer; + return STATUS_SUCCESS; + } + else + { + DPRINT("USBSTOR_PdoHandleQueryDeviceText DeviceTextLocationInformation\n"); + + // + // allocate item + // + Buffer = (LPWSTR)AllocateItem(PagedPool, sizeof(DeviceText)); + if (!Buffer) + { + // + // no memory + // + Irp->IoStatus.Information = 0; + return STATUS_INSUFFICIENT_RESOURCES; + } + + // + // copy buffer + // + wcscpy(Buffer, DeviceText); + + // + // save result + // + Irp->IoStatus.Information = (ULONG_PTR)Buffer; + return STATUS_SUCCESS; + } + +} + + +NTSTATUS +USBSTOR_PdoHandleQueryDeviceId( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PPDO_DEVICE_EXTENSION DeviceExtension; + NTSTATUS Status; + CHAR Buffer[100]; + LPCSTR DeviceType; + ULONG Offset = 0; + PUFI_INQUIRY_RESPONSE InquiryData; + ANSI_STRING AnsiString; + UNICODE_STRING DeviceId; + + // + // get device extension + // + DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + // + // sanity check + // + ASSERT(DeviceExtension->InquiryData); + + // + // get inquiry data + // + InquiryData = (PUFI_INQUIRY_RESPONSE)DeviceExtension->InquiryData; + + // + // get device type + // + DeviceType = USBSTOR_GetDeviceType(InquiryData, DeviceExtension->IsFloppy); + + // + // zero buffer + // + RtlZeroMemory(Buffer, sizeof(Buffer)); + + // + // lets create device string + // + Offset = sprintf(&Buffer[Offset], "USBSTOR\\"); + Offset += sprintf(&Buffer[Offset], DeviceType); + Offset += sprintf(&Buffer[Offset], "&Ven_"); + Offset += CopyField(InquiryData->Vendor, &Buffer[Offset], 8); + Offset += sprintf(&Buffer[Offset], "&Prod_"); + Offset += CopyField(InquiryData->Product, &Buffer[Offset], 16); + Offset += sprintf(&Buffer[Offset], "&Rev_"); + Offset += CopyField(InquiryData->Revision, &Buffer[Offset], 4); + + // + // now initialize ansi string + // + RtlInitAnsiString(&AnsiString, (PCSZ)Buffer); + + // + // allocate DeviceId string + // + DeviceId.Length = 0; + DeviceId.MaximumLength = (strlen((PCHAR)Buffer) + 1) * sizeof(WCHAR); + DeviceId.Buffer = (LPWSTR)AllocateItem(PagedPool, DeviceId.MaximumLength); + if (!DeviceId.Buffer) + { + // + // no memory + // + Irp->IoStatus.Information = 0; + return STATUS_INSUFFICIENT_RESOURCES; + } + + + // + // convert to unicode + // + Status = RtlAnsiStringToUnicodeString(&DeviceId, &AnsiString, FALSE); + + if (NT_SUCCESS(Status)) + { + // + // store result + // + Irp->IoStatus.Information = (ULONG_PTR)DeviceId.Buffer; + } + + DPRINT("DeviceId %wZ Status %x\n", &DeviceId, Status); + + // + // done + // + return Status; +} + +VOID +USBSTOR_ConvertToUnicodeString( + IN CHAR * Buffer, + IN ULONG ResultBufferLength, + IN ULONG ResultBufferOffset, + OUT LPWSTR ResultBuffer, + OUT PULONG NewResultBufferOffset) +{ + UNICODE_STRING DeviceString; + ANSI_STRING AnsiString; + NTSTATUS Status; + + ASSERT(ResultBufferLength); + ASSERT(ResultBufferLength > ResultBufferOffset); + + DPRINT("ResultBufferOffset %lu ResultBufferLength %lu Buffer %s Length %lu\n", ResultBufferOffset, ResultBufferLength, Buffer, strlen(Buffer)); + + // + // construct destination string + // + DeviceString.Buffer = &ResultBuffer[ResultBufferOffset]; + DeviceString.Length = 0; + DeviceString.MaximumLength = (ResultBufferLength - ResultBufferOffset) * sizeof(WCHAR); + + // + // initialize source string + // + RtlInitAnsiString(&AnsiString, Buffer); + + // + // convert to unicode + // + Status = RtlAnsiStringToUnicodeString(&DeviceString, &AnsiString, FALSE); + ASSERT(Status == STATUS_SUCCESS); + + // + // subtract consumed bytes + // + ResultBufferLength -= (DeviceString.Length + sizeof(WCHAR)) / sizeof(WCHAR); + ResultBufferOffset += (DeviceString.Length + sizeof(WCHAR)) / sizeof(WCHAR); + + // + // store new offset + // + *NewResultBufferOffset = ResultBufferOffset; +} + + + +NTSTATUS +USBSTOR_PdoHandleQueryHardwareId( + IN PDEVICE_OBJECT DeviceObject, + IN OUT PIRP Irp) +{ + PPDO_DEVICE_EXTENSION PDODeviceExtension; + PFDO_DEVICE_EXTENSION FDODeviceExtension; + LPCSTR GenericType, DeviceType; + LPWSTR Buffer; + CHAR Id1[50], Id2[50], Id3[50], Id4[50], Id5[50], Id6[50]; + ULONG Id1Length, Id2Length, Id3Length, Id4Length, Id5Length,Id6Length; + ULONG Offset, TotalLength, Length; + PUFI_INQUIRY_RESPONSE InquiryData; + + // + // get PDO device extension + // + PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + // + // get FDO device extension + // + FDODeviceExtension = (PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension; + + // + // sanity check + // + ASSERT(FDODeviceExtension->DeviceDescriptor); + + // + // get inquiry data + // + InquiryData = (PUFI_INQUIRY_RESPONSE)PDODeviceExtension->InquiryData; + + + // + // get device type and generic type + // + DeviceType = USBSTOR_GetDeviceType(InquiryData, PDODeviceExtension->IsFloppy); + GenericType = USBSTOR_GetGenericType(InquiryData, PDODeviceExtension->IsFloppy); + + ASSERT(GenericType); + + // + // generate id 1 + // USBSTOR\SCSIType_Vendor(8)_Product(16)_Revision(4) + // + RtlZeroMemory(Id1, sizeof(Id1)); + Offset = 0; + Offset = sprintf(&Id1[Offset], "USBSTOR\\"); + Offset += sprintf(&Id1[Offset], DeviceType); + Offset += CopyField(InquiryData->Vendor, &Id1[Offset], 8); + Offset += CopyField(InquiryData->Product, &Id1[Offset], 16); + Offset += CopyField(InquiryData->Revision, &Id1[Offset], 4); + Id1Length = strlen(Id1) + 1; + DPRINT("USBSTOR_PdoHandleQueryHardwareId HardwareId1 %s\n", Id1); + + // + // generate id 2 + // USBSTOR\SCSIType_VENDOR(8)_Product(16) + // + RtlZeroMemory(Id2, sizeof(Id2)); + Offset = 0; + Offset = sprintf(&Id2[Offset], "USBSTOR\\"); + Offset += sprintf(&Id2[Offset], DeviceType); + Offset += CopyField(InquiryData->Vendor, &Id2[Offset], 8); + Offset += CopyField(InquiryData->Product, &Id2[Offset], 16); + Id2Length = strlen(Id2) + 1; + DPRINT("USBSTOR_PdoHandleQueryHardwareId HardwareId2 %s\n", Id2); + + // + // generate id 3 + // USBSTOR\SCSIType_VENDOR(8) + // + RtlZeroMemory(Id3, sizeof(Id3)); + Offset = 0; + Offset = sprintf(&Id3[Offset], "USBSTOR\\"); + Offset += sprintf(&Id3[Offset], DeviceType); + Offset += CopyField(InquiryData->Vendor, &Id3[Offset], 8); + Id3Length = strlen(Id3) + 1; + DPRINT("USBSTOR_PdoHandleQueryHardwareId HardwareId3 %s\n", Id3); + + // + // generate id 4 + // USBSTOR\SCSIType_VENDOR(8)_Product(16)_Revision(1) + // + RtlZeroMemory(Id4, sizeof(Id4)); + Offset = 0; + Offset = sprintf(&Id4[Offset], "USBSTOR\\"); + Offset += sprintf(&Id4[Offset], DeviceType); + Offset += CopyField(InquiryData->Vendor, &Id4[Offset], 8); + Offset += CopyField(InquiryData->Product, &Id4[Offset], 16); + Offset += CopyField(InquiryData->Revision, &Id4[Offset], 1); + Id4Length = strlen(Id4) + 1; + DPRINT("USBSTOR_PdoHandleQueryHardwareId HardwareId4 %s\n", Id4); + + // + // generate id 5 + // USBSTOR\SCSIType + // + RtlZeroMemory(Id5, sizeof(Id5)); + Offset = 0; + Offset = sprintf(&Id5[Offset], "USBSTOR\\"); + Offset += sprintf(&Id5[Offset], GenericType); + Id5Length = strlen(Id5) + 1; + DPRINT("USBSTOR_PdoHandleQueryHardwareId HardwareId5 %s\n", Id5); + + // + // generate id 6 + // SCSIType + // + RtlZeroMemory(Id6, sizeof(Id6)); + Offset = 0; + Offset = sprintf(&Id6[Offset], GenericType); + Id6Length = strlen(Id6) + 1; + DPRINT("USBSTOR_PdoHandleQueryHardwareId HardwareId6 %s\n", Id6); + + // + // compute total length + // + TotalLength = Id1Length + Id2Length + Id3Length + Id4Length + Id5Length + Id6Length + 1; + + // + // allocate buffer + // + Buffer = (LPWSTR)AllocateItem(PagedPool, TotalLength * sizeof(WCHAR)); + if (!Buffer) + { + // + // no memory + // + Irp->IoStatus.Information = 0; + return STATUS_INSUFFICIENT_RESOURCES; + } + + // + // reset offset + // + Offset = 0; + Length = TotalLength; + + USBSTOR_ConvertToUnicodeString(Id1, Length, Offset, Buffer, &Offset); + USBSTOR_ConvertToUnicodeString(Id2, Length, Offset, Buffer, &Offset); + USBSTOR_ConvertToUnicodeString(Id3, Length, Offset, Buffer, &Offset); + USBSTOR_ConvertToUnicodeString(Id4, Length, Offset, Buffer, &Offset); + USBSTOR_ConvertToUnicodeString(Id5, Length, Offset, Buffer, &Offset); + USBSTOR_ConvertToUnicodeString(Id6, Length, Offset, Buffer, &Offset); + + // + // sanity check + // + ASSERT(Offset + 1 == Length); + + // + // store result + // + Irp->IoStatus.Information = (ULONG_PTR)Buffer; + + // + // done + // + return STATUS_SUCCESS; +} + +NTSTATUS +USBSTOR_PdoHandleQueryCompatibleId( + IN PDEVICE_OBJECT DeviceObject, + IN OUT PIRP Irp) +{ + PPDO_DEVICE_EXTENSION PDODeviceExtension; + PFDO_DEVICE_EXTENSION FDODeviceExtension; + CHAR Buffer[100]; + ULONG Length, Offset; + LPWSTR InstanceId; + LPCSTR DeviceType; + + // + // get PDO device extension + // + PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + // + // get FDO device extension + // + FDODeviceExtension = (PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension; + + // + // sanity check + // + ASSERT(FDODeviceExtension->DeviceDescriptor); + + // + // get target device type + // + DeviceType = USBSTOR_GetDeviceType((PUFI_INQUIRY_RESPONSE)PDODeviceExtension->InquiryData, PDODeviceExtension->IsFloppy); + + // + // zero memory + // + RtlZeroMemory(Buffer, sizeof(Buffer)); + + // + // format instance id + // + Length = sprintf(Buffer, "USBSTOR\\%s", DeviceType) + 1; + Length += sprintf(&Buffer[Length], "USBSTOR\\%s", "RAW") + 2; + + // + // allocate instance id + // + InstanceId = (LPWSTR)AllocateItem(PagedPool, Length * sizeof(WCHAR)); + if (!InstanceId) + { + // + // no memory + // + Irp->IoStatus.Information = 0; + return STATUS_INSUFFICIENT_RESOURCES; + } + + USBSTOR_ConvertToUnicodeString(Buffer, Length, 0, InstanceId, &Offset); + USBSTOR_ConvertToUnicodeString(&Buffer[Offset], Length, Offset, InstanceId, &Offset); + + DPRINT("USBSTOR_PdoHandleQueryCompatibleId %S\n", InstanceId); + + // + // store result + // + Irp->IoStatus.Information = (ULONG_PTR)InstanceId; + + // + // completed successfully + // + return STATUS_SUCCESS; +} + +NTSTATUS +USBSTOR_PdoHandleQueryInstanceId( + IN PDEVICE_OBJECT DeviceObject, + IN OUT PIRP Irp) +{ + PPDO_DEVICE_EXTENSION PDODeviceExtension; + PFDO_DEVICE_EXTENSION FDODeviceExtension; + WCHAR Buffer[100]; + ULONG Length; + LPWSTR InstanceId; + + // + // get PDO device extension + // + PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + // + // get FDO device extension + // + FDODeviceExtension = (PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension; + + // + // format instance id + // + if (FDODeviceExtension->SerialNumber) + { + // + // using serial number from device + // + swprintf(Buffer, L"%s&%c", FDODeviceExtension->SerialNumber->bString, PDODeviceExtension->LUN); + } + else + { + // + // use instance count and LUN + // + swprintf(Buffer, L"%04lu&%c", FDODeviceExtension->InstanceCount, PDODeviceExtension->LUN); + } + + // + // calculate length + // + Length = wcslen(Buffer) + 1; + + // + // allocate instance id + // + InstanceId = (LPWSTR)AllocateItem(PagedPool, Length * sizeof(WCHAR)); + if (!InstanceId) + { + // + // no memory + // + Irp->IoStatus.Information = 0; + return STATUS_INSUFFICIENT_RESOURCES; + } + + // + // copy instance id + // + wcscpy(InstanceId, Buffer); + + DPRINT("USBSTOR_PdoHandleQueryInstanceId %S\n", InstanceId); + + // + // store result + // + Irp->IoStatus.Information = (ULONG_PTR)InstanceId; + + // + // completed successfully + // + return STATUS_SUCCESS; +} + +NTSTATUS +USBSTOR_PdoHandleDeviceRelations( + IN PDEVICE_OBJECT DeviceObject, + IN OUT PIRP Irp) +{ + PDEVICE_RELATIONS DeviceRelations; + PIO_STACK_LOCATION IoStack; + + DPRINT("USBSTOR_PdoHandleDeviceRelations\n"); + + // + // get current irp stack location + // + IoStack = IoGetCurrentIrpStackLocation(Irp); + + // + // check if relation type is BusRelations + // + if (IoStack->Parameters.QueryDeviceRelations.Type != TargetDeviceRelation) + { + // + // PDO handles only target device relation + // + return Irp->IoStatus.Status; + } + + // + // allocate device relations + // + DeviceRelations = (PDEVICE_RELATIONS)AllocateItem(PagedPool, sizeof(DEVICE_RELATIONS)); + if (!DeviceRelations) + { + // + // no memory + // + return STATUS_INSUFFICIENT_RESOURCES; + } + + // + // initialize device relations + // + DeviceRelations->Count = 1; + DeviceRelations->Objects[0] = DeviceObject; + ObReferenceObject(DeviceObject); + + // + // store result + // + Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations; + + // + // completed successfully + // + return STATUS_SUCCESS; +} + + +NTSTATUS +USBSTOR_PdoHandlePnp( + IN PDEVICE_OBJECT DeviceObject, + IN OUT PIRP Irp) +{ + PIO_STACK_LOCATION IoStack; + PPDO_DEVICE_EXTENSION DeviceExtension; + NTSTATUS Status; + PDEVICE_CAPABILITIES Caps; + ULONG bDelete; + + // + // get current stack location + // + IoStack = IoGetCurrentIrpStackLocation(Irp); + + // + // get device extension + // + DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + // + // sanity check + // + ASSERT(DeviceExtension->Common.IsFDO == FALSE); + + switch(IoStack->MinorFunction) + { + case IRP_MN_QUERY_DEVICE_RELATIONS: + { + Status = USBSTOR_PdoHandleDeviceRelations(DeviceObject, Irp); + break; + } + case IRP_MN_QUERY_DEVICE_TEXT: + { + Status = USBSTOR_PdoHandleQueryDeviceText(DeviceObject, Irp); + break; + } + case IRP_MN_QUERY_ID: + { + if (IoStack->Parameters.QueryId.IdType == BusQueryDeviceID) + { + // + // handle query device id + // + Status = USBSTOR_PdoHandleQueryDeviceId(DeviceObject, Irp); + break; + } + else if (IoStack->Parameters.QueryId.IdType == BusQueryHardwareIDs) + { + // + // handle instance id + // + Status = USBSTOR_PdoHandleQueryHardwareId(DeviceObject, Irp); + break; + } + else if (IoStack->Parameters.QueryId.IdType == BusQueryInstanceID) + { + // + // handle instance id + // + Status = USBSTOR_PdoHandleQueryInstanceId(DeviceObject, Irp); + break; + } + else if (IoStack->Parameters.QueryId.IdType == BusQueryCompatibleIDs) + { + // + // handle instance id + // + Status = USBSTOR_PdoHandleQueryCompatibleId(DeviceObject, Irp); + break; + } + + DPRINT1("USBSTOR_PdoHandlePnp: IRP_MN_QUERY_ID IdType %x unimplemented\n", IoStack->Parameters.QueryId.IdType); + Status = STATUS_NOT_SUPPORTED; + Irp->IoStatus.Information = 0; + break; + } + case IRP_MN_REMOVE_DEVICE: + { + DPRINT("IRP_MN_REMOVE_DEVICE\n"); + + if(*DeviceExtension->PDODeviceObject != NULL) + { + // + // clear entry in FDO pdo list + // + *DeviceExtension->PDODeviceObject = NULL; + bDelete = TRUE; + } + else + { + // + // device object already marked for deletion + // + bDelete = FALSE; + } + + /* Complete the IRP */ + Irp->IoStatus.Status = STATUS_SUCCESS; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + if (bDelete) + { + /* Delete the device object */ + IoDeleteDevice(DeviceObject); + } + return STATUS_SUCCESS; + } + case IRP_MN_QUERY_CAPABILITIES: + { + // + // just forward irp to lower device + // + Status = USBSTOR_SyncForwardIrp(DeviceExtension->LowerDeviceObject, Irp); + ASSERT(Status == STATUS_SUCCESS); + + if (NT_SUCCESS(Status)) + { + // + // check if no unique id + // + Caps = (PDEVICE_CAPABILITIES)IoStack->Parameters.DeviceCapabilities.Capabilities; + Caps->UniqueID = FALSE; // no unique id is supported + Caps->Removable = TRUE; //FIXME + } + break; + } + case IRP_MN_QUERY_REMOVE_DEVICE: + case IRP_MN_QUERY_STOP_DEVICE: + { +#if 0 + // + // if we're not claimed it's ok + // + if (DeviceExtension->Claimed) +#else + if (TRUE) +#endif + { + Status = STATUS_UNSUCCESSFUL; + DPRINT1("[USBSTOR] Request %x fails because device is still claimed\n", IoStack->MinorFunction); + } + else + Status = STATUS_SUCCESS; + break; + } + case IRP_MN_START_DEVICE: + { + // + // no-op for PDO + // + Status = STATUS_SUCCESS; + break; + } + case IRP_MN_SURPRISE_REMOVAL: + { + Status = STATUS_SUCCESS; + break; + } + default: + { + // + // do nothing + // + Status = Irp->IoStatus.Status; + } + } + + // + // complete request + // + if (Status != STATUS_PENDING) + { + // + // store result + // + Irp->IoStatus.Status = Status; + + // + // complete request + // + IoCompleteRequest(Irp, IO_NO_INCREMENT); + } + + // + // done processing + // + return Status; +} + +NTSTATUS +NTAPI +USBSTOR_CompletionRoutine( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PVOID Ctx) +{ + PKEVENT Event = (PKEVENT)Ctx; + + // + // signal event + // + KeSetEvent(Event, 0, FALSE); + return STATUS_MORE_PROCESSING_REQUIRED; +} + +NTSTATUS +USBSTOR_AllocateIrp( + IN PDEVICE_OBJECT DeviceObject, + IN ULONG DataTransferLength, + IN UCHAR OpCode, + IN PKEVENT Event, + OUT PSCSI_REQUEST_BLOCK *OutRequest, + OUT PIRP *OutIrp) +{ + PIRP Irp; + PIO_STACK_LOCATION IoStack; + PSCSI_REQUEST_BLOCK Request; + PCDB pCDB; + + // + // allocate irp + // + Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE); + if (!Irp) + { + // + // no memory + // + return STATUS_INSUFFICIENT_RESOURCES; + } + + // + // get next stack location + // + IoStack = IoGetNextIrpStackLocation(Irp); + + // + // create scsi block + // + Request = ExAllocatePoolWithTag(NonPagedPool, + sizeof(SCSI_REQUEST_BLOCK), + USB_STOR_TAG); + if (!Request) + { + // + // no memory + // + IoFreeIrp(Irp); + return STATUS_INSUFFICIENT_RESOURCES; + } + + // + // init request + // + RtlZeroMemory(Request, sizeof(SCSI_REQUEST_BLOCK)); + + // + // allocate data transfer block + // + Request->DataBuffer = ExAllocatePoolWithTag(NonPagedPool, + DataTransferLength, + USB_STOR_TAG); + if (!Request->DataBuffer) + { + // + // no memory + // + IoFreeIrp(Irp); + ExFreePoolWithTag(Request, USB_STOR_TAG); + return STATUS_INSUFFICIENT_RESOURCES; + } + + // + // allocate MDL + // + Irp->MdlAddress = IoAllocateMdl(Request->DataBuffer, DataTransferLength, FALSE, FALSE, NULL); + if (!Irp->MdlAddress) + { + // + // no memory + // + IoFreeIrp(Irp); + ExFreePoolWithTag(Request->DataBuffer, USB_STOR_TAG); + ExFreePoolWithTag(Request, USB_STOR_TAG); + return STATUS_INSUFFICIENT_RESOURCES; + } + + // + // non paged pool + // + MmBuildMdlForNonPagedPool(Irp->MdlAddress); + + // + // init scsi block + // + Request->DataTransferLength = DataTransferLength; + Request->Function = SRB_FUNCTION_EXECUTE_SCSI; + Request->SrbFlags = SRB_FLAGS_DATA_IN; + + RtlZeroMemory(Request->DataBuffer, DataTransferLength); + + + // + // get SCSI command data block + // + pCDB = (PCDB)Request->Cdb; + + // + // set op code + // + pCDB->AsByte[0] = OpCode; + + // + // store result + // + IoStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; + IoStack->Parameters.Others.Argument1 = Request; + IoStack->DeviceObject = DeviceObject; + + // + // init event + // + KeInitializeEvent(Event, NotificationEvent, FALSE); + + // + // lets setup a completion routine + // + IoSetCompletionRoutine(Irp, USBSTOR_CompletionRoutine, (PVOID)Event, TRUE, TRUE, TRUE); + + // + // output result + // + *OutIrp = Irp; + *OutRequest = Request; + return STATUS_SUCCESS; +} + +NTSTATUS +USBSTOR_SendIrp( + IN PDEVICE_OBJECT PDODeviceObject, + IN ULONG DataTransferLength, + IN UCHAR OpCode, + OUT PVOID *OutData) +{ + NTSTATUS Status; + PIRP Irp; + KEVENT Event; + PPDO_DEVICE_EXTENSION PDODeviceExtension; + PSCSI_REQUEST_BLOCK Request; + + // + // let's allocate an irp + // + Status = USBSTOR_AllocateIrp(PDODeviceObject, DataTransferLength, OpCode, &Event, &Request, &Irp); + if (!NT_SUCCESS(Status)) + { + // + // failed + // + DPRINT1("[USBSTOR] Failed to build irp\n"); + return Status; + } + + // + // get device extension + // + PDODeviceExtension = (PPDO_DEVICE_EXTENSION)PDODeviceObject->DeviceExtension; + + // + // send irp + // + ASSERT(Irp); + ASSERT(PDODeviceExtension->LowerDeviceObject); + Status = IoCallDriver(PDODeviceExtension->Self, Irp); + + if (Status == STATUS_PENDING) + { + // + // wait for completion + // + KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); + Status = Irp->IoStatus.Status; + } + + if (NT_SUCCESS(Status)) + { + // + // store result + // + *OutData = Request->DataBuffer; + } + else + { + // + // free the data + // + ExFreePoolWithTag(Request->DataBuffer, USB_STOR_TAG); + *OutData = NULL; + } + + // + // free resources + // + ExFreePoolWithTag(Request, USB_STOR_TAG); + IoFreeMdl(Irp->MdlAddress); + IoFreeIrp(Irp); + return Status; +} + +NTSTATUS +USBSTOR_SendInquiryIrp( + IN PDEVICE_OBJECT PDODeviceObject) +{ + NTSTATUS Status; + PPDO_DEVICE_EXTENSION PDODeviceExtension; + PUFI_INQUIRY_RESPONSE Response; + + // + // get device extension + // + PDODeviceExtension = (PPDO_DEVICE_EXTENSION)PDODeviceObject->DeviceExtension; + + // + // send request + // + Status = USBSTOR_SendIrp(PDODeviceObject, sizeof(UFI_INQUIRY_RESPONSE), SCSIOP_INQUIRY, (PVOID*)&Response); + if (!NT_SUCCESS(Status)) + { + // + // command failed + // + DPRINT1("USBSTOR_SendInquiryIrp Failed with %x\n", Status); + return Status; + } + + DPRINT1("Response %p\n", Response); + DPRINT1("DeviceType %x\n", Response->DeviceType); + DPRINT1("RMB %x\n", Response->RMB); + DPRINT1("Version %x\n", Response->Version); + DPRINT1("Format %x\n", Response->Format); + DPRINT1("Length %x\n", Response->Length); + DPRINT1("Reserved %p\n", Response->Reserved); + DPRINT1("Vendor %c%c%c%c%c%c%c%c\n", Response->Vendor[0], Response->Vendor[1], Response->Vendor[2], Response->Vendor[3], Response->Vendor[4], Response->Vendor[5], Response->Vendor[6], Response->Vendor[7]); + DPRINT1("Product %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n", Response->Product[0], Response->Product[1], Response->Product[2], Response->Product[3], + Response->Product[4], Response->Product[5], Response->Product[6], Response->Product[7], + Response->Product[8], Response->Product[9], Response->Product[10], Response->Product[11], + Response->Product[12], Response->Product[13], Response->Product[14], Response->Product[15]); + + DPRINT1("Revision %c%c%c%c\n", Response->Revision[0], Response->Revision[1], Response->Revision[2], Response->Revision[3]); + + // + // store result + // + PDODeviceExtension->InquiryData = (PVOID)Response; + return Status; +} + +NTSTATUS +USBSTOR_SendFormatCapacityIrp( + IN PDEVICE_OBJECT PDODeviceObject) +{ + NTSTATUS Status; + PPDO_DEVICE_EXTENSION PDODeviceExtension; + PUCHAR Response; + + // + // get device extension + // + PDODeviceExtension = (PPDO_DEVICE_EXTENSION)PDODeviceObject->DeviceExtension; + + // + // send request + // + Status = USBSTOR_SendIrp(PDODeviceObject, 0xFC, SCSIOP_READ_FORMATTED_CAPACITY, (PVOID*)&Response); + if (!NT_SUCCESS(Status)) + { + // + // command failed + // + return Status; + } + + // + // check if its a floppy + // + PDODeviceExtension->IsFloppy = USBSTOR_IsFloppy(Response, 0xFC /*FIXME*/, &PDODeviceExtension->MediumTypeCode); + + // + // free response + // + ExFreePoolWithTag(Response, USB_STOR_TAG); + return Status; +} + + + +NTSTATUS +USBSTOR_CreatePDO( + IN PDEVICE_OBJECT DeviceObject, + IN UCHAR LUN) +{ + PDEVICE_OBJECT PDO; + NTSTATUS Status; + PPDO_DEVICE_EXTENSION PDODeviceExtension; + PUFI_INQUIRY_RESPONSE Response; + PFDO_DEVICE_EXTENSION FDODeviceExtension; + + // + // get device extension + // + FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + + // + // create child device object + // + Status = IoCreateDevice(DeviceObject->DriverObject, sizeof(PDO_DEVICE_EXTENSION), NULL, FILE_DEVICE_MASS_STORAGE, FILE_AUTOGENERATED_DEVICE_NAME | FILE_DEVICE_SECURE_OPEN, FALSE, &PDO); + if (!NT_SUCCESS(Status)) + { + // + // failed to create device + // + return Status; + } + + // + // patch the stack size + // + PDO->StackSize = DeviceObject->StackSize; + + // + // get device extension + // + PDODeviceExtension = (PPDO_DEVICE_EXTENSION)PDO->DeviceExtension; + + // + // initialize device extension + // + RtlZeroMemory(PDODeviceExtension, sizeof(PDO_DEVICE_EXTENSION)); + PDODeviceExtension->Common.IsFDO = FALSE; + PDODeviceExtension->LowerDeviceObject = DeviceObject; + PDODeviceExtension->PDODeviceObject = &FDODeviceExtension->ChildPDO[LUN]; + PDODeviceExtension->Self = PDO; + PDODeviceExtension->LUN = LUN; + + // + // set device flags + // + PDO->Flags |= DO_DIRECT_IO | DO_MAP_IO_BUFFER; + + // + // device is initialized + // + PDO->Flags &= ~DO_DEVICE_INITIALIZING; + + // + // output device object + // + FDODeviceExtension->ChildPDO[LUN] = PDO; + + // + // send inquiry command by irp + // + Status = USBSTOR_SendInquiryIrp(PDO); + ASSERT(Status == STATUS_SUCCESS); + + // + // check response data + // + Response = (PUFI_INQUIRY_RESPONSE)PDODeviceExtension->InquiryData; + ASSERT(Response); + + if (Response->DeviceType == 0) + { + // + // check if it is a floppy + // + Status = USBSTOR_SendFormatCapacityIrp(PDO); + + // + // display result + // + DPRINT1("[USBSTOR] Status %x IsFloppy %x MediumTypeCode %x\n", Status, PDODeviceExtension->IsFloppy, PDODeviceExtension->MediumTypeCode); + + // + // failing command is non critical + // + Status = STATUS_SUCCESS; + } + + // + // done + // + return Status; +} diff --git a/drivers/usb/usbstor_new/queue.c b/drivers/usb/usbstor_new/queue.c new file mode 100644 index 0000000000..a945ab97c9 --- /dev/null +++ b/drivers/usb/usbstor_new/queue.c @@ -0,0 +1,670 @@ +/* + * PROJECT: ReactOS Universal Serial Bus Bulk Storage Driver + * LICENSE: GPL - See COPYING in the top level directory + * FILE: drivers/usb/usbstor/queue.c + * PURPOSE: USB block storage device driver. + * PROGRAMMERS: + * James Tabor + * Michael Martin (michael.martin(a)reactos.org) + * Johannes Anderwald (johannes.anderwald(a)reactos.org) + */ + +#include "usbstor.h" + +#define NDEBUG +#include <debug.h> + +VOID +USBSTOR_QueueInitialize( + PFDO_DEVICE_EXTENSION FDODeviceExtension) +{ + // + // sanity check + // + ASSERT(FDODeviceExtension->Common.IsFDO); + + // + // initialize queue lock + // + KeInitializeSpinLock(&FDODeviceExtension->IrpListLock); + + // + // initialize irp list head + // + InitializeListHead(&FDODeviceExtension->IrpListHead); + + // + // initialize event + // + KeInitializeEvent(&FDODeviceExtension->NoPendingRequests, NotificationEvent, TRUE); +} + +VOID +NTAPI +USBSTOR_CancelIo( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PFDO_DEVICE_EXTENSION FDODeviceExtension; + + // + // get FDO device extension + // + FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + // + // sanity check + // + ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); + ASSERT(FDODeviceExtension->Common.IsFDO); + + // + // this IRP isn't in our list here + // + + // + // now release the cancel lock + // + IoReleaseCancelSpinLock(Irp->CancelIrql); + + // + // set cancel status + // + Irp->IoStatus.Status = STATUS_CANCELLED; + + // + // now cancel the irp + // + USBSTOR_QueueTerminateRequest(DeviceObject, Irp); + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + // + // start the next one + // + USBSTOR_QueueNextRequest(DeviceObject); +} + +VOID +NTAPI +USBSTOR_Cancel( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PFDO_DEVICE_EXTENSION FDODeviceExtension; + + // + // get FDO device extension + // + FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + // + // sanity check + // + ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); + ASSERT(FDODeviceExtension->Common.IsFDO); + + // + // acquire irp list lock + // + KeAcquireSpinLockAtDpcLevel(&FDODeviceExtension->IrpListLock); + + // + // remove the irp from the list + // + RemoveEntryList(&Irp->Tail.Overlay.ListEntry); + + // + // release irp list lock + // + KeReleaseSpinLockFromDpcLevel(&FDODeviceExtension->IrpListLock); + + // + // now release the cancel lock + // + IoReleaseCancelSpinLock(Irp->CancelIrql); + + // + // set cancel status + // + Irp->IoStatus.Status = STATUS_CANCELLED; + + // + // now cancel the irp + // + USBSTOR_QueueTerminateRequest(DeviceObject, Irp); + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + // + // start the next one + // + USBSTOR_QueueNextRequest(DeviceObject); +} + +BOOLEAN +USBSTOR_QueueAddIrp( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PDRIVER_CANCEL OldDriverCancel; + KIRQL OldLevel; + PFDO_DEVICE_EXTENSION FDODeviceExtension; + BOOLEAN IrpListFreeze; + BOOLEAN SrbProcessing; + PIO_STACK_LOCATION IoStack = IoGetCurrentIrpStackLocation(Irp); + PSCSI_REQUEST_BLOCK Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1; + + // + // get FDO device extension + // + FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + // + // sanity check + // + ASSERT(FDODeviceExtension->Common.IsFDO); + + // + // mark irp pending + // + IoMarkIrpPending(Irp); + + // + // acquire lock + // + KeAcquireSpinLock(&FDODeviceExtension->IrpListLock, &OldLevel); + + // + // check if there are irp pending + // + SrbProcessing = FDODeviceExtension->IrpPendingCount != 0; + + if (SrbProcessing) + { + // + // add irp to queue + // + InsertTailList(&FDODeviceExtension->IrpListHead, &Irp->Tail.Overlay.ListEntry); + } + + // + // increment pending count + // + FDODeviceExtension->IrpPendingCount++; + + + // + // clear the no requests pending event + // + KeClearEvent(&FDODeviceExtension->NoPendingRequests); + + // + // check if queue is freezed + // + IrpListFreeze = FDODeviceExtension->IrpListFreeze; + + // + // release list lock + // + KeReleaseSpinLock(&FDODeviceExtension->IrpListLock, OldLevel); + + // + // synchronize with cancellations by holding the cancel lock + // + IoAcquireCancelSpinLock(&Irp->CancelIrql); + + // + // now set the driver cancel routine + // + if (SrbProcessing) + { + ASSERT(FDODeviceExtension->ActiveSrb != NULL); + + OldDriverCancel = IoSetCancelRoutine(Irp, USBSTOR_Cancel); + } + else + { + ASSERT(FDODeviceExtension->ActiveSrb == NULL); + + FDODeviceExtension->ActiveSrb = Request; + OldDriverCancel = IoSetCancelRoutine(Irp, USBSTOR_CancelIo); + } + + // + // check if the irp has already been cancelled + // + if (Irp->Cancel && OldDriverCancel == NULL) + { + // + // cancel irp + // + Irp->CancelRoutine(DeviceObject, Irp); + + // + // irp was cancelled + // + return FALSE; + } + + // + // release the cancel lock + // + IoReleaseCancelSpinLock(Irp->CancelIrql); + + // + // if list is freezed, dont start this packet + // + DPRINT("IrpListFreeze: %lu IrpPendingCount %lu\n", IrpListFreeze, FDODeviceExtension->IrpPendingCount); + + return (IrpListFreeze || SrbProcessing); +} + +PIRP +USBSTOR_RemoveIrp( + IN PDEVICE_OBJECT DeviceObject) +{ + KIRQL OldLevel; + PFDO_DEVICE_EXTENSION FDODeviceExtension; + PLIST_ENTRY Entry; + PIRP Irp = NULL; + + // + // get FDO device extension + // + FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + // + // sanity check + // + ASSERT(FDODeviceExtension->Common.IsFDO); + + // + // acquire lock + // + KeAcquireSpinLock(&FDODeviceExtension->IrpListLock, &OldLevel); + + // + // check if list is empty + // + if (!IsListEmpty(&FDODeviceExtension->IrpListHead)) + { + // + // remove entry + // + Entry = RemoveHeadList(&FDODeviceExtension->IrpListHead); + + // + // get offset to start of irp + // + Irp = (PIRP)CONTAINING_RECORD(Entry, IRP, Tail.Overlay.ListEntry); + } + + // + // release list lock + // + KeReleaseSpinLock(&FDODeviceExtension->IrpListLock, OldLevel); + + // + // return result + // + return Irp; +} + +VOID +USBSTOR_QueueWaitForPendingRequests( + IN PDEVICE_OBJECT DeviceObject) +{ + PFDO_DEVICE_EXTENSION FDODeviceExtension; + + // + // get FDO device extension + // + FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + // + // perform the wait + // + KeWaitForSingleObject(&FDODeviceExtension->NoPendingRequests, + Executive, + KernelMode, + FALSE, + NULL); +} + +VOID +USBSTOR_QueueTerminateRequest( + IN PDEVICE_OBJECT FDODeviceObject, + IN PIRP Irp) +{ + KIRQL OldLevel; + PFDO_DEVICE_EXTENSION FDODeviceExtension; + PIO_STACK_LOCATION IoStack = IoGetCurrentIrpStackLocation(Irp); + PSCSI_REQUEST_BLOCK Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1; + + // + // get FDO device extension + // + FDODeviceExtension = (PFDO_DEVICE_EXTENSION)FDODeviceObject->DeviceExtension; + + // + // sanity check + // + ASSERT(FDODeviceExtension->Common.IsFDO); + + // + // acquire lock + // + KeAcquireSpinLock(&FDODeviceExtension->IrpListLock, &OldLevel); + + // + // decrement pending irp count + // + FDODeviceExtension->IrpPendingCount--; + + // + // check if this was our current active SRB + // + if (FDODeviceExtension->ActiveSrb == Request) + { + // + // indicate processing is completed + // + FDODeviceExtension->ActiveSrb = NULL; + } + + // + // Set the event if nothing else is pending + // + if (FDODeviceExtension->IrpPendingCount == 0 && + FDODeviceExtension->ActiveSrb == NULL) + { + KeSetEvent(&FDODeviceExtension->NoPendingRequests, IO_NO_INCREMENT, FALSE); + } + + // + // release lock + // + KeReleaseSpinLock(&FDODeviceExtension->IrpListLock, OldLevel); + +} + +VOID +USBSTOR_QueueNextRequest( + IN PDEVICE_OBJECT DeviceObject) +{ + PFDO_DEVICE_EXTENSION FDODeviceExtension; + PIRP Irp; + PIO_STACK_LOCATION IoStack; + PSCSI_REQUEST_BLOCK Request; + + // + // get pdo device extension + // + FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + // + // sanity check + // + ASSERT(FDODeviceExtension->Common.IsFDO); + + // + // check first if there's already a request pending or the queue is frozen + // + if (FDODeviceExtension->ActiveSrb != NULL || + FDODeviceExtension->IrpListFreeze) + { + // + // no work to do yet + // + return; + } + + // + // remove first irp from list + // + Irp = USBSTOR_RemoveIrp(DeviceObject); + + // + // is there an irp pending + // + if (!Irp) + { + // + // no work to do + // + IoStartNextPacket(DeviceObject, TRUE); + return; + } + + // + // get current stack location + // + IoStack = IoGetCurrentIrpStackLocation(Irp); + + // + // get srb + // + Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1; + + // + // sanity check + // + ASSERT(Request); + + // + // set the active SRB + // + FDODeviceExtension->ActiveSrb = Request; + + // + // start next packet + // + IoStartPacket(DeviceObject, Irp, &Request->QueueSortKey, USBSTOR_CancelIo); + + // + // start next request + // + IoStartNextPacket(DeviceObject, TRUE); +} + +VOID +USBSTOR_QueueRelease( + IN PDEVICE_OBJECT DeviceObject) +{ + PFDO_DEVICE_EXTENSION FDODeviceExtension; + PIRP Irp; + KIRQL OldLevel; + PIO_STACK_LOCATION IoStack; + PSCSI_REQUEST_BLOCK Request; + + // + // get FDO device extension + // + FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + // + // sanity check + // + ASSERT(FDODeviceExtension->Common.IsFDO); + + // + // acquire lock + // + KeAcquireSpinLock(&FDODeviceExtension->IrpListLock, &OldLevel); + + // + // clear freezed status + // + FDODeviceExtension->IrpListFreeze = FALSE; + + // + // release irp list lock + // + KeReleaseSpinLock(&FDODeviceExtension->IrpListLock, OldLevel); + + // + // grab newest irp + // + Irp = USBSTOR_RemoveIrp(DeviceObject); + + // + // is there an irp + // + if (!Irp) + { + // + // no irp + // + return; + } + + // + // get current irp stack location + // + IoStack = IoGetCurrentIrpStackLocation(Irp); + + // + // get srb + // + Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1; + + // + // start new packet + // + IoStartPacket(DeviceObject, + Irp, + &Request->QueueSortKey, + USBSTOR_CancelIo); +} + + +VOID +NTAPI +USBSTOR_StartIo( + PDEVICE_OBJECT DeviceObject, + PIRP Irp) +{ + PIO_STACK_LOCATION IoStack; + PFDO_DEVICE_EXTENSION FDODeviceExtension; + PPDO_DEVICE_EXTENSION PDODeviceExtension; + KIRQL OldLevel; + BOOLEAN ResetInProgress; + + DPRINT("USBSTOR_StartIo\n"); + + // + // get FDO device extension + // + FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + // + // sanity check + // + ASSERT(FDODeviceExtension->Common.IsFDO); + + // + // acquire cancel spinlock + // + IoAcquireCancelSpinLock(&OldLevel); + + // + // set cancel routine to zero + // + IoSetCancelRoutine(Irp, NULL); + + // + // check if the irp has been cancelled + // + if (Irp->Cancel) + { + // + // irp has been cancelled, release cancel spinlock + // + IoReleaseCancelSpinLock(OldLevel); + + // + // irp is cancelled + // + Irp->IoStatus.Status = STATUS_CANCELLED; + Irp->IoStatus.Information = 0; + + // + // terminate request + // + USBSTOR_QueueTerminateRequest(DeviceObject, Irp); + + // + // complete request + // + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + // + // queue next request + // + USBSTOR_QueueNextRequest(DeviceObject); + + // + // done + // + return; + } + + // + // release cancel spinlock + // + IoReleaseCancelSpinLock(OldLevel); + + // + // acquire lock + // + KeAcquireSpinLock(&FDODeviceExtension->IrpListLock, &OldLevel); + + // + // check reset is in progress + // + ResetInProgress = FDODeviceExtension->ResetInProgress; + ASSERT(ResetInProgress == FALSE); + + // + // release lock + // + KeReleaseSpinLock(&FDODeviceExtension->IrpListLock, OldLevel); + + // + // get current irp stack location + // + IoStack = IoGetCurrentIrpStackLocation(Irp); + + // + // get pdo device extension + // + PDODeviceExtension = (PPDO_DEVICE_EXTENSION)IoStack->DeviceObject->DeviceExtension; + + // + // sanity check + // + ASSERT(PDODeviceExtension->Common.IsFDO == FALSE); + + // + // is a reset in progress + // + if (ResetInProgress) + { + // + // hard reset is in progress + // + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = STATUS_DEVICE_DOES_NOT_EXIST; + USBSTOR_QueueTerminateRequest(DeviceObject, Irp); + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return; + } + + // + // execute scsi + // + USBSTOR_HandleExecuteSCSI(IoStack->DeviceObject, Irp, 0); + + // + // FIXME: handle error + // +} diff --git a/drivers/usb/usbstor_new/scsi.c b/drivers/usb/usbstor_new/scsi.c new file mode 100644 index 0000000000..ee5bfba189 --- /dev/null +++ b/drivers/usb/usbstor_new/scsi.c @@ -0,0 +1,1429 @@ +/* + * PROJECT: ReactOS Universal Serial Bus Bulk Storage Driver + * LICENSE: GPL - See COPYING in the top level directory + * FILE: drivers/usb/usbstor/pdo.c + * PURPOSE: USB block storage device driver. + * PROGRAMMERS: + * James Tabor + * Michael Martin (michael.martin(a)reactos.org) + * Johannes Anderwald (johannes.anderwald(a)reactos.org) + */ + +#include "usbstor.h" + +#define NDEBUG +#include <debug.h> + +NTSTATUS +USBSTOR_BuildCBW( + IN ULONG Tag, + IN ULONG DataTransferLength, + IN UCHAR LUN, + IN UCHAR CommandBlockLength, + IN PUCHAR CommandBlock, + IN OUT PCBW Control) +{ + // + // sanity check + // + ASSERT(CommandBlockLength <= 16); + + // + // now initialize CBW + // + Control->Signature = CBW_SIGNATURE; + Control->Tag = Tag; + Control->DataTransferLength = DataTransferLength; + Control->Flags = (CommandBlock[0] != SCSIOP_WRITE) ? 0x80 : 0x00; + Control->LUN = (LUN & MAX_LUN); + Control->CommandBlockLength = CommandBlockLength; + + // + // copy command block + // + RtlCopyMemory(Control->CommandBlock, CommandBlock, CommandBlockLength); + + // + // done + // + return STATUS_SUCCESS; +} + +PIRP_CONTEXT +USBSTOR_AllocateIrpContext() +{ + PIRP_CONTEXT Context; + + // + // allocate irp context + // + Context = (PIRP_CONTEXT)AllocateItem(NonPagedPool, sizeof(IRP_CONTEXT)); + if (!Context) + { + // + // no memory + // + return NULL; + } + + // + // allocate cbw block + // + Context->cbw = (PCBW)AllocateItem(NonPagedPool, 512); + if (!Context->cbw) + { + // + // no memory + // + FreeItem(Context); + return NULL; + } + + // + // done + // + return Context; + +} + +BOOLEAN +USBSTOR_IsCSWValid( + PIRP_CONTEXT Context) +{ + // + // sanity checks + // + if (Context->csw->Signature != CSW_SIGNATURE) + { + DPRINT1("[USBSTOR] Expected Signature %x but got %x\n", CSW_SIGNATURE, Context->csw->Signature); + return FALSE; + } + + if (Context->csw->Tag != (ULONG)Context->csw) + { + DPRINT1("[USBSTOR] Expected Tag %x but got %x\n", (ULONG)Context->csw, Context->csw->Tag); + return FALSE; + } + + if (Context->csw->Status != 0x00) + { + DPRINT1("[USBSTOR] Expected Status 0x00 but got %x\n", Context->csw->Status); + return FALSE; + } + + // + // CSW is valid + // + return TRUE; + +} + +NTSTATUS +USBSTOR_QueueWorkItem( + PIRP_CONTEXT Context, + PIRP Irp) +{ + PERRORHANDLER_WORKITEM_DATA ErrorHandlerWorkItemData; + + // + // Allocate Work Item Data + // + ErrorHandlerWorkItemData = ExAllocatePoolWithTag(NonPagedPool, sizeof(ERRORHANDLER_WORKITEM_DATA), USB_STOR_TAG); + if (!ErrorHandlerWorkItemData) + { + // + // no memory + // + return STATUS_INSUFFICIENT_RESOURCES; + } + + // + // error handling started + // + Context->FDODeviceExtension->SrbErrorHandlingActive = TRUE; + + // + // srb error handling finished + // + Context->FDODeviceExtension->TimerWorkQueueEnabled = FALSE; + + // + // Initialize and queue the work item to handle the error + // + ExInitializeWorkItem(&ErrorHandlerWorkItemData->WorkQueueItem, + ErrorHandlerWorkItemRoutine, + ErrorHandlerWorkItemData); + + ErrorHandlerWorkItemData->DeviceObject = Context->FDODeviceExtension->FunctionalDeviceObject; + ErrorHandlerWorkItemData->Context = Context; + ErrorHandlerWorkItemData->Irp = Irp; + ErrorHandlerWorkItemData->DeviceObject = Context->FDODeviceExtension->FunctionalDeviceObject; + + DPRINT1("Queuing WorkItemROutine\n"); + ExQueueWorkItem(&ErrorHandlerWorkItemData->WorkQueueItem, DelayedWorkQueue); + return STATUS_MORE_PROCESSING_REQUIRED; +} + + +// +// driver verifier +// +IO_COMPLETION_ROUTINE USBSTOR_CSWCompletionRoutine; + +NTSTATUS +NTAPI +USBSTOR_CSWCompletionRoutine( + PDEVICE_OBJECT DeviceObject, + PIRP Irp, + PVOID Ctx) +{ + PIRP_CONTEXT Context; + PIO_STACK_LOCATION IoStack; + PSCSI_REQUEST_BLOCK Request; + PCDB pCDB; + PREAD_CAPACITY_DATA_EX CapacityDataEx; + PREAD_CAPACITY_DATA CapacityData; + PUFI_CAPACITY_RESPONSE Response; + NTSTATUS Status; + + // + // access context + // + Context = (PIRP_CONTEXT)Ctx; + + // ... 2103 lines suppressed ...
6 years, 11 months
1
0
0
0
01/01: [FREETYPE] Bring back our diffs to reduce the stack usage in cf2_interpT2CharString(). CORE-14227
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=d7c47feb25ce8af855ce0…
commit d7c47feb25ce8af855ce0ad4202d0499c8a1b1bd Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Sat Jan 20 22:30:11 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Sun Jan 21 13:31:05 2018 +0100 [FREETYPE] Bring back our diffs to reduce the stack usage in cf2_interpT2CharString(). CORE-14227 --- sdk/lib/3rdparty/freetype/src/psaux/psintrp.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/sdk/lib/3rdparty/freetype/src/psaux/psintrp.c b/sdk/lib/3rdparty/freetype/src/psaux/psintrp.c index 5c0ee78492..1ac5b9392b 100644 --- a/sdk/lib/3rdparty/freetype/src/psaux/psintrp.c +++ b/sdk/lib/3rdparty/freetype/src/psaux/psintrp.c @@ -525,8 +525,13 @@ CF2_ArrStackRec vStemHintArray; CF2_HintMaskRec hintMask; +#ifdef __REACTOS__ + CF2_GlyphPathRec *glyphPath = malloc(sizeof(CF2_GlyphPathRec)); +/* Ugly but it allows us to reduce the diff */ +#define glyphPath (*glyphPath) +#else CF2_GlyphPathRec glyphPath; - +#endif FT_ZERO( &storage ); FT_ZERO( &results ); @@ -2606,7 +2611,13 @@ * discard `counterMask' and `counterHintMap'. * */ +#ifdef __REACTOS__ + CF2_HintMapRec *counterHintMap = malloc(sizeof(CF2_HintMapRec)); +/* Ugly but it allows us to reduce the diff */ +#define counterHintMap (*counterHintMap) +#else CF2_HintMapRec counterHintMap; +#endif CF2_HintMaskRec counterMask; @@ -2627,6 +2638,9 @@ &counterMask, 0, FALSE ); +#ifdef __REACTOS__ + free(&counterHintMap); +#endif } break; @@ -3031,6 +3045,12 @@ FT_TRACE4(( "\n" )); +#ifdef __REACTOS__ + free(&glyphPath); +#undef counterHintMap +#undef glyphPath +#endif + return; }
6 years, 11 months
1
0
0
0
01/01: [WIN32K:NTUSER] Fix hardcoded color for MF_GRAYED menu items
by Stanislav Motylkov
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=dade22f4797c7de5a81d8…
commit dade22f4797c7de5a81d8701519586feb9696345 Author: Stanislav Motylkov <x86corez(a)gmail.com> AuthorDate: Sun Jan 21 00:22:36 2018 +0300 Commit: Giannis Adamopoulos <gadamopoulos(a)reactos.org> CommitDate: Sun Jan 21 00:27:23 2018 +0200 [WIN32K:NTUSER] Fix hardcoded color for MF_GRAYED menu items CORE-14196 #resolve --- win32ss/user/ntuser/menu.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/win32ss/user/ntuser/menu.c b/win32ss/user/ntuser/menu.c index 965a72b81d..1407ef1d0a 100644 --- a/win32ss/user/ntuser/menu.c +++ b/win32ss/user/ntuser/menu.c @@ -2511,11 +2511,11 @@ static void FASTCALL MENU_DrawMenuItem(PWND Wnd, PMENU Menu, PWND WndOwner, HDC if (!(lpitem->fState & MF_HILITE) ) { ++rect.left; ++rect.top; ++rect.right; ++rect.bottom; - IntGdiSetTextColor(hdc, RGB(0xff, 0xff, 0xff)); + IntGdiSetTextColor(hdc, IntGetSysColor(COLOR_HIGHLIGHTTEXT)); DrawTextW( hdc, Text, i, &rect, uFormat ); --rect.left; --rect.top; --rect.right; --rect.bottom; } - IntGdiSetTextColor(hdc, RGB(0x80, 0x80, 0x80)); + IntGdiSetTextColor(hdc, IntGetSysColor(COLOR_GRAYTEXT)); } DrawTextW( hdc, Text, i, &rect, uFormat); @@ -2538,11 +2538,11 @@ static void FASTCALL MENU_DrawMenuItem(PWND Wnd, PMENU Menu, PWND WndOwner, HDC if (!(lpitem->fState & MF_HILITE) ) { ++rect.left; ++rect.top; ++rect.right; ++rect.bottom; - IntGdiSetTextColor(hdc, RGB(0xff, 0xff, 0xff)); + IntGdiSetTextColor(hdc, IntGetSysColor(COLOR_HIGHLIGHTTEXT)); DrawTextW( hdc, Text + i + 1, -1, &rect, uFormat); --rect.left; --rect.top; --rect.right; --rect.bottom; } - IntGdiSetTextColor(hdc, RGB(0x80, 0x80, 0x80)); + IntGdiSetTextColor(hdc, IntGetSysColor(COLOR_GRAYTEXT)); } DrawTextW( hdc, Text + i + 1, -1, &rect, uFormat ); }
6 years, 11 months
1
0
0
0
01/01: [NFI] Rewrite the way files are handled, this allows querying handling a new file while already handling one. This is useful to fix the problem when a directory wasn't in cache yet, but one of its files is to be displayed.
by Pierre Schweitzer
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=d849794a3529e94364f2f…
commit d849794a3529e94364f2f8e5d748a5b65bbf2e01 Author: Pierre Schweitzer <pierre(a)reactos.org> AuthorDate: Sat Jan 20 22:25:46 2018 +0100 Commit: Pierre Schweitzer <pierre(a)reactos.org> CommitDate: Sat Jan 20 22:25:46 2018 +0100 [NFI] Rewrite the way files are handled, this allows querying handling a new file while already handling one. This is useful to fix the problem when a directory wasn't in cache yet, but one of its files is to be displayed. --- .../rosapps/applications/rosinternals/nfi/nfi.c | 186 ++++++++++++++------- 1 file changed, 121 insertions(+), 65 deletions(-) diff --git a/modules/rosapps/applications/rosinternals/nfi/nfi.c b/modules/rosapps/applications/rosinternals/nfi/nfi.c index 3aa54a6d6b..377826b437 100644 --- a/modules/rosapps/applications/rosinternals/nfi/nfi.c +++ b/modules/rosapps/applications/rosinternals/nfi/nfi.c @@ -164,15 +164,37 @@ void PrintUsage(void) /* FIXME */ } -void AddToCache(PWSTR Name, DWORD Length, ULONGLONG MftId) +PNAME_CACHE_ENTRY FindInCache(ULONGLONG MftId) { PNAME_CACHE_ENTRY CacheEntry; + for (CacheEntry = CacheHead; CacheEntry != NULL; CacheEntry = CacheEntry->Next) + { + if (MftId == CacheEntry->MftId) + { + return CacheEntry; + } + } + + return NULL; +} + +PNAME_CACHE_ENTRY AddToCache(PWSTR Name, DWORD Length, ULONGLONG MftId) +{ + PNAME_CACHE_ENTRY CacheEntry; + + /* Don't add in cache if already there! */ + CacheEntry = FindInCache(MftId); + if (CacheEntry != NULL) + { + return CacheEntry; + } + /* Allocate an entry big enough to store name and cache info */ CacheEntry = HeapAlloc(GetProcessHeap(), 0, sizeof(NAME_CACHE_ENTRY) + Length); if (CacheEntry == NULL) { - return; + return NULL; } /* Insert in head (likely more perf) */ @@ -182,28 +204,34 @@ void AddToCache(PWSTR Name, DWORD Length, ULONGLONG MftId) CacheEntry->MftId = MftId; CacheEntry->NameLen = Length; CopyMemory(CacheEntry->Name, Name, Length); + + return CacheEntry; } -void PrintPrettyName(PNTFS_ATTR_RECORD Attributes, PNTFS_ATTR_RECORD AttributesEnd, ULONGLONG MftId) +PNAME_CACHE_ENTRY HandleFile(HANDLE VolumeHandle, PNTFS_VOLUME_DATA_BUFFER VolumeInfo, ULONGLONG Id, PNTFS_FILE_RECORD_OUTPUT_BUFFER OutputBuffer, BOOLEAN Silent); + +PNAME_CACHE_ENTRY PrintPrettyName(HANDLE VolumeHandle, PNTFS_VOLUME_DATA_BUFFER VolumeInfo, PNTFS_ATTR_RECORD Attributes, PNTFS_ATTR_RECORD AttributesEnd, ULONGLONG MftId, BOOLEAN Silent) { - BOOLEAN FirstRun, Found; + BOOLEAN FirstRun; PNTFS_ATTR_RECORD Attribute; FirstRun = TRUE; - Found = FALSE; /* Setup name for "standard" files */ if (MftId <= NTFS_FILE_EXTEND) { - _tprintf(_T("%s\n"), KnownEntries[MftId]); + if (!Silent) + { + _tprintf(_T("%s\n"), KnownEntries[MftId]); + } /* $Extend can contain entries, add it in cache */ if (MftId == NTFS_FILE_EXTEND) { - AddToCache(L"\\$Extend", sizeof(L"\\$Extend") - sizeof(UNICODE_NULL), NTFS_FILE_EXTEND); + return AddToCache(L"\\$Extend", sizeof(L"\\$Extend") - sizeof(UNICODE_NULL), NTFS_FILE_EXTEND); } - return; + return NULL; } /* We'll first try to use the Win32 name @@ -218,6 +246,7 @@ TryAgain: PFILENAME_ATTRIBUTE Name; ULONGLONG ParentId; ULONG Length; + PNAME_CACHE_ENTRY CacheEntry; /* Move to the next arg if: * - Not a file name @@ -251,19 +280,25 @@ TryAgain: /* Default case */ else { - PNAME_CACHE_ENTRY CacheEntry; - /* Did we already cache the name? */ - for (CacheEntry = CacheHead; CacheEntry != NULL; CacheEntry = CacheEntry->Next) + CacheEntry = FindInCache(ParentId); + + /* It wasn't in cache? Try to get it in! */ + if (CacheEntry == NULL) { - if (ParentId == CacheEntry->MftId) + PNTFS_FILE_RECORD_OUTPUT_BUFFER OutputBuffer; + + OutputBuffer = HeapAlloc(GetProcessHeap(), 0, VolumeInfo->BytesPerFileRecordSegment + sizeof(NTFS_FILE_RECORD_OUTPUT_BUFFER)); + if (OutputBuffer != NULL) { - break; + CacheEntry = HandleFile(VolumeHandle, VolumeInfo, ParentId, OutputBuffer, TRUE); + HeapFree(GetProcessHeap(), 0, OutputBuffer); } } /* Nothing written yet */ Length = 0; + /* We cached it */ if (CacheEntry != NULL) { @@ -275,7 +310,6 @@ TryAgain: } else { - /* FIXME: Do something, like trying to read parent... */ _tprintf(_T("Parent: %I64d\n"), ParentId); } @@ -285,20 +319,25 @@ TryAgain: Display[Length] = UNICODE_NULL; } - /* Display the name */ - _tprintf(_T("%s\n"), Display); + if (!Silent) + { + /* Display the name */ + _tprintf(_T("%s\n"), Display); + } + + /* Reset cache entry */ + CacheEntry = NULL; /* If that's a directory, put it in the cache */ if (Name->FileAttributes & NTFS_FILE_TYPE_DIRECTORY) { - AddToCache(Display, Length * sizeof(WCHAR), MftId); + CacheEntry = AddToCache(Display, Length * sizeof(WCHAR), MftId); } /* Now, just quit */ FirstRun = FALSE; - Found = TRUE; - break; + return CacheEntry; } /* If was first run (Win32 search), retry with other names */ @@ -309,10 +348,12 @@ TryAgain: } /* If we couldn't find a name, print unknown */ - if (!Found) + if (!Silent) { _tprintf(_T("(unknown/unnamed)\n")); } + + return NULL; } PUCHAR DecodeRun(PUCHAR DataRun, LONGLONG *DataRunOffset, ULONGLONG *DataRunLength) @@ -463,6 +504,65 @@ void PrintAttributeInfo(PNTFS_ATTR_RECORD Attribute, DWORD MaxSize) } } +PNAME_CACHE_ENTRY HandleFile(HANDLE VolumeHandle, PNTFS_VOLUME_DATA_BUFFER VolumeInfo, ULONGLONG Id, PNTFS_FILE_RECORD_OUTPUT_BUFFER OutputBuffer, BOOLEAN Silent) +{ + NTFS_FILE_RECORD_INPUT_BUFFER InputBuffer; + PFILE_RECORD_HEADER FileRecord; + PNTFS_ATTR_RECORD Attribute, AttributesEnd; + DWORD LengthReturned; + PNAME_CACHE_ENTRY CacheEntry; + + /* Get the file record */ + InputBuffer.FileReferenceNumber.QuadPart = Id; + if (!DeviceIoControl(VolumeHandle, FSCTL_GET_NTFS_FILE_RECORD, &InputBuffer, sizeof(InputBuffer), + OutputBuffer, VolumeInfo->BytesPerFileRecordSegment + sizeof(NTFS_FILE_RECORD_OUTPUT_BUFFER), + &LengthReturned, NULL)) + { + return NULL; + } + + /* Don't deal with it if we already browsed it + * FSCTL_GET_NTFS_FILE_RECORD always returns previous record if demanded + * isn't allocated + */ + if (OutputBuffer->FileReferenceNumber.QuadPart != Id) + { + return NULL; + } + + /* Sanity check */ + FileRecord = (PFILE_RECORD_HEADER)OutputBuffer->FileRecordBuffer; + if (FileRecord->Ntfs.Type != NRH_FILE_TYPE) + { + return NULL; + } + + if (!Silent) + { + /* Print ID */ + _tprintf(_T("\nFile %I64d\n"), OutputBuffer->FileReferenceNumber.QuadPart); + } + + /* Get attributes list */ + Attribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)FileRecord + FileRecord->AttributeOffset); + AttributesEnd = (PNTFS_ATTR_RECORD)((ULONG_PTR)FileRecord + FileRecord->BytesInUse); + + /* Print the file name */ + CacheEntry = PrintPrettyName(VolumeHandle, VolumeInfo, Attribute, AttributesEnd, Id, Silent); + + if (!Silent) + { + /* And print attributes information for each attribute */ + while (Attribute < AttributesEnd && Attribute->Type != AttributeEnd) + { + PrintAttributeInfo(Attribute, VolumeInfo->BytesPerFileRecordSegment); + Attribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)Attribute + Attribute->Length); + } + } + + return CacheEntry; +} + int __cdecl _tmain(int argc, const TCHAR *argv[]) @@ -526,51 +626,7 @@ _tmain(int argc, const TCHAR *argv[]) /* Forever loop, extract all the files! */ for (File = 0;; ++File) { - NTFS_FILE_RECORD_INPUT_BUFFER InputBuffer; - PFILE_RECORD_HEADER FileRecord; - PNTFS_ATTR_RECORD Attribute, AttributesEnd; - - /* Get the file record */ - InputBuffer.FileReferenceNumber.QuadPart = File; - if (!DeviceIoControl(VolumeHandle, FSCTL_GET_NTFS_FILE_RECORD, &InputBuffer, sizeof(InputBuffer), - OutputBuffer, VolumeInfo.BytesPerFileRecordSegment + sizeof(NTFS_FILE_RECORD_OUTPUT_BUFFER), - &LengthReturned, NULL)) - { - continue; - } - - /* Don't deal with it if we already browsed it - * FSCTL_GET_NTFS_FILE_RECORD always returns previous record if demanded - * isn't allocated - */ - if (OutputBuffer->FileReferenceNumber.QuadPart != File) - { - continue; - } - - /* Sanity check */ - FileRecord = (PFILE_RECORD_HEADER)OutputBuffer->FileRecordBuffer; - if (FileRecord->Ntfs.Type != NRH_FILE_TYPE) - { - continue; - } - - /* Print ID */ - _tprintf(_T("\nFile %I64d\n"), OutputBuffer->FileReferenceNumber.QuadPart); - - /* Get attributes list */ - Attribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)FileRecord + FileRecord->AttributeOffset); - AttributesEnd = (PNTFS_ATTR_RECORD)((ULONG_PTR)FileRecord + FileRecord->BytesInUse); - - /* Print the file name */ - PrintPrettyName(Attribute, AttributesEnd, File); - - /* And print attributes information for each attribute */ - while (Attribute < AttributesEnd && Attribute->Type != AttributeEnd) - { - PrintAttributeInfo(Attribute, VolumeInfo.BytesPerFileRecordSegment); - Attribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)Attribute + Attribute->Length); - } + HandleFile(VolumeHandle, &VolumeInfo, File, OutputBuffer, FALSE); } /* Free memory! */
6 years, 11 months
1
0
0
0
01/01: [NTOSKRNL] In FsRtlAddToTunnelCache() allocate memory from PagedPool when required. Also, if allocating from lookaside list, reattempt a cold allocation.
by Pierre Schweitzer
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=2abb99faa95ba50a352d6…
commit 2abb99faa95ba50a352d690fdfa767c87d59af91 Author: Pierre Schweitzer <pierre(a)reactos.org> AuthorDate: Sat Jan 20 21:20:11 2018 +0100 Commit: Pierre Schweitzer <pierre(a)reactos.org> CommitDate: Sat Jan 20 21:21:00 2018 +0100 [NTOSKRNL] In FsRtlAddToTunnelCache() allocate memory from PagedPool when required. Also, if allocating from lookaside list, reattempt a cold allocation. --- ntoskrnl/fsrtl/tunnel.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/ntoskrnl/fsrtl/tunnel.c b/ntoskrnl/fsrtl/tunnel.c index 727f467ddf..545cf2f214 100644 --- a/ntoskrnl/fsrtl/tunnel.c +++ b/ntoskrnl/fsrtl/tunnel.c @@ -346,7 +346,7 @@ FsRtlAddToTunnelCache(IN PTUNNEL Cache, IN ULONG DataLength, IN PVOID Data) { - PTUNNEL_NODE_ENTRY NodeEntry; + PTUNNEL_NODE_ENTRY NodeEntry = NULL; PRTL_SPLAY_LINKS CurEntry, LastEntry; ULONG Length; LONG Result = 0; @@ -384,23 +384,24 @@ FsRtlAddToTunnelCache(IN PTUNNEL Cache, Length += LongName->Length; } - if (Length > DEFAULT_ENTRY_SIZE) - { - /* bigger than default entry */ - NodeEntry = ExAllocatePool(NonPagedPool, Length); - AllocatedFromPool = TRUE; - } - else + if (Length <= DEFAULT_ENTRY_SIZE) { /* get standard entry */ NodeEntry = ExAllocateFromPagedLookasideList(&TunnelLookasideList); } - /* check for success */ - if (!NodeEntry) + if (NodeEntry == NULL) { - /* out of memory */ - return; + /* bigger than default entry or allocation failed */ + NodeEntry = ExAllocatePool(PagedPool | POOL_COLD_ALLOCATION, Length); + /* check for success */ + if (NodeEntry == NULL) + { + /* out of memory */ + return; + } + + AllocatedFromPool = TRUE; } /* acquire lock */
6 years, 11 months
1
0
0
0
← Newer
1
...
14
15
16
17
18
19
20
...
38
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
Results per page:
10
25
50
100
200